all labels can be visible or not; use proper color selection; allow to move files
authorgc <gc>
Fri, 17 Aug 2007 18:42:11 +0000 (18:42 +0000)
committergc <gc>
Fri, 17 Aug 2007 18:42:11 +0000 (18:42 +0000)
bin/booh-classifier

index 5258c1905bddfb78a33feaacab8c8aad3d6f39b6..130c702b25cbf1ed4e4dd49c8e0a837781d6cd29 100644 (file)
@@ -218,7 +218,7 @@ $colors = [ Gdk::Color.new(0, 65535, 0),
             Gdk::Color.new(65535, 0, 65535) ]
 
 class Label
-    attr_accessor :color, :name
+    attr_accessor :color, :name, :button
     def initialize(name)
         @name = name
     end
@@ -723,26 +723,24 @@ def thumbnail_keypressed(entry, event)
             entry.labeled = nil
             entry.show_bg
             $mainview.show_next_entry(entry)
-            if $hide_todel.active?
-                entry.button.hide
-            end
+            update_visibility(entry)
 
             save_undo(_("set for removal"),
                       proc {
                           entry.removed = removed_before
                           entry.labeled = label_before
                           entry.show_bg
-                          if ! $hide_todel.active? && ! entry.removed
-                              entry.button.show
+                          update_visibility(entry)
+                          if entry.button.visible?
                               $mainview.set_shown_entry(entry)
                           end
                           proc {
                               entry.removed = true
                               entry.labeled = nil
                               entry.show_bg
-                              $mainview.set_shown_entry(entry)
-                              if $hide_todel.active?
-                                  entry.button.hide
+                              update_visibility(entry)
+                              if entry.button.visible?
+                                  $mainview.set_shown_entry(entry)
                               end
                           }
                       })
@@ -783,19 +781,10 @@ def thumbnail_keypressed(entry, event)
                 if label.nil?
                     vb = Gtk::VBox.new(false, 0)
                     vb.pack_start(entry = Gtk::Entry.new.set_text(char), false, false)
-                    vb.pack_start(Gtk::Alignment.new(0.5, 0.5, 0, 0).add(bt = Gtk::Button.new(utf8(_("  Change color  ")))))
+                    vb.pack_start(Gtk::Alignment.new(0.5, 0.5, 0, 0).add(bt = Gtk::ColorButton.new))
+                    color = bt.color = Gdk::Color.new(16384 + rand(49151), 16384 + rand(49151), 16384 + rand(49151))
+                    bt.signal_connect('color-set') { color = bt.color }
                     text = nil
