Make the tab columns resizable: PersistentTreeView

Implements #8767
This commit is contained in:
SNoiraud 2021-10-30 19:18:46 +02:00 committed by Nick Hall
parent 37395da262
commit c7b1a23441
65 changed files with 472 additions and 32 deletions

View File

@ -59,6 +59,7 @@ from .ddtargets import DdTargets
from .makefilter import make_filter from .makefilter import make_filter
from .utils import is_right_click, no_match_primary_mask from .utils import is_right_click, no_match_primary_mask
from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.const import GRAMPS_LOCALE as glocale
from gramps.gui.widgets.persistenttreeview import PersistentTreeView
_ = glocale.translation.sgettext _ = glocale.translation.sgettext
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -1412,6 +1413,7 @@ class ClipboardWindow(ManagedWindow):
self.db.connect('database-changed', self.db.connect('database-changed',
lambda x: ClipboardWindow.otree.clear()) lambda x: ClipboardWindow.otree.clear())
mtv.restore_column_size()
self.show() self.show()
def build_menu_names(self, obj): def build_menu_names(self, obj):
@ -1453,7 +1455,7 @@ class ClipboardWindow(ManagedWindow):
# MultiTreeView class # MultiTreeView class
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
class MultiTreeView(Gtk.TreeView): class MultiTreeView(PersistentTreeView):
''' '''
TreeView that captures mouse events to make drag and drop work properly TreeView that captures mouse events to make drag and drop work properly
''' '''
@ -1461,7 +1463,7 @@ class MultiTreeView(Gtk.TreeView):
self.dbstate = dbstate self.dbstate = dbstate
self.uistate = uistate self.uistate = uistate
self.title = title if title else _("Clipboard") self.title = title if title else _("Clipboard")
Gtk.TreeView.__init__(self) PersistentTreeView.__init__(self, self.uistate, "clipboard")
self.connect('button_press_event', self.on_button_press) self.connect('button_press_event', self.on_button_press)
self.connect('button_release_event', self.on_button_release) self.connect('button_release_event', self.on_button_release)
self.connect('drag-end', self.on_drag_end) self.connect('drag-end', self.on_drag_end)

View File

@ -63,7 +63,8 @@ class ColumnOrder(Gtk.Box):
Column ordering selection widget Column ordering selection widget
""" """
def __init__(self, config, column_names, widths, on_apply, tree=False): def __init__(self, config, column_names, widths, on_apply, tree=False,
resizable=None):
""" """
Create the Column Ordering widget based on config Create the Column Ordering widget based on config
@ -80,6 +81,7 @@ class ColumnOrder(Gtk.Box):
self.colnames = column_names self.colnames = column_names
self.config = config self.config = config
self.on_apply = on_apply self.on_apply = on_apply
self.resizable = resizable
self.pack_start(Gtk.Label(label=' '), False, False, 0) self.pack_start(Gtk.Label(label=' '), False, False, 0)
@ -137,7 +139,23 @@ class ColumnOrder(Gtk.Box):
#obtain the columns from config file #obtain the columns from config file
self.oldorder = self.config.get('columns.rank') self.oldorder = self.config.get('columns.rank')
self.oldsize = self.config.get('columns.size') oldsize = self.config.get('columns.size')
# try to use the current columns size.
if resizable:
self.oldsize = []
newsize = self.resizable.get_columns_size()
nbc = 0
for size in oldsize:
if nbc < len(newsize):
if newsize[nbc] == 0:
self.oldsize.append(size)
else:
self.oldsize.append(newsize[nbc])
else:
self.oldsize.append(size)
nbc += 1
else:
self.oldsize = oldsize
self.oldvis = self.config.get('columns.visible') self.oldvis = self.config.get('columns.visible')
colord = [] colord = []
index = 0 index = 0
@ -185,6 +203,7 @@ class ColumnOrder(Gtk.Box):
self.config.set('columns.visible', newvis) self.config.set('columns.visible', newvis)
self.config.save() self.config.save()
self.on_apply() self.on_apply()
self.resizable.save_column_info()
def toggled(cell, path, model): def toggled(cell, path, model):
""" """

View File

@ -69,6 +69,7 @@ from .listmodel import ListModel
from gramps.gen.constfunc import win from gramps.gen.constfunc import win
from gramps.gen.plug import BasePluginManager from gramps.gen.plug import BasePluginManager
from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.const import GRAMPS_LOCALE as glocale
from gramps.gui.widgets.persistenttreeview import PersistentTreeView
_ = glocale.translation.gettext _ = glocale.translation.gettext
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -170,7 +171,7 @@ class DbManager(CLIDbManager, ManagedWindow):
self.viewmanager = viewmanager self.viewmanager = viewmanager
for attr in ['connect_btn', 'cancel_btn', 'new_btn', 'remove_btn', for attr in ['connect_btn', 'cancel_btn', 'new_btn', 'remove_btn',
'info_btn', 'dblist', 'rename_btn', 'convert_btn', 'info_btn', 'rename_btn', 'convert_btn',
'repair_btn', 'rcs_btn', 'msg', 'close_btn']: 'repair_btn', 'rcs_btn', 'msg', 'close_btn']:
setattr(self, attr, self.glade.get_object(attr)) setattr(self, attr, self.glade.get_object(attr))
@ -179,6 +180,11 @@ class DbManager(CLIDbManager, ManagedWindow):
self.lock_file = None self.lock_file = None
self.data_to_delete = None self.data_to_delete = None
objectlist = self.glade.get_object('dblist')
self.dblist = PersistentTreeView(uistate, "dbman")
scrolledwindow = self.glade.get_object('scrolledwindow88')
scrolledwindow.remove(objectlist)
scrolledwindow.add(self.dblist)
self.selection = self.dblist.get_selection() self.selection = self.dblist.get_selection()
# For already loaded database: # For already loaded database:
@ -410,6 +416,7 @@ class DbManager(CLIDbManager, ManagedWindow):
column = Gtk.TreeViewColumn(_('Last accessed'), render, text=DATE_COL) column = Gtk.TreeViewColumn(_('Last accessed'), render, text=DATE_COL)
column.set_sort_column_id(DSORT_COL) column.set_sort_column_id(DSORT_COL)
self.dblist.append_column(column) self.dblist.append_column(column)
self.dblist.restore_column_size()
def __populate(self): def __populate(self):
""" """

View File

@ -148,3 +148,6 @@ class AddrEmbedList(EmbeddedList):
Called to update the screen when the address changes Called to update the screen when the address changes
""" """
self.rebuild() self.rebuild()
def get_config_name(self):
return __name__

View File

@ -123,3 +123,6 @@ class AttrEmbedList(EmbeddedList):
def edit_callback(self, name): def edit_callback(self, name):
self.changed = True self.changed = True
self.rebuild() self.rebuild()
def get_config_name(self):
return __name__

View File

@ -143,3 +143,6 @@ class BackRefList(EmbeddedList):
def edit_button_clicked(self, obj): def edit_button_clicked(self, obj):
(reftype, ref) = self.find_node() (reftype, ref) = self.find_node()
edit_object(self.dbstate, self.uistate, reftype, ref) edit_object(self.dbstate, self.uistate, reftype, ref)
def get_config_name(self):
return __name__

