def on_app_options(self):
        """Display application options"""

        self.xml = gtk.glade.XML(get_resource("rc", "keepnote.glade"),
                                 "app_config_dialog")
        self.dialog = self.xml.get_widget("app_config_dialog")
        self.dialog.set_transient_for(self.main_window)
        self.tabs = self.xml.get_widget("app_config_tabs")
        self.setup_overview_tree()

        # populate default notebook
        self.xml.get_widget("default_notebook_entry").\
            set_text(self.app.pref.default_notebook)

        # populate autosave
        self.xml.get_widget("autosave_check").set_active(
            self.app.pref.autosave)
        self.xml.get_widget("autosave_entry").set_text(
            str(int(self.app.pref.autosave_time / 1000)))

        self.xml.get_widget("autosave_entry").set_sensitive(
            self.app.pref.autosave)
        self.xml.get_widget("autosave_label").set_sensitive(
            self.app.pref.autosave)

        # populate default font
        #self.xml.get_widget("default_font_button").\
        #    set_font_name(self.app.pref.default_font)

        # use systray icon
        self.xml.get_widget("systray_check").set_active(
            self.app.pref.use_systray)
        self.xml.get_widget("skip_taskbar_check").set_active(
            self.app.pref.skip_taskbar)
        self.xml.get_widget("skip_taskbar_check").set_sensitive(
            self.app.pref.use_systray)

        # look and feel
        self.treeview_lines_check = self.xml.get_widget("treeview_lines_check")
        self.treeview_lines_check.set_active(self.app.pref.treeview_lines)
        self.listview_rules_check = self.xml.get_widget("listview_rules_check")
        self.listview_rules_check.set_active(self.app.pref.listview_rules)
        self.use_stock_icons_check = \
            self.xml.get_widget("use_stock_icons_check")
        self.use_stock_icons_check.set_active(self.app.pref.use_stock_icons)

        # populate dates
        for name in ["same_day", "same_month", "same_year", "diff_year"]:
            self.xml.get_widget("date_%s_entry" % name).\
                set_text(self.app.pref.timestamp_formats[name])

        # populate external apps
        self.entries = {}
        apps_widget = self.xml.get_widget("external_apps_frame")
        table = gtk.Table(len(self.app.pref.external_apps), 3)
        apps_widget.add_with_viewport(table)
        apps_widget.get_child().set_property("shadow-type", gtk.SHADOW_NONE)

        for i, app in enumerate(self.app.pref.external_apps):
            key = app.key
            app_title = app.title
            prog = app.prog

            # program label
            label = gtk.Label(app_title + ":")
            label.set_justify(gtk.JUSTIFY_RIGHT)
            label.set_alignment(1.0, 0.5)
            label.show()
            table.attach(label,
                         0,
                         1,
                         i,
                         i + 1,
                         xoptions=gtk.FILL,
                         yoptions=0,
                         xpadding=2,
                         ypadding=2)

            # program entry
            entry = gtk.Entry()
            entry.set_text(prog)
            entry.show()
            self.entries[key] = entry
            table.attach(entry,
                         1,
                         2,
                         i,
                         i + 1,
                         xoptions=gtk.FILL | gtk.EXPAND,
                         yoptions=0,
                         xpadding=2,
                         ypadding=2)

            # browse button
            def button_clicked(key, title, prog):
                return lambda w: \
                    self.on_browse(key,
                                   "Choose %s" % title,
                                   prog)

            button = gtk.Button("Browse...")
            button.set_image(
                gtk.image_new_from_stock(gtk.STOCK_OPEN,
                                         gtk.ICON_SIZE_SMALL_TOOLBAR))
            button.show()
            button.connect("clicked", button_clicked(key, app_title, prog))
            table.attach(button,
                         2,
                         3,
                         i,
                         i + 1,
                         xoptions=0,
                         yoptions=0,
                         xpadding=2,
                         ypadding=2)

        table.show()

        # add notebook font widget
        notebook_font_spot = self.xml.get_widget("notebook_font_spot")
        self.notebook_font_family = FontSelector()
        notebook_font_spot.add(self.notebook_font_family)
        self.notebook_font_family.show()

        # populate notebook font
        self.notebook_font_size = self.xml.get_widget("notebook_font_size")
        self.notebook_font_size.set_value(10)

        if self.main_window.notebook is not None:
            font = self.main_window.notebook.pref.default_font
            family, mods, size = richtext.parse_font(font)
            self.notebook_font_family.set_family(family)
            self.notebook_font_size.set_value(size)

        self.xml.signal_autoconnect(self)
        self.xml.signal_autoconnect({
            "on_cancel_button_clicked":
            lambda w: self.dialog.destroy(),
            "on_default_notebook_button_clicked":
            lambda w: self.
            on_browse("default_notebook", "Choose Default Notebook", self.app.
                      pref.default_notebook),
        })

        self.dialog.show()
Beispiel #2
0
    def make_toolbar(self, toolbar, tips, use_stock_icons):
        
        # bold tool
        self.bold = self._make_toggle_button(
            toolbar, tips,
            "Bold", "bold.png", gtk.STOCK_BOLD,
            lambda: self._editor.get_textview().toggle_font_mod("bold"),
            use_stock_icons)
        
        # italic tool
        self.italic = self._make_toggle_button(
            toolbar, tips,
            "Italic", "italic.png", gtk.STOCK_ITALIC,
            lambda: self._editor.get_textview().toggle_font_mod("italic"),
            use_stock_icons)

        # underline tool
        self.underline = self._make_toggle_button(
            toolbar, tips,
            "Underline", "underline.png", gtk.STOCK_UNDERLINE,
            lambda: self._editor.get_textview().toggle_font_mod("underline"),
            use_stock_icons)

        # strikethrough
        self.strike = self._make_toggle_button(
            toolbar, tips,
            "Strike", "strike.png", gtk.STOCK_STRIKETHROUGH,
            lambda: self._editor.get_textview().toggle_font_mod("strike"),
            use_stock_icons)
        
        # fixed-width tool
        self.fixed_width = self._make_toggle_button(
            toolbar, tips,
            "Monospace", "fixed-width.png", None,
            lambda: self._editor.get_textview().toggle_font_mod("tt"),
            use_stock_icons)

        # link
        self.link = self._make_toggle_button(
            toolbar, tips,
            "Make Link", "link.png", None,
            self.on_toggle_link,
            use_stock_icons)

        # no wrap tool
        self.no_wrap = self._make_toggle_button(
            toolbar, tips,
            "No Wrapping", "no-wrap.png", None,
            lambda: self._editor.get_textview().toggle_font_mod("nowrap"),
            use_stock_icons)

        

        # family combo
        self.font_family_combo = FontSelector()
        self.font_family_combo.set_size_request(150, 25)
        item = gtk.ToolItem()
        item.add(self.font_family_combo)
        tips.set_tip(item, "Font Family")
        toolbar.insert(item, -1)
        self.font_family_id = self.font_family_combo.connect("changed",
            lambda w: self.on_family_set())
        self._font_ui_signals.append(FontUI(self.font_family_combo,
                                           self.font_family_id))
                
        # font size
        DEFAULT_FONT_SIZE = 10
        self.font_size_button = gtk.SpinButton(
          gtk.Adjustment(value=DEFAULT_FONT_SIZE, lower=2, upper=500, 
                         step_incr=1))
        self.font_size_button.set_size_request(-1, 25)
        #self.font_size_button.set_range(2, 100)
        self.font_size_button.set_value(DEFAULT_FONT_SIZE)
        self.font_size_button.set_editable(False)
        item = gtk.ToolItem()
        item.add(self.font_size_button)
        tips.set_tip(item, "Font Size")
        toolbar.insert(item, -1)
        self.font_size_id = self.font_size_button.connect("value-changed",
            lambda w: 
            self.on_font_size_change(self.font_size_button.get_value()))
        self._font_ui_signals.append(FontUI(self.font_size_button,
                                           self.font_size_id))


        # font fg color
        # TODO: code in proper default color
        self.fg_color_button = FgColorTool(14, 15, (0, 0, 0))
        self.fg_color_button.connect("set-color",
            lambda w, color: self.on_color_set("fg", color))
        tips.set_tip(self.fg_color_button, "Set Text Color")
        toolbar.insert(self.fg_color_button, -1)
        

        # font bg color
        self.bg_color_button = BgColorTool(14, 15, (65535, 65535, 65535))
        self.bg_color_button.connect("set-color",
            lambda w, color: self.on_color_set("bg", color))
        tips.set_tip(self.bg_color_button, "Set Background Color")
        toolbar.insert(self.bg_color_button, -1)

                
        
        # separator
        toolbar.insert(gtk.SeparatorToolItem(), -1)
        
                
        # left tool
        self.left_align = self._make_toggle_button(
            toolbar, tips,
            "Left Align", "alignleft.png", gtk.STOCK_JUSTIFY_LEFT,
            lambda: self.on_justify("left"),
            use_stock_icons)

        # center tool
        self.center_align = self._make_toggle_button(
            toolbar, tips,
            "Center Align", "aligncenter.png", gtk.STOCK_JUSTIFY_CENTER,
            lambda: self.on_justify("center"),
            use_stock_icons)

        # right tool
        self.right_align = self._make_toggle_button(
            toolbar, tips,
            "Right Align", "alignright.png", gtk.STOCK_JUSTIFY_RIGHT,
            lambda: self.on_justify("right"),
            use_stock_icons)

        # justify tool
        self.fill_align = self._make_toggle_button(
            toolbar, tips,
            "Justify Align", "alignjustify.png", gtk.STOCK_JUSTIFY_FILL,
            lambda: self.on_justify("fill"),
            use_stock_icons)
        
        
        # bullet list tool
        self.bullet = self._make_toggle_button(
            toolbar, tips,
            "Bullet List", "bullet.png", None,
            lambda: self.on_bullet_list(),
            use_stock_icons)
