Added some primitive dialogs for handling modified and moved images.
authorJoel Rosdahl <joel@rosdahl.net>
Thu, 22 Jul 2004 10:19:37 +0000 (10:19 +0000)
committerJoel Rosdahl <joel@rosdahl.net>
Thu, 22 Jul 2004 10:19:37 +0000 (10:19 +0000)
Made thumbnails and single image view menu items properly inactive at
startup.

src/gkofoto/glade/gkofoto.glade
src/gkofoto/handleimagesdialog.py [new file with mode: 0644]
src/gkofoto/mainwindow.py

index a08dbd4..dba23e1 100644 (file)
                      <property name="visible">True</property>
                      <property name="label" translatable="yes">I_cons</property>
                      <property name="use_underline">True</property>
-                     <property name="active">False</property>
+                     <property name="active">True</property>
                      <signal name="activate" handler="on_icons_view_activate" last_modification_time="Sun, 11 Jul 2004 19:28:48 GMT"/>
                    </widget>
                  </child>
                      <property name="visible">True</property>
                      <property name="label" translatable="yes">_Image</property>
                      <property name="use_underline">True</property>
-                     <property name="active">False</property>
+                     <property name="active">True</property>
                      <property name="group">menubarThumbnailsView</property>
                      <signal name="activate" handler="on_image_view_activate" last_modification_time="Sun, 11 Jul 2004 19:28:48 GMT"/>
                    </widget>
                      <signal name="activate" handler="on_register_images1_activate" last_modification_time="Sun, 11 Jul 2004 19:57:53 GMT"/>
                    </widget>
                  </child>
+
+                 <child>
+                   <widget class="GtkMenuItem" id="menubarHandleModifiedOrRenamedImages">
+                     <property name="visible">True</property>
+                     <property name="label" translatable="yes">Handle modified/moved/renamed images...</property>
+                     <property name="use_underline">True</property>
+                     <signal name="activate" handler="on_menubarUpdateImages_activate" last_modification_time="Wed, 21 Jul 2004 16:33:01 GMT"/>
+                   </widget>
+                 </child>
                </widget>
              </child>
            </widget>
@@ -1821,4 +1830,128 @@ The categories' children will not be destroyed, nor will the images associated w
   </child>
 </widget>
 
+<widget class="GtkDialog" id="updateImagesDialog">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">dialog1</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</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_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="has_separator">True</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox4">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child internal-child="action_area">
+       <widget class="GtkHButtonBox" id="dialog-action_area4">
+         <property name="visible">True</property>
+         <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+         <child>
+           <widget class="GtkButton" id="cancelbutton3">
+             <property name="visible">True</property>
+             <property name="can_default">True</property>
+             <property name="can_focus">True</property>
+             <property name="label">gtk-cancel</property>
+             <property name="use_stock">True</property>
+             <property name="relief">GTK_RELIEF_NORMAL</property>
+             <property name="focus_on_click">True</property>
+             <property name="response_id">-6</property>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="GtkButton" id="okbutton2">
+             <property name="visible">True</property>
+             <property name="can_default">True</property>
+             <property name="can_focus">True</property>
+             <property name="label">gtk-ok</property>
+             <property name="use_stock">True</property>
+             <property name="relief">GTK_RELIEF_NORMAL</property>
+             <property name="focus_on_click">True</property>
+             <property name="response_id">-5</property>
+           </widget>
+         </child>
+       </widget>
+       <packing>
+         <property name="padding">0</property>
+         <property name="expand">False</property>
+         <property name="fill">True</property>
+         <property name="pack_type">GTK_PACK_END</property>
+       </packing>
+      </child>
+
+      <child>
+       <widget class="GtkVBox" id="vbox12">
+         <property name="visible">True</property>
+         <property name="homogeneous">False</property>
+         <property name="spacing">0</property>
+
+         <child>
+           <widget class="GtkScrolledWindow" id="scrolledwindow5">
+             <property name="visible">True</property>
+             <property name="can_focus">True</property>
+             <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
+             <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+             <property name="shadow_type">GTK_SHADOW_NONE</property>
+             <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+             <child>
+               <widget class="GtkTreeView" id="filenameList">
+                 <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>
+               </widget>
+             </child>
+           </widget>
+           <packing>
+             <property name="padding">0</property>
+             <property name="expand">True</property>
+             <property name="fill">True</property>
+           </packing>
+         </child>
+
+         <child>
+           <widget class="GtkLabel" id="dialogText">
+             <property name="visible">True</property>
+             <property name="label" translatable="yes">Text</property>
+             <property name="use_underline">False</property>
+             <property name="use_markup">False</property>
+             <property name="justify">GTK_JUSTIFY_LEFT</property>
+             <property name="wrap">False</property>
+             <property name="selectable">False</property>
+             <property name="xalign">0.5</property>
+             <property name="yalign">0.5</property>
+             <property name="xpad">0</property>
+             <property name="ypad">0</property>
+           </widget>
+           <packing>
+             <property name="padding">10</property>
+             <property name="expand">False</property>
+             <property name="fill">False</property>
+           </packing>
+         </child>
+       </widget>
+       <packing>
+         <property name="padding">10</property>
+         <property name="expand">True</property>
+         <property name="fill">True</property>
+       </packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
 </glade-interface>