View File

@ -283,3 +283,6 @@ class CitationEmbedList(EmbeddedList, DbGUIElement):
parent=self.uistate.window) parent=self.uistate.window)
else: else:
raise ValueError("selection must be either source or citation") raise ValueError("selection must be either source or citation")
def get_config_name(self):
return __name__

View File

@ -43,6 +43,7 @@ from gi.repository import Pango
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from ...widgets.cellrenderertextedit import CellRendererTextEdit from ...widgets.cellrenderertextedit import CellRendererTextEdit
from ...widgets.persistenttreeview import PersistentTreeView
from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext _ = glocale.translation.gettext
from ...utils import is_right_click from ...utils import is_right_click
@ -388,7 +389,8 @@ class EmbeddedList(ButtonTab):
# create the tree, turn on rule hinting and connect the # create the tree, turn on rule hinting and connect the
# button press to the double click function. # button press to the double click function.
self.tree = Gtk.TreeView() _name = self.get_config_name()
self.tree = PersistentTreeView(self.uistate, _name)
self.tree.set_reorderable(True) self.tree.set_reorderable(True)
self.tree.connect('button_press_event', self.double_click) self.tree.connect('button_press_event', self.double_click)
self.tree.connect('key_press_event', self.key_pressed) self.tree.connect('key_press_event', self.key_pressed)
@ -533,6 +535,12 @@ class EmbeddedList(ButtonTab):
self.columns.append(column) self.columns.append(column)
self.tree.append_column(column) self.tree.append_column(column)
self.track_ref_for_deletion("columns") self.track_ref_for_deletion("columns")
self.tree.restore_column_size()
def get_config_name(self):
""" used to associate the selector config name to the PersistentTreeView
"""
assert False, "Must be defined in the subclass"
def icon_func(self, column, renderer, model, iter_, col_num): def icon_func(self, column, renderer, model, iter_, col_num):
''' '''

View File

@ -41,3 +41,6 @@ class EventAttrEmbedList(AttrEmbedList):
def get_user_values(self): def get_user_values(self):
return self.dbstate.db.get_event_attribute_types() return self.dbstate.db.get_event_attribute_types()
def get_config_name(self):
return __name__

View File

@ -419,3 +419,6 @@ class EventEmbedList(DbGUIElement, GroupEmbeddedList):
self.tree.expand_all() self.tree.expand_all()
if prebuildpath is not None: if prebuildpath is not None:
self.selection.select_path(prebuildpath) self.selection.select_path(prebuildpath)
def get_config_name(self):
return __name__

View File

@ -41,3 +41,6 @@ class FamilyAttrEmbedList(AttrEmbedList):
def get_user_values(self): def get_user_values(self):
return self.dbstate.db.get_family_attribute_types() return self.dbstate.db.get_family_attribute_types()
def get_config_name(self):
return __name__

View File

@ -68,3 +68,6 @@ class FamilyLdsEmbedList(LdsEmbedList):
lds = LdsOrd() lds = LdsOrd()
lds.set_type(LdsOrd.SEAL_TO_SPOUSE) lds.set_type(LdsOrd.SEAL_TO_SPOUSE)
return lds return lds
def get_config_name(self):
return __name__

View File

@ -400,3 +400,6 @@ class GroupEmbeddedList(EmbeddedList):
self._move_down(pos, ref[1]) self._move_down(pos, ref[1])
elif ref and ref[1] is None: elif ref and ref[1] is None:
self._move_down_group(ref[0]) self._move_down_group(ref[0])
def get_config_name(self):
assert False, "Must be defined in the subclass"

View File

@ -109,3 +109,6 @@ class LdsEmbedList(EmbeddedList):
def edit_callback(self, name): def edit_callback(self, name):
self.rebuild() self.rebuild()
def get_config_name(self):
return __name__

View File

@ -98,3 +98,6 @@ class LocationEmbedList(EmbeddedList):
def edit_callback(self, name): def edit_callback(self, name):
self.rebuild() self.rebuild()
def get_config_name(self):
return __name__

View File

@ -41,3 +41,6 @@ class MediaAttrEmbedList(AttrEmbedList):
def get_user_values(self): def get_user_values(self):
return self.dbstate.db.get_media_attribute_types() return self.dbstate.db.get_media_attribute_types()
def get_config_name(self):
return __name__

View File

@ -221,3 +221,6 @@ class NameEmbedList(GroupEmbeddedList):
self.tree.expand_all() self.tree.expand_all()
if prebuildpath is not None: if prebuildpath is not None:
self.selection.select_path(prebuildpath) self.selection.select_path(prebuildpath)
def get_config_name(self):
return __name__

View File

@ -208,3 +208,6 @@ class NoteTab(EmbeddedList, DbGUIElement):
if handle in self.data: if handle in self.data:
self.rebuild() self.rebuild()
break break
def get_config_name(self):
return __name__

View File

@ -190,3 +190,6 @@ class PersonEventEmbedList(EventEmbedList):
path = (index + 2,) path = (index + 2,)
self.tree.get_selection().select_path(path) self.tree.get_selection().select_path(path)
GLib.idle_add(self.tree.scroll_to_cell, path) GLib.idle_add(self.tree.scroll_to_cell, path)
def get_config_name(self):
return __name__

View File

@ -197,3 +197,6 @@ class PersonRefEmbedList(DbGUIElement, EmbeddedList):
ref, self.add_callback) ref, self.add_callback)
except WindowActiveError: except WindowActiveError:
pass pass
def get_config_name(self):
return __name__

View File

@ -116,3 +116,6 @@ class PlaceNameEmbedList(EmbeddedList):
Called to update the screen when the place name changes. Called to update the screen when the place name changes.
""" """
self.rebuild() self.rebuild()
def get_config_name(self):
return __name__

View File

@ -199,3 +199,6 @@ class PlaceRefEmbedList(DbGUIElement, EmbeddedList):
place, placeref, self.add_callback) place, placeref, self.add_callback)
except WindowActiveError: except WindowActiveError:
pass pass
def get_config_name(self):
return __name__

View File

@ -214,3 +214,6 @@ class RepoEmbedList(EmbeddedList, DbGUIElement):
if handle in ref_handles: if handle in ref_handles:
self.rebuild() self.rebuild()
break break
def get_config_name(self):
return __name__

View File

@ -159,3 +159,6 @@ class SrcAttrEmbedList(EmbeddedList):
def edit_callback(self, name): def edit_callback(self, name):
self.changed = True self.changed = True
self.rebuild() self.rebuild()
def get_config_name(self):
return __name__

View File

@ -410,3 +410,6 @@ class SurnameTab(EmbeddedList):
self.curr_celle.editing_done() self.curr_celle.editing_done()
return return
return True return True
def get_config_name(self):
return __name__

View File

@ -124,3 +124,6 @@ class WebEmbedList(EmbeddedList):
url = self.get_selected() url = self.get_selected()
if url.get_path(): if url.get_path():
display_url(url.get_path()) display_url(url.get_path())
def get_config_name(self):
return __name__

View File

