diff --git a/README.md b/README.md
index f6caec73d..84b936408 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ Requirements
The following packages **MUST** be installed in order for Gramps to work:
* **Python** 3.2 or greater - The programming language used by Gramps. https://www.python.org/
-* **GTK** 3.10 or greater - A cross-platform widget toolkit for creating graphical user interfaces. http://www.gtk.org/
+* **GTK** 3.12 or greater - A cross-platform widget toolkit for creating graphical user interfaces. http://www.gtk.org/
* **pygobject** 3.12 or greater - Python Bindings for GLib/GObject/GIO/GTK+ https://wiki.gnome.org/Projects/PyGObject
The following three packages with GObject Introspection bindings (the gi packages)
diff --git a/gramps/grampsapp.py b/gramps/grampsapp.py
index 3e7feb5df..97f737275 100644
--- a/gramps/grampsapp.py
+++ b/gramps/grampsapp.py
@@ -459,12 +459,12 @@ def run():
if argpars.need_gui():
LOG.debug("A GUI is needed, set it up")
try:
- from .gui.grampsgui import startgtkloop
+ from .gui.grampsgui import startgramps
# no DISPLAY is a RuntimeError in an older pygtk (e.g. F14's 2.17)
except RuntimeError as msg:
error += [(_("Configuration error:"), str(msg))]
return error
- startgtkloop(error, argpars)
+ startgramps(error, argpars)
else:
# CLI use of Gramps
argpars.print_help()
diff --git a/gramps/gui/actiongroup.py b/gramps/gui/actiongroup.py
deleted file mode 100644
index f24c73a6f..000000000
--- a/gramps/gui/actiongroup.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2015 Nick Hall
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-
-"""
-A replacement ActionGroup that correctly loads named icons from an icon theme.
-"""
-
-from gi.repository import Gtk
-
-class ActionGroup(Gtk.ActionGroup):
-
- def add_actions(self, action_list, **kwargs):
- Gtk.ActionGroup.add_actions(self, action_list, **kwargs)
- self.fix_icon_name(action_list)
-
- def add_toggle_actions(self, action_list, **kwargs):
- Gtk.ActionGroup.add_toggle_actions(self, action_list, **kwargs)
- self.fix_icon_name(action_list)
-
- def add_radio_actions(self, action_list, **kwargs):
- Gtk.ActionGroup.add_radio_actions(self, action_list, **kwargs)
- self.fix_icon_name(action_list)
-
- def fix_icon_name(self, action_list):
- for action_tuple in action_list:
- if action_tuple[1]:
- action = self.get_action(action_tuple[0])
- action.set_icon_name(action_tuple[1])
diff --git a/gramps/gui/displaystate.py b/gramps/gui/displaystate.py
index 936bc9d60..758f9a824 100644
--- a/gramps/gui/displaystate.py
+++ b/gramps/gui/displaystate.py
@@ -28,6 +28,7 @@
#-------------------------------------------------------------------------
import os
from io import StringIO
+import html
#-------------------------------------------------------------------------
#
@@ -65,6 +66,7 @@ from .glade import Glade
from gramps.gen.utils.db import navigation_label
from .widgets.progressdialog import ProgressMonitor, GtkProgressDialog
from .dialog import ErrorDialog
+from .uimanager import ActionGroup
DISABLED = -1
@@ -246,14 +248,34 @@ class History(Callback):
#
#-------------------------------------------------------------------------
-_RCT_TOP = ''
+_RCT_TOP = '\n'
+_RCT_BAR_TOP = ('\n'
+
from gramps.gen.recentfiles import RecentFiles
class RecentDocsMenu:
def __init__(self, uistate, state, fileopen):
- self.action_group = Gtk.ActionGroup(name='RecentFiles')
+ self.ui_xml = []
+ self.action_group = ActionGroup('RecentFiles')
self.active = DISABLED
self.uistate = uistate
self.uimanager = uistate.uimanager
@@ -268,55 +290,52 @@ class RecentDocsMenu:
ErrorDialog(_('Cannot load database'), str(err),
parent=self.uistate.window)
- def build(self):
- buf = StringIO()
- buf.write(_RCT_TOP)
+ def build(self, update_menu=True):
gramps_rf = RecentFiles()
count = 0
if self.active != DISABLED:
- self.uimanager.remove_ui(self.active)
+ self.uimanager.remove_ui(self.ui_xml)
self.uimanager.remove_action_group(self.action_group)
- self.action_group = Gtk.ActionGroup(name='RecentFiles')
self.active = DISABLED
- actions = []
+ actionlist = []
+ menu = _RCT_TOP
+ bar = _RCT_BAR_TOP
rfiles = gramps_rf.gramps_recent_files
rfiles.sort(key=lambda x: x.get_time(), reverse=True)
- new_menu = Gtk.Menu()
+ #new_menu = Gtk.Menu()
+ #new_menu.set_tooltip_text(_("Connect to a recent database"))
for item in rfiles:
try:
- title = item.get_name()
+ title = html.escape(item.get_name())
filename = os.path.basename(item.get_path())
action_id = "RecentMenu%d" % count
- buf.write('' % action_id)
- actions.append((action_id, None, title, None, None,
- make_callback(item, self.load)))
- mitem = Gtk.MenuItem(label=title, use_underline=False)
- mitem.connect('activate', make_callback(item, self.load))
- mitem.show()
- new_menu.append(mitem)
+ # add the menuitem for this file
+ menu += _RCT_MENU % (action_id, title)
+ # add the action for this file
+ actionlist.append((action_id, make_callback(item, self.load)))
+ # add the toolbar menuitem
+ bar += _RCT_BAR % (action_id, title)
except RuntimeError:
# ignore no longer existing files
_LOG.info("Ignoring the RecentItem %s (%s)" % (title, filename))
count += 1
- buf.write(_RCT_BTM)
- self.action_group.add_actions(actions)
- self.uimanager.insert_action_group(self.action_group, 1)
- self.active = self.uimanager.add_ui_from_string(buf.getvalue())
- self.uimanager.ensure_update()
- buf.close()
-
- if len(rfiles) > 0:
- new_menu.show()
- self.uistate.set_open_recent_menu(new_menu)
+ menu += _RCT_BTM
+ bar += _RCT_BAR_BTM
+ self.ui_xml = [menu, bar]
+ self.action_group.add_actions(actionlist)
+ self.uimanager.insert_action_group(self.action_group)
+ self.active = self.uimanager.add_ui_from_string(self.ui_xml)
+ if update_menu:
+ self.uimanager.update_menu()
def make_callback(val, func):
- return lambda x: func(val)
+ return lambda x, y: func(val)
from .logger import RotateHandler
diff --git a/gramps/gui/editors/editnote.py b/gramps/gui/editors/editnote.py
index a80c2682b..7b2756d31 100644
--- a/gramps/gui/editors/editnote.py
+++ b/gramps/gui/editors/editnote.py
@@ -180,7 +180,6 @@ class EditNote(EditPrimary):
self.set_window(win, None, self.get_menu_title())
self.setup_configs('interface.note', 700, 500)
-
vboxnote = self.top.get_object('vbox131')
notebook = self.top.get_object('note_notebook')
#recreate start page as GrampsTab
@@ -271,7 +270,9 @@ class EditNote(EditPrimary):
# create a formatting toolbar
if not self.dbstate.db.readonly:
vbox = self.top.get_object('container')
- vbox.pack_start(self.texteditor.get_toolbar(), False, False, 0)
+ toolbar, self.action_group = self.texteditor.create_toolbar(
+ self.uistate.uimanager, self.window)
+ vbox.pack_start(toolbar, False, False, 0)
self.texteditor.set_transient_parent(self.window)
# setup initial values for textview and textbuffer
diff --git a/gramps/gui/editors/editperson.py b/gramps/gui/editors/editperson.py
index cd8276a52..c54c31e86 100644
--- a/gramps/gui/editors/editperson.py
+++ b/gramps/gui/editors/editperson.py
@@ -676,33 +676,33 @@ class EditPerson(EditPrimary):
EditMediaRef(self.dbstate, self.uistate, self.track,
media_obj, media_ref, self.load_photo)
- def _top_contextmenu(self):
+ def _top_contextmenu(self, prefix):
"""
Override from base class, the menuitems and actiongroups for the top
of context menu.
"""
- self.all_action = Gtk.ActionGroup(name="/PersonAll")
- self.home_action = Gtk.ActionGroup(name="/PersonHome")
- self.track_ref_for_deletion("all_action")
- self.track_ref_for_deletion("home_action")
+ if self.added:
+ # Don't add items if not a real person yet
+ return '', []
- self.all_action.add_actions([
- ('ActivePerson', None, _("Make Active Person"),
- None, None, self._make_active),
- ])
- self.home_action.add_actions([
- ('HomePerson', 'go-home', _("Make Home Person"),
- None, None, self._make_home_person),
- ])
+ _actions = [('ActivePerson', self._make_active),
+ ('HomePerson', self._make_home_person)]
- self.all_action.set_visible(not self.added)
- self.home_action.set_visible(not self.added)
+ ui_top_cm = (
+ '''
+ -
+ {prefix}.ActivePerson
+ Make Active Person'''
+ '''
+
+ -
+ {prefix}.HomePerson
+ Make Home Person'''
+ '''
+
+ '''.format(prefix=prefix))
- ui_top_cm = '''
-
- '''
-
- return ui_top_cm, [self.all_action, self.home_action]
+ return ui_top_cm, _actions
def _top_drag_data_get(self, widget, context, sel_data, info, time):
if info == DdTargets.PERSON_LINK.app_id:
@@ -713,17 +713,21 @@ class EditPerson(EditPrimary):
"""
Override base class, make inactive home action if not needed.
"""
+ if self.added:
+ return
+ home_action = self.uistate.uimanager.get_action(self.action_group,
+ 'HomePerson')
if (self.dbstate.db.get_default_person() and
self.obj.get_handle() ==
self.dbstate.db.get_default_person().get_handle()):
- self.home_action.set_sensitive(False)
+ home_action.set_enabled(False)
else:
- self.home_action.set_sensitive(True)
+ home_action.set_enabled(True)
- def _make_active(self, obj):
+ def _make_active(self, obj, value):
self.uistate.set_active(self.obj.get_handle(), 'Person')
- def _make_home_person(self, obj):
+ def _make_home_person(self, obj, value):
handle = self.obj.get_handle()
if handle:
self.dbstate.db.set_default_person_handle(handle)
diff --git a/gramps/gui/editors/editprimary.py b/gramps/gui/editors/editprimary.py
index 567ddb77a..4a8083281 100644
--- a/gramps/gui/editors/editprimary.py
+++ b/gramps/gui/editors/editprimary.py
@@ -32,6 +32,7 @@ import abc
#
#-------------------------------------------------------------------------
from gi.repository import Gtk
+from gi.repository.Gio import SimpleActionGroup
#-------------------------------------------------------------------------
#
@@ -49,6 +50,8 @@ from ..display import display_help
from ..dialog import SaveDialog
from gramps.gen.lib import PrimaryObject
from ..dbguielement import DbGUIElement
+from ..uimanager import ActionGroup
+
class EditPrimary(ManagedWindow, DbGUIElement, metaclass=abc.ABCMeta):
@@ -75,6 +78,7 @@ class EditPrimary(ManagedWindow, DbGUIElement, metaclass=abc.ABCMeta):
self.get_from_gramps_id = get_from_gramps_id
self.contexteventbox = None
self.__tabs = []
+ self.action_group = None
ManagedWindow.__init__(self, uistate, track, obj)
DbGUIElement.__init__(self, self.db)
@@ -184,6 +188,8 @@ class EditPrimary(ManagedWindow, DbGUIElement, metaclass=abc.ABCMeta):
self.dbstate.disconnect(self.dbstate_connect_key)
self._cleanup_connects()
self._cleanup_on_exit()
+ if self.action_group:
+ self.uistate.uimanager.remove_action_group(self.action_group)
self.get_from_handle = None
self.get_from_gramps_id = None
ManagedWindow.close(self)
@@ -283,48 +289,62 @@ class EditPrimary(ManagedWindow, DbGUIElement, metaclass=abc.ABCMeta):
return False
#build the possible popup menu
- self._build_popup_ui()
+ menu_model = self._build_popup_ui()
+ if not menu_model:
+ return False
#set or unset sensitivity in popup
self._post_build_popup_ui()
- menu = self.popupmanager.get_widget('/Popup')
- if menu:
- menu.popup(None, None, None, None, event.button, event.time)
- return True
+ menu = Gtk.Menu.new_from_model(menu_model)
+ menu.attach_to_widget(obj, None)
+ menu.show_all()
+ if Gtk.MINOR_VERSION < 22:
+ # ToDo The following is reported to work poorly with Wayland
+ menu.popup(None, None, None, None,
+ event.button, event.time)
+ else:
+ menu.popup_at_pointer(event)
+ return True
return False
def _build_popup_ui(self):
"""
Create actions and ui of context menu
+ If you don't need a popup, override this and return None
"""
from ..plug.quick import create_quickreport_menu
- self.popupmanager = Gtk.UIManager()
- #add custom actions
- (ui_top, action_groups) = self._top_contextmenu()
- for action in action_groups :
- self.popupmanager.insert_action_group(action, -1)
+ prefix = str(id(self))
+ #get custom ui and actions
+ (ui_top, actions) = self._top_contextmenu(prefix)
#see which quick reports are available now:
ui_qr = ''
if self.QR_CATEGORY > -1 :
- (ui_qr, reportactions) = create_quickreport_menu(self.QR_CATEGORY,
- self.dbstate, self.uistate,
- self.obj, track=self.track)
- self.report_action = Gtk.ActionGroup(name="/PersonReport")
- self.report_action.add_actions(reportactions)
- self.report_action.set_visible(True)
- self.popupmanager.insert_action_group(self.report_action, -1)
+ (ui_qr, reportactions) = create_quickreport_menu(
+ self.QR_CATEGORY, self.dbstate, self.uistate,
+ self.obj, prefix, track=self.track)
+ actions.extend(reportactions)
- popupui = '''
-
- ''' + ui_top + '''
- ''' + ui_qr + '''
-
- '''
+ popupui = '''
+
+
+ '''
- self.popupmanager.add_ui_from_string(popupui)
+ builder = Gtk.Builder.new_from_string(popupui, -1)
- def _top_contextmenu(self):
+ self.action_group = ActionGroup('EditPopup' + prefix, actions,
+ prefix)
+ act_grp = SimpleActionGroup()
+ self.window.insert_action_group(prefix, act_grp)
+ self.window.set_application(self.uistate.uimanager.app)
+ self.uistate.uimanager.insert_action_group(self.action_group, act_grp)
+ return builder.get_object('Popup')
+
+ def _top_contextmenu(self, prefix):
"""
Derived class can create a ui with menuitems and corresponding list of
actiongroups
diff --git a/gramps/gui/grampsgui.py b/gramps/gui/grampsgui.py
index a1d273b15..7d01e55ab 100644
--- a/gramps/gui/grampsgui.py
+++ b/gramps/gui/grampsgui.py
@@ -3,6 +3,7 @@
#
# Copyright (C) 2000-2006 Donald N. Allingham
# Copyright (C) 2009 Benny Malengier
+# Copyright (C) 2018 Paul Culley
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -50,7 +51,365 @@ _ = glocale.translation.gettext
MIN_PYGOBJECT_VERSION = (3, 12, 0)
PYGOBJ_ERR = False
-MIN_GTK_VERSION = (3, 10)
+MIN_GTK_VERSION = (3, 12)
+UIDEFAULT = (
+ '''
+
+
+
+
+
+
+
+
+
+
+''')
try:
#import gnome introspection, part of pygobject
@@ -235,9 +594,8 @@ class Gramps:
process. It may spawn several windows and control several databases.
"""
- def __init__(self, argparser):
+ def __init__(self, argparser, app):
from gramps.gen.dbstate import DbState
- from . import viewmanager
from .viewmanager import ViewManager
from gramps.cli.arghandler import ArgHandler
from .tipofday import TipOfDay
@@ -248,7 +606,7 @@ class Gramps:
theme.append_search_path(IMAGE_DIR)
dbstate = DbState()
- self._vm = ViewManager(dbstate,
+ self._vm = ViewManager(app, dbstate,
config.get("interface.view-categories"))
if (lin()
@@ -303,68 +661,18 @@ class Gramps:
#
#-------------------------------------------------------------------------
-def __startgramps(errors, argparser):
+def startgramps(errors, argparser):
"""
Main startup function started via GObject.timeout_add
First action inside the gtk loop
"""
- try:
- from .dialog import ErrorDialog
- #handle first existing errors in GUI fashion
- if errors:
- for error in errors:
- ErrorDialog(error[0], error[1]) # TODO no-parent
- Gtk.main_quit()
- sys.exit(1)
-
- if argparser.errors:
- for error in argparser.errors:
- ErrorDialog(error[0], error[1]) # TODO no-parent
- Gtk.main_quit()
- sys.exit(1)
-
- # add gui logger
- from .logger import RotateHandler, GtkHandler
- form = logging.Formatter(
- fmt="%(relativeCreated)d: %(levelname)s: "
- "%(filename)s: line %(lineno)d: %(message)s")
- # Create the log handlers
- rot_h = RotateHandler(capacity=20)
- rot_h.setFormatter(form)
- # Only error and critical log records should
- # trigger the GUI handler.
- gtkh = GtkHandler(rotate_handler=rot_h)
- gtkh.setFormatter(form)
- gtkh.setLevel(logging.ERROR)
- logger = logging.getLogger()
- logger.addHandler(rot_h)
- logger.addHandler(gtkh)
-
- except:
- #make sure there is a clean exit if there is an error in above steps
- quit_now = True
- exit_code = 1
- LOG.error(_("\nGramps failed to start. "
- "Please report a bug about this.\n"
- "This could be because of an error "
- "in a (third party) View on startup.\n"
- "To use another view, don't load a Family Tree, "
- "change view, and then load your Family Tree.\n"
- "You can also change manually "
- "the startup view in the gramps.ini file \n"
- "by changing the last-view parameter.\n"
- ), exc_info=True)
-
- # start Gramps, errors stop the gtk loop
+ app = GrampsApplication(errors, argparser)
try:
quit_now = False
exit_code = 0
- if has_display():
- Gramps(argparser)
- else:
+ if app.run():
print(_("Gramps terminated because of no DISPLAY"))
- quit_now = True
- exit_code = 1
+
except SystemExit as err:
quit_now = True
if err.code:
@@ -395,18 +703,85 @@ def __startgramps(errors, argparser):
), exc_info=True)
if quit_now:
- #stop gtk loop and quit
- Gtk.main_quit()
+ app.quit()
sys.exit(exit_code)
- #function finished, return False to stop the timeout_add function calls
return False
-def startgtkloop(errors, argparser):
- """
- We start the gtk loop and run the function to start up Gramps
- """
- GLib.timeout_add(100, __startgramps, errors, argparser, priority=100)
- if os.path.exists(os.path.join(DATA_DIR, "gramps.accel")):
- Gtk.AccelMap.load(os.path.join(DATA_DIR, "gramps.accel"))
- Gtk.main()
+# we do the following import here to avoid the Gtk require version warning
+from .uimanager import UIManager
+
+
+class GrampsApplication(Gtk.Application):
+
+ def __init__(self, errors, argparser):
+ super().__init__(application_id="org.gramps-project.Gramps")
+ self.window = None
+ self.errors = errors
+ self.argparser = argparser
+
+ def do_startup(self):
+ Gtk.Application.do_startup(self)
+ self.uimanager = UIManager(self, UIDEFAULT)
+ self.uimanager.update_menu(init=True)
+
+ if os.path.exists(os.path.join(DATA_DIR, "gramps.accel")):
+ self.uimanager.load_accels(os.path.join(DATA_DIR, "gramps.accel"))
+ try:
+ from .dialog import ErrorDialog
+ #handle first existing errors in GUI fashion
+ if self.errors:
+ for error in self.errors:
+ ErrorDialog(error[0], error[1]) # TODO no-parent
+ Gtk.main_quit()
+ sys.exit(1)
+
+ if self.argparser.errors:
+ for error in self.argparser.errors:
+ ErrorDialog(error[0], error[1]) # TODO no-parent
+ Gtk.main_quit()
+ sys.exit(1)
+
+ # add gui logger
+ from .logger import RotateHandler, GtkHandler
+ form = logging.Formatter(
+ fmt="%(relativeCreated)d: %(levelname)s: "
+ "%(filename)s: line %(lineno)d: %(message)s")
+ # Create the log handlers
+ rot_h = RotateHandler(capacity=20)
+ rot_h.setFormatter(form)
+ # Only error and critical log records should
+ # trigger the GUI handler.
+ gtkh = GtkHandler(rotate_handler=rot_h)
+ gtkh.setFormatter(form)
+ gtkh.setLevel(logging.ERROR)
+ logger = logging.getLogger()
+ logger.addHandler(rot_h)
+ logger.addHandler(gtkh)
+
+ except:
+ #make sure there is a clean exit if error in above steps
+ exit_code = 1
+ LOG.error(_("\nGramps failed to start. "
+ "Please report a bug about this.\n"
+ "This could be because of an error "
+ "in a (third party) View on startup.\n"
+ "To use another view, don't load a Family Tree, "
+ "change view, and then load your Family Tree.\n"
+ "You can also change manually "
+ "the startup view in the gramps.ini file \n"
+ "by changing the last-view parameter.\n"
+ ), exc_info=True)
+ #stop gtk loop and quit
+ self.quit()
+ sys.exit(exit_code)
+
+ def do_activate(self):
+ # We only allow a single window and raise any existing ones
+ if not self.window:
+ # Windows are associated with the application
+ # when the last one is closed the application shuts down
+ Gramps(self.argparser, self)
+ else:
+ print('Gramps is already running.')
+ self.window.present()
diff --git a/gramps/gui/managedwindow.py b/gramps/gui/managedwindow.py
index a6b41a1af..7aa8d0997 100644
--- a/gramps/gui/managedwindow.py
+++ b/gramps/gui/managedwindow.py
@@ -31,7 +31,7 @@ the create/deletion of dialog windows.
#-------------------------------------------------------------------------
import os
from io import StringIO
-
+import html
#-------------------------------------------------------------------------
#
# GNOME/GTK
@@ -49,6 +49,7 @@ from gramps.gen.const import GLADE_FILE, ICON
from gramps.gen.errors import WindowActiveError
from gramps.gen.config import config
from gramps.gen.constfunc import is_quartz
+from .uimanager import ActionGroup
from .glade import Glade
#-------------------------------------------------------------------------
@@ -57,8 +58,8 @@ from .glade import Glade
#
#-------------------------------------------------------------------------
-_win_top = ''
-_win_btm = ''
+_win_top = '\n'
DISABLED = -1
#-----------------------------------------------------------------------
@@ -108,7 +109,7 @@ class GrampsWindowManager:
self.uimanager = uimanager
self.window_tree = []
self.id2item = {}
- self.action_group = Gtk.ActionGroup(name='WindowManger')
+ self.action_group = ActionGroup(name='WindowManger')
self.active = DISABLED
self.ui = _win_top + _win_btm
@@ -125,9 +126,9 @@ class GrampsWindowManager:
"""
Enables the UI and action groups
"""
- self.uimanager.insert_action_group(self.action_group, 1)
- self.active = self.uimanager.add_ui_from_string(self.ui)
- self.uimanager.ensure_update()
+ self.uimanager.insert_action_group(self.action_group)
+ self.active = self.uimanager.add_ui_from_string([self.ui])
+ self.uimanager.update_menu()
def get_item_from_track(self, track):
# Recursively find an item given track sequence
@@ -270,31 +271,35 @@ class GrampsWindowManager:
def call_back_factory(self, item):
if not isinstance(item, list):
- def func(obj):
+ def func(*obj):
if item.window_id and self.id2item.get(item.window_id):
self.id2item[item.window_id]._present()
else:
- def func(obj):
+ def func(*obj):
pass
return func
def generate_id(self, item):
- return str(item.window_id)
+ return 'wm/' + str(item.window_id)
def display_menu_list(self, data, action_data, mlist):
+ menuitem = ('- \n'
+ 'win.%s\n'
+ ''
+ '%s...\n'
+ '
\n')
if isinstance(mlist, (list, tuple)):
i = mlist[0]
idval = self.generate_id(i)
- data.write('
' % idval)
- action_data.append(("M:"+idval, None, i.submenu_label,
- None, None, None))
+ data.write('\n%s\n' %
+ html.escape(i.submenu_label))
else:
i = mlist
idval = self.generate_id(i)
- data.write('' % idval)
- action_data.append((idval, None, i.menu_label, None, None,
- self.call_back_factory(i)))
+ data.write(menuitem % (idval, html.escape(i.menu_label)))
+ action_data.append((idval, self.call_back_factory(i)))
if isinstance(mlist, (list, tuple)) and (len(mlist) > 1):
for i in mlist[1:]:
@@ -302,20 +307,17 @@ class GrampsWindowManager:
self.display_menu_list(data, action_data, i)
else:
idval = self.generate_id(i)
- data.write(''
- % self.generate_id(i))
- action_data.append((idval, None, i.menu_label,
- None, None,
- self.call_back_factory(i)))
+ data.write(menuitem % (idval, html.escape(i.menu_label)))
+ action_data.append((idval, self.call_back_factory(i)))
if isinstance(mlist, (list, tuple)):
- data.write('')
+ data.write('\n')
def build_windows_menu(self):
if self.active != DISABLED:
self.uimanager.remove_ui(self.active)
self.uimanager.remove_action_group(self.action_group)
- self.action_group = Gtk.ActionGroup(name='WindowManger')
+ self.action_group = ActionGroup(name='WindowManger')
action_data = []
data = StringIO()
diff --git a/gramps/gui/navigator.py b/gramps/gui/navigator.py
index 36a86e997..830a466d9 100644
--- a/gramps/gui/navigator.py
+++ b/gramps/gui/navigator.py
@@ -38,22 +38,21 @@ from gi.repository import Gdk
#-------------------------------------------------------------------------
from gramps.gen.plug import (START, END)
from .pluginmanager import GuiPluginManager
-from .actiongroup import ActionGroup
+from .uimanager import ActionGroup
#-------------------------------------------------------------------------
#
# Constants
#
#-------------------------------------------------------------------------
-UICATEGORY = '''
-
-
- %s
-
-
-
-
-'''
+UICATEGORY = '''
+ '''
+UICATAGORYBAR = '''
+ %s
+
+ '''
CATEGORY_ICON = {
'Dashboard': 'gramps-gramplet',
@@ -88,7 +87,6 @@ class Navigator:
self.active_view = None
self.ui_category = {}
- self.view_toggle_actions = {}
self.cat_view_group = None
self.merge_ids = []
@@ -139,13 +137,35 @@ class Navigator:
"""
Load the sidebar plugins.
"""
+ menuitem = '''
+ -
+ win.ViewInCatagory
+ %s
+ %d %d
+
+ '''
+ baritem = '''
+
+
+ win.ViewInCatagory
+ '%d %d'
+ %s
+ %s
+ %s
+
+
+ False
+
+
+ '''
+
plugman = GuiPluginManager.get_instance()
categories = []
views = {}
for cat_num, cat_views in enumerate(self.viewmanager.get_views()):
uimenuitems = ''
- self.view_toggle_actions[cat_num] = []
+ uibaritems = ''
for view_num, page in enumerate(cat_views):
if view_num == 0:
@@ -156,26 +176,26 @@ class Navigator:
cat_icon = 'gramps-view'
categories.append([cat_num, cat_name, cat_icon])
- pageid = 'page_%i_%i' % (cat_num, view_num)
- uimenuitems += '\n' % pageid
- # id, stock, button text, UI, tooltip, page
if view_num < 9:
- modifier = "%d" % ((view_num % 9) + 1)
- else:
- modifier = ""
+ accel = "%d" % ((view_num % 9) + 1)
+ self.viewmanager.uimanager.app.set_accels_for_action(
+ "win.ViewInCatagory('%d %d')" % (cat_num, view_num),
+ [accel])
+ uimenuitems += menuitem % (page[0].name, cat_num, view_num)
stock_icon = page[0].stock_icon
if stock_icon is None:
stock_icon = cat_icon
- self.view_toggle_actions[cat_num].append((pageid,
- stock_icon,
- page[0].name, modifier, page[0].name, view_num))
+ uibaritems += baritem % (view_num, cat_num, view_num,
+ stock_icon, page[0].name,
+ page[0].name)
views[cat_num].append((view_num, page[0].name, stock_icon))
if len(cat_views) > 1:
#allow for switching views in a category
- self.ui_category[cat_num] = UICATEGORY % uimenuitems
+ self.ui_category[cat_num] = [UICATEGORY % uimenuitems,
+ UICATAGORYBAR % uibaritems]
for pdata in plugman.get_reg_sidebars():
module = plugman.load_plugin(pdata)
@@ -229,12 +249,10 @@ class Navigator:
list(map(uimanager.remove_ui, self.merge_ids))
if cat_num in self.ui_category:
- self.cat_view_group = ActionGroup(name='viewmenu')
- self.cat_view_group.add_radio_actions(
- self.view_toggle_actions[cat_num], value=view_num,
- on_change=self.cb_view_clicked, user_data=cat_num)
- self.cat_view_group.set_sensitive(True)
- uimanager.insert_action_group(self.cat_view_group, 1)
+ action = ('ViewInCatagory', self.cb_view_clicked, '',
+ str(cat_num) + ' ' + str(view_num))
+ self.cat_view_group = ActionGroup('viewmenu', [action])
+ uimanager.insert_action_group(self.cat_view_group)
mergeid = uimanager.add_ui_from_string(self.ui_category[cat_num])
self.merge_ids.append(mergeid)
@@ -245,12 +263,12 @@ class Navigator:
return
sidebar.view_changed(cat_num, view_num)
- def cb_view_clicked(self, radioaction, current, cat_num):
+ def cb_view_clicked(self, radioaction, value):
"""
Called when a view is selected from the menu.
"""
- view_num = radioaction.get_current_value()
- self.viewmanager.goto_page(cat_num, view_num)
+ cat_num, view_num = value.get_string().split()
+ self.viewmanager.goto_page(int(cat_num), int(view_num))
def __menu_button_pressed(self, button, event):
"""
diff --git a/gramps/gui/plug/quick/_quickreports.py b/gramps/gui/plug/quick/_quickreports.py
index de4d7b6bb..d5c926114 100644
--- a/gramps/gui/plug/quick/_quickreports.py
+++ b/gramps/gui/plug/quick/_quickreports.py
@@ -63,6 +63,12 @@ from gramps.gen.plug import (CATEGORY_QR_PERSON, CATEGORY_QR_FAMILY, CATEGORY_QR
from ._textbufdoc import TextBufDoc
from gramps.gen.simple import make_basic_stylesheet
+MENUITEM = ('- \n'
+ '{prefix}.{action}\n'
+ ''
+ '{label}\n'
+ '
\n')
+
def flatten(L):
"""
Flattens a possibly nested list. Removes None results, too.
@@ -77,7 +83,7 @@ def flatten(L):
retval.append(L)
return retval
-def create_web_connect_menu(dbstate, uistate, nav_group, handle):
+def create_web_connect_menu(dbstate, uistate, nav_group, handle, prefix):
"""
This functions querries the registered web connects. It collects
the connects of the requested category, which must be one of
@@ -88,12 +94,12 @@ def create_web_connect_menu(dbstate, uistate, nav_group, handle):
handle as input method. A tuple is returned, containing the ui
string of the menu, and its associated actions.
"""
+ top = ("\n"
+ ''
+ 'Web Connection\n')
actions = []
ofile = StringIO()
- ofile.write('')
- actions.append(('WebConnect', None, _("Web Connect"), None, None, None))
- menu = Gtk.Menu()
- menu.show()
+ ofile.write(top)
#select the web connects to show
showlst = []
pmgr = GuiPluginManager.get_instance()
@@ -109,16 +115,17 @@ def create_web_connect_menu(dbstate, uistate, nav_group, handle):
connections.sort(key=lambda plug: plug.name)
actions = []
for connect in connections:
- ofile.write('' % connect.key)
- actions.append((connect.key, None, connect.name, None, None,
- connect(dbstate, uistate, nav_group, handle)))
- ofile.write('')
- retval = [ofile.getvalue()]
- retval.extend(actions)
- return retval
+ action = connect.key.replace(' ', '-')
+ ofile.write(MENUITEM.format(prefix=prefix, action=action,
+ label=connect.name))
+ callback = connect(dbstate, uistate, nav_group, handle)
+ actions.append((action,
+ lambda x, y: callback(x)))
+ ofile.write('\n')
+ return (ofile.getvalue(), actions)
-def create_quickreport_menu(category, dbstate, uistate, handle, track=[]):
+def create_quickreport_menu(category, dbstate, uistate, handle, prefix, track=[]):
""" This functions querries the registered quick reports with
quick_report_list of _PluginMgr.py
It collects the reports of the requested category, which must be one of
@@ -132,39 +139,35 @@ def create_quickreport_menu(category, dbstate, uistate, handle, track=[]):
A tuple is returned, containing the ui string of the quick report menu,
and its associated actions
"""
-
+ top = ("\n"
+ ''
+ 'Quick View\n')
actions = []
ofile = StringIO()
- ofile.write('')
-
- actions.append(('QuickReport', None, _("Quick View"), None, None, None))
-
- menu = Gtk.Menu()
- menu.show()
+ ofile.write(top)
#select the reports to show
showlst = []
pmgr = GuiPluginManager.get_instance()
for pdata in pmgr.get_reg_quick_reports():
if pdata.supported and pdata.category == category :
- #add tuple function, translated name, name, status
showlst.append(pdata)
showlst.sort(key=lambda x: x.name)
for pdata in showlst:
new_key = pdata.id.replace(' ', '-')
- ofile.write('' % new_key)
- actions.append((new_key, None, pdata.name, None, None,
- make_quick_report_callback(pdata, category, dbstate,
- uistate, handle, track=track)))
- ofile.write('')
+ ofile.write(MENUITEM.format(prefix=prefix, action=new_key,
+ label=pdata.name))
+ actions.append((new_key, make_quick_report_callback(
+ pdata, category, dbstate, uistate, handle, track=track)))
+ ofile.write('\n')
return (ofile.getvalue(), actions)
def make_quick_report_callback(pdata, category, dbstate, uistate, handle,
track=[]):
- return lambda x: run_report(dbstate, uistate, category, handle, pdata,
- track=track)
+ return lambda x, y: run_report(dbstate, uistate, category, handle, pdata,
+ track=track)
def get_quick_report_list(qv_category=None):
"""
diff --git a/gramps/gui/uimanager.py b/gramps/gui/uimanager.py
new file mode 100644
index 000000000..c272bccc6
--- /dev/null
+++ b/gramps/gui/uimanager.py
@@ -0,0 +1,514 @@
+#
+# Gramps - a GTK+/GNOME based genealogy program
+#
+# Copyright (C) 2018 Paul Culley
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+"""
+A replacement UIManager and ActionGroup.
+"""
+
+import copy
+import sys
+import logging
+import xml.etree.ElementTree as ET
+
+from gi.repository import GLib, Gio, Gtk
+
+from ..gen.config import config
+
+
+LOG = logging.getLogger('gui.uimanager')
+
+
+ACTION_NAME = 0 # tuple index for action name
+ACTION_CB = 1 # tuple index for action callback
+ACTION_ACC = 2 # tuple index for action accelerator
+ACTION_ST = 3 # tuple index for action state
+
+
+class ActionGroup():
+ """ This class represents a group of actions that con be manipulated
+ together.
+ """
+ def __init__(self, name, actionlist=None, prefix='win'):
+ """
+ @param name: the action group name, used to match to the 'groups'
+ attribute in the ui xml.
+ @type name: string
+ @type actionlist: list
+ @param actionlist: the list of actions to add
+ The list contains tuples with the following contents:
+ string: Action Name
+ method: signal callback function.
+ None if just adding an accelerator
+ string: accelerator ex: 'Enter' or '' for no accelerator.
+ optional for non-stateful actions.
+ state: initial state for stateful actions.
+ 'True' or 'False': the action is interpreted as a checkbox.
+ 'None': non stateful action (optional)
+ 'string': the action is interpreted as a Radio button
+ @type prefix: str
+ @param prefix: the prefix used by this group. If not provided, 'win'
+ is assumed.
+ """
+ self.name = name
+ self.actionlist = actionlist if actionlist else []
+ self.prefix = prefix + '.'
+ self.act_group = None
+ self.sensitive = True
+
+ def add_actions(self, actionlist):
+ """ Add a list of actions to the current list
+ @type actionlist: list
+ @param actionlist: the list of actions to add
+ """
+ self.actionlist.extend(actionlist)
+
+
+class UIManager():
+ """
+ This is Gramps UIManager, it is designed to replace the deprecated Gtk
+ UIManager. The replacement is not exact, but performs similar
+ functions, in some case with the same method names and parameters.
+ It is designed to be a singleton. The menu portion of this is responsible
+ only for Gramps main window menus and toolbar.
+ This was implemented to extend Gtk.Builder functions to allow editing
+ (merging) of the original builder XML with additional XML fragments during
+ operations. This allows changing of the menus and toolbar when the tree is
+ loaded, views are changed etc.
+
+ The ActionGroup portions can also be used by other windows. Other windows
+ needing menus or toolbars can create them via Gtk.Builder.
+ """
+
+ def __init__(self, app, initial_xml):
+ """
+ @param app: Gramps Gtk.Application reference
+ @type app: Gtk.Application
+ @param initial_xml: Initial (primary) XML string for Gramps menus and
+ toolbar
+ @type changexml: string
+
+ The xml is basically Gtk Builder xml, in particular the various menu
+ and toolbar elements. It is possible to add other elements as well.
+ The xml this supports has been extended in two ways;
+ 1) there is an added "groups=" attribute to elements. This
+ attribute associates the element with one or more named ActionGroups
+ for making the element visible or not. If 'groups' is missing, the
+ element will be shown as long as enclosing elements are shown. The
+ element will be shown if the group is present and considered visible
+ by the uimanager. If more than one group is needed, they should be
+ separated by a space.
+ 2) there is an added tag supported; this is used to mark
+ a place where merged UI XML can be inserted. During the update_menu
+ processing, elements enclosed in this tag pair are promoted to the
+ level of the placeholder tag, and the placeholder tag is removed.
+
+ Note that any elements can be merged (replaced) by the
+ add_ui_from_string method, not just placeholders. This works by
+ matching the "id=" attribute on the element, and replacing the
+ original element with the one from the add method.
+
+ Note that when added elements are removed by the remove_ui method, they
+ are replaced by the containing xml (with the 'id=') only, so don't put
+ anything inside of the containing xml to start with as it will be lost
+ during editing.
+ """
+ self.app = app # the Gtk.Application of Gramps
+ self.et_xml = ET.fromstring(initial_xml)
+ self.builder = None
+ self.toolbar = None
+ self.action_groups = [] # current list of action groups
+ self.show_groups = ['RW', 'RO'] # groups to show at the moment
+ self.accel_dict = {} # used to store accel overrides from file
+
+ def update_menu(self, init=False):
+ """ This updates the menus and toolbar when there is a change in the
+ ui; any addition or removal or set_visible operation needs to call
+ this. It is best to make the call only once, at the end, if multiple
+ changes are to be made.
+ It starts with the ET xml stored in self, cleans it up to meet the
+ Gtk.Builder specifications, and then updates the ui.
+
+ @param init: When True, this is first call and we set the builder
+ toolbar and menu to the application.
+ When False, we update the menus and toolbar
+ @type init: bool
+ """
+
+ def iterator(parents):
+ """ This recursively goes through the ET xml and deals with the
+ 'groups' attribute and tags, which are not valid for
+ builder. Empty submenus are also removed.
+ Groups processing removes elements that are not shown, as well as
+ the 'groups' attribute itself.
+ tags are removed and their enclosed elements are
+ promoted to the level of the placeholder.
+
+ @param parents: the current element to recursively process
+ @type parents: ET element
+ """
+ indx = 0
+ while indx < len(parents):
+ child = parents[indx]
+ if len(child) >= 1:
+ # Recurse until we have a stand-alone child
+ iterator(child)
+ if((len(child) == 1 and child.tag == "submenu") or
+ (len(child) == 0 and child.tag == "section")):
+ # remove empty submenus and sections
+ # print('del', child.tag, child.attrib)
+ del parents[indx]
+ continue
+ # print(child.attrib)
+ groups = child.get('groups')
+ if not groups:
+ indx += 1
+ continue
+ del child.attrib['groups']
+ for group in groups.split(' '):
+ if group in self.show_groups:
+ indx += 1
+ break
+ else:
+ #print('del', child.tag, child.attrib, parents.tag,
+ # parents.attrib)
+ del parents[indx]
+ break
+ # The following looks for 'placeholder' elements and if found,
+ # promotes any children to the same level as the placeholder.
+ # this allows the user to insert elements without using a section.
+ indx = 0
+ while indx < len(parents):
+ if parents[indx].tag == "placeholder":
+ subtree = parents[indx]
+ #print('placholder del', parents[indx].tag,
+ # parents[indx].attrib, parents.tag, parents.attrib)
+ del parents[indx]
+ for child in subtree:
+ parents.insert(indx, child)
+ indx += 1
+ else:
+ indx += 1
+
+ if self.builder:
+ toolbar = self.builder.get_object("ToolBar") # previous toolbar
+
+ # need to copy the tree so we can preserve original for later edits.
+ editable = copy.deepcopy(self.et_xml)
+ iterator(editable) # clean up tree to builder specifications
+ xml_str = ET.tostring(editable, encoding="unicode")
+ #print(xml_str)
+ self.builder = Gtk.Builder.new_from_string(xml_str, -1)
+ if init:
+ self.app.menubar = self.builder.get_object("menubar")
+ self.app.set_menubar(self.app.menubar)
+ return
+ # The following is the only way I have found to update the menus.
+ # app.set_menubar can apparently only be used once, before
+ # ApplicationWindow creation, further uses do NOT cause the menus to
+ # update.
+ self.app.menubar.remove_all()
+ section = self.builder.get_object('menubar-update')
+ self.app.menubar.append_section(None, section)
+
+ # the following updates the toolbar from the new builder
+ toolbar_parent = toolbar.get_parent()
+ tb_show = toolbar.get_visible()
+ toolbar_parent.remove(toolbar)
+ toolbar = self.builder.get_object("ToolBar") # new toolbar
+ toolbar_parent.pack_start(toolbar, False, True, 0)
+ if tb_show:
+ toolbar.show_all()
+ else:
+ toolbar.hide()
+ #print('*** Update ui')
+
+ def add_ui_from_string(self, changexml):
+ """ This performs a merge operation on the xml elements that have
+ matching 'id's between the current ui xml and change xml strings.
+ The 'changexml' is a list of xml fragment strings used to replace
+ matching elements in the current xml.
+
+ There MUST one and only one matching id in the orig xml.
+ @param changexml: list of xml fragments to merge into main
+ @type changexml: list
+ @return: changexml
+ """
+ try:
+ for xml in changexml:
+ if not xml:
+ # allow an xml fragment to be an empty string
+ continue
+ update = ET.fromstring(xml)
+ el_id = update.attrib['id']
+ # find the parent of the id'd element in original xml
+ parent = self.et_xml.find(".//*[@id='%s'].." % el_id)
+ if parent:
+ # we found it, now delete original, inset updated
+ for indx in range(len(parent)):
+ if parent[indx].get('id') == el_id:
+ del parent[indx]
+ parent.insert(indx, update)
+ else:
+ # updated item not present in original, just add it
+ # This allow addition of popups etc.
+ self.et_xml.append(update)
+ #results = ET.tostring(self.et_xml, encoding="unicode")
+ #print(results)
+ #print ('*** Add ui')
+ return changexml
+ except:
+ # the following is only here to assist debug
+ print('*****', sys.exc_info())
+ print(xml)
+ print(changexml)
+ assert False
+
+ def remove_ui(self, change_xml):
+ """ This removes the 'change_xml' from the current ui xml. It works on
+ any element with matching 'id', the actual element remains but any
+ children are removed.
+ The 'change_xml' is a list of xml strings originally used to replace
+ matching elements in the current ui xml.
+ @param change_xml: list of xml fragments to remove from main
+ @type change_xml: list
+ """
+# if not change_xml:
+# import pydevd
+# pydevd.settrace()
+ for xml in change_xml:
+ if not xml:
+ continue
+ update = ET.fromstring(xml)
+ el_id = update.attrib['id']
+ # find parent of id'd element
+ element = self.et_xml.find(".//*[@id='%s']" % el_id)
+ if element: # element may have already been deleted
+ for dummy in range(len(element)):
+ del element[0]
+ #results = ET.tostring(self.et_xml, encoding="unicode")
+ #print(results)
+ #print ('*** Remove ui')
+ return
+
+ def get_widget(self, obj):
+ """ Get the object from the builder.
+ @param obj: the widget to get
+ @type obj: string
+ @return: the object
+ """
+ return self.builder.get_object(obj)
+
+ def insert_action_group(self, group, gio_group=None):
+ """
+ This inserts (actually overwrites any matching actions) the action
+ group's actions to the app.
+ By default (with no gio_group), the action group is added to the main
+ Gramps window and the group assumes a 'win' prefix.
+ If not using the main window, the window MUST have the 'application'
+ property set for the accels to work. In this case the actiongroups
+ must be created like the following:
+
+ # create Gramps ActionGroup
+ self.action_group = ActionGroup('name', actions, 'prefix')
+ # create Gio action group
+ act_grp = SimpleActionGroup()
+ # associate window with Gio group and its prefix
+ window.insert_action_group('prefix', act_grp)
+ # make the window 'application' aware
+ window.set_application(uimanager.app)
+ # tell the uimanager about the groups.
+ uimanager.insert_action_group(self.action_group, act_grp)
+
+ @param group: the action group
+ @type group: ActionGroup
+ @param gio_group: the Gio action group associated with a window.
+ @type gio_group: Gio.SimpleActionGroup
+ """
+ try:
+ assert isinstance(group.actionlist, list)
+ if gio_group:
+ window_group = group.act_group = gio_group
+ elif group.act_group:
+ window_group = group.act_group
+ else:
+ window_group = group.act_group = self.app.window
+ for item in group.actionlist:
+ # deal with accelerator overrides from a file
+ accel = self.accel_dict.get(group.prefix + item[ACTION_NAME])
+ if accel:
+ self.app.set_accels_for_action(
+ group.prefix + item[ACTION_NAME], [accel])
+ elif len(item) > 2 and item[ACTION_ACC]:
+ # deal with accelerators defined in the group
+ accels = self.app.get_actions_for_accel(item[ACTION_ACC])
+ if accels:
+ # diagnostic printout; a duplicate accelerator may be
+ # a problem if both are valid for the same window at
+ # the same time. If the actions are for a different
+ # window, this is not an error. Here we assume a
+ # different prefix is used for different windows.
+ for accel in accels:
+ if group.prefix in accel:
+ LOG.warning('**Duplicate Accelerator %s',
+ item[ACTION_ACC])
+ self.app.set_accels_for_action(
+ group.prefix + item[ACTION_NAME], [item[ACTION_ACC]])
+ if len(item) <= 3:
+ # Normal stateless actions
+ action = Gio.SimpleAction.new(item[ACTION_NAME], None)
+ if item[ACTION_CB]: # in case we have only accelerator
+ action.connect("activate", item[ACTION_CB])
+ elif isinstance(item[ACTION_ST], str):
+ # Radio Actions
+ action = Gio.SimpleAction.new_stateful(
+ item[ACTION_NAME], GLib.VariantType.new("s"),
+ GLib.Variant("s", item[ACTION_ST]))
+ action.connect("change-state", item[ACTION_CB])
+ elif isinstance(item[ACTION_ST], bool):
+ # Checkbox actions
+ action = Gio.SimpleAction.new_stateful(
+ item[ACTION_NAME], None,
+ GLib.Variant.new_boolean(item[ACTION_ST]))
+ action.connect("change-state", item[ACTION_CB])
+ window_group.add_action(action)
+ self.action_groups.append(group)
+ # if action sensitivity was set prior to actually inserting into
+ # UIManager, we need to do it now that we have the action
+ if not group.sensitive:
+ self.set_actions_sensitive(group, False)
+ except:
+ # the following is only to assist in debug
+ print(group.name, item)
+ assert False
+
+ def remove_action_group(self, group):
+ """ This removes the ActionGroup from the UIManager
+
+ @param group: the action group
+ @type group: ActionGroup
+ """
+ if group.act_group:
+ window_group = group.act_group
+ else:
+ window_group = self.app.window
+ for item in group.actionlist:
+ window_group.remove_action(item[ACTION_NAME])
+ self.app.set_accels_for_action(group.prefix + item[ACTION_NAME],
+ [])
+ self.action_groups.remove(group)
+
+ def get_action_groups(self):
+ """ This returns a list of action Groups installed into the UIManager.
+ @return: list of groups
+ """
+ return self.action_groups
+
+ def set_actions_sensitive(self, group, value):
+ """ This sets an ActionGroup enabled or disabled. A disabled action
+ will be greyed out in the UI.
+
+ @param group: the action group
+ @type group: ActionGroup
+ @param value: the state of the group
+ @type value: bool
+ """
+ if group.act_group:
+ for item in group.actionlist:
+ action = group.act_group.lookup_action(item[ACTION_NAME])
+ if action:
+ # We check in case the group has not been inserted into
+ # UIManager yet
+ action.set_enabled(value)
+ group.sensitive = value
+
+ def get_actions_sensitive(self, group):
+ """ This gets an ActionGroup sensitive setting. A disabled action
+ will be greyed out in the UI.
+ We assume that the first action represents the group.
+
+ @param group: the action group
+ @type group: ActionGroup
+ @return: the state of the group
+ """
+ item = group.actionlist[0]
+ action = group.act_group.lookup_action(item[ACTION_NAME])
+ return action.get_enabled()
+
+ def set_actions_visible(self, group, value):
+ """ This sets an ActionGroup visible and enabled or invisible and
+ disabled. Make sure that the menuitems or sections and toolbar items
+ have the 'groups=' xml attribute matching the group name for this to
+ work correctly.
+
+ @param group: the action group
+ @type group: ActionGroup
+ @param value: the state of the group
+ @type value: bool
+ """
+ self.set_actions_sensitive(group, value)
+ if value:
+ if group.name not in self.show_groups:
+ self.show_groups.append(group.name)
+ else:
+ if group.name in self.show_groups:
+ self.show_groups.remove(group.name)
+
+ def get_action(self, group, actionname):
+ """ Return a single action from the group.
+ @param group: the action group
+ @type group: ActionGroup
+ @param actionname: the action name
+ @type actionname: string
+ @return: Gio.Action
+ """
+ return group.act_group.lookup_action(actionname)
+
+ def dump_all_accels(self):
+ ''' A function used diagnostically to see what accels are present.
+ This will only dump the current accel set, if other non-open windows
+ or views have accels, you will need to open them and run this again
+ and manually merge the result files. The results are in a
+ 'gramps.accel' file located in the current working directory.'''
+ out_dict = {}
+ for group in self.action_groups:
+ for item in group.actionlist:
+ act = group.prefix + item[ACTION_NAME]
+ accels = self.app.get_accels_for_action(
+ group.prefix + item[ACTION_NAME])
+ out_dict[act] = accels[0] if accels else ''
+ import json
+ with open('gramps.accel', 'w', ) as hndl:
+ accels = json.dumps(out_dict, indent=0).replace('\n"', '\n# "')
+ hndl.write(accels)
+
+ def load_accels(self, filename):
+ """ This function loads accels from a file such as created by
+ dump_all_accels. The file contents is basically a Python dict
+ definition. As such it contains a line for each dict element.
+ These elements can be commented out with '#' at the beginning of the
+ line.
+
+ If used, this file overrides the accels defined in other Gramps code.
+ As such it must be loaded before any insert_action_group calls.
+ """
+ import ast
+ with open(filename, 'r') as hndl:
+ accels = hndl.read()
+ self.accel_dict = ast.literal_eval(accels)
diff --git a/gramps/gui/viewmanager.py b/gramps/gui/viewmanager.py
index b314fa6e9..a1bb0a7fd 100644
--- a/gramps/gui/viewmanager.py
+++ b/gramps/gui/viewmanager.py
@@ -40,6 +40,7 @@ import datetime
from io import StringIO
import posixpath
import gc
+import html
#-------------------------------------------------------------------------
#
@@ -92,7 +93,7 @@ from .configure import GrampsPreferences
from .aboutdialog import GrampsAboutDialog
from .navigator import Navigator
from .views.tags import Tags
-from .actiongroup import ActionGroup
+from .uimanager import ActionGroup
from gramps.gen.lib import (Person, Surname, Family, Media, Note, Place,
Source, Repository, Citation, Event, EventType,
ChildRef)
@@ -107,148 +108,20 @@ from .managedwindow import ManagedWindow
# Constants
#
#-------------------------------------------------------------------------
-if is_quartz():
- try:
- import gi
- gi.require_version('GtkosxApplication', '1.0')
- from gi.repository import GtkosxApplication as QuartzApp
- _GTKOSXAPPLICATION = True
- except:
- print("Failed to import gtk_osxapplication")
- _GTKOSXAPPLICATION = False
-else:
- _GTKOSXAPPLICATION = False
+# if is_quartz():
+ # try:
+ # import gi
+ # gi.require_version('GtkosxApplication', '1.0')
+ # from gi.repository import GtkosxApplication as QuartzApp
+ # _GTKOSXAPPLICATION = True
+ # except:
+ # print("Failed to import gtk_osxapplication")
+ # _GTKOSXAPPLICATION = False
+# else:
+ # _GTKOSXAPPLICATION = False
_UNSUPPORTED = ("Unsupported", _("Unsupported"))
-UIDEFAULT = '''
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-'''
-
WIKI_HELP_PAGE_FAQ = '%s_-_FAQ' % URL_MANUAL_PAGE
WIKI_HELP_PAGE_KEY = '%s_-_Keybindings' % URL_MANUAL_PAGE
WIKI_HELP_PAGE_MAN = '%s' % URL_MANUAL_PAGE
@@ -289,18 +162,19 @@ class ViewManager(CLIManager):
"""
- def __init__(self, dbstate, view_category_order, user=None):
+ def __init__(self, app, dbstate, view_category_order, user=None):
"""
The viewmanager is initialised with a dbstate on which Gramps is
working, and a fixed view_category_order, which is the order in which
the view categories are accessible in the sidebar.
"""
CLIManager.__init__(self, dbstate, setloader=False, user=user)
- if _GTKOSXAPPLICATION:
- self.macapp = QuartzApp.Application()
- self.macapp.set_use_quartz_accelerators(False)
+ # if _GTKOSXAPPLICATION:
+ # self.macapp = QuartzApp.Application()
+ # self.macapp.set_use_quartz_accelerators(False)
self.view_category_order = view_category_order
+ self.app = app
#set pluginmanager to GUI one
self._pmgr = GuiPluginManager.get_instance()
@@ -329,8 +203,8 @@ class ViewManager(CLIManager):
uistate=self.uistate,
dbstate=self.dbstate)
self.__connect_signals()
- if _GTKOSXAPPLICATION:
- self.macapp.ready()
+ # if _GTKOSXAPPLICATION:
+ # self.macapp.ready()
self.do_reg_plugins(self.dbstate, self.uistate)
#plugins loaded now set relationship class
@@ -391,7 +265,8 @@ class ViewManager(CLIManager):
horiz_position = config.get('interface.main-window-horiz-position')
vert_position = config.get('interface.main-window-vert-position')
- self.window = Gtk.Window()
+ self.window = Gtk.ApplicationWindow(application=self.app)
+ self.app.window = self.window
self.window.set_icon_from_file(ICON)
self.window.set_default_size(width, height)
self.window.move(horiz_position, vert_position)
@@ -419,14 +294,12 @@ class ViewManager(CLIManager):
self.__build_ui_manager()
hpane.add2(self.notebook)
- self.menubar = self.uimanager.get_widget('/MenuBar')
- self.toolbar = self.uimanager.get_widget('/ToolBar')
- self.__attach_menubar(vbox)
- vbox.pack_start(self.toolbar, False, True, 0)
- vbox.pack_start(hpane, True, True, 0)
+ toolbar = self.uimanager.get_widget('ToolBar')
self.statusbar = Statusbar()
self.statusbar.show()
vbox.pack_end(self.statusbar, False, True, 0)
+ vbox.pack_start(toolbar, False, True, 0)
+ vbox.pack_end(hpane, True, True, 0)
vbox.show()
self.uistate = DisplayState(self.window, self.statusbar,
@@ -441,28 +314,21 @@ class ViewManager(CLIManager):
self.tags = Tags(self.uistate, self.dbstate)
- self.sidebar_menu = self.uimanager.get_widget(
- '/MenuBar/ViewMenu/Sidebar/')
-
- # handle OPEN button, insert it into the toolbar. Unfortunately,
- # UIManager has no built in support for and Open Recent button
-
- openbtn = self.__build_open_button()
- self.uistate.set_open_widget(openbtn)
- self.toolbar.insert(openbtn, 0)
-
+ # handle OPEN Recent Menu, insert it into the toolbar.
self.recent_manager = RecentDocsMenu(
self.uistate, self.dbstate, self._read_recent_file)
- self.recent_manager.build()
+ self.recent_manager.build(update_menu=False)
self.db_loader = DbLoader(self.dbstate, self.uistate)
self.__setup_navigator()
+ # need to get toolbar again, because it is a new object now.
+ toolbar = self.uimanager.get_widget('ToolBar')
if self.show_toolbar:
- self.toolbar.show()
+ toolbar.show()
else:
- self.toolbar.hide()
+ toolbar.hide()
if self.fullscreen:
self.window.fullscreen()
@@ -480,185 +346,110 @@ class ViewManager(CLIManager):
else:
self.ebox.hide()
- def __build_open_button(self):
- """
- Build the OPEN button. Since GTK's UIManager does not have support for
- the Open Recent button, we must build in on our own.
- """
- openbtn = Gtk.MenuToolButton()
- openbtn.set_icon_name('gramps')
- openbtn.connect('clicked', self.__open_activate)
- openbtn.set_sensitive(False)
- openbtn.set_tooltip_text(_("Connect to a recent database"))
- openbtn.show()
- return openbtn
-
def __connect_signals(self):
"""
Connects the signals needed
"""
self.window.connect('delete-event', self.quit)
self.notebook.connect('switch-page', self.view_changed)
- if _GTKOSXAPPLICATION:
- self.macapp.connect('NSApplicationWillTerminate', self.quit)
+ # if _GTKOSXAPPLICATION:
+ # self.macapp.connect('NSApplicationWillTerminate', self.quit)
def __init_lists(self):
"""
Initialize the actions lists for the UIManager
"""
self._file_action_list = [
- ('FileMenu', None, _('_Family Trees')),
- ('Open', 'gramps-db', _('_Manage Family Trees...'), "o",
- _("Manage databases"), self.__open_activate),
- ('OpenRecent', None, _('Open _Recent'), None,
- _("Open an existing database")),
- ('Quit', 'application-exit', _('_Quit'), "q", None,
- self.quit),
- ('ViewMenu', None, _('_View')),
- ('EditMenu', None, _('_Edit')),
- ('Preferences', 'preferences-system', _('_Preferences...'), None,
- None, self.preferences_activate),
- ('HelpMenu', None, _('_Help')),
- ('HomePage', None, _('Gramps _Home Page'), None, None,
- home_page_activate),
- ('MailingLists', None, _('Gramps _Mailing Lists'), None, None,
- mailing_lists_activate),
- ('ReportBug', None, _('_Report a Bug'), None, None,
- report_bug_activate),
- ('ExtraPlugins', None, _('_Extra Reports/Tools'), None, None,
- extra_plugins_activate),
- ('About', 'help-about', _('_About'), None, None,
- self.display_about_box),
- ('PluginStatus', None, _('_Plugin Manager'), None, None,
- self.__plugin_status),
- ('FAQ', None, _('_FAQ'), None, None, faq_activate),
- ('KeyBindings', None, _('_Key Bindings'), None, None, key_bindings),
- ('UserManual', 'help-browser', _('_User Manual'), 'F1', None,
- manual_activate),
- ('TipOfDay', None, _('Tip of the Day'), None, None,
- self.tip_of_day_activate),
- ]
+ #('FileMenu', None, _('_Family Trees')),
+ ('Open', self.__open_activate, "o"),
+ #('OpenRecent'_("Open an existing database")),
+ ('Quit', self.quit, "q"),
+ #('ViewMenu', None, _('_View')),
+ ('Navigator', self.navigator_toggle, "m",
+ self.show_navigator),
+ ('Toolbar', self.toolbar_toggle, '', self.show_toolbar),
+ ('Fullscreen', self.fullscreen_toggle, "F11", self.fullscreen),
+ #('EditMenu', None, _('_Edit')),
+ ('Preferences', self.preferences_activate),
+ #('HelpMenu', None, _('_Help')),
+ ('HomePage', home_page_activate),
+ ('MailingLists', mailing_lists_activate),
+ ('ReportBug', report_bug_activate),
+ ('ExtraPlugins', extra_plugins_activate),
+ ('About', self.display_about_box),
+ ('PluginStatus', self.__plugin_status),
+ ('FAQ', faq_activate),
+ ('KeyBindings', key_bindings),
+ ('UserManual', manual_activate, 'F1'),
+ ('TipOfDay', self.tip_of_day_activate), ]
self._readonly_action_list = [
- ('Close', None, _('_Close'), "w",
- _("Close the current database"), self.close_database),
- ('Export', 'gramps-export', _('_Export...'), "e", None,
- self.export_data),
- ('Backup', None, _("Make Backup..."), None,
- _("Make a Gramps XML backup of the database"), self.quick_backup),
- ('Abandon', 'document-revert',
- _('_Abandon Changes and Quit'), None, None, self.abort),
- ('Reports', 'gramps-reports', _('_Reports'), None,
- _("Open the reports dialog"), self.reports_clicked),
- ('GoMenu', None, _('_Go')),
- ('ReportsMenu', None, _('_Reports')),
- ('Books', None, _('Books...'), None, None, self.run_book),
- ('WindowsMenu', None, _('_Windows')),
- ('F2', None, 'F2', "F2", None, self.__keypress),
- ('F3', None, 'F3', "F3", None, self.__keypress),
- ('F4', None, 'F4', "F4", None, self.__keypress),
- ('F5', None, 'F5', "F5", None, self.__keypress),
- ('F6', None, 'F6', "F6", None, self.__keypress),
- ('F7', None, 'F7', "F7", None, self.__keypress),
- ('F8', None, 'F9', "F8", None, self.__keypress),
- ('F9', None, 'F9', "F9", None, self.__keypress),
- ('F11', None, 'F11', "F11", None, self.__keypress),
- ('1', None, '1', "1", None,
- self.__gocat),
- ('2', None, '2', "2", None,
- self.__gocat),
- ('3', None, '3', "3", None,
- self.__gocat),
- ('4', None, '4', "4", None,
- self.__gocat),
- ('5', None, '5', "5", None,
- self.__gocat),
- ('6', None, '6', "6", None,
- self.__gocat),
- ('7', None, '7', "7", None,
- self.__gocat),
- ('8', None, '8', "8", None,
- self.__gocat),
- ('9', None, '9', "9", None,
- self.__gocat),
- ('0', None, '0', "0", None,
- self.__gocat),
- # NOTE: CTRL+ALT+NUMBER is set in src/plugins/sidebar/cat...py
- ('BackSpace', None, 'BackSpace',
- "BackSpace", None, self.__keypress),
- ('Delete', None, 'Delete',
- "Delete", None, self.__keypress),
- ('Insert', None, 'Insert',
- "Insert", None, self.__keypress),
- ('F12', None, 'F12', "F12", None, self.__keypress),
- ('J', None, 'J',
- "J", None, self.__keypress),
- ('N', None, 'N', "N", None,
- self.__next_view),
- ('P', None, 'P', "P", None,
- self.__prev_view),
- ]
+ ('Close', self.close_database, "w"),
+ ('Export', self.export_data, "e"),
+ ('Backup', self.quick_backup),
+ ('Abandon', self.abort),
+ ('Reports', self.reports_clicked),
+ #('GoMenu', None, _('_Go')),
+ #('ReportsMenu', None, _('_Reports')),
+ ('Books', self.run_book),
+ #('WindowsMenu', None, _('_Windows')),
+ #('F2', self.__keypress, 'F2'), #pedigreeview
+ #('F3', self.__keypress, 'F3'), # timelinepedigreeview
+ #('F4', self.__keypress, 'F4'), # timelinepedigreeview
+ #('F5', self.__keypress, 'F5'), # timelinepedigreeview
+ #('F6', self.__keypress, 'F6'), # timelinepedigreeview
+ #('F7', self.__keypress, 'F7'),
+ #('F8', self.__keypress, 'F8'),
+ #('F9', self.__keypress, 'F9'),
+ #('F11', self.__keypress, 'F11'), # used to go full screen
+ #('F12', self.__keypress, 'F12'),
+ #('BackSpace', self.__keypress, 'BackSpace'),
+ #('Delete', self.__keypress, 'Delete'),
+ #('Insert', self.__keypress, 'Insert'),
+ #('J', self.__keypress, 'J'),
+ ('PRIMARY-1', self.__gocat, '1'),
+ ('PRIMARY-2', self.__gocat, '2'),
+ ('PRIMARY-3', self.__gocat, '3'),
+ ('PRIMARY-4', self.__gocat, '4'),
+ ('PRIMARY-5', self.__gocat, '5'),
+ ('PRIMARY-6', self.__gocat, '6'),
+ ('PRIMARY-7', self.__gocat, '7'),
+ ('PRIMARY-8', self.__gocat, '8'),
+ ('PRIMARY-9', self.__gocat, '9'),
+ ('PRIMARY-0', self.__gocat, '0'),
+ # NOTE: CTRL+ALT+NUMBER is set in gramps.gui.navigator
+ ('PRIMARY-N', self.__next_view, 'N'),
+ # the following conflicts with PrintView!!!
+ ('PRIMARY-P', self.__prev_view, 'P'), ]
self._action_action_list = [
- ('Clipboard', 'edit-paste', _('Clip_board'), "b",
- _("Open the Clipboard dialog"), self.clipboard),
- ('AddMenu', None, _('_Add')),
+ ('Clipboard', self.clipboard, "b"),
+ #('AddMenu', None, _('_Add')),
#('AddNewMenu', None, _('New')),
- ('PersonAdd', None, _('Person'), "p", None,
- self.add_new_person),
- ('FamilyAdd', None, _('Family'), "f", None,
- self.add_new_family),
- ('EventAdd', None, _('Event'), "e", None,
- self.add_new_event),
- ('PlaceAdd', None, _('Place'), "l", None,
- self.add_new_place),
- ('SourceAdd', None, _('Source'), "s", None,
- self.add_new_source),
- ('CitationAdd', None, _('Citation'), "c", None,
- self.add_new_citation),
- ('RepositoryAdd', None, _('Repository'), "r", None,
- self.add_new_repository),
- ('MediaAdd', None, _('Media'), "m", None,
- self.add_new_media),
- ('NoteAdd', None, _('Note'), "n", None,
- self.add_new_note),
+ ('PersonAdd', self.add_new_person, "p"),
+ ('FamilyAdd', self.add_new_family, "f"),
+ ('EventAdd', self.add_new_event, "e"),
+ ('PlaceAdd', self.add_new_place, "l"),
+ ('SourceAdd', self.add_new_source, "s"),
+ ('CitationAdd', self.add_new_citation, "c"),
+ ('RepositoryAdd', self.add_new_repository, "r"),
+ ('MediaAdd', self.add_new_media, "m"),
+ ('NoteAdd', self.add_new_note, "n"),
+ ('UndoHistory', self.undo_history, "H"),
#--------------------------------------
- ('Import', 'gramps-import', _('_Import...'), "i", None,
- self.import_data),
- ('Tools', 'gramps-tools', _('_Tools'), None,
- _("Open the tools dialog"), self.tools_clicked),
- ('BookMenu', None, _('_Bookmarks')),
- ('ToolsMenu', None, _('_Tools')),
- ('ConfigView', 'gramps-config', _('_Configure...'),
- 'c', _('Configure the active view'),
- self.config_view),
- ]
-
- self._file_toggle_action_list = [
- ('Navigator', None, _('_Navigator'), "m", None,
- self.navigator_toggle, self.show_navigator),
- ('Toolbar', None, _('_Toolbar'), None, None, self.toolbar_toggle,
- self.show_toolbar),
- ('Fullscreen', None, _('F_ull Screen'), "F11", None,
- self.fullscreen_toggle, self.fullscreen),
- ]
+ ('Import', self.import_data, "i"),
+ ('Tools', self.tools_clicked),
+ #('BookMenu', None, _('_Bookmarks')),
+ #('ToolsMenu', None, _('_Tools')),
+ ('ConfigView', self.config_view, 'c'), ]
self._undo_action_list = [
- ('Undo', 'edit-undo', _('_Undo'), 'z', None,
- self.undo),
- ]
+ ('Undo', self.undo, 'z'), ]
self._redo_action_list = [
- ('Redo', 'edit-redo', _('_Redo'), 'z', None,
- self.redo),
- ]
+ ('Redo', self.redo, 'z'), ]
- self._undo_history_action_list = [
- ('UndoHistory', 'gramps-undo-history',
- _('Undo History...'), "H", None, self.undo_history),
- ]
-
- def run_book(self, action):
+ def run_book(self, *action):
"""
Run a book.
"""
@@ -667,20 +458,7 @@ class ViewManager(CLIManager):
except WindowActiveError:
return
- def __keypress(self, action):
- """
- Callback that is called on a keypress. It works by extracting the
- name of the associated action, and passes that to the active page
- (current view) so that it can take the associated action.
- """
- name = action.get_name()
- try:
- self.active_page.call_function(name)
- except Exception:
- self.uistate.push_message(self.dbstate,
- _("Key %s is not bound") % name)
-
- def __gocat(self, action):
+ def __gocat(self, action, value):
"""
Callback that is called on ctrl+number press. It moves to the
requested category like __next_view/__prev_view. 0 is 10
@@ -694,7 +472,7 @@ class ViewManager(CLIManager):
return False
self.goto_page(cat, None)
- def __next_view(self, action):
+ def __next_view(self, action, value):
"""
Callback that is called when the next category action is selected. It
selects the next category as the active category. If we reach the end,
@@ -712,7 +490,7 @@ class ViewManager(CLIManager):
else:
self.goto_page(cat_num+1, None)
- def __prev_view(self, action):
+ def __prev_view(self, action, value):
"""
Callback that is called when the previous category action is selected.
It selects the previous category as the active category. If we reach
@@ -743,25 +521,18 @@ class ViewManager(CLIManager):
self.goto_page(defaults[0], defaults[1])
- self.fileactions.set_sensitive(False)
+ self.uimanager.set_actions_sensitive(self.fileactions, False)
self.__build_tools_menu(self._pmgr.get_reg_tools())
self.__build_report_menu(self._pmgr.get_reg_reports())
self._pmgr.connect('plugins-reloaded',
self.__rebuild_report_and_tool_menus)
- self.fileactions.set_sensitive(True)
- self.uistate.widget.set_sensitive(True)
+ self.uimanager.set_actions_sensitive(self.fileactions, True)
if not self.file_loaded:
- self.actiongroup.set_sensitive(False)
- self.readonlygroup.set_sensitive(False)
- self.undoactions.set_sensitive(False)
- self.redoactions.set_sensitive(False)
- self.undohistoryactions.set_sensitive(False)
- self.actiongroup.set_visible(False)
- self.readonlygroup.set_visible(False)
- self.undoactions.set_visible(False)
- self.redoactions.set_visible(False)
- self.undohistoryactions.set_visible(False)
- self.uimanager.ensure_update()
+ self.uimanager.set_actions_visible(self.actiongroup, False)
+ self.uimanager.set_actions_visible(self.readonlygroup, False)
+ self.uimanager.set_actions_visible(self.undoactions, False)
+ self.uimanager.set_actions_visible(self.redoactions, False)
+ self.uimanager.update_menu()
config.connect("interface.statusbar", self.__statusbar_key_update)
def __statusbar_key_update(self, client, cnxn_id, entry, data):
@@ -777,7 +548,7 @@ class ViewManager(CLIManager):
"""
self.window.show()
if not self.dbstate.is_open() and show_manager:
- self.__open_activate(None)
+ self.__open_activate(None, None)
def do_reg_plugins(self, dbstate, uistate, rescan=False):
"""
@@ -829,9 +600,9 @@ class ViewManager(CLIManager):
config.set('interface.main-window-horiz-position', horiz_position)
config.set('interface.main-window-vert-position', vert_position)
config.save()
- Gtk.main_quit()
+ self.app.quit()
- def abort(self, obj=None):
+ def abort(self, *obj):
"""
Abandon changes and quit.
"""
@@ -861,56 +632,43 @@ class ViewManager(CLIManager):
"""
Initialize an action group for the UIManager
"""
- new_group = ActionGroup(name=name)
- new_group.add_actions(actions)
- if toggles:
- new_group.add_toggle_actions(toggles)
- new_group.set_sensitive(sensitive)
- self.uimanager.insert_action_group(new_group, 1)
+ new_group = ActionGroup(name, actions)
+ self.uimanager.insert_action_group(new_group)
+ self.uimanager.set_actions_sensitive(new_group, sensitive)
return new_group
def __build_ui_manager(self):
"""
- Builds the UIManager, and the associated action groups
+ Builds the action groups
"""
- self.uimanager = Gtk.UIManager()
-
- accelgroup = self.uimanager.get_accel_group()
+ self.uimanager = self.app.uimanager
self.actiongroup = self.__init_action_group(
- 'MainWindow', self._action_action_list)
+ 'RW', self._action_action_list)
self.readonlygroup = self.__init_action_group(
- 'AllMainWindow', self._readonly_action_list)
- self.undohistoryactions = self.__init_action_group(
- 'UndoHistory', self._undo_history_action_list)
+ 'RO', self._readonly_action_list)
self.fileactions = self.__init_action_group(
- 'FileWindow', self._file_action_list,
- toggles=self._file_toggle_action_list)
+ 'FileWindow', self._file_action_list)
self.undoactions = self.__init_action_group(
'Undo', self._undo_action_list, sensitive=False)
self.redoactions = self.__init_action_group(
'Redo', self._redo_action_list, sensitive=False)
- self.window.add_accel_group(accelgroup)
- self.uimanager.add_ui_from_string(UIDEFAULT)
- self.uimanager.ensure_update()
+# def __attach_menubar(self, vbox):
+# """
+# Attach the menubar
+# """
+# vbox.pack_start(self.menubar, False, True, 0)
+# if _GTKOSXAPPLICATION:
+# self.menubar.hide()
+# quit_item = self.uimanager.get_widget("Quit")
+# about_item = self.uimanager.get_widget("About")
+# prefs_item = self.uimanager.get_widget("Preferences")
+# self.macapp.set_menu_bar(self.menubar)
+# self.macapp.insert_app_menu_item(about_item, 0)
+# self.macapp.insert_app_menu_item(prefs_item, 1)
- def __attach_menubar(self, vbox):
- """
- Attach the menubar
- """
- vbox.pack_start(self.menubar, False, True, 0)
- if _GTKOSXAPPLICATION:
- self.menubar.hide()
- quit_item = self.uimanager.get_widget("/MenuBar/FileMenu/Quit")
- about_item = self.uimanager.get_widget("/MenuBar/HelpMenu/About")
- prefs_item = self.uimanager.get_widget(
- "/MenuBar/EditMenu/Preferences")
- self.macapp.set_menu_bar(self.menubar)
- self.macapp.insert_app_menu_item(about_item, 0)
- self.macapp.insert_app_menu_item(prefs_item, 1)
-
- def preferences_activate(self, obj):
+ def preferences_activate(self, *obj):
"""
Open the preferences dialog.
"""
@@ -919,7 +677,7 @@ class ViewManager(CLIManager):
except WindowActiveError:
return
- def tip_of_day_activate(self, obj):
+ def tip_of_day_activate(self, *obj):
"""
Display Tip of the day
"""
@@ -935,12 +693,13 @@ class ViewManager(CLIManager):
except WindowActiveError:
pass
- def navigator_toggle(self, obj, data=None):
+ def navigator_toggle(self, action, value):
"""
Set the sidebar based on the value of the toggle button. Save the
results in the configuration settings
"""
- if obj.get_active():
+ action.set_state(value)
+ if value.get_boolean():
self.ebox.show()
config.set('interface.view', True)
self.show_navigator = True
@@ -950,25 +709,28 @@ class ViewManager(CLIManager):
self.show_navigator = False
config.save()
- def toolbar_toggle(self, obj, data=None):
+ def toolbar_toggle(self, action, value):
"""
Set the toolbar based on the value of the toggle button. Save the
results in the configuration settings
"""
- if obj.get_active():
- self.toolbar.show()
+ action.set_state(value)
+ toolbar = self.uimanager.get_widget('ToolBar')
+ if value.get_boolean():
+ toolbar.show_all()
config.set('interface.toolbar-on', True)
else:
- self.toolbar.hide()
+ toolbar.hide()
config.set('interface.toolbar-on', False)
config.save()
- def fullscreen_toggle(self, obj, data=None):
+ def fullscreen_toggle(self, action, value):
"""
- Set the main Granps window fullscreen based on the value of the
+ Set the main Gramps window fullscreen based on the value of the
toggle button. Save the setting in the config file.
"""
- if obj.get_active():
+ action.set_state(value)
+ if value.get_boolean():
self.window.fullscreen()
config.set('interface.fullscreen', True)
else:
@@ -1051,17 +813,10 @@ class ViewManager(CLIManager):
hbox.show_all()
page_num = self.notebook.append_page(page.get_display(), hbox)
if not self.file_loaded:
- self.actiongroup.set_sensitive(False)
- self.readonlygroup.set_sensitive(False)
- self.undoactions.set_sensitive(False)
- self.redoactions.set_sensitive(False)
- self.undohistoryactions.set_sensitive(False)
- self.actiongroup.set_visible(False)
- self.readonlygroup.set_visible(False)
- self.undoactions.set_visible(False)
- self.redoactions.set_visible(False)
- self.undohistoryactions.set_visible(False)
- self.uimanager.ensure_update()
+ self.uimanager.set_actions_visible(self.actiongroup, False)
+ self.uimanager.set_actions_visible(self.readonlygroup, False)
+ self.uimanager.set_actions_visible(self.undoactions, False)
+ self.uimanager.set_actions_visible(self.redoactions, False)
return page
def view_changed(self, notebook, page, page_num):
@@ -1103,12 +858,14 @@ class ViewManager(CLIManager):
self.__disconnect_previous_page()
self.active_page = self.pages[page_num]
- self.active_page.set_active()
self.__connect_active_page(page_num)
+ self.active_page.set_active()
+ while Gtk.events_pending():
+ Gtk.main_iteration()
- self.uimanager.ensure_update()
- if _GTKOSXAPPLICATION:
- self.macapp.sync_menubar()
+ self.uimanager.update_menu()
+ # if _GTKOSXAPPLICATION:
+ # self.macapp.sync_menubar()
while Gtk.events_pending():
Gtk.main_iteration()
@@ -1143,7 +900,7 @@ class ViewManager(CLIManager):
into the UIManager
"""
for grp in self.active_page.get_actions():
- self.uimanager.insert_action_group(grp, 1)
+ self.uimanager.insert_action_group(grp)
uidef = self.active_page.ui_definition()
self.merge_ids = [self.uimanager.add_ui_from_string(uidef)]
@@ -1152,13 +909,14 @@ class ViewManager(CLIManager):
mergeid = self.uimanager.add_ui_from_string(uidef)
self.merge_ids.append(mergeid)
- configaction = self.actiongroup.get_action('ConfigView')
+ configaction = self.uimanager.get_action(self.actiongroup,
+ 'ConfigView')
if self.active_page.can_configure():
- configaction.set_sensitive(True)
+ configaction.set_enabled(True)
else:
- configaction.set_sensitive(False)
+ configaction.set_enabled(False)
- def import_data(self, obj):
+ def import_data(self, *obj):
"""
Imports a file
"""
@@ -1170,7 +928,7 @@ class ViewManager(CLIManager):
parent=self.window)
self.__post_load()
- def __open_activate(self, obj):
+ def __open_activate(self, obj, value):
"""
Called when the Open button is clicked, opens the DbManager
"""
@@ -1208,8 +966,8 @@ class ViewManager(CLIManager):
"""
self.dbstate.db.undo_callback = self.__change_undo_label
self.dbstate.db.redo_callback = self.__change_redo_label
- self.__change_undo_label(None)
- self.__change_redo_label(None)
+ self.__change_undo_label(None, update_menu=False)
+ self.__change_redo_label(None, update_menu=False)
self.dbstate.db.undo_history_callback = self.undo_history_update
self.undo_history_close()
@@ -1241,16 +999,10 @@ class ViewManager(CLIManager):
self.uistate.window.set_title(msg)
self.__change_page(self.notebook.get_current_page())
- self.actiongroup.set_visible(rw)
- self.readonlygroup.set_visible(True)
- self.undoactions.set_visible(rw)
- self.redoactions.set_visible(rw)
- self.undohistoryactions.set_visible(rw)
- self.actiongroup.set_sensitive(rw)
- self.readonlygroup.set_sensitive(True)
- self.undoactions.set_sensitive(rw)
- self.redoactions.set_sensitive(rw)
- self.undohistoryactions.set_sensitive(rw)
+ self.uimanager.set_actions_visible(self.actiongroup, rw)
+ self.uimanager.set_actions_visible(self.readonlygroup, True)
+ self.uimanager.set_actions_visible(self.undoactions, rw)
+ self.uimanager.set_actions_visible(self.redoactions, rw)
self.recent_manager.build()
@@ -1263,17 +1015,13 @@ class ViewManager(CLIManager):
"""
self.undo_history_close()
self.uistate.window.set_title("%s - Gramps" % _('No Family Tree'))
- self.actiongroup.set_sensitive(False)
- self.readonlygroup.set_sensitive(False)
- self.undohistoryactions.set_sensitive(False)
self.uistate.clear_filter_results()
self.__disconnect_previous_page()
- self.actiongroup.set_visible(False)
- self.readonlygroup.set_visible(False)
- self.undoactions.set_visible(False)
- self.redoactions.set_visible(False)
- self.undohistoryactions.set_visible(False)
- self.uimanager.ensure_update()
+ self.uimanager.set_actions_visible(self.actiongroup, False)
+ self.uimanager.set_actions_visible(self.readonlygroup, False)
+ self.uimanager.set_actions_visible(self.undoactions, False)
+ self.uimanager.set_actions_visible(self.redoactions, False)
+ self.uimanager.update_menu()
config.set('paths.recent-file', '')
config.save()
@@ -1286,67 +1034,81 @@ class ViewManager(CLIManager):
"""
if not enable:
self.action_st = (
- self.actiongroup.get_sensitive(),
- self.readonlygroup.get_sensitive(),
- self.undoactions.get_sensitive(),
- self.redoactions.get_sensitive(),
- self.undohistoryactions.get_sensitive(),
- self.fileactions.get_sensitive(),
- self.toolactions.get_sensitive(),
- self.reportactions.get_sensitive(),
- self.recent_manager.action_group.get_sensitive())
- self.actiongroup.set_sensitive(enable)
- self.readonlygroup.set_sensitive(enable)
- self.undoactions.set_sensitive(enable)
- self.redoactions.set_sensitive(enable)
- self.undohistoryactions.set_sensitive(enable)
- self.fileactions.set_sensitive(enable)
- self.toolactions.set_sensitive(enable)
- self.reportactions.set_sensitive(enable)
- self.recent_manager.action_group.set_sensitive(enable)
+ self.uimanager.get_actions_sensitive(self.actiongroup),
+ self.uimanager.get_actions_sensitive(self.readonlygroup),
+ self.uimanager.get_actions_sensitive(self.undoactions),
+ self.uimanager.get_actions_sensitive(self.redoactions),
+ self.uimanager.get_actions_sensitive(self.fileactions),
+ self.uimanager.get_actions_sensitive(self.toolactions),
+ self.uimanager.get_actions_sensitive(self.reportactions),
+ self.uimanager.get_actions_sensitive(
+ self.recent_manager.action_group))
+ self.uimanager.set_actions_sensitive(self.actiongroup, enable)
+ self.uimanager.set_actions_sensitive(self.readonlygroup, enable)
+ self.uimanager.set_actions_sensitive(self.undoactions, enable)
+ self.uimanager.set_actions_sensitive(self.redoactions, enable)
+ self.uimanager.set_actions_sensitive(self.fileactions, enable)
+ self.uimanager.set_actions_sensitive(self.toolactions, enable)
+ self.uimanager.set_actions_sensitive(self.reportactions, enable)
+ self.uimanager.set_actions_sensitive(
+ self.recent_manager.action_group, enable)
else:
- self.actiongroup.set_sensitive(self.action_st[0])
- self.readonlygroup.set_sensitive(self.action_st[1])
- self.undoactions.set_sensitive(self.action_st[2])
- self.redoactions.set_sensitive(self.action_st[3])
- self.undohistoryactions.set_sensitive(self.action_st[4])
- self.fileactions.set_sensitive(self.action_st[5])
- self.toolactions.set_sensitive(self.action_st[6])
- self.reportactions.set_sensitive(self.action_st[7])
- self.recent_manager.action_group.set_sensitive(self.action_st[8])
+ self.uimanager.set_actions_sensitive(
+ self.actiongroup, self.action_st[0])
+ self.uimanager.set_actions_sensitive(
+ self.readonlygroup, self.action_st[1])
+ self.uimanager.set_actions_sensitive(
+ self.undoactions, self.action_st[2])
+ self.uimanager.set_actions_sensitive(
+ self.redoactions, self.action_st[3])
+ self.uimanager.set_actions_sensitive(
+ self.fileactions, self.action_st[4])
+ self.uimanager.set_actions_sensitive(
+ self.toolactions, self.action_st[5])
+ self.uimanager.set_actions_sensitive(
+ self.reportactions, self.action_st[6])
+ self.uimanager.set_actions_sensitive(
+ self.recent_manager.action_group, self.action_st[7])
- def __change_undo_label(self, label):
+ def __change_undo_label(self, label, update_menu=True):
"""
Change the UNDO label
"""
- self.uimanager.remove_action_group(self.undoactions)
- self.undoactions = Gtk.ActionGroup(name='Undo')
- if label:
- self.undoactions.add_actions([
- ('Undo', 'edit-undo', label, 'z', None, self.undo)])
+ _menu = '''
+ -
+ win.Undo
+ %s
+
+
+ '''
+ if not label:
+ label = _('_Undo')
+ self.uimanager.set_actions_sensitive(self.undoactions, False)
else:
- self.undoactions.add_actions([
- ('Undo', 'edit-undo', _('_Undo'),
- 'z', None, self.undo)])
- self.undoactions.set_sensitive(False)
- self.uimanager.insert_action_group(self.undoactions, 1)
+ self.uimanager.set_actions_sensitive(self.undoactions, True)
+ self.uimanager.add_ui_from_string([_menu % html.escape(label)])
+ if update_menu:
+ self.uimanager.update_menu()
- def __change_redo_label(self, label):
+ def __change_redo_label(self, label, update_menu=True):
"""
Change the REDO label
"""
- self.uimanager.remove_action_group(self.redoactions)
- self.redoactions = Gtk.ActionGroup(name='Redo')
- if label:
- self.redoactions.add_actions([
- ('Redo', 'edit-redo', label, 'z',
- None, self.redo)])
+ _menu = '''
+ -
+ win.Redo
+ %s
+
+
+ '''
+ if not label:
+ label = _('_Redo')
+ self.uimanager.set_actions_sensitive(self.redoactions, False)
else:
- self.redoactions.add_actions([
- ('Redo', 'edit-undo', _('_Redo'),
- 'z', None, self.redo)])
- self.redoactions.set_sensitive(False)
- self.uimanager.insert_action_group(self.redoactions, 1)
+ self.uimanager.set_actions_sensitive(self.redoactions, True)
+ self.uimanager.add_ui_from_string([_menu % html.escape(label)])
+ if update_menu:
+ self.uimanager.update_menu()
def undo_history_update(self):
"""
@@ -1373,7 +1135,7 @@ class ViewManager(CLIManager):
# Let it go: history window does not exist
return
- def quick_backup(self, obj):
+ def quick_backup(self, *obj):
"""
Make a quick XML back with or without media.
"""
@@ -1413,7 +1175,7 @@ class ViewManager(CLIManager):
filename = os.path.join(backup_path, backup_name)
writer.write(filename)
- def reports_clicked(self, obj):
+ def reports_clicked(self, *obj):
"""
Displays the Reports dialog
"""
@@ -1422,7 +1184,7 @@ class ViewManager(CLIManager):
except WindowActiveError:
return
- def tools_clicked(self, obj):
+ def tools_clicked(self, *obj):
"""
Displays the Tools dialog
"""
@@ -1431,7 +1193,7 @@ class ViewManager(CLIManager):
except WindowActiveError:
return
- def clipboard(self, obj):
+ def clipboard(self, *obj):
"""
Displays the Clipboard
"""
@@ -1442,7 +1204,7 @@ class ViewManager(CLIManager):
return
# ---------------Add new xxx --------------------------------
- def add_new_person(self, obj):
+ def add_new_person(self, *obj):
"""
Add a new person to the database. (Global keybinding)
"""
@@ -1456,7 +1218,7 @@ class ViewManager(CLIManager):
except WindowActiveError:
pass
- def add_new_family(self, obj):
+ def add_new_family(self, *obj):
"""
Add a new family to the database. (Global keybinding)
"""
@@ -1466,7 +1228,7 @@ class ViewManager(CLIManager):
except WindowActiveError:
pass
- def add_new_event(self, obj):
+ def add_new_event(self, *obj):
"""
Add a new custom/unknown event (Note you type first letter of event)
"""
@@ -1477,28 +1239,28 @@ class ViewManager(CLIManager):
except WindowActiveError:
pass
- def add_new_place(self, obj):
+ def add_new_place(self, *obj):
"""Add a new place to the place list"""
try:
EditPlace(self.dbstate, self.uistate, [], Place())
except WindowActiveError:
pass
- def add_new_source(self, obj):
+ def add_new_source(self, *obj):
"""Add a new source to the source list"""
try:
EditSource(self.dbstate, self.uistate, [], Source())
except WindowActiveError:
pass
- def add_new_repository(self, obj):
+ def add_new_repository(self, *obj):
"""Add a new repository to the repository list"""
try:
EditRepository(self.dbstate, self.uistate, [], Repository())
except WindowActiveError:
pass
- def add_new_citation(self, obj):
+ def add_new_citation(self, *obj):
"""
Add a new citation
"""
@@ -1507,14 +1269,14 @@ class ViewManager(CLIManager):
except WindowActiveError:
pass
- def add_new_media(self, obj):
+ def add_new_media(self, *obj):
"""Add a new media object to the media list"""
try:
EditMedia(self.dbstate, self.uistate, [], Media())
except WindowActiveError:
pass
- def add_new_note(self, obj):
+ def add_new_note(self, *obj):
"""Add a new note to the note list"""
try:
EditNote(self.dbstate, self.uistate, [], Note())
@@ -1522,13 +1284,13 @@ class ViewManager(CLIManager):
pass
# ------------------------------------------------------------------------
- def config_view(self, obj):
+ def config_view(self, *obj):
"""
Displays the configuration dialog for the active view
"""
self.active_page.configure()
- def undo(self, obj):
+ def undo(self, *obj):
"""
Calls the undo function on the database
"""
@@ -1536,7 +1298,7 @@ class ViewManager(CLIManager):
self.dbstate.db.undo()
self.uistate.set_busy_cursor(False)
- def redo(self, obj):
+ def redo(self, *obj):
"""
Calls the redo function on the database
"""
@@ -1544,7 +1306,7 @@ class ViewManager(CLIManager):
self.dbstate.db.redo()
self.uistate.set_busy_cursor(False)
- def undo_history(self, obj):
+ def undo_history(self, *obj):
"""
Displays the Undo history window
"""
@@ -1553,7 +1315,7 @@ class ViewManager(CLIManager):
except WindowActiveError:
return
- def export_data(self, obj):
+ def export_data(self, *obj):
"""
Calls the ExportAssistant to export data
"""
@@ -1579,14 +1341,13 @@ class ViewManager(CLIManager):
if self.toolactions:
self.uistate.uimanager.remove_action_group(self.toolactions)
self.uistate.uimanager.remove_ui(self.tool_menu_ui_id)
- self.toolactions = Gtk.ActionGroup(name='ToolWindow')
+ self.toolactions = ActionGroup(name='ToolWindow')
(uidef, actions) = self.build_plugin_menu(
'ToolsMenu', tool_menu_list, tool.tool_categories,
make_plugin_callback)
self.toolactions.add_actions(actions)
self.tool_menu_ui_id = self.uistate.uimanager.add_ui_from_string(uidef)
- self.uimanager.insert_action_group(self.toolactions, 1)
- self.uistate.uimanager.ensure_update()
+ self.uimanager.insert_action_group(self.toolactions)
def __build_report_menu(self, report_menu_list):
"""
@@ -1595,26 +1356,27 @@ class ViewManager(CLIManager):
if self.reportactions:
self.uistate.uimanager.remove_action_group(self.reportactions)
self.uistate.uimanager.remove_ui(self.report_menu_ui_id)
- self.reportactions = Gtk.ActionGroup(name='ReportWindow')
+ self.reportactions = ActionGroup(name='ReportWindow')
(udef, actions) = self.build_plugin_menu(
'ReportsMenu', report_menu_list, standalone_categories,
make_plugin_callback)
self.reportactions.add_actions(actions)
self.report_menu_ui_id = self.uistate.uimanager.add_ui_from_string(udef)
- self.uimanager.insert_action_group(self.reportactions, 1)
- self.uistate.uimanager.ensure_update()
+ self.uimanager.insert_action_group(self.reportactions)
def build_plugin_menu(self, text, item_list, categories, func):
"""
Builds a new XML description for a menu based on the list of plugindata
"""
+ menuitem = ('- \n'
+ 'win.%s\n'
+ ''
+ '%s...\n'
+ '
\n')
+
actions = []
ofile = StringIO()
- ofile.write(''
- '' % (text, 'P_'+ text))
-
- menu = Gtk.Menu()
- menu.show()
+ ofile.write('' % ('P_' + text))
hash_data = defaultdict(list)
for pdata in item_list:
@@ -1628,39 +1390,36 @@ class ViewManager(CLIManager):
catlist = sorted(item for item in hash_data if item != _UNSUPPORTED)
for key in catlist:
- new_key = key[0].replace(' ', '-')
- ofile.write('' % new_key)
- actions.append((new_key, None, key[1]))
+ ofile.write('\n%s\n' % key[1])
pdatas = hash_data[key]
pdatas.sort(key=lambda x: x.name)
for pdata in pdatas:
new_key = pdata.id.replace(' ', '-')
- menu_name = ("%s...") % pdata.name
- ofile.write('' % new_key)
- actions.append((new_key, None, menu_name, None, None,
- func(pdata, self.dbstate, self.uistate)))
- ofile.write('')
+ ofile.write(menuitem % (new_key, pdata.name))
+ actions.append((new_key, func(pdata, self.dbstate,
+ self.uistate)))
+ ofile.write('\n')
# If there are any unsupported items we add separator
# and the unsupported category at the end of the menu
if _UNSUPPORTED in hash_data:
- ofile.write('')
- ofile.write('' % _UNSUPPORTED[0])
- actions.append((_UNSUPPORTED[0], None, _UNSUPPORTED[1]))
+ ofile.write('\n%s\n' %
+ _UNSUPPORTED[1])
pdatas = hash_data[_UNSUPPORTED]
pdatas.sort(key=lambda x: x.name)
for pdata in pdatas:
new_key = pdata.id.replace(' ', '-')
- menu_name = ("%s...") % pdata.name
- ofile.write('' % new_key)
- actions.append((new_key, None, menu_name, None, None,
- func(pdata, self.dbstate, self.uistate)))
- ofile.write('')
+ ofile.write(menuitem % (new_key, pdata.name))
+ actions.append((new_key, func(pdata, self.dbstate,
+ self.uistate)))
+ ofile.write('\n')
- ofile.write('')
- return (ofile.getvalue(), actions)
+ ofile.write('\n')
+ return ([ofile.getvalue()], actions)
- def display_about_box(self, obj):
+ def display_about_box(self, *obj):
"""Display the About box."""
about = GrampsAboutDialog(self.uistate.window)
about.run()
@@ -1720,43 +1479,43 @@ class ViewManager(CLIManager):
if viewstoshow[cat] not in resultorder)
return resultorder
-def key_bindings(obj):
+def key_bindings(*obj):
"""
Display key bindings
"""
display_help(webpage=WIKI_HELP_PAGE_KEY)
-def manual_activate(obj):
+def manual_activate(*obj):
"""
Display the Gramps manual
"""
display_help(webpage=WIKI_HELP_PAGE_MAN)
-def report_bug_activate(obj):
+def report_bug_activate(*obj):
"""
Display the bug tracker web site
"""
display_url(URL_BUGTRACKER)
-def home_page_activate(obj):
+def home_page_activate(*obj):
"""
Display the Gramps home page
"""
display_url(URL_HOMEPAGE)
-def mailing_lists_activate(obj):
+def mailing_lists_activate(*obj):
"""
Display the mailing list web page
"""
display_url(URL_MAILINGLIST)
-def extra_plugins_activate(obj):
+def extra_plugins_activate(*obj):
"""
Display the wiki page with extra plugins
"""
display_url(URL_WIKISTRING+WIKI_EXTRAPLUGINS)
-def faq_activate(obj):
+def faq_activate(*obj):
"""
Display FAQ
"""
@@ -1815,7 +1574,7 @@ def make_plugin_callback(pdata, dbstate, uistate):
"""
Makes a callback for a report/tool menu item
"""
- return lambda x: run_plugin(pdata, dbstate, uistate)
+ return lambda x, y: run_plugin(pdata, dbstate, uistate)
def views_to_show(views, use_last=True):
"""
diff --git a/gramps/gui/views/bookmarks.py b/gramps/gui/views/bookmarks.py
index a29da9b5a..0fa57e439 100644
--- a/gramps/gui/views/bookmarks.py
+++ b/gramps/gui/views/bookmarks.py
@@ -28,6 +28,7 @@
#-------------------------------------------------------------------------
from abc import ABCMeta, abstractmethod
from io import StringIO
+import html
#-------------------------------------------------------------------------
#
@@ -51,6 +52,7 @@ from gi.repository import Gtk
from ..display import display_help
from ..listmodel import ListModel
from ..managedwindow import ManagedWindow
+from ..uimanager import ActionGroup
from gramps.gen.utils.db import navigation_label
from gramps.gen.const import URL_MANUAL_PAGE
from gramps.gen.const import GRAMPS_LOCALE as glocale
@@ -71,9 +73,6 @@ WIKI_HELP_SEC = _('manual|Bookmarks')
#
#-------------------------------------------------------------------------
-TOP = ''''''
-BTM = ''''''
-
DISABLED = -1
class Bookmarks(metaclass=ABCMeta):
@@ -93,7 +92,7 @@ class Bookmarks(metaclass=ABCMeta):
if self.dbstate.is_open():
self.update_bookmarks()
self.active = DISABLED
- self.action_group = Gtk.ActionGroup(name='Bookmarks')
+ self.action_group = ActionGroup(name='Bookmarks')
if self.dbstate.is_open():
self.connect_signals()
self.dbstate.connect('database-changed', self.db_changed)
@@ -129,7 +128,8 @@ class Bookmarks(metaclass=ABCMeta):
"""
Redraw the display.
"""
- self.redraw()
+ # used by navigationview; other updates follow
+ self.redraw(update_menu=False)
def undisplay(self):
"""
@@ -138,8 +138,7 @@ class Bookmarks(metaclass=ABCMeta):
if self.active != DISABLED:
self.uistate.uimanager.remove_ui(self.active)
self.uistate.uimanager.remove_action_group(self.action_group)
- self.action_group = Gtk.ActionGroup(name='Bookmarks')
- self.uistate.uimanager.ensure_update()
+ self.action_group = ActionGroup(name='Bookmarks')
self.active = DISABLED
def redraw_and_report_change(self):
@@ -147,10 +146,14 @@ class Bookmarks(metaclass=ABCMeta):
self.dbstate.db.report_bm_change()
self.redraw()
- def redraw(self):
+ def redraw(self, update_menu=True):
"""Create the pulldown menu."""
+ menuitem = ('- \n'
+ 'win.%s\n'
+ ''
+ '%s\n'
+ '
\n')
text = StringIO()
- text.write(TOP)
self.undisplay()
@@ -158,24 +161,25 @@ class Bookmarks(metaclass=ABCMeta):
count = 0
if self.dbstate.is_open() and len(self.bookmarks.get()) > 0:
- text.write('')
+ text.write('\n')
for item in self.bookmarks.get():
try:
label, dummy_obj = self.make_label(item)
func = self.callback(item)
- action_id = "BM:%s" % item
- actions.append((action_id, None, label, None, None, func))
- text.write('' % action_id)
+ action_id = "BM.%s" % item
+ actions.append((action_id, func))
+ text.write(menuitem % (action_id, html.escape(label)))
count += 1
except AttributeError:
pass
- text.write('')
+ text.write('\n')
- text.write(BTM)
self.action_group.add_actions(actions)
- self.uistate.uimanager.insert_action_group(self.action_group, 1)
- self.active = self.uistate.uimanager.add_ui_from_string(text.getvalue())
- self.uistate.uimanager.ensure_update()
+ self.uistate.uimanager.insert_action_group(self.action_group)
+ self.active = self.uistate.uimanager.add_ui_from_string(
+ [text.getvalue()])
+ if update_menu:
+ self.uistate.uimanager.update_menu()
text.close()
@abstractmethod
@@ -538,4 +542,4 @@ def make_callback(handle, function):
"""
Build a unique call to the function with the associated handle.
"""
- return lambda x: function(handle)
+ return lambda x, y: function(handle)
diff --git a/gramps/gui/views/listview.py b/gramps/gui/views/listview.py
index 84255bdb6..6c7a49681 100644
--- a/gramps/gui/views/listview.py
+++ b/gramps/gui/views/listview.py
@@ -55,7 +55,7 @@ from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.sgettext
from .pageview import PageView
from .navigationview import NavigationView
-from ..actiongroup import ActionGroup
+from ..uimanager import ActionGroup
from ..columnorder import ColumnOrder
from gramps.gen.config import config
from gramps.gen.errors import WindowActiveError, FilterError, HandleError
@@ -64,6 +64,7 @@ from ..widgets.menuitem import add_menuitem
from gramps.gen.const import CUSTOM_FILTERS
from gramps.gen.utils.debug import profile
from gramps.gen.utils.string import data_recover_msg
+from gramps.gen.plug import CATEGORY_QR_PERSON
from ..dialog import QuestionDialog, QuestionDialog2, ErrorDialog
from ..editors import FilterEditor
from ..ddtargets import DdTargets
@@ -122,6 +123,8 @@ class ListView(NavigationView):
self.generic_filter = None
dbstate.connect('database-changed', self.change_db)
self.connect_signals()
+ self.at_popup_action = None
+ self.at_popup_menu = None
def no_database(self):
## TODO GTK3: This is never called!! Dbguielement disconnects
@@ -206,24 +209,19 @@ class ListView(NavigationView):
NavigationView.define_actions(self)
- self.edit_action = ActionGroup(name=self.title + '/ChangeOrder')
+ self.edit_action = ActionGroup(name=self.title + '/Edits')
self.edit_action.add_actions([
- ('Add', 'list-add', _("_Add..."), "Insert",
- self.ADD_MSG, self.add),
- ('Remove', 'list-remove', _("_Delete"), "Delete",
- self.DEL_MSG, self.remove),
- ('Merge', 'gramps-merge', _('_Merge...'), None,
- self.MERGE_MSG, self.merge),
- ('ExportTab', None, _('Export View...'), None, None,
- self.export),
- ])
+ ('Add', self.add, 'Insert'),
+ ('Remove', self.remove, 'Delete'),
+ ('PRIMARY-BackSpace', self.remove, 'BackSpace'),
+ ('Merge', self.merge), ])
self._add_action_group(self.edit_action)
-
- self._add_action('Edit', 'gtk-edit', _("action|_Edit..."),
- accel="Return",
- tip=self.EDIT_MSG,
- callback=self.edit)
+ self.action_list.extend([
+ ('ExportTab', self.export),
+ ('Edit', self.edit, 'Return'),
+ ('PRIMARY-J', self.jump, 'J'),
+ ('FilterEdit', self.filter_editor)])
def build_columns(self):
list(map(self.list.remove_column, self.columns))
@@ -291,7 +289,7 @@ class ListView(NavigationView):
Called when the page is displayed.
"""
NavigationView.set_active(self)
- self.uistate.viewmanager.tags.tag_enable()
+ self.uistate.viewmanager.tags.tag_enable(update_menu=False)
self.uistate.show_filter_results(self.dbstate,
self.model.displayed(),
self.model.total())
@@ -303,9 +301,6 @@ class ListView(NavigationView):
NavigationView.set_inactive(self)
self.uistate.viewmanager.tags.tag_disable()
- def __build_tree(self):
- profile(self._build_tree)
-
def build_tree(self, force_sidebar=False):
if self.active:
cput0 = time.clock()
@@ -372,7 +367,7 @@ class ListView(NavigationView):
"""
return 'gramps-tree-list'
- def filter_editor(self, obj):
+ def filter_editor(self, *obj):
try:
FilterEditor(self.FILTER_TYPE , CUSTOM_FILTERS,
self.dbstate, self.uistate)
@@ -441,7 +436,7 @@ class ListView(NavigationView):
self.uistate.push_message(self.dbstate,
_("Active object not visible"))
- def add_bookmark(self, obj):
+ def add_bookmark(self, *obj):
mlist = []
self.selection.selected_foreach(self.blist, mlist)
@@ -851,6 +846,7 @@ class ListView(NavigationView):
"""
if not self.dbstate.is_open():
return False
+ menu = self.uimanager.get_widget('Popup')
if event.type == Gdk.EventType._2BUTTON_PRESS and event.button == 1:
if self.model.get_flags() & Gtk.TreeModelFlags.LIST_ONLY:
self.edit(obj)
@@ -866,49 +862,54 @@ class ListView(NavigationView):
else:
self.edit(obj)
return True
- elif is_right_click(event):
- menu = self.uistate.uimanager.get_widget('/Popup')
- if menu:
- # Quick Reports
- qr_menu = self.uistate.uimanager.\
- get_widget('/Popup/QuickReport')
- if qr_menu and self.QR_CATEGORY > -1 :
- (ui, qr_actions) = create_quickreport_menu(
- self.QR_CATEGORY,
- self.dbstate,
- self.uistate,
- self.first_selected())
- self.__build_menu(qr_menu, qr_actions)
+ elif is_right_click(event) and menu:
+ prefix = 'win'
+ self.at_popup_menu = []
+ actions = []
+ # Quick Reports
+ if self.QR_CATEGORY > -1:
+ (qr_ui, qr_actions) = create_quickreport_menu(
+ self.QR_CATEGORY, self.dbstate, self.uistate,
+ self.first_selected(), prefix)
+ if self.get_active() and qr_actions:
+ actions.extend(qr_actions)
+ qr_ui = ("%s" %
+ qr_ui)
+ self.at_popup_menu.append(qr_ui)
- # Web Connects
- web_menu = self.uistate.uimanager.\
- get_widget('/Popup/WebConnect')
- if web_menu:
- web_actions = create_web_connect_menu(
- self.dbstate,
- self.uistate,
- self.navigation_type(),
- self.first_selected())
- self.__build_menu(web_menu, web_actions)
+ # Web Connects
+ if self.QR_CATEGORY == CATEGORY_QR_PERSON:
+ (web_ui, web_actions) = create_web_connect_menu(
+ self.dbstate, self.uistate, self.navigation_type(),
+ self.first_selected(), prefix)
+ if self.get_active() and web_actions:
+ actions.extend(web_actions)
+ self.at_popup_menu.append(web_ui)
- menu.popup(None, None, None, None, event.button, event.time)
- return True
+ if self.at_popup_action:
+ self.uimanager.remove_ui(self.at_popup_menu)
+ self.uimanager.remove_action_group(self.at_popup_action)
+ self.at_popup_action = ActionGroup('AtPopupActions',
+ actions)
+ self.uimanager.insert_action_group(self.at_popup_action)
+ self.at_popup_menu = self.uimanager.add_ui_from_string(
+ self.at_popup_menu)
+ self.uimanager.update_menu()
+
+ menu = self.uimanager.get_widget('Popup')
+ popup_menu = Gtk.Menu.new_from_model(menu)
+ popup_menu.attach_to_widget(obj, None)
+ popup_menu.show_all()
+ if Gtk.MINOR_VERSION < 22:
+ # ToDo The following is reported to work poorly with Wayland
+ popup_menu.popup(None, None, None, None,
+ event.button, event.time)
+ else:
+ popup_menu.popup_at_pointer(event)
+ return True
return False
- def __build_menu(self, menu, actions):
- """
- Build a submenu for quick reports and web connects
- """
- if self.get_active() and len(actions) > 1:
- sub_menu = Gtk.Menu()
- for action in actions[1:]:
- add_menuitem(sub_menu, action[2], None, action[5])
- menu.set_submenu(sub_menu)
- menu.show()
- else:
- menu.hide()
-
def _key_press(self, obj, event):
"""
Called when a key is pressed on a listview
@@ -1002,9 +1003,6 @@ class ListView(NavigationView):
return True
return False
- def key_delete(self):
- self.remove(None)
-
def change_page(self):
"""
Called when a page is changed.
@@ -1014,8 +1012,9 @@ class ListView(NavigationView):
self.uistate.show_filter_results(self.dbstate,
self.model.displayed(),
self.model.total())
- self.edit_action.set_visible(True)
- self.edit_action.set_sensitive(not self.dbstate.db.readonly)
+ self.uimanager.set_actions_visible(self.edit_action, True)
+ self.uimanager.set_actions_sensitive(self.edit_action,
+ not self.dbstate.db.readonly)
def on_delete(self):
"""
@@ -1038,7 +1037,7 @@ class ListView(NavigationView):
####################################################################
# Export data
####################################################################
- def export(self, obj):
+ def export(self, *obj):
chooser = Gtk.FileChooserDialog(
_("Export View as Spreadsheet"),
self.uistate.window,
@@ -1140,25 +1139,25 @@ class ListView(NavigationView):
# Template functions
####################################################################
@abstractmethod
- def edit(self, obj, data=None):
+ def edit(self, *obj):
"""
Template function to allow the editing of the selected object
"""
@abstractmethod
- def remove(self, handle, data=None):
+ def remove(self, *obj):
"""
Template function to allow the removal of an object by its handle
"""
@abstractmethod
- def add(self, obj, data=None):
+ def add(self, *obj):
"""
Template function to allow the adding of a new object
"""
@abstractmethod
- def merge(self, obj, data=None):
+ def merge(self, *obj):
"""
Template function to allow the merger of two objects.
"""
@@ -1169,7 +1168,7 @@ class ListView(NavigationView):
Template function to allow the removal of an object by its handle
"""
- def open_all_nodes(self, obj):
+ def open_all_nodes(self, *obj):
"""
Method for Treeviews to open all groups
obj: for use of method in event callback
@@ -1182,14 +1181,14 @@ class ListView(NavigationView):
self.uistate.set_busy_cursor(False)
self.uistate.modify_statusbar(self.dbstate)
- def close_all_nodes(self, obj):
+ def close_all_nodes(self, *obj):
"""
Method for Treeviews to close all groups
obj: for use of method in event callback
"""
self.list.collapse_all()
- def open_branch(self, obj):
+ def open_branch(self, *obj):
"""
Expand the selected branches and all children.
obj: for use of method in event callback
@@ -1204,7 +1203,7 @@ class ListView(NavigationView):
self.uistate.set_busy_cursor(False)
self.uistate.modify_statusbar(self.dbstate)
- def close_branch(self, obj):
+ def close_branch(self, *obj):
"""
Collapse the selected branches.
:param obj: not used, present only to allow the use of the method in
diff --git a/gramps/gui/views/navigationview.py b/gramps/gui/views/navigationview.py
index df4fd3e3b..0194c3164 100644
--- a/gramps/gui/views/navigationview.py
+++ b/gramps/gui/views/navigationview.py
@@ -29,6 +29,7 @@ Provide the base classes for GRAMPS' DataView classes
#
#----------------------------------------------------------------
from abc import abstractmethod
+import html
import logging
_LOG = logging.getLogger('.navigationview')
@@ -49,7 +50,7 @@ from gi.repository import Gtk
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.sgettext
from .pageview import PageView
-from ..actiongroup import ActionGroup
+from ..uimanager import ActionGroup
from gramps.gen.utils.db import navigation_label
from gramps.gen.constfunc import mod_key
from ..utils import match_primary_mask
@@ -57,19 +58,9 @@ from ..utils import match_primary_mask
DISABLED = -1
MRU_SIZE = 10
-MRU_TOP = [
- ''
- ''
- ''
- ''
- ]
+MRU_TOP = ''
-MRU_BTM = [
- ''
- ''
- ''
- ''
- ]
#------------------------------------------------------------------------------
#
# NavigationView
@@ -94,6 +85,7 @@ class NavigationView(PageView):
self.mru_signal = None
self.nav_group = nav_group
self.mru_active = DISABLED
+ self.uimanager = uistate.uimanager
self.uistate.register(state, self.navigation_type(), self.nav_group)
@@ -122,8 +114,8 @@ class NavigationView(PageView):
"""
PageView.disable_action_group(self)
- self.fwd_action.set_visible(False)
- self.back_action.set_visible(False)
+ self.uimanager.set_actions_visible(self.fwd_action, False)
+ self.uimanager.set_actions_visible(self.back_action, False)
def enable_action_group(self, obj):
"""
@@ -133,20 +125,25 @@ class NavigationView(PageView):
"""
PageView.enable_action_group(self, obj)
- self.fwd_action.set_visible(True)
- self.back_action.set_visible(True)
+ self.uimanager.set_actions_visible(self.fwd_action, True)
+ self.uimanager.set_actions_visible(self.back_action, True)
hobj = self.get_history()
- self.fwd_action.set_sensitive(not hobj.at_end())
- self.back_action.set_sensitive(not hobj.at_front())
+ self.uimanager.set_actions_sensitive(self.fwd_action,
+ not hobj.at_end())
+ self.uimanager.set_actions_sensitive(self.back_action,
+ not hobj.at_front())
def change_page(self):
"""
Called when the page changes.
"""
hobj = self.get_history()
- self.fwd_action.set_sensitive(not hobj.at_end())
- self.back_action.set_sensitive(not hobj.at_front())
- self.other_action.set_sensitive(not self.dbstate.db.readonly)
+ self.uimanager.set_actions_sensitive(self.fwd_action,
+ not hobj.at_end())
+ self.uimanager.set_actions_sensitive(self.back_action,
+ not hobj.at_front())
+ self.uimanager.set_actions_sensitive(self.other_action,
+ not self.dbstate.db.readonly)
self.uistate.modify_statusbar(self.dbstate)
def set_active(self):
@@ -159,7 +156,7 @@ class NavigationView(PageView):
hobj = self.get_history()
self.active_signal = hobj.connect('active-changed', self.goto_active)
self.mru_signal = hobj.connect('mru-changed', self.update_mru_menu)
- self.update_mru_menu(hobj.mru)
+ self.update_mru_menu(hobj.mru, update_menu=False)
self.goto_active(None)
@@ -199,8 +196,10 @@ class NavigationView(PageView):
self.goto_handle(active_handle)
hobj = self.get_history()
- self.fwd_action.set_sensitive(not hobj.at_end())
- self.back_action.set_sensitive(not hobj.at_front())
+ self.uimanager.set_actions_sensitive(self.fwd_action,
+ not hobj.at_end())
+ self.uimanager.set_actions_sensitive(self.back_action,
+ not hobj.at_front())
def get_active(self):
"""
@@ -238,7 +237,7 @@ class NavigationView(PageView):
####################################################################
# BOOKMARKS
####################################################################
- def add_bookmark(self, obj):
+ def add_bookmark(self, *obj):
"""
Add a bookmark to the list.
"""
@@ -259,7 +258,7 @@ class NavigationView(PageView):
"no one was selected."),
parent=self.uistate.window)
- def edit_bookmarks(self, obj):
+ def edit_bookmarks(self, *obj):
"""
Call the bookmark editor.
"""
@@ -271,12 +270,8 @@ class NavigationView(PageView):
"""
self.book_action = ActionGroup(name=self.title + '/Bookmark')
self.book_action.add_actions([
- ('AddBook', 'gramps-bookmark-new', _('_Add Bookmark'),
- 'd', None, self.add_bookmark),
- ('EditBook', 'gramps-bookmark-edit',
- _("%(title)s...") % {'title': _("Organize Bookmarks")},
- 'D', None,
- self.edit_bookmarks),
+ ('AddBook', self.add_bookmark, 'd'),
+ ('EditBook', self.edit_bookmarks, 'D'),
])
self._add_action_group(self.book_action)
@@ -290,35 +285,25 @@ class NavigationView(PageView):
"""
# add the Forward action group to handle the Forward button
self.fwd_action = ActionGroup(name=self.title + '/Forward')
- self.fwd_action.add_actions([
- ('Forward', 'go-next', _("_Forward"),
- "%sRight" % mod_key(), _("Go to the next object in the history"),
- self.fwd_clicked)
- ])
+ self.fwd_action.add_actions([('Forward', self.fwd_clicked,
+ "%sRight" % mod_key())])
# add the Backward action group to handle the Forward button
self.back_action = ActionGroup(name=self.title + '/Backward')
- self.back_action.add_actions([
- ('Back', 'go-previous', _("_Back"),
- "%sLeft" % mod_key(), _("Go to the previous object in the history"),
- self.back_clicked)
- ])
+ self.back_action.add_actions([('Back', self.back_clicked,
+ "%sLeft" % mod_key())])
- self._add_action('HomePerson', 'go-home', _("_Home"),
- accel="%sHome" % mod_key(),
- tip=_("Go to the default person"), callback=self.home)
+ self._add_action('HomePerson', self.home, "%sHome" % mod_key())
self.other_action = ActionGroup(name=self.title + '/PersonOther')
self.other_action.add_actions([
- ('SetActive', 'go-home', _("Set _Home Person"), None,
- None, self.set_default_person),
- ])
+ ('SetActive', self.set_default_person)])
self._add_action_group(self.back_action)
self._add_action_group(self.fwd_action)
self._add_action_group(self.other_action)
- def set_default_person(self, obj):
+ def set_default_person(self, *obj):
"""
Set the default person.
"""
@@ -326,7 +311,7 @@ class NavigationView(PageView):
if active:
self.dbstate.db.set_default_person_handle(active)
- def home(self, obj):
+ def home(self, *obj):
"""
Move to the default person.
"""
@@ -342,7 +327,7 @@ class NavigationView(PageView):
"via the menu Edit ->Set Home Person."),
parent=self.uistate.window)
- def jump(self):
+ def jump(self, *obj):
"""
A dialog to move to a Gramps ID entered by the user.
"""
@@ -383,7 +368,7 @@ class NavigationView(PageView):
"""
pass
- def fwd_clicked(self, obj):
+ def fwd_clicked(self, *obj):
"""
Move forward one object in the history.
"""
@@ -392,11 +377,12 @@ class NavigationView(PageView):
if not hobj.at_end():
hobj.forward()
self.uistate.modify_statusbar(self.dbstate)
- self.fwd_action.set_sensitive(not hobj.at_end())
- self.back_action.set_sensitive(True)
+ self.uimanager.set_actions_sensitive(self.fwd_action,
+ not hobj.at_end())
+ self.uimanager.set_actions_sensitive(self.back_action, True)
hobj.lock = False
- def back_clicked(self, obj):
+ def back_clicked(self, *obj):
"""
Move backward one object in the history.
"""
@@ -405,8 +391,9 @@ class NavigationView(PageView):
if not hobj.at_front():
hobj.back()
self.uistate.modify_statusbar(self.dbstate)
- self.back_action.set_sensitive(not hobj.at_front())
- self.fwd_action.set_sensitive(True)
+ self.uimanager.set_actions_sensitive(self.back_action,
+ not hobj.at_front())
+ self.uimanager.set_actions_sensitive(self.fwd_action, True)
hobj.lock = False
####################################################################
@@ -418,44 +405,52 @@ class NavigationView(PageView):
Remove the UI and action groups for the MRU list.
"""
if self.mru_active != DISABLED:
- self.uistate.uimanager.remove_ui(self.mru_active)
- self.uistate.uimanager.remove_action_group(self.mru_action)
+ self.uimanager.remove_ui(self.mru_active)
+ self.uimanager.remove_action_group(self.mru_action)
self.mru_active = DISABLED
- def mru_enable(self):
+ def mru_enable(self, update_menu=False):
"""
Enables the UI and action groups for the MRU list.
"""
if self.mru_active == DISABLED:
- self.uistate.uimanager.insert_action_group(self.mru_action, 1)
- self.mru_active = self.uistate.uimanager.add_ui_from_string(self.mru_ui)
- self.uistate.uimanager.ensure_update()
+ self.uimanager.insert_action_group(self.mru_action)
+ self.mru_active = self.uimanager.add_ui_from_string(self.mru_ui)
+ if update_menu:
+ self.uimanager.update_menu()
- def update_mru_menu(self, items):
+ def update_mru_menu(self, items, update_menu=True):
"""
Builds the UI and action group for the MRU list.
"""
+ menuitem = ''' -
+ win.%s%02d
+ %s
+
+ '''
+ menus = ''
self.mru_disable()
nav_type = self.navigation_type()
hobj = self.get_history()
menu_len = min(len(items) - 1, MRU_SIZE)
- entry = ''
- data = [entry % (nav_type, index) for index in range(0, menu_len)]
- self.mru_ui = "".join(MRU_TOP) + "".join(data) + "".join(MRU_BTM)
+ for index in range(0, menu_len):
+ name, obj = navigation_label(self.dbstate.db, nav_type,
+ items[index])
+ menus += menuitem % (nav_type, index, html.escape(name))
+ self.mru_ui = [MRU_TOP + menus + MRU_BTM]
mitems = items[-MRU_SIZE - 1:-1] # Ignore current handle
mitems.reverse()
data = []
for index, handle in enumerate(mitems):
- name, obj = navigation_label(self.dbstate.db, nav_type, handle)
- data.append(('%s%02d'%(nav_type, index), None, name,
- "%s%d" % (mod_key(), index), None,
- make_callback(hobj.push, handle)))
+ data.append(('%s%02d'%(nav_type, index),
+ make_callback(hobj.push, handle),
+ "%s%d" % (mod_key(), index)))
self.mru_action = ActionGroup(name=self.title + '/MRU')
self.mru_action.add_actions(data)
- self.mru_enable()
+ self.mru_enable(update_menu)
####################################################################
# Template functions
@@ -503,4 +498,4 @@ def make_callback(func, handle):
"""
Generates a callback function based off the passed arguments
"""
- return lambda x: func(handle)
+ return lambda x, y: func(handle)
diff --git a/gramps/gui/views/pageview.py b/gramps/gui/views/pageview.py
index 6fde0810b..1f510aead 100644
--- a/gramps/gui/views/pageview.py
+++ b/gramps/gui/views/pageview.py
@@ -51,7 +51,7 @@ from ..dbguielement import DbGUIElement
from ..widgets.grampletbar import GrampletBar
from ..configure import ConfigureDialog
from gramps.gen.config import config
-from ..actiongroup import ActionGroup
+from ..uimanager import ActionGroup
#------------------------------------------------------------------------------
#
@@ -97,25 +97,24 @@ class PageView(DbGUIElement, metaclass=ABCMeta):
self.uistate = uistate
self.action_list = []
self.action_toggle_list = []
- self.action_toolmenu_list = []
- self.action_toolmenu = {} #easy access to toolmenuaction and proxies
self.action_group = None
self.additional_action_groups = []
self.additional_uis = []
- self.ui_def = '''
-
-
-
-
-
-
-
-
- '''
+ self.ui_def = ['''
+
+ -
+ win.Sidebar
+ _Sidebar
+
+ -
+ win.Bottombar
+ _Bottombar
+
+
+ ''']
self.dirty = True
self.active = False
self._dirty_on_change_inactive = True
- self.func_list = {}
if isinstance(self.pdata.category, tuple):
self.category, self.translated_category = self.pdata.category
@@ -201,24 +200,24 @@ class PageView(DbGUIElement, metaclass=ABCMeta):
"""
self._config.set(setting, widget.get_position())
- def __sidebar_toggled(self, action):
+ def __sidebar_toggled(self, action, value):
"""
Called when the sidebar is toggled.
"""
- active = action.get_active()
- if active:
+ action.set_state(value) # change GUI
+ if value.get_boolean():
self.sidebar.show()
self.sidebar_toggled(True)
else:
self.sidebar.hide()
self.sidebar_toggled(False)
- def __bottombar_toggled(self, action):
+ def __bottombar_toggled(self, action, value):
"""
Called when the bottombar is toggled.
"""
- active = action.get_active()
- if active:
+ action.set_state(value) # change GUI
+ if value.get_boolean():
self.bottombar.show()
else:
self.bottombar.hide()
@@ -312,12 +311,6 @@ class PageView(DbGUIElement, metaclass=ABCMeta):
return True
return False
- def call_function(self, key):
- """
- Calls the function associated with the key value
- """
- self.func_list.get(key)()
-
def post(self):
"""
Called after a page is created.
@@ -373,14 +366,15 @@ class PageView(DbGUIElement, metaclass=ABCMeta):
Turns off the visibility of the View's action group, if defined
"""
if self.action_group:
- self.action_group.set_visible(False)
+ self.uistate.uimanager.set_actions_visible(self.action_group,
+ False)
def enable_action_group(self, obj):
"""
Turns on the visibility of the View's action group, if defined
"""
if self.action_group:
- self.action_group.set_visible(True)
+ self.uistate.uimanager.set_actions_visible(self.action_group, True)
def get_stock(self):
"""
@@ -438,11 +432,9 @@ class PageView(DbGUIElement, metaclass=ABCMeta):
View. The user typically defines self.action_list and
self.action_toggle_list in this function.
"""
- self._add_toggle_action('Sidebar', None, _('_Sidebar'),
- "R", None, self.__sidebar_toggled,
+ self._add_toggle_action('Sidebar', self.__sidebar_toggled, '',
self.sidebar.get_property('visible'))
- self._add_toggle_action('Bottombar', None, _('_Bottombar'),
- "B", None, self.__bottombar_toggled,
+ self._add_toggle_action('Bottombar', self.__bottombar_toggled, '',
self.bottombar.get_property('visible'))
def __build_action_group(self):
@@ -455,31 +447,19 @@ class PageView(DbGUIElement, metaclass=ABCMeta):
if len(self.action_list) > 0:
self.action_group.add_actions(self.action_list)
if len(self.action_toggle_list) > 0:
- self.action_group.add_toggle_actions(self.action_toggle_list)
+ self.action_group.add_actions(self.action_toggle_list)
- def _add_action(self, name, icon_name, label, accel=None, tip=None,
- callback=None):
+ def _add_action(self, name, callback=None, accel=None):
"""
Add an action to the action list for the current view.
"""
- self.action_list.append((name, icon_name, label, accel, tip,
- callback))
+ self.action_list.append((name, callback, accel))
- def _add_toggle_action(self, name, icon_name, label, accel=None,
- tip=None, callback=None, value=False):
+ def _add_toggle_action(self, name, callback=None, accel= None, value=False):
"""
Add a toggle action to the action list for the current view.
"""
- self.action_toggle_list.append((name, icon_name, label, accel,
- tip, callback, value))
-
- def _add_toolmenu_action(self, name, label, tooltip, callback,
- arrowtooltip):
- """
- Add a menu action to the action list for the current view.
- """
- self.action_toolmenu_list.append((name, label, tooltip, callback,
- arrowtooltip))
+ self.action_toggle_list.append((name, callback, accel, value))
def get_actions(self):
"""
diff --git a/gramps/gui/views/tags.py b/gramps/gui/views/tags.py
index 3c677c64c..0206ae611 100644
--- a/gramps/gui/views/tags.py
+++ b/gramps/gui/views/tags.py
@@ -50,7 +50,7 @@ from gramps.gen.const import URL_MANUAL_PAGE
from ..display import display_help
from ..dialog import ErrorDialog, QuestionDialog2
import gramps.gui.widgets.progressdialog as progressdlg
-from ..actiongroup import ActionGroup
+from ..uimanager import ActionGroup
from ..managedwindow import ManagedWindow
#-------------------------------------------------------------------------
@@ -58,29 +58,54 @@ from ..managedwindow import ManagedWindow
# Constants
#
#-------------------------------------------------------------------------
-TAG_1 = '''
-
-
-
-
-'''
+TAG_1 = '''
+
+ '''
-TAG_2 = '''
-
-
-
-
-
-
-
+TAG_2 = (
+ '''
+
+
+ gramps-tag
+ win.TagButton
+ '''
+ '''Tag selected rows
+ Tag
+
+
+ False
+
+
-
-
-'''
+ ''')
TAG_3 = '''
-
-'''
+ '''
+
+TAG_MENU = (
+ '''
+ -
+ win.NewTag
+ '''
+ '''New Tag...
+
+ -
+ win.OrganizeTags
+ '''
+ '''Organize Tags...
+
+
+
+ ''')
WIKI_HELP_PAGE = '%s_-_Filters' % \
URL_MANUAL_PAGE
@@ -119,13 +144,14 @@ class Tags(DbGUIElement):
self._build_tag_menu()
- def tag_enable(self):
+ def tag_enable(self, update_menu=True):
"""
Enables the UI and action groups for the tag menu.
"""
- self.uistate.uimanager.insert_action_group(self.tag_action, 1)
+ self.uistate.uimanager.insert_action_group(self.tag_action)
self.tag_id = self.uistate.uimanager.add_ui_from_string(self.tag_ui)
- self.uistate.uimanager.ensure_update()
+ if update_menu:
+ self.uistate.uimanager.update_menu()
def tag_disable(self):
"""
@@ -134,7 +160,6 @@ class Tags(DbGUIElement):
if self.tag_id is not None:
self.uistate.uimanager.remove_ui(self.tag_id)
self.uistate.uimanager.remove_action_group(self.tag_action)
- self.uistate.uimanager.ensure_update()
self.tag_id = None
def _db_changed(self, db):
@@ -209,46 +234,55 @@ class Tags(DbGUIElement):
actions = []
if not self.dbstate.is_open():
- self.tag_ui = ''
+ self.tag_ui = ['']
self.tag_action = ActionGroup(name='Tag')
return
- tag_menu = ''
- tag_menu += ''
- tag_menu += ''
+ tag_menu = ''
+ menuitem = '''
+ -
+ win.TAG_%s
+ %s
+
'''
+
for tag_name, handle in self.__tag_list:
- tag_menu += '' % handle
- actions.append(('TAG_%s' % handle, None, tag_name, None, None,
- make_callback(self.tag_selected_rows, handle)))
+ tag_menu += menuitem % (handle, tag_name)
+ actions.append(('TAG_%s' % handle,
+ make_callback(self.tag_selected_rows, handle)))
+ tag_menu = TAG_MENU % tag_menu
- self.tag_ui = TAG_1 + tag_menu + TAG_2 + tag_menu + TAG_3
+ self.tag_ui = [TAG_1 % tag_menu, TAG_2, TAG_3 % tag_menu]
- actions.append(('Tag', 'gramps-tag', _('Tag'), None, None, None))
- actions.append(('NewTag', 'gramps-tag-new', _('New Tag...'), None, None,
- self.cb_new_tag))
- actions.append(('OrganizeTags', None, _('Organize Tags...'), None, None,
- self.cb_organize_tags))
- actions.append(('TagButton', 'gramps-tag', _('Tag'), None,
- _('Tag selected rows'), self.cb_tag_button))
+ actions.append(('NewTag', self.cb_new_tag))
+ actions.append(('OrganizeTags', self.cb_organize_tags))
+ actions.append(('TagButton', self.cb_tag_button))
self.tag_action = ActionGroup(name='Tag')
self.tag_action.add_actions(actions)
- def cb_tag_button(self, action):
+ def cb_tag_button(self, *args):
"""
Display the popup menu when the toolbar button is clicked.
"""
- menu = self.uistate.uimanager.get_widget('/TagPopup')
- button = self.uistate.uimanager.get_widget('/ToolBar/TagTool/TagButton')
- menu.popup(None, None, cb_menu_position, button, 0, 0)
+ menu = self.uistate.uimanager.get_widget('TagPopup')
+ button = self.uistate.uimanager.get_widget('TagButton')
+ popup_menu = Gtk.Menu.new_from_model(menu)
+ popup_menu.attach_to_widget(button, None)
+ popup_menu.show_all()
+ if Gtk.MINOR_VERSION < 22:
+ # ToDo The following is reported to work poorly with Wayland
+ popup_menu.popup(None, None, cb_menu_position, button, 0, 0)
+ else:
+ popup_menu.popup_at_widget(button, Gdk.Gravity.SOUTH,
+ Gdk.Gravity.NORTH_WEST, None)
- def cb_organize_tags(self, action):
+ def cb_organize_tags(self, *action):
"""
Display the Organize Tags dialog.
"""
OrganizeTagsDialog(self.db, self.uistate, [])
- def cb_new_tag(self, action):
+ def cb_new_tag(self, *action):
"""
Create a new tag and tag the selected objects.
"""
@@ -304,7 +338,7 @@ def make_callback(func, tag_handle):
"""
Generates a callback function based off the passed arguments
"""
- return lambda x: func(tag_handle)
+ return lambda x, y: func(tag_handle)
#-------------------------------------------------------------------------
#
diff --git a/gramps/gui/widgets/__init__.py b/gramps/gui/widgets/__init__.py
index 71489981f..b12eec59b 100644
--- a/gramps/gui/widgets/__init__.py
+++ b/gramps/gui/widgets/__init__.py
@@ -34,16 +34,12 @@ from .monitoredwidgets import *
from .selectionwidget import SelectionWidget, Region
from .shadebox import *
from .shortlistcomboentry import *
-from .springseparator import *
from .statusbar import Statusbar
from .styledtextbuffer import *
from .styledtexteditor import *
-from .toolcomboentry import *
from .undoablebuffer import *
from .undoableentry import *
from .undoablestyledbuffer import *
from .validatedcomboentry import *
from .validatedmaskedentry import *
-from .valueaction import *
-from .valuetoolitem import *
from .placewithin import *
diff --git a/gramps/gui/widgets/grampletpane.py b/gramps/gui/widgets/grampletpane.py
index bc09d987f..2d3042d60 100644
--- a/gramps/gui/widgets/grampletpane.py
+++ b/gramps/gui/widgets/grampletpane.py
@@ -49,7 +49,7 @@ from gramps.gen.const import URL_MANUAL_PAGE, VERSION_DIR, COLON
from ..editors import EditPerson, EditFamily
from ..managedwindow import ManagedWindow
from ..utils import is_right_click, match_primary_mask, get_link_color
-from .menuitem import add_menuitem
+from ..uimanager import ActionGroup
from ..plug import make_gui_option
from ..plug.quick import run_quick_report_by_name
from ..display import display_help, display_url
@@ -189,6 +189,13 @@ def logical_true(value):
"""
return value in ["True", True, 1, "1"]
+def make_callback(func, arg):
+ """
+ Generates a callback function based off the passed arguments
+ """
+ return lambda x, y: func(arg)
+
+
class LinkTag(Gtk.TextTag):
"""
Class for keeping track of link data.
@@ -999,6 +1006,8 @@ class GrampletPane(Gtk.ScrolledWindow):
self.pageview = pageview
self.pane = self
self._popup_xy = None
+ self.at_popup_action = None
+ self.at_popup_menu = None
user_gramplets = self.load_gramplets()
# build the GUI:
msg = _("Right click to add gramplets")
@@ -1349,8 +1358,7 @@ class GrampletPane(Gtk.ScrolledWindow):
self.place_gramplets(recolumn=True)
self.show()
- def restore_gramplet(self, obj):
- name = obj.get_child().get_label()
+ def restore_gramplet(self, name):
############### First kind: from current session
for gramplet in self.closed_gramplets:
if gramplet.title == name:
@@ -1392,8 +1400,7 @@ class GrampletPane(Gtk.ScrolledWindow):
else:
self.drop_widget(self, gramplet, 0, 0, 0)
- def add_gramplet(self, obj):
- tname = obj.get_child().get_label()
+ def add_gramplet(self, tname):
all_opts = get_gramplet_options_by_tname(tname)
name = all_opts["name"]
if all_opts is None:
@@ -1437,39 +1444,73 @@ class GrampletPane(Gtk.ScrolledWindow):
LOG.warning("Can't make gramplet of type '%s'.", name)
def _button_press(self, obj, event):
+ ui_def = (
+ '''
+ ''')
+ menuitem = ('- \n'
+ 'win.%s\n'
+ ''
+ '%s\n'
+ '
\n')
+
if is_right_click(event):
self._popup_xy = (event.x, event.y)
uiman = self.uistate.uimanager
- ag_menu = uiman.get_widget('/GrampletPopup/AddGramplet')
- if ag_menu:
- qr_menu = ag_menu.get_submenu()
- qr_menu = Gtk.Menu()
- names = [gplug.name for gplug in PLUGMAN.get_reg_gramplets()
- if gplug.navtypes == []
- or 'Dashboard' in gplug.navtypes]
- names.sort()
+ actions = []
+ r_menuitems = ''
+ a_menuitems = ''
+ names = [gplug.name for gplug in PLUGMAN.get_reg_gramplets()
+ if gplug.navtypes == []
+ or 'Dashboard' in gplug.navtypes]
+ names.sort()
+ for name in names:
+ action_name = name.replace(' ', '-')
+ a_menuitems += menuitem % (action_name, name)
+ actions.append((action_name,
+ make_callback(self.add_gramplet, name)))
+ names = [gramplet.title for gramplet in self.closed_gramplets]
+ names.extend(opts["title"] for opts in self.closed_opts)
+ names.sort()
+ if len(names) > 0:
for name in names:
- add_menuitem(qr_menu, name, None,
- self.add_gramplet)
- ag_menu.set_submenu(qr_menu)
- rg_menu = uiman.get_widget('/GrampletPopup/RestoreGramplet')
- if rg_menu:
- qr_menu = rg_menu.get_submenu()
- if qr_menu is not None:
- rg_menu.set_submenu(None)
- names = [gramplet.title for gramplet in self.closed_gramplets]
- names.extend(opts["title"] for opts in self.closed_opts)
- names.sort()
- if len(names) > 0:
- qr_menu = Gtk.Menu()
- for name in names:
- add_menuitem(qr_menu, name, None,
- self.restore_gramplet)
- rg_menu.set_submenu(qr_menu)
- self.menu = uiman.get_widget('/GrampletPopup')
- if self.menu:
- #GTK3 does not show the popup, workaround: menu as attribute
- self.menu.popup(None, None, None, None, event.button, event.time)
+ action_name = name.replace(' ', '-')
+ r_menuitems += menuitem % (action_name, name)
+ actions.append((action_name,
+ make_callback(self.restore_gramplet,
+ name)))
+
+ if self.at_popup_action:
+ uiman.remove_ui(self.at_popup_menu)
+ uiman.remove_action_group(self.at_popup_action)
+ self.at_popup_action = ActionGroup('AtPopupActions',
+ actions)
+ uiman.insert_action_group(self.at_popup_action)
+ self.at_popup_menu = uiman.add_ui_from_string([
+ ui_def % (a_menuitems, r_menuitems)])
+ uiman.update_menu()
+
+ menu = uiman.get_widget('Popup')
+ popup_menu = Gtk.Menu.new_from_model(menu)
+ popup_menu.attach_to_widget(obj, None)
+ popup_menu.show_all()
+ if Gtk.MINOR_VERSION < 22:
+ # ToDo The following is reported to work poorly with Wayland
+ popup_menu.popup(None, None, None, None,
+ event.button, event.time)
+ else:
+ popup_menu.popup_at_pointer(event)
return True
return False
diff --git a/gramps/gui/widgets/shortlistcomboentry.py b/gramps/gui/widgets/shortlistcomboentry.py
index 48411e0cb..a4766a8ec 100644
--- a/gramps/gui/widgets/shortlistcomboentry.py
+++ b/gramps/gui/widgets/shortlistcomboentry.py
@@ -70,7 +70,10 @@ class ShortlistComboEntry(ValidatedComboEntry):
"""
__gtype_name__ = "ShortlistComboEntry"
- def __init__(self, items, shortlist=True, validator=None):
+ def __init__(self):
+ pass
+
+ def init(self, items, shortlist=True, validator=None):
if not items:
raise ValueError
diff --git a/gramps/gui/widgets/springseparator.py b/gramps/gui/widgets/springseparator.py
deleted file mode 100644
index 0504007c9..000000000
--- a/gramps/gui/widgets/springseparator.py
+++ /dev/null
@@ -1,76 +0,0 @@
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2008 Zsolt Foldvari
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-
-"Separator classes used for Toolbar."
-
-__all__ = ["SpringSeparatorAction", "SpringSeparatorToolItem"]
-
-#-------------------------------------------------------------------------
-#
-# Python modules
-#
-#-------------------------------------------------------------------------
-import logging
-_LOG = logging.getLogger(".widgets.springseparator")
-
-#-------------------------------------------------------------------------
-#
-# GTK modules
-#
-#-------------------------------------------------------------------------
-from gi.repository import Gtk
-
-#-------------------------------------------------------------------------
-#
-# SpringSeparatorToolItem class
-#
-#-------------------------------------------------------------------------
-class SpringSeparatorToolItem(Gtk.SeparatorToolItem):
- """Custom separator toolitem.
-
- Its only purpose is to push following tool items to the right end
- of the toolbar.
-
- """
- __gtype_name__ = "SpringSeparatorToolItem"
-
- def __init__(self):
- Gtk.SeparatorToolItem.__init__(self)
-
- self.set_draw(False)
- self.set_expand(True)
-
-#-------------------------------------------------------------------------
-#
-# SpringSeparatorAction class
-#
-#-------------------------------------------------------------------------
-class SpringSeparatorAction(Gtk.Action):
- """Custom Action to hold a SpringSeparatorToolItem."""
-
- __gtype_name__ = "SpringSeparatorAction"
-
- def __init__(self, name, label, tooltip, stock_id):
- Gtk.Action.__init__(self, name=name, label=label,
- tooltip=tooltip, stock_id=stock_id)
-
-## TODO GTK3, How to connect these? Used in styledtexteditor
-##SpringSeparatorToolItem.set_related_action(SpringSeparatorAction)
-##deprecated: SpringSeparatorAction.set_tool_item_type(SpringSeparatorToolItem)
diff --git a/gramps/gui/widgets/styledtexteditor.py b/gramps/gui/widgets/styledtexteditor.py
index 4b8460659..9502184cf 100644
--- a/gramps/gui/widgets/styledtexteditor.py
+++ b/gramps/gui/widgets/styledtexteditor.py
@@ -43,6 +43,8 @@ from gi.repository import GObject
from gi.repository import Gdk
from gi.repository import Gtk
from gi.repository import Pango
+from gi.repository.Gio import SimpleActionGroup
+from gi.repository.GLib import Variant
#-------------------------------------------------------------------------
#
@@ -55,15 +57,12 @@ from .styledtextbuffer import (ALLOWED_STYLES,
MATCH_FLAVOR, MATCH_STRING,
LinkTag)
from .undoablestyledbuffer import UndoableStyledBuffer
-from .valueaction import ValueAction
-from .toolcomboentry import ToolComboEntry
-from .springseparator import SpringSeparatorAction
from ..spell import Spell
from ..display import display_url
from ..utils import SystemFonts, match_primary_mask, get_link_color
from gramps.gen.config import config
from gramps.gen.constfunc import has_display, mac
-from ..actiongroup import ActionGroup
+from ..uimanager import ActionGroup
#-------------------------------------------------------------------------
#
@@ -75,33 +74,141 @@ if has_display():
HAND_CURSOR = Gdk.Cursor.new_for_display(display, Gdk.CursorType.HAND2)
REGULAR_CURSOR = Gdk.Cursor.new_for_display(display, Gdk.CursorType.XTERM)
-FORMAT_TOOLBAR = '''
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-''' % (StyledTextTagType.ITALIC,
- StyledTextTagType.BOLD,
- StyledTextTagType.UNDERLINE,
- StyledTextTagType.FONTFACE,
- StyledTextTagType.FONTSIZE,
- StyledTextTagType.FONTCOLOR,
- StyledTextTagType.HIGHLIGHT,
- StyledTextTagType.LINK,
- )
-
+FORMAT_TOOLBAR = (
+ '''
+
+
+ True
+ GTK_TOOLBAR_ICONS
+
+
+
+ format-text-italic
+ ste.ITALIC
+ Italic
+
+
+ False
+
+
+
+
+ format-text-bold
+ ste.BOLD
+ Bold
+
+
+ False
+
+
+
+
+ format-text-underline
+ ste.UNDERLINE
+ Underline
+
+
+ False
+
+
+
+
+ Font family
+
+
+
+
+
+
+
+ Font size
+
+
+
+
+
+
+
+ edit-undo
+ ste.STUndo
+ Undo
+ Undo
+
+
+ False
+
+
+
+
+ edit-redo
+ ste.STRedo
+ Redo
+ Redo
+
+
+ False
+
+
+
+
+ gramps-font-color
+ ste.FONTCOLOR
+ Font Color
+ Font Color
+
+
+ False
+
+
+
+
+ gramps-font-bgcolor
+ ste.HIGHLIGHT
+ '''
+ '''Background Color
+ Background Color
+
+
+ False
+
+
+
+
+ go-jump
+ ste.LINK
+ Link
+ Link
+
+
+ False
+
+
+
+
+ False
+ True
+
+
+ True
+
+
+
+
+ edit-clear
+ ste.CLEAR
+ '''
+ '''Clear Markup
+ Clear Markup
+
+
+ False
+
+
+
+
+''')
FONT_SIZES = [8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 22,
24, 26, 28, 32, 36, 40, 48, 56, 64, 72]
@@ -182,6 +289,7 @@ class StyledTextEditor(Gtk.TextView):
self.undo_disabled = self.textbuffer.undo_disabled # see bug 7097
self.textbuffer.connect('style-changed', self._on_buffer_style_changed)
self.textbuffer.connect('changed', self._on_buffer_changed)
+ self.undo_action = self.redo_action = None
Gtk.TextView.__init__(self)
self.set_buffer(self.textbuffer)
@@ -194,9 +302,9 @@ class StyledTextEditor(Gtk.TextView):
self._init_url_match()
self.url_match = None
- self.toolbar = self._create_toolbar()
self.spellcheck = Spell(self)
self._internal_style_change = False
+ self.uimanager = None
self._connect_signals()
@@ -236,30 +344,6 @@ class StyledTextEditor(Gtk.TextView):
window.set_cursor(REGULAR_CURSOR)
self.url_match = None
- def on_key_press_event(self, widget, event):
- """Signal handler.
-
- Handle formatting shortcuts.
-
- """
- if ((Gdk.keyval_name(event.keyval) == 'Z') and
- match_primary_mask(event.get_state(), Gdk.ModifierType.SHIFT_MASK)):
- self.redo()
- return True
- elif ((Gdk.keyval_name(event.keyval) == 'z') and
- match_primary_mask(event.get_state())):
- self.undo()
- return True
- else:
- for accel, accel_name in self.action_accels.items():
- key, mod = Gtk.accelerator_parse(accel)
- if ((event.keyval == key) and (event.get_state() & mod)):
- action_name = accel_name
- action = self.action_group.get_action(action_name)
- action.activate()
- return True
- return False
-
def on_insert_at_cursor(self, widget, string):
"""Signal handler. for debugging only."""
_LOG.debug("Textview insert '%s'" % string)
@@ -423,14 +507,13 @@ class StyledTextEditor(Gtk.TextView):
Reset the undoable buffer
"""
self.textbuffer.reset()
- self.undo_action.set_sensitive(False)
- self.redo_action.set_sensitive(False)
+ self.undo_action.set_enabled(False)
+ self.redo_action.set_enabled(False)
# private methods
def _connect_signals(self):
"""Connect to several signals of the super class Gtk.TextView."""
- self.connect('key-press-event', self.on_key_press_event)
self.connect('insert-at-cursor', self.on_insert_at_cursor)
self.connect('delete-from-cursor', self.on_delete_from_cursor)
self.connect('paste-clipboard', self.on_paste_clipboard)
@@ -439,104 +522,74 @@ class StyledTextEditor(Gtk.TextView):
self.connect('button-release-event', self.on_button_release_event)
self.connect('populate-popup', self.on_populate_popup)
- def _create_toolbar(self):
+ def create_toolbar(self, uimanager, window):
"""
Create a formatting toolbar.
:returns: toolbar containing text formatting toolitems.
:rtype: Gtk.Toolbar
"""
+ self.uimanager = uimanager
+ # build the toolbar
+ builder = Gtk.Builder.new_from_string(FORMAT_TOOLBAR, -1)
# define the actions...
- # ...first the toggle actions, which have a ToggleToolButton as proxy
- format_toggle_actions = [
- (str(StyledTextTagType.ITALIC), 'format-text-italic', None, None,
- _('Italic'), self._on_toggle_action_activate),
- (str(StyledTextTagType.BOLD), 'format-text-bold', None, None,
- _('Bold'), self._on_toggle_action_activate),
- (str(StyledTextTagType.UNDERLINE), 'format-text-underline', None,
- None, _('Underline'), self._on_toggle_action_activate),
+ _actions = [
+ ('ITALIC', self._on_toggle_action_activate, 'i', False),
+ ('BOLD', self._on_toggle_action_activate, 'b', False),
+ ('UNDERLINE', self._on_toggle_action_activate, 'u',
+ False),
+ ('FONTCOLOR', self._on_action_activate),
+ ('HIGHLIGHT', self._on_action_activate),
+ ('LINK', self._on_link_activate),
+ ('CLEAR', self._format_clear_cb),
+ ('STUndo', self.undo, 'z'),
+ ('STRedo', self.redo, 'z'),
]
- self.toggle_actions = [action[0] for action in format_toggle_actions]
-
- # ...then the normal actions, which have a ToolButton as proxy
- format_actions = [
- (str(StyledTextTagType.FONTCOLOR), 'gramps-font-color',
- _('Font Color'), None, _('Font Color'), self._on_action_activate),
- (str(StyledTextTagType.HIGHLIGHT), 'gramps-font-bgcolor',
- _('Background Color'), None, _('Background Color'),
- self._on_action_activate),
- (str(StyledTextTagType.LINK), 'go-jump', _('Link'), None,
- _('Link'), self._on_link_activate),
- ('clear', 'edit-clear', _('Clear Markup'), None,
- _('Clear Markup'), self._format_clear_cb),
- ]
-
- # ...last the custom actions, which have custom proxies
- default = StyledTextTagType.STYLE_DEFAULT[StyledTextTagType.FONTFACE]
+ # the following are done manually rather than using actions
fonts = SystemFonts()
- fontface_action = ValueAction(str(StyledTextTagType.FONTFACE),
- _("Font family"),
- default,
- ToolComboEntry,
- fonts.get_system_fonts(),
- False, #editable
- True, #shortlist
- None) # validator
- fontface_action.connect('changed', self._on_valueaction_changed)
+ fontface = builder.get_object('Fontface')
+ fontface.init(fonts.get_system_fonts(), shortlist=True, validator=None)
+ fontface.set_entry_editable(False)
+ fontface.connect('changed', make_cb(
+ self._on_valueaction_changed, StyledTextTagType.FONTFACE))
+ # set initial value
+ default = StyledTextTagType.STYLE_DEFAULT[StyledTextTagType.FONTFACE]
+ self.fontface = fontface.get_child()
+ self.fontface.set_text(str(default))
+ fontface.show()
items = FONT_SIZES
+ fontsize = builder.get_object('Fontsize')
+ fontsize.init(items, shortlist=False, validator=is_valid_fontsize)
+ fontsize.set_entry_editable(True)
+ fontsize.connect('changed', make_cb(
+ self._on_valueaction_changed, StyledTextTagType.FONTSIZE))
+ # set initial value
default = StyledTextTagType.STYLE_DEFAULT[StyledTextTagType.FONTSIZE]
- fontsize_action = ValueAction(str(StyledTextTagType.FONTSIZE),
- _("Font size"),
- default,
- ToolComboEntry,
- items,
- True, #editable
- False, #shortlist
- is_valid_fontsize) #validator
- fontsize_action.connect('changed', self._on_valueaction_changed)
-
- spring = SpringSeparatorAction("spring", "", "", None)
-
- # action accelerators
- self.action_accels = {
- 'i': str(StyledTextTagType.ITALIC),
- 'b': str(StyledTextTagType.BOLD),
- 'u': str(StyledTextTagType.UNDERLINE),
- }
+ self.fontsize = fontsize.get_child()
+ self.fontsize.set_text(str(default))
+ fontsize.show()
# create the action group and insert all the actions
- self.action_group = ActionGroup(name='Format')
- self.action_group.add_toggle_actions(format_toggle_actions)
- self.undo_action = Gtk.Action(name="Undo", label=_('Undo'),
- tooltip=_('Undo'))
- self.undo_action.set_icon_name('edit-undo')
- self.undo_action.connect('activate', self.undo)
- self.redo_action = Gtk.Action.new(name="Redo", label=_('Redo'),
- tooltip=_('Redo'))
- self.redo_action.set_icon_name('edit-redo')
- self.redo_action.connect('activate', self.redo)
- self.action_group.add_action(self.undo_action)
- self.action_group.add_action(self.redo_action)
- self.action_group.add_actions(format_actions)
- self.action_group.add_action(fontface_action)
- self.action_group.add_action(fontsize_action)
- self.action_group.add_action(spring)
+ self.action_group = ActionGroup('Format', _actions, 'ste')
+ act_grp = SimpleActionGroup()
+ window.insert_action_group('ste', act_grp)
+ window.set_application(uimanager.app)
+ uimanager.insert_action_group(self.action_group, act_grp)
- # define the toolbar and create the proxies via ensure_update()
- uimanager = Gtk.UIManager()
- uimanager.insert_action_group(self.action_group, 0)
- uimanager.add_ui_from_string(FORMAT_TOOLBAR)
- uimanager.ensure_update()
+ self.undo_action = uimanager.get_action(self.action_group, "STUndo")
+ self.redo_action = uimanager.get_action(self.action_group, "STRedo")
+ # allow undo/redo to see actions if editable.
+ self.textbuffer.connect('changed', self._on_buffer_changed)
+ # undo/redo are initially greyed out, until something is changed
+ self.undo_action.set_enabled(False)
+ self.redo_action.set_enabled(False)
# get the toolbar and set it's style
- toolbar = uimanager.get_widget('/ToolBar')
- toolbar.set_style(Gtk.ToolbarStyle.ICONS)
- self.undo_action.set_sensitive(False)
- self.redo_action.set_sensitive(False)
+ toolbar = builder.get_object('ToolBar')
- return toolbar
+ return toolbar, self.action_group
def set_transient_parent(self, parent=None):
self.transient_parent = parent
@@ -582,21 +635,22 @@ class StyledTextEditor(Gtk.TextView):
# Callback functions
- def _on_toggle_action_activate(self, action):
+ def _on_toggle_action_activate(self, action, value):
"""
Toggle a style.
Toggle styles are e.g. 'bold', 'italic', 'underline'.
"""
+ action.set_state(value)
if self._internal_style_change:
return
- style = int(action.get_name())
- value = action.get_active()
- _LOG.debug("applying style '%d' with value '%s'" % (style, str(value)))
- self.textbuffer.apply_style(style, value)
+ style = action.get_name()
+ value = value.get_boolean()
+ _LOG.debug("applying style '%s' with value '%s'" % (style, str(value)))
+ self.textbuffer.apply_style(getattr(StyledTextTagType, style), value)
- def _on_link_activate(self, action):
+ def _on_link_activate(self, action, value):
"""
Create a link of a selected region of text.
"""
@@ -633,10 +687,9 @@ class StyledTextEditor(Gtk.TextView):
else:
tag.data = uri
-
- def _on_action_activate(self, action):
+ def _on_action_activate(self, action, value):
"""Apply a format set from a Gtk.Action type of action."""
- style = int(action.get_name())
+ style = getattr(StyledTextTagType, action.get_name())
current_value = self.textbuffer.get_style_at_cursor(style)
if style == StyledTextTagType.FONTCOLOR:
@@ -668,14 +721,12 @@ class StyledTextEditor(Gtk.TextView):
(style, str(value)))
self.textbuffer.apply_style(style, value)
- def _on_valueaction_changed(self, action):
- """Apply a format set by a ValueAction type of action."""
+ def _on_valueaction_changed(self, obj, style):
+ """Apply a format set by a ShortListComboEntry."""
if self._internal_style_change:
return
- style = int(action.get_name())
-
- value = action.get_value()
+ value = obj.get_active_data()
try:
value = StyledTextTagType.STYLE_TYPE[style](value)
_LOG.debug("applying style '%d' with value '%s'" %
@@ -685,7 +736,7 @@ class StyledTextEditor(Gtk.TextView):
_LOG.debug("unable to convert '%s' to '%s'" %
(value, StyledTextTagType.STYLE_TYPE[style]))
- def _format_clear_cb(self, action):
+ def _format_clear_cb(self, action, value):
"""
Remove all formats from the selection or from all.
@@ -709,24 +760,27 @@ class StyledTextEditor(Gtk.TextView):
def _on_buffer_changed(self, buffer):
"""synchronize the undo/redo buttons with what is possible"""
- self.undo_action.set_sensitive(self.textbuffer.can_undo)
- self.redo_action.set_sensitive(self.textbuffer.can_redo)
+ if self.undo_action:
+ self.undo_action.set_enabled(self.textbuffer.can_undo)
+ self.redo_action.set_enabled(self.textbuffer.can_redo)
def _on_buffer_style_changed(self, buffer, changed_styles):
"""Synchronize actions as the format changes at the buffer's cursor."""
+ if not self.uimanager:
+ return # never initialized a toolbar, not editable
+ types = [StyledTextTagType.ITALIC, StyledTextTagType.BOLD,
+ StyledTextTagType.UNDERLINE]
+ self._internal_style_change = True
for style, style_value in changed_styles.items():
- if str(style) in self.toggle_actions:
- action = self.action_group.get_action(str(style))
- self._internal_style_change = True
- action.set_active(style_value)
- self._internal_style_change = False
-
- if ((style == StyledTextTagType.FONTFACE) or
- (style == StyledTextTagType.FONTSIZE)):
- action = self.action_group.get_action(str(style))
- self._internal_style_change = True
- action.set_value(style_value)
- self._internal_style_change = False
+ if style in types:
+ action = self.uimanager.get_action(
+ self.action_group, str(StyledTextTagType(style)).upper())
+ action.change_state(Variant.new_boolean(style_value))
+ elif (style == StyledTextTagType.FONTFACE):
+ self.fontface.set_text(style_value)
+ elif style == StyledTextTagType.FONTSIZE:
+ self.fontsize.set_text(str(style_value))
+ self._internal_style_change = False
def _spell_change_cb(self, menuitem, spellcheck):
"""Set spell checker spellcheck according to user selection."""
@@ -818,20 +872,17 @@ class StyledTextEditor(Gtk.TextView):
start, end = self.textbuffer.get_bounds()
return self.textbuffer.get_text(start, end, True)
- def get_toolbar(self):
- """
- Get the formatting toolbar of the editor.
-
- :returns: toolbar widget to use as formatting GUI.
- :rtype: Gtk.Toolbar
- """
- return self.toolbar
-
- def undo(self, obj=None):
+ def undo(self, *obj):
self.textbuffer.undo()
- def redo(self, obj=None):
+ def redo(self, *obj):
self.textbuffer.redo()
+#-------------------------------------------------------------------------
+#
+# Module functions
+#
+#-------------------------------------------------------------------------
+
def uri_dialog(self, uri, callback):
"""
@@ -851,12 +902,14 @@ def uri_dialog(self, uri, callback):
uri = "gramps://%s/handle/%s" % (object_class, handle)
EditLink(obj.dbstate, obj.uistate, obj.track, uri, callback)
-#-------------------------------------------------------------------------
-#
-# Module functions
-#
-#-------------------------------------------------------------------------
def is_valid_fontsize(size):
"""Validator function for font size selector widget."""
return (size > 0) and (size < 73)
+
+
+def make_cb(func, value):
+ """
+ Generates a callback function based off the passed arguments
+ """
+ return lambda x: func(x, value)
diff --git a/gramps/gui/widgets/toolcomboentry.py b/gramps/gui/widgets/toolcomboentry.py
deleted file mode 100644
index 124c3a19d..000000000
--- a/gramps/gui/widgets/toolcomboentry.py
+++ /dev/null
@@ -1,78 +0,0 @@
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2008 Zsolt Foldvari
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-
-"ToolComboEntry class."
-
-__all__ = ["ToolComboEntry"]
-
-#-------------------------------------------------------------------------
-#
-# Python modules
-#
-#-------------------------------------------------------------------------
-import logging
-_LOG = logging.getLogger(".widgets.toolcomboentry")
-
-#-------------------------------------------------------------------------
-#
-# GTK modules
-#
-#-------------------------------------------------------------------------
-#from gi.repository import GObject
-from gi.repository import Gtk
-
-#-------------------------------------------------------------------------
-#
-# Gramps modules
-#
-#-------------------------------------------------------------------------
-from .valuetoolitem import ValueToolItem
-from .shortlistcomboentry import ShortlistComboEntry
-
-#-------------------------------------------------------------------------
-#
-# ToolComboEntry class
-#
-#-------------------------------------------------------------------------
-class ToolComboEntry(ValueToolItem):
- """Tool bar item containing a ShortlistComboEntry widget."""
- __gtype_name__ = "ToolComboEntry"
-
- def _create_widget(self, items, editable, shortlist=True, validator=None):
- self.set_border_width(2)
- self.set_homogeneous(False)
- self.set_expand(False)
-
- combo = ShortlistComboEntry(items, shortlist, validator)
- if (Gtk.MAJOR_VERSION, Gtk.MINOR_VERSION) < (3, 20):
- combo.set_focus_on_click(False)
- else:
- Gtk.Widget.set_focus_on_click(combo, False)
- combo.set_entry_editable(editable)
- combo.show()
- self.add(combo)
-
- combo.connect('changed', self._on_widget_changed)
-
- def set_value(self, value):
- self.get_child().set_active_data(value)
-
- def get_value(self):
- return self.get_child().get_active_data()
diff --git a/gramps/gui/widgets/validatedcomboentry.py b/gramps/gui/widgets/validatedcomboentry.py
index 17a535ae6..e2520251a 100644
--- a/gramps/gui/widgets/validatedcomboentry.py
+++ b/gramps/gui/widgets/validatedcomboentry.py
@@ -65,7 +65,8 @@ class ValidatedComboEntry(Gtk.ComboBox):
__gtype_name__ = "ValidatedComboEntry"
def __init__(self, datatype, model=None, column=-1, validator=None, width=-1):
- Gtk.ComboBox.__init__(self, model=model)
+ Gtk.ComboBox.__init__(self)
+ self.set_model(model)
self._entry = Gtk.Entry()
self._entry.set_width_chars(width)
@@ -201,6 +202,9 @@ class ValidatedComboEntry(Gtk.ComboBox):
self._internal_change = True
new_iter = self._is_in_model(new_data)
if new_iter is None:
+ if self.get_active_iter() is None:
+ # allows response when changing between two non-model values
+ self.set_active(0)
self.set_active(-1)
else:
self.set_active_iter(new_iter)
diff --git a/gramps/gui/widgets/valueaction.py b/gramps/gui/widgets/valueaction.py
deleted file mode 100644
index 68e629252..000000000
--- a/gramps/gui/widgets/valueaction.py
+++ /dev/null
@@ -1,169 +0,0 @@
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2008 Zsolt Foldvari
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-
-"ValueAction class."
-
-__all__ = ["ValueAction"]
-
-#-------------------------------------------------------------------------
-#
-# Python modules
-#
-#-------------------------------------------------------------------------
-import logging
-_LOG = logging.getLogger(".widgets.valueaction")
-
-#-------------------------------------------------------------------------
-#
-# GTK modules
-#
-#-------------------------------------------------------------------------
-from gi.repository import GObject
-from gi.repository import Gtk
-
-#-------------------------------------------------------------------------
-#
-# Gramps modules
-#
-#-------------------------------------------------------------------------
-from .valuetoolitem import ValueToolItem
-
-#-------------------------------------------------------------------------
-#
-# ValueAction class
-#
-#-------------------------------------------------------------------------
-class ValueAction(Gtk.Action):
- """
- Value action class.
-
- (A ValueAction with menu item doesn't make any sense.)
- """
- __gtype_name__ = "ValueAction"
-
- __gsignals__ = {
- 'changed': (GObject.SignalFlags.RUN_FIRST,
- None, #return value
- ()), # arguments
- }
-
- def __init__(self, name, tooltip, default, itemtype, *args):
- """
- Create a new ValueAction instance.
-
- :param name: the name of the action
- :type name: str
- :param tooltip: tooltip string
- :type tooltip: str
- :param default: default value for the action, it will set the type of
- the action and thus the type of all the connected
- proxies.
- :type default: set by itemtype
- :param itemtype: default tool item class
- :type itemtype: :class:`.ValueToolItem` subclass
- :param args: arguments to be passed to the default toolitem class
- at creation. see: :meth:`do_create_tool_item`
- :type args: list
- """
- Gtk.Action.__init__(self, name=name, label='', tooltip=tooltip,
- stock_id=None)
-
- self._value = default
- self._data_type = type(default)
-
- # have to be remembered, because we can't access
- # GtkAction->toolbar_item_type later.
- self._default_toolitem_type = itemtype
-##TODO GTK3: following is deprecated, must be replaced by
-## itemtype.set_related_action(ValueAction) in calling class?
-## self.set_tool_item_type(itemtype)
- self._args_for_toolitem = args
-
- self._handlers = {}
-
- def do_changed(self):
- """
- Default signal handler for 'changed' signal.
-
- Synchronize all the proxies with the active value.
- """
- for proxy in self.get_proxies():
- proxy.handler_block(self._handlers[proxy])
- proxy.set_value(self._value)
- proxy.handler_unblock(self._handlers[proxy])
-
- def do_create_tool_item(self):
- """
- Create a 'default' toolbar item widget.
-
- Override the default method, to be able to pass the required
- parameters to the proxy's constructor.
-
- This method is called from Gtk.UIManager.ensure_update(), when a
- 'toolitem' is found in the UI definition with a name refering to a
- ValueAction. Thus, to use the action via the UIManager a 'default'
- toolitem type has to be set with the Gtk.Action.set_tool_item_type()
- method, before invoking the Gtk.UIManager.ensure_update() method.
-
- Widgets other than the default type has to be created and added
- manually with the Gtk.Action.connect_proxy() method.
-
- :returns: a toolbar item connected to the action.
- :rtype: :class:`.ValueToolItem` subclass
- """
- proxy = self._default_toolitem_type(self._data_type,
- self._args_for_toolitem)
- self.connect_proxy(proxy)
- return proxy
-
- def _on_proxy_changed(self, proxy):
- """Signal handler for the proxies' 'changed' signal."""
- value = proxy.get_value()
- if value is not None:
- self.set_value(value)
-
- def connect_proxy(self, proxy):
- """
- Connect a widget to an action object as a proxy.
-
- :param proxy: widget to be connected
- :type proxy: :class:`.ValueToolItem` subclass
- """
- if not isinstance(proxy, ValueToolItem):
- raise TypeError
-
- # do this before connecting, so that we don't call the handler
- proxy.set_value(self._value)
- self._handlers[proxy] = proxy.connect('changed', self._on_proxy_changed)
-
- # if this is called the proxy will appear on the proxy list twice. why?
- #Gtk.Action.connect_proxy(self, proxy)
-
- def set_value(self, value):
- """Set value to action."""
- if not isinstance(value, self._data_type):
- raise TypeError
-
- self._value = value
- self.emit('changed')
-
- def get_value(self):
- """Get the value from the action."""
- return self._value
diff --git a/gramps/gui/widgets/valuetoolitem.py b/gramps/gui/widgets/valuetoolitem.py
deleted file mode 100644
index 0c8d355b0..000000000
--- a/gramps/gui/widgets/valuetoolitem.py
+++ /dev/null
@@ -1,92 +0,0 @@
-#
-# Gramps - a GTK+/GNOME based genealogy program
-#
-# Copyright (C) 2008 Zsolt Foldvari
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-
-"ValueToolItem class."
-
-__all__ = ["ValueToolItem"]
-
-#-------------------------------------------------------------------------
-#
-# Python modules
-#
-#-------------------------------------------------------------------------
-import logging
-_LOG = logging.getLogger(".widgets.valuetoolitem")
-
-#-------------------------------------------------------------------------
-#
-# GTK modules
-#
-#-------------------------------------------------------------------------
-from gi.repository import GObject
-from gi.repository import Gtk
-
-
-#-------------------------------------------------------------------------
-#
-# ValueToolItem class
-#
-#-------------------------------------------------------------------------
-class ValueToolItem(Gtk.ToolItem):
- """ValueToolItem is an abstract toolbar proxy for ValueAction.
-
- For each kind of widget a separete tool item proxy has to be
- subclassed from this ValueToolItem.
-
- """
- __gtype_name__ = "ValueToolItem"
-
- __gsignals__ = {
- 'changed': (GObject.SignalFlags.RUN_FIRST,
- None, #return value
- ()), # arguments
- }
-
- def __init__(self, data_type, args):
- Gtk.ToolItem.__init__(self)
-
- self._data_type = data_type
-
- self._create_widget(*args)
-
- def _on_widget_changed(self, widget):
- self.emit('changed')
-
- def _create_widget(self, args):
- """Create the apropriate widget for the actual proxy."""
- raise NotImplementedError
-
- def set_value(self, value):
- """Set new value for the proxied widget.
-
- The method is responsible converting the data type between action and
- widget.
-
- """
- raise NotImplementedError
-
- def get_value(self):
- """Get value from the proxied widget.
-
- The method is responsible converting the data type between action and
- widget.
-
- """
- raise NotImplementedError
diff --git a/gramps/plugins/lib/libpersonview.py b/gramps/plugins/lib/libpersonview.py
index 58579f90a..4a91dccc8 100644
--- a/gramps/plugins/lib/libpersonview.py
+++ b/gramps/plugins/lib/libpersonview.py
@@ -48,7 +48,7 @@ _LOG = logging.getLogger(".gui.personview")
from gramps.gen.lib import Person, Surname
from gramps.gen.db import DbTxn
from gramps.gui.views.listview import ListView, TEXT, MARKUP, ICON
-from gramps.gui.actiongroup import ActionGroup
+from gramps.gui.uimanager import ActionGroup
from gramps.gen.utils.string import data_recover_msg
from gramps.gen.display.name import displayer as name_displayer
from gramps.gui.dialog import ErrorDialog, MultiSelectDialog, QuestionDialog
@@ -152,15 +152,10 @@ class BasePersonView(ListView):
multiple=True,
filter_class=PersonSidebarFilter)
- self.func_list.update({
- 'J' : self.jump,
- 'BackSpace' : self.key_delete,
- })
-
uistate.connect('nameformat-changed', self.build_tree)
uistate.connect('placeformat-changed', self.build_tree)
- self.additional_uis.append(self.additional_ui())
+ self.additional_uis.append(self.additional_ui)
def navigation_type(self):
"""
@@ -187,70 +182,226 @@ class BasePersonView(ListView):
"""
return 'gramps-person'
- def additional_ui(self):
- """
- Defines the UI string for UIManager
- """
- return '''
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- '''
+ additional_ui = [ # Defines the UI string for UIManager
+ '''
+
+ -
+ win.ExportTab
+ Export View...
+
+
+''',
+ '''
+
+ -
+ win.AddBook
+ _Add Bookmark
+
+ -
+ win.EditBook
+ %s...
+
+
+''' % _('Organize Bookmarks'),
+ '''
+
+
+ -
+ win.Back
+ _Back
+
+ -
+ win.Forward
+ _Forward
+
+
+
+ -
+ win.HomePerson
+ _Home
+
+
+
+''',
+ '''
+
+ -
+ win.Add
+ _Add...
+
+ -
+ win.Edit
+ %s
+
+ -
+ win.Remove
+ _Delete
+
+ -
+ win.Merge
+ _Merge...
+
+
+''' % _("action|_Edit..."), # to use sgettext()
+ '''
+
+ -
+ win.SetActive
+ '''
+ '''Set _Home Person
+
+ -
+ win.FilterEdit
+ '''
+ '''Person Filter Editor
+
+
+''', # Following are the Toolbar items
+ '''
+
+
+
+ go-previous
+ win.Back
+ '''
+ '''Go to the previous object in the history
+ _Back
+ True
+
+
+ False
+
+
+
+
+ go-next
+ win.Forward
+ '''
+ '''Go to the next object in the history
+ _Forward
+ True
+
+
+ False
+
+
+
+
+ go-home
+ win.HomePerson
+ '''
+ '''Go to the default person
+ _Home
+ True
+
+
+ False
+
+
+
+''',
+ '''
+
+
+
+ list-add
+ win.Add
+ %s
+ _Add...
+ True
+
+
+ False
+
+
+
+
+ gtk-edit
+ win.Edit
+ %s
+ Edit...
+ True
+
+
+ False
+
+
+
+
+ list-remove
+ win.Remove
+ %s
+ _Delete
+ True
+
+
+ False
+
+
+
+
+ gramps-merge
+ win.Merge
+ %s
+ _Merge...
+ True
+
+
+ False
+
+
+
+''' % (ADD_MSG, EDIT_MSG, DEL_MSG, MERGE_MSG),
+ '''
+
+ ''' % _('action|_Edit...') # to use sgettext()
+ ]
def get_handle_from_gramps_id(self, gid):
"""
@@ -262,7 +413,7 @@ class BasePersonView(ListView):
else:
return None
- def add(self, obj):
+ def add(self, *obj):
"""
Add a new person to the database.
"""
@@ -276,7 +427,7 @@ class BasePersonView(ListView):
except WindowActiveError:
pass
- def edit(self, obj):
+ def edit(self, *obj):
"""
Edit an existing person in the database.
"""
@@ -287,7 +438,7 @@ class BasePersonView(ListView):
except WindowActiveError:
pass
- def remove(self, obj):
+ def remove(self, *obj):
"""
Remove a person from the database.
"""
@@ -373,53 +524,7 @@ class BasePersonView(ListView):
ListView.define_actions(self)
- self.all_action = ActionGroup(name=self.title + "/PersonAll")
- self.edit_action = ActionGroup(name=self.title + "/PersonEdit")
-
- self.all_action.add_actions([
- ('FilterEdit', None, _('Person Filter Editor'), None, None,
- self.filter_editor),
- ('Edit', 'gtk-edit', _("action|_Edit..."),
- "Return", self.EDIT_MSG, self.edit),
- ('QuickReport', None, _("Quick View"), None, None, None),
- ('WebConnect', None, _("Web Connection"), None, None, None),
- ])
-
-
- self.edit_action.add_actions(
- [
- ('Add', 'list-add', _("_Add..."), "Insert",
- self.ADD_MSG, self.add),
- ('Remove', 'list-remove', _("_Delete"), "Delete",
- self.DEL_MSG, self.remove),
- ('Merge', 'gramps-merge', _('_Merge...'), None,
- self.MERGE_MSG, self.merge),
- ('ExportTab', None, _('Export View...'), None, None,
- self.export),
- ])
-
- self._add_action_group(self.edit_action)
- self._add_action_group(self.all_action)
-
- def enable_action_group(self, obj):
- """
- Turns on the visibility of the View's action group.
- """
- ListView.enable_action_group(self, obj)
- self.all_action.set_visible(True)
- self.edit_action.set_visible(True)
- self.edit_action.set_sensitive(not self.dbstate.db.readonly)
-
- def disable_action_group(self):
- """
- Turns off the visibility of the View's action group.
- """
- ListView.disable_action_group(self)
-
- self.all_action.set_visible(False)
- self.edit_action.set_visible(False)
-
- def merge(self, obj):
+ def merge(self, *obj):
"""
Merge the selected people.
"""
diff --git a/gramps/plugins/lib/libplaceview.py b/gramps/plugins/lib/libplaceview.py
index 21f88df22..32ec7dd00 100644
--- a/gramps/plugins/lib/libplaceview.py
+++ b/gramps/plugins/lib/libplaceview.py
@@ -39,7 +39,6 @@ from gi.repository import Gtk
#-------------------------------------------------------------------------
from gramps.gen.lib import Place
from gramps.gui.views.listview import ListView, TEXT, ICON
-from gramps.gui.widgets.menuitem import add_menuitem
from gramps.gen.errors import WindowActiveError
from gramps.gui.views.bookmarks import PlaceBookmarks
from gramps.gen.config import config
@@ -51,6 +50,7 @@ from gramps.gui.filters.sidebar import PlaceSidebarFilter
from gramps.gui.merge import MergePlace
from gramps.gen.plug import CATEGORY_QR_PLACE
from gramps.gen.utils.location import located_in
+from gramps.gui.uimanager import ActionGroup
#-------------------------------------------------------------------------
#
@@ -58,7 +58,7 @@ from gramps.gen.utils.location import located_in
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
-_ = glocale.translation.gettext
+_ = glocale.translation.sgettext
#-------------------------------------------------------------------------
@@ -117,6 +117,7 @@ class PlaceBaseView(ListView):
self.mapservice = config.get('interface.mapservice')
self.mapservicedata = {}
+ self.map_action_group = None
ListView.__init__(
self, title, pdata, dbstate, uistate,
@@ -125,42 +126,17 @@ class PlaceBaseView(ListView):
multiple=True,
filter_class=PlaceSidebarFilter)
- self.func_list.update({
- 'J' : self.jump,
- 'BackSpace' : self.key_delete,
- })
- self.maptoolbtn = None
-
uistate.connect('placeformat-changed', self.build_tree)
- self.additional_uis.append(self.additional_ui())
+ _ui = self.__create_maps_menu_actions()
+ self.additional_uis.append(_ui)
def navigation_type(self):
return 'Place'
def define_actions(self):
ListView.define_actions(self)
- self._add_toolmenu_action('MapsList', _('Loading...'),
- _("Attempt to see selected locations with a Map "
- "Service (OpenstreetMap, Google Maps, ...)"),
- self.gotomap,
- _('Select a Map Service'))
- self._add_action('GotoMap', 'go-jump',
- _('_Look up with Map Service'),
- callback=self.gotomap,
- tip=_("Attempt to see this location with a Map "
- "Service (OpenstreetMap, Google Maps, ...)"))
- self._add_action('FilterEdit', None, _('Place Filter Editor'),
- callback=self.filter_editor)
- self._add_action('QuickReport', None, _("Quick View"), None, None, None)
-
- def set_inactive(self):
- """called by viewmanager when moving away from the page
- Here we need to remove the menutoolbutton from the menu
- """
- tb = self.uistate.viewmanager.uimanager.get_widget('/ToolBar')
- tb.remove(self.maptoolbtn)
- ListView.set_inactive(self)
+ self._add_action('GotoMap', self.gotomap)
def change_page(self):
"""
@@ -173,39 +149,6 @@ class PlaceBaseView(ListView):
5. store label so it can be changed when selection changes
"""
ListView.change_page(self)
- #menutoolbutton has to be made and added in correct place on toolbar
- if not self.maptoolbtn:
- self.maptoolbtn = Gtk.MenuToolButton()
- self.maptoolbtn.set_icon_name('go-jump')
- self.maptoolbtn.connect('clicked', self.gotomap)
- self.mmenu = self.__create_maps_menu_actions()
- self.maptoolbtn.set_menu(self.mmenu)
- self.maptoolbtn.show()
- tb = self.uistate.viewmanager.uimanager.get_widget('/ToolBar')
- ind = tb.get_item_index(self.uistate.viewmanager.uimanager.get_widget(
- '/ToolBar/CommonEdit/Merge'))
- tb.insert(self.maptoolbtn, ind+1)
- widget = self.maptoolbtn
-
- if not self.mapservicedata:
- return
-
- self.mapslistlabel = []
- if not self.mapservice in self.mapservicedata:
- #stored val no longer exists, use the first key instead
- self.set_mapservice(list(self.mapservicedata.keys())[0])
-
- #store all gtk labels to be able to update label on selection change_('Loading...'),
- widget.set_menu(self.mmenu)
- widget.set_arrow_tooltip_text(_('Select a Map Service'))
- widget.set_tooltip_text(
- _("Attempt to see selected locations with a Map "
- "Service (OpenstreetMap, Google Maps, ...)"))
- lbl = Gtk.Label(label=self.mapservice_label())
- lbl.show()
- self.mapslistlabel.append(lbl)
- widget.set_label_widget(self.mapslistlabel[-1])
- widget.set_icon_name('go-jump')
if self.drag_info():
self.list.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK,
[],
@@ -222,30 +165,52 @@ class PlaceBaseView(ListView):
Function creating a menu and actions that are used as dropdown menu
from the menutoolbutton
"""
- menu = Gtk.Menu()
+ _bar = '''
+ -
+ win.MapChoice
+ %s
+ %s
+
+ '''
+ menu = ''
#select the map services to show
self.mapservicedata = {}
servlist = GuiPluginManager.get_instance().get_reg_mapservices()
- for i, pdata in enumerate(servlist):
+ for pdata in servlist:
key = pdata.id.replace(' ', '-')
- add_menuitem(menu, pdata.name, None,
- make_callback(self.set_mapservice, key))
+ menu += _bar % (key, pdata.name)
self.mapservicedata[key] = pdata
- return menu
+ if not self.mapservicedata:
+ return self.additional_ui
+ if self.mapservice not in self.mapservicedata:
+ #stored val no longer exists, use the most recent key instead
+ self.set_mapservice(None, key)
- def set_mapservice(self, mapkey):
+ self._add_toggle_action('MapChoice', self.set_mapservice, '',
+ self.mapservice)
+
+ label = self.mapservice_label()
+ _ui = self.additional_ui[:]
+ _ui.append(self.map_ui_menu % menu)
+ _ui.append(self.map_ui % label)
+ return _ui
+
+ def set_mapservice(self, action, value):
"""
change the service that runs on click of the menutoolbutton
used as callback menu on menu clicks
"""
- self.mapservice = mapkey
- for label in self.mapslistlabel:
- label.set_label(self.mapservice_label())
- label.show()
+ if action:
+ action.set_state(value)
+ self.mapservice = mapkey = value.get_string()
config.set('interface.mapservice', mapkey)
config.save()
+ _ui = self.__create_maps_menu_actions()
+ self.uimanager.add_ui_from_string(_ui)
+ self.uimanager.update_menu()
+ return False
def mapservice_label(self):
"""
@@ -253,7 +218,7 @@ class PlaceBaseView(ListView):
"""
return self.mapservicedata[self.mapservice].name
- def gotomap(self, obj):
+ def gotomap(self, *obj):
"""
Run the map service
"""
@@ -295,72 +260,245 @@ class PlaceBaseView(ListView):
def get_stock(self):
return 'gramps-place'
- def additional_ui(self):
- return '''
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- '''
+ #
+ # Defines the UI string for UIManager
+ #
+ additional_ui = [
+ '''
+
+ -
+ win.ExportTab
+ Export View...
+
+
+''',
+ '''
+
+ -
+ win.AddBook
+ _Add Bookmark
+
+ -
+ win.EditBook
+ %s...
+
+
+''' % _('Organize Bookmarks'),
+ '''
+
+
+ -
+ win.Back
+ _Back
+
+ -
+ win.Forward
+ _Forward
+
+
+
+''',
+ '''
+
+ -
+ win.Add
+ _Add...
+
+ -
+ win.Edit
+ %s
+
+ -
+ win.Remove
+ _Delete
+
+ -
+ win.Merge
+ _Merge...
+
+
+''' % _("action|_Edit..."), # to use sgettext()
+ '''
+
+ -
+ win.FilterEdit
+ '''
+ '''Place Filter Editor
+
+
+''', # Following are the Toolbar items
+ '''
+
+
+
+ go-previous
+ win.Back
+ '''
+ '''Go to the previous object in the history
+ _Back
+ True
+
+
+ False
+
+
+
+
+ go-next
+ win.Forward
+ '''
+ '''Go to the next object in the history
+ _Forward
+ True
+
+
+ False
+
+
+
+''',
+ '''
+
+
+
+ list-add
+ win.Add
+ %s
+ _Add...
+ True
+
+
+ False
+
+
+
+
+ gtk-edit
+ win.Edit
+ %s
+ Edit...
+ True
+
+
+ False
+
+
+
+
+ list-remove
+ win.Remove
+ %s
+ _Delete
+ True
+
+
+ False
+
+
+
+
+ gramps-merge
+ win.Merge
+ %s
+ _Merge...
+ True
+
+
+ False
+
+
+
+
+''' % (ADD_MSG, EDIT_MSG, DEL_MSG, MERGE_MSG),
+ '''
+
+''' % _('action|_Edit...')] # to use sgettext()
- def add(self, obj):
+ map_ui_menu = '''
+
+ '''
+
+ map_ui = (
+ '''
+
+
+ go-jump
+ win.GotoMap
+ '''
+ '''Attempt to see selected locations with a Map Service '''
+ '''(OpenstreetMap, Google Maps, ...)
+ %s
+ True
+
+
+ False
+
+
+
+
+
+
+
+
+
+
+ ''')
+
+ def add(self, *obj):
try:
EditPlace(self.dbstate, self.uistate, [], Place())
except WindowActiveError:
pass
- def remove(self, obj):
+ def remove(self, *obj):
for handle in self.selected_handles():
for link in self.dbstate.db.find_backlink_handles(handle,['Place']):
msg = _("Cannot delete place.")
@@ -390,7 +528,7 @@ class PlaceBaseView(ListView):
is_used = len(person_list) + len(family_list) + len(event_list) > 0
return (query, is_used, object)
- def edit(self, obj):
+ def edit(self, *obj):
for handle in self.selected_handles():
place = self.dbstate.db.get_place_from_handle(handle)
try:
@@ -398,7 +536,7 @@ class PlaceBaseView(ListView):
except WindowActiveError:
pass
- def merge(self, obj):
+ def merge(self, *obj):
"""
Merge the selected places.
"""
@@ -468,5 +606,6 @@ class PlaceBaseView(ListView):
"Place Notes",
"Place Backlinks"))
+
def make_callback(func, val):
- return lambda x: func(val)
+ return lambda x, y: func(val)
diff --git a/gramps/plugins/lib/maps/geography.py b/gramps/plugins/lib/maps/geography.py
index f2b625b95..3fca483cd 100644
--- a/gramps/plugins/lib/maps/geography.py
+++ b/gramps/plugins/lib/maps/geography.py
@@ -191,7 +191,7 @@ class GeoGraphyView(OsmGps, NavigationView):
self.clearmap = None
self.nbplaces = 0
- def add_bookmark(self, menu):
+ def add_bookmark(self, *menu):
"""
Add the place to the bookmark
"""
@@ -300,16 +300,7 @@ class GeoGraphyView(OsmGps, NavigationView):
another method.
"""
NavigationView.define_actions(self)
- self.define_print_actions()
-
- def define_print_actions(self):
- """
- Associate the print button to the PrintView action.
- """
- self._add_action('PrintView', 'document-print', _("_Print..."),
- accel="P",
- tip=_("Print or save the Map"),
- callback=self.printview)
+ self._add_action('PrintView', self.printview, 'P')
def config_connect(self):
"""
@@ -345,7 +336,6 @@ class GeoGraphyView(OsmGps, NavigationView):
"""
self.menu = Gtk.Menu()
menu = self.menu
- menu.set_title(_('Map Menu'))
if config.get("geography.show_cross"):
title = _('Remove cross hair')
@@ -876,7 +866,7 @@ class GeoGraphyView(OsmGps, NavigationView):
# Printing functionalities
#
#-------------------------------------------------------------------------
- def printview(self, obj):
+ def printview(self, *obj):
"""
Print or save the view that is currently shown
"""
diff --git a/gramps/plugins/sidebar/categorysidebar.py b/gramps/plugins/sidebar/categorysidebar.py
index c4458ca23..29ce50b4d 100644
--- a/gramps/plugins/sidebar/categorysidebar.py
+++ b/gramps/plugins/sidebar/categorysidebar.py
@@ -88,14 +88,6 @@ class CategorySidebar(BaseSidebar):
button.drag_dest_set(0, [], 0)
button.connect('drag_motion', self.cb_switch_page_on_dnd, cat_num)
- # toollbar buttons for switching views in a category
- uitoolitems = ''
- for view_num, view_name, view_icon in views[cat_num]:
- pageid = 'page_%i_%i' % (cat_num, view_num)
- uitoolitems += '\n' % pageid
- if len(views[cat_num]) > 1:
- self.ui_category[cat_num] = UICATEGORY % uitoolitems
-
vbox.show_all()
def get_top(self):
diff --git a/gramps/plugins/view/citationlistview.py b/gramps/plugins/view/citationlistview.py
index 297a36a67..c2bfab321 100644
--- a/gramps/plugins/view/citationlistview.py
+++ b/gramps/plugins/view/citationlistview.py
@@ -62,7 +62,7 @@ from gramps.gui.merge import MergeCitation
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
-_ = glocale.translation.gettext
+_ = glocale.translation.sgettext
#-------------------------------------------------------------------------
@@ -146,12 +146,7 @@ class CitationListView(ListView):
multiple=True,
filter_class=CitationSidebarFilter)
- self.func_list.update({
- 'J' : self.jump,
- 'BackSpace' : self.key_delete,
- })
-
- self.additional_uis.append(self.additional_ui())
+ self.additional_uis.append(self.additional_ui)
def navigation_type(self):
return 'Citation'
@@ -159,94 +154,196 @@ class CitationListView(ListView):
def drag_info(self):
return DdTargets.CITATION_LINK
- def define_actions(self):
- """
- This defines the possible actions for the citation views.
- Possible actions are:
- add: Add a new citation and a new source (this can also be done
- by source view add a source, then citation view add a new
- citation to an existing source)
- edit: Edit a citation.
- merge: Merge the selected citations.
- remove: Delete the selected citations.
-
-
- """
- ListView.define_actions(self)
-
- self.all_action = Gtk.ActionGroup(name=self.title + "/CitationAll")
- self.edit_action = Gtk.ActionGroup(name=self.title + "/CitationEdit")
-
- self._add_action('FilterEdit', None, _('Citation Filter Editor'),
- callback=self.filter_editor,)
- self._add_action('QuickReport', None, _("Quick View"), None, None, None)
-
- self._add_action_group(self.edit_action)
- self._add_action_group(self.all_action)
-
def get_stock(self):
return 'gramps-citation'
- def additional_ui(self):
- """
- Defines the UI string for UIManager
- """
- return '''
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- '''
+ additional_ui = [
+ '''
+
+ -
+ win.ExportTab
+ Export View...
+
+
+''',
+ '''
+
+ -
+ win.AddBook
+ _Add Bookmark
+
+ -
+ win.EditBook
+ %s...
+
+
+''' % _('Organize Bookmarks'),
+ '''
+
+
+ -
+ win.Back
+ _Back
+
+ -
+ win.Forward
+ _Forward
+
+
+
+''',
+ '''
+
+ -
+ win.Add
+ _Add...
+
+ -
+ win.Edit
+ %s
+
+ -
+ win.Remove
+ _Delete
+
+ -
+ win.Merge
+ _Merge...
+
+
+''' % _("action|_Edit..."), # to use sgettext()
+ '''
+
+ -
+ win.FilterEdit
+ '''
+ '''Citation Filter Editor
+
+
+''', # Following are the Toolbar items
+ '''
+
+
+
+ go-previous
+ win.Back
+ '''
+ '''Go to the previous object in the history
+ _Back
+ True
+
+
+ False
+
+
+
+
+ go-next
+ win.Forward
+ '''
+ '''Go to the next object in the history
+ _Forward
+ True
+
+
+ False
+
+
+
+''',
+ '''
+
+
+
+ list-add
+ win.Add
+ %s
+ _Add...
+ True
+
+
+ False
+
+
+
+
+ gtk-edit
+ win.Edit
+ %s
+ Edit...
+ True
+
+
+ False
+
+
+
+
+ list-remove
+ win.Remove
+ %s
+ _Delete
+ True
+
+
+ False
+
+
+
+
+ gramps-merge
+ win.Merge
+ %s
+ _Merge...
+ True
+
+
+ False
+
+
+
+''' % (ADD_MSG, EDIT_MSG, DEL_MSG, MERGE_MSG),
+ '''
+
+''' % _('action|_Edit...') # to use sgettext()
+]
- def add(self, obj):
+ def add(self, *obj):
"""
add: Add a new citation and a new source (this can also be done
by source view add a source, then citation view add a new
@@ -269,7 +366,7 @@ class CitationListView(ListView):
except WindowActiveError:
pass
- def remove(self, obj):
+ def remove(self, *obj):
self.remove_selected_objects()
def remove_object_from_handle(self, handle):
@@ -280,7 +377,7 @@ class CitationListView(ListView):
is_used = any(the_lists)
return (query, is_used, object)
- def edit(self, obj):
+ def edit(self, *obj):
"""
Edit a Citation
"""
@@ -301,7 +398,7 @@ class CitationListView(ListView):
"the same citation is being edited.\n\nTo edit this "
"citation, you need to close the object.")
- def merge(self, obj):
+ def merge(self, *obj):
"""
Merge the selected citations.
"""
diff --git a/gramps/plugins/view/citationtreeview.py b/gramps/plugins/view/citationtreeview.py
index 8121e9620..2cc1c0699 100644
--- a/gramps/plugins/view/citationtreeview.py
+++ b/gramps/plugins/view/citationtreeview.py
@@ -65,7 +65,7 @@ from gramps.gui.merge import MergeCitation, MergeSource
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
-_ = glocale.translation.gettext
+_ = glocale.translation.sgettext
#-------------------------------------------------------------------------
#
@@ -147,12 +147,7 @@ class CitationTreeView(ListView):
multiple=True,
filter_class=SourceSidebarFilter)
- self.func_list.update({
- 'J' : self.jump,
- 'BackSpace' : self.key_delete,
- })
-
- self.additional_uis.append(self.additional_ui())
+ self.additional_uis.append(self.additional_ui)
# Override change_active from NavigationView, so that only Citations can be
# put in the history list for the CitationTreeView
@@ -298,100 +293,241 @@ class CitationTreeView(ListView):
"""
ListView.define_actions(self)
- self._add_action('Add source', 'gramps-source', _("Add source..."),
- accel=None,
- tip=self.ADD_SOURCE_MSG,
- callback=self.add_source)
- self._add_action('Add citation', 'gramps-citation',
- _("Add citation..."),
- accel=None,
- tip=self.ADD_CITATION_MSG,
- callback=self.share)
+ self.action_list.extend([
+ ('AddSource', self.add_source),
+ ('AddCitation', self.share),
+ ('OpenAllNodes', self.open_all_nodes),
+ ('CloseAllNodes', self.close_all_nodes), ])
- self.all_action = Gtk.ActionGroup(name=self.title + "/CitationAll")
- self.edit_action = Gtk.ActionGroup(name=self.title + "/CitationEdit")
+ additional_ui = [ # Defines the UI string for UIManager
+ '''
+
+ -
+ win.ExportTab
+ Export View...
+
+
+''',
+ '''
+
+ -
+ win.AddBook
+ _Add Bookmark
+
+ -
+ win.EditBook
+ %s...
+
+
+''' % _('Organize Bookmarks'),
+ '''
+
+
+ -
+ win.Back
+ _Back
+
+ -
+ win.Forward
+ _Forward
+
+
+
+''',
+ '''
+
+ -
+ win.Add
+ _Add...
+
+ -
+ win.AddSource
+ Add source...
+
+ -
+ win.AddCitation
+ Add citation...
+
+ -
+ win.Edit
+ %s
+
+ -
+ win.Remove
+ _Delete
+
+ -
+ win.Merge
+ _Merge...
+
+
+''' % _("action|_Edit..."), # to use sgettext()
+ '''
+
+ -
+ win.FilterEdit
+ '''
+ '''Citation Filter Editor
+
+
+''', # Following are the Toolbar items
+ '''
+
+
+
+ go-previous
+ win.Back
+ '''
+ '''Go to the previous object in the history
+
+
+ False
+
+
+
+
+ go-next
+ win.Forward
+ '''
+ '''Go to the next object in the history
+
+
+ False
+
+
+
+''',
+ '''
+
+
+
+ list-add
+ win.Add
+ %s
+ _Add...
+ True
+
+
+ False
+
+
+
+
+ gramps-source
+ win.AddSource
+ %s
+ Add source...
+
+
+ False
+
+
+
+
+ gramps-citation
+ win.AddCitation
+ %s
+ Add citation...
+
+
+ False
+
+
+
+
+ gtk-edit
+ win.Edit
+ %s
+ Edit...
+ True
+
+
+ False
+
+
+
+
+ list-remove
+ win.Remove
+ %s
+ _Delete
+ True
+
+
+ False
+
+
+
+
+ gramps-merge
+ win.Merge
+ %s
+ _Merge...
+ True
+
+
+ False
+
+
+
+''' % (ADD_MSG, ADD_SOURCE_MSG, ADD_CITATION_MSG, EDIT_MSG, DEL_MSG,
+ MERGE_MSG),
+ '''
+
+''' % _('action|_Edit...') # to use sgettext()
+]
- self._add_action('FilterEdit', None, _('Citation Filter Editor'),
- callback=self.filter_editor,)
- self._add_action('QuickReport', None, _("Quick View"), None, None, None)
-
- self._add_action_group(self.edit_action)
- self._add_action_group(self.all_action)
-
- self.all_action.add_actions([
- ('OpenAllNodes', None, _("Expand all Nodes"), None, None,
- self.open_all_nodes),
- ('CloseAllNodes', None, _("Collapse all Nodes"), None, None,
- self.close_all_nodes),
- ])
-
- def additional_ui(self):
- """
- Defines the UI string for UIManager
- """
- return '''
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- '''
-
- def add_source(self, obj):
+ def add_source(self, *obj):
"""
add_source: Add a new source (this is also available from the
source view)
@@ -412,7 +548,7 @@ class CitationTreeView(ListView):
except WindowActiveError:
pass
- def add(self, obj):
+ def add(self, *obj):
"""
add: Add a new citation and a new source (this can also be done
by source view add a source, then citation view add a new
@@ -435,7 +571,7 @@ class CitationTreeView(ListView):
except WindowActiveError:
pass
- def share(self, obj):
+ def share(self, *obj):
"""
share: Add a new citation to an existing source (when a source is
selected)
@@ -455,7 +591,7 @@ class CitationTreeView(ListView):
self.__blocked_text(),
parent=self.uistate.window)
#
- def remove(self, obj):
+ def remove(self, *obj):
self.remove_selected_objects()
def remove_object_from_handle(self, handle):
@@ -477,7 +613,7 @@ class CitationTreeView(ListView):
is_used = any(the_lists)
return (query, is_used, source)
- def edit(self, obj):
+ def edit(self, *obj):
"""
Edit either a Source or a Citation, depending on user selection
"""
@@ -518,7 +654,7 @@ class CitationTreeView(ListView):
"source is being edited.\n\nTo edit this "
"source, you need to close the object.")
- def merge(self, obj):
+ def merge(self, *obj):
"""
Merge the selected citations.
"""
diff --git a/gramps/plugins/view/dashboardview.py b/gramps/plugins/view/dashboardview.py
index a54a8f26f..a004227cb 100644
--- a/gramps/plugins/view/dashboardview.py
+++ b/gramps/plugins/view/dashboardview.py
@@ -49,12 +49,7 @@ class DashboardView(PageView):
Create a DashboardView, with the current dbstate and uistate
"""
PageView.__init__(self, _('Dashboard'), pdata, dbstate, uistate)
- self.ui_def = '''
-
-
-
-
- '''
+ self.ui_def = [] # No special menu for Dashboard, Popup in GrampletPane
def build_interface(self):
"""
@@ -101,10 +96,11 @@ class DashboardView(PageView):
def define_actions(self):
"""
- Defines the UIManager actions.
+ Defines the UIManager actions. Called by the ViewManager to set up the
+ View. The user typically defines self.action_list and
+ self.action_toggle_list in this function.
"""
- self._add_action("AddGramplet", 'list-add', _("Add a gramplet"))
- self._add_action("RestoreGramplet", None, _("Restore a gramplet"))
+ pass
def set_inactive(self):
self.active = False
diff --git a/gramps/plugins/view/eventview.py b/gramps/plugins/view/eventview.py
index b403fe9e5..f940a7022 100644
--- a/gramps/plugins/view/eventview.py
+++ b/gramps/plugins/view/eventview.py
@@ -38,7 +38,7 @@ _LOG = logging.getLogger(".plugins.eventview")
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
-_ = glocale.translation.gettext
+_ = glocale.translation.sgettext
from gramps.gui.dialog import ErrorDialog, MultiSelectDialog, QuestionDialog
from gramps.gen.errors import WindowActiveError
@@ -126,15 +126,10 @@ class EventView(ListView):
multiple=True,
filter_class=EventSidebarFilter)
- self.func_list.update({
- 'J' : self.jump,
- 'BackSpace' : self.key_delete,
- })
-
uistate.connect('nameformat-changed', self.build_tree)
uistate.connect('placeformat-changed', self.build_tree)
- self.additional_uis.append(self.additional_ui())
+ self.additional_uis.append(self.additional_ui)
def person_update(self, hndl_list):
""" Deal with person updates thay may effect the Main Participants
@@ -176,71 +171,191 @@ class EventView(ListView):
"""
return 'gramps-event'
- def additional_ui(self):
- """
- Defines the UI string for UIManager
- """
- return '''
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- '''
-
- def define_actions(self):
- ListView.define_actions(self)
- self._add_action('FilterEdit', None,
- _('Event Filter Editor'), callback=self.filter_editor)
- self._add_action('QuickReport', None,
- _("Quick View"), None, None, None)
+ additional_ui = [ # Defines the UI string for UIManager
+ '''
+
+ -
+ win.ExportTab
+ Export View...
+
+
+''',
+ '''
+
+ -
+ win.AddBook
+ _Add Bookmark
+
+ -
+ win.EditBook
+ %s...
+
+
+''' % _('Organize Bookmarks'),
+ '''
+
+
+ -
+ win.Back
+ _Back
+
+ -
+ win.Forward
+ _Forward
+
+
+
+''',
+ '''
+
+ -
+ win.Add
+ _Add...
+
+ -
+ win.Edit
+ %s
+
+ -
+ win.Remove
+ _Delete
+
+ -
+ win.Merge
+ _Merge...
+
+
+''' % _("action|_Edit..."), # to use sgettext()
+ '''
+
+ -
+ win.FilterEdit
+ '''
+ '''Event Filter Editor
+
+
+''', # Following are the Toolbar items
+ '''
+
+
+
+ go-previous
+ win.Back
+ '''
+ '''Go to the previous object in the history
+ _Back
+ True
+
+
+ False
+
+
+
+
+ go-next
+ win.Forward
+ '''
+ '''Go to the next object in the history
+ _Forward
+ True
+
+
+ False
+
+
+
+''',
+ '''
+
+
+
+ list-add
+ win.Add
+ %s
+ _Add...
+ True
+
+
+ False
+
+
+
+
+ gtk-edit
+ win.Edit
+ %s
+ Edit...
+ True
+
+
+ False
+
+
+
+
+ list-remove
+ win.Remove
+ %s
+ _Delete
+ True
+
+
+ False
+
+
+
+
+ gramps-merge
+ win.Merge
+ %s
+ _Merge...
+ True
+
+
+ False
+
+
+
+''' % (ADD_MSG, EDIT_MSG, DEL_MSG, MERGE_MSG),
+ '''
+
+''' % _('action|_Edit...') # to use sgettext()
+ ]
def get_handle_from_gramps_id(self, gid):
obj = self.dbstate.db.get_event_from_gramps_id(gid)
@@ -249,13 +364,13 @@ class EventView(ListView):
else:
return None
- def add(self, obj):
+ def add(self, *obj):
try:
EditEvent(self.dbstate, self.uistate, [], Event())
except WindowActiveError:
pass
- def remove(self, obj):
+ def remove(self, *obj):
"""
Method called when deleting event(s) from the event view.
"""
@@ -310,7 +425,7 @@ class EventView(ListView):
"""
pass
- def edit(self, obj):
+ def edit(self, *obj):
for handle in self.selected_handles():
event = self.dbstate.db.get_event_from_handle(handle)
try:
@@ -318,7 +433,7 @@ class EventView(ListView):
except WindowActiveError:
pass
- def merge(self, obj):
+ def merge(self, *obj):
"""
Merge the selected events.
"""
diff --git a/gramps/plugins/view/familyview.py b/gramps/plugins/view/familyview.py
index 3c3f71730..f046e5069 100644
--- a/gramps/plugins/view/familyview.py
+++ b/gramps/plugins/view/familyview.py
@@ -29,7 +29,7 @@ Family View.
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
-_ = glocale.translation.gettext
+_ = glocale.translation.sgettext
import logging
_LOG = logging.getLogger(".plugins.eventview")
#-------------------------------------------------------------------------
@@ -120,14 +120,9 @@ class FamilyView(ListView):
multiple=True,
filter_class=FamilySidebarFilter)
- self.func_list.update({
- 'J' : self.jump,
- 'BackSpace' : self.key_delete,
- })
-
uistate.connect('nameformat-changed', self.build_tree)
- self.additional_uis.append(self.additional_ui())
+ self.additional_uis.append(self.additional_ui)
def navigation_type(self):
return 'Family'
@@ -135,84 +130,214 @@ class FamilyView(ListView):
def get_stock(self):
return 'gramps-family'
- def additional_ui(self):
- return '''
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- '''
+ additional_ui = [ # Defines the UI string for UIManager
+ '''
+
+ -
+ win.ExportTab
+ Export View...
+
+
+''',
+ '''
+
+ -
+ win.AddBook
+ _Add Bookmark
+
+ -
+ win.EditBook
+ %s...
+
+
+''' % _('Organize Bookmarks'),
+ '''
+
+
+ -
+ win.Back
+ _Back
+
+ -
+ win.Forward
+ _Forward
+
+
+
+''',
+ '''
+
+ -
+ win.Add
+ _Add...
+
+ -
+ win.Edit
+ %s
+
+ -
+ win.Remove
+ _Delete
+
+ -
+ win.Merge
+ _Merge...
+
+
+''' % _("action|_Edit..."), # to use sgettext()
+ '''
+
+ -
+ win.FilterEdit
+ '''
+ '''Family Filter Editor
+
+
+''', # Following are the Toolbar items
+ '''
+
+
+
+ go-previous
+ win.Back
+ '''
+ '''Go to the previous object in the history
+ _Back
+ True
+
+
+ False
+
+
+
+
+ go-next
+ win.Forward
+ '''
+ '''Go to the next object in the history
+ _Forward
+ True
+
+
+ False
+
+
+
+''',
+ '''
+
+
+
+ list-add
+ win.Add
+ %s
+ _Add...
+ True
+
+
+ False
+
+
+
+
+ gtk-edit
+ win.Edit
+ %s
+ Edit...
+ True
+
+
+ False
+
+
+
+
+ list-remove
+ win.Remove
+ %s
+ _Delete
+ True
+
+
+ False
+
+
+
+
+ gramps-merge
+ win.Merge
+ %s
+ _Merge...
+ True
+
+
+ False
+
+
+
+''' % (ADD_MSG, EDIT_MSG, DEL_MSG, MERGE_MSG),
+ '''
+
+''' % _('action|_Edit...') # to use sgettext()
+ ]
def define_actions(self):
"""Add the Forward action group to handle the Forward button."""
ListView.define_actions(self)
- self._add_action('FilterEdit', None, _('Family Filter Editor'),
- callback=self.filter_editor,)
+ self.action_list.extend([
+ ('MakeFatherActive', self._make_father_active),
+ ('MakeMotherActive', self._make_mother_active), ])
- self.all_action = Gtk.ActionGroup(name=self.title + "/FamilyAll")
- self.all_action.add_actions([
- ('MakeFatherActive', None, _("Make Father Active Person"),
- None, None, self._make_father_active),
- ('MakeMotherActive', None, _("Make Mother Active Person"),
- None, None, self._make_mother_active),
- ('QuickReport', None, _("Quick View"), None, None, None),
- ])
- self._add_action_group(self.all_action)
-
- def add_bookmark(self, obj):
+ def add_bookmark(self, *obj):
mlist = self.selected_handles()
if mlist:
self.bookmarks.add(mlist[0])
@@ -223,14 +348,14 @@ class FamilyView(ListView):
_("A bookmark could not be set because "
"no one was selected."), parent=self.uistate.window)
- def add(self, obj):
+ def add(self, *obj):
family = Family()
try:
EditFamily(self.dbstate, self.uistate, [], family)
except WindowActiveError:
pass
- def remove(self, obj):
+ def remove(self, *obj):
"""
Method called when deleting a family from a family view.
"""
@@ -289,7 +414,7 @@ class FamilyView(ListView):
"""
pass
- def edit(self, obj):
+ def edit(self, *obj):
for handle in self.selected_handles():
family = self.dbstate.db.get_family_from_handle(handle)
try:
@@ -297,7 +422,7 @@ class FamilyView(ListView):
except WindowActiveError:
pass
- def merge(self, obj):
+ def merge(self, *obj):
"""
Merge the selected families.
"""
@@ -312,7 +437,7 @@ class FamilyView(ListView):
else:
MergeFamily(self.dbstate, self.uistate, [], mlist[0], mlist[1])
- def _make_father_active(self, obj):
+ def _make_father_active(self, *obj):
"""
Make the father of the family the active person.
"""
@@ -322,7 +447,7 @@ class FamilyView(ListView):
if family:
self.uistate.set_active(family.father_handle, 'Person')
- def _make_mother_active(self, obj):
+ def _make_mother_active(self, *obj):
"""
Make the mother of the family the active person.
"""
diff --git a/gramps/plugins/view/fanchart2wayview.py b/gramps/plugins/view/fanchart2wayview.py
index 00c670744..9a7ab7fc3 100644
--- a/gramps/plugins/view/fanchart2wayview.py
+++ b/gramps/plugins/view/fanchart2wayview.py
@@ -47,6 +47,7 @@ import gramps.gui.widgets.fanchart2way as fanchart2way
from gramps.gui.views.navigationview import NavigationView
from gramps.gui.views.bookmarks import PersonBookmarks
from gramps.gui.utils import SystemFonts
+from gramps.plugins.view.fanchartview import FanChartView
# the print settings to remember between print sessions
PRINT_SETTINGS = None
@@ -101,13 +102,9 @@ class FanChart2WayView(fanchart2way.FanChart2WayGrampsGUI, NavigationView):
dbstate.connect('active-changed', self.active_changed)
dbstate.connect('database-changed', self.change_db)
- self.additional_uis.append(self.additional_ui())
+ self.additional_uis.append(FanChartView.additional_ui)
self.allfonts = [x for x in enumerate(SystemFonts().get_system_fonts())]
- self.func_list.update({
- 'J' : self.jump,
- })
-
def navigation_type(self):
return 'Person'
@@ -144,43 +141,6 @@ class FanChart2WayView(fanchart2way.FanChart2WayGrampsGUI, NavigationView):
"""
return 'gramps-fanchart'
- def additional_ui(self):
- return '''
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- '''
-
def define_actions(self):
"""
Required define_actions function for PageView. Builds the action
@@ -188,10 +148,9 @@ class FanChart2WayView(fanchart2way.FanChart2WayGrampsGUI, NavigationView):
"""
NavigationView.define_actions(self)
- self._add_action('PrintView', Gtk.STOCK_PRINT, _("_Print..."),
- accel="P",
- tip=_("Print or save the Fan Chart View"),
- callback=self.printview)
+ self._add_action('PrintView', self.printview, "P")
+ self._add_action('PRIMARY-J', self.jump, 'J')
+
def build_tree(self):
"""
Generic method called by PageView to construct the view.
@@ -249,7 +208,7 @@ class FanChart2WayView(fanchart2way.FanChart2WayGrampsGUI, NavigationView):
if self.active:
self.bookmarks.redraw()
- def printview(self, obj):
+ def printview(self, *obj):
"""
Print or save the view that is currently shown
"""
diff --git a/gramps/plugins/view/fanchartdescview.py b/gramps/plugins/view/fanchartdescview.py
index 23e636327..51093acae 100644
--- a/gramps/plugins/view/fanchartdescview.py
+++ b/gramps/plugins/view/fanchartdescview.py
@@ -46,6 +46,7 @@ import gramps.gui.widgets.fanchartdesc as fanchartdesc
from gramps.gui.views.navigationview import NavigationView
from gramps.gui.views.bookmarks import PersonBookmarks
from gramps.gui.utils import SystemFonts
+from gramps.plugins.view.fanchartview import FanChartView
# the print settings to remember between print sessions
PRINT_SETTINGS = None
@@ -96,13 +97,9 @@ class FanChartDescView(fanchartdesc.FanChartDescGrampsGUI, NavigationView):
dbstate.connect('active-changed', self.active_changed)
dbstate.connect('database-changed', self.change_db)
- self.additional_uis.append(self.additional_ui())
+ self.additional_uis.append(FanChartView.additional_ui)
self.allfonts = [x for x in enumerate(SystemFonts().get_system_fonts())]
- self.func_list.update({
- 'J' : self.jump,
- })
-
def navigation_type(self):
return 'Person'
@@ -139,43 +136,6 @@ class FanChartDescView(fanchartdesc.FanChartDescGrampsGUI, NavigationView):
"""
return 'gramps-fanchart'
- def additional_ui(self):
- return '''
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- '''
-
def define_actions(self):
"""
Required define_actions function for PageView. Builds the action
@@ -183,10 +143,9 @@ class FanChartDescView(fanchartdesc.FanChartDescGrampsGUI, NavigationView):
"""
NavigationView.define_actions(self)
- self._add_action('PrintView', 'document-print', _("_Print..."),
- accel="P",
- tip=_("Print or save the Fan Chart View"),
- callback=self.printview)
+ self._add_action('PrintView', self.printview, "P")
+ self._add_action('PRIMARY-J', self.jump, 'J')
+
def build_tree(self):
"""
Generic method called by PageView to construct the view.
@@ -244,7 +203,7 @@ class FanChartDescView(fanchartdesc.FanChartDescGrampsGUI, NavigationView):
if self.active:
self.bookmarks.redraw()
- def printview(self, obj):
+ def printview(self, *obj):
"""
Print or save the view that is currently shown
"""
diff --git a/gramps/plugins/view/fanchartview.py b/gramps/plugins/view/fanchartview.py
index bf1b86cda..65b3f557b 100644
--- a/gramps/plugins/view/fanchartview.py
+++ b/gramps/plugins/view/fanchartview.py
@@ -34,7 +34,7 @@ from gi.repository import Gdk
from gi.repository import Gtk
import cairo
from gramps.gen.const import GRAMPS_LOCALE as glocale
-_ = glocale.translation.gettext
+_ = glocale.translation.sgettext
#-------------------------------------------------------------------------
#
@@ -93,13 +93,9 @@ class FanChartView(fanchart.FanChartGrampsGUI, NavigationView):
dbstate.connect('active-changed', self.active_changed)
dbstate.connect('database-changed', self.change_db)
- self.additional_uis.append(self.additional_ui())
+ self.additional_uis.append(self.additional_ui)
self.allfonts = [x for x in enumerate(SystemFonts().get_system_fonts())]
- self.func_list.update({
- 'J' : self.jump,
- })
-
def navigation_type(self):
return 'Person'
@@ -135,42 +131,107 @@ class FanChartView(fanchart.FanChartGrampsGUI, NavigationView):
"""
return 'gramps-fanchart'
- def additional_ui(self):
- return '''
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ additional_ui = [ # Defines the UI string for UIManager
'''
+
+
+ -
+ win.Back
+ _Back
+
+ -
+ win.Forward
+ _Forward
+
+
+
+ -
+ win.HomePerson
+ _Home
+
+
+
+''',
+ '''
+
+ -
+ win.PrintView
+ _Print...
+
+
+''',
+ '''
+
+ -
+ win.AddBook
+ _Add Bookmark
+
+ -
+ win.EditBook
+ %s...
+
+
+''' % _('Organize Bookmarks'), # Following are the Toolbar items
+ '''
+
+
+
+ go-previous
+ win.Back
+ '''
+ '''Go to the previous object in the history
+ _Back
+ True
+
+
+ False
+
+
+
+
+ go-next
+ win.Forward
+ '''
+ '''Go to the next object in the history
+ _Forward
+ True
+
+
+ False
+
+
+
+
+ go-home
+ win.HomePerson
+ '''
+ '''Go to the default person
+ _Home
+ True
+
+
+ False
+
+
+
+''',
+ '''
+
+
+
+ document-print
+ win.PrintView
+ '''
+ '''Print or save the Fan Chart View
+ _Print...
+ True
+
+
+ False
+
+
+
+ ''']
def define_actions(self):
"""
@@ -179,10 +240,9 @@ class FanChartView(fanchart.FanChartGrampsGUI, NavigationView):
"""
NavigationView.define_actions(self)
- self._add_action('PrintView', 'document-print', _("_Print..."),
- accel="P",
- tip=_("Print or save the Fan Chart View"),
- callback=self.printview)
+ self._add_action('PrintView', self.printview, "P")
+ self._add_action('PRIMARY-J', self.jump, 'J')
+
def build_tree(self):
"""
Generic method called by PageView to construct the view.
@@ -240,7 +300,7 @@ class FanChartView(fanchart.FanChartGrampsGUI, NavigationView):
if self.active:
self.bookmarks.redraw()
- def printview(self, obj):
+ def printview(self, *obj):
"""
Print or save the view that is currently shown
"""
diff --git a/gramps/plugins/view/geoclose.py b/gramps/plugins/view/geoclose.py
index f831a9c01..f029cdaf3 100644
--- a/gramps/plugins/view/geoclose.py
+++ b/gramps/plugins/view/geoclose.py
@@ -54,12 +54,12 @@ from gramps.gen.datehandler import displayer, get_date
from gramps.gen.display.name import displayer as _nd
from gramps.gen.display.place import displayer as _pd
from gramps.gen.utils.place import conv_lat_lon
-from gramps.gui.views.navigationview import NavigationView
from gramps.gui.views.bookmarks import PersonBookmarks
from gramps.plugins.lib.maps import constants
from gramps.plugins.lib.maps.geography import GeoGraphyView
from gramps.gui.selectors import SelectorFactory
from gramps.gen.utils.db import (get_birth_or_fallback, get_death_or_fallback)
+from gramps.gui.uimanager import ActionGroup
#-------------------------------------------------------------------------
#
@@ -67,43 +67,120 @@ from gramps.gen.utils.db import (get_birth_or_fallback, get_death_or_fallback)
#
#-------------------------------------------------------------------------
-_UI_DEF = '''\
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-'''
+_UI_DEF = [
+ '''
+
+
+ -
+ win.Back
+ _Back
+
+ -
+ win.Forward
+ _Forward
+
+
+
+ -
+ win.HomePerson
+ _Home
+
+
+
+ ''',
+ '''
+
+ -
+ win.PrintView
+ _Print...
+
+
+ ''',
+ '''
+
+ -
+ win.AddBook
+ _Add Bookmark
+
+ -
+ win.EditBook
+ %s...
+
+
+ ''' % _('Organize Bookmarks'), # Following are the Toolbar items
+ '''
+
+
+
+ go-previous
+ win.Back
+ '''
+ '''Go to the previous object in the history
+ _Back
+ True
+
+
+ False
+
+
+
+
+ go-next
+ win.Forward
+ '''
+ '''Go to the next object in the history
+ _Forward
+ True
+
+
+ False
+
+
+
+
+ go-home
+ win.HomePerson
+ '''
+ '''Go to the default person
+ _Home
+ True
+
+
+ False
+
+
+
+
+ gramps-person
+ win.RefPerson
+ '''
+ '''Select the person which is the reference for life ways
+ reference _Person
+ True
+
+
+ False
+
+
+
+ ''',
+ '''
+
+
+
+ document-print
+ win.PrintView
+ '''
+ '''Print or save the Map
+ _Print...
+ True
+
+
+ False
+
+
+
+ ''']
# pylint: disable=no-member
# pylint: disable=unused-argument
@@ -291,18 +368,10 @@ class GeoClose(GeoGraphyView):
"""
Define action for the reference person button.
"""
- NavigationView.define_actions(self)
+ GeoGraphyView.define_actions(self)
+ self._add_action('RefPerson', self.select_person)
- self.define_print_actions()
- self.ref_person = Gtk.ActionGroup(name=self.title + '/Selection')
- self.ref_person.add_actions([
- ('RefPerson', 'gramps-person', _('reference _Person'), None,
- _("Select the person which is the reference for life ways"),
- self.select_person),
- ])
- self._add_action_group(self.ref_person)
-
- def select_person(self, obj):
+ def select_person(self, *obj):
"""
Open a selection box to choose the ref person.
"""
diff --git a/gramps/plugins/view/geoevents.py b/gramps/plugins/view/geoevents.py
index fcf54eb94..1a6f28284 100644
--- a/gramps/plugins/view/geoevents.py
+++ b/gramps/plugins/view/geoevents.py
@@ -64,39 +64,84 @@ from gramps.gui.utils import ProgressMeter
#
#-------------------------------------------------------------------------
-_UI_DEF = '''\
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-'''
+_UI_DEF = ['''
+
+
+ -
+ win.Back
+ _Back
+
+ -
+ win.Forward
+ _Forward
+
+
+
+ ''',
+ '''
+
+ -
+ win.PrintView
+ _Print...
+
+
+ ''',
+ '''
+
+ -
+ win.AddBook
+ _Add Bookmark
+
+ -
+ win.EditBook
+ %s...
+
+
+ ''' % _('Organize Bookmarks'), # Following are the Toolbar items
+ '''
+
+
+
+ go-previous
+ win.Back
+ Go to the previous object in the history
+ _Back
+ True
+
+
+ False
+
+
+
+
+ go-next
+ win.Forward
+ Go to the next object in the history
+ _Forward
+ True
+
+
+ False
+
+
+
+ ''',
+ '''
+
+
+
+ document-print
+ win.PrintView
+ Print or save the Map
+ _Print...
+ True
+
+
+ False
+
+
+
+ ''']
# pylint: disable=unused-argument
# pylint: disable=no-member
diff --git a/gramps/plugins/view/geofamclose.py b/gramps/plugins/view/geofamclose.py
index 266ff6d81..fca0c28e4 100644
--- a/gramps/plugins/view/geofamclose.py
+++ b/gramps/plugins/view/geofamclose.py
@@ -65,43 +65,120 @@ from gramps.gui.selectors import SelectorFactory
#
#-------------------------------------------------------------------------
-_UI_DEF = '''\
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-'''
+_UI_DEF = [
+ '''
+
+
+ -
+ win.Back
+ _Back
+
+ -
+ win.Forward
+ _Forward
+
+
+
+ -
+ win.HomePerson
+ _Home
+
+
+
+''',
+ '''
+
+ -
+ win.PrintView
+ _Print...
+
+
+''',
+ '''
+
+ -
+ win.AddBook
+ _Add Bookmark
+
+ -
+ win.EditBook
+ %s...
+
+
+''' % _('Organize Bookmarks'), # Following are the Toolbar items
+ '''
+
+
+
+ go-previous
+ win.Back
+ '''
+ '''Go to the previous object in the history
+ _Back
+ True
+
+
+ False
+
+
+
+
+ go-next
+ win.Forward
+ '''
+ '''Go to the next object in the history
+ _Forward
+ True
+
+
+ False
+
+
+
+
+ go-home
+ win.HomePerson
+ '''
+ '''Go to the default person
+ _Home
+ True
+
+
+ False
+
+
+
+
+ gramps-family
+ win.RefFamily
+ '''
+ '''Select the family which is the reference for life ways
+ reference _Family
+ True
+
+
+ False
+
+
+
+''',
+ '''
+
+
+
+ document-print
+ win.PrintView
+ '''
+ '''Print or save the Map
+ _Print...
+ True
+
+
+ False
+
+
+
+ ''']
# pylint: disable=no-member
# pylint: disable=unused-variable
@@ -287,18 +364,10 @@ class GeoFamClose(GeoGraphyView):
"""
Define action for the reference family button.
"""
- NavigationView.define_actions(self)
+ GeoGraphyView.define_actions(self)
+ self._add_action('RefFamily', self.select_family)
- self.define_print_actions()
- self.ref_family = Gtk.ActionGroup(self.title + '/Selection')
- self.ref_family.add_actions([
- ('RefFamily', 'gramps-family', _('reference _Family'), None,
- _("Select the family which is the reference for life ways"),
- self.select_family),
- ])
- self._add_action_group(self.ref_family)
-
- def select_family(self, obj):
+ def select_family(self, *obj):
"""
Open a selection box to choose the ref family.
"""
diff --git a/gramps/plugins/view/geofamily.py b/gramps/plugins/view/geofamily.py
index 977fc9af6..42fcac16d 100644
--- a/gramps/plugins/view/geofamily.py
+++ b/gramps/plugins/view/geofamily.py
@@ -63,39 +63,88 @@ from gramps.plugins.lib.maps.geography import GeoGraphyView
#
#-------------------------------------------------------------------------
-_UI_DEF = '''\
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-'''
+_UI_DEF = [
+ '''
+
+
+ -
+ win.Back
+ _Back
+
+ -
+ win.Forward
+ _Forward
+
+
+
+''',
+ '''
+
+ -
+ win.PrintView
+ _Print...
+
+
+''',
+ '''
+
+ -
+ win.AddBook
+ _Add Bookmark
+
+ -
+ win.EditBook
+ %s...
+
+
+''' % _('Organize Bookmarks'), # Following are the Toolbar items
+ '''
+
+
+
+ go-previous
+ win.Back
+ ...
+ ...Go to the previous object in the history
+ _Back
+ True
+
+
+ False
+
+
+
+
+ go-next
+ win.Forward
+ '''
+ '''Go to the next object in the history
+ _Forward
+ True
+
+
+ False
+
+
+
+''',
+ '''
+
+
+
+ document-print
+ win.PrintView
+ '''
+ '''Print or save the Map
+ _Print...
+ True
+
+
+ False
+
+
+
+ ''']
# pylint: disable=no-member
# pylint: disable=unused-variable
diff --git a/gramps/plugins/view/geomoves.py b/gramps/plugins/view/geomoves.py
index 6855c4e14..00234c764 100644
--- a/gramps/plugins/view/geomoves.py
+++ b/gramps/plugins/view/geomoves.py
@@ -64,42 +64,107 @@ from gramps.plugins.lib.maps.geography import GeoGraphyView
#
#-------------------------------------------------------------------------
-_UI_DEF = '''\
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-'''
+_UI_DEF = [
+ '''
+
+
+ -
+ win.Back
+ _Back
+
+ -
+ win.Forward
+ _Forward
+
+
+
+ -
+ win.HomePerson
+ _Home
+
+
+
+''',
+ '''
+
+ -
+ win.PrintView
+ _Print...
+
+
+''',
+ '''
+
+ -
+ win.AddBook
+ _Add Bookmark
+
+ -
+ win.EditBook
+ %s...
+
+
+''' % _('Organize Bookmarks'), # Following are the Toolbar items
+ '''
+
+
+
+ go-previous
+ win.Back
+ '''
+ '''Go to the previous object in the history
+ _Back
+ True
+
+
+ False
+
+
+
+
+ go-next
+ win.Forward
+ '''
+ '''Go to the next object in the history
+ _Forward
+ True
+
+
+ False
+
+
+
+
+ go-home
+ win.HomePerson
+ '''
+ '''Go to the default person
+ _Home
+ True
+
+
+ False
+
+
+
+''',
+ '''
+
+
+
+ document-print
+ win.PrintView
+ '''
+ '''Print or save the Map
+ _Print...
+ True
+
+
+ False
+
+
+
+ ''']
# pylint: disable=no-member
# pylint: disable=unused-variable
diff --git a/gramps/plugins/view/geoperson.py b/gramps/plugins/view/geoperson.py
index b0648fc2f..2c5e09c3f 100644
--- a/gramps/plugins/view/geoperson.py
+++ b/gramps/plugins/view/geoperson.py
@@ -65,42 +65,107 @@ from gramps.plugins.lib.maps.geography import GeoGraphyView
#
#-------------------------------------------------------------------------
-_UI_DEF = '''\
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-'''
+_UI_DEF = [
+ '''
+
+
+ -
+ win.Back
+ _Back
+
+ -
+ win.Forward
+ _Forward
+
+
+
+ -
+ win.HomePerson
+ _Home
+
+
+
+''',
+ '''
+
+ -
+ win.PrintView
+ _Print...
+
+
+''',
+ '''
+
+ -
+ win.AddBook
+ _Add Bookmark
+
+ -
+ win.EditBook
+ %s...
+
+
+''' % _('Organize Bookmarks'), # Following are the Toolbar items
+ '''
+
+
+
+ go-previous
+ win.Back
+ '''
+ '''Go to the previous object in the history
+ _Back
+ True
+
+
+ False
+
+
+
+
+ go-next
+ win.Forward
+ '''
+ '''Go to the next object in the history
+ _Forward
+ True
+
+
+ False
+
+
+
+
+ go-home
+ win.HomePerson
+ '''
+ '''Go to the default person
+ _Home
+ True
+
+
+ False
+
+
+
+''',
+ '''
+
+
+
+ document-print
+ win.PrintView
+ '''
+ '''Print or save the Map
+ reference _Family
+ True
+
+
+ False
+
+
+
+ ''']
# pylint: disable=no-member
# pylint: disable=maybe-no-member
diff --git a/gramps/plugins/view/geoplaces.py b/gramps/plugins/view/geoplaces.py
index 9a4cb6423..d2832b927 100644
--- a/gramps/plugins/view/geoplaces.py
+++ b/gramps/plugins/view/geoplaces.py
@@ -65,39 +65,88 @@ from gramps.gui.utils import ProgressMeter
#
#-------------------------------------------------------------------------
-_UI_DEF = '''\
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-'''
+_UI_DEF = [
+ '''
+
+
+ -
+ win.Back
+ _Back
+
+ -
+ win.Forward
+ _Forward
+
+
+
+''',
+ '''
+
+ -
+ win.PrintView
+ _Print...
+
+
+''',
+ '''
+
+ -
+ win.AddBook
+ _Add Bookmark
+
+ -
+ win.EditBook
+ %s...
+
+
+''' % _('Organize Bookmarks'), # Following are the Toolbar items
+ '''
+
+
+
+ go-previous
+ win.Back
+ '''
+ '''Go to the previous object in the history
+ _Back
+ True
+
+
+ False
+
+
+
+
+ go-next
+ win.Forward
+ '''
+ '''Go to the next object in the history
+ _Forward
+ True
+
+
+ False
+
+
+
+''',
+ '''
+
+
+
+ document-print
+ win.PrintView
+ '''
+ '''Print or save the Map
+ _Print...
+ True
+
+
+ False
+
+
+
+ ''']
# pylint: disable=no-member
# pylint: disable=maybe-no-member
diff --git a/gramps/plugins/view/mediaview.py b/gramps/plugins/view/mediaview.py
index 2644af1a3..bcc22a013 100644
--- a/gramps/plugins/view/mediaview.py
+++ b/gramps/plugins/view/mediaview.py
@@ -30,7 +30,7 @@ Media View.
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
-_ = glocale.translation.gettext
+_ = glocale.translation.sgettext
import os
from urllib.parse import urlparse
from urllib.request import url2pathname
@@ -133,12 +133,7 @@ class MediaView(ListView):
filter_class=MediaSidebarFilter,
multiple=True)
- self.func_list.update({
- 'J' : self.jump,
- 'BackSpace' : self.key_delete,
- })
-
- self.additional_uis.append(self.additional_ui())
+ self.additional_uis.append(self.additional_ui)
self.uistate = uistate
def navigation_type(self):
@@ -206,19 +201,10 @@ class MediaView(ListView):
"""
ListView.define_actions(self)
- self._add_action('FilterEdit', None, _('Media Filter Editor'),
- callback=self.filter_editor)
- self._add_action('OpenMedia', 'gramps-viewmedia', _('View'),
- tip=_("View in the default viewer"),
- callback=self.view_media)
- self._add_action('OpenContainingFolder', None,
- _('Open Containing _Folder'),
- tip=_("Open the folder containing the media file"),
- callback=self.open_containing_folder)
+ self._add_action('OpenMedia', self.view_media)
+ self._add_action('OpenContainingFolder', self.open_containing_folder)
- self._add_action('QuickReport', None, _("Quick View"), None, None, None)
-
- def view_media(self, obj):
+ def view_media(self, *obj):
"""
Launch external viewers for the selected objects.
"""
@@ -227,7 +213,7 @@ class MediaView(ListView):
mpath = media_path_full(self.dbstate.db, ref_obj.get_path())
open_file_with_default_application(mpath, self.uistate)
- def open_containing_folder(self, obj):
+ def open_containing_folder(self, *obj):
"""
Launch external viewers for the selected objects.
"""
@@ -244,78 +230,225 @@ class MediaView(ListView):
"""
return 'gramps-media'
- def additional_ui(self):
- """
- Return the UIManager XML description of the menus
- """
- return '''
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- '''
+ additional_ui = [ # Defines the UI string for UIManager
+ '''
+
+ -
+ win.ExportTab
+ Export View...
+
+
+''',
+ '''
+
+ -
+ win.AddBook
+ _Add Bookmark
+
+ -
+ win.EditBook
+ %s...
+
+
+''' % _('Organize Bookmarks'),
+ '''
+
+
+ -
+ win.Back
+ _Back
+
+ -
+ win.Forward
+ _Forward
+
+
+
+''',
+ '''
+
+ -
+ win.Add
+ _Add...
+
+ -
+ win.Edit
+ %s
+
+ -
+ win.Remove
+ _Delete
+
+ -
+ win.Merge
+ _Merge...
+
+
+''' % _("action|_Edit..."), # to use sgettext()
+ '''
+
+ -
+ win.FilterEdit
+ '''
+ '''Media Filter Editor
+
+
+''', # Following are the Toolbar items
+ '''
+
+
+
+ go-previous
+ win.Back
+ '''
+ '''Go to the previous object in the history
+ _Back
+ True
+
+
+ False
+
+
+
+
+ go-next
+ win.Forward
+ '''
+ '''Go to the next object in the history
+ _Forward
+ True
+
+
+ False
+
+
+
+''',
+ '''
+
+
+
+ list-add
+ win.Add
+ %s
+ _Add...
+ True
+
+
+ False
+
+
+
+
+ gtk-edit
+ win.Edit
+ %s
+ Edit...
+ True
+
+
+ False
+
+
+
+
+ list-remove
+ win.Remove
+ %s
+ _Delete
+ True
+
+
+ False
+
+
+
+
+ gramps-merge
+ win.Merge
+ %s
+ _Merge...
+ True
+
+
+ False
+
+
+
+''' % (ADD_MSG, EDIT_MSG, DEL_MSG, MERGE_MSG),
+ '''
+
+
+
+ gramps-viewmedia
+ win.OpenMedia
+ '''
+ '''View in the default viewer
+ View
+
+
+ False
+
+
+
+''',
+ '''
+
+''' % _('action|_Edit...') # to use sgettext()
+ ]
- def add(self, obj):
+ def add(self, *obj):
"""Add a new media object to the media list"""
try:
EditMedia(self.dbstate, self.uistate, [], Media())
except WindowActiveError:
pass
- def remove(self, obj):
+ def remove(self, *obj):
self.remove_selected_objects()
def remove_object_from_handle(self, handle):
@@ -329,7 +462,7 @@ class MediaView(ListView):
is_used = any(the_lists)
return (query, is_used, object)
- def edit(self, obj):
+ def edit(self, *obj):
"""
Edit the selected objects in the EditMedia dialog
"""
@@ -340,7 +473,7 @@ class MediaView(ListView):
except WindowActiveError:
pass
- def merge(self, obj):
+ def merge(self, *obj):
"""
Merge the selected objects.
"""
diff --git a/gramps/plugins/view/noteview.py b/gramps/plugins/view/noteview.py
index 2002c2414..e295f52e1 100644
--- a/gramps/plugins/view/noteview.py
+++ b/gramps/plugins/view/noteview.py
@@ -28,7 +28,7 @@ Note View.
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
-_ = glocale.translation.gettext
+_ = glocale.translation.sgettext
import logging
_LOG = logging.getLogger(".plugins.noteview")
@@ -113,12 +113,7 @@ class NoteView(ListView):
filter_class=NoteSidebarFilter,
multiple=True)
- self.func_list.update({
- 'J' : self.jump,
- 'BackSpace' : self.key_delete,
- })
-
- self.additional_uis.append(self.additional_ui())
+ self.additional_uis.append(self.additional_ui)
def navigation_type(self):
return 'Note'
@@ -135,70 +130,191 @@ class NoteView(ListView):
"""
return 'gramps-notes'
- def additional_ui(self):
- """
- Defines the UI string for UIManager
- """
- return '''
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- '''
-
- def define_actions(self):
- ListView.define_actions(self)
- self._add_action('FilterEdit', None, _('Note Filter Editor'),
- callback=self.filter_editor,)
- self._add_action('QuickReport', None, _("Quick View"), None, None, None)
+ additional_ui = [ # Defines the UI string for UIManager
+ '''
+
+ -
+ win.ExportTab
+ Export View...
+
+
+''',
+ '''
+
+ -
+ win.AddBook
+ _Add Bookmark
+
+ -
+ win.EditBook
+ %s...
+
+
+''' % _('Organize Bookmarks'),
+ '''
+
+
+ -
+ win.Back
+ _Back
+
+ -
+ win.Forward
+ _Forward
+
+
+
+''',
+ '''
+
+ -
+ win.Add
+ _Add...
+
+ -
+ win.Edit
+ %s
+
+ -
+ win.Remove
+ _Delete
+
+ -
+ win.Merge
+ _Merge...
+
+
+''' % _("action|_Edit..."), # to use sgettext()
+ '''
+
+ -
+ win.FilterEdit
+ '''
+ '''Note Filter Editor
+
+
+''', # Following are the Toolbar items
+ '''
+
+
+
+ go-previous
+ win.Back
+ '''
+ '''Go to the previous object in the history
+ _Back
+ True
+
+
+ False
+
+
+
+
+ go-next
+ win.Forward
+ '''
+ '''Go to the next object in the history
+ _Forward
+ True
+
+
+ False
+
+
+
+''',
+ '''
+
+
+
+ list-add
+ win.Add
+ %s
+ _Add...
+ True
+
+
+ False
+
+
+
+
+ gtk-edit
+ win.Edit
+ %s
+ Edit...
+ True
+
+
+ False
+
+
+
+
+ list-remove
+ win.Remove
+ %s
+ _Delete
+ True
+
+
+ False
+
+
+
+
+ gramps-merge
+ win.Merge
+ %s
+ _Merge...
+ True
+
+
+ False
+
+
+
+''' % (ADD_MSG, EDIT_MSG, DEL_MSG, MERGE_MSG),
+ '''
+
+ ''' % _('action|_Edit...') # to use sgettext()
+ ]
def get_handle_from_gramps_id(self, gid):
obj = self.dbstate.db.get_note_from_gramps_id(gid)
@@ -207,13 +323,13 @@ class NoteView(ListView):
else:
return None
- def add(self, obj):
+ def add(self, *obj):
try:
EditNote(self.dbstate, self.uistate, [], Note())
except WindowActiveError:
pass
- def remove(self, obj):
+ def remove(self, *obj):
self.remove_selected_objects()
def remove_object_from_handle(self, handle):
@@ -223,7 +339,7 @@ class NoteView(ListView):
is_used = any(the_lists)
return (query, is_used, object)
- def edit(self, obj):
+ def edit(self, *obj):
for handle in self.selected_handles():
note = self.dbstate.db.get_note_from_handle(handle)
try:
@@ -231,7 +347,7 @@ class NoteView(ListView):
except WindowActiveError:
pass
- def merge(self, obj):
+ def merge(self, *obj):
"""
Merge the selected notes.
"""
diff --git a/gramps/plugins/view/pedigreeview.py b/gramps/plugins/view/pedigreeview.py
index 6bb65d8d4..3529d3279 100644
--- a/gramps/plugins/view/pedigreeview.py
+++ b/gramps/plugins/view/pedigreeview.py
@@ -63,7 +63,6 @@ from gramps.gui.ddtargets import DdTargets
from gramps.gen.config import config
from gramps.gui.views.bookmarks import PersonBookmarks
from gramps.gen.const import CUSTOM_FILTERS
-from gramps.gen.constfunc import is_quartz, win
from gramps.gui.dialog import RunDatabaseRepair, ErrorDialog
from gramps.gui.utils import color_graph_box, hex_to_rgb_float, is_right_click
from gramps.gen.constfunc import lin
@@ -528,11 +527,6 @@ class PedigreeView(NavigationView):
NavigationView.__init__(self, _('Pedigree'), pdata, dbstate, uistate,
PersonBookmarks, nav_group)
- self.func_list.update({
- 'F2' : self.kb_goto_home,
- 'J' : self.jump,
- })
-
self.dbstate = dbstate
self.dbstate.connect('database-changed', self.change_db)
uistate.connect('nameformat-changed', self.person_rebuild)
@@ -551,7 +545,7 @@ class PedigreeView(NavigationView):
self.scrolledwindow = None
self.table = None
- self.additional_uis.append(self.additional_ui())
+ self.additional_uis.append(self.additional_ui)
# Automatic resize
self.force_size = self._config.get('interface.pedview-tree-size')
@@ -572,10 +566,6 @@ class PedigreeView(NavigationView):
self.show_unknown_people = self._config.get(
'interface.pedview-show-unknown-people')
- self.func_list.update({
- 'J' : self.jump,
- })
-
def get_handle_from_gramps_id(self, gid):
"""
returns the handle of the specified object
@@ -642,41 +632,91 @@ class PedigreeView(NavigationView):
return self.scrolledwindow
- def additional_ui(self):
- """
- Specifies the UIManager XML code that defines the menus and buttons
- associated with the interface.
- """
- return '''
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- '''
+ additional_ui = [ # Defines the UI string for UIManager
+ '''
+
+
+ -
+ win.Back
+ _Back
+
+ -
+ win.Forward
+ _Forward
+
+
+
+ -
+ win.HomePerson
+ _Home
+
+
+
+''',
+ '''
+
+ -
+ win.AddBook
+ _Add Bookmark
+
+ -
+ win.EditBook
+ %s...
+
+
+''' % _('Organize Bookmarks'),
+ '''
+
+ -
+ win.FilterEdit
+ '''
+ '''Person Filter Editor
+
+
+''', # Following are the Toolbar items
+ '''
+
+
+
+ go-previous
+ win.Back
+ '''
+ '''Go to the previous object in the history
+ _Back
+ True
+
+
+ False
+
+
+
+
+ go-next
+ win.Forward
+ '''
+ '''Go to the next object in the history
+ _Forward
+ True
+
+
+ False
+
+
+
+
+ go-home
+ win.HomePerson
+ '''
+ '''Go to the default person
+ _Home
+ True
+
+
+ False
+
+
+
+ ''']
def define_actions(self):
"""
@@ -693,10 +733,11 @@ class PedigreeView(NavigationView):
"""
NavigationView.define_actions(self)
- self._add_action('FilterEdit', None, _('Person Filter Editor'),
- callback=self.cb_filter_editor)
+ self._add_action('FilterEdit', self.cb_filter_editor)
+ self._add_action('F2', self.kb_goto_home, 'F2')
+ self._add_action('PRIMARY-J', self.jump, 'J')
- def cb_filter_editor(self, obj):
+ def cb_filter_editor(self, *obj):
"""
Display the person filter editor.
"""
@@ -1520,7 +1561,7 @@ class PedigreeView(NavigationView):
else:
self.scroll_direction = False
- def kb_goto_home(self):
+ def kb_goto_home(self, *obj):
"""Goto home person from keyboard."""
self.cb_home(None)
diff --git a/gramps/plugins/view/persontreeview.py b/gramps/plugins/view/persontreeview.py
index f13c39a17..bf7d93a0b 100644
--- a/gramps/plugins/view/persontreeview.py
+++ b/gramps/plugins/view/persontreeview.py
@@ -78,82 +78,28 @@ class PersonTreeView(BasePersonView):
"""
BasePersonView.define_actions(self)
- self.all_action.add_actions([
- ('OpenAllNodes', None, _("Expand all Nodes"), None, None,
- self.open_all_nodes),
- ('CloseAllNodes', None, _("Collapse all Nodes"), None, None,
- self.close_all_nodes),
- ])
+ self.action_list.extend([
+ ('OpenAllNodes', self.open_all_nodes),
+ ('CloseAllNodes', self.close_all_nodes)])
- def additional_ui(self):
- """
- Defines the UI string for UIManager
- """
- return '''
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- '''
+ additional_ui = BasePersonView.additional_ui[:]
+ additional_ui.append( # Defines the UI string for UIManager
+ '''
+
+ ''')
- def add(self, obj):
+ def add(self, *obj):
person = Person()
# attempt to get the current surname
diff --git a/gramps/plugins/view/placetreeview.py b/gramps/plugins/view/placetreeview.py
index 35d48d917..c6c650394 100644
--- a/gramps/plugins/view/placetreeview.py
+++ b/gramps/plugins/view/placetreeview.py
@@ -67,80 +67,39 @@ class PlaceTreeView(PlaceBaseView):
"""
PlaceBaseView.define_actions(self)
- self._add_action('OpenBranch', None, _("Expand this Entire Group"),
- callback=self.open_branch)
- self._add_action('CloseBranch', None, _("Collapse this Entire Group"),
- callback=self.close_branch)
- self._add_action('OpenAllNodes', None, _("Expand all Nodes"),
- callback=self.open_all_nodes)
- self._add_action('CloseAllNodes', None, _("Collapse all Nodes"),
- callback=self.close_all_nodes)
+ self._add_action('OpenBranch', self.open_branch)
+ self._add_action('CloseBranch', self.close_branch)
+ self._add_action('OpenAllNodes', self.open_all_nodes)
+ self._add_action('CloseAllNodes', self.close_all_nodes)
- def additional_ui(self):
- """
- A user interface definition including tree specific actions.
- """
- return '''
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- '''
+ additional_ui = PlaceBaseView.additional_ui[:]
+ additional_ui.append(
+ '''
+
+ ''')
- def add(self, obj):
+ def add(self, *obj):
"""
Add a new place. Use the currently selected rows as parent places.
"""
diff --git a/gramps/plugins/view/relview.py b/gramps/plugins/view/relview.py
index e752c3a59..3c5b5d87b 100644
--- a/gramps/plugins/view/relview.py
+++ b/gramps/plugins/view/relview.py
@@ -60,7 +60,7 @@ from gramps.gen.lib import (ChildRef, EventRoleType, EventType, Family,
from gramps.gen.lib.date import Today
from gramps.gen.db import DbTxn
from gramps.gui.views.navigationview import NavigationView
-from gramps.gui.actiongroup import ActionGroup
+from gramps.gui.uimanager import ActionGroup
from gramps.gui.editors import EditPerson, EditFamily
from gramps.gui.editors import FilterEditor
from gramps.gen.display.name import displayer as name_displayer
@@ -138,10 +138,6 @@ class RelationshipView(NavigationView):
PersonBookmarks,
nav_group)
- self.func_list.update({
- 'J' : self.jump,
- })
-
dbstate.connect('database-changed', self.change_db)
uistate.connect('nameformat-changed', self.build_tree)
uistate.connect('placeformat-changed', self.build_tree)
@@ -153,7 +149,7 @@ class RelationshipView(NavigationView):
self.reorder_sensitive = False
self.collapsed_items = {}
- self.additional_uis.append(self.additional_ui())
+ self.additional_uis.append(self.additional_ui)
self.show_siblings = self._config.get('preferences.family-siblings')
self.show_details = self._config.get('preferences.family-details')
@@ -335,102 +331,205 @@ class RelationshipView(NavigationView):
container.show_all()
return container
- def additional_ui(self):
- """
- Specifies the UIManager XML code that defines the menus and buttons
- associated with the interface.
- """
- return '''
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- '''
+ additional_ui = [ # Defines the UI string for UIManager
+ '''
+
+
+ -
+ win.Back
+ _Add Bookmark
+
+ -
+ win.Forward
+ '''
+ '''Organize Bookmarks...
+
+
+
+ -
+ win.HomePerson
+ _Home
+
+
+
+''',
+ '''
+
+ -
+ win.Edit
+ Edit...
+
+ -
+ win.AddParents
+ '''
+ '''Add New Parents...
+
+ -
+ win.ShareFamily
+ '''
+ '''Add Existing Parents...
+
+ -
+ win.AddSpouse
+ Add Partner...
+
+ -
+ win.ChangeOrder
+ _Reorder
+
+ -
+ win.FilterEdit
+ '''
+ '''Person Filter Editor
+
+
+''',
+ '''
+
+ -
+ win.AddBook
+ _Add Bookmark
+
+ -
+ win.EditBook
+ %s...
+
+
+''' % _('Organize Bookmarks'), # Following are the Toolbar items
+ '''
+
+
+
+ go-previous
+ win.Back
+ '''
+ '''Go to the previous object in the history
+ _Back
+ True
+
+
+ False
+
+
+
+
+ go-next
+ win.Forward
+ '''
+ '''Go to the next object in the history
+ _Forward
+ True
+
+
+ False
+
+
+
+
+ go-home
+ win.HomePerson
+ '''
+ '''Go to the default person
+ _Home
+ True
+
+
+ False
+
+
+
+''',
+ '''
+
+
+
+ gtk-edit
+ win.Edit
+ '''
+ '''Edit the active person
+ Edit...
+
+
+ False
+
+
+
+
+ gramps-parents-add
+ win.AddParents
+ '''
+ '''Add a new set of parents
+ Add
+
+
+ False
+
+
+
+
+ gramps-parents-open
+ win.ShareFamily
+ '''
+ '''Add person as child to an existing family
+ Share
+
+
+ False
+
+
+
+
+ gramps-spouse
+ win.AddSpouse
+ '''
+ '''Add a new family with person as parent
+ Partner
+
+
+ False
+
+
+
+
+ view-sort-ascending
+ win.ChangeOrder
+ '''
+ '''Change order of parents and families
+ _Reorder
+ True
+
+
+ False
+
+
+
+ ''']
def define_actions(self):
NavigationView.define_actions(self)
self.order_action = ActionGroup(name=self.title + '/ChangeOrder')
self.order_action.add_actions([
- ('ChangeOrder', 'view-sort-ascending', _('_Reorder'), None ,
- _("Change order of parents and families"), self.reorder),
- ])
+ ('ChangeOrder', self.reorder)])
self.family_action = ActionGroup(name=self.title + '/Family')
self.family_action.add_actions([
- ('Edit', 'gtk-edit', _('Edit...'), "Return",
- _("Edit the active person"), self.edit_active),
- ('AddSpouse', 'gramps-spouse', _('Partner'), None ,
- _("Add a new family with person as parent"), self.add_spouse),
- ('AddSpouseMenu', 'gramps-spouse', _('Add Partner...'), None ,
- _("Add a new family with person as parent"), self.add_spouse),
- ('AddParents', 'gramps-parents-add', _('Add'), None ,
- _("Add a new set of parents"), self.add_parents),
- ('AddParentsMenu', 'gramps-parents-add', _('Add New Parents...'),
- None, _("Add a new set of parents"), self.add_parents),
- ('ShareFamily', 'gramps-parents-open', _('Share'),
- None , _("Add person as child to an existing family"),
- self.select_parents),
- ('ShareFamilyMenu', 'gramps-parents-open',
- _('Add Existing Parents...'), None ,
- _("Add person as child to an existing family"),
- self.select_parents),
- ])
+ ('Edit', self.edit_active, "Return"),
+ ('AddSpouse', self.add_spouse),
+ ('AddParents', self.add_parents),
+ ('ShareFamily', self.select_parents)])
- self._add_action('FilterEdit', None, _('Person Filter Editor'),
- callback=self.filter_editor)
+ self._add_action('FilterEdit', callback=self.filter_editor)
+ self._add_action('PRIMARY-J', self.jump, 'J')
self._add_action_group(self.order_action)
self._add_action_group(self.family_action)
- self.order_action.set_sensitive(self.reorder_sensitive)
- self.family_action.set_sensitive(False)
+ self.uimanager.set_actions_sensitive(self.order_action,
+ self.reorder_sensitive)
+ self.uimanager.set_actions_sensitive(self.family_action, False)
- def filter_editor(self, obj):
+ def filter_editor(self, *obj):
try:
FilterEditor('Person', CUSTOM_FILTERS,
self.dbstate, self.uistate)
@@ -505,11 +604,11 @@ class RelationshipView(NavigationView):
if obj:
person = self.dbstate.db.get_person_from_handle(obj)
if not person:
- self.family_action.set_sensitive(False)
- self.order_action.set_sensitive(False)
+ self.uimanager.set_actions_sensitive(self.family_action, False)
+ self.uimanager.set_actions_sensitive(self.order_action, False)
self.redrawing = False
return
- self.family_action.set_sensitive(True)
+ self.uimanager.set_actions_sensitive(self.family_action, True)
self.write_title(person)
@@ -549,7 +648,8 @@ class RelationshipView(NavigationView):
self.redrawing = False
self.uistate.modify_statusbar(self.dbstate)
- self.order_action.set_sensitive(self.reorder_sensitive)
+ self.uimanager.set_actions_sensitive(self.order_action,
+ self.reorder_sensitive)
self.dirty = False
return True
@@ -1488,7 +1588,7 @@ class RelationshipView(NavigationView):
except WindowActiveError:
pass
- def add_spouse(self, obj):
+ def add_spouse(self, *obj):
family = Family()
person = self.dbstate.db.get_person_from_handle(self.get_active())
@@ -1505,7 +1605,7 @@ class RelationshipView(NavigationView):
except WindowActiveError:
pass
- def edit_active(self, obj):
+ def edit_active(self, obj, value):
phandle = self.get_active()
self.edit_person(obj, phandle)
@@ -1576,7 +1676,7 @@ class RelationshipView(NavigationView):
self.dbstate.db.add_child_to_family(family, child)
- def select_parents(self, obj):
+ def select_parents(self, *obj):
SelectFamily = SelectorFactory('Family')
phandle = self.get_active()
@@ -1592,7 +1692,7 @@ class RelationshipView(NavigationView):
self.dbstate.db.add_child_to_family(family, child)
- def add_parents(self, obj):
+ def add_parents(self, *obj):
family = Family()
person = self.dbstate.db.get_person_from_handle(self.get_active())
@@ -1637,7 +1737,7 @@ class RelationshipView(NavigationView):
if button_activated(event, _LEFT_BUTTON):
self.reorder(obj)
- def reorder(self, obj, dumm1=None, dummy2=None):
+ def reorder(self, *obj):
if self.get_active():
try:
Reorder(self.dbstate, self.uistate, [], self.get_active())
diff --git a/gramps/plugins/view/repoview.py b/gramps/plugins/view/repoview.py
index 47b546f47..204452323 100644
--- a/gramps/plugins/view/repoview.py
+++ b/gramps/plugins/view/repoview.py
@@ -53,7 +53,7 @@ from gramps.gen.plug import CATEGORY_QR_REPOSITORY
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
-_ = glocale.translation.gettext
+_ = glocale.translation.sgettext
#-------------------------------------------------------------------------
@@ -132,12 +132,7 @@ class RepositoryView(ListView):
multiple=True,
filter_class=RepoSidebarFilter)
- self.func_list.update({
- 'J' : self.jump,
- 'BackSpace' : self.key_delete,
- })
-
- self.additional_uis.append(self.additional_ui())
+ self.additional_uis.append(self.additional_ui)
def navigation_type(self):
return 'Repository'
@@ -145,76 +140,199 @@ class RepositoryView(ListView):
def drag_info(self):
return DdTargets.REPO_LINK
- def define_actions(self):
- ListView.define_actions(self)
- self._add_action('FilterEdit', None, _('Repository Filter Editor'),
- callback=self.filter_editor,)
- self._add_action('QuickReport', None,
- _("Quick View"), None, None, None)
-
def get_stock(self):
return 'gramps-repository'
- def additional_ui(self):
- return '''
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- '''
+ additional_ui = [ # Defines the UI string for UIManager
+ '''
+
+ -
+ win.ExportTab
+ Export View...
+
+
+''',
+ '''
+
+ -
+ win.AddBook
+ _Add Bookmark
+
+ -
+ win.EditBook
+ %s...
+
+
+''' % _('Organize Bookmarks'),
+ '''
+
+
+ -
+ win.Back
+ _Back
+
+ -
+ win.Forward
+ _Forward
+
+
+
+''',
+ '''
+
+ -
+ win.Add
+ _Add...
+
+ -
+ win.Edit
+ %s
+
+ -
+ win.Remove
+ _Delete
+
+ -
+ win.Merge
+ _Merge...
+
+
+''' % _("action|_Edit..."), # to use sgettext()
+ '''
+
+ -
+ win.FilterEdit
+ '''
+ '''Repository Filter Editor
+
+
+''', # Following are the Toolbar items
+ '''
+
+
+
+ go-previous
+ win.Back
+ '''
+ '''Go to the previous object in the history
+ _Back
+ True
+
+
+ False
+
+
+
+
+ go-next
+ win.Forward
+ '''
+ '''Go to the next object in the history
+ _Forward
+ True
+
+
+ False
+
+
+
+''',
+ '''
+
+
+
+ list-add
+ win.Add
+ %s
+ _Add...
+ True
+
+
+ False
+
+
+
+
+ gtk-edit
+ win.Edit
+ %s
+ Edit...
+ True
+
+
+ False
+
+
+
+
+ list-remove
+ win.Remove
+ %s
+ _Delete
+ True
+
+
+ False
+
+
+
+
+ gramps-merge
+ win.Merge
+ %s
+ _Merge...
+ True
+
+
+ False
+
+
+
+''' % (ADD_MSG, EDIT_MSG, DEL_MSG, MERGE_MSG),
+ '''
+
+ ''' % _('action|_Edit...') # to use sgettext()
+ ]
- def add(self, obj):
+ def add(self, *obj):
EditRepository(self.dbstate, self.uistate, [], Repository())
- def remove(self, obj):
+ def remove(self, *obj):
self.remove_selected_objects()
def remove_object_from_handle(self, handle):
@@ -227,7 +345,7 @@ class RepositoryView(ListView):
is_used = len(source_list) > 0
return (query, is_used, object)
- def edit(self, obj):
+ def edit(self, *obj):
for handle in self.selected_handles():
repos = self.dbstate.db.get_repository_from_handle(handle)
try:
@@ -235,7 +353,7 @@ class RepositoryView(ListView):
except WindowActiveError:
pass
- def merge(self, obj):
+ def merge(self, *obj):
"""
Merge the selected repositories.
"""
diff --git a/gramps/plugins/view/sourceview.py b/gramps/plugins/view/sourceview.py
index 858c6a97b..c34ccabc9 100644
--- a/gramps/plugins/view/sourceview.py
+++ b/gramps/plugins/view/sourceview.py
@@ -57,7 +57,7 @@ from gramps.gen.plug import CATEGORY_QR_SOURCE
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
-_ = glocale.translation.gettext
+_ = glocale.translation.sgettext
#-------------------------------------------------------------------------
@@ -118,12 +118,7 @@ class SourceView(ListView):
multiple=True,
filter_class=SourceSidebarFilter)
- self.func_list.update({
- 'J' : self.jump,
- 'BackSpace' : self.key_delete,
- })
-
- self.additional_uis.append(self.additional_ui())
+ self.additional_uis.append(self.additional_ui)
def navigation_type(self):
return 'Source'
@@ -131,75 +126,199 @@ class SourceView(ListView):
def drag_info(self):
return DdTargets.SOURCE_LINK
- def define_actions(self):
- ListView.define_actions(self)
- self._add_action('FilterEdit', None, _('Source Filter Editor'),
- callback=self.filter_editor,)
- self._add_action('QuickReport', None, _("Quick View"), None, None, None)
-
def get_stock(self):
return 'gramps-source'
- def additional_ui(self):
- return '''
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- '''
+ additional_ui = [ # Defines the UI string for UIManager
+ '''
+
+ -
+ win.ExportTab
+ Export View...
+
+
+''',
+ '''
+
+ -
+ win.AddBook
+ _Add Bookmark
+
+ -
+ win.EditBook
+ %s...
+
+
+''' % _('Organize Bookmarks'),
+ '''
+
+
+ -
+ win.Back
+ _Back
+
+ -
+ win.Forward
+ _Forward
+
+
+
+''',
+ '''
+
+ -
+ win.Add
+ _Add...
+
+ -
+ win.Edit
+ %s
+
+ -
+ win.Remove
+ _Delete
+
+ -
+ win.Merge
+ _Merge...
+
+
+''' % _("action|_Edit..."), # to use sgettext()
+ '''
+
+ -
+ win.FilterEdit
+ '''
+ '''Source Filter Editor
+
+
+''', # Following are the Toolbar items
+ '''
+
+
+
+ go-previous
+ win.Back
+ '''
+ '''Go to the previous object in the history
+ _Back
+ True
+
+
+ False
+
+
+
+
+ go-next
+ win.Forward
+ '''
+ '''Go to the next object in the history
+ _Forward
+ True
+
+
+ False
+
+
+
+''',
+ '''
+
+
+
+ list-add
+ win.Add
+ %s
+ _Add...
+ True
+
+
+ False
+
+
+
+
+ gtk-edit
+ win.Edit
+ %s
+ Edit...
+ True
+
+
+ False
+
+
+
+
+ list-remove
+ win.Remove
+ %s
+ _Delete
+ True
+
+
+ False
+
+
+
+
+ gramps-merge
+ win.Merge
+ %s
+ _Merge...
+ True
+
+
+ False
+
+
+
+''' % (ADD_MSG, EDIT_MSG, DEL_MSG, MERGE_MSG),
+ '''
+
+ ''' % _('action|_Edit...') # to use sgettext()
+ ]
- def add(self, obj):
+ def add(self, *obj):
EditSource(self.dbstate, self.uistate, [], Source())
- def remove(self, obj):
+ def remove(self, *obj):
self.remove_selected_objects()
def remove_object_from_handle(self, handle):
@@ -211,7 +330,7 @@ class SourceView(ListView):
is_used = any(the_lists)
return (query, is_used, object)
- def edit(self, obj):
+ def edit(self, *obj):
for handle in self.selected_handles():
source = self.dbstate.db.get_source_from_handle(handle)
try:
@@ -219,7 +338,7 @@ class SourceView(ListView):
except WindowActiveError:
pass
- def merge(self, obj):
+ def merge(self, *obj):
"""
Merge the selected sources.
"""
diff --git a/mac/gramps.accel b/mac/gramps.accel
index d4bdbc9a8..13556f181 100644
--- a/mac/gramps.accel
+++ b/mac/gramps.accel
@@ -1,149 +1,85 @@
-; Gramps.py GtkAccelMap rc-file -*- scheme -*-
-; this file is an automated accelerator map dump
-;
-; (gtk_accel_path "/ToolWindow/relcalc" "")
-; (gtk_accel_path "/ReportWindow/place_report" "")
-; (gtk_accel_path "/ToolWindow/mediaman" "")
- (gtk_accel_path "/MainWindow/SourceAdd" "s")
-; (gtk_accel_path "/ReportWindow/summary" "")
-; (gtk_accel_path "/ToolWindow/rebuild_refmap" "")
-; (gtk_accel_path "/Redo/Redo" "z")
-; (gtk_accel_path "/ToolWindow/ToolAnExp" "")
-; (gtk_accel_path "/FileWindow/Toolbar" "")
-; (gtk_accel_path "/ToolWindow/editowner" "")
-; (gtk_accel_path "/FileWindow/Preferences" "")
- (gtk_accel_path "/MainWindow/MediaAdd" "m")
-; (gtk_accel_path "/ToolWindow/sortevents" "")
-; (gtk_accel_path "/AllMainWindow/Delete" "Delete")
-; (gtk_accel_path "/FileWindow/ReportBug" "")
-; (gtk_accel_path "/ReportWindow/hourglass_graph" "")
-; (gtk_accel_path "/Undo/Undo" "z")
-; (gtk_accel_path "/ToolWindow/reorder_ids" "")
-; (gtk_accel_path "/ReportWindow/rel_graph" "")
-; (gtk_accel_path "/MainWindow/ConfigView" "c")
-; (gtk_accel_path "/ReportWindow/descend_report" "")
-; (gtk_accel_path "/ReportWindow/ancestor_chart" "")
-; (gtk_accel_path "/MainWindow/Clipboard" "b")
-; (gtk_accel_path "/FileWindow/MailingLists" "")
-; (gtk_accel_path "