-                    color = nil
-                    bt.signal_connect('clicked') {
-                        color = $colors.shift
-                        if color.nil?
-                            color = Gdk::Color.new(16384 + rand(49151), 16384 + rand(49151), 16384 + rand(49151))
-                        end
-                        bt.modify_bg(Gtk::StateType::NORMAL, color)
-                        bt.modify_bg(Gtk::StateType::PRELIGHT, color)
-                        bt.modify_bg(Gtk::StateType::ACTIVE, color.darker)
-                    }
-                    bt.clicked
                     entry.signal_connect('changed') {  #- cannot add a new label with first letter of an existing label
                         while $labels.has_key?(entry.text[0,1])
                             entry.text = entry.text.sub(/./, '')
@@ -813,7 +802,12 @@ def thumbnail_keypressed(entry, event)
                             label.color = color
                             $labels[char] = label
                             lbl = Gtk::Label.new.set_markup('<b>(' + char + ')</b>' + text[1..-1]).set_justify(Gtk::Justification::CENTER)
-                            $labels_vbox.pack_start(evt = Gtk::EventBox.new.add(lbl).modify_bg(Gtk::StateType::NORMAL, label.color).show_all)
+                            $labels_vbox.pack_start(label.button = Gtk::CheckButton.new.add(evt = Gtk::EventBox.new.add(lbl)).show_all)
+                            label.button.active = true
+                            label.button.signal_connect('toggled') { update_all_visibilities }
+                            evt.modify_bg(Gtk::StateType::NORMAL, label.color)
+                            evt.modify_bg(Gtk::StateType::PRELIGHT, label.color.lighter.lighter)
+                            evt.modify_bg(Gtk::StateType::ACTIVE, label.color.lighter)
                         end
                     end
 
@@ -822,18 +816,25 @@ def thumbnail_keypressed(entry, event)
                     entry.labeled = label
                     entry.show_bg
                     $mainview.show_next_entry(entry)
+                    update_visibility(entry)
 
                     save_undo(_("set label"),
                               proc {
                                   entry.removed = removed_before
                                   entry.labeled = label_before
                                   entry.show_bg
-                                  $mainview.set_shown_entry(entry)
+                                  update_visibility(entry)
+                                  if entry.button.visible?
+                                      $mainview.set_shown_entry(entry)
+                                  end
                                   proc {
                                       entry.removed = false
                                       entry.labeled = label
                                       entry.show_bg
-                                      $mainview.set_shown_entry(entry)
+                                      update_visibility(entry)
+                                      if entry.button.visible?
+                                          $mainview.set_shown_entry(entry)
+                                      end
                                   }
                               })
                 end
@@ -963,7 +964,6 @@ def open_dir(path)
     $workingdir = path
     show_entries
     $execute.sensitive = true
-    $hide_todel.sensitive = true
     return nil
 end
 
@@ -1063,6 +1063,9 @@ def execute
         if normal
             iter[0] = $main_window.render_icon(Gtk::Stock::GO_FORWARD, Gtk::IconSize::MENU)
             iter[1] = utf8(_("Move to:"))
+            iter = combostore.append
+            iter[0] = $main_window.render_icon(Gtk::Stock::PASTE, Gtk::IconSize::MENU)
+            iter[1] = utf8(_("Copy to:"))
         else
             iter[0] = $main_window.render_icon(Gtk::Stock::DELETE, Gtk::IconSize::MENU)
             iter[1] = utf8(_("Permanently remove"))
@@ -1097,7 +1100,7 @@ def execute
                 fc.destroy
             }
             combo.signal_connect('changed') {
-                pathbutton.sensitive = combo.active == 0
+                pathbutton.sensitive = combo.active <= 1
             }
             vb = Gtk::VBox.new(false, 5)
             vb.pack_start(combo, false, false)
@@ -1110,7 +1113,7 @@ def execute
         end
     }
     stuff = {}
-    stuff['toremove'] = add_row.call(1, utf8(_("<i>to remove</i>")), Gdk::Color.new(65535, 0, 0), proc { |entry| entry.removed }, false)
+    stuff['toremove'] = add_row.call(1, utf8(_("<i>to remove</i>")), $color_red, proc { |entry| entry.removed }, false)
     $labels.values.each_with_index { |label, row| stuff[label] = add_row.call(row + 2, label.name, label.color, proc { |entry| entry.labeled == label }, true) }
     vb1.pack_start(sw = Gtk::ScrolledWindow.new(nil, nil).add_with_viewport(table).set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC), true, true)
 