@ -367,6 +367,9 @@ class ChildEmbedList(DbGUIElement, EmbeddedList):
else: else:
return name return name
def get_config_name(self):
return __name__
class FastMaleFilter: class FastMaleFilter:
def __init__(self, db): def __init__(self, db):
@ -1275,6 +1278,9 @@ class EditFamily(EditPrimary):
return name return name
return name return name
def get_config_name(self):
return __name__
def button_activated(event, mouse_button): def button_activated(event, mouse_button):
if (event.type == Gdk.EventType.BUTTON_PRESS and if (event.type == Gdk.EventType.BUTTON_PRESS and
event.button == mouse_button) or \ event.button == mouse_button) or \

View File

@ -74,6 +74,7 @@ from gramps.gen.utils.string import conf_strings
from ..widgets import DateEntry from ..widgets import DateEntry
from gramps.gen.datehandler import displayer from gramps.gen.datehandler import displayer
from gramps.gen.config import config from gramps.gen.config import config
from gramps.gui.widgets.persistenttreeview import PersistentTreeView
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -456,10 +457,15 @@ class EditRule(ManagedWindow):
self.window.hide() self.window.hide()
self.valuebox = self.get_widget('valuebox') self.valuebox = self.get_widget('valuebox')
self.rname_filter = self.get_widget('ruletreefilter') self.rname_filter = self.get_widget('ruletreefilter')
self.rname = self.get_widget('ruletree')
self.rule_name = self.get_widget('rulename') self.rule_name = self.get_widget('rulename')
self.description = self.get_widget('description') self.description = self.get_widget('description')
objectlist = self.get_widget('ruletree')
self.rname = PersistentTreeView(uistate, "filt_edit")
scrolledwindow = self.get_widget('box2')
scrolledwindow.remove(objectlist)
scrolledwindow.add(self.rname)
self.notebook = Gtk.Notebook() self.notebook = Gtk.Notebook()
self.notebook.set_show_tabs(0) self.notebook.set_show_tabs(0)
self.notebook.set_show_border(0) self.notebook.set_show_border(0)
@ -697,6 +703,7 @@ class EditRule(ManagedWindow):
config.register('interface.edit-rule-pane', 205) config.register('interface.edit-rule-pane', 205)
panepos = config.get('interface.edit-rule-pane') panepos = config.get('interface.edit-rule-pane')
self.get_widget('hpaned1').set_position(panepos) self.get_widget('hpaned1').set_position(panepos)
self.rname.restore_column_size()
self.show() self.show()
def select_iter(self, data): def select_iter(self, data):
@ -831,8 +838,14 @@ class EditFilter(ManagedWindow):
_('Define filter')) _('Define filter'))
self.setup_configs('interface.edit-filter', 500, 420) self.setup_configs('interface.edit-filter', 500, 420)
objectlist = self.get_widget('rule_list')
self.rule_list = PersistentTreeView(uistate, "filt_rule")
scrolledwindow = self.get_widget('scrolledwindow1')
scrolledwindow.remove(objectlist)
scrolledwindow.add(self.rule_list)
self.rlist = ListModel( self.rlist = ListModel(
self.get_widget('rule_list'), self.rule_list,
[(_('Name'),-1,150),(_('Values'),-1,150)], [(_('Name'),-1,150),(_('Values'),-1,150)],
self.select_row, self.select_row,
self.on_edit_clicked) self.on_edit_clicked)
@ -867,6 +880,7 @@ class EditFilter(ManagedWindow):
self.draw_rules() self.draw_rules()
self._set_size() self._set_size()
self.rule_list.restore_column_size()
self.show() self.show()
def on_help_clicked(self, obj): def on_help_clicked(self, obj):
@ -1089,7 +1103,6 @@ class FilterEditor(ManagedWindow):
self.namespace = namespace self.namespace = namespace
self.define_glade('filter_list', RULE_GLADE) self.define_glade('filter_list', RULE_GLADE)
self.filter_list = self.get_widget('filters')
self.edit = self.get_widget('filter_list_edit') self.edit = self.get_widget('filter_list_edit')
self.clone = self.get_widget('filter_list_clone') self.clone = self.get_widget('filter_list_clone')
self.delete = self.get_widget('filter_list_delete') self.delete = self.get_widget('filter_list_delete')
@ -1100,6 +1113,12 @@ class FilterEditor(ManagedWindow):
self.delete.set_sensitive(False) self.delete.set_sensitive(False)
self.test.set_sensitive(False) self.test.set_sensitive(False)
objectlist = self.get_widget('filters')
self.filter_list = PersistentTreeView(self.uistate, "filt_list")
scrolledwindow = self.get_widget('scrolledwindow2')
scrolledwindow.remove(objectlist)
scrolledwindow.add(self.filter_list)
self.set_window(self.get_widget('filter_list'), self.set_window(self.get_widget('filter_list'),
self.get_widget('filter_list_title'), self.get_widget('filter_list_title'),
_TITLES[self.namespace]) _TITLES[self.namespace])
@ -1123,6 +1142,7 @@ class FilterEditor(ManagedWindow):
self.edit_filter) self.edit_filter)
self.draw_filters() self.draw_filters()
self._set_size() self._set_size()
self.filter_list.restore_column_size()
self.show() self.show()
def build_menu_names(self, obj): def build_menu_names(self, obj):

View File

@ -2,6 +2,7 @@
<!-- Generated with glade 3.18.3 --> <!-- Generated with glade 3.18.3 -->
<interface> <interface>
<requires lib="gtk+" version="3.10"/> <requires lib="gtk+" version="3.10"/>
<requires lib="grampswidgets" version="0.0"/>
<object class="GtkDialog" id="baseselector"> <object class="GtkDialog" id="baseselector">
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="modal">True</property> <property name="modal">True</property>
@ -100,7 +101,7 @@
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="shadow_type">in</property> <property name="shadow_type">in</property>
<child> <child>
<object class="GtkTreeView" id="plist"> <object class="PersistentTreeView" id="plist">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="fixed_height_mode">True</property> <property name="fixed_height_mode">True</property>

View File

@ -33,3 +33,6 @@ class StyledTextEditor(Gtk.TextView):
class UndoableBuffer(Gtk.TextBuffer): class UndoableBuffer(Gtk.TextBuffer):
__gtype_name__ = 'UndoableBuffer' __gtype_name__ = 'UndoableBuffer'
class PersistentTreeView(Gtk.TreeView):
__gtype_name__ = 'PersistentTreeView'

View File

@ -15,10 +15,15 @@
name="StyledTextEditor" name="StyledTextEditor"
title="Styled Text Editor" title="Styled Text Editor"
generic-name="styled_text"/> generic-name="styled_text"/>
<glade-widget-class
name="PersistentTreeView"
title="Persistent TreeView"
generic-name="resizable_treeview"/>
</glade-widget-classes> </glade-widget-classes>
<glade-widget-group name="GrampsWidgets" title="Gramps Widgets"> <glade-widget-group name="GrampsWidgets" title="Gramps Widgets">
<glade-widget-class-ref name="ValidatableMaskedEntry"/> <glade-widget-class-ref name="ValidatableMaskedEntry"/>
<glade-widget-class-ref name="UndoableEntry"/> <glade-widget-class-ref name="UndoableEntry"/>
<glade-widget-class-ref name="StyledTextEditor"/> <glade-widget-class-ref name="StyledTextEditor"/>
<glade-widget-class-ref name="PersistentTreeView"/>
</glade-widget-group> </glade-widget-group>
</glade-catalog> </glade-catalog>

