2006-08-10 Don Allingham <don@gramps-project.org>
* src/DisplayTabs/_EmbeddedList.py: use cPickle instead of pickle * src/DisplayTabs/_GalleryTab.py: add dnd functionality * src/DdTargets.py: add URI_LIST and APP_ROOT svn: r7151
This commit is contained in:
		@@ -1,3 +1,8 @@
 | 
			
		||||
2006-08-10  Don Allingham  <don@gramps-project.org>
 | 
			
		||||
	* src/DisplayTabs/_EmbeddedList.py: use cPickle instead of pickle
 | 
			
		||||
	* src/DisplayTabs/_GalleryTab.py: add dnd functionality
 | 
			
		||||
	* src/DdTargets.py: add URI_LIST and APP_ROOT
 | 
			
		||||
 | 
			
		||||
2006-08-10  Alex Roitman  <shura@gramps-project.org>
 | 
			
		||||
	* src/Filters/SideBar/_PersonSidebarFilter.py (get_filter): Typo.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -153,6 +153,8 @@ class _DdTargets(object):
 | 
			
		||||
        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.
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
from gettext import gettext as _
 | 
			
		||||
import pickle
 | 
			
		||||
import cPickle as pickle
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,8 @@
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
from gettext import gettext as _
 | 
			
		||||
import cPickle as pickle
 | 
			
		||||
import urlparse
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
@@ -33,6 +35,7 @@ from gettext import gettext as _
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
import gtk
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
@@ -44,6 +47,8 @@ import Utils
 | 
			
		||||
import ImgManip
 | 
			
		||||
import Mime
 | 
			
		||||
import Errors
 | 
			
		||||
import Mime
 | 
			
		||||
from DdTargets import DdTargets
 | 
			
		||||
from _ButtonTab import ButtonTab
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
@@ -61,10 +66,16 @@ def make_launcher(prog, path):
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
class GalleryTab(ButtonTab):
 | 
			
		||||
 | 
			
		||||
    _DND_TYPE   = DdTargets.MEDIAOBJ
 | 
			
		||||
    _DND_EXTRA  = DdTargets.URI_LIST
 | 
			
		||||
 | 
			
		||||
    def __init__(self, dbstate, uistate, track,  media_list, update=None):
 | 
			
		||||
        ButtonTab.__init__(self, dbstate, uistate, track, _('Gallery'), True)
 | 
			
		||||
        self.media_list = media_list
 | 
			
		||||
        self.update = update
 | 
			
		||||
 | 
			
		||||
        self._set_dnd()
 | 
			
		||||
 | 
			
		||||
        self.rebuild()
 | 
			
		||||
        self.show_all()
 | 
			
		||||
 | 
			
		||||