class ApplicationOptionsDialog(object):
    """Application options"""
    def __init__(self, main_window):
        self.main_window = main_window
        self.app = main_window.app
        self.entries = {}

    def on_app_options(self):
        """Display application options"""

        self.xml = gtk.glade.XML(get_resource("rc", "keepnote.glade"),
                                 "app_config_dialog")
        self.dialog = self.xml.get_widget("app_config_dialog")
        self.dialog.set_transient_for(self.main_window)
        self.tabs = self.xml.get_widget("app_config_tabs")
        self.setup_overview_tree()

        # populate default notebook
        self.xml.get_widget("default_notebook_entry").\
            set_text(self.app.pref.default_notebook)

        # populate autosave
        self.xml.get_widget("autosave_check").set_active(
            self.app.pref.autosave)
        self.xml.get_widget("autosave_entry").set_text(
            str(int(self.app.pref.autosave_time / 1000)))

        self.xml.get_widget("autosave_entry").set_sensitive(
            self.app.pref.autosave)
        self.xml.get_widget("autosave_label").set_sensitive(
            self.app.pref.autosave)

        # populate default font
        #self.xml.get_widget("default_font_button").\
        #    set_font_name(self.app.pref.default_font)

        # use systray icon
        self.xml.get_widget("systray_check").set_active(
            self.app.pref.use_systray)
        self.xml.get_widget("skip_taskbar_check").set_active(
            self.app.pref.skip_taskbar)
        self.xml.get_widget("skip_taskbar_check").set_sensitive(
            self.app.pref.use_systray)

        # look and feel
        self.treeview_lines_check = self.xml.get_widget("treeview_lines_check")
        self.treeview_lines_check.set_active(self.app.pref.treeview_lines)
        self.listview_rules_check = self.xml.get_widget("listview_rules_check")
        self.listview_rules_check.set_active(self.app.pref.listview_rules)
        self.use_stock_icons_check = \
            self.xml.get_widget("use_stock_icons_check")
        self.use_stock_icons_check.set_active(self.app.pref.use_stock_icons)

        # populate dates
        for name in ["same_day", "same_month", "same_year", "diff_year"]:
            self.xml.get_widget("date_%s_entry" % name).\
                set_text(self.app.pref.timestamp_formats[name])

        # populate external apps
        self.entries = {}
        apps_widget = self.xml.get_widget("external_apps_frame")
        table = gtk.Table(len(self.app.pref.external_apps), 3)
        apps_widget.add_with_viewport(table)
        apps_widget.get_child().set_property("shadow-type", gtk.SHADOW_NONE)

        for i, app in enumerate(self.app.pref.external_apps):
            key = app.key
            app_title = app.title
            prog = app.prog

            # program label
            label = gtk.Label(app_title + ":")
            label.set_justify(gtk.JUSTIFY_RIGHT)
            label.set_alignment(1.0, 0.5)
            label.show()
            table.attach(label,
                         0,
                         1,
                         i,
                         i + 1,
                         xoptions=gtk.FILL,
                         yoptions=0,
                         xpadding=2,
                         ypadding=2)

            # program entry
            entry = gtk.Entry()
            entry.set_text(prog)
            entry.show()
            self.entries[key] = entry
            table.attach(entry,
                         1,
                         2,
                         i,
                         i + 1,
                         xoptions=gtk.FILL | gtk.EXPAND,
                         yoptions=0,
                         xpadding=2,
                         ypadding=2)

            # browse button
            def button_clicked(key, title, prog):
                return lambda w: \
                    self.on_browse(key,
                                   "Choose %s" % title,
                                   prog)

            button = gtk.Button("Browse...")
            button.set_image(
                gtk.image_new_from_stock(gtk.STOCK_OPEN,
                                         gtk.ICON_SIZE_SMALL_TOOLBAR))
            button.show()
            button.connect("clicked", button_clicked(key, app_title, prog))
            table.attach(button,
                         2,
                         3,
                         i,
                         i + 1,
                         xoptions=0,
                         yoptions=0,
                         xpadding=2,
                         ypadding=2)

        table.show()

        # add notebook font widget
        notebook_font_spot = self.xml.get_widget("notebook_font_spot")
        self.notebook_font_family = FontSelector()
        notebook_font_spot.add(self.notebook_font_family)
        self.notebook_font_family.show()

        # populate notebook font
        self.notebook_font_size = self.xml.get_widget("notebook_font_size")
        self.notebook_font_size.set_value(10)

        if self.main_window.notebook is not None:
            font = self.main_window.notebook.pref.default_font
            family, mods, size = richtext.parse_font(font)
            self.notebook_font_family.set_family(family)
            self.notebook_font_size.set_value(size)

        self.xml.signal_autoconnect(self)
        self.xml.signal_autoconnect({
            "on_cancel_button_clicked":
            lambda w: self.dialog.destroy(),
            "on_default_notebook_button_clicked":
            lambda w: self.
            on_browse("default_notebook", "Choose Default Notebook", self.app.
                      pref.default_notebook),
        })

        self.dialog.show()

    def setup_overview_tree(self):

        # setup treeview
        self.overview = self.xml.get_widget("app_config_treeview")
        overview_store = gtk.TreeStore(str)
        self.overview.set_model(overview_store)
        self.overview.connect("cursor-changed", self.on_overview_select)
        #self.set_headers_visible(False)

        # create the treeview column
        column = gtk.TreeViewColumn()
        self.overview.append_column(column)
        cell_text = gtk.CellRendererText()
        column.pack_start(cell_text, True)
        column.add_attribute(cell_text, 'text', 0)

        # populate treestore
        app = overview_store.append(None, [keepnote.PROGRAM_NAME])
        overview_store.append(app, ["Look and Feel"])
        overview_store.append(app, ["Helper Applications"])
        overview_store.append(app, ["Data and Time"])
        note = overview_store.append(None, ["This Notebook"])

        self.overview.expand_all()

        self.tree2tab = {
            (0, ): 0,
            (
                0,
                0,
            ): 4,
            (
                0,
                1,
            ): 1,
            (
                0,
                2,
            ): 2,
            (1, ): 3
        }

    def on_overview_select(self, overview):
        """Callback for changing topic in overview"""

        row, col = overview.get_cursor()
        if row is not None:
            self.tabs.set_current_page(self.tree2tab[row])

    def on_autosave_check_toggled(self, widget):
        """The autosave option controls sensitivity of autosave time"""
        self.xml.get_widget("autosave_entry").set_sensitive(
            widget.get_active())
        self.xml.get_widget("autosave_label").set_sensitive(
            widget.get_active())

    def on_systray_check_toggled(self, widget):
        """Systray option controls sensitivity of skip taskbar"""
        self.xml.get_widget("skip_taskbar_check").set_sensitive(
            widget.get_active())

    def on_browse(self, name, title, filename):
        """Callback for selecting file browser"""

        dialog = gtk.FileChooserDialog(title,
                                       self.dialog,
                                       action=gtk.FILE_CHOOSER_ACTION_OPEN,
                                       buttons=("Cancel", gtk.RESPONSE_CANCEL,
                                                "Open", gtk.RESPONSE_OK))
        dialog.set_transient_for(self.dialog)
        dialog.set_modal(True)

        # set the filename if it is fully specified
        if os.path.isabs(filename):
            dialog.set_filename(filename)

        response = dialog.run()

        if response == gtk.RESPONSE_OK:
            filename = dialog.get_filename()

            if name == "default_notebook":
                self.xml.get_widget("default_notebook_entry").\
                    set_text(filename)
            else:
                self.entries[name].set_text(filename)

        dialog.destroy()

    def on_set_default_notebook_button_clicked(self, widget):

        if self.main_window.notebook:
            self.xml.get_widget("default_notebook_entry").set_text(
                self.main_window.notebook.get_path())

    def on_ok_button_clicked(self, widget):
        # TODO: add arguments

        self.app.pref.default_notebook = \
            self.xml.get_widget("default_notebook_entry").get_text()

        # save autosave
        self.app.pref.autosave = \
            self.xml.get_widget("autosave_check").get_active()
        try:
            self.app.pref.autosave_time = \
                int(self.xml.get_widget("autosave_entry").get_text()) * 1000
        except:
            pass

        # use systray icon
        self.app.pref.use_systray = self.xml.get_widget(
            "systray_check").get_active()
        self.app.pref.skip_taskbar = self.xml.get_widget(
            "skip_taskbar_check").get_active()

        # look and feel
        self.app.pref.treeview_lines = self.treeview_lines_check.get_active()
        self.app.pref.listview_rules = self.listview_rules_check.get_active()
        self.app.pref.use_stock_icons = self.use_stock_icons_check.get_active()

        # save date formatting
        for name in ["same_day", "same_month", "same_year", "diff_year"]:
            self.app.pref.timestamp_formats[name] = \
                self.xml.get_widget("date_%s_entry" % name).get_text()

        # save external app options
        for key, entry in self.entries.iteritems():
            self.app.pref._external_apps_lookup[key].prog = \
                self.entries[key].get_text()

        # save notebook font
        if self.main_window.notebook is not None:
            pref = self.main_window.notebook.pref
            pref.default_font = "%s %d" % (
                self.notebook_font_family.get_family(),
                self.notebook_font_size.get_value())

            self.main_window.notebook.write_preferences()
            self.main_window.notebook.notify_change(False)

        self.app.pref.write()
        self.app.pref.changed.notify()

        self.dialog.destroy()
        self.dialog = None