View File

@ -97,7 +97,7 @@
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="shadow_type">in</property> <property name="shadow_type">in</property>
<child> <child>
<object class="GtkTreeView" id="objectlist"> <object class="PersistentTreeView" id="objectlist">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<child internal-child="selection"> <child internal-child="selection">

View File

@ -185,7 +185,7 @@
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="shadow_type">in</property> <property name="shadow_type">in</property>
<child> <child>
<object class="GtkTreeView" id="dblist"> <object class="PersistentTreeView" id="dblist">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="hexpand">True</property> <property name="hexpand">True</property>

View File

@ -91,7 +91,7 @@
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="shadow_type">in</property> <property name="shadow_type">in</property>
<child> <child>
<object class="GtkTreeView" id="filters"> <object class="PersistentTreeView" id="filters">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<child internal-child="selection"> <child internal-child="selection">
@ -581,7 +581,7 @@
<property name="margin_left">6</property> <property name="margin_left">6</property>
<property name="shadow_type">in</property> <property name="shadow_type">in</property>
<child> <child>
<object class="GtkTreeView" id="rule_list"> <object class="PersistentTreeView" id="rule_list">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="hexpand">True</property> <property name="hexpand">True</property>
@ -855,7 +855,7 @@
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkTreeView" id="ruletree"> <object class="PersistentTreeView" id="ruletree">
<property name="width_request">250</property> <property name="width_request">250</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>

View File

@ -219,7 +219,8 @@ class ListModel:
column.set_sort_column_id(name[1]) column.set_sort_column_id(name[1])
column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
column.set_fixed_width(name[2]) # removed since we have a PersistentTreeView
# column.set_fixed_width(name[2])
cnum += 1 cnum += 1
self.cids.append(name[1]) self.cids.append(name[1])

View File

@ -38,6 +38,7 @@ from ..glade import Glade
from ..widgets.interactivesearchbox import InteractiveSearchBox from ..widgets.interactivesearchbox import InteractiveSearchBox
from ..display import display_help from ..display import display_help
from gramps.gen.const import URL_MANUAL_PAGE from gramps.gen.const import URL_MANUAL_PAGE
from gramps.gui.widgets.persistenttreeview import PersistentTreeView
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -83,7 +84,12 @@ class BaseSelector(ManagedWindow):
self.showall = self.glade.get_object('showall') self.showall = self.glade.get_object('showall')
title_label = self.glade.get_object('title') title_label = self.glade.get_object('title')
vbox = self.glade.get_object('select_person_vbox') vbox = self.glade.get_object('select_person_vbox')
self.tree = self.glade.get_object('plist') objectlist = self.glade.get_object('plist')
_name = self.get_config_name()
self.tree = PersistentTreeView(self.uistate, _name)
scrolledwindow = self.glade.get_object('scrolledwindow33')
scrolledwindow.remove(objectlist)
scrolledwindow.add(self.tree)
self.tree.set_headers_visible(True) self.tree.set_headers_visible(True)
self.tree.set_headers_clickable(True) self.tree.set_headers_clickable(True)
self.tree.connect('row-activated', self._on_row_activated) self.tree.connect('row-activated', self._on_row_activated)
@ -298,6 +304,7 @@ class BaseSelector(ManagedWindow):
search=filter_info) search=filter_info)
self.tree.set_model(self.model) self.tree.set_model(self.model)
self.tree.restore_column_size()
#sorting arrow in column header (not on start, only on click) #sorting arrow in column header (not on start, only on click)
if not self.setupcols : if not self.setupcols :
@ -314,6 +321,9 @@ class BaseSelector(ManagedWindow):
if sel: if sel:
self.goto_handle(sel) self.goto_handle(sel)
def get_config_name(self):
assert False, "Must be defined in the subclass"
def column_clicked(self, obj, data): def column_clicked(self, obj, data):
if self.sort_col != data: if self.sort_col != data:
self.sortorder = Gtk.SortType.ASCENDING self.sortorder = Gtk.SortType.ASCENDING
@ -336,6 +346,7 @@ class BaseSelector(ManagedWindow):
sort_map=self.column_order(), skip=self.skip_list, sort_map=self.column_order(), skip=self.skip_list,
search=filter_info) search=filter_info)
self.tree.set_model(self.model) self.tree.set_model(self.model)
self.tree.restore_column_size()
self.tree.grab_focus() self.tree.grab_focus()
def clear_model(self): def clear_model(self):

View File

@ -83,5 +83,8 @@ class SelectCitation(BaseSelector):
else: else:
return self.db.get_citation_from_handle(handle) return self.db.get_citation_from_handle(handle)
def get_config_name(self):
return __name__
WIKI_HELP_PAGE = URL_MANUAL_SECT2 WIKI_HELP_PAGE = URL_MANUAL_SECT2
WIKI_HELP_SEC = _('Select_Source_or_Citation_selector', 'manual') WIKI_HELP_SEC = _('Select_Source_or_Citation_selector', 'manual')

View File

@ -75,5 +75,8 @@ class SelectEvent(BaseSelector):
def get_from_handle_func(self): def get_from_handle_func(self):
return self.db.get_event_from_handle return self.db.get_event_from_handle
def get_config_name(self):
return __name__
WIKI_HELP_PAGE = URL_MANUAL_SECT1 WIKI_HELP_PAGE = URL_MANUAL_SECT1
WIKI_HELP_SEC = _('Select_Event_selector', 'manual') WIKI_HELP_SEC = _('Select_Event_selector', 'manual')

View File

@ -72,5 +72,8 @@ class SelectFamily(BaseSelector):
def get_from_handle_func(self): def get_from_handle_func(self):
return self.db.get_family_from_handle return self.db.get_family_from_handle
def get_config_name(self):
return __name__
WIKI_HELP_PAGE = '%s_-_Categories' % URL_MANUAL_PAGE WIKI_HELP_PAGE = '%s_-_Categories' % URL_MANUAL_PAGE
WIKI_HELP_SEC = _('Select_Family_selector', 'manual') WIKI_HELP_SEC = _('Select_Family_selector', 'manual')

View File

@ -78,5 +78,8 @@ class SelectNote(BaseSelector):
def get_from_handle_func(self): def get_from_handle_func(self):
return self.db.get_note_from_handle return self.db.get_note_from_handle
def get_config_name(self):
return __name__
WIKI_HELP_PAGE = URL_MANUAL_SECT1 WIKI_HELP_PAGE = URL_MANUAL_SECT1
WIKI_HELP_SEC = _('Select_Note_selector', 'manual') WIKI_HELP_SEC = _('Select_Note_selector', 'manual')

View File

@ -104,5 +104,8 @@ class SelectObject(BaseSelector):
self.preview.set_from_pixbuf(pix) self.preview.set_from_pixbuf(pix)
gc.collect() gc.collect()
def get_config_name(self):
return __name__
WIKI_HELP_PAGE = URL_MANUAL_SECT1 WIKI_HELP_PAGE = URL_MANUAL_SECT1
WIKI_HELP_SEC = _('Select_Media_Object_selector', 'manual') WIKI_HELP_SEC = _('Select_Media_Object_selector', 'manual')

