scratchpad/drag-n-drop fixes

svn: r6194
This commit is contained in:
Don Allingham 2006-03-22 23:03:57 +00:00
parent dcf4c6f2a2
commit 621d8757ee
24 changed files with 273 additions and 114 deletions

View File

@ -1,3 +1,29 @@
2006-03-22 Don Allingham <don@gramps-project.org>
* src/DataViews/_SourceView.py: handle drag and drop
* src/DataViews/_PersonView.py: handle drag and drop
* src/ViewManager.py: pychecker fixes
* src/RelLib/_Person.py: pychecker fixes
* src/RelLib/_Date.py: pychecker fixes
* src/RelLib/_Family.py: pychecker fixes
* src/RelLib/_Note.py: pychecker fixes
* src/RelLib/_EventRef.py: pychecker fixes
* src/PeopleModel.py: pychecker fixes
* src/DisplayModels.py: pychecker fixes
* src/DisplayTabs.py: allow a display tab to handle other dnd types other
than the default. This allows reference tabs to catch their sources. SourceTab
can now handle catching both a sourceref and a source, for example.
* src/Utils.py: pychecker
* src/NameDisplay.py: pychecker
* src/ScratchPad.py: unified dnd handling with rest of system.
* src/DdTargets.py: support for new types (refs and handles)
* src/DateEdit.py: pychecker
* src/ListModel.py: pychecker
* src/gramps_main.py: pychecker
* src/BaseDoc.py: pychecker
* src/SelectSource.py: pychecker
* src/ImgManip.py: pychecker
* src/PageView.py: drag-n-drop fixes
2006-03-22 Martin Hawlisch <Martin.Hawlisch@gmx.de> 2006-03-22 Martin Hawlisch <Martin.Hawlisch@gmx.de>
* src/Utils.py: Add wrappers for displaying the tuple types * src/Utils.py: Add wrappers for displaying the tuple types
* src/DataViews/_PedigreeView.py, * src/DataViews/_PedigreeView.py,

View File

@ -1235,7 +1235,6 @@ class BaseDoc:
self.title = name self.title = name
def add_draw_style(self,name,style): def add_draw_style(self,name,style):
assert(self.init_called==False)
self.draw_styles[name] = GraphicsStyle(style) self.draw_styles[name] = GraphicsStyle(style)
def get_draw_style(self,name): def get_draw_style(self,name):

View File

@ -37,6 +37,7 @@ import PageView
import DisplayModels import DisplayModels
import const import const
import Utils import Utils
from DdTargets import DdTargets
from QuestionDialog import QuestionDialog, ErrorDialog from QuestionDialog import QuestionDialog, ErrorDialog
from Editors import EditEvent, DelEventQuery from Editors import EditEvent, DelEventQuery
@ -77,6 +78,9 @@ class EventView(PageView.ListView):
DisplayModels.EventModel, DisplayModels.EventModel,
signal_map) signal_map)
def drag_info(self):
return DdTargets.EVENT
def column_order(self): def column_order(self):
return self.dbstate.db.get_event_column_order() return self.dbstate.db.get_event_column_order()

View File

@ -493,22 +493,20 @@ class PersonView(PageView.PersonNavView):
if len(selected_ids) == 1: if len(selected_ids) == 1:
self.tree.drag_source_set(BUTTON1_MASK, self.tree.drag_source_set(BUTTON1_MASK,
[DdTargets.PERSON_LINK.target()], [DdTargets.PERSON_LINK.target()],
ACTION_COPY) ACTION_COPY)
elif len(selected_ids) > 1: elif len(selected_ids) > 1:
self.tree.drag_source_set(BUTTON1_MASK, self.tree.drag_source_set(BUTTON1_MASK,
[DdTargets.PERSON_LINK_LIST.target()], [DdTargets.PERSON_LINK_LIST.target()],
ACTION_COPY) ACTION_COPY)
self.uistate.modify_statusbar() self.uistate.modify_statusbar()
def drag_data_get(self, widget, context, sel_data, info, time): def drag_data_get(self, widget, context, sel_data, info, time):
selected_ids = self.get_selected_objects() selected_ids = self.get_selected_objects()
if len(selected_ids) == 1: data = (DdTargets.PERSON_LINK.drag_type, id(self), selected_ids[0], 0)
sel_data.set(sel_data.target, 8, selected_ids[0])
elif len(selected_ids) > 1: sel_data.set(sel_data.target, 8 ,pickle.dumps(data))
sel_data.set(DdTargets.PERSON_LINK_LIST.drag_type,8,
pickle.dumps(selected_ids))
def person_added(self,handle_list): def person_added(self,handle_list):
self.model.clear_cache() self.model.clear_cache()

View File

@ -37,6 +37,7 @@ import PageView
import DisplayModels import DisplayModels
import const import const
import Utils import Utils
from DdTargets import DdTargets
from Editors import EditSource, DelSrcQuery from Editors import EditSource, DelSrcQuery
from QuestionDialog import QuestionDialog, ErrorDialog from QuestionDialog import QuestionDialog, ErrorDialog
@ -77,6 +78,9 @@ class SourceView(PageView.ListView):
DisplayModels.SourceModel, DisplayModels.SourceModel,
signal_map) signal_map)
def drag_info(self):
return DdTargets.SOURCE_LINK
def define_actions(self): def define_actions(self):
PageView.ListView.define_actions(self) PageView.ListView.define_actions(self)
self.add_action('ColumnEdit', gtk.STOCK_PROPERTIES, self.add_action('ColumnEdit', gtk.STOCK_PROPERTIES,

View File

@ -145,7 +145,7 @@ class DateEdit:
self.pixmap_obj.render_icon(gtk.STOCK_DIALOG_WARNING, self.pixmap_obj.render_icon(gtk.STOCK_DIALOG_WARNING,
gtk.ICON_SIZE_MENU)) gtk.ICON_SIZE_MENU))
def parse_and_check(self,obj,val): def parse_and_check(self,*obj):
""" """
Called with the text box loses focus. Parses the text and calls Called with the text box loses focus. Parses the text and calls
the check() method ONLY if the text has changed. the check() method ONLY if the text has changed.

