# # Gramps - a GTK+/GNOME based genealogy program # # Copyright (C) 2000-2006 Donald N. Allingham # 2009 Gary Burton # 2009 Benny Malengier # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # $Id$ #------------------------------------------------------------------------- # # Python classes # #------------------------------------------------------------------------- from gen.ggettext import gettext as _ import logging _LOG = logging.getLogger(".gui.editors.EditNote") #------------------------------------------------------------------------- # # GTK libraries # #------------------------------------------------------------------------- import gtk import gobject import pango #------------------------------------------------------------------------- # # GRAMPS modules # #------------------------------------------------------------------------- import config import const from gui.widgets import StyledTextEditor from editprimary import EditPrimary from displaytabs import GrampsTab, NoteBackRefList from gui.widgets import (MonitoredDataType, MonitoredCheckbox, MonitoredEntry, PrivacyButton) from gen.lib import Note from QuestionDialog import ErrorDialog from glade import Glade #------------------------------------------------------------------------- # # NoteTab # #------------------------------------------------------------------------- class NoteTab(GrampsTab): """ This class provides the tabpage of the note """ def __init__(self, dbstate, uistate, track, name, widget): """ @param dbstate: The database state. Contains a reference to the database, along with other state information. The GrampsTab uses this to access the database and to pass to and created child windows (such as edit dialogs). @type dbstate: L{DbState.DbState} @param uistate: The UI state. Used primarily to pass to any created subwindows. @type uistate: L{DisplayState.DisplayState} @param track: The window tracking mechanism used to manage windows. This is only used to pass to generted child windows. @type track: list @param name: Notebook label name @type name: str/unicode @param widget: widget to be shown in the tab @type widget: gtk widget """ GrampsTab.__init__(self, dbstate, uistate, track, name) eventbox = gtk.EventBox() eventbox.add(widget) self.pack_start(eventbox) self._set_label(show_image=False) eventbox.connect('key_press_event', self.key_pressed) self.show_all() def is_empty(self): """ Override base class """ return False #------------------------------------------------------------------------- # # EditNote # #------------------------------------------------------------------------- class EditNote(EditPrimary): def __init__(self, dbstate, uistate, track, note, callback=None, callertitle = None, extratype = None): """Create an EditNote window. Associate a note with the window. @param callertitle: Text passed by calling object to add to title @type callertitle: str @param extratype: Extra L{NoteType} values to add to the default types. They are removed from the ignorelist of L{NoteType}. @type extratype: list of int """ self.callertitle = callertitle self.extratype = extratype EditPrimary.__init__(self, dbstate, uistate, track, note, dbstate.db.get_note_from_handle, dbstate.db.get_note_from_gramps_id, callback) def empty_object(self): """Return an empty Note object for comparison for changes. It is used by the base class L{EditPrimary}. """ empty_note = Note(); if self.extratype: empty_note.set_type(self.extratype[0]) return empty_note def get_menu_title(self): if self.obj.get_handle(): if self.callertitle : title = _('Note: %(id)s - %(context)s') % { 'id' : self.obj.get_gramps_id(), 'context' : self.callertitle } else : title = _('Note: %s') % self.obj.get_gramps_id() else: if self.callertitle : title = _('New Note - %(context)s') % { 'context' : self.callertitle } else : title = _('New Note') return title def get_custom_notetypes(self): return self.dbstate.db.get_note_types() def _local_init(self): """Local initialization function. Perform basic initialization, including setting up widgets and the glade interface. It is called by the base class L{EditPrimary}, and overridden here. """ self.width_key = 'interface.note-width' self.height_key = 'interface.note-height' self.top = Glade() win = self.top.toplevel self.set_window(win, None, self.get_menu_title()) vboxnote = self.top.get_object('vbox131') notebook = self.top.get_object('note_notebook') #recreate start page as GrampsTab notebook.remove_page(0) self.ntab = NoteTab(self.dbstate, self.uistate, self.track, _('_Note'), vboxnote) self.track_ref_for_deletion("ntab") self.build_interface() def _setup_fields(self): """Get control widgets and attach them to Note's attributes.""" self.type_selector = MonitoredDataType( self.top.get_object('type'), self.obj.set_type, self.obj.get_type, self.db.readonly, custom_values=self.get_custom_notetypes(), ignore_values=self.obj.get_type().get_ignore_list(self.extratype)) self.check = MonitoredCheckbox( self.obj, self.top.get_object('format'), self.obj.set_format, self.obj.get_format, readonly = self.db.readonly) self.gid = MonitoredEntry( self.top.get_object('id'), self.obj.set_gramps_id, self.obj.get_gramps_id, self.db.readonly) self.marker = MonitoredDataType( self.top.get_object('marker'), self.obj.set_marker, self.obj.get_marker, self.db.readonly, self.db.get_marker_types()) self.priv = PrivacyButton( self.top.get_object("private"), self.obj, self.db.readonly) def _connect_signals(self): """Connects any signals that need to be connected. Called by the init routine of the base class L{EditPrimary}. """ self.define_ok_button(self.top.get_object('ok'), self.save) self.define_cancel_button(self.top.get_object('cancel')) self.define_help_button(self.top.get_object('help')) def _connect_db_signals(self): """ Connect any signals that need to be connected. Called by the init routine of the base class (_EditPrimary). """ self._add_db_signal('note-rebuild', self._do_close) self._add_db_signal('note-delete', self.check_for_close) def _create_tabbed_pages(self): """Create the notebook tabs and inserts them into the main window.""" notebook = self.top.get_object("note_notebook") self._add_tab(notebook, self.ntab) handles = self.dbstate.db.find_backlink_handles(self.obj.handle) self.rlist = NoteBackRefList(self.dbstate, self.uistate, self.track, handles) self.backref_tab = self._add_tab(notebook, self.rlist) self.track_ref_for_deletion("rlist") self.track_ref_for_deletion("backref_tab") self._setup_notebook_tabs(notebook) def build_interface(self): self.texteditor = self.top.get_object('texteditor') self.texteditor.set_editable(not self.dbstate.db.readonly) self.texteditor.set_wrap_mode(gtk.WRAP_WORD) # create a formatting toolbar if not self.dbstate.db.readonly: vbox = self.top.get_object('container') vbox.pack_start(self.texteditor.get_toolbar(), expand=False, fill=False) # setup initial values for textview and textbuffer if self.obj: self.empty = False self.texteditor.set_text(self.obj.get_styledtext()) _LOG.debug("Initial Note: %s" % str(self.texteditor.get_text())) else: self.empty = True def build_menu_names(self, person): """ Provide the information needed by the base class to define the window management menu entries. """ return (_('Edit Note'), self.get_menu_title()) def _post_init(self): self.texteditor.grab_focus() def update_note(self): """Update the Note object with current value.""" if self.obj: text = self.texteditor.get_text() self.obj.set_styledtext(text) _LOG.debug(str(text)) def save(self, *obj): """Save the data.""" self.ok_button.set_sensitive(False) self.update_note() if self.object_is_empty(): ErrorDialog(_("Cannot save note"), _("No data exists for this note. Please " "enter data or cancel the edit.")) self.ok_button.set_sensitive(True) return (uses_dupe_id, id) = self._uses_duplicate_id() if uses_dupe_id: msg1 = _("Cannot save note. ID already exists.") msg2 = _("You have attempted to use the existing Gramps ID with " "value %(id)s. This value is already used. Please " "enter a different ID or leave " "blank to get the next available ID value.") % { 'id' : id } ErrorDialog(msg1, msg2) self.ok_button.set_sensitive(True) return trans = self.db.transaction_begin() if not self.obj.get_handle(): self.db.add_note(self.obj, trans) msg = _("Add Note") else: if not self.obj.get_gramps_id(): self.obj.set_gramps_id(self.db.find_next_note_gramps_id()) self.db.commit_note(self.obj, trans) msg = _("Edit Note") self.db.transaction_commit(trans, msg) if self.callback: self.callback(self.obj.get_handle()) self.close() class DeleteNoteQuery(object): def __init__(self, dbstate, uistate, note, the_lists): self.note = note self.db = dbstate.db self.uistate = uistate self.the_lists = the_lists def query_response(self): trans = self.db.transaction_begin() self.db.disable_signals() (person_list, family_list, event_list, place_list, source_list, media_list, repo_list) = self.the_lists note_handle = self.note.get_handle() for handle in person_list: person = self.db.get_person_from_handle(handle) person.remove_note(note_handle) self.db.commit_person(person, trans) for handle in family_list: family = self.db.get_family_from_handle(handle) family.remove_note(note_handle) self.db.commit_family(family, trans) for handle in event_list: event = self.db.get_event_from_handle(handle) event.remove_note(note_handle) self.db.commit_event(event, trans) for handle in place_list: place = self.db.get_place_from_handle(handle) place.remove_note(note_handle) self.db.commit_place(place, trans) for handle in source_list: source = self.db.get_source_from_handle(handle) source.remove_note(note_handle) self.db.commit_source(source, trans) for handle in media_list: media = self.db.get_object_from_handle(handle) media.remove_note(note_handle) self.db.commit_media_object(media, trans) for handle in repo_list: repo = self.db.get_repository_from_handle(handle) repo.remove_note(note_handle) self.db.commit_repository(repo, trans) self.db.enable_signals() self.db.remove_note(note_handle, trans) self.db.transaction_commit( trans,_("Delete Note (%s)") % self.note.get_gramps_id())