View File

@ -122,3 +122,6 @@ class SelectPerson(BaseSelector):
self.tree.expand_row(paths[0], 0) self.tree.expand_row(paths[0], 0)
return True return True
return False return False
def get_config_name(self):
return __name__

View File

@ -86,5 +86,8 @@ class SelectPlace(BaseSelector):
] ]
self.search_bar.setup_filter(cols) self.search_bar.setup_filter(cols)
def get_config_name(self):
return __name__
WIKI_HELP_PAGE = URL_MANUAL_SECT2 WIKI_HELP_PAGE = URL_MANUAL_SECT2
WIKI_HELP_SEC = _('Select_Place_selector', 'manual') WIKI_HELP_SEC = _('Select_Place_selector', 'manual')

View File

@ -71,5 +71,8 @@ class SelectRepository(BaseSelector):
def get_from_handle_func(self): def get_from_handle_func(self):
return self.db.get_repository_from_handle return self.db.get_repository_from_handle
def get_config_name(self):
return __name__
WIKI_HELP_PAGE = URL_MANUAL_SECT2 WIKI_HELP_PAGE = URL_MANUAL_SECT2
WIKI_HELP_SEC = _('Select_Repository_selector', 'manual') WIKI_HELP_SEC = _('Select_Repository_selector', 'manual')

View File

@ -73,5 +73,8 @@ class SelectSource(BaseSelector):
def get_from_handle_func(self): def get_from_handle_func(self):
return self.db.get_source_from_handle return self.db.get_source_from_handle
def get_config_name(self):
return __name__
WIKI_HELP_PAGE = URL_MANUAL_SECT2 WIKI_HELP_PAGE = URL_MANUAL_SECT2
WIKI_HELP_SEC = _('Select_Source_selector', 'manual') WIKI_HELP_SEC = _('Select_Source_selector', 'manual')

View File

@ -53,6 +53,7 @@ from ..display import display_help
from ..listmodel import ListModel from ..listmodel import ListModel
from ..managedwindow import ManagedWindow from ..managedwindow import ManagedWindow
from ..uimanager import ActionGroup from ..uimanager import ActionGroup
from gramps.gui.widgets.persistenttreeview import PersistentTreeView
from gramps.gen.utils.db import navigation_label from gramps.gen.utils.db import navigation_label
from gramps.gen.const import URL_MANUAL_PAGE from gramps.gen.const import URL_MANUAL_PAGE
from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.const import GRAMPS_LOCALE as glocale
@ -98,6 +99,7 @@ class Bookmarks(metaclass=ABCMeta):
self.connect_signals() self.connect_signals()
self.dbstate.connect('database-changed', self.db_changed) self.dbstate.connect('database-changed', self.db_changed)
self.dbstate.connect("no-database", self.undisplay) self.dbstate.connect("no-database", self.undisplay)
self.name = None
def db_changed(self, data): def db_changed(self, data):
""" """
@ -236,7 +238,14 @@ class Bookmarks(metaclass=ABCMeta):
selected row is attached to the name list. This is either 0 if the selected row is attached to the name list. This is either 0 if the
list is not empty, or -1 if it is. list is not empty, or -1 if it is.
""" """
BookmarksDialog(self) self.bkm_dialog = BookmarksDialog(self)
self.bkm_dialog.namelist.set_config_name(self.name)
def set_config_name(self, name):
"""
Set the config name used to have persistent column size.
"""
self.name = name
class BookmarksDialog(ManagedWindow): class BookmarksDialog(ManagedWindow):
""" """
@ -249,7 +258,7 @@ class BookmarksDialog(ManagedWindow):
self.bookmarks = bm_class.bookmarks self.bookmarks = bm_class.bookmarks
self.dbstate = bm_class.dbstate self.dbstate = bm_class.dbstate
self.make_label = bm_class.make_label self.make_label = bm_class.make_label
uistate = bm_class.uistate self.uistate = bm_class.uistate
self.namemodel = None self.namemodel = None
self.top = None self.top = None
@ -257,13 +266,17 @@ class BookmarksDialog(ManagedWindow):
self.response = None self.response = None
self.namelist = None self.namelist = None
ManagedWindow.__init__(self, uistate, [], self.__class__, modal=True) ManagedWindow.__init__(self, self.uistate, [], self.__class__, modal=True)
# the self.top.run() below makes Gtk make it modal, so any change to # the self.top.run() below makes Gtk make it modal, so any change to
# the previous line's "modal" would require that line to be changed # the previous line's "modal" would require that line to be changed
self.draw_window() self.draw_window()
self.set_window(self.top, None, _("Organize Bookmarks")) self.set_window(self.top, None, _("Organize Bookmarks"))
self.setup_configs('interface.bookmarksdialog', 400, 350) # Remove the "bkm_" prefix to the config class name and add it to the
# bookmarksdialog config name.
# This allow to have different widget size depending on the class.
config_name = 'interface.bookmarksdialog-' + bm_class.name[4:]
self.setup_configs(config_name, 400, 350)
self.show() self.show()
self.edit() self.edit()
@ -279,7 +292,7 @@ class BookmarksDialog(ManagedWindow):
self.top.vbox.pack_start(box, 1, 1, 5) self.top.vbox.pack_start(box, 1, 1, 5)
name_titles = [(_('Name'), -1, 200), (_('ID'), -1, 50), ('', -1, 0)] name_titles = [(_('Name'), -1, 200), (_('ID'), -1, 50), ('', -1, 0)]
self.namelist = Gtk.TreeView() self.namelist = PersistentTreeView(self.uistate, self.bm_class.name)
self.namemodel = ListModel(self.namelist, name_titles) self.namemodel = ListModel(self.namelist, name_titles)
slist = Gtk.ScrolledWindow() slist = Gtk.ScrolledWindow()
@ -301,6 +314,7 @@ class BookmarksDialog(ManagedWindow):
bbox.add(down) bbox.add(down)
bbox.add(delete) bbox.add(delete)
box.pack_start(bbox, 0, 0, 5) box.pack_start(bbox, 0, 0, 5)
self.namelist.restore_column_size()
def edit(self): def edit(self):
""" """
@ -377,6 +391,7 @@ class ListBookmarks(Bookmarks):
def __init__(self, dbstate, uistate, change_active): def __init__(self, dbstate, uistate, change_active):
self.change_active = change_active self.change_active = change_active
Bookmarks.__init__(self, dbstate, uistate) Bookmarks.__init__(self, dbstate, uistate)
self.set_config_name(self.get_config_name())
def callback(self, handle): def callback(self, handle):
return make_callback(handle, self.do_callback) return make_callback(handle, self.do_callback)
@ -400,6 +415,9 @@ class PersonBookmarks(ListBookmarks):
def get_bookmarks(self): def get_bookmarks(self):
return self.dbstate.db.get_bookmarks() return self.dbstate.db.get_bookmarks()
def get_config_name(self):
return __name__
class FamilyBookmarks(ListBookmarks): class FamilyBookmarks(ListBookmarks):
"Handle the bookmarks interface for Gramps." "Handle the bookmarks interface for Gramps."
@ -415,6 +433,9 @@ class FamilyBookmarks(ListBookmarks):
def get_bookmarks(self): def get_bookmarks(self):
return self.dbstate.db.get_family_bookmarks() return self.dbstate.db.get_family_bookmarks()
def get_config_name(self):
return __name__
class EventBookmarks(ListBookmarks): class EventBookmarks(ListBookmarks):
"Handle the bookmarks interface for Gramps." "Handle the bookmarks interface for Gramps."
@ -430,6 +451,9 @@ class EventBookmarks(ListBookmarks):
def get_bookmarks(self): def get_bookmarks(self):
return self.dbstate.db.get_event_bookmarks() return self.dbstate.db.get_event_bookmarks()
def get_config_name(self):
return __name__
class SourceBookmarks(ListBookmarks): class SourceBookmarks(ListBookmarks):
"Handle the bookmarks interface for Gramps." "Handle the bookmarks interface for Gramps."
@ -445,6 +469,9 @@ class SourceBookmarks(ListBookmarks):
def get_bookmarks(self): def get_bookmarks(self):
return self.dbstate.db.get_source_bookmarks() return self.dbstate.db.get_source_bookmarks()
def get_config_name(self):
return __name__
class CitationBookmarks(ListBookmarks): class CitationBookmarks(ListBookmarks):
"Handle the bookmarks interface for Gramps." "Handle the bookmarks interface for Gramps."
@ -486,6 +513,9 @@ class CitationBookmarks(ListBookmarks):
def get_bookmarks(self): def get_bookmarks(self):
return self.dbstate.db.get_citation_bookmarks() return self.dbstate.db.get_citation_bookmarks()
def get_config_name(self):
return __name__
class MediaBookmarks(ListBookmarks): class MediaBookmarks(ListBookmarks):
"Handle the bookmarks interface for Gramps." "Handle the bookmarks interface for Gramps."
@ -501,6 +531,9 @@ class MediaBookmarks(ListBookmarks):
def get_bookmarks(self): def get_bookmarks(self):
return self.dbstate.db.get_media_bookmarks() return self.dbstate.db.get_media_bookmarks()
def get_config_name(self):
return __name__
class RepoBookmarks(ListBookmarks): class RepoBookmarks(ListBookmarks):
"Handle the bookmarks interface for Gramps." "Handle the bookmarks interface for Gramps."
@ -516,6 +549,9 @@ class RepoBookmarks(ListBookmarks):
def get_bookmarks(self): def get_bookmarks(self):
return self.dbstate.db.get_repo_bookmarks() return self.dbstate.db.get_repo_bookmarks()
def get_config_name(self):
return __name__
class PlaceBookmarks(ListBookmarks): class PlaceBookmarks(ListBookmarks):
"Handle the bookmarks interface for Gramps." "Handle the bookmarks interface for Gramps."
@ -531,6 +567,9 @@ class PlaceBookmarks(ListBookmarks):
def get_bookmarks(self): def get_bookmarks(self):
return self.dbstate.db.get_place_bookmarks() return self.dbstate.db.get_place_bookmarks()
def get_config_name(self):
return __name__
class NoteBookmarks(ListBookmarks): class NoteBookmarks(ListBookmarks):
"Handle the bookmarks interface for Gramps." "Handle the bookmarks interface for Gramps."
@ -546,6 +585,9 @@ class NoteBookmarks(ListBookmarks):
def get_bookmarks(self): def get_bookmarks(self):
return self.dbstate.db.get_note_bookmarks() return self.dbstate.db.get_note_bookmarks()
def get_config_name(self):
return __name__
def make_callback(handle, function): def make_callback(handle, function):
""" """
Build a unique call to the function with the associated handle. Build a unique call to the function with the associated handle.

