2005-03-15 Richard Taylor <rjt-gramps@thegrindstone.me.uk>
* src/Makefile.am : Added TreeTip.py to list of installed modules. * src/TreeTip.py: New module that implements tooltips on TreeView rows. * src/plugins/Makefile.am: Added ScratchPad.py and scratchpad.glade. * src/plugins/ScratchPad.py: New module to implement a scratch pad for temporary storage of drag and drop objects. * src/plugins/scratchpad.glade: New glade file for ScratchPad window. svn: r4184
This commit is contained in:
parent
40611a11f1
commit
86c6d36e8f
@ -1,3 +1,11 @@
|
||||
2005-03-15 Richard Taylor <rjt-gramps@thegrindstone.me.uk>
|
||||
* src/Makefile.am : Added TreeTip.py to list of installed modules.
|
||||
* src/TreeTip.py: New module that implements tooltips on TreeView rows.
|
||||
* src/plugins/Makefile.am: Added ScratchPad.py and scratchpad.glade.
|
||||
* src/plugins/ScratchPad.py: New module to implement a scratch pad for
|
||||
temporary storage of drag and drop objects.
|
||||
* src/plugins/scratchpad.glade: New glade file for ScratchPad window.
|
||||
|
||||
2005-03-15 Martin Hawlisch <Martin.Hawlisch@gmx.de>
|
||||
* src/GenericFilter.py (FullTextSearch): Added new filter thad provides
|
||||
a full-text search thru (nearly) all attributes and linked objexts of a person.
|
||||
|
@ -101,6 +101,7 @@ gdir_PYTHON = \
|
||||
TarFile.py\
|
||||
TipOfDay.py\
|
||||
TransTable.py\
|
||||
TreeTips.py\
|
||||
UrlEdit.py\
|
||||
Utils.py\
|
||||
Witness.py\
|
||||
|
248
src/TreeTips.py
Normal file
248
src/TreeTips.py
Normal file
@ -0,0 +1,248 @@
|
||||
# File: treetips.py
|
||||
# Author: Toshio Kuratomi <toshio@tiki-lounge.com>
|
||||
# Date: 6 April, 2004
|
||||
# Copyright: Toshio Kuratomi
|
||||
# License: GPL
|
||||
# Id: $Id$
|
||||
"""A tooltip class for TreeViews
|
||||
"""
|
||||
__revision__ = "$Rev$"
|
||||
|
||||
|
||||
#
|
||||
# Support for text markup added: March 05 - rjt-gramps <at> thegrindstone.me.uk
|
||||
#
|
||||
|
||||
import gtk
|
||||
import gobject
|
||||
|
||||
class TreeTips(gtk.Widget):
|
||||
''' A tooltips widget specialized to work with gtk.TreeView's.
|
||||
|
||||
TreeTips associates a column in a TreeStore with tooltips that will be
|
||||
displayed when the mouse is over the row the column is for. Each row can
|
||||
have one treetip.
|
||||
'''
|
||||
__gproperties__ = {
|
||||
'tip_window' : (gobject.TYPE_PYOBJECT,
|
||||
'The window that the tooltip is displayed in.',
|
||||
'The window that the tooltip is displayed in.',
|
||||
gobject.PARAM_READABLE),
|
||||
'tip_label' : (gobject.TYPE_PYOBJECT,
|
||||
'The label that displays the tooltip text.',
|
||||
'The label that displays the tooltip text.',
|
||||
gobject.PARAM_READABLE),
|
||||
'active_tips_data' : (gobject.TYPE_PYOBJECT,
|
||||
'The data associated with the active tooltip.',
|
||||
'The data associated with the active tooltip.',
|
||||
gobject.PARAM_READABLE),
|
||||
'delay' : (gobject.TYPE_INT,
|
||||
'MSecs before displaying the tooltip.',
|
||||
'The delay between the mouse pausing over the widget and the display of the tooltip in msec.',
|
||||
0, 60000, 500,
|
||||
gobject.PARAM_READWRITE),
|
||||
'enabled' : (gobject.TYPE_BOOLEAN,
|
||||
'If TRUE the tooltips are enabled',
|
||||
'If TRUE the tooltips are enabled',
|
||||
True,
|
||||
gobject.PARAM_READABLE),
|
||||
'view' : (gobject.TYPE_PYOBJECT,
|
||||
'gtk.TreeView that we get our data from.',
|
||||
'The tip data comes from a column in a gtk.TreeView.',
|
||||
gobject.PARAM_READWRITE),
|
||||
'column' : (gobject.TYPE_INT,
|
||||
'Column from the gtk.TreeView that holds tip data.',
|
||||
'The tip data for each row is held by a column in the row. This specifies which column that data is in.',
|
||||
0, 32000, 0,
|
||||
gobject.PARAM_READWRITE),
|
||||
'markup_enabled' : (gobject.TYPE_BOOLEAN,
|
||||
'If TRUE the tooltips are in Pango Markup',
|
||||
'If TRUE the tooltips are in Pango Markup',
|
||||
False,
|
||||
gobject.PARAM_READWRITE),
|
||||
|
||||
}
|
||||
|
||||
def __init__(self, treeview=None, column=None, markup_enabled=False):
|
||||
'''Create a new TreeTips Group.
|
||||
|
||||
:Parameters:
|
||||
treeview : gtk.TreeView === Treeview for which the tips display,
|
||||
default is None.
|
||||
column : integer === Column id in the Treemodel holding the treetip
|
||||
text, default is None.
|
||||
markup_enabled : bool === If True the tooltips are in Pango Markup,
|
||||
if False the tooltips are in plain text.
|
||||
'''
|
||||
if treeview:
|
||||
try:
|
||||
treeview.connect('leave-notify-event', self.__tree_leave_notify)
|
||||
treeview.connect('motion-notify-event', self.__tree_motion_notify)
|
||||
except (AttributeError, TypeError):
|
||||
raise TypeError, ('The value of view must be an object that'
|
||||
'implements leave-notify-event and motion-notify-event '
|
||||
'gsignals such as gtk.TreeStore.')
|
||||
|
||||
gobject.GObject.__init__(self)
|
||||
|
||||
self.view = treeview or None
|
||||
self.delay = 500
|
||||
self.enabled = True
|
||||
self.column = column or 0
|
||||
self.markup_enabled = markup_enabled
|
||||
self.tip_window = gtk.Window(gtk.WINDOW_POPUP)
|
||||
self.tip_window.set_app_paintable(True)
|
||||
self.tip_window.set_border_width(4)
|
||||
self.tip_window.connect('expose-event', self.__paint_window)
|
||||
self.tip_label = gtk.Label('')
|
||||
self.tip_label.set_line_wrap(True)
|
||||
self.tip_label.set_alignment(0.5, 0.5)
|
||||
self.active_tips_data = ''
|
||||
self.tip_window.add(self.tip_label)
|
||||
self.unique = 1 # Unique number used for timeouts
|
||||
self.timeoutID = 0
|
||||
self.path = None
|
||||
self.screenWidth = gtk.gdk.screen_width()
|
||||
self.screenHeight = gtk.gdk.screen_height()
|
||||
|
||||
def enable(self):
|
||||
'''Enable showing of tooltips'''
|
||||
self.enabled = True
|
||||
|
||||
def disable(self):
|
||||
'''Disable showing tooltips'''
|
||||
self.enabled = False
|
||||
|
||||
def do_get_property(self, prop):
|
||||
'''Return the gproperty's value.'''
|
||||
if prop.name == 'delay':
|
||||
return self.delay
|
||||
elif prop.name == 'enabled':
|
||||
return self.enabled
|
||||
elif prop.name == 'view':
|
||||
return self.view
|
||||
elif prop.name == 'column':
|
||||
return self.column
|
||||
elif prop.name == 'active-tips-data':
|
||||
return self.active_tips_data
|
||||
elif prop.name == 'tip-label':
|
||||
return self.tip_label
|
||||
elif prop.name == 'tip-window':
|
||||
return self.tip_window
|
||||
elif prop.name == 'markup_enabled':
|
||||
return self.markup_enabled
|
||||
else:
|
||||
raise AttributeError, 'unknown property %s' % prop.name
|
||||
|
||||
def do_set_property(self, prop, value):
|
||||
'''Set the property of writable properties.
|
||||
|
||||
'''
|
||||
if prop.name == 'delay':
|
||||
self.delay = value
|
||||
elif prop.name == 'view':
|
||||
try:
|
||||
value.connect('leave-notify-event', self.__tree_leave_notify)
|
||||
value.connect('motion-notify-event', self.__tree_motion_notify)
|
||||
except (AttributeError, TypeError):
|
||||
raise TypeError, ('The value of view must be an object that'
|
||||
'implements leave-notify-event and motion-notify-event '
|
||||
'gsignals')
|
||||
self.view = value
|
||||
elif prop.name == 'column':
|
||||
self.column = value
|
||||
elif prop.name == 'markup_enabled':
|
||||
self.markup_enabled = value
|
||||
else:
|
||||
raise AttributeError, 'unknown or read only property %s' % prop.name
|
||||
|
||||
def __paint_window(self, window, event):
|
||||
window.style.paint_flat_box(window.window, gtk.STATE_NORMAL,
|
||||
gtk.SHADOW_OUT, None, window,
|
||||
'tooltip', 0, 0, -1, -1)
|
||||
|
||||
def __tree_leave_notify(self, tree, event):
|
||||
'''Hide tooltips when we leave the tree.'''
|
||||
|
||||
self.timeoutID = 0
|
||||
self.path = None
|
||||
self.tip_window.hide()
|
||||
|
||||
def __tree_motion_notify(self, tree, event):
|
||||
'''Decide which tooltip to display when we move within the tree.'''
|
||||
|
||||
if not self.enabled:
|
||||
return
|
||||
self.tip_window.hide()
|
||||
self.path = None
|
||||
self.unique += 1
|
||||
self.timeoutID = self.unique
|
||||
gobject.timeout_add(self.delay, self.__treetip_show, tree,
|
||||
int(event.x), int(event.y), self.timeoutID)
|
||||
|
||||
def __treetip_show(self, tree, xEvent, yEvent, ID):
|
||||
'''Show the treetip window.'''
|
||||
if self.timeoutID != ID:
|
||||
return False
|
||||
pathReturn = tree.get_path_at_pos(xEvent, yEvent)
|
||||
model = tree.get_model()
|
||||
if pathReturn == None:
|
||||
self.path = None
|
||||
elif self.path != pathReturn[0]:
|
||||
self.path = pathReturn[0]
|
||||
rowIter = model.get_iter(self.path)
|
||||
text = model.get_value(rowIter, self.column)
|
||||
self.active_tips_data = text
|
||||
if not text:
|
||||
if self.markup_enabled:
|
||||
self.tip_label.set_markup('')
|
||||
else:
|
||||
self.tip_label.set_text('')
|
||||
return False
|
||||
|
||||
if self.markup_enabled:
|
||||
self.tip_label.set_markup(text)
|
||||
else:
|
||||
self.tip_label.set_text(text)
|
||||
x, y = self.tip_label.size_request()
|
||||
self.tip_window.resize(x, y)
|
||||
windowWidth, windowHeight = self.tip_window.get_size()
|
||||
cellInfo = tree.get_cell_area(self.path, pathReturn[1])
|
||||
x, y = self.__compute_tooltip_position(cellInfo, windowWidth, windowHeight)
|
||||
self.tip_window.move(int(x), int(y))
|
||||
self.tip_window.show_all()
|
||||
|
||||
return False
|
||||
|
||||
def __compute_tooltip_position(self, cellInfo, popupWidth, popupHeight):
|
||||
'''Figures out where the tooltip should be placed on the page::
|
||||
|
||||
[p] = pointer
|
||||
x = [p]
|
||||
+---------+
|
||||
(half on each side)
|
||||
|
||||
y = [p]
|
||||
+------------+
|
||||
|____________|
|
||||
If it fits else:
|
||||
+------------+
|
||||
|____________|
|
||||
[p]
|
||||
'''
|
||||
|
||||
xOrigin, yOrigin = self.view.get_bin_window().get_origin()
|
||||
x = xOrigin + cellInfo.x + cellInfo.width/2 - popupWidth/2
|
||||
if x < 0:
|
||||
x = 0
|
||||
elif x + popupWidth > self.screenWidth:
|
||||
x = self.screenWidth - popupWidth
|
||||
|
||||
y = yOrigin + cellInfo.y + cellInfo.height + 3
|
||||
if y + popupHeight > self.screenHeight:
|
||||
y = yOrigin + cellInfo.y - 3 - popupHeight
|
||||
if y < 0:
|
||||
y = 0
|
||||
|
||||
return x, y
|
||||
gobject.type_register(TreeTips)
|
@ -35,6 +35,7 @@ pkgdata_PYTHON = \
|
||||
ReadPkg.py\
|
||||
RelCalc.py\
|
||||
ReorderIds.py\
|
||||
ScratchPad.py\
|
||||
SoundGen.py\
|
||||
StatisticsChart.py\
|
||||
Summary.py\
|
||||
@ -80,7 +81,8 @@ GLADEFILES = \
|
||||
leak.glade\
|
||||
book.glade\
|
||||
writeftree.glade\
|
||||
genewebexport.glade
|
||||
genewebexport.glade\
|
||||
scratchpad.glade
|
||||
|
||||
dist_pkgdata_DATA = $(GLADEFILES)
|
||||
|
||||
|
489
src/plugins/ScratchPad.py
Normal file
489
src/plugins/ScratchPad.py
Normal file
@ -0,0 +1,489 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2004 Donald N. Allingham
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modiy
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
# $Id$
|
||||
|
||||
import pickle
|
||||
import os
|
||||
from xml.sax.saxutils import escape
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GTK/Gnome modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
import gtk.gdk
|
||||
import gtk.glade
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
import const
|
||||
import Utils
|
||||
import ListModel
|
||||
import TreeTips
|
||||
|
||||
from gettext import gettext as _
|
||||
|
||||
from gtk.gdk import ACTION_COPY, BUTTON1_MASK
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Globals
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
text_targets = ['text/plain',
|
||||
'TEXT',
|
||||
'STRING',
|
||||
'COMPOUND_TEXT',
|
||||
'UTF8_STRING']
|
||||
|
||||
gramps_targets = ['url',
|
||||
'pevent',
|
||||
'pattr',
|
||||
'paddr',
|
||||
'srcref']
|
||||
|
||||
pycode_tgts = [('url', 0, 0),
|
||||
('pevent', 0, 1),
|
||||
('pattr', 0, 2),
|
||||
('paddr', 0, 3),
|
||||
('srcref', 0, 4),
|
||||
('text/plain',0,0),
|
||||
('TEXT', 0, 1),
|
||||
('STRING', 0, 2),
|
||||
('COMPOUND_TEXT', 0, 3),
|
||||
('UTF8_STRING', 0, 4)]
|
||||
|
||||
TEXT_TARGET = 'TEXT'
|
||||
|
||||
target_map = {'url':('url', 0, 0),
|
||||
'pevent': ('pevent', 0, 1),
|
||||
'pattr': ('pattr', 0, 2),
|
||||
'paddr': ('paddr', 0, 3),
|
||||
'srcref': ('srcref', 0, 4),
|
||||
TEXT_TARGET: ('TEXT', 0, 1)}
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# ScatchPadWindow class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class ScratchPadWindow:
|
||||
"""
|
||||
The ScratchPad provides a temporary area to hold objects that can
|
||||
be reused accross multiple Person records. The pad provides a window
|
||||
onto which objects can be dropped and then dragged into new Person
|
||||
dialogs. The objects are stored as the pickles that are built by the
|
||||
origininating widget. The objects are only unpickled in order to
|
||||
provide the text in the display.
|
||||
|
||||
No attempt is made to ensure that any references contained within
|
||||
the pickles are valid. Because the pad extends the life time of drag
|
||||
and drop objects, it is possible that references that were valid
|
||||
when an object is copied to the pad are invalid by the time they
|
||||
are dragged to a new Person. For this reason, using the pad places
|
||||
a responsibility on all '_drag_data_received' methods to check the
|
||||
references of objects before attempting to use them.
|
||||
"""
|
||||
|
||||
def __init__(self,database,parent):
|
||||
"""Initializes the ScratchPad class, and displays the window"""
|
||||
|
||||
self.db = database
|
||||
self.parent = parent
|
||||
self.win_key = self
|
||||
|
||||
self.olist = []
|
||||
self.otitles = [(_('Type'),-1,150),
|
||||
(_('Title'),-1,150),
|
||||
(_('Value'),-1,150),
|
||||
('',-1,0)] # To hold the tooltip text
|
||||
|
||||
base = os.path.dirname(__file__)
|
||||
self.glade_file = "%s/%s" % (base,"scratchpad.glade")
|
||||
|
||||
self.top = gtk.glade.XML(self.glade_file,"scratchPad","gramps")
|
||||
self.window = self.top.get_widget("scratchPad")
|
||||
self.window.set_icon(self.parent.topWindow.get_icon())
|
||||
|
||||
self.object_list = self.top.get_widget('objectlist')
|
||||
|
||||
self.otree = ListModel.ListModel(self.object_list,self.otitles,
|
||||
self.on_object_select_row,
|
||||
self.on_update_object_clicked)
|
||||
|
||||
self.treetips = TreeTips.TreeTips(self.object_list,3,True)
|
||||
|
||||
self.top.signal_autoconnect({
|
||||
"on_close_scratchpad" : self.on_close_scratchpad,
|
||||
"on_clear_clicked": self.on_clear_clicked,
|
||||
"on_clear_all_clicked": self.on_clear_all_clicked,
|
||||
"on_objectlist_delete_event": self.on_delete_event,
|
||||
"on_scratchPad_delete_event": self.on_delete_event
|
||||
})
|
||||
|
||||
self.object_list.drag_dest_set(gtk.DEST_DEFAULT_ALL, pycode_tgts,
|
||||
ACTION_COPY)
|
||||
|
||||
self.object_list.connect('drag_data_get', self.object_drag_data_get)
|
||||
self.object_list.connect('drag_begin', self.object_drag_begin)
|
||||
self.object_list.connect('drag_data_received',
|
||||
self.object_drag_data_received)
|
||||
|
||||
self.add_itself_to_menu()
|
||||
self.window.show()
|
||||
|
||||
|
||||
def on_delete_event(self,obj,b):
|
||||
self.remove_itself_from_menu()
|
||||
|
||||
def add_itself_to_menu(self):
|
||||
"""Add the ScratchPad window to the list of windows in the
|
||||
main GRAMPS interface. If this is the first instance to be
|
||||
created a submenu is created, if it is not the first instance
|
||||
then an entry is created in the existing sub menu."""
|
||||
|
||||
sub_menu_label = _("Scratch Pad Tool")
|
||||
instance_number_key = "scratch_pad_instance_number"
|
||||
|
||||
self.parent.child_windows[self.win_key] = self
|
||||
|
||||
# First check to see if the Scratch Pad sub menu already exists.
|
||||
# The MenuItems contain a list of child widgets, the first one
|
||||
# should be the AccelLabel so we can check the label text on
|
||||
# that one.
|
||||
sub_menu_list = [ menu for menu in self.parent.winsmenu.get_children() if \
|
||||
menu.get_children()[0].get_label() == sub_menu_label ]
|
||||
|
||||
if len(sub_menu_list) > 0:
|
||||
# This list should always be of length 0 or 1 but in the unlikely
|
||||
# situation that it is greater than 1 it will still be safe to use
|
||||
# the first.
|
||||
self.parent_menu_item = sub_menu_list[0]
|
||||
else:
|
||||
# There is no existing instances so we must create the submenu.
|
||||
self.parent_menu_item = gtk.MenuItem(sub_menu_label)
|
||||
self.parent_menu_item.set_submenu(gtk.Menu())
|
||||
self.parent_menu_item.show()
|
||||
self.parent.winsmenu.append(self.parent_menu_item)
|
||||
|
||||
# Get a handle to the submenu and remember it so that
|
||||
# remove_itself_from_menu can delete it later.
|
||||
self.winsmenu = self.parent_menu_item.get_submenu()
|
||||
|
||||
# Get the first available instance number. The instance number
|
||||
# is stored in the data item store of the menu item so we can
|
||||
# read it with get_data.
|
||||
num = 1
|
||||
existing_instances = [ menu_item.get_data(instance_number_key) \
|
||||
for menu_item in self.winsmenu.get_children() ]
|
||||
|
||||
if len(existing_instances) > 0:
|
||||
# Calculate the first available instance number.
|
||||
existing_instances.sort()
|
||||
for instance_num in existing_instances:
|
||||
if instance_num != num:
|
||||
break
|
||||
else:
|
||||
num += 1
|
||||
|
||||
# Create the instance menuitem with the instance number in the
|
||||
# label.
|
||||
instance_title = _('Scratch Pad - %d') % (num,)
|
||||
self.menu_item = gtk.MenuItem(instance_title)
|
||||
self.menu_item.set_data(instance_number_key,num)
|
||||
self.menu_item.connect("activate",self.present)
|
||||
self.menu_item.show()
|
||||
|
||||
# Set the window title to the same as the menu label.
|
||||
self.window.set_title(instance_title)
|
||||
|
||||
# Add the item to the submenu.
|
||||
self.winsmenu.append(self.menu_item)
|
||||
|
||||
def remove_itself_from_menu(self):
|
||||
"""Remove the instance of the pad from the Window menu in the
|
||||
main GRAMPS window. If this is the last pad then remove the
|
||||
ScratchPad sub menu as well."""
|
||||
|
||||
del self.parent.child_windows[self.win_key]
|
||||
self.menu_item.destroy()
|
||||
if len(self.winsmenu.get_children()) == 0:
|
||||
self.winsmenu.destroy()
|
||||
self.parent_menu_item.destroy()
|
||||
|
||||
def present(self,obj):
|
||||
self.window.present()
|
||||
|
||||
|
||||
def on_close_scratchpad(self,obj):
|
||||
self.remove_itself_from_menu()
|
||||
self.window.destroy()
|
||||
|
||||
def on_clear_clicked(self,obj):
|
||||
"""Deletes the selected object from the object list"""
|
||||
store,node = self.otree.get_selected()
|
||||
if node:
|
||||
self.olist.remove(self.otree.get_object(node))
|
||||
self.redraw_object_list()
|
||||
|
||||
def on_clear_all_clicked(self,obj):
|
||||
self.olist = []
|
||||
self.redraw_object_list()
|
||||
|
||||
def on_object_select_row(self,obj):
|
||||
global target_map
|
||||
global TEXT_TARGET
|
||||
|
||||
o = self.otree.get_selected_objects()
|
||||
|
||||
if len(o):
|
||||
bits_per = 8; # we're going to pass a string
|
||||
|
||||
obj_targets = o[0]['targets']
|
||||
|
||||
# union with gramps_types
|
||||
if len([target for target \
|
||||
in obj_targets if target in gramps_targets]) > 0:
|
||||
|
||||
exec 'data = %s' % o[0]['data']
|
||||
exec 'mytype = "%s"' % data[0]
|
||||
target = target_map[mytype]
|
||||
|
||||
# Union with text targets
|
||||
elif len([target for target \
|
||||
in obj_targets if target in text_targets]) > 0:
|
||||
target = target_map[TEXT_TARGET]
|
||||
|
||||
self.object_list.drag_source_unset()
|
||||
self.object_list.drag_source_set(BUTTON1_MASK, [target], ACTION_COPY)
|
||||
|
||||
|
||||
def on_update_object_clicked(self, obj):
|
||||
pass
|
||||
|
||||
def object_drag_begin(self, context, a):
|
||||
return
|
||||
|
||||
def object_drag_data_get(self,widget, context, sel_data, info, time):
|
||||
|
||||
global gramps_targets
|
||||
global text_targets
|
||||
|
||||
o = self.otree.get_selected_objects()
|
||||
|
||||
if len(o):
|
||||
bits_per = 8; # we're going to pass a string
|
||||
|
||||
obj_targets = o[0]['targets']
|
||||
|
||||
# union with gramps_types
|
||||
if len([target for target \
|
||||
in obj_targets if target in gramps_targets]) > 0:
|
||||
|
||||
exec 'data = %s' % o[0]['data']
|
||||
exec 'mytype = "%s"' % data[0]
|
||||
exec 'person = "%s"' % data[1]
|
||||
|
||||
pickled = data[2]
|
||||
send_data = str((mytype,person,pickled));
|
||||
|
||||
# Union with text targets
|
||||
elif len([target for target \
|
||||
in obj_targets if target in text_targets]) > 0:
|
||||
send_data = str(o[0]['data'])
|
||||
|
||||
sel_data.set(sel_data.target, bits_per, send_data)
|
||||
|
||||
|
||||
def object_drag_data_received(self,widget,context,x,y,sel_data,info,time):
|
||||
row = self.otree.get_row_at(x,y)
|
||||
|
||||
if sel_data and sel_data.data:
|
||||
self.olist.insert(row,{'targets':context.targets,
|
||||
'data':sel_data.data})
|
||||
self.redraw_object_list()
|
||||
|
||||
|
||||
def redraw_object_list(self):
|
||||
"""Redraws the address list"""
|
||||
|
||||
global gramps_targets
|
||||
global text_targets
|
||||
|
||||
self.otree.clear()
|
||||
|
||||
for obj in self.olist:
|
||||
obj_targets = obj['targets']
|
||||
|
||||
# union with gramps_types
|
||||
if len([target for target \
|
||||
in obj_targets if target in gramps_targets]) > 0:
|
||||
|
||||
exec 'unpack_data = %s' % obj['data']
|
||||
exec 'mytype = "%s"' % unpack_data[0]
|
||||
data = pickle.loads(unpack_data[2]);
|
||||
|
||||
node = None
|
||||
|
||||
if mytype == 'paddr':
|
||||
location = "%s %s %s %s" % (data.get_street(),data.get_city(),
|
||||
data.get_state(),data.get_country())
|
||||
node = self.otree.add([_("Address"),
|
||||
data.get_date(),
|
||||
location,
|
||||
self.generate_addr_tooltip(data)],obj)
|
||||
|
||||
elif mytype == 'pevent':
|
||||
node = self.otree.add([_("Event"),
|
||||
const.display_pevent(data.get_name()),
|
||||
data.get_description(),
|
||||
self.generate_event_tooltip(data)],obj)
|
||||
|
||||
elif mytype == 'url':
|
||||
node = self.otree.add([_("Url"),
|
||||
data.get_path(),
|
||||
data.get_description(),
|
||||
self.generate_url_tooltip(data)],obj)
|
||||
elif mytype == 'pattr':
|
||||
node = self.otree.add([_("Attribute"),
|
||||
const.display_pattr(data.get_type()),
|
||||
data.get_value(),
|
||||
self.generate_pattr_tooltip(data)],obj)
|
||||
elif mytype == 'srcref':
|
||||
base = self.db.get_source_from_handle(data.get_base_handle())
|
||||
node = self.otree.add([_("SourceRef"),
|
||||
base.get_title(),
|
||||
data.get_text(),
|
||||
self.generate_srcref_tooltip(data)],obj)
|
||||
|
||||
# Union with text targets
|
||||
elif len([target for target \
|
||||
in obj_targets if target in text_targets]) > 0:
|
||||
node = self.otree.add([_("Text"),
|
||||
"",
|
||||
obj['data'],
|
||||
self.generate_text_tooltip(obj['data'])],obj)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if self.olist:
|
||||
self.otree.select_row(0)
|
||||
|
||||
|
||||
def generate_addr_tooltip(self,addr):
|
||||
global escape
|
||||
return "<big><b>%s</b></big>\n"\
|
||||
"<b>%s:</b>\t%s\n"\
|
||||
"<b>%s:</b>\n"\
|
||||
"\t%s\n"\
|
||||
"\t%s\n"\
|
||||
"\t%s\n"\
|
||||
"\t%s" % (_("Address"),
|
||||
_("Date"),
|
||||
escape(addr.get_date()),
|
||||
_("Location"),
|
||||
escape(addr.get_street()),
|
||||
escape(addr.get_city()),
|
||||
escape(addr.get_state()),
|
||||
escape(addr.get_country()))
|
||||
|
||||
def generate_event_tooltip(self,event):
|
||||
global escape
|
||||
return "<big><b>%s</b></big>\n"\
|
||||
"<b>%s:</b>\t%s\n"\
|
||||
"<b>%s:</b>\t%s\n" % (_("Event"),
|
||||
_("Name"),
|
||||
escape(const.display_pevent(event.get_name())),
|
||||
_("Description"),
|
||||
escape(event.get_description()))
|
||||
|
||||
def generate_url_tooltip(self,url):
|
||||
global escape
|
||||
return "<big><b>%s</b></big>\n"\
|
||||
"<b>%s:</b>\t%s\n"\
|
||||
"<b>%s:</b>\t%s" % (_("Url"),
|
||||
_("Path"),
|
||||
escape(url.get_path()),
|
||||
_("Description"),
|
||||
escape(url.get_description()))
|
||||
|
||||
def generate_pattr_tooltip(self,pattr):
|
||||
global escape
|
||||
return "<big><b>%s</b></big>\n"\
|
||||
"<b>%s:</b>\t%s\n"\
|
||||
"<b>%s:</b>\t%s" % (_("Attribute"),
|
||||
_("Type"),
|
||||
escape(const.display_pattr(pattr.get_type())),
|
||||
_("Value"),
|
||||
escape(pattr.get_value()))
|
||||
|
||||
def generate_srcref_tooltip(self,srcref):
|
||||
global escape
|
||||
base = self.db.get_source_from_handle(srcref.get_base_handle())
|
||||
return "<big><b>%s</b></big>\n"\
|
||||
"<b>%s:</b>\t%s\n"\
|
||||
"<b>%s:</b>\t%s" % (_("SourceRef"),
|
||||
_("Title"),
|
||||
escape(base.get_title()),
|
||||
_("Text"),
|
||||
escape(srcref.get_text()))
|
||||
|
||||
def generate_text_tooltip(self,text):
|
||||
global escape
|
||||
return "<big><b>%s</b></big>\n"\
|
||||
"%s" % (_("Text"),
|
||||
escape(text))
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def ScratchPad(database,person,callback,parent=None):
|
||||
ScratchPadWindow(database,parent)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from PluginMgr import register_tool
|
||||
|
||||
|
||||
register_tool(
|
||||
ScratchPad,
|
||||
_("Scratch Pad"),
|
||||
category=_("Utilities"),
|
||||
description=_("The Scratch Pad provides a tempory note pad to store "
|
||||
"objects for easy reuse.")
|
||||
)
|
||||
|
||||
|
113
src/plugins/scratchpad.glade
Normal file
113
src/plugins/scratchpad.glade
Normal file
@ -0,0 +1,113 @@
|
||||
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
|
||||
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
|
||||
|
||||
<glade-interface>
|
||||
<requires lib="gnome"/>
|
||||
|
||||
<widget class="GtkWindow" id="scratchPad">
|
||||
<property name="visible">True</property>
|
||||
<property name="title" translatable="yes">Scratch Pad</property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||
<property name="modal">False</property>
|
||||
<property name="default_width">400</property>
|
||||
<property name="default_height">200</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="decorated">True</property>
|
||||
<property name="skip_taskbar_hint">False</property>
|
||||
<property name="skip_pager_hint">False</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
|
||||
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||
<signal name="delete_event" handler="on_scratchPad_delete_event" object="ScratchPad" last_modification_time="Fri, 11 Mar 2005 11:35:07 GMT"/>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbx_scratchpad">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow85">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkTreeView" id="objectlist">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="headers_visible">True</property>
|
||||
<property name="rules_hint">False</property>
|
||||
<property name="reorderable">False</property>
|
||||
<property name="enable_search">True</property>
|
||||
<signal name="delete_event" handler="on_objectlist_delete_event" object="ScratchPad" last_modification_time="Wed, 09 Mar 2005 13:48:09 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHButtonBox" id="hbuttonbox37">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_DEFAULT_STYLE</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="btn_clear_all">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Clear_All</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<signal name="clicked" handler="on_clear_all_clicked" object="ScratchPad" last_modification_time="Tue, 08 Mar 2005 15:26:49 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="btn_clear">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">C_lear</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<signal name="clicked" handler="on_clear_clicked" object="ScratchPad" last_modification_time="Tue, 08 Mar 2005 15:26:40 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="btn_close">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<signal name="clicked" handler="on_close_scratchpad" object="ScratchPad" last_modification_time="Tue, 08 Mar 2005 15:26:57 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">3</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
</glade-interface>
|
Loading…
Reference in New Issue
Block a user