@@ -257,3 +268,163 @@ class GalleryTab(ButtonTab):
 | 
			
		||||
    def edit_callback(self, media_ref, ref):
 | 
			
		||||
        self.changed = True
 | 
			
		||||
        self.rebuild()
 | 
			
		||||
 | 
			
		||||
    def _set_dnd(self):
 | 
			
		||||
        """
 | 
			
		||||
        Sets up drag-n-drop. The source and destionation are set by calling .target()
 | 
			
		||||
        on the _DND_TYPE. Obviously, this means that there must be a _DND_TYPE
 | 
			
		||||
        variable defined that points to an entry in DdTargets.
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        if self._DND_EXTRA:
 | 
			
		||||
            dnd_types = [ self._DND_TYPE.target(), self._DND_EXTRA.target() ]
 | 
			
		||||
        else:
 | 
			
		||||
            dnd_types = [ self._DND_TYPE.target() ]
 | 
			
		||||
 | 
			
		||||
        self.iconlist.drag_dest_set(gtk.DEST_DEFAULT_ALL, dnd_types,
 | 
			
		||||
                                    gtk.gdk.ACTION_COPY)
 | 
			
		||||
        self.iconlist.drag_source_set(gtk.gdk.BUTTON1_MASK,
 | 
			
		||||
                                      [self._DND_TYPE.target()],
 | 
			
		||||
                                      gtk.gdk.ACTION_COPY)
 | 
			
		||||
        self.iconlist.connect('drag_data_get', self.drag_data_get)
 | 
			
		||||
        self.iconlist.connect('drag_data_received', self.drag_data_received)
 | 
			
		||||
        
 | 
			
		||||
    def drag_data_get(self, widget, context, sel_data, info, time):
 | 
			
		||||
        """
 | 
			
		||||
        Provide the drag_data_get function, which passes a tuple consisting of:
 | 
			
		||||
 | 
			
		||||
           1) Drag type defined by the .drag_type field specfied by the value
 | 
			
		||||
              assigned to _DND_TYPE
 | 
			
		||||
           2) The id value of this object, used for the purpose of determining
 | 
			
		||||
              the source of the object. If the source of the object is the same
 | 
			
		||||
              as the object, we are doing a reorder instead of a normal drag
 | 
			
		||||
              and drop
 | 
			
		||||
           3) Pickled data. The pickled version of the selected object
 | 
			
		||||
           4) Source row. Used for a reorder to determine the original position
 | 
			
		||||
              of the object
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        # get the selected object, returning if not is defined
 | 
			
		||||
        obj = self.get_selected()
 | 
			
		||||
        if not obj:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        # pickle the data, and build the tuple to be passed
 | 
			
		||||
        value = (self._DND_TYPE.drag_type, id(self), obj, self.find_index(obj))
 | 
			
		||||
        data = pickle.dumps(value)
 | 
			
		||||
 | 
			
		||||
        # pass as a string (8 bits)
 | 
			
		||||
        sel_data.set(sel_data.target, 8, data)
 | 
			
		||||
 | 
			
		||||
    def drag_data_received(self, widget, context, x, y, sel_data, info, time):
 | 
			
		||||
        """
 | 
			
		||||
        Handle the standard gtk interface for drag_data_received.
 | 
			
		||||
 | 
			
		||||
        If the selection data is define, extract the value from sel_data.data,
 | 
			
		||||
        and decide if this is a move or a reorder.
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        if sel_data and sel_data.data:
 | 
			
		||||
            try:
 | 
			
		||||
                (mytype, selfid, obj, row_from) = pickle.loads(sel_data.data)
 | 
			
		||||
 | 
			
		||||
                # make sure this is the correct DND type for this object
 | 
			
		||||
                if mytype == self._DND_TYPE.drag_type:
 | 
			
		||||
                    
 | 
			
		||||
                    # determine the destination row
 | 
			
		||||
                    data = self.iconlist.get_dest_item_at_pos(x,y)
 | 
			
		||||
                    if data:
 | 
			
		||||
                        (path, pos) = data
 | 
			
		||||
                        row = path[0]
 | 
			
		||||
 | 
			
		||||
                        if pos ==  gtk.ICON_VIEW_DROP_LEFT:
 | 
			
		||||
                            row = max(row, 0)
 | 
			
		||||
                        elif pos == gtk.ICON_VIEW_DROP_RIGHT:
 | 
			
		||||
                            row = min(row, len(self.get_data()))
 | 
			
		||||
                        elif pos == gtk.ICON_VIEW_DROP_INTO:
 | 
			
		||||
                            row = min(row+1, len(self.get_data()))
 | 
			
		||||
                    else:
 | 
			
		||||
                        row = len(self.get_data())
 | 
			
		||||
                    
 | 
			
		||||
                    # if the is same object, we have a move, otherwise,
 | 
			
		||||
                    # it is a standard drag-n-drop
 | 
			
		||||
                    
 | 
			
		||||
                    if id(self) == selfid:
 | 
			
		||||
                        self._move(row_from, row, obj)
 | 
			
		||||
                    else:
 | 
			
		||||
                        self._handle_drag(row, obj)
 | 
			
		||||
                    self.rebuild()
 | 
			
		||||
                elif self._DND_EXTRA and mytype == self._DND_EXTRA.drag_type:
 | 
			
		||||
                    self.handle_extra_type(mytype, obj)
 | 
			
		||||
            except pickle.UnpicklingError:
 | 
			
		||||
                d = Utils.fix_encoding(sel_data.data.replace('\0',' ').strip())
 | 
			
		||||
                protocol,site,mfile,j,k,l = urlparse.urlparse(d)
 | 
			
		||||
                if protocol == "file":
 | 
			
		||||
                    name = Utils.fix_encoding(mfile)
 | 
			
		||||
                    mime = Mime.get_type(name)
 | 
			
		||||
                    if not Mime.is_valid_type(mime):
 | 
			
		||||
                        return
 | 
			
		||||
                    photo = RelLib.MediaObject()
 | 
			
		||||
                    photo.set_path(name)
 | 
			
		||||
                    photo.set_mime_type(mime)
 | 
			
		||||
                    basename = os.path.basename(name)
 | 
			
		||||
                    (root,ext) = os.path.splitext(basename)
 | 
			
		||||
                    photo.set_description(root)
 | 
			
		||||
                    trans = self.dbstate.db.transaction_begin()
 | 
			
		||||
                    self.dbstate.db.add_object(photo, trans)
 | 
			
		||||
                    oref = RelLib.MediaRef()
 | 
			
		||||
                    oref.set_reference_handle(photo.get_handle())
 | 
			
		||||
                    self.get_data().append(oref)
 | 
			
		||||
                    self.changed = True
 | 
			
		||||
#                    self.dataobj.add_media_reference(oref)
 | 
			
		||||
                    self.dbstate.db.transaction_commit(trans,
 | 
			
		||||
                                                       _("Drag Media Object"))
 | 
			
		||||
                    self.rebuild()
 | 
			
		||||
#                 elif protocol != "":
 | 
			
		||||
#                     import urllib
 | 
			
		||||
#                     u = urllib.URLopener()
 | 
			
		||||
#                     try:
 | 
			
		||||
#                         tfile,headers = u.retrieve(d)
 | 
			
		||||
#                     except (IOError,OSError), msg:
 | 
			
		||||
#                         t = _("Could not import %s") % d
 | 
			
		||||
#                         ErrorDialog(t,str(msg))
 | 
			
		||||
#                         return
 | 
			
		||||
#                     tfile = Utils.fix_encoding(tfile)
 | 
			
		||||
#                     mime = GrampsMime.get_type(tfile)
 | 
			
		||||
#                     photo = RelLib.MediaObject()
 | 
			
		||||
#                     photo.set_mime_type(mime)
 | 
			
		||||
#                     photo.set_description(d)
 | 
			
		||||
#                     photo.set_path(tfile)
 | 
			
		||||
#                     trans = self.db.transaction_begin()
 | 
			
		||||
#                     self.db.add_object(photo,trans)
 | 
			
		||||
#                     self.db.transaction_commit(trans,_("Drag Media Object"))
 | 
			
		||||
#                     oref = RelLib.MediaRef()
 | 
			
		||||
#                     oref.set_reference_handle(photo.get_handle())
 | 
			
		||||
#                     self.dataobj.add_media_reference(oref)
 | 
			
		||||
#                     self.add_thumbnail(oref)
 | 
			
		||||
 | 
			
		||||
    def handle_extra_type(self, objtype, obj):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def _handle_drag(self, row, obj):
 | 
			
		||||
        self.get_data().insert(row, obj)
 | 
			
		||||
        self.changed = True
 | 
			
		||||
        self.rebuild()
 | 
			
		||||
 | 
			
		||||
    def _move(self, row_from, row_to, obj):
 | 
			
		||||
        dlist = self.get_data()
 | 
			
		||||
        if row_from < row_to:
 | 
			
		||||
            dlist.insert(row_to, obj)
 | 
			
		||||
            del dlist[row_from]
 | 
			
		||||
        else:
 | 
			
		||||
            del dlist[row_from]
 | 
			
		||||
            dlist.insert(row_to-1, obj)
 | 
			
		||||
        self.changed = True
 | 
			
		||||
        self.rebuild()
 | 
			
		||||
 | 
			
		||||
    def find_index(self, obj):
 | 
			
		||||
        """
 | 
			
		||||
        returns the index of the object within the associated data
 | 
			
		||||
        """
 | 
			
		||||
        return self.get_data().index(obj)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user