View File

@ -75,6 +75,7 @@ from ..ddtargets import DdTargets
from ..plug.quick import create_quickreport_menu, create_web_connect_menu from ..plug.quick import create_quickreport_menu, create_web_connect_menu
from ..utils import is_right_click from ..utils import is_right_click
from ..widgets.interactivesearchbox import InteractiveSearchBox from ..widgets.interactivesearchbox import InteractiveSearchBox
from ..widgets.persistenttreeview import PersistentTreeView
#---------------------------------------------------------------- #----------------------------------------------------------------
# #
@ -156,7 +157,7 @@ class ListView(NavigationView):
self.search_build_tree) self.search_build_tree)
filter_box = self.search_bar.build() filter_box = self.search_bar.build()
self.list = Gtk.TreeView() self.list = PersistentTreeView(self.uistate, self.get_config_name())
self.list.set_headers_visible(True) self.list.set_headers_visible(True)
self.list.set_headers_clickable(True) self.list.set_headers_clickable(True)
self.list.set_fixed_height_mode(True) self.list.set_fixed_height_mode(True)
@ -196,6 +197,7 @@ class ListView(NavigationView):
self.selection.connect('changed', self.row_changed) self.selection.connect('changed', self.row_changed)
self.setup_filter() self.setup_filter()
self.list.restore_column_size()
return self.vbox return self.vbox
def define_actions(self): def define_actions(self):
@ -227,8 +229,9 @@ class ListView(NavigationView):
build the columns build the columns
""" """
# Preserve the column widths if rebuilding the view. # Preserve the column widths if rebuilding the view.
if self.columns and preserve_col: # removed since we have a PersistentTreeView
self.save_column_info() #if self.columns and preserve_col:
# self.list.save_column_info(self.list)
list(map(self.list.remove_column, self.columns)) list(map(self.list.remove_column, self.columns))
self.columns = [] self.columns = []
@ -263,11 +266,13 @@ class ListView(NavigationView):
column.set_resizable(True) column.set_resizable(True)
column.set_clickable(True) column.set_clickable(True)
column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
column.set_fixed_width(pair[2]) # removed since we have a PersistentTreeView
# column.set_fixed_width(pair[2])
self.columns.append(column) self.columns.append(column)
self.list.append_column(column) self.list.append_column(column)
index += 1 index += 1
return self.vbox
def icon(self, column, renderer, model, iter_, col_num): def icon(self, column, renderer, model, iter_, col_num):
''' '''
@ -336,6 +341,7 @@ class ListView(NavigationView):
cput1 = perf_counter() cput1 = perf_counter()
self.build_columns(preserve_col) self.build_columns(preserve_col)
self.list.restore_column_size()
cput2 = perf_counter() cput2 = perf_counter()
self.list.set_model(self.model) self.list.set_model(self.model)
cput3 = perf_counter() cput3 = perf_counter()
@ -1115,12 +1121,21 @@ class ListView(NavigationView):
""" """
Save the column widths when the view is shutdown. Save the column widths when the view is shutdown.
""" """
self.list.save_column_info()
# The following is used when we change the columns order.
self.save_column_info() self.save_column_info()
PageView.on_delete(self) PageView.on_delete(self)
def get_config_name(self):
"""
Set the associated config name string for the treeview
"""
assert False, "Must be defined in the subclass"
def save_column_info(self): def save_column_info(self):
""" """
Save the column widths, order, and view settings Save the column widths, order, and view settings
This is used only when we change the columns order
""" """
widths = self.get_column_widths() widths = self.get_column_widths()
order = self._config.get('columns.rank') order = self._config.get('columns.rank')
@ -1343,7 +1358,8 @@ class ListView(NavigationView):
return _('Columns'), ColumnOrder(self._config, column_names, return _('Columns'), ColumnOrder(self._config, column_names,
self.get_column_widths(), self.get_column_widths(),
self.set_column_order, self.set_column_order,
tree=not flat) tree=not flat,
resizable=self.list)
def csvdialect(configdialog): def csvdialect(configdialog):
return _('CSV Dialect'), CsvDialect() return _('CSV Dialect'), CsvDialect()
return [columnpage, csvdialect] return [columnpage, csvdialect]