diff --git a/src/gkofoto/handleimagesdialog.py b/src/gkofoto/handleimagesdialog.py
new file mode 100644 (file)
index 0000000..702bcde
--- /dev/null
@@ -0,0 +1,119 @@
+import gtk
+import gobject
+import os
+from environment import env
+from kofoto.shelf import \
+     ImageDoesNotExistError, ImageExistsError, \
+     MultipleImagesAtOneLocationError, NotAnImageError, \
+     makeValidTag
+from kofoto.clientutils import walk_files
+
+class HandleImagesDialog(gtk.FileSelection):
+    def __init__(self):
+        gtk.FileSelection.__init__(self, title="Register images")
+        self.set_select_multiple(True)
+        self.ok_button.connect("clicked", self._ok)
+
+    def _ok(self, widget):
+        modifiedImages = []
+        movedImages = []
+        for filepath in walk_files(self.get_selections()):
+            filepath = filepath.decode("utf-8")
+            try:
+                image = env.shelf.getImage(filepath)
+                if image.getLocation() == os.path.realpath(filepath):
+                    # Registered.
+                    pass
+                else:
+                    # Moved.
+                    movedImages.append(filepath)
+            except ImageDoesNotExistError:
+                try:
+                    image = env.shelf.getImage(
+                        filepath, identifyByLocation=True)
+                    # Modified.
+                    modifiedImages.append(filepath)
+                except MultipleImagesAtOneLocationError:
+                    # Multiple images at one location.
+                    # TODO: Handle this error.
+                    pass
+                except ImageDoesNotExistError:
+                    # Unregistered.
+                    pass
+        if modifiedImages or movedImages:
+            if modifiedImages:
+                self._dialogHelper(
+                    "Update modified images",
+                    "The above image files have been modified. Press OK to"
+                    " make Kofoto recognize the new contents.",
+                    modifiedImages,
+                    self._updateModifiedImages)
+            if movedImages:
+                self._dialogHelper(
+                    "Update moved or renamed images",
+                    "The above image files have been moved or renamed. Press OK to"
+                    " make Kofoto recognize the new locations.",
+                    movedImages,
+                    self._updateMovedImages)
+        else:
+            dialog = gtk.MessageDialog(
+                type=gtk.MESSAGE_INFO,
+                buttons=gtk.BUTTONS_OK,
+                message_format="No modified, renamed or moved images found.")
+            dialog.run()
+            dialog.destroy()
+
+    def _dialogHelper(self, title, text, filepaths, handlerFunction):
+        widgets = gtk.glade.XML(env.gladeFile, "updateImagesDialog")
+        dialog = widgets.get_widget("updateImagesDialog")
+        dialog.set_title(title)
+        filenameList = widgets.get_widget("filenameList")
+        renderer = gtk.CellRendererText()
+        column = gtk.TreeViewColumn("Image filename", renderer, text=0)
+        filenameList.append_column(column)
+        dialogText = widgets.get_widget("dialogText")
+        dialogText.set_text(text)
+        model = gtk.ListStore(gobject.TYPE_STRING)
+        for filepath in filepaths:
+            model.append([filepath])
+        filenameList.set_model(model)
+        if dialog.run() == gtk.RESPONSE_OK:
+            handlerFunction(filepaths)
+        dialog.destroy()
+
+    def _error(self, errorText):
+        dialog = gtk.MessageDialog(
+            type=gtk.MESSAGE_ERROR,
+            buttons=gtk.BUTTONS_OK,
+            message_format=errorText)
+        dialog.run()
+        dialog.destroy()
+
+    def _updateModifiedImages(self, filepaths):
+        for filepath in filepaths:
+            try:
+                image = env.shelf.getImage(
+                    filepath, identifyByLocation=True)
+                image.contentChanged()
+            except ImageDoesNotExistError:
+                self._error("Image does not exist: %s" % filepath)
+            except MultipleImagesAtOneLocationError:
+                # TODO: Handle this.
+                pass
+            except IOError, x:
+                self._error("Error while reading %s: %s" % (
+                    filepath, x))
+
+    def _updateMovedImages(self, filepaths):
+        for filepath in filepaths:
+            try:
+                image = env.shelf.getImage(filepath)
+                image.locationChanged(filepath)
+            except ImageDoesNotExistError:
+                self._error("Image does not exist: %s" % filepath)
+            except MultipleImagesAtOneLocationError:
+                # TODO: Handle this.
+                pass
+            except IOError, x:
+                self._error("Error while reading %s: %s" % (
+                    filepath, x))
index b4816bf..5058e63 100644 (file)
@@ -11,6 +11,7 @@ from gkofoto.singleobjectview import *
 from gkofoto.objectcollectionfactory import *
 from gkofoto.objectcollection import *
 from gkofoto.registerimagesdialog import RegisterImagesDialog
+from gkofoto.handleimagesdialog import HandleImagesDialog
 
 class MainWindow(gtk.Window):
     def __init__(self):
@@ -50,6 +51,8 @@ class MainWindow(gtk.Window):
         env.widgets["menubarZoom"].set_sensitive(False)
 
         env.widgets["menubarRegisterImages"].connect("activate", self.registerImages, None)
+        env.widgets["menubarHandleModifiedOrRenamedImages"].connect(
+            "activate", self.handleModifiedOrRenamedImages, None)
 
         env.widgets["menubarRotateLeft"].get_children()[1].set_from_pixbuf(
             gtk.gdk.pixbuf_new_from_file(os.path.join(env.iconDir, "rotateleft.png")))
@@ -97,6 +100,11 @@ class MainWindow(gtk.Window):
         dialog.run()
         dialog.destroy()
 
+    def handleModifiedOrRenamedImages(self, widget, data):
+        dialog = HandleImagesDialog()
+        dialog.run()
+        dialog.destroy()
+
     def getIconImage(self, name):
         pixbuf = gtk.gdk.pixbuf_new_from_file(os.path.join(env.iconDir, name))
         image = gtk.Image()