add new, save and save_as features
authorgc <gc>
Sun, 17 Apr 2005 01:10:35 +0000 (01:10 +0000)
committergc <gc>
Sun, 17 Apr 2005 01:10:35 +0000 (01:10 +0000)
bin/booh-gui
data/booh/images/stock-close-24.png [new file with mode: 0644]

index d0aa2cdf871c5df7458b82185e364b1f84e5e7ea..4ca72c98b93efdf6da28011e4b0a15fceb3303db 100755 (executable)
@@ -107,7 +107,7 @@ def write_config
 
     ios = File.open($config_file, "w")
     $xmldoc = Document.new "<booh-gui-rc version='#{$VERSION}'/>"
-    $xmldoc << XMLDecl.new( XMLDecl::DEFAULT_VERSION, $CURRENT_CHARSET )
+    $xmldoc << XMLDecl.new(XMLDecl::DEFAULT_VERSION, $CURRENT_CHARSET)
     $config.each_pair { |key, value|
         elem = $xmldoc.root.add_element key
         if value.is_a? Hash
@@ -236,6 +236,7 @@ def create_editzone(scrolledwindow, pagenum)
     }
     textview.signal_connect('key-release-event') { |w, event|
         if candidate_undo_text && candidate_undo_text != textview.buffer.text
+            $modified = true
             save_undo(_("text edit"),
                       Proc.new { |text|
                           save_text = textview.buffer.text
@@ -257,6 +258,8 @@ def create_editzone(scrolledwindow, pagenum)
 end
 
 def rotate_real(angle, thumbnail_img, img, xmlelem, attributes_prefix, desired_x, desired_y)
+    $modified = true
+
     #- update rotate attribute
     xmlelem.add_attribute("#{attributes_prefix}rotate", current_angle = ( xmlelem.attributes["#{attributes_prefix}rotate"].to_i + angle ) % 360)
 
@@ -282,6 +285,7 @@ def rotate_real(angle, thumbnail_img, img, xmlelem, attributes_prefix, desired_x
 end
 
 def rotate(angle, thumbnail_img, img, xmlelem, attributes_prefix, desired_x, desired_y)
+    $modified = true
 
     rotate_real(angle, thumbnail_img, img, xmlelem, attributes_prefix, desired_x, desired_y)
 
@@ -298,6 +302,7 @@ def rotate(angle, thumbnail_img, img, xmlelem, attributes_prefix, desired_x, des
 end
 
 def color_swap(xmldir, attributes_prefix)
+    $modified = true
     if xmldir.attributes["#{attributes_prefix}color-swap"]
         xmldir.delete_attribute("#{attributes_prefix}color-swap")
     else
@@ -306,6 +311,7 @@ def color_swap(xmldir, attributes_prefix)
 end
 
 def enhance(xmldir, attributes_prefix)
+    $modified = true
     if xmldir.attributes["#{attributes_prefix}enhance"]
         xmldir.delete_attribute("#{attributes_prefix}enhance")
     else
@@ -314,6 +320,7 @@ def enhance(xmldir, attributes_prefix)
 end
 
 def change_frame_offset(xmldir, attributes_prefix, value)
+    $modified = true
     xmldir.add_attribute("#{attributes_prefix}frame-offset", value)
 end
 
@@ -349,6 +356,7 @@ from. There are approximately 25 frames per second in a video.
     dialog.show_all
 
     dialog.run { |response|
+        $modified = true
         newval = entry.text
         dialog.destroy
         if response == Gtk::Dialog::RESPONSE_OK
@@ -532,6 +540,7 @@ def add_thumbnail(autotable, filename, type, thumbnail_img, caption)
     }
 
     delete = Proc.new {
+        $modified = true
         perform_delete = Proc.new {
             after = autotable.get_next_widget(vbox)
             if !after
@@ -681,6 +690,7 @@ def add_thumbnail(autotable, filename, type, thumbnail_img, caption)
             if target.name == 'reorder-elements'
                 from, to = selection_data.data.to_i, autotable.get_current_number(vbox)
                 if from != to
+                    $modified = true
                     autotable.move(from, to)
                     save_undo(_("reorder"),
                               Proc.new { |from, to|
@@ -723,13 +733,38 @@ def create_subalbums_page
     $subalbums_sw.add_with_viewport(subalbums_hb)
 end
 
-def try_quit
+def save_current_file
     save_changes
     if $filename
         ios = File.open($filename, "w")
         $xmldoc.write(ios, 0)
         ios.close
+        $modified = false
     end
+end
+
+def try_quit
+    if $modified
+        dialog = Gtk::Dialog.new(utf8(_("Save before quitting?")),
+                                 $main_window,
+                                 Gtk::Dialog::MODAL | Gtk::Dialog::DESTROY_WITH_PARENT,
+                                 [Gtk::Stock::CLOSE, Gtk::Dialog::RESPONSE_NO],
+                                 [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
+                                 [Gtk::Stock::SAVE, Gtk::Dialog::RESPONSE_YES])
+        dialog.vbox.add(Gtk::Label.new(utf8(_("Do you want to save your changes before quitting?"))))
+        dialog.window_position = Gtk::Window::POS_CENTER
+        dialog.show_all
+        
+        dialog.run { |response|
+            dialog.destroy
+            if response == Gtk::Dialog::RESPONSE_CANCEL
+                return
+            elsif response == Gtk::Dialog::RESPONSE_YES
+                save_current_file
+            end
+        }
+    end
+
     Gtk.main_quit
 end
 
@@ -742,6 +777,9 @@ def show_popup(parent, msg, *options)
         lbl.set_justify(Gtk::Justification::CENTER)
     end
     dialog.vbox.add(lbl)
+    if options[0] && options[0][:okcancel]
+        dialog.add_button(Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL)
+    end
     dialog.add_button(Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK)
 
     dialog.transient_for = parent
@@ -753,8 +791,36 @@ def show_popup(parent, msg, *options)
     end
     dialog.show_all
 
-    dialog.run
-    dialog.destroy
+    dialog.run { |response|
+        dialog.destroy
+        if options[0] && options[0][:okcancel]
+            return response == Gtk::Dialog::RESPONSE_OK
+        end
+    }
+end
+
+def wait_message(parent, msg)
+    w = Gtk::Window.new
+    w.set_transient_for(parent)
+
+    vb = Gtk::VBox.new(false, 5)
+    vb.pack_start(Gtk::Label.new(msg), false, false)
+    bottom = Gtk::Alignment.new(0.5, 0.5, 0, 0).add(b = Gtk::Button.new(utf8(_("_Abort"))))
+    b.image = Gtk::Image.new("#{$FPATH}/images/stock-close-24.png")
+    vb.pack_start(pb = Gtk::ProgressBar.new.set_pulse_step(0.05), false, false)
+    vb.pack_start(Gtk::HSeparator.new, false, false)
+    vb.pack_end(bottom, false, false)
+
+    timeout = Gtk.timeout_add(200) { pb.pulse }
+    b.signal_connect_after('clicked') { w.destroy }
+
+    w.add(vb)
+    w.signal_connect('delete-event') { w.destroy }
+    w.signal_connect('destroy') { Gtk.timeout_remove(timeout) }
+    w.window_position = Gtk::Window::POS_CENTER
+    w.show_all
+
+    return [ b, w ]
 end
 
 def save_changes
@@ -1035,6 +1101,7 @@ end
 def open_file(filename)
 
     $filename = nil
+    $modified = false
     $current_path = nil   #- invalidate
     $rotated_pixbufs = {}
     $albums_ts.clear
@@ -1115,7 +1182,7 @@ def open_file_popup
     while !ok
         if fc.run == Gtk::Dialog::RESPONSE_ACCEPT
             push_mousecursor_wait(fc)
-            msg = open_file(fc.filename)
+            msg = open_file(from_utf8(fc.filename))
             pop_mousecursor(fc)
             if msg
                 show_popup(fc, msg)
@@ -1130,6 +1197,149 @@ def open_file_popup
     fc.destroy
 end
 
+def new_album
+    dialog = Gtk::Dialog.new(utf8(_("Create a new album")),
+                             $main_window,
+                             Gtk::Dialog::MODAL | Gtk::Dialog::DESTROY_WITH_PARENT,
+                             [Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK],
+                             [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL])
+    
+    frame1 = Gtk::Frame.new(utf8(_("Locations"))).add(tbl = Gtk::Table.new(0, 0, false))
+    tbl.attach(Gtk::Label.new(utf8(_("Directory of images/videos: "))),
+               0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 2, 2)
+    tbl.attach(src = Gtk::Entry.new,
+               1, 2, 0, 1, Gtk::FILL, Gtk::SHRINK, 2, 2)
+    tbl.attach(src_browse = Gtk::Button.new(utf8(_("browse..."))),
+               2, 3, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 2, 2)
+    tbl.attach(Gtk::Label.new(utf8(_("Directory where to put the web-album: "))),
+               0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 2, 2)
+    tbl.attach(dest = Gtk::Entry.new,
+               1, 2, 1, 2, Gtk::FILL, Gtk::SHRINK, 2, 2)
+    tbl.attach(dest_browse = Gtk::Button.new(utf8(_("browse..."))),
+               2, 3, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 2, 2)
+    tbl.attach(Gtk::Label.new(utf8(_("Filename to store this album's properties: "))),
+               0, 1, 2, 3, Gtk::SHRINK, Gtk::SHRINK, 2, 2)
+    tbl.attach(conf = Gtk::Entry.new.set_size_request(250, -1),
+               1, 2, 2, 3, Gtk::FILL, Gtk::SHRINK, 2, 2)
+    tbl.attach(conf_browse = Gtk::Button.new(utf8(_("browse..."))),
+               2, 3, 2, 3, Gtk::SHRINK, Gtk::SHRINK, 2, 2)
+
+    src_browse.signal_connect('clicked') {
+        fc = Gtk::FileChooserDialog.new(utf8(_("Select the directory of images/videos")),
+                                        nil,
+                                        Gtk::FileChooser::ACTION_SELECT_FOLDER,
+                                        nil,
+                                        [Gtk::Stock::OPEN, Gtk::Dialog::RESPONSE_ACCEPT], [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL])
+        fc.transient_for = $main_window
+        if fc.run == Gtk::Dialog::RESPONSE_ACCEPT
+            src.text = fc.filename
+            conf.text = File.expand_path("~/.booh-gui-files/#{File.basename(src.text)}")
+        end
+        fc.destroy
+    }
+
+    dest_browse.signal_connect('clicked') {
+        fc = Gtk::FileChooserDialog.new(utf8(_("Select a new directory where to put the web-album")),
+                                        nil,
+                                        Gtk::FileChooser::ACTION_CREATE_FOLDER,
+                                        nil,
+                                        [Gtk::Stock::OPEN, Gtk::Dialog::RESPONSE_ACCEPT], [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL])
+        fc.transient_for = $main_window
+        if fc.run == Gtk::Dialog::RESPONSE_ACCEPT
+            dest.text = fc.filename
+        end
+        fc.destroy
+    }
+
+    conf_browse.signal_connect('clicked') {
+        fc = Gtk::FileChooserDialog.new(utf8(_("Select a new file to store this album's properties")),
+                                        nil,
+                                        Gtk::FileChooser::ACTION_SAVE,
+                                        nil,
+                                        [Gtk::Stock::OPEN, Gtk::Dialog::RESPONSE_ACCEPT], [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL])
+        fc.transient_for = $main_window
+        fc.add_shortcut_folder(File.expand_path("~/.booh-gui-files"))
+        fc.set_current_folder(File.expand_path("~/.booh-gui-files"))
+        if fc.run == Gtk::Dialog::RESPONSE_ACCEPT
+            conf.text = fc.filename
+        end
+        fc.destroy
+    }
+
+    dialog.vbox.add(frame1)
+    dialog.window_position = Gtk::Window::POS_MOUSE
+    dialog.show_all
+
+    keepon = true
+    ok = true
+    while keepon
+        dialog.run { |response|
+            if response == Gtk::Dialog::RESPONSE_OK
+                srcdir = from_utf8(src.text)
+                destdir = from_utf8(dest.text)
+                if !File.directory?(srcdir)
+                    show_popup(dialog, utf8(_("The directory of images/videos doesn't exist. Please check your input.")))
+                    src.grab_focus
+                elsif conf.text == ''
+                    show_popup(dialog, utf8(_("Please specify a filename to store the album's properties.")))
+                    conf.grab_focus
+                elsif File.directory?(destdir)
+                    keepon = !show_popup(dialog, utf8(_("The destination directory already exists. Are you sure you want to continue?")), { :okcancel => true })
+                    dest.grab_focus
+                elsif File.exists?(destdir)
+                    show_popup(dialog, utf8(_("There is already a file by the name of the destination directory. Please choose another one.")))
+                    dest.grab_focus
+                else
+                    system("mkdir '#{destdir}'")
+                    if !File.directory?(destdir)
+                        show_popup(dialog, utf8(_("Could not create destination directory. Permission denied?")))
+                        dest.grab_focus
+                    else
+                        keepon = false
+                    end
+                end
+            else
+                keepon = ok = false
+            end
+        }
+    end
+    srcdir = from_utf8(src.text)
+    destdir = from_utf8(dest.text)
+    configskel = from_utf8(conf.text)
+    dialog.destroy
+
+    if ok
+        button, w8 = wait_message($main_window, utf8(_("Please wait while scanning source directory...")))
+        backend = Thread.new {
+            cmd = "booh --source #{srcdir} --destination #{destdir} --config-skel #{configskel} --for-gui --verbose-level #{$verbose_level}"
+            msg 2, cmd
+            system(cmd)
+            w8.destroy
+            open_file(configskel)
+        }
+        button.signal_connect('clicked') {
+            Thread.kill(backend)
+        }
+    end
+end
+
+def save_as_do
+    fc = Gtk::FileChooserDialog.new(utf8(_("Select a new filename to store this album's properties")),
+                                    nil,
+                                    Gtk::FileChooser::ACTION_SAVE,
+                                    nil,
+                                    [Gtk::Stock::OPEN, Gtk::Dialog::RESPONSE_ACCEPT], [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL])
+    fc.transient_for = $main_window
+    fc.add_shortcut_folder(File.expand_path("~/.booh-gui-files"))
+    fc.set_current_folder(File.expand_path("~/.booh-gui-files"))
+    fc.filename = $filename
+    if fc.run == Gtk::Dialog::RESPONSE_ACCEPT
+        $filename = from_utf8(fc.filename)
+        save_current_file
+    end
+    fc.destroy
+end
+
 def create_menu_and_toolbar
 
     #- menu
@@ -1141,13 +1351,16 @@ def create_menu_and_toolbar
     filesubmenu.append(open    = Gtk::ImageMenuItem.new(Gtk::Stock::OPEN))
     filesubmenu.append(          Gtk::SeparatorMenuItem.new)
     filesubmenu.append(save    = Gtk::ImageMenuItem.new(Gtk::Stock::SAVE))
-    filesubmenu.append(save    = Gtk::ImageMenuItem.new(Gtk::Stock::SAVE_AS))
+    filesubmenu.append(save_as = Gtk::ImageMenuItem.new(Gtk::Stock::SAVE_AS))
     filesubmenu.append(          Gtk::SeparatorMenuItem.new)
     filesubmenu.append(quit    = Gtk::ImageMenuItem.new(Gtk::Stock::QUIT))
     filemenu.set_submenu(filesubmenu)
     mb.append(filemenu)
 
+    new.signal_connect('activate') { new_album }
     open.signal_connect('activate') { open_file_popup }
+    save.signal_connect('activate') { save_current_file }
+    save_as.signal_connect('activate') { save_as_do }
     quit.signal_connect('activate') { try_quit }
 
     editmenu = Gtk::MenuItem.new(utf8(_("_Edit")))
@@ -1414,7 +1627,7 @@ def create_main_window
     $main_window.show_all
 end
 
-
+Thread.abort_on_exception = true
 handle_options
 read_config
 
diff --git a/data/booh/images/stock-close-24.png b/data/booh/images/stock-close-24.png
new file mode 100644 (file)
index 0000000..b560765
Binary files /dev/null and b/data/booh/images/stock-close-24.png differ