View File

@ -44,3 +44,4 @@ from .undoablestyledbuffer import *
from .validatedcomboentry import * from .validatedcomboentry import *
from .validatedmaskedentry import * from .validatedmaskedentry import *
from .placewithin import * from .placewithin import *
from .persistenttreeview import *

View File

@ -0,0 +1,145 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2021 Serge Noiraud
#
# 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.
#
"""
An override to allow resizable columns
"""
import logging
from gi.repository import Gtk
from gramps.gen.config import config
_LOG = logging.getLogger(".persistent")
# -------------------------------------------------------------------------
#
# PersistentTreeView class
#
# -------------------------------------------------------------------------
__all__ = ["PersistentTreeView"]
class PersistentTreeView(Gtk.TreeView):
'''
TreeView that has resizable columns
'''
__gtype_name__ = 'PersistentTreeView'
def __init__(self, uistate=None, config_name=None):
"""
Create a TreeView widgets with column size saving
"""
Gtk.TreeView.__init__(self)
self.config_name = "undefined"
self.connect("destroy", self.save_column_info)
self.uistate = None
if uistate:
self.set_uistate(uistate)
if config_name:
self.set_config_name(config_name)
def set_uistate(self, uistate):
"""
parameter: uistate: The associated uistate
This parameter is used to connect some signals from this class.
"""
if not self.uistate and uistate:
_LOG.debug("connect signal font-changed")
uistate.connect('font-changed', self.restore_column_size)
self.uistate = uistate
def set_config_name(self, name):
"""
parameter: name: The associated config name string for the treeview
This parameter must be unique as it allow the tab columns size saving
"""
# Here, we can have:
# name = gramps.gui.editors.displaytabs.personeventembedlist
# The following line return only the last part of the string.
# personeventembedlist in this case
last = name.split('.')[-1]
_LOG.debug("set persistent name : %s" % last)
self.config_name = "spacing.%s" % last
if not config.is_set(self.config_name):
_LOG.debug("registering %s" % self.config_name)
config.register(self.config_name, [])
def save_column_info(self, tree=None):
"""
Save the columns width
"""
if self.config_name == "undefined":
return
newsize = self.get_columns_size()
if 0 not in newsize:
# Don't save the values if one column size is null.
config.set(self.config_name, newsize)
_LOG.debug("save persistent : %s = %s" % (self.config_name,
newsize))
return
def get_columns_size(self):
"""
Get all the columns size
"""
columns = self.get_columns()
newsize = []
nbc = 0
context = Gtk.Label().get_pango_context()
font_desc = context.get_font_description()
char_width = 1.2 * (font_desc.get_size() / 1000)
for column in columns:
if nbc < len(columns) - 1 or len(columns) == 1:
# Don't save the last column size, it's wrong
# except if we have only one column (i.e. EditRule)
child = column.get_widget()
if isinstance(child, Gtk.Image):
# Don't resize the icons
size = 2
else:
size = int(column.get_width() / char_width) + 1
size = 2 if size < 2 else size
newsize.append(size)
nbc += 1
return newsize
def restore_column_size(self):
"""
restore the columns width
"""
if self.config_name == "undefined":
return
size = config.get(self.config_name)
if len(size) == 0:
_LOG.debug("restore for the first time : %s = %s" %
(self.config_name, size))
return
_LOG.debug("restore persistent : %s = %s" % (self.config_name, size))
context = Gtk.Label().get_pango_context()
font_desc = context.get_font_description()
char_width = 1.2 * (font_desc.get_size() / 1000)
nbc = 0
columns = self.get_columns()
for column in columns:
if nbc < len(size):
column.set_fixed_width(size[nbc] * char_width)
nbc += 1

View File