Beispiel #4
0
class EditorMenus (gobject.GObject):

    def __init__(self, editor):
        gobject.GObject.__init__(self)
        
        self._editor = editor
        self._font_ui_signals = []     # list of font ui widgets


    #=============================================================
    # Update UI (menubar) from font under cursor
    
    def on_font_change(self, editor, font):
        """Update the toolbar reflect the font under the cursor"""
        
        # block toolbar handlers
        for ui in self._font_ui_signals:
            ui.widget.handler_block(ui.signal)

        # update font mods
        self.bold.widget.set_active(font.mods["bold"])
        self.italic.widget.set_active(font.mods["italic"])
        self.underline.widget.set_active(font.mods["underline"])
        self.strike.widget.set_active(font.mods["strike"])
        self.fixed_width.widget.set_active(font.mods["tt"])
        self.link.widget.set_active(font.link is not None)
        self.no_wrap.widget.set_active(font.mods["nowrap"])
        
        # update text justification
        self.left_align.widget.set_active(font.justify == "left")
        self.center_align.widget.set_active(font.justify == "center")
        self.right_align.widget.set_active(font.justify == "right")
        self.fill_align.widget.set_active(font.justify == "fill")

        # update bullet list
        self.bullet.widget.set_active(font.par_type == "bullet")
        
        # update family/size buttons        
        self.font_family_combo.set_family(font.family)
        self.font_size_button.set_value(font.size)
        
        # unblock toolbar handlers
        for ui in self._font_ui_signals:
            ui.widget.handler_unblock(ui.signal)


    #==================================================
    # changing font handlers

    def on_mod(self, mod):
        """Toggle a font modification"""
        self._editor.get_textview().toggle_font_mod(mod)

        #font = self._editor.get_textview().get_font()        
        #mod_button.handler_block(mod_id)
        #mod_button.set_active(font.mods[mod])
        #mod_button.handler_unblock(mod_id)


    def on_toggle_link(self):

        textview = self._editor.get_textview()
        textview.toggle_link()
        tag, start, end = textview.get_link()

        if tag is not None:
            self.emit("make-link")
    

    def on_justify(self, justify):
        """Set font justification"""
        self._editor.get_textview().set_justify(justify)
        font = self._editor.get_textview().get_font()
        self.on_font_change(self._editor, font)
        
    def on_bullet_list(self):
        """Toggle bullet list"""
        self._editor.get_textview().toggle_bullet()
        font = self._editor.get_textview().get_font()
        self.on_font_change(self._editor, font)
        
    def on_indent(self):
        """Indent current paragraph"""
        self._editor.get_textview().indent()

    def on_unindent(self):
        """Unindent current paragraph"""
        self._editor.get_textview().unindent()


    
    def on_family_set(self):
        """Set the font family"""
        self._editor.get_textview().set_font_family(
            self.font_family_combo.get_family())
        self._editor.get_textview().grab_focus()
        

    def on_font_size_change(self, size):
        """Set the font size"""
        self._editor.get_textview().set_font_size(size)
        self._editor.get_textview().grab_focus()
    
    def on_font_size_inc(self):
        """Increase font size"""
        font = self._editor.get_textview().get_font()
        font.size += 2        
        self._editor.get_textview().set_font_size(font.size)
        self.on_font_change(self._editor, font)
    
    
    def on_font_size_dec(self):
        """Decrease font size"""
        font = self._editor.get_textview().get_font()
        if font.size > 4:
            font.size -= 2
        self._editor.get_textview().set_font_size(font.size)
        self.on_font_change(self._editor, font)


    def on_color_set(self, kind, color=0):
        """Set text/background color"""
        
        if color == 0:
            if kind == "fg":
                color = self.fg_color_button.color
            elif kind == "bg":
                color = self.bg_color_button.color
            else:
                color = None

        if color is not None:
            colorstr = color_tuple_to_string(color)
        else:
            colorstr = None

        if kind == "fg":
            self._editor.get_textview().set_font_fg_color(colorstr)
        elif kind == "bg":
            self._editor.get_textview().set_font_bg_color(colorstr)
        else:
            raise Exception("unknown color type '%s'" % str(kind))
        

    def on_choose_font(self):
        """Callback for opening Choose Font Dialog"""
        
        font = self._editor.get_textview().get_font()

        dialog = gtk.FontSelectionDialog("Choose Font")
        dialog.set_font_name("%s %d" % (font.family, font.size))
        response = dialog.run()

        if response == gtk.RESPONSE_OK:
            self._editor.get_textview().set_font(dialog.get_font_name())
            self._editor.get_textview().grab_focus()

        dialog.destroy()


    def _make_toggle_button(self, toolbar, tips, tip_text, icon, 
                            stock_id=None, 
                            func=lambda: None,
                            use_stock_icons=False):

        button = gtk.ToggleToolButton()
        if use_stock_icons and stock_id:
            button.set_stock_id(stock_id)
        else:
            button.set_icon_widget(get_resource_image(icon))
        signal = button.connect("toggled", lambda w: func())
        font_ui = FontUI(button, signal)
        self._font_ui_signals.append(font_ui)
        
        toolbar.insert(button, -1)
        tips.set_tip(button, tip_text)

        return font_ui


    def make_toolbar(self, toolbar, tips, use_stock_icons):
        
        # bold tool
        self.bold = self._make_toggle_button(
            toolbar, tips,
            "Bold", "bold.png", gtk.STOCK_BOLD,
            lambda: self._editor.get_textview().toggle_font_mod("bold"),
            use_stock_icons)
        
        # italic tool
        self.italic = self._make_toggle_button(
            toolbar, tips,
            "Italic", "italic.png", gtk.STOCK_ITALIC,
            lambda: self._editor.get_textview().toggle_font_mod("italic"),
            use_stock_icons)

        # underline tool
        self.underline = self._make_toggle_button(
            toolbar, tips,
            "Underline", "underline.png", gtk.STOCK_UNDERLINE,
            lambda: self._editor.get_textview().toggle_font_mod("underline"),
            use_stock_icons)

        # strikethrough
        self.strike = self._make_toggle_button(
            toolbar, tips,
            "Strike", "strike.png", gtk.STOCK_STRIKETHROUGH,
            lambda: self._editor.get_textview().toggle_font_mod("strike"),
            use_stock_icons)
        
        # fixed-width tool
        self.fixed_width = self._make_toggle_button(
            toolbar, tips,
            "Monospace", "fixed-width.png", None,
            lambda: self._editor.get_textview().toggle_font_mod("tt"),
            use_stock_icons)

        # link
        self.link = self._make_toggle_button(
            toolbar, tips,
            "Make Link", "link.png", None,
            self.on_toggle_link,
            use_stock_icons)

        # no wrap tool
        self.no_wrap = self._make_toggle_button(
            toolbar, tips,
            "No Wrapping", "no-wrap.png", None,
            lambda: self._editor.get_textview().toggle_font_mod("nowrap"),
            use_stock_icons)

        

        # family combo
        self.font_family_combo = FontSelector()
        self.font_family_combo.set_size_request(150, 25)
        item = gtk.ToolItem()
        item.add(self.font_family_combo)
        tips.set_tip(item, "Font Family")
        toolbar.insert(item, -1)
        self.font_family_id = self.font_family_combo.connect("changed",
            lambda w: self.on_family_set())
        self._font_ui_signals.append(FontUI(self.font_family_combo,
                                           self.font_family_id))
                
        # font size
        DEFAULT_FONT_SIZE = 10
        self.font_size_button = gtk.SpinButton(
          gtk.Adjustment(value=DEFAULT_FONT_SIZE, lower=2, upper=500, 
                         step_incr=1))
        self.font_size_button.set_size_request(-1, 25)
        #self.font_size_button.set_range(2, 100)
        self.font_size_button.set_value(DEFAULT_FONT_SIZE)
        self.font_size_button.set_editable(False)
        item = gtk.ToolItem()
        item.add(self.font_size_button)
        tips.set_tip(item, "Font Size")
        toolbar.insert(item, -1)
        self.font_size_id = self.font_size_button.connect("value-changed",
            lambda w: 
            self.on_font_size_change(self.font_size_button.get_value()))
        self._font_ui_signals.append(FontUI(self.font_size_button,
                                           self.font_size_id))


        # font fg color
        # TODO: code in proper default color
        self.fg_color_button = FgColorTool(14, 15, (0, 0, 0))
        self.fg_color_button.connect("set-color",
            lambda w, color: self.on_color_set("fg", color))
        tips.set_tip(self.fg_color_button, "Set Text Color")
        toolbar.insert(self.fg_color_button, -1)
        

        # font bg color
        self.bg_color_button = BgColorTool(14, 15, (65535, 65535, 65535))
        self.bg_color_button.connect("set-color",
            lambda w, color: self.on_color_set("bg", color))
        tips.set_tip(self.bg_color_button, "Set Background Color")
        toolbar.insert(self.bg_color_button, -1)

                
        
        # separator
        toolbar.insert(gtk.SeparatorToolItem(), -1)
        
                
        # left tool
        self.left_align = self._make_toggle_button(
            toolbar, tips,
            "Left Align", "alignleft.png", gtk.STOCK_JUSTIFY_LEFT,
            lambda: self.on_justify("left"),
            use_stock_icons)

        # center tool
        self.center_align = self._make_toggle_button(
            toolbar, tips,
            "Center Align", "aligncenter.png", gtk.STOCK_JUSTIFY_CENTER,
            lambda: self.on_justify("center"),
            use_stock_icons)

        # right tool
        self.right_align = self._make_toggle_button(
            toolbar, tips,
            "Right Align", "alignright.png", gtk.STOCK_JUSTIFY_RIGHT,
            lambda: self.on_justify("right"),
            use_stock_icons)

        # justify tool
        self.fill_align = self._make_toggle_button(
            toolbar, tips,
            "Justify Align", "alignjustify.png", gtk.STOCK_JUSTIFY_FILL,
            lambda: self.on_justify("fill"),
            use_stock_icons)
        
        
        # bullet list tool
        self.bullet = self._make_toggle_button(
            toolbar, tips,
            "Bullet List", "bullet.png", None,
            lambda: self.on_bullet_list(),
            use_stock_icons)
        
        
    def get_format_menu(self):

        return [
            ("/Fo_rmat", 
             None, None, 0, "<Branch>"),

            ("/Format/_Bold", 
             "<control>B", lambda w,e: self.on_mod("bold"), 0, 
             "<ImageItem>", 
             get_resource_pixbuf("bold.png")),
            ("/Format/_Italic", 
             "<control>I", lambda w,e: self.on_mod("italic"), 0, 
             "<ImageItem>", 
             get_resource_pixbuf("italic.png")),
            ("/Format/_Underline", 
             "<control>U", lambda w,e: self.on_mod("underline"), 0, 
             "<ImageItem>", 
             get_resource_pixbuf("underline.png")),
            ("/Format/S_trike", 
             "", lambda w,e: self.on_mod("strike"), 0, 
             "<ImageItem>", 
             get_resource_pixbuf("strike.png")),            
            ("/Format/_Monospace",
             "<control>M", lambda w,e: self.on_mod("tt"), 0,
             "<ImageItem>",
             get_resource_pixbuf("fixed-width.png")),
            ("/Format/Lin_k",
             "<control>L", lambda w, e: self.on_toggle_link(), 0,
             "<ImageItem>",
             get_resource_pixbuf("link.png")),
            ("/Format/No _Wrapping",
             None, lambda w, e: self.on_mod("nowrap"), 0,
             "<ImageItem>",
             get_resource_pixbuf("no-wrap.png")),
            
            ("/Format/sep1",
             None, None, 0, "<Separator>" ),            
            
            ("/Format/_Left Align", 
             "<shift><control>L", lambda w,e: self.on_justify("left"), 0, 
             "<ImageItem>", 
             get_resource_pixbuf("alignleft.png")),
            ("/Format/C_enter Align", 
             "<shift><control>E", lambda w,e: self.on_justify("center"), 0, 
             "<ImageItem>", 
             get_resource_pixbuf("aligncenter.png")),
            ("/Format/_Right Align", 
             "<shift><control>R", lambda w,e: self.on_justify("right"), 0, 
             "<ImageItem>", 
             get_resource_pixbuf("alignright.png")),
            ("/Format/_Justify Align", 
             "<shift><control>J", lambda w,e: self.on_justify("fill"), 0, 
             "<ImageItem>", 
             get_resource_pixbuf("alignjustify.png")),
            ("/Format/sep2",
             None, None, 0, "<Separator>" ),

            ("/Format/_Bullet List", 
             "<control>asterisk", lambda w,e: self.on_bullet_list(), 0, 
             "<ImageItem>", 
             get_resource_pixbuf("bullet.png")),
            ("/Format/Indent M_ore", 
             "<control>parenright", lambda w,e: self.on_indent(), 0, 
             "<ImageItem>", 
             get_resource_pixbuf("indent-more.png")),     
            ("/Format/Indent Le_ss", 
             "<control>parenleft", lambda w,e: self.on_unindent(), 0, 
             "<ImageItem>", 
             get_resource_pixbuf("indent-less.png")),
            
            ("/Format/sep4", 
                None, None, 0, "<Separator>" ),
            ("/Format/Increase Font _Size", 
                "<control>equal", lambda w, e: self.on_font_size_inc(), 0, 
                "<ImageItem>", 
                get_resource_pixbuf("font-inc.png")),
            ("/Format/_Decrease Font Size", 
                "<control>minus", lambda w, e: self.on_font_size_dec(), 0, 
                "<ImageItem>", 
                get_resource_pixbuf("font-dec.png")),

            ("/Format/sep5", 
                None, None, 0, "<Separator>" ),
            ("/Format/_Apply Text Color", 
                "", lambda w, e: self.on_color_set("fg"), 0),
            ("/Format/A_pply Background Color", 
                "", lambda w, e: self.on_color_set("bg"), 0),
            
            
            ("/Format/sep6", 
                None, None, 0, "<Separator>" ),
            ("/Format/Choose _Font", 
                "<control><shift>F", lambda w, e: self.on_choose_font(), 0, 
                "<ImageItem>", 
                get_resource_pixbuf("font.png"))
        ]
    def on_app_options(self):
        """Display application options"""
        
        self.xml = gtk.glade.XML(get_resource("rc", "keepnote.glade"),
                                 "app_config_dialog")
        self.dialog = self.xml.get_widget("app_config_dialog")
        self.dialog.set_transient_for(self.main_window)
        self.tabs = self.xml.get_widget("app_config_tabs")
        self.setup_overview_tree()

        

        # populate default notebook
        self.xml.get_widget("default_notebook_entry").\
            set_text(self.app.pref.default_notebook)

        # populate autosave
        self.xml.get_widget("autosave_check").set_active(
            self.app.pref.autosave)
        self.xml.get_widget("autosave_entry").set_text(
            str(int(self.app.pref.autosave_time / 1000)))

        self.xml.get_widget("autosave_entry").set_sensitive(
            self.app.pref.autosave)
        self.xml.get_widget("autosave_label").set_sensitive(
            self.app.pref.autosave)
        

        # populate default font
        #self.xml.get_widget("default_font_button").\
        #    set_font_name(self.app.pref.default_font)

        # use systray icon
        self.xml.get_widget("systray_check").set_active(self.app.pref.use_systray)
        self.xml.get_widget("skip_taskbar_check").set_active(self.app.pref.skip_taskbar)
        self.xml.get_widget("skip_taskbar_check").set_sensitive(self.app.pref.use_systray)

        # look and feel
        self.treeview_lines_check = self.xml.get_widget("treeview_lines_check")
        self.treeview_lines_check.set_active(self.app.pref.treeview_lines)
        self.listview_rules_check = self.xml.get_widget("listview_rules_check")
        self.listview_rules_check.set_active(self.app.pref.listview_rules)
        self.use_stock_icons_check = \
            self.xml.get_widget("use_stock_icons_check")
        self.use_stock_icons_check.set_active(self.app.pref.use_stock_icons)


        # populate dates
        for name in ["same_day", "same_month", "same_year", "diff_year"]:
            self.xml.get_widget("date_%s_entry" % name).\
                set_text(self.app.pref.timestamp_formats[name])


        # populate external apps
        self.entries = {}
        apps_widget = self.xml.get_widget("external_apps_frame")
        table = gtk.Table(len(self.app.pref.external_apps), 3)
        apps_widget.add_with_viewport(table)
        apps_widget.get_child().set_property("shadow-type", gtk.SHADOW_NONE)
        
        for i, app in enumerate(self.app.pref.external_apps):
            key = app.key
            app_title = app.title
            prog = app.prog
            
            # program label
            label = gtk.Label(app_title +":")
            label.set_justify(gtk.JUSTIFY_RIGHT)
            label.set_alignment(1.0, 0.5)
            label.show()
            table.attach(label, 0, 1, i, i+1,
                         xoptions=gtk.FILL, yoptions=0,
                         xpadding=2, ypadding=2)

            # program entry
            entry = gtk.Entry()
            entry.set_text(prog)
            entry.show()
            self.entries[key] = entry
            table.attach(entry, 1, 2, i, i+1,
                         xoptions=gtk.FILL | gtk.EXPAND, yoptions=0,
                         xpadding=2, ypadding=2)

            # browse button
            def button_clicked(key, title, prog):
                return lambda w: \
                    self.on_browse(key,
                                   "Choose %s" % title,
                                   prog)
            button = gtk.Button("Browse...")
            button.set_image(
                gtk.image_new_from_stock(gtk.STOCK_OPEN,
                                         gtk.ICON_SIZE_SMALL_TOOLBAR))
            button.show()
            button.connect("clicked", button_clicked(key, app_title, prog))
            table.attach(button, 2, 3, i, i+1,
                         xoptions=0, yoptions=0,
                         xpadding=2, ypadding=2)

        table.show()


        # add notebook font widget
        notebook_font_spot = self.xml.get_widget("notebook_font_spot")
        self.notebook_font_family = FontSelector()
        notebook_font_spot.add(self.notebook_font_family)
        self.notebook_font_family.show()        

        # populate notebook font
        self.notebook_font_size = self.xml.get_widget("notebook_font_size")
        self.notebook_font_size.set_value(10)

        if self.main_window.notebook is not None:
            font = self.main_window.notebook.pref.default_font
            family, mods, size = richtext.parse_font(font)
            self.notebook_font_family.set_family(family)
            self.notebook_font_size.set_value(size)

        self.xml.signal_autoconnect(self)
        self.xml.signal_autoconnect({
            "on_cancel_button_clicked": 
                lambda w: self.dialog.destroy(),
                
            "on_default_notebook_button_clicked": 
                lambda w: self.on_browse(
                    "default_notebook", 
                    "Choose Default Notebook",
                    self.app.pref.default_notebook),
            })

        self.dialog.show()
