diff --git a/src/gui/plug/_guioptions.py b/src/gui/plug/_guioptions.py index c17713d12..b297d5d52 100644 --- a/src/gui/plug/_guioptions.py +++ b/src/gui/plug/_guioptions.py @@ -163,7 +163,7 @@ class GuiStringOption(gtk.Entry): """ This class displays an option that is a simple one-line string. """ - def __init__(self, option, dbstate, uistate, track): + def __init__(self, option, dbstate, uistate, track, override): """ @param option: The option to display. @type option: gen.plug.menu.StringOption @@ -225,7 +225,7 @@ class GuiColorOption(gtk.ColorButton): """ This class displays an option that allows the selection of a colour. """ - def __init__(self, option, dbstate, uistate, track): + def __init__(self, option, dbstate, uistate, track, override): self.__option = option value = self.__option.get_value() gtk.ColorButton.__init__( self, gtk.gdk.color_parse(value) ) @@ -278,7 +278,7 @@ class GuiNumberOption(gtk.SpinButton): This class displays an option that is a simple number with defined maximum and minimum values. """ - def __init__(self, option, dbstate, uistate, track): + def __init__(self, option, dbstate, uistate, track, override): self.__option = option decimals = 0 @@ -350,7 +350,7 @@ class GuiTextOption(gtk.ScrolledWindow): """ This class displays an option that is a multi-line string. """ - def __init__(self, option, dbstate, uistate, track): + def __init__(self, option, dbstate, uistate, track, override): self.__option = option gtk.ScrolledWindow.__init__(self) self.set_shadow_type(gtk.SHADOW_IN) @@ -433,7 +433,7 @@ class GuiBooleanOption(gtk.CheckButton): """ This class displays an option that is a boolean (True or False). """ - def __init__(self, option, dbstate, uistate, track): + def __init__(self, option, dbstate, uistate, track, override): self.__option = option gtk.CheckButton.__init__(self, self.__option.get_label()) self.set_active(self.__option.get_value()) @@ -489,7 +489,7 @@ class GuiEnumeratedListOption(gtk.HBox): This class displays an option that provides a finite number of values. Each possible value is assigned a value and a description. """ - def __init__(self, option, dbstate, uistate, track): + def __init__(self, option, dbstate, uistate, track, override): gtk.HBox.__init__(self) evtBox = gtk.EventBox() self.__option = option @@ -582,7 +582,7 @@ class GuiPersonOption(gtk.HBox): This class displays an option that allows a person from the database to be selected. """ - def __init__(self, option, dbstate, uistate, track): + def __init__(self, option, dbstate, uistate, track, override): """ @param option: The option to display. @type option: gen.plug.menu.PersonOption @@ -612,11 +612,12 @@ class GuiPersonOption(gtk.HBox): person_handle = self.__uistate.get_active('Person') person = self.__dbstate.db.get_person_from_handle(person_handle) - if not person: + if override or not person: # Pick up the stored option value if there is one person = self.__db.get_person_from_gramps_id(gid) if not person: + # If all else fails, get the default person to avoid bad values person = self.__db.get_default_person() self.__update_person(person) @@ -703,7 +704,7 @@ class GuiFamilyOption(gtk.HBox): This class displays an option that allows a family from the database to be selected. """ - def __init__(self, option, dbstate, uistate, track): + def __init__(self, option, dbstate, uistate, track, override): """ @param option: The option to display. @type option: gen.plug.menu.FamilyOption @@ -727,7 +728,7 @@ class GuiFamilyOption(gtk.HBox): self.pack_start(pevt, False) self.pack_end(family_button, False) - self.__initialize_family() + self.__initialize_family(override) self.valuekey = self.__option.connect('value-changed', self.__value_changed) @@ -737,10 +738,10 @@ class GuiFamilyOption(gtk.HBox): pevt.set_tooltip_text(self.__option.get_help()) family_button.set_tooltip_text(_('Select a different family')) - def __initialize_family(self): + def __initialize_family(self, override): """ Find a family to initialize the option with. If there is no saved - family option, use the active family. If there ris no active + family option, use the active family. If there is no active family, try to find a family that the user is likely interested in. """ family_list = [] @@ -749,7 +750,7 @@ class GuiFamilyOption(gtk.HBox): # Use the active family if one is selected family = self.__uistate.get_active('Family') - if family: + if family and not override: family_list = [family] else: # Use the stored option value @@ -886,7 +887,7 @@ class GuiNoteOption(gtk.HBox): This class displays an option that allows a note from the database to be selected. """ - def __init__(self, option, dbstate, uistate, track): + def __init__(self, option, dbstate, uistate, track, override): """ @param option: The option to display. @type option: gen.plug.menu.NoteOption @@ -990,7 +991,7 @@ class GuiMediaOption(gtk.HBox): This class displays an option that allows a media object from the database to be selected. """ - def __init__(self, option, dbstate, uistate, track): + def __init__(self, option, dbstate, uistate, track, override): """ @param option: The option to display. @type option: gen.plug.menu.MediaOption @@ -1091,7 +1092,7 @@ class GuiPersonListOption(gtk.HBox): This class displays a widget that allows multiple people from the database to be selected. """ - def __init__(self, option, dbstate, uistate, track): + def __init__(self, option, dbstate, uistate, track, override): """ @param option: The option to display. @type option: gen.plug.menu.PersonListOption @@ -1268,7 +1269,7 @@ class GuiPlaceListOption(gtk.HBox): This class displays a widget that allows multiple places from the database to be selected. """ - def __init__(self, option, dbstate, uistate, track): + def __init__(self, option, dbstate, uistate, track, override): """ @param option: The option to display. @type option: gen.plug.menu.PlaceListOption @@ -1412,7 +1413,7 @@ class GuiSurnameColorOption(gtk.HBox): selected from the database, and to assign a colour (not necessarily unique) to each one. """ - def __init__(self, option, dbstate, uistate, track): + def __init__(self, option, dbstate, uistate, track, override): """ @param option: The option to display. @type option: gen.plug.menu.SurnameColorOption @@ -1603,7 +1604,7 @@ class GuiDestinationOption(gtk.HBox): This class displays an option that allows the user to select a DestinationOption. """ - def __init__(self, option, dbstate, uistate, track): + def __init__(self, option, dbstate, uistate, track, override): """ @param option: The option to display. @type option: gen.plug.menu.DestinationOption @@ -1732,7 +1733,7 @@ class GuiStyleOption(GuiEnumeratedListOption): """ This class displays a StyleOption. """ - def __init__(self, option, dbstate, uistate, track): + def __init__(self, option, dbstate, uistate, track, override): """ @param option: The option to display. @type option: gen.plug.menu.StyleOption @@ -1772,7 +1773,7 @@ class GuiBooleanListOption(gtk.HBox): This class displays an option that provides a list of check boxes. Each possible value is assigned a value and a description. """ - def __init__(self, option, dbstate, uistate, track): + def __init__(self, option, dbstate, uistate, track, override): gtk.HBox.__init__(self) self.__option = option self.__cbutton = [] @@ -1884,10 +1885,14 @@ _OPTIONS = ( ) del menu -def make_gui_option(option, dbstate, uistate, track): +def make_gui_option(option, dbstate, uistate, track, override=False): """ Stand-alone function so that Options can be used in other ways, too. Takes an Option and returns a GuiOption. + + override: if True will override the GuiOption's normal behavior + (in a GuiOption-dependant fashion, for instance in a GuiPersonOption + it will force the use of the options's value to set the GuiOption) """ label, widget = True, None @@ -1904,7 +1909,7 @@ def make_gui_option(option, dbstate, uistate, track): "can't make GuiOption: unknown option type: '%s'" % option) if widget: - widget = widget(option, dbstate, uistate, track) + widget = widget(option, dbstate, uistate, track, override) return widget, label diff --git a/src/plugins/BookReport.py b/src/plugins/BookReport.py index 3d56da0c6..1756427b7 100644 --- a/src/plugins/BookReport.py +++ b/src/plugins/BookReport.py @@ -79,6 +79,8 @@ import ManagedWindow from glade import Glade import gui.utils import gui.user +from gui.plug import make_gui_option +from types import ClassType # Import from specific modules in ReportBase from gen.plug.report import CATEGORY_BOOK, book_categories @@ -446,7 +448,7 @@ class BookList(object): f = open(self.file, "w") f.write("\n") f.write('\n') - for name in self.bookmap: + for name in sorted(self.bookmap): # enable a diff of archived copies book = self.get_book(name) dbname = book.get_dbname() f.write('\n' % (name, dbname) ) @@ -934,20 +936,26 @@ class BookReportSelector(ManagedWindow.ManagedWindow): """ store, the_iter = self.book_model.get_selected() if not the_iter: + WarningDialog(_('No selected book item'), + _('Please select a book item to configure.') + ) return data = self.book_model.get_data(the_iter, range(self.book_nr_cols)) row = self.book_model.get_selected_row() item = self.book.get_item(row) option_class = item.option_class + option_class.handler.set_default_stylesheet_name(item.get_style_name()) + item.is_from_saved_book = bool(self.book.get_name()) item_dialog = BookItemDialog(self.dbstate, self.uistate, - item, - self.track) + item, self.track) while True: response = item_dialog.window.run() if response == gtk.RESPONSE_OK: # dialog will be closed by connect, now continue work while # rest of dialog is unresponsive, release when finished + style = option_class.handler.get_default_stylesheet_name() + item.set_style_name(style) subject = _get_subject(option_class, self.db) self.book_model.model.set_value(the_iter, 2, subject) self.book.set_item(row, item) @@ -1042,6 +1050,9 @@ class BookReportSelector(ManagedWindow.ManagedWindow): if self.book.item_list: BookReportDialog(self.dbstate, self.uistate, self.book, BookOptions) + else: + WarningDialog(_('No items'), _('This book has no items.')) + return self.close() def on_save_clicked(self, obj): @@ -1086,7 +1097,7 @@ class BookReportSelector(ManagedWindow.ManagedWindow): if book: self.open_book(book) self.name_entry.set_text(book.get_name()) - self.book.name = book.get_name() + self.book.set_name(book.get_name()) def on_edit_clicked(self, obj): """ @@ -1115,6 +1126,7 @@ class BookItemDialog(ReportDialog): name = item.get_name() translated_name = item.get_translated_name() self.option_class = item.option_class + self.is_from_saved_book = item.is_from_saved_book ReportDialog.__init__(self, dbstate, uistate, self.option_class, name, translated_name, track) @@ -1135,6 +1147,43 @@ class BookItemDialog(ReportDialog): def parse_target_frame(self): """Target frame is not used.""" return 1 + + def init_options(self, option_class): + try: + if (issubclass(option_class, object) or # New-style class + isinstance(option_class, ClassType)): # Old-style class + self.options = option_class(self.raw_name, self.db) + except TypeError: + self.options = option_class + if not self.is_from_saved_book: + self.options.load_previous_values() + + def add_user_options(self): + """ + Generic method to add user options to the gui. + """ + if not hasattr(self.options, "menu"): + return + menu = self.options.menu + options_dict = self.options.options_dict + for category in menu.get_categories(): + for name in menu.get_option_names(category): + option = menu.get_option(category, name) + + # override option default with xml-saved value: + if name in options_dict: + option.set_value(options_dict[name]) + + widget, label = make_gui_option(option, self.dbstate, + self.uistate, self.track, + self.is_from_saved_book) + if widget is not None: + if label: + self.add_frame_option(category, + option.get_label(), + widget) + else: + self.add_frame_option(category, "", widget) #------------------------------------------------------------------------- # @@ -1190,10 +1239,11 @@ class BookReportDialog(DocReportDialog): def __init__(self, dbstate, uistate, book, options): self.format_menu = None self.options = options + self.is_from_saved_book = False self.page_html_added = False + self.book = book DocReportDialog.__init__(self, dbstate, uistate, options, 'book', _("Book Report")) - self.book = book self.options.options_dict['bookname'] = self.book.name self.database = dbstate.db @@ -1259,6 +1309,16 @@ class BookReportDialog(DocReportDialog): if self.open_with_app.get_active(): gui.utils.open_file_with_default_application(self.target_path) + def init_options(self, option_class): + try: + if (issubclass(option_class, object) or # New-style class + isinstance(option_class, ClassType)): # Old-style class + self.options = option_class(self.raw_name, self.db) + except TypeError: + self.options = option_class + if not self.is_from_saved_book: + self.options.load_previous_values() + #------------------------------------------------------------------------ # # Function to write books from command line