View File

@ -95,7 +95,7 @@ class _DdTargets(object):
def __new__(cls): def __new__(cls):
"""Ensure that we never have more than one instance.""" """Ensure that we never have more than one instance."""
if _DdTargets._instance is not None: if _DdTargets._instance:
return _DdTargets._instance return _DdTargets._instance
_DdTargets._instance = object.__new__(cls) _DdTargets._instance = object.__new__(cls)
return _DdTargets._instance return _DdTargets._instance
@ -108,7 +108,7 @@ class _DdTargets(object):
self.URL = _DdType(self,'url') self.URL = _DdType(self,'url')
self.EVENT = _DdType(self,'pevent') self.EVENT = _DdType(self,'pevent')
self.EVENTREF = _DdType(self,'peventref') self.EVENTREF = _DdType(self,'eventref')
self.ATTRIBUTE = _DdType(self,'pattr') self.ATTRIBUTE = _DdType(self,'pattr')
self.ADDRESS = _DdType(self,'paddr') self.ADDRESS = _DdType(self,'paddr')
self.SOURCEREF = _DdType(self,'srcref') self.SOURCEREF = _DdType(self,'srcref')
@ -120,6 +120,8 @@ class _DdTargets(object):
self.PERSON_LINK = _DdType(self,'person-link') self.PERSON_LINK = _DdType(self,'person-link')
self.PERSON_LINK_LIST = _DdType(self,'person-link-list') self.PERSON_LINK_LIST = _DdType(self,'person-link-list')
self.SOURCE_LINK = _DdType(self,'source-link')
self.FAMILY_EVENT = _DdType(self,'fevent') self.FAMILY_EVENT = _DdType(self,'fevent')
self.FAMILY_ATTRIBUTE = _DdType(self,'fattr') self.FAMILY_ATTRIBUTE = _DdType(self,'fattr')
@ -130,14 +132,16 @@ class _DdTargets(object):
self.EVENT, self.EVENT,
self.ATTRIBUTE, self.ATTRIBUTE,
self.ADDRESS, self.ADDRESS,
self.SOURCE_LINK,
self.SOURCEREF, self.SOURCEREF,
self.EVENTREF,
self.NAME, self.NAME,
self.MEDIAOBJ, self.MEDIAOBJ,
self.PERSON_LINK, self.PERSON_LINK,
self.PERSON_LINK_LIST] self.PERSON_LINK_LIST]
self.CHILD = _DdType(self,'child') self.CHILD = _DdType(self,'child')
self.SPOUSE = _DdType(self,'spouce') self.SPOUSE = _DdType(self,'spouse')
self.TEXT = _DdType(self,'TEXT',0,1) self.TEXT = _DdType(self,'TEXT',0,1)
self.TEXT_MIME = _DdType(self,'text/plain',0,0) self.TEXT_MIME = _DdType(self,'text/plain',0,0)

View File

@ -36,7 +36,6 @@ log = logging.getLogger(".")
# GNOME/GTK modules # GNOME/GTK modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import gobject
import gtk import gtk
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -52,8 +51,6 @@ import ToolTips
import GrampsLocale import GrampsLocale
import const import const
_GENDER = [ _(u'female'), _(u'male'), _(u'unknown') ]
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# Localized constants # Localized constants

View File