class ApplicationOptionsDialog (object):
    """Application options"""
    
    def __init__(self, main_window):
        self.main_window = main_window
        self.app = main_window.app
        self.entries = {}
        
    
    def on_app_options(self):
        """Display application options"""
        
        self.xml = gtk.glade.XML(get_resource("rc", "keepnote.glade"),
                                 "app_config_dialog")
        self.dialog = self.xml.get_widget("app_config_dialog")
        self.dialog.set_transient_for(self.main_window)
        self.tabs = self.xml.get_widget("app_config_tabs")
        self.setup_overview_tree()

        

        # populate default notebook
        self.xml.get_widget("default_notebook_entry").\
            set_text(self.app.pref.default_notebook)

        # populate autosave
        self.xml.get_widget("autosave_check").set_active(
            self.app.pref.autosave)
        self.xml.get_widget("autosave_entry").set_text(
            str(int(self.app.pref.autosave_time / 1000)))

        self.xml.get_widget("autosave_entry").set_sensitive(
            self.app.pref.autosave)
        self.xml.get_widget("autosave_label").set_sensitive(
            self.app.pref.autosave)
        

        # populate default font
        #self.xml.get_widget("default_font_button").\
        #    set_font_name(self.app.pref.default_font)

        # use systray icon
        self.xml.get_widget("systray_check").set_active(self.app.pref.use_systray)
        self.xml.get_widget("skip_taskbar_check").set_active(self.app.pref.skip_taskbar)
        self.xml.get_widget("skip_taskbar_check").set_sensitive(self.app.pref.use_systray)

        # look and feel
        self.treeview_lines_check = self.xml.get_widget("treeview_lines_check")
        self.treeview_lines_check.set_active(self.app.pref.treeview_lines)
        self.listview_rules_check = self.xml.get_widget("listview_rules_check")
        self.listview_rules_check.set_active(self.app.pref.listview_rules)
        self.use_stock_icons_check = \
            self.xml.get_widget("use_stock_icons_check")
        self.use_stock_icons_check.set_active(self.app.pref.use_stock_icons)


        # populate dates
        for name in ["same_day", "same_month", "same_year", "diff_year"]:
            self.xml.get_widget("date_%s_entry" % name).\
                set_text(self.app.pref.timestamp_formats[name])


        # populate external apps
        self.entries = {}
        apps_widget = self.xml.get_widget("external_apps_frame")
        table = gtk.Table(len(self.app.pref.external_apps), 3)
        apps_widget.add_with_viewport(table)
        apps_widget.get_child().set_property("shadow-type", gtk.SHADOW_NONE)
        
        for i, app in enumerate(self.app.pref.external_apps):
            key = app.key
            app_title = app.title
            prog = app.prog
            
            # program label
            label = gtk.Label(app_title +":")
            label.set_justify(gtk.JUSTIFY_RIGHT)
            label.set_alignment(1.0, 0.5)
            label.show()
            table.attach(label, 0, 1, i, i+1,
                         xoptions=gtk.FILL, yoptions=0,
                         xpadding=2, ypadding=2)

            # program entry
            entry = gtk.Entry()
            entry.set_text(prog)
            entry.show()
            self.entries[key] = entry
            table.attach(entry, 1, 2, i, i+1,
                         xoptions=gtk.FILL | gtk.EXPAND, yoptions=0,
                         xpadding=2, ypadding=2)

            # browse button
            def button_clicked(key, title, prog):
                return lambda w: \
                    self.on_browse(key,
                                   "Choose %s" % title,
                                   prog)
            button = gtk.Button("Browse...")
            button.set_image(
                gtk.image_new_from_stock(gtk.STOCK_OPEN,
                                         gtk.ICON_SIZE_SMALL_TOOLBAR))
            button.show()
            button.connect("clicked", button_clicked(key, app_title, prog))
            table.attach(button, 2, 3, i, i+1,
                         xoptions=0, yoptions=0,
                         xpadding=2, ypadding=2)

        table.show()


        # add notebook font widget
        notebook_font_spot = self.xml.get_widget("notebook_font_spot")
        self.notebook_font_family = FontSelector()
        notebook_font_spot.add(self.notebook_font_family)
        self.notebook_font_family.show()        

        # populate notebook font
        self.notebook_font_size = self.xml.get_widget("notebook_font_size")
        self.notebook_font_size.set_value(10)

        if self.main_window.notebook is not None:
            font = self.main_window.notebook.pref.default_font
            family, mods, size = richtext.parse_font(font)
            self.notebook_font_family.set_family(family)
            self.notebook_font_size.set_value(size)

        self.xml.signal_autoconnect(self)
        self.xml.signal_autoconnect({
            "on_cancel_button_clicked": 
                lambda w: self.dialog.destroy(),
                
            "on_default_notebook_button_clicked": 
                lambda w: self.on_browse(
                    "default_notebook", 
                    "Choose Default Notebook",
                    self.app.pref.default_notebook),
            })

        self.dialog.show()


    def setup_overview_tree(self):

        # setup treeview
        self.overview = self.xml.get_widget("app_config_treeview")
        overview_store = gtk.TreeStore(str)
        self.overview.set_model(overview_store)
        self.overview.connect("cursor-changed", self.on_overview_select)
        #self.set_headers_visible(False)

        # create the treeview column
        column = gtk.TreeViewColumn()
        self.overview.append_column(column)
        cell_text = gtk.CellRendererText()
        column.pack_start(cell_text, True)
        column.add_attribute(cell_text, 'text', 0)

        # populate treestore
        app = overview_store.append(None, [keepnote.PROGRAM_NAME])
        overview_store.append(app, ["Look and Feel"])
        overview_store.append(app, ["Helper Applications"])
        overview_store.append(app, ["Data and Time"])        
        note = overview_store.append(None, ["This Notebook"])

        self.overview.expand_all()

        self.tree2tab = {
            (0,): 0,
            (0, 0,): 4,            
            (0, 1,): 1,
            (0, 2,): 2,
            (1,): 3
            }
        

    def on_overview_select(self, overview):
        """Callback for changing topic in overview"""
        
        row, col = overview.get_cursor()
        if row is not None:
            self.tabs.set_current_page(self.tree2tab[row])


    def on_autosave_check_toggled(self, widget):
        """The autosave option controls sensitivity of autosave time"""
        self.xml.get_widget("autosave_entry").set_sensitive(
            widget.get_active())
        self.xml.get_widget("autosave_label").set_sensitive(
            widget.get_active())


    def on_systray_check_toggled(self, widget):
        """Systray option controls sensitivity of skip taskbar"""
        self.xml.get_widget("skip_taskbar_check").set_sensitive(
            widget.get_active())
        
    
    def on_browse(self, name, title, filename):
        """Callback for selecting file browser"""
        
        dialog = gtk.FileChooserDialog(title, self.dialog, 
            action=gtk.FILE_CHOOSER_ACTION_OPEN,
            buttons=("Cancel", gtk.RESPONSE_CANCEL,
                     "Open", gtk.RESPONSE_OK))
        dialog.set_transient_for(self.dialog)
        dialog.set_modal(True)
                
        # set the filename if it is fully specified
        if os.path.isabs(filename):            
            dialog.set_filename(filename)
        
        response = dialog.run()
        
        if response == gtk.RESPONSE_OK:
            filename = dialog.get_filename()

            if name == "default_notebook":
                self.xml.get_widget("default_notebook_entry").\
                    set_text(filename)
            else:
                self.entries[name].set_text(filename)
            
        dialog.destroy()


    def on_set_default_notebook_button_clicked(self, widget):

        if self.main_window.notebook:
            self.xml.get_widget("default_notebook_entry").set_text(
                self.main_window.notebook.get_path())
            
        
    
    def on_ok_button_clicked(self, widget):
        # TODO: add arguments
    
        self.app.pref.default_notebook = \
            self.xml.get_widget("default_notebook_entry").get_text()

        # save autosave
        self.app.pref.autosave = \
            self.xml.get_widget("autosave_check").get_active()
        try:
            self.app.pref.autosave_time = \
                int(self.xml.get_widget("autosave_entry").get_text()) * 1000
        except:
            pass

        # use systray icon
        self.app.pref.use_systray = self.xml.get_widget("systray_check").get_active()
        self.app.pref.skip_taskbar = self.xml.get_widget("skip_taskbar_check").get_active()

        # look and feel
        self.app.pref.treeview_lines = self.treeview_lines_check.get_active()
        self.app.pref.listview_rules = self.listview_rules_check.get_active()
        self.app.pref.use_stock_icons = self.use_stock_icons_check.get_active()
        
        
        # save date formatting
        for name in ["same_day", "same_month", "same_year", "diff_year"]:
            self.app.pref.timestamp_formats[name] = \
                self.xml.get_widget("date_%s_entry" % name).get_text()
        

        # save external app options
        for key, entry in self.entries.iteritems():
            self.app.pref._external_apps_lookup[key].prog = \
                self.entries[key].get_text()

        # save notebook font        
        if self.main_window.notebook is not None:
            pref = self.main_window.notebook.pref
            pref.default_font = "%s %d" % (
                self.notebook_font_family.get_family(),
                self.notebook_font_size.get_value())

            self.main_window.notebook.write_preferences()
            self.main_window.notebook.notify_change(False)
            
        
        self.app.pref.write()
        self.app.pref.changed.notify()

        
        self.dialog.destroy()
        self.dialog = None
