2007-07-11 Don Allingham <don@gramps-project.org>

* src/DbManager.py (DbManager.__button_press): check for node == None



svn: r8713
This commit is contained in:
Don Allingham 2007-07-12 04:24:44 +00:00
parent 5984415471
commit 576c4b705f
5 changed files with 292 additions and 261 deletions

View File

@ -1,3 +1,6 @@
2007-07-11 Don Allingham <don@gramps-project.org>
* src/DbManager.py (DbManager.__button_press): check for node == None
2007-07-10 Alex Roitman <shura@gramps-project.org>
* src/GrampsDb/_GrampsDbWriteXML.py (write_date): Write datespan.
* src/GrampsDbUtils/_ReadXML.py: (start_compound_date): Add new

View File

@ -70,6 +70,7 @@ import GrampsDb
import GrampsDbUtils
import Config
import Mime
from DdTargets import DdTargets
IMPORT_TYPES = (const.app_gramps_xml, const.app_gedcom,
const.app_gramps_package, const.app_geneweb,
@ -144,22 +145,20 @@ class DbManager:
"""
Connects the signals to the buttons on the interface.
"""
ddtargets = [ DdTargets.URI_LIST.target() ]
self.top.drag_dest_set(gtk.DEST_DEFAULT_ALL, ddtargets, ACTION_COPY)
self.remove.connect('clicked', self.__remove_db)
self.new.connect('clicked', self.__new_db)
self.rename.connect('clicked', self.__rename_db)
self.repair.connect('clicked', self.__repair_db)
if RCS_FOUND:
self.rcs.connect('clicked', self.__rcs)
self.selection.connect('changed', self.__selection_changed)
self.dblist.connect('button-press-event', self.__button_press)
self.top.drag_dest_set(
gtk.DEST_DEFAULT_ALL,
(('text/plain', 0, 1),
('text/uri-list', 0, 2)),
ACTION_COPY)
self.top.connect('drag_data_received', self.__drag_data_received)
if RCS_FOUND:
self.rcs.connect('clicked', self.__rcs)
def __button_press(self, obj, event):
"""
Checks for a double click event. In the tree view, we want to
@ -168,6 +167,8 @@ class DbManager:
"""
if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1:
store, node = self.selection.get_selected()
if not node:
return
# don't open a locked file
if store.get_value(node, STOCK_COL) == 'gramps-lock':
self.__ask_to_break_lock(store, node)
@ -658,6 +659,7 @@ class DbManager:
# Check for Thunar
uris = selection.get_uris()
if uris: # Thunar
drag_value = uris[0]
elif selection.get_text(): # Nautilus

View File

@ -60,7 +60,7 @@ class _DdType:
_APP_ID_OFFSET = 40 # Starting value of app_ids
def __init__(self,container,drag_type,target_flags=0,app_id=None):
def __init__(self, container, drag_type, target_flags=0, app_id=None):
"""Create a new DdType:
drag_type: string holding the name of the type.
@ -83,7 +83,7 @@ class _DdType:
def target(self):
"""return the full target information in the format
required by the Gtk functions."""
return (self.drag_type,self.target_flags,self.app_id)
return (self.drag_type, self.target_flags, self.app_id)
@ -106,87 +106,87 @@ class _DdTargets(object):
self._type_map = {}
self._app_id_map = {}
self.URL = _DdType(self,'url')
self.EVENT = _DdType(self,'pevent')
self.EVENTREF = _DdType(self,'eventref')
self.ATTRIBUTE = _DdType(self,'pattr')
self.ADDRESS = _DdType(self,'paddr')
self.LOCATION = _DdType(self,'location')
self.SOURCEREF = _DdType(self,'srcref')
self.REPOREF = _DdType(self,'reporef')
self.REPO_LINK = _DdType(self,'repo-link')
self.PLACE_LINK= _DdType(self,'place-link')
self.NAME = _DdType(self,'name')
self.MEDIAOBJ = _DdType(self,'mediaobj')
self.MEDIAREF = _DdType(self,'mediaref')
self.DATA = _DdType(self,'data_tuple')
self.NOTE_LINK = _DdType(self,'note-link')
self.URL = _DdType(self, 'url')
self.EVENT = _DdType(self, 'pevent')
self.EVENTREF = _DdType(self, 'eventref')
self.ATTRIBUTE = _DdType(self, 'pattr')
self.ADDRESS = _DdType(self, 'paddr')
self.LOCATION = _DdType(self, 'location')
self.SOURCEREF = _DdType(self, 'srcref')
self.REPOREF = _DdType(self, 'reporef')
self.REPO_LINK = _DdType(self, 'repo-link')
self.PLACE_LINK = _DdType(self, 'place-link')
self.NAME = _DdType(self, 'name')
self.MEDIAOBJ = _DdType(self, 'mediaobj')
self.MEDIAREF = _DdType(self, 'mediaref')
self.DATA = _DdType(self, 'data_tuple')
self.NOTE_LINK = _DdType(self, 'note-link')
self.PERSON_LINK = _DdType(self,'person-link')
self.PERSON_LINK_LIST = _DdType(self,'person-link-list')
self.PERSONREF = _DdType(self,'personref')
self.PERSON_LINK = _DdType(self, 'person-link')
self.PERSON_LINK_LIST = _DdType(self, 'person-link-list')
self.PERSONREF = _DdType(self, 'personref')
self.SOURCE_LINK = _DdType(self,'source-link')
self.SOURCE_LINK = _DdType(self, 'source-link')
self.FAMILY_EVENT = _DdType(self,'fevent')
self.FAMILY_ATTRIBUTE = _DdType(self,'fattr')
self.FAMILY_EVENT = _DdType(self, 'fevent')
self.FAMILY_ATTRIBUTE = _DdType(self, 'fattr')
# List of all types that are used between
# gramps widgets but should not be exported
# to non gramps widgets.
self._all_gramps_types = [
self.URL,
self.EVENT,
self.ATTRIBUTE,
self.ADDRESS,
self.LOCATION,
self.SOURCEREF,
self.EVENTREF,
self.NAME,
self.REPOREF,
self.MEDIAOBJ,
self.MEDIAREF,
self.REPO_LINK,
self.PLACE_LINK,
self.SOURCE_LINK,
self.PERSON_LINK,
self.PERSON_LINK_LIST,
self.PERSONREF,
self.NOTE_LINK,
self.URL,
self.EVENT,
self.ATTRIBUTE,
self.ADDRESS,
self.LOCATION,
self.SOURCEREF,
self.EVENTREF,
self.NAME,
self.REPOREF,
self.MEDIAOBJ,
self.MEDIAREF,
self.REPO_LINK,
self.PLACE_LINK,
self.SOURCE_LINK,
self.PERSON_LINK,
self.PERSON_LINK_LIST,
self.PERSONREF,
self.NOTE_LINK,
]
self.CHILD = _DdType(self,'child')
self.SPOUSE = _DdType(self,'spouse')
self.TEXT = _DdType(self,'TEXT',0,1)
self.TEXT_MIME = _DdType(self,'text/plain',0,0)
self.STRING = _DdType(self,'STRING', 0, 2)
self.COMPOUND_TEXT = _DdType(self,'COMPOUND_TEXT', 0, 3)
self.UTF8_STRING = _DdType(self,'UTF8_STRING', 0, 4)
self.URI_LIST = _DdType(self,'text/uri-list', 0, 5)
self.APP_ROOT = _DdType(self,'application/x-rootwin-drop', 0, 6)
self.CHILD = _DdType(self, 'child')
self.SPOUSE = _DdType(self, 'spouse')
self.TEXT = _DdType(self, 'TEXT', 0, 1)
self.TEXT_MIME = _DdType(self, 'text/plain', 0, 0)
self.STRING = _DdType(self, 'STRING', 0, 2)
self.COMPOUND_TEXT = _DdType(self, 'COMPOUND_TEXT', 0, 3)
self.UTF8_STRING = _DdType(self, 'UTF8_STRING', 0, 4)
self.URI_LIST = _DdType(self, 'text/uri-list', 0, 5)
self.APP_ROOT = _DdType(self, 'application/x-rootwin-drop', 0, 6)
# List of all the test types. These are types
# that can be interpreted as text.
self._all_text_types = (self.UTF8_STRING,
self.TEXT,
self.TEXT_MIME,
self.STRING,
self._all_text_types = (self.UTF8_STRING,
self.TEXT,
self.TEXT_MIME,
self.STRING,
self.COMPOUND_TEXT)
def insert(self,dd_type):
def insert(self, dd_type):
"""Add a target to the lookup lists. These lists are
used purely for performance reasons."""
self._type_map[dd_type.drag_type] = dd_type
self._app_id_map[dd_type.app_id] = dd_type
def get_dd_type_from_type_name(self,type_name):
return self._type_map.get(type_name,None)
def get_dd_type_from_type_name(self, type_name):
return self._type_map.get(type_name, None)
def get_dd_type_from_app_id(self,app_id):
return self._app_id_map.get(app_id,None)
def get_dd_type_from_app_id(self, app_id):
return self._app_id_map.get(app_id, None)
def is_text_type(self,type_name):
def is_text_type(self, type_name):
return type_name in self.all_text_types()
def all_text(self):
@ -198,7 +198,7 @@ class _DdTargets(object):
return tuple([t.drag_type for t in self._all_text_types])
def is_gramps_type(self,type_name):
def is_gramps_type(self, type_name):
return type_name in self.all_gramps_types()
def all_gramps_types(self):

View File

@ -8,7 +8,7 @@
# 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,
# 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.
@ -56,10 +56,10 @@ from Errors import NameDisplayError
#-------------------------------------------------------------------------
_surname_styles = [
_("Father's surname"),
_("None"),
_("Combination of mother's and father's surname"),
_("Icelandic style"),
_("Father's surname"),
_("None"),
_("Combination of mother's and father's surname"),
_("Icelandic style"),
]
# column numbers for the 'name format' model
@ -85,7 +85,7 @@ def get_researcher():
e = Config.get(Config.RESEARCHER_EMAIL)
owner = RelLib.Researcher()
owner.set(n,a,c,s,ct,p,ph,e)
owner.set(n, a, c, s, ct, p, ph, e)
return owner
#-------------------------------------------------------------------------
@ -96,14 +96,14 @@ def get_researcher():
class GrampsPreferences(ManagedWindow.ManagedWindow):
def __init__(self, uistate, dbstate):
ManagedWindow.ManagedWindow.__init__(self,uistate,[],GrampsPreferences)
ManagedWindow.ManagedWindow.__init__(self, uistate, [], GrampsPreferences)
self.dbstate = dbstate
self.set_window(
gtk.Dialog(_('Preferences'),
flags=gtk.DIALOG_NO_SEPARATOR,
buttons=(gtk.STOCK_CLOSE,gtk.RESPONSE_CLOSE)),
gtk.Dialog(_('Preferences'),
flags=gtk.DIALOG_NO_SEPARATOR,
buttons=(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)),
None, _('Preferences'), None)
panel = gtk.Notebook()
@ -111,22 +111,22 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
self.original = Config.get(Config.TRANSACTIONS)
self.window.vbox.add(panel)
self.window.connect('response',self.done)
panel.append_page(self.add_behavior_panel(),
self.window.connect('response', self.done)
panel.append_page(self.add_behavior_panel(),
MarkupLabel(_('General')))
panel.append_page(self.add_database_panel(),
panel.append_page(self.add_database_panel(),
MarkupLabel(_('Database')))
panel.append_page(self.add_formats_panel(),
panel.append_page(self.add_formats_panel(),
MarkupLabel(_('Display')))
panel.append_page(self.add_name_panel(),
panel.append_page(self.add_name_panel(),
MarkupLabel(_('Name Display')))
panel.append_page(self.add_prefix_panel(),
panel.append_page(self.add_prefix_panel(),
MarkupLabel(_('ID Formats')))
panel.append_page(self.add_advanced_panel(),
panel.append_page(self.add_advanced_panel(),
MarkupLabel(_('Warnings')))
panel.append_page(self.add_researcher_panel(),
panel.append_page(self.add_researcher_panel(),
MarkupLabel(_('Researcher')))
panel.append_page(self.add_color_panel(),
panel.append_page(self.add_color_panel(),
MarkupLabel(_('Marker Colors')))
self.window.show_all()
@ -138,7 +138,7 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
self.close()
def add_researcher_panel(self):
table = gtk.Table(3,8)
table = gtk.Table(3, 8)
table.set_border_width(12)
table.set_col_spacings(6)
table.set_row_spacings(6)
@ -153,7 +153,7 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
return table
def add_prefix_panel(self):
table = gtk.Table(3,8)
table = gtk.Table(3, 8)
table.set_border_width(12)
table.set_col_spacings(6)
table.set_row_spacings(6)
@ -167,40 +167,40 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
return table
def add_advanced_panel(self):
table = gtk.Table(4,8)
table = gtk.Table(4, 8)
table.set_border_width(12)
table.set_col_spacings(6)
table.set_row_spacings(6)
self.add_checkbox(
table, _('Suppress warning when adding parents to a child'),
table, _('Suppress warning when adding parents to a child'),
0, Config.FAMILY_WARN)
self.add_checkbox(
table, _('Suppress warning when cancelling with changed data'),
table, _('Suppress warning when cancelling with changed data'),
1, Config.DONT_ASK)
self.add_checkbox(
table, _('Suppress warning about missing researcher when'
' exporting to GEDCOM'),
' exporting to GEDCOM'),
2, Config.OWNER_WARN)
self.add_checkbox(
table, _('Show plugin status dialog on plugin load error'),
table, _('Show plugin status dialog on plugin load error'),
3, Config.POP_PLUGIN_STATUS)
return table
def add_color_panel(self):
table = gtk.Table(3,8)
table = gtk.Table(3, 8)
table.set_border_width(12)
table.set_col_spacings(12)
table.set_row_spacings(6)
self.comp_color = self.add_color(table, _("Complete"), 0,
self.comp_color = self.add_color(table, _("Complete"), 0,
Config.COMPLETE_COLOR)
self.todo_color = self.add_color(table, _("ToDo"), 1,
self.todo_color = self.add_color(table, _("ToDo"), 1,
Config.TODO_COLOR)
self.custom_color = self.add_color(table, _("Custom"), 2,
self.custom_color = self.add_color(table, _("Custom"), 2,
Config.CUSTOM_MARKER_COLOR)
button = gtk.Button(stock=gtk.STOCK_REVERT_TO_SAVED)
@ -210,9 +210,9 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
def reset_colors(self, obj):
def_comp = Config.get_default(Config.COMPLETE_COLOR,'')
def_todo = Config.get_default(Config.TODO_COLOR,'')
def_cust = Config.get_default(Config.CUSTOM_MARKER_COLOR,'')
def_comp = Config.get_default(Config.COMPLETE_COLOR, '')
def_todo = Config.get_default(Config.TODO_COLOR, '')
def_cust = Config.get_default(Config.CUSTOM_MARKER_COLOR, '')
Config.set(Config.COMPLETE_COLOR, def_comp)
Config.set(Config.TODO_COLOR, def_todo)
@ -221,7 +221,7 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
self.comp_color.set_color(gtk.gdk.color_parse(def_comp))
self.todo_color.set_color(gtk.gdk.color_parse(def_todo))
self.custom_color.set_color(gtk.gdk.color_parse(def_cust))
for widget in [self.comp_color,self.todo_color,self.custom_color]:
for widget in [self.comp_color, self.todo_color, self.custom_color]:
widget.emit('color-set')
def add_name_panel(self):
@ -239,14 +239,14 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
self.examplename.set_patronymic('Patronymic')
self.examplename.set_call_name('Ed')
table = gtk.Table(2,2)
table = gtk.Table(2, 2)
table.set_border_width(12)
table.set_col_spacings(6)
table.set_row_spacings(6)
# get the model for the combo and the treeview
active = _nd.get_default_format()
self.fmt_model,active = self._build_name_format_model(active)
self.fmt_model, active = self._build_name_format_model(active)
# set up the combo to choose the preset format
self.fmt_obox = gtk.ComboBox()
@ -276,30 +276,30 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
return table
def _build_name_format_model(self,active):
def _build_name_format_model(self, active):
"""
Create a common model for ComboBox and TreeView
"""
name_format_model = gtk.ListStore(int,str,str,str)
name_format_model = gtk.ListStore(int, str, str, str)
index = 0
the_index = 0
for num,name,fmt_str,act in _nd.get_name_format():
for num, name, fmt_str, act in _nd.get_name_format():
self.examplename.set_display_as(num)
name_format_model.append(
row=[num, name, fmt_str, _nd.display_name(self.examplename)])
if num == active: the_index = index
index += 1
return name_format_model,the_index
return name_format_model, the_index
def _build_custom_name_ui(self):
"""
UI to manage the custom name formats
"""
table = gtk.Table(2,3)
table = gtk.Table(2, 3)
table.set_border_width(6)
table.set_col_spacings(6)
table.set_row_spacings(6)
@ -307,22 +307,22 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
# make a treeview for listing all the name formats
format_tree = gtk.TreeView(self.fmt_model)
name_renderer = gtk.CellRendererText()
name_column = gtk.TreeViewColumn(_('Format Name'),
name_renderer,
name_column = gtk.TreeViewColumn(_('Format Name'),
name_renderer,
text=COL_NAME)
format_tree.append_column(name_column)
example_renderer = gtk.CellRendererText()
example_column = gtk.TreeViewColumn(_('Example'),
example_renderer,
example_column = gtk.TreeViewColumn(_('Example'),
example_renderer,
text=COL_EXPL)
format_tree.append_column(example_column)
format_tree.get_selection().connect('changed',
format_tree.get_selection().connect('changed',
self.cb_format_tree_select)
format_tree.set_rules_hint(True)
# ... and put it into a scrolled win
format_sw = gtk.ScrolledWindow()
format_sw.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
format_sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
format_sw.add(format_tree)
format_sw.set_shadow_type(gtk.SHADOW_IN)
table.attach(format_sw, 0, 3, 0, 1, yoptions=gtk.FILL|gtk.EXPAND)
@ -332,30 +332,30 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
self.iter = None
insert_button = gtk.Button(stock=gtk.STOCK_ADD)
insert_button.connect('clicked',self.cb_insert_fmt_str)
insert_button.connect('clicked', self.cb_insert_fmt_str)
self.edit_button = gtk.Button(stock=gtk.STOCK_EDIT)
self.edit_button.connect('clicked',self.cb_edit_fmt_str)
self.edit_button.connect('clicked', self.cb_edit_fmt_str)
self.edit_button.set_sensitive(False)
self.remove_button = gtk.Button(stock=gtk.STOCK_REMOVE)
self.remove_button.connect('clicked',self.cb_del_fmt_str)
self.remove_button.connect('clicked', self.cb_del_fmt_str)
self.remove_button.set_sensitive(False)
table.attach(insert_button, 0, 1, 1, 2,yoptions=0)
table.attach(self.remove_button, 1, 2, 1, 2,yoptions=0)
table.attach(self.edit_button, 2, 3, 1, 2,yoptions=0)
table.attach(insert_button, 0, 1, 1, 2, yoptions=0)
table.attach(self.remove_button, 1, 2, 1, 2, yoptions=0)
table.attach(self.edit_button, 2, 3, 1, 2, yoptions=0)
return table
def cb_name_changed(self,obj):
def cb_name_changed(self, obj):
"""
Preset name format ComboBox callback
"""
the_list = obj.get_model()
the_iter = obj.get_active_iter()
new_idx = the_list.get_value(the_iter,COL_NUM)
Config.set(Config.NAME_FORMAT,new_idx)
new_idx = the_list.get_value(the_iter, COL_NUM)
Config.set(Config.NAME_FORMAT, new_idx)
_nd.set_default_format(new_idx)
self.uistate.emit('nameformat-changed')
@ -367,53 +367,53 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
and set the Remove and Edit button sensitivity
"""
model,self.iter = tree_selection.get_selected()
model, self.iter = tree_selection.get_selected()
if self.iter == None:
tree_selection.select_path(0)
model,self.iter = tree_selection.get_selected()
model, self.iter = tree_selection.get_selected()
self.selected_fmt = model.get(self.iter, 0, 1, 2)
idx = self.selected_fmt[COL_NUM] < 0
self.remove_button.set_sensitive(idx)
self.edit_button.set_sensitive(idx)
def cb_edit_fmt_str(self,obj):
def cb_edit_fmt_str(self, obj):
"""
Name format editor Edit button callback
"""
num,name,fmt = self.selected_fmt[COL_NUM:COL_EXPL]
num, name, fmt = self.selected_fmt[COL_NUM:COL_EXPL]
dlg = NameFormatEditDlg(name, fmt, self.examplename)
dlg.dlg.set_transient_for(self.window)
(res,name,fmt) = dlg.run()
(res, name, fmt) = dlg.run()
if res == gtk.RESPONSE_OK and (name != self.selected_fmt[COL_NAME] or
fmt != self.selected_fmt[COL_FMT]):
exmpl = _nd.format_str(self.examplename,fmt)
self.fmt_model.set(self.iter,COL_NAME,name,
COL_FMT,fmt,
COL_EXPL,exmpl)
self.selected_fmt = (num,name,fmt,exmpl)
_nd.edit_name_format(num,name,fmt)
exmpl = _nd.format_str(self.examplename, fmt)
self.fmt_model.set(self.iter, COL_NAME, name,
COL_FMT, fmt,
COL_EXPL, exmpl)
self.selected_fmt = (num, name, fmt, exmpl)
_nd.edit_name_format(num, name, fmt)
self.dbstate.db.name_formats = _nd.get_name_format(only_custom=True,
self.dbstate.db.name_formats = _nd.get_name_format(only_custom=True,
only_active=False)
def cb_insert_fmt_str(self,obj):
def cb_insert_fmt_str(self, obj):
"""
Name format editor Insert button callback
"""
dlg = NameFormatEditDlg('','',self.examplename)
dlg = NameFormatEditDlg('', '', self.examplename)
dlg.dlg.set_transient_for(self.window)
(res,n,f) = dlg.run()
(res, n, f) = dlg.run()
if res == gtk.RESPONSE_OK:
i = _nd.add_name_format(n,f)
self.fmt_model.append(row=[i,n,f,
_nd.format_str(self.examplename,f)])
i = _nd.add_name_format(n, f)
self.fmt_model.append(row=[i, n, f,
_nd.format_str(self.examplename, f)])
self.dbstate.db.name_formats = _nd.get_name_format(only_custom=True,
self.dbstate.db.name_formats = _nd.get_name_format(only_custom=True,
only_active=False)
def cb_del_fmt_str(self,obj):
def cb_del_fmt_str(self, obj):
"""
Name format editor Remove button callback
"""
@ -424,11 +424,11 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
self.fmt_model.remove(self.iter)
_nd.set_format_inactive(num)
self.dbstate.db.name_formats = _nd.get_name_format(only_custom=True,
self.dbstate.db.name_formats = _nd.get_name_format(only_custom=True,
only_active=False)
def add_formats_panel(self):
table = gtk.Table(3,8)
table = gtk.Table(3, 8)
table.set_border_width(12)
table.set_col_spacings(6)
table.set_row_spacings(6)
@ -453,7 +453,7 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
for item in formats:
obox.append_text(item)
obox.set_active(Config.get(Config.SURNAME_GUESSING))
obox.connect('changed',
obox.connect('changed',
lambda obj: Config.set(Config.SURNAME_GUESSING,
obj.get_active()))
@ -462,7 +462,7 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
table.attach(obox, 1, 3, 1, 2, yoptions=0)
obox = gtk.combo_box_new_text()
formats = [_("Active person's name and ID"),
formats = [_("Active person's name and ID"),
_("Relationship to home person")]
for item in formats:
@ -473,14 +473,14 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
obox.set_active(0)
else:
obox.set_active(1)
obox.connect('changed',
obox.connect('changed',
lambda obj: Config.set(Config.STATUSBAR, 2*obj.get_active()))
lwidget = BasicLabel("%s: " % _('Status bar'))
table.attach(lwidget, 0, 1, 2, 3, yoptions=0)
table.attach(obox, 1, 3, 2, 3, yoptions=0)
self.add_checkbox(table, _("Show text in sidebar buttons (takes effect on restart)"),
self.add_checkbox(table, _("Show text in sidebar buttons (takes effect on restart)"),
4, Config.SIDEBAR_TEXT)
return table
@ -489,50 +489,50 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
from QuestionDialog import OkDialog
Config.set(Config.DATE_FORMAT, obj.get_active())
OkDialog(_('Change is not immediate'),
OkDialog(_('Change is not immediate'),
_('Changing the data format will not take '
'effect until the next time GRAMPS is started.'))
def add_behavior_panel(self):
table = gtk.Table(3,8)
table = gtk.Table(3, 8)
table.set_border_width(12)
table.set_col_spacings(6)
table.set_row_spacings(6)
self.add_checkbox(table, _('Add default source on import'),
self.add_checkbox(table, _('Add default source on import'),
0, Config.DEFAULT_SOURCE)
self.add_checkbox(table, _('Enable spelling checker'),
self.add_checkbox(table, _('Enable spelling checker'),
1, Config.SPELLCHECK)
self.add_checkbox(table, _('Display Tip of the Day'),
self.add_checkbox(table, _('Display Tip of the Day'),
2, Config.USE_TIPS)
self.add_checkbox(table, _('Use shading in Relationship View'),
self.add_checkbox(table, _('Use shading in Relationship View'),
3, Config.RELATION_SHADE)
self.add_checkbox(table, _('Display edit buttons on Relationship View'),
self.add_checkbox(table, _('Display edit buttons on Relationship View'),
4, Config.RELEDITBTN)
self.add_checkbox(table, _('Remember last view displayed'),
self.add_checkbox(table, _('Remember last view displayed'),
5, Config.USE_LAST_VIEW)
return table
def add_database_panel(self):
table = gtk.Table(3,8)
table = gtk.Table(3, 8)
table.set_border_width(12)
table.set_col_spacings(6)
table.set_row_spacings(6)
self.add_entry(table, _('Database path'), 0, Config.DATABASE_PATH)
self.add_checkbox(table, _('Automatically backup database on exit'),
self.add_checkbox(table, _('Automatically backup database on exit'),
1, Config.ENABLE_AUTOBACKUP)
self.add_checkbox(table, _('Automatically load last database'),
self.add_checkbox(table, _('Automatically load last database'),
2, Config.AUTOLOAD)
self.add_checkbox(table, _('Enable database transactions'),
self.add_checkbox(table, _('Enable database transactions'),
3, Config.TRANSACTIONS)
return table
def add_checkbox(self, table, label, index, constant):
checkbox = gtk.CheckButton(label)
checkbox.set_active(Config.get(constant))
checkbox.connect('toggled',self.update_checkbox, constant)
checkbox.connect('toggled', self.update_checkbox, constant)
table.attach(checkbox, 1, 3, index, index+1, yoptions=0)
def add_entry(self, table, label, index, constant):
@ -540,7 +540,7 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
entry = gtk.Entry()
entry.set_text(Config.get(constant))
entry.connect('changed', self.update_entry, constant)
table.attach(lwidget, 0, 1, index, index+1, yoptions=0,
table.attach(lwidget, 0, 1, index, index+1, yoptions=0,
xoptions=gtk.FILL)
table.attach(entry, 1, 2, index, index+1, yoptions=0)
@ -550,8 +550,8 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
color = gtk.gdk.color_parse(hexval)
entry = gtk.ColorButton(color=color)
color_hex_label = BasicLabel(hexval)
entry.connect('color-set',self.update_color,constant,color_hex_label)
table.attach(lwidget, 0, 1, index, index+1, yoptions=0,
entry.connect('color-set', self.update_color, constant, color_hex_label)
table.attach(lwidget, 0, 1, index, index+1, yoptions=0,
xoptions=gtk.FILL)
table.attach(entry, 1, 2, index, index+1, yoptions=0, xoptions=0)
table.attach(color_hex_label, 2, 3, index, index+1, yoptions=0)
@ -562,8 +562,8 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
def update_color(self, obj, constant, color_hex_label):
color = obj.get_color()
hexval = "#%02x%02x%02x" % (color.red/256,
color.green/256,
hexval = "#%02x%02x%02x" % (color.red/256,
color.green/256,
color.blue/256)
color_hex_label.set_text(hexval)
Config.set(constant, hexval)
@ -571,8 +571,8 @@ class GrampsPreferences(ManagedWindow.ManagedWindow):
def update_checkbox(self, obj, constant):
Config.set(constant, obj.get_active())
def build_menu_names(self,obj):
return (_('Preferences'),None)
def build_menu_names(self, obj):
return (_('Preferences'), None)
# FIXME: is this needed?
def _set_button(stock):
@ -594,7 +594,7 @@ class NameFormatEditDlg:
self.name = name
self.valid = True
self.top = gtk.glade.XML(const.gladeFile, 'namefmt_edit','gramps')
self.top = gtk.glade.XML(const.gladeFile, 'namefmt_edit', 'gramps')
self.dlg = self.top.get_widget('namefmt_edit')
ManagedWindow.set_titles(self.dlg, None, _('Name Format Editor'))
@ -619,9 +619,9 @@ class NameFormatEditDlg:
if self.response == gtk.RESPONSE_OK:
if not self.valid:
q = QuestionDialog.QuestionDialog2(
_('The format definition is invalid'),
_('What would you like to do?'),
_('_Continue anyway'), _('_Modify format'),
_('The format definition is invalid'),
_('What would you like to do?'),
_('_Continue anyway'), _('_Modify format'),
parent=self.dlg)
running = not q.run()
self.response = gtk.RESPONSE_CANCEL
@ -629,7 +629,7 @@ class NameFormatEditDlg:
self.response = gtk.RESPONSE_CANCEL
elif (self.fmt_name == '') ^ (self.fmt_str == ''):
QuestionDialog.ErrorDialog(
_('Both Format name and definition have to be defined'),
_('Both Format name and definition have to be defined'),
parent=self.dlg)
running = True

View File

@ -8,7 +8,7 @@
# 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,
# 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.
@ -18,6 +18,10 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
"""
Provides the basic functionality for a list view
"""
#-------------------------------------------------------------------------
#
# GTK
@ -26,7 +30,6 @@
import gtk
import pango
import const
gtk26 = gtk.pygtk_version >= (2,6,0)
#-------------------------------------------------------------------------
#
@ -48,19 +51,22 @@ NOSORT = -1
#-------------------------------------------------------------------------
class ListModel:
def __init__(self,tree,dlist,select_func=None,
event_func=None,mode=gtk.SELECTION_SINGLE):
def __init__(self, tree, dlist, select_func=None, event_func=None,
mode=gtk.SELECTION_SINGLE):
self.tree = tree
self.tree.set_fixed_height_mode(True)
self.mylist = []
self.data_index = 0
for l in dlist:
if len(l)>3:
if l[3] == TOGGLE:
self.sel_iter = None
for info in dlist:
if len(info) > 3:
if info[3] == TOGGLE:
self.mylist.append(bool)
elif l[3] == IMAGE:
elif info[3] == IMAGE:
self.mylist.append(gtk.gdk.Pixbuf)
elif l[3] == INTEGER:
elif info[3] == INTEGER:
self.mylist.append(int)
else:
self.mylist.append(str)
@ -78,50 +84,48 @@ class ListModel:
self.cids = []
self.idmap = {}
self.__build_columns(dlist)
self.__connect_model()
if select_func:
self.selection.connect('changed', select_func)
if event_func:
self.double_click = event_func
self.tree.connect('event', self.__button_press)
def __build_columns(self, dlist):
"""
Builds the columns based of the data in dlist
"""
cnum = 0
for name in dlist:
if not name[2]:
continue
for name in [ item for item in dlist if item[2]]:
if len(name) == 3:
name = (name[0],name[1],name[2],TEXT,False, None)
name = (name[0], name[1], name[2], TEXT, False, None)
elif len(name) == 4:
name = (name[0],name[1],name[2],name[3],False, None)
name = (name[0], name[1], name[2], name[3], False, None)
if name[0] and name[3] == TOGGLE:
renderer = gtk.CellRendererToggle()
column = gtk.TreeViewColumn(name[0],renderer)
column.add_attribute(renderer,'active',cnum)
column = gtk.TreeViewColumn(name[0], renderer)
column.add_attribute(renderer, 'active', cnum)
elif name[0] and name[3] == IMAGE:
renderer = gtk.CellRendererPixbuf()
column = gtk.TreeViewColumn(name[0],renderer)
column.add_attribute(renderer,'pixbuf',cnum)
renderer.set_property('height',const.thumbScale/2)
elif gtk26 and name[3] == COMBO:
store = gtk.ListStore(str)
model = gtk.ListStore(str, object)
for val in name[4]:
model.append((val,store))
self.function[cnum] = name[5]
renderer = gtk.CellRendererCombo()
renderer.set_property('model',model)
renderer.set_property('text_column',0)
renderer.set_fixed_height_from_font(True)
renderer.set_property('editable',True)
renderer.connect('edited',self.edited_cb, cnum)
column = gtk.TreeViewColumn(name[0],renderer,text=cnum)
column.set_reorderable(True)
column = gtk.TreeViewColumn(name[0], renderer)
column.add_attribute(renderer, 'pixbuf', cnum)
renderer.set_property('height', const.thumbScale/2)
else:
renderer = gtk.CellRendererText()
renderer.set_fixed_height_from_font(True)
renderer.set_property('ellipsize', pango.ELLIPSIZE_END)
if name[5]:
renderer.set_property('editable',True)
renderer.connect('edited',self.edited_cb, cnum)
renderer.set_property('editable', True)
renderer.connect('edited', self.__edited_cb, cnum)
self.function[cnum] = name[5]
else:
renderer.set_property('editable',False)
column = gtk.TreeViewColumn(name[0],renderer,text=cnum)
renderer.set_property('editable', False)
column = gtk.TreeViewColumn(name[0], renderer, text=cnum)
column.set_reorderable(True)
column.set_min_width(name[2])
@ -143,26 +147,30 @@ class ListModel:
if name[0] != '':
self.tree.append_column(column)
self.connect_model()
if select_func:
self.selection.connect('changed',select_func)
if event_func:
self.double_click = event_func
self.tree.connect('event',self.button_press)
def edited_cb(self, cell, path, new_text, col):
def __edited_cb(self, cell, path, new_text, col):
"""
Callback executed when the text of the cell renderer has changed
"""
self.model[path][col] = new_text
if self.function.has_key(col):
self.function[col](int(path),new_text)
self.function[col](int(path), new_text)
def unselect(self):
"""
Removes the selection from the view
"""
self.selection.unselect_all()
def set_reorderable(self,order):
def set_reorderable(self, order):
"""
Enables or disables reordering of data
"""
self.tree.set_reorderable(order)
def new_model(self):
"""
Creates a new model instance
"""
if self.model:
self.cid = self.model.get_sort_column_id()
del self.model
@ -174,7 +182,10 @@ class ListModel:
self.selection.set_mode(self.mode)
self.sel_iter = None
def connect_model(self):
def __connect_model(self):
"""
Connects the model to the associated tree
"""
self.tree.set_model(self.model)
if self.sel_iter:
self.selection.select_iter(self.sel_iter)
@ -184,31 +195,43 @@ class ListModel:
val = self.model.get_sort_column_id()
if val[0] == -2 and self.cid:
self.model.set_sort_column_id(self.cid[0],self.cid[1])
self.model.set_sort_column_id(self.cid[0], self.cid[1])
self.sort()
def sort(self):
"""
Sorts the current view
"""
val = self.model.get_sort_column_id()
col = val[0]
if col < 0:
return
if col > 0:
self.model.set_sort_column_id(col,val[1])
self.model.set_sort_column_id(col, val[1])
else:
self.model.set_sort_column_id(self.cids[0],val[1])
self.model.set_sort_column_id(self.cids[0], val[1])
self.model.sort_column_changed()
def get_selected(self):
"""
Returns the selected items
"""
return self.selection.get_selected()
def get_row_at(self,x,y):
path = self.tree.get_path_at_pos(x,y)
def get_row_at(self, xpos, ypos):
"""
Returns the row at the specified (x,y) coordinates
"""
path = self.tree.get_path_at_pos(xpos, ypos)
if path == None:
return self.count -1
else:
return path[0][0]-1
def get_selected_row(self):
"""
Gets the selected row number
"""
store, node = self.selection.get_selected()
if node:
rows = store.get_path(node)
@ -220,75 +243,75 @@ class ListModel:
if self.count == 0:
return []
elif self.mode == gtk.SELECTION_SINGLE:
store,node = self.selection.get_selected()
store, node = self.selection.get_selected()
if node:
return [self.model.get_value(node,self.data_index)]
return [self.model.get_value(node, self.data_index)]
else:
return []
else:
mlist = []
self.selection.selected_foreach(self.blist,mlist)
self.selection.selected_foreach(self.blist, mlist)
return mlist
def get_icon(self):
if self.mode == gtk.SELECTION_SINGLE:
store,node = self.selection.get_selected()
store, node = self.selection.get_selected()
path = self.model.get_path(node)
else:
mlist = []
self.selection.selected_foreach(self.blist,mlist)
self.selection.selected_foreach(self.blist, mlist)
path = self.model.get_path(mlist[0])
return self.tree.create_row_drag_icon(path)
def blist(self,store,path,node,list):
list.append(self.model.get_value(node,self.data_index))
def blist(self, store, path, node, dlist):
dlist.append(self.model.get_value(node, self.data_index))
def clear(self):
self.count = 0
self.model.clear()
def remove(self,node):
def remove(self, node):
self.model.remove(node)
self.count -= 1
def get_row(self,node):
def get_row(self, node):
row = self.model.get_path(node)
return row[0]
def select_row(self,row):
def select_row(self, row):
self.selection.select_path((row))
def select_iter(self,node):
def select_iter(self, node):
self.selection.select_iter(node)
def get_object(self,node):
return self.model.get_value(node,self.data_index)
def get_object(self, node):
return self.model.get_value(node, self.data_index)
def insert(self,position,data,info=None,select=0):
def insert(self, position, data, info=None, select=0):
self.count += 1
node = self.model.insert(position)
col = 0
for obj in data:
self.model.set_value(node,col,obj)
self.model.set_value(node, col, obj)
col += 1
self.model.set_value(node,col,info)
self.model.set_value(node, col, info)
if info:
self.idmap[str(info)] = node
if select:
self.selection.select_iter(node)
return node
def get_data(self,node,cols):
return [ self.model.get_value(node,c) for c in cols ]
def get_data(self, node, cols):
return [ self.model.get_value(node, c) for c in cols ]
def add(self,data,info=None,select=0):
def add(self, data, info=None, select=0):
self.count += 1
node = self.model.append()
col = 0
for obj in data:
self.model.set_value(node,col,obj)
self.model.set_value(node, col, obj)
col += 1
self.model.set_value(node,col,info)
self.model.set_value(node, col, info)
if info:
self.idmap[str(info)] = node
if select:
@ -296,43 +319,46 @@ class ListModel:
self.selection.select_iter(self.sel_iter)
return node
def set(self,node,data,info=None,select=0):
def set(self, node, data, info=None, select=0):
col = 0
for obj in data:
self.model.set_value(node,col,obj)
self.model.set_value(node, col, obj)
col += 1
self.model.set_value(node,col,info)
self.model.set_value(node, col, info)
if info:
self.idmap[str(info)] = node
if select:
self.sel_iter = node
return node
def add_and_select(self,data,info=None):
def add_and_select(self, data, info=None):
self.count += 1
node = self.model.append()
col = 0
for obj in data:
self.model.set_value(node,col,obj)
self.model.set_value(node, col, obj)
col += 1
if info:
self.idmap[str(info)] = node
self.model.set_value(node,col,info)
self.model.set_value(node, col, info)
self.selection.select_iter(node)
def center_selected(self):
model,node = self.selection.get_selected()
model, node = self.selection.get_selected()
if node:
path = model.get_path(node)
self.tree.scroll_to_cell(path,None,True,0.5,0.5)
self.tree.scroll_to_cell(path, None, True, 0.5, 0.5)
def button_press(self,obj,event):
def __button_press(self, obj, event):
"""
Called when a button press is executed
"""
if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1:
self.double_click(obj)
return True
return False
def find(self,info):
def find(self, info):
if info in self.idmap.keys():
node = self.idmap[str(info)]
self.selection.select_iter(node)