@@ -1146,10 +1149,10 @@ def execute
                 $labels.values.each { |label| label2entries[label] = [] }
                 $allentries.each { |entry| entry.labeled and label2entries[entry.labeled] << entry }
                 stuff.keys.each { |key|
-                    if key.is_a?(Label) && stuff[key][:combo].active == 0
+                    if key.is_a?(Label) && stuff[key][:combo].active <= 1
                         destination = stuff[key][:pathlabel].text
                         if destination[0] != ?/
-                            show_popup(dialog, utf8(_("You have not selected a directory where to move %s.") % key.name))
+                            show_popup(dialog, utf8(_("You have not selected a directory where to move/copy %s.") % key.name))
                             problem = true
                             break
                         end
@@ -1160,12 +1163,12 @@ def execute
                         begin
                             st = File.stat(destination)
                         rescue
-                            show_popup(dialog, utf8(_("Directory %s, where to move %s, is not valid or not createable.") % [destination, key.name]))
+                            show_popup(dialog, utf8(_("Directory %s, where to move/copy %s, is not valid or not createable.") % [destination, key.name]))
                             problem = true
                             break
                         end
                         if ! st.directory? || ! st.writable?
-                            show_popup(dialog, utf8(_("Directory %s, where to move %s, is not valid or not writable.") % [destination, key.name]))
+                            show_popup(dialog, utf8(_("Directory %s, where to move/copy %s, is not valid or not writable.") % [destination, key.name]))
                             problem = true
                             break
                         end
@@ -1186,12 +1189,18 @@ def execute
                 if ! problem
                     begin
                         moved = 0
+                        copied = 0
                         stuff.keys.each { |key|
-                            if key.is_a?(Label) && stuff[key][:combo].active == 0
+                            if key.is_a?(Label) && stuff[key][:combo].active <= 1
                                 destination = stuff[key][:pathlabel].text
                                 label2entries[key].each { |entry|
-                                    File.rename(entry.path, File.join(destination, File.basename(entry.path)))
-                                    moved += 1
+                                    if stuff[key][:combo].active == 0
+                                        File.rename(entry.path, File.join(destination, File.basename(entry.path)))
+                                        moved += 1
+                                    elsif stuff[key][:combo].active == 1
+                                        system("cp -dp '#{entry.path}' '#{destination}'")
+                                        copied += 1
+                                    end
                                 }
                             end
                         }
@@ -1208,7 +1217,7 @@ def execute
                         msg 1, "woops: #{$!}"
                         show_popup(dialog, utf8(_("Unexpected system call error: '%s'.") % $!))
                     end
-                    show_popup(dialog, utf8(_("Successfully moved %d files and removed %d files.") % [ moved, removed ]))
+                    show_popup(dialog, utf8(_("Successfully moved %d files, copied %d file, and removed %d files.") % [ moved, copied, removed ]))
                     dialog.destroy
                     reset_all
                     return
@@ -1222,15 +1231,39 @@ def execute
     end
 end
 
-def hide_todel
-    active = $hide_todel.active?
+def update_visibility(entry)
+    if entry.labeled
+        if entry.labeled.button.active?
+            entry.button.show
+        else
+            entry.button.hide
+        end
+    elsif entry.removed
+        if $toremove_button.active?
+            entry.button.show
+        else
+            entry.button.hide
+        end
+    end
+end
+        
+def update_all_visibilities
     $allentries.each { |entry|
-        if entry.removed
-            if active
-                entry.button.hide
-            else
-                entry.button.show
-            end
+        update_visibility(entry)
+    }
+    shown = $mainview.get_shown_entry
+    while ! shown.button.visible? && shown != $allentries.last
+        $mainview.show_next_entry(shown)
+        shown = $mainview.get_shown_entry
+    end 
+    if shown && shown.button.visible?
+        shown.button.grab_focus
+        return
+    end
+    $allentries.reverse.each { |entry|
+        if entry.button.visible?
+            entry.button.grab_focus
+            return
         end
     }
 end
@@ -1356,15 +1389,12 @@ def create_menubar
     editsubmenu.append($undo_mb    = Gtk::ImageMenuItem.new(Gtk::Stock::UNDO).set_sensitive(false))
     editsubmenu.append($redo_mb    = Gtk::ImageMenuItem.new(Gtk::Stock::REDO).set_sensitive(false))
     editsubmenu.append(              Gtk::SeparatorMenuItem.new)
-    editsubmenu.append($hide_todel = Gtk::CheckMenuItem.new(utf8(_("Hide images/videos marked for deletion"))).set_sensitive(false))
-    editsubmenu.append(              Gtk::SeparatorMenuItem.new)
     editsubmenu.append(prefs       = Gtk::ImageMenuItem.new(Gtk::Stock::PREFERENCES))
     editmenu.set_submenu(editsubmenu)
     mb.append(editmenu)
 
     $undo_mb.signal_connect('activate') { perform_undo }
     $redo_mb.signal_connect('activate') { perform_redo }
-    $hide_todel.signal_connect('activate') { hide_todel }
     prefs.signal_connect('activate') { preferences }
     
     helpmenu = Gtk::MenuItem.new(utf8(_("_Help")))
@@ -1391,6 +1421,13 @@ def reset_labels
     end
     $labels_vbox.pack_start(Gtk::Label.new(utf8(_("Labels list:"))).set_justify(Gtk::Justification::CENTER), false, false).show_all
     $labels = {}
+    lbl = Gtk::Label.new.set_markup(utf8(_("<i>to remove</i>")))
+    $labels_vbox.pack_start($toremove_button = Gtk::CheckButton.new.add(evt = Gtk::EventBox.new.add(lbl)).show_all)
+    $toremove_button.active = true
+    $toremove_button.signal_connect('toggled') { update_all_visibilities }
+    evt.modify_bg(Gtk::StateType::NORMAL, $color_red)
+    evt.modify_bg(Gtk::StateType::PRELIGHT, $color_red.lighter.lighter)
+    evt.modify_bg(Gtk::StateType::ACTIVE, $color_red.lighter)
 end
 
 def reset_thumbnails