@ -313,6 +313,7 @@ class EmbeddedList(ButtonTab):
_HANDLE_COL = -1 _HANDLE_COL = -1
_DND_TYPE = None _DND_TYPE = None
_DND_EXTRA = None
def __init__(self, dbstate, uistate, track, name, build_model,share=False): def __init__(self, dbstate, uistate, track, name, build_model,share=False):
""" """
@ -350,8 +351,13 @@ class EmbeddedList(ButtonTab):
on the _DND_TYPE. Obviously, this means that there must be a _DND_TYPE on the _DND_TYPE. Obviously, this means that there must be a _DND_TYPE
variable defined that points to an entry in DdTargets. variable defined that points to an entry in DdTargets.
""" """
self.tree.drag_dest_set(gtk.DEST_DEFAULT_ALL, [self._DND_TYPE.target()],
ACTION_COPY) if self._DND_EXTRA:
dnd_types = [ self._DND_TYPE.target(), self._DND_EXTRA.target() ]
else:
dnd_types = [ self._DND_TYPE.target() ]
self.tree.drag_dest_set(gtk.DEST_DEFAULT_ALL, dnd_types, ACTION_COPY)
self.tree.drag_source_set(BUTTON1_MASK, [self._DND_TYPE.target()], ACTION_COPY) self.tree.drag_source_set(BUTTON1_MASK, [self._DND_TYPE.target()], ACTION_COPY)
self.tree.connect('drag_data_get', self.drag_data_get) self.tree.connect('drag_data_get', self.drag_data_get)
self.tree.connect('drag_data_received', self.drag_data_received) self.tree.connect('drag_data_received', self.drag_data_received)
@ -377,8 +383,8 @@ class EmbeddedList(ButtonTab):
return return
# pickle the data, and build the tuple to be passed # pickle the data, and build the tuple to be passed
pickled = pickle.dumps(obj); value = (self._DND_TYPE.drag_type, id(self), obj,self.find_index(obj))
data = str((self._DND_TYPE.drag_type, id(self), pickled, self.find_index(obj))) data = pickle.dumps(value)
# pass as a string (8 bits) # pass as a string (8 bits)
sel_data.set(sel_data.target, 8, data) sel_data.set(sel_data.target, 8, data)
@ -391,10 +397,10 @@ class EmbeddedList(ButtonTab):
and decide if this is a move or a reorder. and decide if this is a move or a reorder.
""" """
if sel_data and sel_data.data: if sel_data and sel_data.data:
exec 'dnddata = %s' % sel_data.data dnddata = pickle.loads(sel_data.data)
mytype = dnddata[0] mytype = dnddata[0]
selfid = dnddata[1] selfid = dnddata[1]
obj = pickle.loads(dnddata[2]) obj = dnddata[2]
row_from = dnddata[3] row_from = dnddata[3]
# make sure this is the correct DND type for this object # make sure this is the correct DND type for this object
@ -411,6 +417,11 @@ class EmbeddedList(ButtonTab):
else: else:
self._handle_drag(row,obj) self._handle_drag(row,obj)
self.rebuild() self.rebuild()
elif self._DND_EXTRA and mytype == self._DND_EXTRA.drag_type:
self.handle_extra_type(mytype,obj)
def handle_extra_type(self, objtype, obj):
pass
def _find_row(self,x,y): def _find_row(self,x,y):
row = self.tree.get_path_at_pos(x,y) row = self.tree.get_path_at_pos(x,y)
@ -568,6 +579,7 @@ class EventEmbedList(EmbeddedList):
_HANDLE_COL = 6 _HANDLE_COL = 6
_DND_TYPE = DdTargets.EVENTREF _DND_TYPE = DdTargets.EVENTREF
_DND_EXTRA = DdTargets.EVENT
_MSG = { _MSG = {
'add' : _('Add a new event'), 'add' : _('Add a new event'),
@ -599,6 +611,22 @@ class EventEmbedList(EmbeddedList):
def column_order(self): def column_order(self):
return ((1,0),(1,1),(1,2),(1,3),(1,4),(1,5)) return ((1,0),(1,1),(1,2),(1,3),(1,4),(1,5))
def handle_extra_type(self, objtype, obj):
from Editors import EditEventRef
try:
ref = RelLib.EventRef()
event = self.dbstate.db.get_event_from_handle(obj)
if self.obj.__class__.__name__ == 'Person':
event.set_type((RelLib.Event.BIRTH,''))
ref.set_role((RelLib.EventRef.PRIMARY,''))
else:
event.set_type((RelLib.Event.MARRIAGE,''))
ref.set_role((RelLib.EventRef.FAMILY,''))
EditEventRef(self.dbstate,self.uistate,self.track,
event, ref, self.obj, self.event_added)
except Errors.WindowActiveError:
pass
def add_button_clicked(self,obj): def add_button_clicked(self,obj):
from Editors import EditEventRef from Editors import EditEventRef
try: try:
@ -1362,6 +1390,7 @@ class SourceEmbedList(EmbeddedList):
_HANDLE_COL = 4 _HANDLE_COL = 4
_DND_TYPE = DdTargets.SOURCEREF _DND_TYPE = DdTargets.SOURCEREF
_DND_EXTRA = DdTargets.SOURCE_LINK
_column_names = [ _column_names = [
(_('ID'), 0, 75), (_('ID'), 0, 75),
@ -1431,6 +1460,18 @@ class SourceEmbedList(EmbeddedList):
self.changed = True self.changed = True
self.rebuild() self.rebuild()
def handle_extra_type(self, objtype, obj):
from Editors import EditSourceRef
sref = RelLib.SourceRef()
src = self.dbstate.db.get_source_from_handle(obj)
try:
EditSourceRef(self.dbstate, self.uistate, self.track,
src, sref, self.add_callback)
except Errors.WindowActiveError:
pass
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# RepoEmbedList # RepoEmbedList

View File

@ -137,8 +137,9 @@ def run_thumbnailer(mtype, frm, to, size=const.thumbScale):
} }
base = '/desktop/gnome/thumbnailers/%s' % mtype.replace('/','@') base = '/desktop/gnome/thumbnailers/%s' % mtype.replace('/','@')
cmd = Config.client.get_string(base + '/command')
enable = Config.client.get_bool(base + '/enable') cmd = Config.get_string(base + '/command')
enable = Config.get_bool(base + '/enable')
if cmd and enable: if cmd and enable:
cmdlist = map(lambda x: sublist.get(x,x),cmd.split()) cmdlist = map(lambda x: sublist.get(x,x),cmd.split())

View File

@ -20,7 +20,6 @@
import gtk import gtk
import pango import pango
import const
gtk26 = gtk.pygtk_version >= (2,6,0) gtk26 = gtk.pygtk_version >= (2,6,0)

View File

@ -136,7 +136,6 @@ class NameDisplay:
""" """
first = raw_data[2] first = raw_data[2]
surname = raw_data[3]
suffix = raw_data[4] suffix = raw_data[4]
prefix = raw_data[7] prefix = raw_data[7]
patronymic = raw_data[8] patronymic = raw_data[8]
@ -152,7 +151,7 @@ class NameDisplay:
else: else:
return "%s %s, %s" % (last, suffix, first) return "%s %s, %s" % (last, suffix, first)
else: else:
if name.prefix: if prefix:
return "%s %s, %s" % (prefix, last, first) return "%s %s, %s" % (prefix, last, first)
else: else:
return "%s, %s" % (last, first) return "%s, %s" % (last, first)

View File

@ -26,6 +26,7 @@
# #
#---------------------------------------------------------------- #----------------------------------------------------------------
from TransUtils import sgettext as _ from TransUtils import sgettext as _
import cPickle as pickle
#---------------------------------------------------------------- #----------------------------------------------------------------
# #
@ -34,6 +35,7 @@ from TransUtils import sgettext as _
#---------------------------------------------------------------- #----------------------------------------------------------------
import gtk import gtk
import pango import pango
from gtk.gdk import ACTION_COPY, BUTTON1_MASK
#---------------------------------------------------------------- #----------------------------------------------------------------
# #
@ -350,6 +352,9 @@ class ListView(PageView):
self.signal_map = signal_map self.signal_map = signal_map
dbstate.connect('database-changed',self.change_db) dbstate.connect('database-changed',self.change_db)
def drag_info(self):
return None
def column_order(self): def column_order(self):
assert False assert False
@ -373,6 +378,8 @@ class ListView(PageView):
self.list.set_fixed_height_mode(True) self.list.set_fixed_height_mode(True)
self.list.connect('button-press-event',self.button_press) self.list.connect('button-press-event',self.button_press)
self.list.connect('key-press-event',self.key_press) self.list.connect('key-press-event',self.key_press)
if self.drag_info():
self.list.connect('drag_data_get', self.drag_data_get)
scrollwindow = gtk.ScrolledWindow() scrollwindow = gtk.ScrolledWindow()
scrollwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scrollwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
@ -389,12 +396,33 @@ class ListView(PageView):
self.columns = [] self.columns = []
self.build_columns() self.build_columns()
self.selection = self.list.get_selection() self.selection = self.list.get_selection()
#self.selection.connect('changed',self.row_changed) self.selection.connect('changed',self.row_changed)
self.setup_filter() self.setup_filter()
return self.vbox return self.vbox
def row_changed(self,obj):
"""Called with a row is changed. Check the selected objects from
the person_tree to get the IDs of the selected objects. Set the
active person to the first person in the list. If no one is
selected, set the active person to None"""
if self.drag_info():
selected_ids = self.selected_handles()
if len(selected_ids) == 1:
self.list.drag_source_set(BUTTON1_MASK,
[self.drag_info().target()],
ACTION_COPY)
def drag_data_get(self, widget, context, sel_data, info, time):
selected_ids = self.selected_handles()
data = (self.drag_info().drag_type, id(self), selected_ids[0], 0)
sel_data.set(sel_data.target, 8 ,pickle.dumps(data))
def setup_filter(self): def setup_filter(self):
""" """
Builds the default filters and add them to the filter menu. Builds the default filters and add them to the filter menu.

View File

@ -29,11 +29,8 @@ from TransUtils import sgettext as _
import time import time
import cgi import cgi
import sys import sys
import traceback
import locale import locale
import cPickle as pickle
try: try:
set() set()
except: except:
@ -52,9 +49,7 @@ log = logging.getLogger(".")
# GTK modules # GTK modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import gobject
import gtk import gtk
import pango
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -66,6 +61,8 @@ import NameDisplay
import DateHandler import DateHandler
import ToolTips import ToolTips
import GrampsLocale import GrampsLocale
import Utils
import const
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #

View File

@ -512,7 +512,7 @@ class Date:
if self.is_compound(): if self.is_compound():
ry = max(self.dateval[Date._POS_RYR],1) ry = max(self.dateval[Date._POS_RYR],1)
rm = max(self.dateval[Date._POS_RMON],1) rm = max(self.dateval[Date._POS_RMON],1)
rd = max(self.dateval[_POS_RDAY],1) rd = max(self.dateval[Date._POS_RDAY],1)
sdn = Date._calendar_convert[self.calendar](ry,rm,rd) sdn = Date._calendar_convert[self.calendar](ry,rm,rd)
(ny,nm,nd) = Date._calendar_change[calendar](sdn) (ny,nm,nd) = Date._calendar_change[calendar](sdn)
self.dateval = (d,m,y,self.dateval[Date._POS_SL], self.dateval = (d,m,y,self.dateval[Date._POS_SL],

View File

@ -68,6 +68,7 @@ class EventRef(BaseObject,PrivacyBase,NoteBase):
""" """
Creates a new EventRef instance, copying from the source if present. Creates a new EventRef instance, copying from the source if present.
""" """
BaseObject.__init__(self)
PrivacyBase.__init__(self) PrivacyBase.__init__(self)
NoteBase.__init__(self) NoteBase.__init__(self)
if source: if source:

View File

@ -437,7 +437,7 @@ class Family(PrimaryObject,SourceNote,MediaBase,AttributeBase):
Person's L{EventRef} list. Person's L{EventRef} list.
@type event_ref: EventRef @type event_ref: EventRef
""" """
if event_ref is not None and not isinstance(event_ref,EventRef): if event_ref and not isinstance(event_ref,EventRef):
raise ValueError("Expecting EventRef instance") raise ValueError("Expecting EventRef instance")
self.event_ref_list.append(event_ref) self.event_ref_list.append(event_ref)

View File

@ -57,7 +57,7 @@ class Note(BaseObject):
return (self.text,self.format) return (self.text,self.format)
def unserialize(self,data): def unserialize(self,data):
if data is not None: if data:
(self.text,self.format) = data (self.text,self.format) = data
return self return self

View File

@ -245,7 +245,7 @@ class Person(PrimaryObject,SourceNote,
elif classname == 'Place': elif classname == 'Place':
for ordinance in [self.lds_bapt,self.lds_endow,self.lds_seal]: for ordinance in [self.lds_bapt,self.lds_endow,self.lds_seal]:
if ordinance.place in handle_list: if ordinance.place in handle_list:
ordinance.place == None ordinance.place = None
def _replace_handle_reference(self,classname,old_handle,new_handle): def _replace_handle_reference(self,classname,old_handle,new_handle):
if classname == 'Event': if classname == 'Event':
@ -273,7 +273,7 @@ class Person(PrimaryObject,SourceNote,
elif classname == 'Place': elif classname == 'Place':
for ordinance in [self.lds_bapt,self.lds_endow,self.lds_seal]: for ordinance in [self.lds_bapt,self.lds_endow,self.lds_seal]:
if ordinance.place == old_handle: if ordinance.place == old_handle:
ordinance.place == new_handle ordinance.place = new_handle
def get_text_data_list(self): def get_text_data_list(self):
""" """
@ -456,7 +456,7 @@ class Person(PrimaryObject,SourceNote,
the Person's birth. the Person's birth.
@type event_handle: EventRef @type event_handle: EventRef
""" """
if event_ref is not None and not isinstance(event_ref,EventRef): if event_ref and not isinstance(event_ref,EventRef):
raise ValueError("Expecting EventRef instance") raise ValueError("Expecting EventRef instance")
self.birth_ref = event_ref self.birth_ref = event_ref
@ -479,7 +479,7 @@ class Person(PrimaryObject,SourceNote,
the Person's death. the Person's death.
@type event_handle: EventRef @type event_handle: EventRef
""" """
if event_ref is not None and not isinstance(event_ref,EventRef): if event_ref and not isinstance(event_ref,EventRef):
raise ValueError("Expecting EventRef instance") raise ValueError("Expecting EventRef instance")
self.death_ref = event_ref self.death_ref = event_ref
@ -542,7 +542,7 @@ class Person(PrimaryObject,SourceNote,
Person's L{EventRef} list. Person's L{EventRef} list.
@type event_ref: EventRef @type event_ref: EventRef
""" """
if event_ref is not None and not isinstance(event_ref,EventRef): if event_ref and not isinstance(event_ref,EventRef):
raise ValueError("Expecting EventRef instance") raise ValueError("Expecting EventRef instance")
self.event_ref_list.append(event_ref) self.event_ref_list.append(event_ref)

View File

@ -29,6 +29,8 @@ import cPickle as pickle
import os import os
from xml.sax.saxutils import escape from xml.sax.saxutils import escape
from TransUtils import sgettext as _ from TransUtils import sgettext as _
import Utils
import RelLib
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -105,9 +107,7 @@ class ScratchPadGrampsTypeWrapper(ScratchPadWrapper):
ScratchPadWrapper.__init__(self,dbstate,obj) ScratchPadWrapper.__init__(self,dbstate,obj)
#unpack object #unpack object
exec 'unpack_data = %s' % self._obj (drag_type, idval, self._obj, val) = pickle.loads(obj)
exec 'o_type = "%s"' % unpack_data[0]
self._obj = pickle.loads(unpack_data[2])
self._pickle = obj self._pickle = obj
def pack(self): def pack(self):
@ -175,45 +175,50 @@ class ScratchPadAddress(ScratchPadGrampsTypeWrapper):
return s return s
class ScratchPadEvent(ScratchPadGrampsTypeWrapper): class ScratchPadEvent(ScratchPadWrapper):
DROP_TARGETS = [DdTargets.EVENT] DROP_TARGETS = [DdTargets.EVENT]
DRAG_TARGET = DdTargets.EVENT DRAG_TARGET = DdTargets.EVENT
ICON = LINK_PIC ICON = LINK_PIC
def __init__(self,dbstate,obj): def __init__(self,dbstate,obj):
ScratchPadGrampsTypeWrapper.__init__(self,dbstate,obj) ScratchPadWrapper.__init__(self,dbstate,obj)
self._type = _("Event") self._type = _("Event")
self._title = Utils.format_personal_event(self._obj.get_name())
self._value = self._obj.get_description()
(drag_type, idval, handle, val) = pickle.loads(obj)
value = dbstate.db.get_event_from_handle(handle)
self._title = Utils.format_personal_event(value.get_type())
self._value = value.get_description()
def tooltip(self): def tooltip(self):
global escape global escape
return ""
s = "<big><b>%s</b></big>\n\n"\ # s = "<big><b>%s</b></big>\n\n"\
"\t<b>%s:</b>\t%s\n"\ # "\t<b>%s:</b>\t%s\n"\
"\t<b>%s:</b>\t%s\n"\ # "\t<b>%s:</b>\t%s\n"\
"\t<b>%s:</b>\t%s\n"\ # "\t<b>%s:</b>\t%s\n"\
"\t<b>%s:</b>\t%s\n"\ # "\t<b>%s:</b>\t%s\n"\
"\t<b>%s:</b>\t%s\n" % ( # "\t<b>%s:</b>\t%s\n" % (
_("Event"), # _("Event"),
_("Type"),escape(Utils.format_personal_event(self._obj.get_name())), # _("Type"),escape(Utils.format_personal_event(self._obj.get_name())),
_("Date"),escape(DateHander.get_date(self._obj)), # _("Date"),escape(DateHander.get_date(self._obj)),
_("Place"),escape(place_title(self._db,self._obj)), # _("Place"),escape(place_title(self._db,self._obj)),
_("Cause"),escape(self._obj.get_cause()), # _("Cause"),escape(self._obj.get_cause()),
_("Description"), escape(self._obj.get_description())) # _("Description"), escape(self._obj.get_description()))
if len(self._obj.get_source_references()) > 0: # if len(self._obj.get_source_references()) > 0:
psrc_ref = self._obj.get_source_references()[0] # psrc_ref = self._obj.get_source_references()[0]
psrc_id = psrc_ref.get_base_handle() # psrc_id = psrc_ref.get_base_handle()
psrc = self._db.get_source_from_handle(psrc_id) # psrc = self._db.get_source_from_handle(psrc_id)
s += "\n<big><b>%s</b></big>\n\n"\ # s += "\n<big><b>%s</b></big>\n\n"\
"\t<b>%s:</b>\t%s\n" % ( # "\t<b>%s:</b>\t%s\n" % (
_("Primary source"), # _("Primary source"),
_("Name"), # _("Name"),
escape(short(psrc.get_title()))) # escape(short(psrc.get_title())))
return s return s
@ -356,11 +361,11 @@ class ScratchPadSourceRef(ScratchPadGrampsTypeWrapper):
def __init__(self,dbstate,obj): def __init__(self,dbstate,obj):
ScratchPadGrampsTypeWrapper.__init__(self,dbstate,obj) ScratchPadGrampsTypeWrapper.__init__(self,dbstate,obj)
self._type = _("SourceRef") self._type = _("Source Reference")
base = self._db.get_source_from_handle(self._obj.get_base_handle()) base = self._db.get_source_from_handle(self._obj.get_base_handle())
self._title = base.get_title() self._title = base.get_title()
self._value = self._obj.get_text(), self._value = self._obj.get_text()
def tooltip(self): def tooltip(self):
global escape global escape
@ -378,6 +383,28 @@ class ScratchPadSourceRef(ScratchPadGrampsTypeWrapper):
return s return s
class ScratchPadEventRef(ScratchPadGrampsTypeWrapper):
DROP_TARGETS = [DdTargets.EVENTREF]
DRAG_TARGET = DdTargets.EVENTREF
ICON = BLANK_PIC
def __init__(self,dbstate,obj):
ScratchPadGrampsTypeWrapper.__init__(self,dbstate,obj)
self._type = _("EventRef")
base = self._db.get_event_from_handle(self._obj.ref)
self._title = base.get_description()
value = base.get_type()
if value == RelLib.Event.CUSTOM:
self._value = value[1]
else:
self._value = Utils.personal_events[value[0]]
def tooltip(self):
return ""
class ScratchPadName(ScratchPadGrampsTypeWrapper): class ScratchPadName(ScratchPadGrampsTypeWrapper):
DROP_TARGETS = [DdTargets.NAME] DROP_TARGETS = [DdTargets.NAME]
@ -388,8 +415,11 @@ class ScratchPadName(ScratchPadGrampsTypeWrapper):
ScratchPadGrampsTypeWrapper.__init__(self,dbstate,obj) ScratchPadGrampsTypeWrapper.__init__(self,dbstate,obj)
self._type = _("Name") self._type = _("Name")
self._title = self._obj.get_name() self._title = self._obj.get_name()
self._value = self._obj.get_type() value = self._obj.get_type()
if value == RelLib.Name.CUSTOM:
self._value = value[1]
else:
self._value = Utils.name_types[value[0]]
def tooltip(self): def tooltip(self):
global escape global escape
@ -462,10 +492,13 @@ class ScratchPersonLink(ScratchPadWrapper):
ScratchPadWrapper.__init__(self,dbstate,obj) ScratchPadWrapper.__init__(self,dbstate,obj)
self._type = _("Person Link") self._type = _("Person Link")
person = self._db.get_person_from_handle(self._obj) (drag_type, idval, handle, val) = pickle.loads(obj)
person = self._db.get_person_from_handle(handle)
self._title = person.get_primary_name().get_name() self._title = person.get_primary_name().get_name()
birth_handle = person.get_birth_handle() birth_ref = person.get_birth_ref()
if birth_handle: if birth_ref:
birth_handle = birth_ref.ref
birth = self._db.get_event_from_handle(birth_handle) birth = self._db.get_event_from_handle(birth_handle)
date_str = DateHandler.get_date(birth) date_str = DateHandler.get_date(birth)
if date_str != "": if date_str != "":
@ -497,6 +530,27 @@ class ScratchPersonLink(ScratchPadWrapper):
return s return s
class ScratchSourceLink(ScratchPadWrapper):
DROP_TARGETS = [DdTargets.SOURCE_LINK]
DRAG_TARGET = DdTargets.SOURCE_LINK
ICON = LINK_PIC
def __init__(self,dbstate,obj):
ScratchPadWrapper.__init__(self,dbstate,obj)
self._type = _("Source Link")
(drag_type, idval, handle, val) = pickle.loads(obj)
source = self._db.get_source_from_handle(handle)
self._title = source.get_title()
self._value = source.get_gramps_id()
def tooltip(self):
return ""
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# Wrapper classes to deal with lists of objects # Wrapper classes to deal with lists of objects
@ -646,18 +700,19 @@ class ScratchPadListView:
def register_wrapper_classes(self): def register_wrapper_classes(self):
self.register_wrapper_class(ScratchPadAddress) self.register_wrapper_class(ScratchPadAddress)
self.register_wrapper_class(ScratchPadEvent) self.register_wrapper_class(ScratchPadEvent)
self.register_wrapper_class(ScratchPadEventRef)
self.register_wrapper_class(ScratchPadSourceRef)
self.register_wrapper_class(ScratchPadFamilyEvent) self.register_wrapper_class(ScratchPadFamilyEvent)
self.register_wrapper_class(ScratchPadUrl) self.register_wrapper_class(ScratchPadUrl)
self.register_wrapper_class(ScratchPadAttribute) self.register_wrapper_class(ScratchPadAttribute)
self.register_wrapper_class(ScratchPadFamilyAttribute) self.register_wrapper_class(ScratchPadFamilyAttribute)
self.register_wrapper_class(ScratchPadSourceRef)
self.register_wrapper_class(ScratchPadName) self.register_wrapper_class(ScratchPadName)
self.register_wrapper_class(ScratchPadText) self.register_wrapper_class(ScratchPadText)
self.register_wrapper_class(ScratchMediaObj) self.register_wrapper_class(ScratchMediaObj)
self.register_wrapper_class(ScratchSourceLink)
self.register_wrapper_class(ScratchPersonLink) self.register_wrapper_class(ScratchPersonLink)
self.register_wrapper_class(ScratchPersonLinkList) self.register_wrapper_class(ScratchPersonLinkList)
def register_wrapper_class(self,wrapper_class): def register_wrapper_class(self,wrapper_class):
for drop_target in wrapper_class.DROP_TARGETS: for drop_target in wrapper_class.DROP_TARGETS:
self._target_type_to_wrapper_class_map[drop_target.drag_type] = wrapper_class self._target_type_to_wrapper_class_map[drop_target.drag_type] = wrapper_class
@ -736,6 +791,10 @@ class ScratchPadListView:
wrapper_class = self._target_type_to_wrapper_class_map[str(possible_wrappers[0])] wrapper_class = self._target_type_to_wrapper_class_map[str(possible_wrappers[0])]
o = wrapper_class(self._db,sel_data) o = wrapper_class(self._db,sel_data)
# try:
# o = wrapper_class(self._db,sel_data)
# except:
# return
# If the wrapper object is a subclass of ScratchDropList then # If the wrapper object is a subclass of ScratchDropList then
# the drag data was a list of objects and we need to decode # the drag data was a list of objects and we need to decode

View File

@ -44,8 +44,6 @@ import gtk.glade
import const import const
import Utils import Utils
import ListModel import ListModel
import RelLib
import DateHandler
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #

View File

@ -28,7 +28,9 @@
import os import os
import sys import sys
import locale import locale
import sets import random
import time
from TransUtils import sgettext as _ from TransUtils import sgettext as _
try: try:
@ -417,7 +419,6 @@ data_recover_msg = _('The data can only be recovered by Undo operation '
'or by quitting with abandoning changes.') 'or by quitting with abandoning changes.')
def fix_encoding(value): def fix_encoding(value):
import locale
if type(value) != unicode: if type(value) != unicode:
try: try:
return unicode(value) return unicode(value)
@ -429,8 +430,6 @@ def fix_encoding(value):
else: else:
return value return value
import locale
def xml_lang(): def xml_lang():
(loc,enc) = locale.getlocale() (loc,enc) = locale.getlocale()
if loc == None: if loc == None:
@ -856,14 +855,11 @@ def temp_label(label,widget=None):
# create_id # create_id
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import random
import time
from sys import maxint
rand = random.Random(time.time()) rand = random.Random(time.time())
def create_id(): def create_id():
return "%08x%08x" % ( int(time.time()*10000), return "%08x%08x" % ( int(time.time()*10000),
rand.randint(0,maxint)) rand.randint(0,sys.maxint))
def probably_alive(person,db,current_year=None,limit=0): def probably_alive(person,db,current_year=None,limit=0):
"""Returns true if the person may be alive. """Returns true if the person may be alive.
@ -1287,7 +1283,7 @@ class ProgressMeter:
while gtk.events_pending(): while gtk.events_pending():
gtk.main_iteration() gtk.main_iteration()
def warn(self,obj,obj2): def warn(self,*obj):
WarningDialog( WarningDialog(
_("Attempt to force closing the dialog"), _("Attempt to force closing the dialog"),
_("Please do not force closing this important dialog."), _("Please do not force closing this important dialog."),

View File

@ -44,6 +44,7 @@ log = logging.getLogger(".")
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import gtk import gtk
import gobject
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -68,7 +69,6 @@ import Bookmarks
import RecentFiles import RecentFiles
import NameDisplay import NameDisplay
import Mime import Mime
import Config
import GrampsWidgets import GrampsWidgets
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -369,30 +369,35 @@ class ViewManager:
self.uimanager.insert_action_group(self.redoactions,1) self.uimanager.insert_action_group(self.redoactions,1)
def home_page_activate(self,obj): def home_page_activate(self,obj):
import GrampsDisplay
GrampsDisplay.url(const.url_homepage) GrampsDisplay.url(const.url_homepage)
def mailing_lists_activate(self,obj): def mailing_lists_activate(self,obj):
import GrampsDisplay
GrampsDisplay.url( const.url_mailinglist) GrampsDisplay.url( const.url_mailinglist)
def preferences_activate(self,obj): def preferences_activate(self,obj):
GrampsCfg.display_preferences_box(self.state.db) GrampsCfg.display_preferences_box(self.state.db)
def report_bug_activate(self,obj): def report_bug_activate(self,obj):
import GrampsDisplay
GrampsDisplay.url( const.url_bugtracker) GrampsDisplay.url( const.url_bugtracker)
def manual_activate(self,obj): def manual_activate(self,obj):
"""Display the GRAMPS manual""" """Display the GRAMPS manual"""
try: try:
import GrampsDisplay
GrampsDisplay.help('index') GrampsDisplay.help('index')
except gobject.GError, msg: except gobject.GError, msg:
ErrorDialog(_("Could not open help"),str(msg)) QuestionDialog.ErrorDialog(_("Could not open help"),str(msg))
def faq_activate(self,obj): def faq_activate(self,obj):
"""Display FAQ""" """Display FAQ"""
try: try:
import GrampsDisplay
GrampsDisplay.help('faq') GrampsDisplay.help('faq')
except gobject.GError, msg: except gobject.GError, msg:
ErrorDialog(_("Could not open help"),str(msg)) QuestionDialog.ErrorDialog(_("Could not open help"),str(msg))
def tip_of_day_activate(self,obj): def tip_of_day_activate(self,obj):
"""Display Tip of the day""" """Display Tip of the day"""
@ -487,7 +492,7 @@ class ViewManager:
if num == -1: if num == -1:
num = self.notebook.get_current_page() num = self.notebook.get_current_page()
if self.state.open == True: if self.state.open:
for mergeid in self.merge_ids: for mergeid in self.merge_ids:
self.uimanager.remove_ui(mergeid) self.uimanager.remove_ui(mergeid)
@ -714,21 +719,24 @@ class ViewManager:
filename = os.path.normpath(os.path.abspath(filename)) filename = os.path.normpath(os.path.abspath(filename))
if os.path.isdir(filename): if os.path.isdir(filename):
ErrorDialog(_('Cannot open database'), QuestionDialog.ErrorDialog(
_('The selected file is a directory, not ' _('Cannot open database'),
'a file.\nA GRAMPS database must be a file.')) _('The selected file is a directory, not '
'a file.\nA GRAMPS database must be a file.'))
return False return False
elif os.path.exists(filename): elif os.path.exists(filename):
if not os.access(filename,os.R_OK): if not os.access(filename,os.R_OK):
ErrorDialog(_('Cannot open database'), QuestionDialog.ErrorDialog(
_('You do not have read access to the selected ' _('Cannot open database'),
'file.')) _('You do not have read access to the selected '
'file.'))
return False return False
elif not os.access(filename,os.W_OK): elif not os.access(filename,os.W_OK):
mode = "r" mode = "r"
QuestionDialog.WarningDialog(_('Read only database'), QuestionDialog.WarningDialog(
_('You do not have write access ' _('Read only database'),
'to the selected file.')) _('You do not have write access '
'to the selected file.'))
try: try:
os.chdir(os.path.dirname(filename)) os.chdir(os.path.dirname(filename))
@ -755,15 +763,17 @@ class ViewManager:
self.uistate.window.set_title(msg) self.uistate.window.set_title(msg)
else: else:
Config.save_last_file("") Config.save_last_file("")
QuestionDialog.ErrorDialog(_('Cannot open database'), QuestionDialog.ErrorDialog(
_('The database file specified could not be opened.')) _('Cannot open database'),
_('The database file specified could not be opened.'))
return False return False
except ( IOError, OSError, Errors.FileVersionError), msg: except ( IOError, OSError, Errors.FileVersionError), msg:
QuestionDialog.ErrorDialog(_('Cannot open database'),str(msg)) QuestionDialog.ErrorDialog(_('Cannot open database'),str(msg))
return False return False
except (db.DBAccessError,db.DBError), msg: except (db.DBAccessError,db.DBError), msg:
QuestionDialog.ErrorDialog(_('Cannot open database'), QuestionDialog.ErrorDialog(
_('%s could not be opened.' % filename) + '\n' + msg[1]) _('Cannot open database'),
_('%s could not be opened.' % filename) + '\n' + msg[1])
return False return False
except Exception: except Exception:
log.error("Failed to open database.", exc_info=True) log.error("Failed to open database.", exc_info=True)
@ -851,19 +861,18 @@ class ViewManager:
name = NameDisplay.displayer.display(self.state.active) name = NameDisplay.displayer.display(self.state.active)
self.uistate.push_message(_("%s has been bookmarked") % name) self.uistate.push_message(_("%s has been bookmarked") % name)
else: else:
WarningDialog(_("Could Not Set a Bookmark"), QuestionDialog.WarningDialog(
_("A bookmark could not be set because " _("Could Not Set a Bookmark"),
"no one was selected.")) _("A bookmark could not be set because "
"no one was selected."))
def edit_bookmarks(self,obj): def edit_bookmarks(self,obj):
self.bookmarks.edit() self.bookmarks.edit()
def reports_clicked(self,obj): def reports_clicked(self,obj):
import Plugins
Plugins.ReportPlugins(self.state,self.uistate,[]) Plugins.ReportPlugins(self.state,self.uistate,[])
def tools_clicked(self,obj): def tools_clicked(self,obj):
import Plugins
Plugins.ToolPlugins(self.state,self.uistate,[]) Plugins.ToolPlugins(self.state,self.uistate,[])
def scratchpad(self,obj): def scratchpad(self,obj):

View File

@ -36,8 +36,6 @@ log = logging.getLogger(".")
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import ViewManager import ViewManager
import GrampsDisplay
import RelLib
import GrampsDb import GrampsDb
import ArgHandler import ArgHandler
import Config import Config
@ -48,6 +46,7 @@ import TipOfDay
import DataViews import DataViews
from Mime import mime_type_is_defined from Mime import mime_type_is_defined
from QuestionDialog import ErrorDialog from QuestionDialog import ErrorDialog
from TransUtils import sgettext as _
iconpaths = [const.image_dir,"."] iconpaths = [const.image_dir,"."]