Beispiel #7
0
    def make_toolbar(self, toolbar, tips, use_stock_icons):

        # bold tool
        self.bold = self._make_toggle_button(
            toolbar, tips, "Bold", "bold.png", gtk.STOCK_BOLD,
            lambda: self._editor.get_textview().toggle_font_mod("bold"),
            use_stock_icons)

        # italic tool
        self.italic = self._make_toggle_button(
            toolbar, tips, "Italic", "italic.png", gtk.STOCK_ITALIC,
            lambda: self._editor.get_textview().toggle_font_mod("italic"),
            use_stock_icons)

        # underline tool
        self.underline = self._make_toggle_button(
            toolbar, tips, "Underline", "underline.png", gtk.STOCK_UNDERLINE,
            lambda: self._editor.get_textview().toggle_font_mod("underline"),
            use_stock_icons)

        # strikethrough
        self.strike = self._make_toggle_button(
            toolbar, tips, "Strike", "strike.png", gtk.STOCK_STRIKETHROUGH,
            lambda: self._editor.get_textview().toggle_font_mod("strike"),
            use_stock_icons)

        # fixed-width tool
        self.fixed_width = self._make_toggle_button(
            toolbar, tips, "Monospace", "fixed-width.png", None,
            lambda: self._editor.get_textview().toggle_font_mod("tt"),
            use_stock_icons)

        # link
        self.link = self._make_toggle_button(toolbar, tips, "Make Link",
                                             "link.png", None,
                                             self.on_toggle_link,
                                             use_stock_icons)

        # no wrap tool
        self.no_wrap = self._make_toggle_button(
            toolbar, tips, "No Wrapping", "no-wrap.png", None,
            lambda: self._editor.get_textview().toggle_font_mod("nowrap"),
            use_stock_icons)

        # family combo
        self.font_family_combo = FontSelector()
        self.font_family_combo.set_size_request(150, 25)
        item = gtk.ToolItem()
        item.add(self.font_family_combo)
        tips.set_tip(item, "Font Family")
        toolbar.insert(item, -1)
        self.font_family_id = self.font_family_combo.connect(
            "changed", lambda w: self.on_family_set())
        self._font_ui_signals.append(
            FontUI(self.font_family_combo, self.font_family_id))

        # font size
        DEFAULT_FONT_SIZE = 10
        self.font_size_button = gtk.SpinButton(
            gtk.Adjustment(value=DEFAULT_FONT_SIZE,
                           lower=2,
                           upper=500,
                           step_incr=1))
        self.font_size_button.set_size_request(-1, 25)
        #self.font_size_button.set_range(2, 100)
        self.font_size_button.set_value(DEFAULT_FONT_SIZE)
        self.font_size_button.set_editable(False)
        item = gtk.ToolItem()
        item.add(self.font_size_button)
        tips.set_tip(item, "Font Size")
        toolbar.insert(item, -1)
        self.font_size_id = self.font_size_button.connect(
            "value-changed",
            lambda w: self.on_font_size_change(self.font_size_button.get_value(
            )))
        self._font_ui_signals.append(
            FontUI(self.font_size_button, self.font_size_id))

        # font fg color
        # TODO: code in proper default color
        self.fg_color_button = FgColorTool(14, 15, (0, 0, 0))
        self.fg_color_button.connect(
            "set-color", lambda w, color: self.on_color_set("fg", color))
        tips.set_tip(self.fg_color_button, "Set Text Color")
        toolbar.insert(self.fg_color_button, -1)

        # font bg color
        self.bg_color_button = BgColorTool(14, 15, (65535, 65535, 65535))
        self.bg_color_button.connect(
            "set-color", lambda w, color: self.on_color_set("bg", color))
        tips.set_tip(self.bg_color_button, "Set Background Color")
        toolbar.insert(self.bg_color_button, -1)

        # separator
        toolbar.insert(gtk.SeparatorToolItem(), -1)

        # left tool
        self.left_align = self._make_toggle_button(
            toolbar, tips, "Left Align", "alignleft.png",
            gtk.STOCK_JUSTIFY_LEFT, lambda: self.on_justify("left"),
            use_stock_icons)

        # center tool
        self.center_align = self._make_toggle_button(
            toolbar, tips, "Center Align", "aligncenter.png",
            gtk.STOCK_JUSTIFY_CENTER, lambda: self.on_justify("center"),
            use_stock_icons)

        # right tool
        self.right_align = self._make_toggle_button(
            toolbar, tips, "Right Align", "alignright.png",
            gtk.STOCK_JUSTIFY_RIGHT, lambda: self.on_justify("right"),
            use_stock_icons)

        # justify tool
        self.fill_align = self._make_toggle_button(
            toolbar, tips, "Justify Align", "alignjustify.png",
            gtk.STOCK_JUSTIFY_FILL, lambda: self.on_justify("fill"),
            use_stock_icons)

        # bullet list tool
        self.bullet = self._make_toggle_button(toolbar, tips, "Bullet List",
                                               "bullet.png", None,
                                               lambda: self.on_bullet_list(),
                                               use_stock_icons)