@ -39,8 +39,11 @@ from gramps.gen.datehandler import get_date
from gramps.gen.display.place import displayer as place_displayer from gramps.gen.display.place import displayer as place_displayer
from gramps.gen.errors import WindowActiveError from gramps.gen.errors import WindowActiveError
from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.const import GRAMPS_LOCALE as glocale
from gramps.gui.widgets.persistenttreeview import PersistentTreeView
_ = glocale.translation.gettext _ = glocale.translation.gettext
class Children(Gramplet): class Children(Gramplet):
""" """
Displays the children of a person or family. Displays the children of a person or family.
@ -51,6 +54,10 @@ class Children(Gramplet):
self.gui.get_container_widget().add(self.gui.WIDGET) self.gui.get_container_widget().add(self.gui.WIDGET)
self.gui.WIDGET.show() self.gui.WIDGET.show()
self.uistate.connect('nameformat-changed', self.update) self.uistate.connect('nameformat-changed', self.update)
self.gui.WIDGET.restore_column_size()
def on_save(self):
self.gui.WIDGET.save_column_info()
def get_date_place(self, event): def get_date_place(self, event):
""" """
@ -88,7 +95,7 @@ class PersonChildren(Children):
""" """
tip = _('Double-click on a row to edit the selected child.') tip = _('Double-click on a row to edit the selected child.')
self.set_tooltip(tip) self.set_tooltip(tip)
top = Gtk.TreeView() top = PersistentTreeView(self.uistate, __name__)
titles = [('', NOSORT, 50,), titles = [('', NOSORT, 50,),
(_('Child'), 1, 250), (_('Child'), 1, 250),
(_('Birth Date'), 3, 100), (_('Birth Date'), 3, 100),
@ -187,7 +194,7 @@ class FamilyChildren(Children):
""" """
tip = _('Double-click on a row to edit the selected child.') tip = _('Double-click on a row to edit the selected child.')
self.set_tooltip(tip) self.set_tooltip(tip)
top = Gtk.TreeView() top = PersistentTreeView(self.uistate, __name__)
titles = [('', NOSORT, 50,), titles = [('', NOSORT, 50,),
(_('Child'), 1, 250), (_('Child'), 1, 250),
(_('Birth Date'), 3, 100), (_('Birth Date'), 3, 100),

View File

@ -38,6 +38,8 @@ from gramps.gen.datehandler._dateutils import get_date
from gramps.gui.dbguielement import DbGUIElement from gramps.gui.dbguielement import DbGUIElement
from gramps.gen.errors import WindowActiveError from gramps.gen.errors import WindowActiveError
from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.const import GRAMPS_LOCALE as glocale
from gramps.gui.widgets.persistenttreeview import PersistentTreeView
_ = glocale.translation.gettext _ = glocale.translation.gettext
class Citations(Gramplet, DbGUIElement): class Citations(Gramplet, DbGUIElement):
@ -55,6 +57,10 @@ class Citations(Gramplet, DbGUIElement):
self.gui.get_container_widget().remove(self.gui.textview) self.gui.get_container_widget().remove(self.gui.textview)
self.gui.get_container_widget().add(self.gui.WIDGET) self.gui.get_container_widget().add(self.gui.WIDGET)
self.gui.WIDGET.show() self.gui.WIDGET.show()
self.gui.WIDGET.restore_column_size()
def on_save(self):
self.gui.WIDGET.save_column_info()
def _connect_db_signals(self): def _connect_db_signals(self):
""" """
@ -81,7 +87,7 @@ class Citations(Gramplet, DbGUIElement):
""" """
tip = _('Double-click on a row to edit the selected source/citation.') tip = _('Double-click on a row to edit the selected source/citation.')
self.set_tooltip(tip) self.set_tooltip(tip)
top = Gtk.TreeView() top = PersistentTreeView(self.uistate, __name__)
titles = [('', NOSORT, 50,), titles = [('', NOSORT, 50,),
(_('Source/Date'), 1, 350), (_('Source/Date'), 1, 350),
(_('Volume/Page'), 2, 150), (_('Volume/Page'), 2, 150),

View File

@ -44,6 +44,7 @@ from gramps.gen.errors import WindowActiveError
from gramps.gen.config import config from gramps.gen.config import config
from gramps.gen.proxy.cache import CacheProxyDb from gramps.gen.proxy.cache import CacheProxyDb
from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.const import GRAMPS_LOCALE as glocale
from gramps.gui.widgets.persistenttreeview import PersistentTreeView
_ = glocale.translation.gettext _ = glocale.translation.gettext
age_precision = config.get('preferences.age-display-precision') age_precision = config.get('preferences.age-display-precision')
@ -63,6 +64,10 @@ class Events(Gramplet, DbGUIElement):
self.gui.get_container_widget().remove(self.gui.textview) self.gui.get_container_widget().remove(self.gui.textview)
self.gui.get_container_widget().add(self.gui.WIDGET) self.gui.get_container_widget().add(self.gui.WIDGET)
self.gui.WIDGET.show() self.gui.WIDGET.show()
self.gui.WIDGET.restore_column_size()
def on_save(self):
self.gui.WIDGET.save_column_info()
def _connect_db_signals(self): def _connect_db_signals(self):
""" """
@ -83,7 +88,7 @@ class Events(Gramplet, DbGUIElement):
""" """
tip = _('Double-click on a row to edit the selected event.') tip = _('Double-click on a row to edit the selected event.')
self.set_tooltip(tip) self.set_tooltip(tip)
top = Gtk.TreeView() top = PersistentTreeView(self.uistate, __name__)
titles = [('', NOSORT, 50,), titles = [('', NOSORT, 50,),
(_('Type'), 1, 100), (_('Type'), 1, 100),
(_('Description'), 2, 150), (_('Description'), 2, 150),

View File

@ -538,3 +538,9 @@ class BasePersonView(ListView):
"Person Notes", "Person Notes",
"Person Attributes", "Person Attributes",
"Person Backlinks")) "Person Backlinks"))
def get_config_name(self):
"""
return the config name for this view
"""
assert False, "Must be defined in the subclass"

View File

@ -463,3 +463,6 @@ class CitationListView(ListView):
("Citation Gallery", ("Citation Gallery",
"Citation Notes", "Citation Notes",
"Citation Backlinks")) "Citation Backlinks"))
def get_config_name(self):
return __name__

View File

@ -743,3 +743,6 @@ class CitationTreeView(LibSourceView, ListView):
("Citation Gallery", ("Citation Gallery",
"Citation Notes", "Citation Notes",
"Citation Backlinks")) "Citation Backlinks"))
def get_config_name(self):
return __name__

View File

@ -445,3 +445,6 @@ class EventView(ListView):
"Event Notes", "Event Notes",
"Event Attributes", "Event Attributes",
"Event Backlinks")) "Event Backlinks"))
def get_config_name(self):
return __name__

View File

@ -124,6 +124,9 @@ class FamilyView(ListView):
self.additional_uis.append(self.additional_ui) self.additional_uis.append(self.additional_ui)
def get_config_name(self):
return __name__
def navigation_type(self): def navigation_type(self):
return 'Family' return 'Family'

View File

@ -538,3 +538,6 @@ class MediaView(ListView):
"Media Attributes", "Media Attributes",
"Metadata Viewer", "Metadata Viewer",
"Media Backlinks")) "Media Backlinks"))
def get_config_name(self):
return __name__

View File

@ -390,3 +390,6 @@ class NoteView(ListView):
""" """
return (("Note Filter",), return (("Note Filter",),
("Note Backlinks",)) ("Note Backlinks",))
def get_config_name(self):
return __name__

View File

@ -42,7 +42,7 @@ _ = glocale.translation.gettext
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# PlaceTreeView # PersonListView
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
class PersonListView(BasePersonView): class PersonListView(BasePersonView):
@ -53,3 +53,6 @@ class PersonListView(BasePersonView):
BasePersonView.__init__(self, pdata, dbstate, uistate, BasePersonView.__init__(self, pdata, dbstate, uistate,
_('Person View'), PersonListModel, _('Person View'), PersonListModel,
nav_group=nav_group) nav_group=nav_group)
def get_config_name(self):
return __name__

View File

@ -124,3 +124,6 @@ class PersonTreeView(BasePersonView):
EditPerson(self.dbstate, self.uistate, [], person) EditPerson(self.dbstate, self.uistate, [], person)
except WindowActiveError: except WindowActiveError:
pass pass
def get_config_name(self):
return __name__

View File

@ -50,3 +50,6 @@ class PlaceListView(PlaceBaseView):
PlaceBaseView.__init__(self, pdata, dbstate, uistate, PlaceBaseView.__init__(self, pdata, dbstate, uistate,
_('Place View'), PlaceListModel, _('Place View'), PlaceListModel,
nav_group=0) nav_group=0)
def get_config_name(self):
return __name__

View File

@ -153,3 +153,6 @@ class PlaceTreeView(PlaceBaseView):
old_handle = self.model.get_handle_from_iter(parent_iter) old_handle = self.model.get_handle_from_iter(parent_iter)
children = self.model.get_node_from_iter(iter_).children children = self.model.get_node_from_iter(iter_).children
return new_handle != old_handle or children return new_handle != old_handle or children
def get_config_name(self):
return __name__

View File

@ -407,3 +407,6 @@ class RepositoryView(ListView):
("Repository Details", ("Repository Details",
"Repository Notes", "Repository Notes",
"Repository Backlinks")) "Repository Backlinks"))
def get_config_name(self):
return __name__

View File

@ -384,3 +384,6 @@ class SourceView(LibSourceView, ListView):
("Source Gallery", ("Source Gallery",
"Source Notes", "Source Notes",
"Source Backlinks")) "Source Backlinks"))
def get_config_name(self):
return __name__