def __init__(self, name, style, parent): """ Create the StyleEditor. name - name of the style that is to be edited style - style object that is to be edited parent - StyleListDisplay object that called the editor """ self.current_p = None self.current_name = None self.style = StyleSheet(style) self.parent = parent self.top = Glade(toplevel='editor') self.window = self.top.toplevel self.top.connect_signals({ "on_save_style_clicked": self.on_save_style_clicked, "destroy_passed_object": self.__close, "on_ok_clicked": dummy_callback, "on_add_clicked": dummy_callback, "on_delete_clicked": dummy_callback, "on_button_press": dummy_callback, "on_edit_clicked": dummy_callback, }) self.pname = self.top.get_object('pname') self.pdescription = self.top.get_object('pdescription') set_titles(self.window, self.top.get_object('title'), _('Style editor')) self.top.get_object("label6").set_text(_("point size|pt")) titles = [(_('Paragraph'), 0, 130)] self.plist = ListModel(self.top.get_object("ptree"), titles, self.change_display) self.top.get_object('color').connect('color-set', self.fg_color_set) self.top.get_object('bgcolor').connect('color-set', self.bg_color_set) self.top.get_object("style_name").set_text(name) def _alphanumeric_sort(iterable): """ sort the given iterable in the way that humans expect """ convert = lambda text: int(text) if text.isdigit() else text sort_key = lambda k: [convert(c) for c in re.split('([0-9]+)', k)] return sorted(iterable, key=sort_key) names = _alphanumeric_sort(self.style.get_paragraph_style_names()) for p_name in names: self.plist.add([p_name], self.style.get_paragraph_style(p_name)) self.plist.select_row(0) if self.parent: self.window.set_transient_for(parent.window) self.window.run() self.window.destroy()
def setup_style_frame(self): """Set up the style frame of the dialog. This function relies on other routines to create the default style for this report, and to read in any user-defined styles for this report. It then builds a menu of all the available styles for the user to choose from.""" # Build the default style set for this report. self.default_style = StyleSheet() self.options.make_default_style(self.default_style) if self.default_style.is_empty(): # Don't display the option if no styles are used return # Styles Frame label = Gtk.Label(label="%s:" % _("Style")) label.set_alignment(0.0, 0.5) self.style_menu = StyleComboBox() self.style_button = Gtk.Button("%s..." % _("Style Editor")) self.style_button.connect('clicked', self.on_style_edit_clicked) self.tbl.attach(label, 1, 2, self.row, self.row + 1, Gtk.AttachOptions.SHRINK | Gtk.AttachOptions.FILL) self.tbl.attach(self.style_menu, 2, 3, self.row, self.row + 1, yoptions=Gtk.AttachOptions.SHRINK) self.tbl.attach(self.style_button, 3, 4, self.row, self.row + 1, xoptions=Gtk.AttachOptions.SHRINK | Gtk.AttachOptions.FILL, yoptions=Gtk.AttachOptions.SHRINK) self.row += 1 # Build the initial list of available styles sets. This # includes the default style set and any style sets saved from # previous invocations of gramps. self.style_sheet_list = StyleSheetList( self.options.handler.get_stylesheet_savefile(), self.default_style) # Now build the actual menu. style = self.options.handler.get_default_stylesheet_name() self.build_style_menu(style)
def cl_book(database, name, book, options_str_dict): """ function to actually run the selected book, which in turn runs whatever reports the book has in it """ clr = CommandLineReport(database, name, CATEGORY_BOOK, ReportOptions, options_str_dict) # Exit here if show option was given if clr.show: return # write report doc = clr.format( None, PaperStyle(clr.paper, clr.orien, clr.marginl, clr.marginr, clr.margint, clr.marginb)) user = User() rptlist = [] selected_style = StyleSheet() for item in book.get_item_list(): # The option values were loaded magically by the book parser. # But they still need to be applied to the menu options. opt_dict = item.option_class.options_dict menu = item.option_class.menu for optname in opt_dict: menu_option = menu.get_option_by_name(optname) if menu_option: menu_option.set_value(opt_dict[optname]) item.option_class.set_document(doc) report_class = item.get_write_item() obj = (write_book_item(database, report_class, item.option_class, user), item.get_translated_name()) if obj: append_styles(selected_style, item) rptlist.append(obj) doc.set_style_sheet(selected_style) doc.open(clr.option_class.get_output()) doc.init() newpage = 0 err_msg = _("Failed to make '%s' report.") try: for (rpt, name) in rptlist: if newpage: doc.page_break() newpage = 1 rpt.begin_report() rpt.write_report() doc.close() except ReportError as msg: (msg1, msg2) = msg.messages() print(err_msg % name, file=sys.stderr) # which report has the error? print(msg1, file=sys.stderr) if msg2: print(msg2, file=sys.stderr)
def cl_book(database, name, book, options_str_dict): clr = CommandLineReport(database, name, CATEGORY_BOOK, ReportOptions, options_str_dict) # Exit here if show option was given if clr.show: return # write report doc = clr.format( None, PaperStyle(clr.paper, clr.orien, clr.marginl, clr.marginr, clr.margint, clr.marginb)) user = User() rptlist = [] selected_style = StyleSheet() for item in book.get_item_list(): # The option values were loaded magically by the book parser. # But they still need to be applied to the menu options. opt_dict = item.option_class.options_dict menu = item.option_class.menu for optname in opt_dict: menu_option = menu.get_option_by_name(optname) if menu_option: menu_option.set_value(opt_dict[optname]) item.option_class.set_document(doc) report_class = item.get_write_item() obj = write_book_item(database, report_class, item.option_class, user) if obj: append_styles(selected_style, item) rptlist.append(obj) doc.set_style_sheet(selected_style) doc.open(clr.option_class.get_output()) doc.init() newpage = 0 for rpt in rptlist: if newpage: doc.page_break() newpage = 1 rpt.begin_report() rpt.write_report() doc.close()
def make_document(self): """Create a document of the type requested by the user.""" user = User() self.rptlist = [] selected_style = StyleSheet() pstyle = self.paper_frame.get_paper_style() self.doc = self.format(None, pstyle) for item in self.book.get_item_list(): item.option_class.set_document(self.doc) report_class = item.get_write_item() obj = write_book_item(self.database, report_class, item.option_class, user) self.rptlist.append(obj) append_styles(selected_style, item) self.doc.set_style_sheet(selected_style) self.doc.open(self.target_path)
def setup_style_frame(self): """Set up the style frame of the dialog. This function relies on other routines to create the default style for this report, and to read in any user-defined styles for this report. It then builds a menu of all the available styles for the user to choose from.""" # Build the default style set for this report. self.default_style = StyleSheet() self.options.make_default_style(self.default_style) if self.default_style.is_empty(): # Don't display the option if no styles are used return # Styles Frame label = Gtk.Label(label="%s:" % _("Style")) label.set_halign(Gtk.Align.START) self.style_menu = StyleComboBox() self.style_menu.set_hexpand(True) self.style_button = Gtk.Button("%s..." % _("Style Editor")) self.style_button.connect('clicked', self.on_style_edit_clicked) self.grid.attach(label, 1, self.row, 1, 1) self.grid.attach(self.style_menu, 2, self.row, 1, 1) self.grid.attach(self.style_button, 3, self.row, 1, 1) self.row += 1 # Build the initial list of available styles sets. This # includes the default style set and any style sets saved from # previous invocations of gramps. self.style_sheet_list = StyleSheetList( self.options.handler.get_stylesheet_savefile(), self.default_style) # Now build the actual menu. style = self.options.handler.get_default_stylesheet_name() self.build_style_menu(style)
def test_write_report(self): """ Creates a report from test data. """ options = FamilyChroniclesOptions("Familiy Chronicles", self.db) options.load_previous_values() options.menu.get_option_by_name('pid').set_value(TEST_PERSON_ID) docgen_plugin = Familychroniclestest.__get_docgen_plugin('latexdoc') doc_class = docgen_plugin.get_basedoc() styles = StyleSheet() options.make_default_style(styles) paper_layout = PaperStyle(PaperSize("a4", None, None), PAPER_LANDSCAPE) doc = doc_class(styles, paper_layout, []) options.set_document(doc) options.set_output(TEST_OUTPUT) # Initialization sequence inspired by _reportdialog.py, report() my_report = FamilyChronicles(self.db, options, User()) my_report.doc.init() my_report.begin_report() my_report.write_report() my_report.end_report()
def parse_options(self): """ Load the options that the user has entered. """ if not hasattr(self.option_class, "menu"): menu = None else: menu = self.option_class.menu menu_opt_names = menu.get_all_option_names() _format_str = self.options_str_dict.pop('off', None) if _format_str: self.options_dict['off'] = _format_str self.css_filename = None _chosen_format = None self.doc_option_class = None if self.category in [CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_BOOK]: if self.category == CATEGORY_TEXT: plugins = self.__textdoc_plugins self.css_filename = self.options_dict['css'] elif self.category == CATEGORY_DRAW: plugins = self.__drawdoc_plugins elif self.category == CATEGORY_BOOK: plugins = self.__bookdoc_plugins for plugin in plugins: if plugin.get_extension() == self.options_dict['off']: self.format = plugin.get_basedoc() self.doc_option_class = plugin.get_doc_option_class() if self.format is None: # Pick the first one as the default. plugin = plugins[0] self.format = plugin.get_basedoc() self.doc_option_class = plugin.get_doc_option_class() _chosen_format = plugin.get_extension() elif self.category == CATEGORY_GRAPHVIZ: for graph_format in graphdoc.FORMATS: if graph_format['type'] == self.options_dict['off']: if not self.format: # choose the first one, not the last self.format = graph_format["class"] if self.format is None: # Pick the first one as the default. self.format = graphdoc.FORMATS[0]["class"] _chosen_format = graphdoc.FORMATS[0]["type"] else: self.format = None if _chosen_format and _format_str: print(_("Ignoring '%(notranslate1)s=%(notranslate2)s' " "and using '%(notranslate1)s=%(notranslate3)s'.") % { 'notranslate1': "off", 'notranslate2': self.options_dict['off'], 'notranslate3': _chosen_format }, file=sys.stderr) print(_("Use '%(notranslate)s' to see valid values.") % {'notranslate': "show=off"}, file=sys.stderr) self.do_doc_options() for opt in self.options_str_dict: if opt in self.options_dict: self.options_dict[opt] = \ _convert_str_to_match_type(self.options_str_dict[opt], self.options_dict[opt]) self.option_class.handler.options_dict[opt] = \ self.options_dict[opt] if menu and opt in menu_opt_names: option = menu.get_option_by_name(opt) option.set_value(self.options_dict[opt]) else: print(_("Ignoring unknown option: %s") % opt, file=sys.stderr) print(_(" Valid options are:"), ", ".join(list(self.options_dict.keys())), file=sys.stderr) print(_(" Use '%(donottranslate)s' to see description " "and acceptable values") % {'donottranslate': "show=option"}, file=sys.stderr) self.option_class.handler.output = self.options_dict['of'] self.paper = paper_sizes[0] # make sure one exists for paper in paper_sizes: if paper.get_name() == self.options_dict['papers']: self.paper = paper self.option_class.handler.set_paper(self.paper) self.orien = self.options_dict['papero'] self.marginl = self.options_dict['paperml'] self.marginr = self.options_dict['papermr'] self.margint = self.options_dict['papermt'] self.marginb = self.options_dict['papermb'] if self.category in (CATEGORY_TEXT, CATEGORY_DRAW): default_style = StyleSheet() self.option_class.make_default_style(default_style) # Read all style sheets available for this item style_file = self.option_class.handler.get_stylesheet_savefile() self.style_list = StyleSheetList(style_file, default_style) # Get the selected stylesheet style_name = self.option_class.handler.get_default_stylesheet_name( ) self.selected_style = self.style_list.get_style_sheet(style_name)
def init_standard_options(self, noopt): """ Initialize the options that are hard-coded into the report system. """ self.options_dict = { 'of' : self.option_class.handler.module_name, 'off' : self.option_class.handler.get_format_name(), 'style' : \ self.option_class.handler.get_default_stylesheet_name(), 'papers' : self.option_class.handler.get_paper_name(), 'papero' : self.option_class.handler.get_orientation(), 'paperml' : self.option_class.handler.get_margins()[0], 'papermr' : self.option_class.handler.get_margins()[1], 'papermt' : self.option_class.handler.get_margins()[2], 'papermb' : self.option_class.handler.get_margins()[3], 'css' : self.option_class.handler.get_css_filename(), } self.options_help = { 'of': [_("=filename"), _("Output file name. MANDATORY"), ""], 'off': [_("=format"), _("Output file format."), []], 'style': [_("=name"), _("Style name."), ""], 'papers': [_("=name"), _("Paper size name."), ""], 'papero': [_("=number"), _("Paper orientation number."), ""], 'paperml': [_("=number"), _("Left paper margin"), _("Size in cm")], 'papermr': [_("=number"), _("Right paper margin"), _("Size in cm")], 'papermt': [_("=number"), _("Top paper margin"), _("Size in cm")], 'papermb': [_("=number"), _("Bottom paper margin"), _("Size in cm")], 'css': [ _("=css filename"), _("CSS filename to use, " "html format only"), "" ], } if noopt: return self.options_help['of'][2] = os.path.join(USER_HOME, "whatever_name") if self.category == CATEGORY_TEXT: for plugin in self.__textdoc_plugins: self.options_help['off'][2].append(plugin.get_extension() + "\t" + plugin.get_description()) elif self.category == CATEGORY_DRAW: for plugin in self.__drawdoc_plugins: self.options_help['off'][2].append(plugin.get_extension() + "\t" + plugin.get_description()) elif self.category == CATEGORY_BOOK: for plugin in self.__bookdoc_plugins: self.options_help['off'][2].append(plugin.get_extension() + "\t" + plugin.get_description()) elif self.category == CATEGORY_GRAPHVIZ: for graph_format in graphdoc.FORMATS: self.options_help['off'][2].append(graph_format["type"] + "\t" + graph_format["descr"]) else: self.options_help['off'][2] = "NA" self.options_help['papers'][2] = \ [ paper.get_name() for paper in paper_sizes if paper.get_name() != 'Custom Size' ] self.options_help['papero'][2] = [ "%d\tPortrait" % PAPER_PORTRAIT, "%d\tLandscape" % PAPER_LANDSCAPE ] self.options_help['css'][2] = os.path.join(USER_HOME, "whatever_name.css") if self.category in (CATEGORY_TEXT, CATEGORY_DRAW): default_style = StyleSheet() self.option_class.make_default_style(default_style) # Read all style sheets available for this item style_file = self.option_class.handler.get_stylesheet_savefile() self.style_list = StyleSheetList(style_file, default_style) self.options_help['style'][2] = self.style_list.get_style_names()
class ReportDialog(ManagedWindow): """ The ReportDialog base class. This is a base class for generating customized dialogs to solicit options for a report. It cannot be used as is, but it can be easily sub-classed to create a functional dialog for a stand-alone report. """ border_pad = 6 def __init__(self, dbstate, uistate, option_class, name, trans_name, track=[]): """Initialize a dialog to request that the user select options for a basic *stand-alone* report.""" self.style_name = "default" self.firstpage_added = False self.raw_name = name self.dbstate = dbstate self.uistate = uistate self.db = dbstate.db self.report_name = trans_name ManagedWindow.__init__(self, uistate, track, self) self.init_options(option_class) self.init_interface() def close(self, *obj): """ Close itself. cleanup things that can prevent garbage collection """ if hasattr(self, 'widgets'): # handle pathlogical bug 4145 totwidg = list(range(len(self.widgets))) totwidg.reverse() for ind in totwidg: if hasattr(self.widgets[ind][1], 'clean_up'): self.widgets[ind][1].clean_up() del self.widgets[ind] delattr(self, 'widgets') for name, fram in self.frames.items(): totwidg = list(range(len(fram))) totwidg.reverse() for ind in totwidg: if hasattr(fram[ind][1], 'clean_up'): fram[ind][1].clean_up() del fram[ind] self.frames.clear() self.frames = None ManagedWindow.close(self, *obj) def init_options(self, option_class): try: if issubclass(option_class, object): self.options = option_class(self.raw_name, self.db) except TypeError: self.options = option_class self.options.load_previous_values() def build_window_key(self, obj): key = self.raw_name return key def build_menu_names(self, obj): return (_("Configuration"), self.report_name) def init_interface(self): self.widgets = [] self.doc_widgets = [] self.frame_names = [] self.frames = {} self.format_menu = None self.style_button = None self.style_name = self.options.handler.get_default_stylesheet_name() window = Gtk.Dialog('Gramps') self.set_window(window, None, self.get_title()) self.window.set_modal(True) self.help = self.window.add_button(_('_Help'), Gtk.ResponseType.HELP) self.help.connect('clicked', self.on_help_clicked) self.cancel = self.window.add_button(_('_Cancel'), Gtk.ResponseType.CANCEL) self.cancel.connect('clicked', self.on_cancel) self.ok = self.window.add_button(_('_OK'), Gtk.ResponseType.OK) self.ok.connect('clicked', self.on_ok_clicked) self.window.set_position(Gtk.WindowPosition.CENTER) self.window.set_default_size(600, -1) # Set up and run the dialog. These calls are not in top down # order when looking at the dialog box as there is some # interaction between the various frames. self.setup_title() self.setup_header() self.grid = Gtk.Grid() self.grid.set_column_spacing(12) self.grid.set_row_spacing(6) self.grid.set_border_width(6) self.row = 0 # Build the list of widgets that are used to extend the Options # frame and to create other frames self.add_user_options() self.setup_init() self.setup_format_frame() self.setup_target_frame() self.setup_style_frame() self.notebook = Gtk.Notebook() self.notebook.set_scrollable(True) self.notebook.set_border_width(6) try: #assume a vbox or hbox self.window.vbox.pack_start(self.notebook, expand=True, fill=True, padding=0) except: #general container instead: self.window.vbox.add(self.notebook) self.setup_report_options_frame() self.setup_other_frames() self.notebook.set_current_page(0) try: #assume a vbox or hbox self.window.vbox.pack_start(self.grid, expand=True, fill=True, padding=0) except: #general container instead: self.window.vbox.add(self.grid) self.show() def get_title(self): """The window title for this dialog""" name = self.report_name category = standalone_categories[self.category][1] return "%s - %s - Gramps" % (name, category) #------------------------------------------------------------------------ # # Functions related to extending the options # #------------------------------------------------------------------------ def add_user_options(self): """Called to allow subclasses to add widgets to the dialog form. It is called immediately before the window is displayed. All calls to add_option or add_frame_option should be called in this task.""" add_gui_options(self) def parse_user_options(self): """Called to allow parsing of added widgets. It is called when OK is pressed in a dialog. All custom widgets should provide a parsing code here.""" try: self.options.parse_user_options() except: LOG.error("Failed to parse user options.", exc_info=True) def add_option(self, label_text, widget): """Takes a text string and a Gtk Widget, and stores them to be appended to the Options section of the dialog. The text string is used to create a label for the passed widget. This allows the subclass to extend the Options section with its own widgets. The subclass is responsible for all managing of the widgets, including extracting the final value before the report executes. This task should only be called in the add_user_options task.""" self.widgets.append((label_text, widget)) def add_frame_option(self, frame_name, label_text, widget): """Similar to add_option this method takes a frame_name, a text string and a Gtk Widget. When the interface is built, all widgets with the same frame_name are grouped into a GtkFrame. This allows the subclass to create its own sections, filling them with its own widgets. The subclass is responsible for all managing of the widgets, including extracting the final value before the report executes. This task should only be called in the add_user_options task.""" if frame_name in self.frames: self.frames[frame_name].append((label_text, widget)) else: self.frames[frame_name] = [(label_text, widget)] self.frame_names.append(frame_name) #------------------------------------------------------------------------ # # Functions to create a default output style. # #------------------------------------------------------------------------ def build_style_menu(self, default=None): """Build a menu of style sets that are available for use in this report. This menu will always have a default style available, and will have any other style set name that the user has previously created for this report. This menu is created here instead of inline with the rest of the style frame, because it must be recreated to reflect any changes whenever the user closes the style editor dialog.""" if default is None: default = self.style_name style_sheet_map = self.style_sheet_list.get_style_sheet_map() self.style_menu.set(style_sheet_map, default) #------------------------------------------------------------------------ # # Functions related to setting up the dialog window. # #------------------------------------------------------------------------ def setup_title(self): """Set up the title bar of the dialog. This function relies on the get_title() customization function for what the title should be.""" self.window.set_title(self.get_title()) def setup_header(self): """Set up the header line bar of the dialog.""" label = Gtk.Label(label='<span size="larger" weight="bold">%s</span>' % self.report_name) label.set_use_markup(True) self.window.vbox.pack_start(label, False, False, self.border_pad) def setup_style_frame(self): """Set up the style frame of the dialog. This function relies on other routines to create the default style for this report, and to read in any user-defined styles for this report. It then builds a menu of all the available styles for the user to choose from.""" # Build the default style set for this report. self.default_style = StyleSheet() self.options.make_default_style(self.default_style) if self.default_style.is_empty(): # Don't display the option if no styles are used return # Styles Frame label = Gtk.Label(label="%s:" % _("Style")) label.set_halign(Gtk.Align.START) self.style_menu = StyleComboBox() self.style_menu.set_hexpand(True) self.style_button = Gtk.Button("%s..." % _("Style Editor")) self.style_button.connect('clicked', self.on_style_edit_clicked) self.grid.attach(label, 1, self.row, 1, 1) self.grid.attach(self.style_menu, 2, self.row, 1, 1) self.grid.attach(self.style_button, 3, self.row, 1, 1) self.row += 1 # Build the initial list of available styles sets. This # includes the default style set and any style sets saved from # previous invocations of gramps. self.style_sheet_list = StyleSheetList( self.options.handler.get_stylesheet_savefile(), self.default_style) # Now build the actual menu. style = self.options.handler.get_default_stylesheet_name() self.build_style_menu(style) def setup_report_options_frame(self): """Set up the report options frame of the dialog. This function relies on several report_xxx() customization functions to determine which of the items should be present in this box. *All* of these items are optional, although the generations fields is used in most (but not all) dialog boxes.""" row = 0 max_rows = len(self.widgets) if max_rows == 0: return grid = Gtk.Grid() grid.set_border_width(6) grid.set_column_spacing(12) grid.set_row_spacing(6) label = Gtk.Label(label="<b>%s</b>" % _("Report Options")) label.set_halign(Gtk.Align.START) label.set_use_markup(True) self.notebook.append_page(grid, label) # Setup requested widgets for (text, widget) in self.widgets: widget.set_hexpand(True) if text: text_widget = Gtk.Label(label="%s:" % text) text_widget.set_halign(Gtk.Align.START) grid.attach(text_widget, 1, row, 1, 1) grid.attach(widget, 2, row, 1, 1) else: grid.attach(widget, 2, row, 1, 1) row += 1 def setup_other_frames(self): from gramps.gui.plug._guioptions import GuiTextOption for key in self.frame_names: flist = self.frames[key] grid = Gtk.Grid() grid.set_column_spacing(12) grid.set_row_spacing(6) grid.set_border_width(6) l = Gtk.Label(label="<b>%s</b>" % _(key)) l.set_use_markup(True) self.notebook.append_page(grid, l) row = 0 for (text, widget) in flist: widget.set_hexpand(True) if text: text_widget = Gtk.Label(label='%s:' % text) text_widget.set_halign(Gtk.Align.START) grid.attach(text_widget, 1, row, 1, 1) if isinstance(widget, GuiTextOption): grid.attach(widget, 2, row, 1, 1) else: grid.attach(widget, 2, row, 1, 1) else: grid.attach(widget, 2, row, 1, 1) row += 1 #------------------------------------------------------------------------ # # Customization hooks for stand-alone reports (subclass ReportDialog) # #------------------------------------------------------------------------ def setup_format_frame(self): """Not used in bare report dialogs. Override in the subclass.""" pass #------------------------------------------------------------------------ # # Functions related getting/setting the default directory for a dialog. # #------------------------------------------------------------------------ def get_default_directory(self): """Get the name of the directory to which the target dialog box should default. This value can be set in the preferences panel.""" return config.get('paths.report-directory') def set_default_directory(self, value): """Save the name of the current directory, so that any future reports will default to the most recently used directory. This also changes the directory name that will appear in the preferences panel, but does not change the preference in disk. This means that the last directory used will only be remembered for this session of gramps unless the user saves his/her preferences.""" config.set('paths.report-directory', value) #------------------------------------------------------------------------ # # Functions related to setting up the dialog window. # #------------------------------------------------------------------------ def setup_init(self): # add any elements that we are going to need: hid = self.style_name if hid[-4:] == ".xml": hid = hid[0:-4] self.target_fileentry = FileEntry(hid, _("Save As"), parent=self.window) spath = self.get_default_directory() self.target_fileentry.set_filename(spath) # need any labels at top: label = Gtk.Label(label="<b>%s</b>" % _('Document Options')) label.set_use_markup(1) label.set_halign(Gtk.Align.START) self.grid.set_border_width(12) self.grid.attach(label, 0, self.row, 4, 1) self.row += 1 def setup_target_frame(self): """Set up the target frame of the dialog. This function relies on several target_xxx() customization functions to determine whether the target is a directory or file, what the title of any browser window should be, and what default directory should be used.""" # Save Frame self.doc_label = Gtk.Label(label="%s:" % _("Filename")) self.doc_label.set_halign(Gtk.Align.START) self.grid.attach(self.doc_label, 1, self.row, 1, 1) self.target_fileentry.set_hexpand(True) self.grid.attach(self.target_fileentry, 2, self.row, 2, 1) self.row += 1 #------------------------------------------------------------------------ # # Functions related to retrieving data from the dialog window # #------------------------------------------------------------------------ def parse_target_frame(self): """Parse the target frame of the dialog. If the target filename is empty this routine returns a special value of None to tell the calling routine to give up. This function also saves the current directory so that any future reports will default to the most recently used directory.""" self.target_path = conv_to_unicode(self.target_fileentry.get_full_path(0)) if not self.target_path: return None # First we check whether the selected path exists if os.path.exists(self.target_path): # selected path is an existing dir and we need a dir if os.path.isdir(self.target_path): # check whether the dir has rwx permissions if not os.access(self.target_path, os.R_OK|os.W_OK|os.X_OK): ErrorDialog(_('Permission problem'), _("You do not have permission to write " "under the directory %s\n\n" "Please select another directory or correct " "the permissions.") % self.target_path, parent=self.window) return None # selected path is an existing file and we need a file if os.path.isfile(self.target_path): a = OptionDialog(_('File already exists'), _('You can choose to either overwrite the ' 'file, or change the selected filename.'), _('_Overwrite'), None, _('_Change filename'), None, parent=self.window) if a.get_response() == Gtk.ResponseType.YES: return None # selected path does not exist yet else: # we will need to create the file/dir # need to make sure we can create in the parent dir parent_dir = os.path.dirname(os.path.normpath(self.target_path)) if os.path.isdir(parent_dir): if not os.access(parent_dir, os.W_OK): ErrorDialog(_('Permission problem'), _("You do not have permission to create " "%s\n\n" "Please select another path or correct " "the permissions.") % self.target_path, parent=self.window) return None else: ErrorDialog(_('No directory'), _('There is no directory %s.\n\n' 'Please select another directory ' 'or create it.') % parent_dir, parent=self.window) return None self.set_default_directory(os.path.dirname(self.target_path) + os.sep) self.options.handler.output = self.target_path return 1 def parse_style_frame(self): """Parse the style frame of the dialog. Save the user selected output style for later use. Note that this routine retrieves a value whether or not the menu is displayed on the screen. The subclass will know whether this menu was enabled. This is for simplicity of programming.""" if not self.default_style.is_empty(): (style_name, self.selected_style) = self.style_menu.get_value() self.options.handler.set_default_stylesheet_name(style_name) #------------------------------------------------------------------------ # # Callback functions from the dialog # #------------------------------------------------------------------------ def on_ok_clicked(self, obj): """The user is satisfied with the dialog choices. Validate the output file name before doing anything else. If there is a file name, gather the options and create the report.""" # Is there a filename? This should also test file permissions, etc. if not self.parse_target_frame(): self.window.run() # Preparation self.parse_style_frame() self.parse_user_options() # Save options self.options.handler.save_options() def on_cancel(self, *obj): pass def on_help_clicked(self, *obj): from ...display import display_help display_help(URL_REPORT_PAGE, self.report_name.replace(" ", "_")) def on_style_edit_clicked(self, *obj): """The user has clicked on the 'Edit Styles' button. Create a style sheet editor object and let them play. When they are done, the previous routine will be called to update the dialog menu for selecting a style.""" StyleListDisplay(self.style_sheet_list, self.build_style_menu, self.window) #---------------------------------------------------------------------- # # Functions related to any docgen options for a dialog. # #---------------------------------------------------------------------- def setup_doc_options_frame(self): if self.doc_widgets: for option_widget in self.doc_widgets: self.grid.remove(option_widget) self.doc_widgets = [] self.doc_options = None if not self.doc_option_class: return # this docgen type has no options self.init_doc_options(self.doc_option_class) menu = self.doc_options.menu for name in menu.get_option_names('Document Options'): option = menu.get_option('Document Options', name) # override option default with xml-saved value: if name in self.doc_options.options_dict: option.set_value(self.doc_options.options_dict[name]) widget, has_label = make_gui_option(option, self.dbstate, self.uistate, self.track) if has_label: widget_text = Gtk.Label('%s:' % option.get_label()) widget_text.set_halign(Gtk.Align.START) self.grid.attach(widget_text, 1, self.row, 1, 1) self.doc_widgets.append(widget_text) self.grid.attach(widget, 2, self.row, 2, 1) self.doc_widgets.append(widget) self.row += 1 def init_doc_options(self, option_class): try: if (issubclass(option_class, object) or # New-style class isinstance(option_class, ClassType)): # Old-style class self.doc_options = option_class(self.raw_name, self.db) except TypeError: self.doc_options = option_class self.doc_options.load_previous_values() def parse_doc_options(self): """ Called to allow parsing of added docgen widgets. It is called when OK is pressed in a dialog. """ if not self.doc_options: return try: self.doc_options.parse_user_options() for opt in self.doc_options.options_dict: self.options.options_dict[opt] = \ [self.basedocname, self.doc_options.options_dict[opt]] except: logging.warning("Failed to parse doc options")
def __init__(self, name, style, parent): """ Create the StyleEditor. name - name of the style that is to be edited style - style object that is to be edited parent - StyleListDisplay object that called the editor """ self.current_style = None self.current_name = None self.style = StyleSheet(style) self.parent = parent self.top = Glade(toplevel='editor') self.window = self.top.toplevel self.top.connect_signals({ "on_save_style_clicked": self.on_save_style_clicked, "destroy_passed_object": self.__close, "on_ok_clicked": dummy_callback, "on_add_clicked": dummy_callback, "on_delete_clicked": dummy_callback, "on_button_press": dummy_callback, "on_edit_clicked": dummy_callback, }) self.pname = self.top.get_object('pname') self.pdescription = self.top.get_object('pdescription') self.notebook = self.top.get_object('notebook1') self.vbox = self.top.get_object('column_widths') self.line_style = self.top.get_object('line_style') line_styles = Gtk.ListStore(int, str) line_styles.append([0, "Solid"]) line_styles.append([1, "Dashed"]) line_styles.append([2, "Dotted"]) self.line_style.set_model(line_styles) renderer_text = Gtk.CellRendererText() self.line_style.pack_start(renderer_text, True) self.line_style.add_attribute(renderer_text, "text", 1) set_titles(self.window, self.top.get_object('title'), _('Style editor')) self.top.get_object("label6").set_text(_("point size|pt")) titles = [(_('Style'), 0, 130)] self.plist = ListModel(self.top.get_object("ptree"), titles, self.change_display) for widget_name in ('color', 'bgcolor', 'line_color', 'fill_color'): color = self.top.get_object(widget_name) label = self.top.get_object(widget_name + '_code') color.connect('notify::color', self.color_changed, label) self.top.get_object("style_name").set_text(name) def _alphanumeric_sort(iterable): """ sort the given iterable in the way that humans expect """ convert = lambda text: int(text) if text.isdigit() else text sort_key = lambda k: [convert(c) for c in re.split('([0-9]+)', k)] return sorted(iterable, key=sort_key) names = _alphanumeric_sort(self.style.get_paragraph_style_names()) for p_name in names: self.plist.add([p_name], self.style.get_paragraph_style(p_name)) names = _alphanumeric_sort(self.style.get_table_style_names()) for t_name in names: self.plist.add([t_name], self.style.get_table_style(t_name)) names = _alphanumeric_sort(self.style.get_cell_style_names()) for c_name in names: self.plist.add([c_name], self.style.get_cell_style(c_name)) names = _alphanumeric_sort(self.style.get_draw_style_names()) for d_name in names: self.plist.add([d_name], self.style.get_draw_style(d_name)) self.plist.select_row(0) if self.parent: self.window.set_transient_for(parent.window) self.window.run() self.window.destroy()
class ReportDialog(ManagedWindow): """ The ReportDialog base class. This is a base class for generating customized dialogs to solicit options for a report. It cannot be used as is, but it can be easily sub-classed to create a functional dialog for a stand-alone report. """ border_pad = 6 def __init__(self, dbstate, uistate, option_class, name, trans_name, track=[]): """Initialize a dialog to request that the user select options for a basic *stand-alone* report.""" self.style_name = "default" self.firstpage_added = False self.raw_name = name self.dbstate = dbstate self.uistate = uistate self.db = dbstate.db self.report_name = trans_name ManagedWindow.__init__(self, uistate, track, self) self.init_options(option_class) self.init_interface() def close(self, *obj): """ Close itself. cleanup things that can prevent garbage collection """ if hasattr(self, 'widgets'): # handle pathlogical bug 4145 totwidg = list(range(len(self.widgets))) totwidg.reverse() for ind in totwidg: if hasattr(self.widgets[ind][1], 'clean_up'): self.widgets[ind][1].clean_up() del self.widgets[ind] delattr(self, 'widgets') for name, fram in self.frames.items(): totwidg = list(range(len(fram))) totwidg.reverse() for ind in totwidg: if hasattr(fram[ind][1], 'clean_up'): fram[ind][1].clean_up() del fram[ind] self.frames.clear() self.frames = None ManagedWindow.close(self, *obj) def init_options(self, option_class): try: if issubclass(option_class, object): self.options = option_class(self.raw_name, self.db) except TypeError: self.options = option_class self.options.load_previous_values() def build_window_key(self, obj): key = self.raw_name return key def build_menu_names(self, obj): return (_("Configuration"), self.report_name) def init_interface(self): self.widgets = [] self.doc_widgets = [] self.frame_names = [] self.frames = {} self.format_menu = None self.style_button = None self.style_name = self.options.handler.get_default_stylesheet_name() window = Gtk.Dialog(title='Gramps') self.set_window(window, None, self.get_title()) self.window.set_modal(True) self.help = self.window.add_button(_('_Help'), Gtk.ResponseType.HELP) self.help.connect('clicked', self.on_help_clicked) self.cancel = self.window.add_button(_('_Cancel'), Gtk.ResponseType.CANCEL) self.cancel.connect('clicked', self.on_cancel) self.ok = self.window.add_button(_('_OK'), Gtk.ResponseType.OK) self.ok.connect('clicked', self.on_ok_clicked) self.window.set_position(Gtk.WindowPosition.CENTER_ON_PARENT) self.window.set_default_size(600, -1) # Set up and run the dialog. These calls are not in top down # order when looking at the dialog box as there is some # interaction between the various frames. self.setup_title() self.setup_header() self.grid = Gtk.Grid() self.grid.set_column_spacing(12) self.grid.set_row_spacing(6) self.grid.set_border_width(6) self.row = 0 # Build the list of widgets that are used to extend the Options # frame and to create other frames self.add_user_options() self.setup_init() self.setup_format_frame() self.setup_target_frame() self.setup_style_frame() self.notebook = Gtk.Notebook() self.notebook.set_scrollable(True) self.notebook.set_border_width(6) try: #assume a vbox or hbox self.window.vbox.pack_start(self.notebook, expand=True, fill=True, padding=0) except: #general container instead: self.window.vbox.add(self.notebook) self.setup_report_options_frame() self.setup_other_frames() self.notebook.set_current_page(0) try: #assume a vbox or hbox self.window.vbox.pack_start(self.grid, expand=True, fill=True, padding=0) except: #general container instead: self.window.vbox.add(self.grid) self.show() def get_title(self): """The window title for this dialog""" name = self.report_name category = standalone_categories[self.category][1] return "%s - %s - Gramps" % (name, category) #------------------------------------------------------------------------ # # Functions related to extending the options # #------------------------------------------------------------------------ def add_user_options(self): """Called to allow subclasses to add widgets to the dialog form. It is called immediately before the window is displayed. All calls to add_option or add_frame_option should be called in this task.""" add_gui_options(self) def parse_user_options(self): """Called to allow parsing of added widgets. It is called when OK is pressed in a dialog. All custom widgets should provide a parsing code here.""" try: self.options.parse_user_options() except: LOG.error("Failed to parse user options.", exc_info=True) def add_option(self, label_text, widget): """Takes a text string and a Gtk Widget, and stores them to be appended to the Options section of the dialog. The text string is used to create a label for the passed widget. This allows the subclass to extend the Options section with its own widgets. The subclass is responsible for all managing of the widgets, including extracting the final value before the report executes. This task should only be called in the add_user_options task.""" self.widgets.append((label_text, widget)) def add_frame_option(self, frame_name, label_text, widget): """Similar to add_option this method takes a frame_name, a text string and a Gtk Widget. When the interface is built, all widgets with the same frame_name are grouped into a GtkFrame. This allows the subclass to create its own sections, filling them with its own widgets. The subclass is responsible for all managing of the widgets, including extracting the final value before the report executes. This task should only be called in the add_user_options task.""" if frame_name in self.frames: self.frames[frame_name].append((label_text, widget)) else: self.frames[frame_name] = [(label_text, widget)] self.frame_names.append(frame_name) #------------------------------------------------------------------------ # # Functions to create a default output style. # #------------------------------------------------------------------------ def build_style_menu(self, default=None): """Build a menu of style sets that are available for use in this report. This menu will always have a default style available, and will have any other style set name that the user has previously created for this report. This menu is created here instead of inline with the rest of the style frame, because it must be recreated to reflect any changes whenever the user closes the style editor dialog.""" if default is None: default = self.style_name style_sheet_map = self.style_sheet_list.get_style_sheet_map() self.style_menu.set(style_sheet_map, default) #------------------------------------------------------------------------ # # Functions related to setting up the dialog window. # #------------------------------------------------------------------------ def setup_title(self): """Set up the title bar of the dialog. This function relies on the get_title() customization function for what the title should be.""" self.window.set_title(self.get_title()) def setup_header(self): """Set up the header line bar of the dialog.""" label = Gtk.Label(label='<span size="larger" weight="bold">%s</span>' % self.report_name) label.set_use_markup(True) self.window.vbox.pack_start(label, False, False, self.border_pad) def setup_style_frame(self): """Set up the style frame of the dialog. This function relies on other routines to create the default style for this report, and to read in any user-defined styles for this report. It then builds a menu of all the available styles for the user to choose from.""" # Build the default style set for this report. self.default_style = StyleSheet() self.options.make_default_style(self.default_style) if self.default_style.is_empty(): # Don't display the option if no styles are used return # Styles Frame label = Gtk.Label(label=_("%s:") % _("Style")) label.set_halign(Gtk.Align.START) self.style_menu = StyleComboBox() self.style_menu.set_hexpand(True) self.style_button = Gtk.Button(label="%s..." % _("Style Editor")) self.style_button.connect('clicked', self.on_style_edit_clicked) self.grid.attach(label, 1, self.row, 1, 1) self.grid.attach(self.style_menu, 2, self.row, 1, 1) self.grid.attach(self.style_button, 3, self.row, 1, 1) self.row += 1 # Build the initial list of available styles sets. This # includes the default style set and any style sets saved from # previous invocations of gramps. self.style_sheet_list = StyleSheetList( self.options.handler.get_stylesheet_savefile(), self.default_style) # Now build the actual menu. style = self.options.handler.get_default_stylesheet_name() self.build_style_menu(style) def setup_report_options_frame(self): """Set up the report options frame of the dialog. This function relies on several report_xxx() customization functions to determine which of the items should be present in this box. *All* of these items are optional, although the generations fields is used in most (but not all) dialog boxes.""" row = 0 max_rows = len(self.widgets) if max_rows == 0: return grid = Gtk.Grid() grid.set_border_width(6) grid.set_column_spacing(12) grid.set_row_spacing(6) label = Gtk.Label(label="<b>%s</b>" % _("Report Options")) label.set_halign(Gtk.Align.START) label.set_use_markup(True) self.notebook.append_page(grid, label) # Setup requested widgets for (text, widget) in self.widgets: widget.set_hexpand(True) if text: # translators: needed for French, ignore otherwise text_widget = Gtk.Label(label=_("%s:") % text) text_widget.set_halign(Gtk.Align.START) grid.attach(text_widget, 1, row, 1, 1) grid.attach(widget, 2, row, 1, 1) else: grid.attach(widget, 2, row, 1, 1) row += 1 def setup_other_frames(self): from .._guioptions import GuiTextOption for key in self.frame_names: flist = self.frames[key] grid = Gtk.Grid() grid.set_column_spacing(12) grid.set_row_spacing(6) grid.set_border_width(6) l = Gtk.Label(label="<b>%s</b>" % _(key)) l.set_use_markup(True) self.notebook.append_page(grid, l) row = 0 for (text, widget) in flist: widget.set_hexpand(True) if text: text_widget = Gtk.Label(label=_('%s:') % text) text_widget.set_halign(Gtk.Align.START) grid.attach(text_widget, 1, row, 1, 1) if isinstance(widget, GuiTextOption): grid.attach(widget, 2, row, 1, 1) else: grid.attach(widget, 2, row, 1, 1) else: grid.attach(widget, 2, row, 1, 1) row += 1 #------------------------------------------------------------------------ # # Customization hooks for stand-alone reports (subclass ReportDialog) # #------------------------------------------------------------------------ def setup_format_frame(self): """Not used in bare report dialogs. Override in the subclass.""" pass #------------------------------------------------------------------------ # # Functions related getting/setting the default directory for a dialog. # #------------------------------------------------------------------------ def get_default_directory(self): """Get the name of the directory to which the target dialog box should default. This value can be set in the preferences panel.""" return config.get('paths.report-directory') def set_default_directory(self, value): """Save the name of the current directory, so that any future reports will default to the most recently used directory. This also changes the directory name that will appear in the preferences panel, but does not change the preference in disk. This means that the last directory used will only be remembered for this session of gramps unless the user saves his/her preferences.""" config.set('paths.report-directory', value) #------------------------------------------------------------------------ # # Functions related to setting up the dialog window. # #------------------------------------------------------------------------ def setup_init(self): # add any elements that we are going to need: hid = self.style_name if hid[-4:] == ".xml": hid = hid[0:-4] self.target_fileentry = FileEntry(hid, _("Save As"), parent=self.window) spath = self.get_default_directory() self.target_fileentry.set_filename(spath) # need any labels at top: label = Gtk.Label(label="<b>%s</b>" % _('Document Options')) label.set_use_markup(1) label.set_halign(Gtk.Align.START) self.grid.set_border_width(12) self.grid.attach(label, 0, self.row, 4, 1) self.row += 1 def setup_target_frame(self): """Set up the target frame of the dialog. This function relies on several target_xxx() customization functions to determine whether the target is a directory or file, what the title of any browser window should be, and what default directory should be used.""" # Save Frame self.doc_label = Gtk.Label(label=_("%s:") % _("Filename")) self.doc_label.set_halign(Gtk.Align.START) self.grid.attach(self.doc_label, 1, self.row, 1, 1) self.target_fileentry.set_hexpand(True) self.grid.attach(self.target_fileentry, 2, self.row, 2, 1) self.row += 1 #------------------------------------------------------------------------ # # Functions related to retrieving data from the dialog window # #------------------------------------------------------------------------ def parse_target_frame(self): """Parse the target frame of the dialog. If the target filename is empty this routine returns a special value of None to tell the calling routine to give up. This function also saves the current directory so that any future reports will default to the most recently used directory.""" self.target_path = self.target_fileentry.get_full_path(0) if not self.target_path: return None # First we check whether the selected path exists if os.path.exists(self.target_path): # selected path is an existing dir and we need a dir if os.path.isdir(self.target_path): # check whether the dir has rwx permissions if not os.access(self.target_path, os.R_OK | os.W_OK | os.X_OK): ErrorDialog(_('Permission problem'), _("You do not have permission to write " "under the directory %s\n\n" "Please select another directory or correct " "the permissions.") % self.target_path, parent=self.window) return None # selected path is an existing file and we need a file if os.path.isfile(self.target_path): aaa = OptionDialog(_('File already exists'), _('You can choose to either overwrite the ' 'file, or change the selected filename.'), _('_Overwrite'), None, _('_Change filename'), None, parent=self.window) if aaa.get_response() == Gtk.ResponseType.YES: return None # selected path does not exist yet else: # we will need to create the file/dir # need to make sure we can create in the parent dir parent_dir = os.path.dirname(os.path.normpath(self.target_path)) if os.path.isdir(parent_dir): if not os.access(parent_dir, os.W_OK): ErrorDialog(_('Permission problem'), _("You do not have permission to create " "%s\n\n" "Please select another path or correct " "the permissions.") % self.target_path, parent=self.window) return None else: ErrorDialog(_('No directory'), _('There is no directory %s.\n\n' 'Please select another directory ' 'or create it.') % parent_dir, parent=self.window) return None self.set_default_directory(os.path.dirname(self.target_path) + os.sep) self.options.handler.output = self.target_path return 1 def parse_style_frame(self): """Parse the style frame of the dialog. Save the user selected output style for later use. Note that this routine retrieves a value whether or not the menu is displayed on the screen. The subclass will know whether this menu was enabled. This is for simplicity of programming.""" if not self.default_style.is_empty(): (style_name, self.selected_style) = self.style_menu.get_value() self.options.handler.set_default_stylesheet_name(style_name) #------------------------------------------------------------------------ # # Callback functions from the dialog # #------------------------------------------------------------------------ def on_ok_clicked(self, obj): """The user is satisfied with the dialog choices. Validate the output file name before doing anything else. If there is a file name, gather the options and create the report.""" # Is there a filename? This should also test file permissions, etc. if not self.parse_target_frame(): self.window.run() # Preparation self.parse_style_frame() self.parse_user_options() # Save options self.options.handler.save_options() def on_cancel(self, *obj): pass def on_help_clicked(self, *obj): from ...display import display_help display_help(URL_REPORT_PAGE, self.report_name.replace(" ", "_")) def on_style_edit_clicked(self, *obj): """The user has clicked on the 'Edit Styles' button. Create a style sheet editor object and let them play. When they are done, the previous routine will be called to update the dialog menu for selecting a style.""" StyleListDisplay(self.style_sheet_list, self.uistate, self.track, callback=self.build_style_menu) #---------------------------------------------------------------------- # # Functions related to any docgen options for a dialog. # #---------------------------------------------------------------------- def setup_doc_options_frame(self): if self.doc_widgets: for option_widget in self.doc_widgets: self.grid.remove(option_widget) self.doc_widgets = [] self.doc_options = None if not self.doc_option_class: return # this docgen type has no options self.init_doc_options(self.doc_option_class) menu = self.doc_options.menu for name in menu.get_option_names(DOCGEN_OPTIONS): option = menu.get_option(DOCGEN_OPTIONS, name) # override option default with xml-saved value: if name in self.doc_options.options_dict: option.set_value(self.doc_options.options_dict[name]) widget, has_label = make_gui_option(option, self.dbstate, self.uistate, self.track) if has_label: widget_text = Gtk.Label(label=(_('%s:') % option.get_label())) widget_text.set_halign(Gtk.Align.START) self.grid.attach(widget_text, 1, self.row, 1, 1) self.doc_widgets.append(widget_text) self.grid.attach(widget, 2, self.row, 2, 1) self.doc_widgets.append(widget) self.row += 1 def init_doc_options(self, option_class): try: if issubclass(option_class, object): self.doc_options = option_class(self.raw_name, self.db) except TypeError: self.doc_options = option_class self.doc_options.load_previous_values() def parse_doc_options(self): """ Called to allow parsing of added docgen widgets. It is called when OK is pressed in a dialog. """ if not self.doc_options: return try: self.doc_options.parse_user_options() for opt in self.doc_options.options_dict: self.options.options_dict[opt] = \ [self.basedocname, self.doc_options.options_dict[opt]] except: logging.warning("Failed to parse doc options")
def __init__(self, name, style, parent): """ Create the StyleEditor. name - name of the style that is to be edited style - style object to be edited: a :class:`.StyleSheet` instance parent - StyleListDisplay object that called the editor """ ManagedWindow.__init__(self, parent.uistate, parent.track, self.__class__, modal=True) # the self.window.run() below makes Gtk make it modal, so any change # to the previous line's "modal" would require that line to be changed self.current_style = None self.current_name = None self.style = StyleSheet(style) self.parent = parent self.top = Glade( toplevel='editor', also_load=[ "adjustment1", "adjustment2", "adjustment3", "adjustment4", "adjustment5", "adjustment6", "adjustment7", "adjustment8", "adjustment9", "adjustment10", "adjustment11"]) self.set_window(self.top.toplevel, self.top.get_object('title'), _('Style editor')) self.setup_configs('interface.styleeditor', 550, 610) self.show() self.top.connect_signals({ "on_save_style_clicked" : self.on_save_style_clicked, "on_cancel_style_clicked" : self.__cancel, "on_help_btn_style_clicked" : lambda x: display_help( WIKI_HELP_PAGE, _('manual|Style_editor_dialog')), "on_cancel_clicked" : dummy_callback, "on_ok_clicked" : dummy_callback, "on_add_clicked" : dummy_callback, "on_delete_clicked" : dummy_callback, "on_button_press" : dummy_callback, "on_edit_clicked" : dummy_callback, "on_help_btn_clicked" : dummy_callback, }) self.pname = self.top.get_object('pname') self.pdescription = self.top.get_object('pdescription') self.notebook = self.top.get_object('notebook1') self.vbox = self.top.get_object('column_widths') self.line_style = self.top.get_object('line_style') line_styles = Gtk.ListStore(int, str) line_styles.append([0, "Solid"]) line_styles.append([1, "Dashed"]) line_styles.append([2, "Dotted"]) self.line_style.set_model(line_styles) renderer_text = Gtk.CellRendererText() self.line_style.pack_start(renderer_text, True) self.line_style.add_attribute(renderer_text, "text", 1) self.top.get_object("label6").set_text(_("point size|pt")) titles = [(_('Style'), 0, 130)] self.plist = ListModel(self.top.get_object("ptree"), titles, self.change_display) for widget_name in ('color', 'bgcolor', 'line_color', 'fill_color'): color = self.top.get_object(widget_name) label = self.top.get_object(widget_name + '_code') color.connect('notify::color', self.color_changed, label) self.top.get_object("style_name").set_text(name) def _alphanumeric_sort(iterable): """ sort the given iterable in the way that humans expect """ convert = lambda text: int(text) if text.isdigit() else text sort_key = lambda k: [convert(c) for c in re.split('([0-9]+)', k)] return sorted(iterable, key=sort_key) names = _alphanumeric_sort(self.style.get_paragraph_style_names()) for p_name in names: self.plist.add([p_name], self.style.get_paragraph_style(p_name)) names = _alphanumeric_sort(self.style.get_table_style_names()) for t_name in names: self.plist.add([t_name], self.style.get_table_style(t_name)) names = _alphanumeric_sort(self.style.get_cell_style_names()) for c_name in names: self.plist.add([c_name], self.style.get_cell_style(c_name)) names = _alphanumeric_sort(self.style.get_draw_style_names()) for d_name in names: self.plist.add([d_name], self.style.get_draw_style(d_name)) self.plist.select_row(0) # the self.window.run() makes Gtk make it modal, so any change to that # line would require the ManagedWindow.__init__ to be changed also self.window.run() if self.opened: self.close()
def __init__(self, name, style, parent): """ Create the StyleEditor. name - name of the style that is to be edited style - style object to be edited: a :class:`.StyleSheet` instance parent - StyleListDisplay object that called the editor """ ManagedWindow.__init__(self, parent.uistate, parent.track, self.__class__, modal=True) # the self.window.run() below makes Gtk make it modal, so any change # to the previous line's "modal" would require that line to be changed self.current_style = None self.current_name = None self.style = StyleSheet(style) self.parent = parent self.top = Glade(toplevel='editor') self.set_window(self.top.toplevel, self.top.get_object('title'), _('Style editor')) self.setup_configs('interface.styleeditor', 550, 610) self.show() self.top.connect_signals({ "on_save_style_clicked": self.on_save_style_clicked, "on_cancel_style_clicked": self.__cancel, "on_cancel_clicked": dummy_callback, "on_ok_clicked": dummy_callback, "on_add_clicked": dummy_callback, "on_delete_clicked": dummy_callback, "on_button_press": dummy_callback, "on_edit_clicked": dummy_callback, }) self.pname = self.top.get_object('pname') self.pdescription = self.top.get_object('pdescription') self.notebook = self.top.get_object('notebook1') self.vbox = self.top.get_object('column_widths') self.line_style = self.top.get_object('line_style') line_styles = Gtk.ListStore(int, str) line_styles.append([0, "Solid"]) line_styles.append([1, "Dashed"]) line_styles.append([2, "Dotted"]) self.line_style.set_model(line_styles) renderer_text = Gtk.CellRendererText() self.line_style.pack_start(renderer_text, True) self.line_style.add_attribute(renderer_text, "text", 1) self.top.get_object("label6").set_text(_("point size|pt")) titles = [(_('Style'), 0, 130)] self.plist = ListModel(self.top.get_object("ptree"), titles, self.change_display) for widget_name in ('color', 'bgcolor', 'line_color', 'fill_color'): color = self.top.get_object(widget_name) label = self.top.get_object(widget_name + '_code') color.connect('notify::color', self.color_changed, label) self.top.get_object("style_name").set_text(name) def _alphanumeric_sort(iterable): """ sort the given iterable in the way that humans expect """ convert = lambda text: int(text) if text.isdigit() else text sort_key = lambda k: [convert(c) for c in re.split('([0-9]+)', k)] return sorted(iterable, key=sort_key) names = _alphanumeric_sort(self.style.get_paragraph_style_names()) for p_name in names: self.plist.add([p_name], self.style.get_paragraph_style(p_name)) names = _alphanumeric_sort(self.style.get_table_style_names()) for t_name in names: self.plist.add([t_name], self.style.get_table_style(t_name)) names = _alphanumeric_sort(self.style.get_cell_style_names()) for c_name in names: self.plist.add([c_name], self.style.get_cell_style(c_name)) names = _alphanumeric_sort(self.style.get_draw_style_names()) for d_name in names: self.plist.add([d_name], self.style.get_draw_style(d_name)) self.plist.select_row(0) # the self.window.run() makes Gtk make it modal, so any change to that # line would require the ManagedWindow.__init__ to be changed also self.window.run() if self.opened: self.close()
class StyleEditor: """ Edits the current style definition. Presents a dialog allowing the values of the paragraphs in the style to be altered. """ def __init__(self, name, style, parent): """ Create the StyleEditor. name - name of the style that is to be edited style - style object that is to be edited parent - StyleListDisplay object that called the editor """ self.current_style = None self.current_name = None self.style = StyleSheet(style) self.parent = parent self.top = Glade(toplevel='editor') self.window = self.top.toplevel self.top.connect_signals({ "on_save_style_clicked" : self.on_save_style_clicked, "destroy_passed_object" : self.__close, "on_ok_clicked" : dummy_callback, "on_add_clicked" : dummy_callback, "on_delete_clicked" : dummy_callback, "on_button_press" : dummy_callback, "on_edit_clicked" : dummy_callback, }) self.pname = self.top.get_object('pname') self.pdescription = self.top.get_object('pdescription') self.notebook = self.top.get_object('notebook1') self.vbox = self.top.get_object('column_widths') self.line_style = self.top.get_object('line_style') line_styles = Gtk.ListStore(int, str) line_styles.append([0, "Solid"]) line_styles.append([1, "Dashed"]) line_styles.append([2, "Dotted"]) self.line_style.set_model(line_styles) renderer_text = Gtk.CellRendererText() self.line_style.pack_start(renderer_text, True) self.line_style.add_attribute(renderer_text, "text", 1) set_titles(self.window, self.top.get_object('title'), _('Style editor')) self.top.get_object("label6").set_text(_("point size|pt")) titles = [(_('Style'), 0, 130)] self.plist = ListModel(self.top.get_object("ptree"), titles, self.change_display) for widget_name in ('color', 'bgcolor', 'line_color', 'fill_color'): color = self.top.get_object(widget_name) label = self.top.get_object(widget_name + '_code') color.connect('notify::color', self.color_changed, label) self.top.get_object("style_name").set_text(name) def _alphanumeric_sort(iterable): """ sort the given iterable in the way that humans expect """ convert = lambda text: int(text) if text.isdigit() else text sort_key = lambda k: [convert(c) for c in re.split('([0-9]+)', k)] return sorted(iterable, key=sort_key) names = _alphanumeric_sort(self.style.get_paragraph_style_names()) for p_name in names: self.plist.add([p_name], self.style.get_paragraph_style(p_name)) names = _alphanumeric_sort(self.style.get_table_style_names()) for t_name in names: self.plist.add([t_name], self.style.get_table_style(t_name)) names = _alphanumeric_sort(self.style.get_cell_style_names()) for c_name in names: self.plist.add([c_name], self.style.get_cell_style(c_name)) names = _alphanumeric_sort(self.style.get_draw_style_names()) for d_name in names: self.plist.add([d_name], self.style.get_draw_style(d_name)) self.plist.select_row(0) if self.parent: self.window.set_transient_for(parent.window) self.window.run() self.window.destroy() def __close(self, obj): self.window.destroy() def show_pages(self, show_pages): """ Make the given pages visible. """ for page_num in range(self.notebook.get_n_pages()): page = self.notebook.get_nth_page(page_num) if page_num in show_pages: page.show() else: page.hide() def draw(self): """ Updates the display with the selected style. """ if isinstance(self.current_style, ParagraphStyle): self.show_pages([0, 1, 2]) self.draw_paragraph() elif isinstance(self.current_style, TableStyle): self.show_pages([0, 3]) self.draw_table() elif isinstance(self.current_style, TableCellStyle): self.show_pages([0, 4]) self.draw_cell() elif isinstance(self.current_style, GraphicsStyle): self.show_pages([0, 5]) self.draw_graphics() def draw_graphics(self): """ Updates the display with the selected graphics style. """ g = self.current_style self.pname.set_text( '<span size="larger" weight="bold">%s</span>' % self.current_name) self.pname.set_use_markup(True) self.pdescription.set_text(_("No description available") ) self.top.get_object("line_style").set_active(g.get_line_style()) self.top.get_object("line_width").set_value(g.get_line_width()) self.line_color = rgb2color(g.get_color()) self.top.get_object("line_color").set_color(self.line_color) self.fill_color = rgb2color(g.get_fill_color()) self.top.get_object("fill_color").set_color(self.fill_color) self.top.get_object("shadow").set_active(g.get_shadow()) self.top.get_object("shadow_space").set_value(g.get_shadow_space()) def draw_cell(self): """ Updates the display with the selected cell style. """ c = self.current_style self.pname.set_text( '<span size="larger" weight="bold">%s</span>' % self.current_name) self.pname.set_use_markup(True) self.pdescription.set_text(_("No description available") ) self.top.get_object("cell_lborder").set_active(c.get_left_border()) self.top.get_object("cell_rborder").set_active(c.get_right_border()) self.top.get_object("cell_tborder").set_active(c.get_top_border()) self.top.get_object("cell_bborder").set_active(c.get_bottom_border()) self.top.get_object("cell_padding").set_value(c.get_padding()) def draw_table(self): """ Updates the display with the selected table style. """ t = self.current_style self.pname.set_text( '<span size="larger" weight="bold">%s</span>' % self.current_name) self.pname.set_use_markup(True) self.pdescription.set_text(_("No description available") ) self.top.get_object("table_width").set_value(t.get_width()) self.column = [] for widget in self.vbox.get_children(): self.vbox.remove(widget) for i in range(t.get_columns()): hbox = Gtk.Box() label = Gtk.Label(label=_('Column %d:') % (i + 1)) hbox.pack_start(label, False, False, 6) spin = Gtk.SpinButton() spin.set_range(0, 100) spin.set_increments(1, 10) spin.set_numeric(True) spin.set_value(t.get_column_width(i)) self.column.append(spin) hbox.pack_start(spin, False, False, 6) hbox.pack_start(Gtk.Label('%'), False, False, 6) hbox.show_all() self.vbox.pack_start(hbox, False, False, 3) def draw_paragraph(self): """ Updates the display with the selected paragraph style. """ p = self.current_style self.pname.set_text( '<span size="larger" weight="bold">%s</span>' % self.current_name) self.pname.set_use_markup(True) descr = p.get_description() self.pdescription.set_text(descr or _("No description available") ) font = p.get_font() self.top.get_object("size").set_value(font.get_size()) if font.get_type_face() == FONT_SERIF: self.top.get_object("roman").set_active(1) else: self.top.get_object("swiss").set_active(1) self.top.get_object("bold").set_active(font.get_bold()) self.top.get_object("italic").set_active(font.get_italic()) self.top.get_object("underline").set_active(font.get_underline()) if p.get_alignment() == PARA_ALIGN_LEFT: self.top.get_object("lalign").set_active(1) elif p.get_alignment() == PARA_ALIGN_RIGHT: self.top.get_object("ralign").set_active(1) elif p.get_alignment() == PARA_ALIGN_CENTER: self.top.get_object("calign").set_active(1) else: self.top.get_object("jalign").set_active(1) self.top.get_object("rmargin").set_value(p.get_right_margin()) self.top.get_object("lmargin").set_value(p.get_left_margin()) self.top.get_object("pad").set_value(p.get_padding()) self.top.get_object("tmargin").set_value(p.get_top_margin()) self.top.get_object("bmargin").set_value(p.get_bottom_margin()) self.top.get_object("indent").set_value(p.get_first_indent()) self.top.get_object("tborder").set_active(p.get_top_border()) self.top.get_object("lborder").set_active(p.get_left_border()) self.top.get_object("rborder").set_active(p.get_right_border()) self.top.get_object("bborder").set_active(p.get_bottom_border()) color = rgb2color(font.get_color()) self.top.get_object("color").set_color(color) bg_color = rgb2color(p.get_background_color()) self.top.get_object("bgcolor").set_color(bg_color) def color_changed(self, color, name, label): """ Called to set the color code when a color is changed. """ rgb = color2rgb(color.get_color()) label.set_text("#%02X%02X%02X" % color2rgb(color.get_color())) def save(self): """ Saves the current style displayed on the dialog. """ if isinstance(self.current_style, ParagraphStyle): self.save_paragraph() elif isinstance(self.current_style, TableStyle): self.save_table() elif isinstance(self.current_style, TableCellStyle): self.save_cell() elif isinstance(self.current_style, GraphicsStyle): self.save_graphics() def save_graphics(self): """ Saves the current graphics style displayed on the dialog. """ g = self.current_style g.set_line_style(self.top.get_object("line_style").get_active()) g.set_line_width(self.top.get_object("line_width").get_value()) line_color = self.top.get_object("line_color").get_color() g.set_color(color2rgb(line_color)) fill_color = self.top.get_object("fill_color").get_color() g.set_fill_color(color2rgb(fill_color)) shadow = self.top.get_object("shadow").get_active() shadow_space = self.top.get_object("shadow_space").get_value() g.set_shadow(shadow, shadow_space) self.style.add_draw_style(self.current_name, self.current_style) def save_cell(self): """ Saves the current cell style displayed on the dialog. """ c = self.current_style c.set_left_border(self.top.get_object("cell_lborder").get_active()) c.set_right_border(self.top.get_object("cell_rborder").get_active()) c.set_top_border(self.top.get_object("cell_tborder").get_active()) c.set_bottom_border(self.top.get_object("cell_bborder").get_active()) c.set_padding(self.top.get_object("cell_padding").get_value()) self.style.add_cell_style(self.current_name, self.current_style) def save_table(self): """ Saves the current table style displayed on the dialog. """ t = self.current_style t.set_width(self.top.get_object("table_width").get_value_as_int()) for i in range(t.get_columns()): t.set_column_width(i, self.column[i].get_value_as_int()) self.style.add_table_style(self.current_name, self.current_style) def save_paragraph(self): """ Saves the current paragraph style displayed on the dialog. """ p = self.current_style font = p.get_font() font.set_size(self.top.get_object("size").get_value_as_int()) if self.top.get_object("roman").get_active(): font.set_type_face(FONT_SERIF) else: font.set_type_face(FONT_SANS_SERIF) font.set_bold(self.top.get_object("bold").get_active()) font.set_italic(self.top.get_object("italic").get_active()) font.set_underline(self.top.get_object("underline").get_active()) if self.top.get_object("lalign").get_active(): p.set_alignment(PARA_ALIGN_LEFT) elif self.top.get_object("ralign").get_active(): p.set_alignment(PARA_ALIGN_RIGHT) elif self.top.get_object("calign").get_active(): p.set_alignment(PARA_ALIGN_CENTER) else: p.set_alignment(PARA_ALIGN_JUSTIFY) p.set_right_margin(self.top.get_object("rmargin").get_value()) p.set_left_margin(self.top.get_object("lmargin").get_value()) p.set_top_margin(self.top.get_object("tmargin").get_value()) p.set_bottom_margin(self.top.get_object("bmargin").get_value()) p.set_padding(self.top.get_object("pad").get_value()) p.set_first_indent(self.top.get_object("indent").get_value()) p.set_top_border(self.top.get_object("tborder").get_active()) p.set_left_border(self.top.get_object("lborder").get_active()) p.set_right_border(self.top.get_object("rborder").get_active()) p.set_bottom_border(self.top.get_object("bborder").get_active()) color = self.top.get_object("color").get_color() font.set_color(color2rgb(color)) bg_color = self.top.get_object("bgcolor").get_color() p.set_background_color(color2rgb(bg_color)) self.style.add_paragraph_style(self.current_name, self.current_style) def on_save_style_clicked(self, obj): """ Saves the current style sheet and causes the parent to be updated with the changes. """ name = str(self.top.get_object("style_name").get_text()) self.save() self.style.set_name(name) self.parent.sheetlist.set_style_sheet(name, self.style) self.parent.redraw() self.window.destroy() def change_display(self, obj): """ Called when the paragraph selection has been changed. Saves the old paragraph, then draws the newly selected paragraph. """ # Don't save until current_name is defined # If it's defined, save under the current paragraph name if self.current_name: self.save() # Then change to new paragraph objs = self.plist.get_selected_objects() store, node = self.plist.get_selected() self.current_name = store.get_value(node, 0) self.current_style = objs[0] self.draw()
class StyleEditor(object): """ Edits the current style definition. Presents a dialog allowing the values of the paragraphs in the style to be altered. """ def __init__(self, name, style, parent): """ Create the StyleEditor. name - name of the style that is to be edited style - style object that is to be edited parent - StyleListDisplay object that called the editor """ self.current_style = None self.current_name = None self.style = StyleSheet(style) self.parent = parent self.top = Glade(toplevel='editor') self.window = self.top.toplevel self.top.connect_signals({ "on_save_style_clicked": self.on_save_style_clicked, "destroy_passed_object": self.__close, "on_ok_clicked": dummy_callback, "on_add_clicked": dummy_callback, "on_delete_clicked": dummy_callback, "on_button_press": dummy_callback, "on_edit_clicked": dummy_callback, }) self.pname = self.top.get_object('pname') self.pdescription = self.top.get_object('pdescription') self.notebook = self.top.get_object('notebook1') self.vbox = self.top.get_object('column_widths') self.line_style = self.top.get_object('line_style') line_styles = Gtk.ListStore(int, str) line_styles.append([0, "Solid"]) line_styles.append([1, "Dashed"]) line_styles.append([2, "Dotted"]) self.line_style.set_model(line_styles) renderer_text = Gtk.CellRendererText() self.line_style.pack_start(renderer_text, True) self.line_style.add_attribute(renderer_text, "text", 1) set_titles(self.window, self.top.get_object('title'), _('Style editor')) self.top.get_object("label6").set_text(_("point size|pt")) titles = [(_('Style'), 0, 130)] self.plist = ListModel(self.top.get_object("ptree"), titles, self.change_display) for widget_name in ('color', 'bgcolor', 'line_color', 'fill_color'): color = self.top.get_object(widget_name) label = self.top.get_object(widget_name + '_code') color.connect('notify::color', self.color_changed, label) self.top.get_object("style_name").set_text(name) def _alphanumeric_sort(iterable): """ sort the given iterable in the way that humans expect """ convert = lambda text: int(text) if text.isdigit() else text sort_key = lambda k: [convert(c) for c in re.split('([0-9]+)', k)] return sorted(iterable, key=sort_key) names = _alphanumeric_sort(self.style.get_paragraph_style_names()) for p_name in names: self.plist.add([p_name], self.style.get_paragraph_style(p_name)) names = _alphanumeric_sort(self.style.get_table_style_names()) for t_name in names: self.plist.add([t_name], self.style.get_table_style(t_name)) names = _alphanumeric_sort(self.style.get_cell_style_names()) for c_name in names: self.plist.add([c_name], self.style.get_cell_style(c_name)) names = _alphanumeric_sort(self.style.get_draw_style_names()) for d_name in names: self.plist.add([d_name], self.style.get_draw_style(d_name)) self.plist.select_row(0) if self.parent: self.window.set_transient_for(parent.window) self.window.run() self.window.destroy() def __close(self, obj): self.window.destroy() def show_pages(self, show_pages): """ Make the given pages visible. """ for page_num in range(self.notebook.get_n_pages()): page = self.notebook.get_nth_page(page_num) if page_num in show_pages: page.show() else: page.hide() def draw(self): """ Updates the display with the selected style. """ if isinstance(self.current_style, ParagraphStyle): self.show_pages([0, 1, 2]) self.draw_paragraph() elif isinstance(self.current_style, TableStyle): self.show_pages([0, 3]) self.draw_table() elif isinstance(self.current_style, TableCellStyle): self.show_pages([0, 4]) self.draw_cell() elif isinstance(self.current_style, GraphicsStyle): self.show_pages([0, 5]) self.draw_graphics() def draw_graphics(self): """ Updates the display with the selected graphics style. """ g = self.current_style self.pname.set_text('<span size="larger" weight="bold">%s</span>' % self.current_name) self.pname.set_use_markup(True) self.pdescription.set_text(_("No description available")) self.top.get_object("line_style").set_active(g.get_line_style()) self.top.get_object("line_width").set_value(g.get_line_width()) self.line_color = rgb2color(g.get_color()) self.top.get_object("line_color").set_color(self.line_color) self.fill_color = rgb2color(g.get_fill_color()) self.top.get_object("fill_color").set_color(self.fill_color) self.top.get_object("shadow").set_active(g.get_shadow()) self.top.get_object("shadow_space").set_value(g.get_shadow_space()) def draw_cell(self): """ Updates the display with the selected cell style. """ c = self.current_style self.pname.set_text('<span size="larger" weight="bold">%s</span>' % self.current_name) self.pname.set_use_markup(True) self.pdescription.set_text(_("No description available")) self.top.get_object("cell_lborder").set_active(c.get_left_border()) self.top.get_object("cell_rborder").set_active(c.get_right_border()) self.top.get_object("cell_tborder").set_active(c.get_top_border()) self.top.get_object("cell_bborder").set_active(c.get_bottom_border()) self.top.get_object("cell_padding").set_value(c.get_padding()) def draw_table(self): """ Updates the display with the selected table style. """ t = self.current_style self.pname.set_text('<span size="larger" weight="bold">%s</span>' % self.current_name) self.pname.set_use_markup(True) self.pdescription.set_text(_("No description available")) self.top.get_object("table_width").set_value(t.get_width()) self.column = [] for widget in self.vbox.get_children(): self.vbox.remove(widget) for i in range(t.get_columns()): hbox = Gtk.Box() label = Gtk.Label(label=_('Column %d:') % (i + 1)) hbox.pack_start(label, False, False, 6) spin = Gtk.SpinButton() spin.set_range(0, 100) spin.set_increments(1, 10) spin.set_numeric(True) spin.set_value(t.get_column_width(i)) self.column.append(spin) hbox.pack_start(spin, False, False, 6) hbox.pack_start(Gtk.Label('%'), False, False, 6) hbox.show_all() self.vbox.pack_start(hbox, False, False, 3) def draw_paragraph(self): """ Updates the display with the selected paragraph style. """ p = self.current_style self.pname.set_text('<span size="larger" weight="bold">%s</span>' % self.current_name) self.pname.set_use_markup(True) descr = p.get_description() self.pdescription.set_text(descr or _("No description available")) font = p.get_font() self.top.get_object("size").set_value(font.get_size()) if font.get_type_face() == FONT_SERIF: self.top.get_object("roman").set_active(1) else: self.top.get_object("swiss").set_active(1) self.top.get_object("bold").set_active(font.get_bold()) self.top.get_object("italic").set_active(font.get_italic()) self.top.get_object("underline").set_active(font.get_underline()) if p.get_alignment() == PARA_ALIGN_LEFT: self.top.get_object("lalign").set_active(1) elif p.get_alignment() == PARA_ALIGN_RIGHT: self.top.get_object("ralign").set_active(1) elif p.get_alignment() == PARA_ALIGN_CENTER: self.top.get_object("calign").set_active(1) else: self.top.get_object("jalign").set_active(1) self.top.get_object("rmargin").set_value(p.get_right_margin()) self.top.get_object("lmargin").set_value(p.get_left_margin()) self.top.get_object("pad").set_value(p.get_padding()) self.top.get_object("tmargin").set_value(p.get_top_margin()) self.top.get_object("bmargin").set_value(p.get_bottom_margin()) self.top.get_object("indent").set_value(p.get_first_indent()) self.top.get_object("tborder").set_active(p.get_top_border()) self.top.get_object("lborder").set_active(p.get_left_border()) self.top.get_object("rborder").set_active(p.get_right_border()) self.top.get_object("bborder").set_active(p.get_bottom_border()) color = rgb2color(font.get_color()) self.top.get_object("color").set_color(color) bg_color = rgb2color(p.get_background_color()) self.top.get_object("bgcolor").set_color(bg_color) def color_changed(self, color, name, label): """ Called to set the color code when a color is changed. """ rgb = color2rgb(color.get_color()) label.set_text("#%02X%02X%02X" % color2rgb(color.get_color())) def save(self): """ Saves the current style displayed on the dialog. """ if isinstance(self.current_style, ParagraphStyle): self.save_paragraph() elif isinstance(self.current_style, TableStyle): self.save_table() elif isinstance(self.current_style, TableCellStyle): self.save_cell() elif isinstance(self.current_style, GraphicsStyle): self.save_graphics() def save_graphics(self): """ Saves the current graphics style displayed on the dialog. """ g = self.current_style g.set_line_style(self.top.get_object("line_style").get_active()) g.set_line_width(self.top.get_object("line_width").get_value()) line_color = self.top.get_object("line_color").get_color() g.set_color(color2rgb(line_color)) fill_color = self.top.get_object("fill_color").get_color() g.set_fill_color(color2rgb(fill_color)) shadow = self.top.get_object("shadow").get_active() shadow_space = self.top.get_object("shadow_space").get_value() g.set_shadow(shadow, shadow_space) self.style.add_draw_style(self.current_name, self.current_style) def save_cell(self): """ Saves the current cell style displayed on the dialog. """ c = self.current_style c.set_left_border(self.top.get_object("cell_lborder").get_active()) c.set_right_border(self.top.get_object("cell_rborder").get_active()) c.set_top_border(self.top.get_object("cell_tborder").get_active()) c.set_bottom_border(self.top.get_object("cell_bborder").get_active()) c.set_padding(self.top.get_object("cell_padding").get_value()) self.style.add_cell_style(self.current_name, self.current_style) def save_table(self): """ Saves the current table style displayed on the dialog. """ t = self.current_style t.set_width(self.top.get_object("table_width").get_value_as_int()) for i in range(t.get_columns()): t.set_column_width(i, self.column[i].get_value_as_int()) self.style.add_table_style(self.current_name, self.current_style) def save_paragraph(self): """ Saves the current paragraph style displayed on the dialog. """ p = self.current_style font = p.get_font() font.set_size(self.top.get_object("size").get_value_as_int()) if self.top.get_object("roman").get_active(): font.set_type_face(FONT_SERIF) else: font.set_type_face(FONT_SANS_SERIF) font.set_bold(self.top.get_object("bold").get_active()) font.set_italic(self.top.get_object("italic").get_active()) font.set_underline(self.top.get_object("underline").get_active()) if self.top.get_object("lalign").get_active(): p.set_alignment(PARA_ALIGN_LEFT) elif self.top.get_object("ralign").get_active(): p.set_alignment(PARA_ALIGN_RIGHT) elif self.top.get_object("calign").get_active(): p.set_alignment(PARA_ALIGN_CENTER) else: p.set_alignment(PARA_ALIGN_JUSTIFY) p.set_right_margin(self.top.get_object("rmargin").get_value()) p.set_left_margin(self.top.get_object("lmargin").get_value()) p.set_top_margin(self.top.get_object("tmargin").get_value()) p.set_bottom_margin(self.top.get_object("bmargin").get_value()) p.set_padding(self.top.get_object("pad").get_value()) p.set_first_indent(self.top.get_object("indent").get_value()) p.set_top_border(self.top.get_object("tborder").get_active()) p.set_left_border(self.top.get_object("lborder").get_active()) p.set_right_border(self.top.get_object("rborder").get_active()) p.set_bottom_border(self.top.get_object("bborder").get_active()) color = self.top.get_object("color").get_color() font.set_color(color2rgb(color)) bg_color = self.top.get_object("bgcolor").get_color() p.set_background_color(color2rgb(bg_color)) self.style.add_paragraph_style(self.current_name, self.current_style) def on_save_style_clicked(self, obj): """ Saves the current style sheet and causes the parent to be updated with the changes. """ name = str(self.top.get_object("style_name").get_text()) self.save() self.style.set_name(name) self.parent.sheetlist.set_style_sheet(name, self.style) self.parent.redraw() self.window.destroy() def change_display(self, obj): """ Called when the paragraph selection has been changed. Saves the old paragraph, then draws the newly selected paragraph. """ # Don't save until current_name is defined # If it's defined, save under the current paragraph name if self.current_name: self.save() # Then change to new paragraph objs = self.plist.get_selected_objects() store, node = self.plist.get_selected() self.current_name = store.get_value(node, 0) self.current_style = objs[0] self.draw()
def __init__(self, name, style, parent): """ Create the StyleEditor. name - name of the style that is to be edited style - style object that is to be edited parent - StyleListDisplay object that called the editor """ self.current_style = None self.current_name = None self.style = StyleSheet(style) self.parent = parent self.top = Glade(toplevel='editor') self.window = self.top.toplevel self.top.connect_signals({ "on_save_style_clicked" : self.on_save_style_clicked, "destroy_passed_object" : self.__close, "on_ok_clicked" : dummy_callback, "on_add_clicked" : dummy_callback, "on_delete_clicked" : dummy_callback, "on_button_press" : dummy_callback, "on_edit_clicked" : dummy_callback, }) self.pname = self.top.get_object('pname') self.pdescription = self.top.get_object('pdescription') self.notebook = self.top.get_object('notebook1') self.vbox = self.top.get_object('column_widths') self.line_style = self.top.get_object('line_style') line_styles = Gtk.ListStore(int, str) line_styles.append([0, "Solid"]) line_styles.append([1, "Dashed"]) line_styles.append([2, "Dotted"]) self.line_style.set_model(line_styles) renderer_text = Gtk.CellRendererText() self.line_style.pack_start(renderer_text, True) self.line_style.add_attribute(renderer_text, "text", 1) set_titles(self.window, self.top.get_object('title'), _('Style editor')) self.top.get_object("label6").set_text(_("point size|pt")) titles = [(_('Style'), 0, 130)] self.plist = ListModel(self.top.get_object("ptree"), titles, self.change_display) for widget_name in ('color', 'bgcolor', 'line_color', 'fill_color'): color = self.top.get_object(widget_name) label = self.top.get_object(widget_name + '_code') color.connect('notify::color', self.color_changed, label) self.top.get_object("style_name").set_text(name) def _alphanumeric_sort(iterable): """ sort the given iterable in the way that humans expect """ convert = lambda text: int(text) if text.isdigit() else text sort_key = lambda k: [convert(c) for c in re.split('([0-9]+)', k)] return sorted(iterable, key=sort_key) names = _alphanumeric_sort(self.style.get_paragraph_style_names()) for p_name in names: self.plist.add([p_name], self.style.get_paragraph_style(p_name)) names = _alphanumeric_sort(self.style.get_table_style_names()) for t_name in names: self.plist.add([t_name], self.style.get_table_style(t_name)) names = _alphanumeric_sort(self.style.get_cell_style_names()) for c_name in names: self.plist.add([c_name], self.style.get_cell_style(c_name)) names = _alphanumeric_sort(self.style.get_draw_style_names()) for d_name in names: self.plist.add([d_name], self.style.get_draw_style(d_name)) self.plist.select_row(0) if self.parent: self.window.set_transient_for(parent.window) self.window.run() self.window.destroy()
class StyleEditor(object): """ Edits the current style definition. Presents a dialog allowing the values of the paragraphs in the style to be altered. """ def __init__(self, name, style, parent): """ Create the StyleEditor. name - name of the style that is to be edited style - style object that is to be edited parent - StyleListDisplay object that called the editor """ self.current_p = None self.current_name = None self.style = StyleSheet(style) self.parent = parent self.top = Glade(toplevel='editor') self.window = self.top.toplevel self.top.connect_signals({ "on_save_style_clicked": self.on_save_style_clicked, "destroy_passed_object": self.__close, "on_ok_clicked": dummy_callback, "on_add_clicked": dummy_callback, "on_delete_clicked": dummy_callback, "on_button_press": dummy_callback, "on_edit_clicked": dummy_callback, }) self.pname = self.top.get_object('pname') self.pdescription = self.top.get_object('pdescription') set_titles(self.window, self.top.get_object('title'), _('Style editor')) self.top.get_object("label6").set_text(_("point size|pt")) titles = [(_('Paragraph'), 0, 130)] self.plist = ListModel(self.top.get_object("ptree"), titles, self.change_display) self.top.get_object('color').connect('color-set', self.fg_color_set) self.top.get_object('bgcolor').connect('color-set', self.bg_color_set) self.top.get_object("style_name").set_text(name) def _alphanumeric_sort(iterable): """ sort the given iterable in the way that humans expect """ convert = lambda text: int(text) if text.isdigit() else text sort_key = lambda k: [convert(c) for c in re.split('([0-9]+)', k)] return sorted(iterable, key=sort_key) names = _alphanumeric_sort(self.style.get_paragraph_style_names()) for p_name in names: self.plist.add([p_name], self.style.get_paragraph_style(p_name)) self.plist.select_row(0) if self.parent: self.window.set_transient_for(parent.window) self.window.run() self.window.destroy() def __close(self, obj): self.window.destroy() def draw(self): """Updates the display with the selected paragraph.""" p = self.current_p self.pname.set_text('<span size="larger" weight="bold">%s</span>' % self.current_name) self.pname.set_use_markup(True) descr = p.get_description() self.pdescription.set_text(descr or _("No description available")) font = p.get_font() self.top.get_object("size").set_value(font.get_size()) if font.get_type_face() == FONT_SERIF: self.top.get_object("roman").set_active(1) else: self.top.get_object("swiss").set_active(1) self.top.get_object("bold").set_active(font.get_bold()) self.top.get_object("italic").set_active(font.get_italic()) self.top.get_object("underline").set_active(font.get_underline()) if p.get_alignment() == PARA_ALIGN_LEFT: self.top.get_object("lalign").set_active(1) elif p.get_alignment() == PARA_ALIGN_RIGHT: self.top.get_object("ralign").set_active(1) elif p.get_alignment() == PARA_ALIGN_CENTER: self.top.get_object("calign").set_active(1) else: self.top.get_object("jalign").set_active(1) self.top.get_object("rmargin").set_value(p.get_right_margin()) self.top.get_object("lmargin").set_value(p.get_left_margin()) self.top.get_object("pad").set_value(p.get_padding()) self.top.get_object("tmargin").set_value(p.get_top_margin()) self.top.get_object("bmargin").set_value(p.get_bottom_margin()) self.top.get_object("indent").set_value(p.get_first_indent()) self.top.get_object("tborder").set_active(p.get_top_border()) self.top.get_object("lborder").set_active(p.get_left_border()) self.top.get_object("rborder").set_active(p.get_right_border()) self.top.get_object("bborder").set_active(p.get_bottom_border()) self.fg_color = font.get_color() c = Gdk.Color(self.fg_color[0] << 8, self.fg_color[1] << 8, self.fg_color[2] << 8) self.top.get_object("color").set_color(c) self.top.get_object('color_code').set_text("#%02X%02X%02X" % self.fg_color) self.bg_color = p.get_background_color() c = Gdk.Color(self.bg_color[0] << 8, self.bg_color[1] << 8, self.bg_color[2] << 8) self.top.get_object("bgcolor").set_color(c) self.top.get_object('bgcolor_code').set_text("#%02X%02X%02X" % self.bg_color) def bg_color_set(self, x): c = x.get_color() self.bg_color = (c.red >> 8, c.green >> 8, c.blue >> 8) self.top.get_object('bgcolor_code').set_text("#%02X%02X%02X" % self.bg_color) def fg_color_set(self, x): c = x.get_color() self.fg_color = (c.red >> 8, c.green >> 8, c.blue >> 8) self.top.get_object('color_code').set_text("#%02X%02X%02X" % self.fg_color) def save_paragraph(self): """Saves the current paragraph displayed on the dialog""" p = self.current_p font = p.get_font() font.set_size(self.top.get_object("size").get_value_as_int()) if self.top.get_object("roman").get_active(): font.set_type_face(FONT_SERIF) else: font.set_type_face(FONT_SANS_SERIF) font.set_bold(self.top.get_object("bold").get_active()) font.set_italic(self.top.get_object("italic").get_active()) font.set_underline(self.top.get_object("underline").get_active()) if self.top.get_object("lalign").get_active(): p.set_alignment(PARA_ALIGN_LEFT) elif self.top.get_object("ralign").get_active(): p.set_alignment(PARA_ALIGN_RIGHT) elif self.top.get_object("calign").get_active(): p.set_alignment(PARA_ALIGN_CENTER) else: p.set_alignment(PARA_ALIGN_JUSTIFY) p.set_right_margin(self.top.get_object("rmargin").get_value()) p.set_left_margin(self.top.get_object("lmargin").get_value()) p.set_top_margin(self.top.get_object("tmargin").get_value()) p.set_bottom_margin(self.top.get_object("bmargin").get_value()) p.set_padding(self.top.get_object("pad").get_value()) p.set_first_indent(self.top.get_object("indent").get_value()) p.set_top_border(self.top.get_object("tborder").get_active()) p.set_left_border(self.top.get_object("lborder").get_active()) p.set_right_border(self.top.get_object("rborder").get_active()) p.set_bottom_border(self.top.get_object("bborder").get_active()) font.set_color(self.fg_color) p.set_background_color(self.bg_color) self.style.add_paragraph_style(self.current_name, self.current_p) def on_save_style_clicked(self, obj): """ Saves the current style sheet and causes the parent to be updated with the changes. """ name = cuni(self.top.get_object("style_name").get_text()) self.save_paragraph() self.style.set_name(name) self.parent.sheetlist.set_style_sheet(name, self.style) self.parent.redraw() self.window.destroy() def change_display(self, obj): """Called when the paragraph selection has been changed. Saves the old paragraph, then draws the newly selected paragraph""" # Don't save until current_name is defined # If it's defined, save under the current paragraph name if self.current_name: self.save_paragraph() # Then change to new paragraph objs = self.plist.get_selected_objects() store, node = self.plist.get_selected() self.current_name = store.get_value(node, 0) self.current_p = objs[0] self.draw()