Beispiel #8
0
class EditorMenus(gobject.GObject):
    def __init__(self, editor):
        gobject.GObject.__init__(self)

        self._editor = editor
        self._font_ui_signals = []  # list of font ui widgets

    #=============================================================
    # Update UI (menubar) from font under cursor

    def on_font_change(self, editor, font):
        """Update the toolbar reflect the font under the cursor"""

        # block toolbar handlers
        for ui in self._font_ui_signals:
            ui.widget.handler_block(ui.signal)

        # update font mods
        self.bold.widget.set_active(font.mods["bold"])
        self.italic.widget.set_active(font.mods["italic"])
        self.underline.widget.set_active(font.mods["underline"])
        self.strike.widget.set_active(font.mods["strike"])
        self.fixed_width.widget.set_active(font.mods["tt"])
        self.link.widget.set_active(font.link is not None)
        self.no_wrap.widget.set_active(font.mods["nowrap"])

        # update text justification
        self.left_align.widget.set_active(font.justify == "left")
        self.center_align.widget.set_active(font.justify == "center")
        self.right_align.widget.set_active(font.justify == "right")
        self.fill_align.widget.set_active(font.justify == "fill")

        # update bullet list
        self.bullet.widget.set_active(font.par_type == "bullet")

        # update family/size buttons
        self.font_family_combo.set_family(font.family)
        self.font_size_button.set_value(font.size)

        # unblock toolbar handlers
        for ui in self._font_ui_signals:
            ui.widget.handler_unblock(ui.signal)

    #==================================================
    # changing font handlers

    def on_mod(self, mod):
        """Toggle a font modification"""
        self._editor.get_textview().toggle_font_mod(mod)

        #font = self._editor.get_textview().get_font()
        #mod_button.handler_block(mod_id)
        #mod_button.set_active(font.mods[mod])
        #mod_button.handler_unblock(mod_id)

    def on_toggle_link(self):

        textview = self._editor.get_textview()
        textview.toggle_link()
        tag, start, end = textview.get_link()

        if tag is not None:
            self.emit("make-link")

    def on_justify(self, justify):
        """Set font justification"""
        self._editor.get_textview().set_justify(justify)
        font = self._editor.get_textview().get_font()
        self.on_font_change(self._editor, font)

    def on_bullet_list(self):
        """Toggle bullet list"""
        self._editor.get_textview().toggle_bullet()
        font = self._editor.get_textview().get_font()
        self.on_font_change(self._editor, font)

    def on_indent(self):
        """Indent current paragraph"""
        self._editor.get_textview().indent()

    def on_unindent(self):
        """Unindent current paragraph"""
        self._editor.get_textview().unindent()

    def on_family_set(self):
        """Set the font family"""
        self._editor.get_textview().set_font_family(
            self.font_family_combo.get_family())
        self._editor.get_textview().grab_focus()

    def on_font_size_change(self, size):
        """Set the font size"""
        self._editor.get_textview().set_font_size(size)
        self._editor.get_textview().grab_focus()

    def on_font_size_inc(self):
        """Increase font size"""
        font = self._editor.get_textview().get_font()
        font.size += 2
        self._editor.get_textview().set_font_size(font.size)
        self.on_font_change(self._editor, font)

    def on_font_size_dec(self):
        """Decrease font size"""
        font = self._editor.get_textview().get_font()
        if font.size > 4:
            font.size -= 2
        self._editor.get_textview().set_font_size(font.size)
        self.on_font_change(self._editor, font)

    def on_color_set(self, kind, color=0):
        """Set text/background color"""

        if color == 0:
            if kind == "fg":
                color = self.fg_color_button.color
            elif kind == "bg":
                color = self.bg_color_button.color
            else:
                color = None

        if color is not None:
            colorstr = color_tuple_to_string(color)
        else:
            colorstr = None

        if kind == "fg":
            self._editor.get_textview().set_font_fg_color(colorstr)
        elif kind == "bg":
            self._editor.get_textview().set_font_bg_color(colorstr)
        else:
            raise Exception("unknown color type '%s'" % str(kind))

    def on_choose_font(self):
        """Callback for opening Choose Font Dialog"""

        font = self._editor.get_textview().get_font()

        dialog = gtk.FontSelectionDialog("Choose Font")
        dialog.set_font_name("%s %d" % (font.family, font.size))
        response = dialog.run()

        if response == gtk.RESPONSE_OK:
            self._editor.get_textview().set_font(dialog.get_font_name())
            self._editor.get_textview().grab_focus()

        dialog.destroy()

    def _make_toggle_button(self,
                            toolbar,
                            tips,
                            tip_text,
                            icon,
                            stock_id=None,
                            func=lambda: None,
                            use_stock_icons=False):

        button = gtk.ToggleToolButton()
        if use_stock_icons and stock_id:
            button.set_stock_id(stock_id)
        else:
            button.set_icon_widget(get_resource_image(icon))
        signal = button.connect("toggled", lambda w: func())
        font_ui = FontUI(button, signal)
        self._font_ui_signals.append(font_ui)

        toolbar.insert(button, -1)
        tips.set_tip(button, tip_text)

        return font_ui

    def make_toolbar(self, toolbar, tips, use_stock_icons):

        # bold tool
        self.bold = self._make_toggle_button(
            toolbar, tips, "Bold", "bold.png", gtk.STOCK_BOLD,
            lambda: self._editor.get_textview().toggle_font_mod("bold"),
            use_stock_icons)

        # italic tool
        self.italic = self._make_toggle_button(
            toolbar, tips, "Italic", "italic.png", gtk.STOCK_ITALIC,
            lambda: self._editor.get_textview().toggle_font_mod("italic"),
            use_stock_icons)

        # underline tool
        self.underline = self._make_toggle_button(
            toolbar, tips, "Underline", "underline.png", gtk.STOCK_UNDERLINE,
            lambda: self._editor.get_textview().toggle_font_mod("underline"),
            use_stock_icons)

        # strikethrough
        self.strike = self._make_toggle_button(
            toolbar, tips, "Strike", "strike.png", gtk.STOCK_STRIKETHROUGH,
            lambda: self._editor.get_textview().toggle_font_mod("strike"),
            use_stock_icons)

        # fixed-width tool
        self.fixed_width = self._make_toggle_button(
            toolbar, tips, "Monospace", "fixed-width.png", None,
            lambda: self._editor.get_textview().toggle_font_mod("tt"),
            use_stock_icons)

        # link
        self.link = self._make_toggle_button(toolbar, tips, "Make Link",
                                             "link.png", None,
                                             self.on_toggle_link,
                                             use_stock_icons)

        # no wrap tool
        self.no_wrap = self._make_toggle_button(
            toolbar, tips, "No Wrapping", "no-wrap.png", None,
            lambda: self._editor.get_textview().toggle_font_mod("nowrap"),
            use_stock_icons)

        # family combo
        self.font_family_combo = FontSelector()
        self.font_family_combo.set_size_request(150, 25)
        item = gtk.ToolItem()
        item.add(self.font_family_combo)
        tips.set_tip(item, "Font Family")
        toolbar.insert(item, -1)
        self.font_family_id = self.font_family_combo.connect(
            "changed", lambda w: self.on_family_set())
        self._font_ui_signals.append(
            FontUI(self.font_family_combo, self.font_family_id))

        # font size
        DEFAULT_FONT_SIZE = 10
        self.font_size_button = gtk.SpinButton(
            gtk.Adjustment(value=DEFAULT_FONT_SIZE,
                           lower=2,
                           upper=500,
                           step_incr=1))
        self.font_size_button.set_size_request(-1, 25)
        #self.font_size_button.set_range(2, 100)
        self.font_size_button.set_value(DEFAULT_FONT_SIZE)
        self.font_size_button.set_editable(False)
        item = gtk.ToolItem()
        item.add(self.font_size_button)
        tips.set_tip(item, "Font Size")
        toolbar.insert(item, -1)
        self.font_size_id = self.font_size_button.connect(
            "value-changed",
            lambda w: self.on_font_size_change(self.font_size_button.get_value(
            )))
        self._font_ui_signals.append(
            FontUI(self.font_size_button, self.font_size_id))

        # font fg color
        # TODO: code in proper default color
        self.fg_color_button = FgColorTool(14, 15, (0, 0, 0))
        self.fg_color_button.connect(
            "set-color", lambda w, color: self.on_color_set("fg", color))
        tips.set_tip(self.fg_color_button, "Set Text Color")
        toolbar.insert(self.fg_color_button, -1)

        # font bg color
        self.bg_color_button = BgColorTool(14, 15, (65535, 65535, 65535))
        self.bg_color_button.connect(
            "set-color", lambda w, color: self.on_color_set("bg", color))
        tips.set_tip(self.bg_color_button, "Set Background Color")
        toolbar.insert(self.bg_color_button, -1)

        # separator
        toolbar.insert(gtk.SeparatorToolItem(), -1)

        # left tool
        self.left_align = self._make_toggle_button(
            toolbar, tips, "Left Align", "alignleft.png",
            gtk.STOCK_JUSTIFY_LEFT, lambda: self.on_justify("left"),
            use_stock_icons)

        # center tool
        self.center_align = self._make_toggle_button(
            toolbar, tips, "Center Align", "aligncenter.png",
            gtk.STOCK_JUSTIFY_CENTER, lambda: self.on_justify("center"),
            use_stock_icons)

        # right tool
        self.right_align = self._make_toggle_button(
            toolbar, tips, "Right Align", "alignright.png",
            gtk.STOCK_JUSTIFY_RIGHT, lambda: self.on_justify("right"),
            use_stock_icons)

        # justify tool
        self.fill_align = self._make_toggle_button(
            toolbar, tips, "Justify Align", "alignjustify.png",
            gtk.STOCK_JUSTIFY_FILL, lambda: self.on_justify("fill"),
            use_stock_icons)

        # bullet list tool
        self.bullet = self._make_toggle_button(toolbar, tips, "Bullet List",
                                               "bullet.png", None,
                                               lambda: self.on_bullet_list(),
                                               use_stock_icons)

    def get_format_menu(self):

        return [
            ("/Fo_rmat", None, None, 0, "<Branch>"),
            ("/Format/_Bold", "<control>B", lambda w, e: self.on_mod("bold"),
             0, "<ImageItem>", get_resource_pixbuf("bold.png")),
            ("/Format/_Italic", "<control>I",
             lambda w, e: self.on_mod("italic"), 0, "<ImageItem>",
             get_resource_pixbuf("italic.png")),
            ("/Format/_Underline", "<control>U",
             lambda w, e: self.on_mod("underline"), 0, "<ImageItem>",
             get_resource_pixbuf("underline.png")),
            ("/Format/S_trike", "", lambda w, e: self.on_mod("strike"), 0,
             "<ImageItem>", get_resource_pixbuf("strike.png")),
            ("/Format/_Monospace", "<control>M",
             lambda w, e: self.on_mod("tt"), 0, "<ImageItem>",
             get_resource_pixbuf("fixed-width.png")),
            ("/Format/Lin_k", "<control>L", lambda w, e: self.on_toggle_link(),
             0, "<ImageItem>", get_resource_pixbuf("link.png")),
            ("/Format/No _Wrapping", None, lambda w, e: self.on_mod("nowrap"),
             0, "<ImageItem>", get_resource_pixbuf("no-wrap.png")),
            ("/Format/sep1", None, None, 0, "<Separator>"),
            ("/Format/_Left Align", "<shift><control>L",
             lambda w, e: self.on_justify("left"), 0, "<ImageItem>",
             get_resource_pixbuf("alignleft.png")),
            ("/Format/C_enter Align", "<shift><control>E",
             lambda w, e: self.on_justify("center"), 0, "<ImageItem>",
             get_resource_pixbuf("aligncenter.png")),
            ("/Format/_Right Align", "<shift><control>R",
             lambda w, e: self.on_justify("right"), 0, "<ImageItem>",
             get_resource_pixbuf("alignright.png")),
            ("/Format/_Justify Align", "<shift><control>J",
             lambda w, e: self.on_justify("fill"), 0, "<ImageItem>",
             get_resource_pixbuf("alignjustify.png")),
            ("/Format/sep2", None, None, 0, "<Separator>"),
            ("/Format/_Bullet List", "<control>asterisk",
             lambda w, e: self.on_bullet_list(), 0, "<ImageItem>",
             get_resource_pixbuf("bullet.png")),
            ("/Format/Indent M_ore", "<control>parenright",
             lambda w, e: self.on_indent(), 0, "<ImageItem>",
             get_resource_pixbuf("indent-more.png")),
            ("/Format/Indent Le_ss", "<control>parenleft",
             lambda w, e: self.on_unindent(), 0, "<ImageItem>",
             get_resource_pixbuf("indent-less.png")),
            ("/Format/sep4", None, None, 0, "<Separator>"),
            ("/Format/Increase Font _Size", "<control>equal",
             lambda w, e: self.on_font_size_inc(), 0, "<ImageItem>",
             get_resource_pixbuf("font-inc.png")),
            ("/Format/_Decrease Font Size", "<control>minus",
             lambda w, e: self.on_font_size_dec(), 0, "<ImageItem>",
             get_resource_pixbuf("font-dec.png")),
            ("/Format/sep5", None, None, 0, "<Separator>"),
            ("/Format/_Apply Text Color", "",
             lambda w, e: self.on_color_set("fg"), 0),
            ("/Format/A_pply Background Color", "",
             lambda w, e: self.on_color_set("bg"), 0),
            ("/Format/sep6", None, None, 0, "<Separator>"),
            ("/Format/Choose _Font", "<control><shift>F",
             lambda w, e: self.on_choose_font(), 0, "<ImageItem>",
             get_resource_pixbuf("font.png"))
        ]