[glom] Image fields: Add Open, Open With, and Save context menu items.



commit d47124d746e15c738f29c647341898d209663753
Author: Murray Cumming <murrayc murrayc com>
Date:   Tue Jul 12 11:28:01 2011 +0200

    Image fields: Add Open, Open With, and Save context menu items.
    
    * glom/utility_widgets/dialog_image_save_progress.[h|cc]:
    * ui/operator/dialog_image_save_progress.glade:
    Added a progress dialog to do image saving, though it does not yet do
    async saving so the dialog is never shown.
    * Makefile.am:
    * Makefile_glom.am:
    * po/POTFILES.in: Mention the new files.
      * glom/utility_widgets/imageglom.[h|cc]: Add the new context menu items,
      using a temporary file for the Open and Open With features.
      Open With uses AppChooserDialog to offer a choice to the user.
      Bug #630057

 ChangeLog                                          |   16 ++
 Makefile.am                                        |    1 +
 Makefile_glom.am                                   |    2 +
 glom/utility_widgets/dialog_image_load_progress.cc |    3 +-
 glom/utility_widgets/dialog_image_load_progress.h  |    1 -
 glom/utility_widgets/dialog_image_save_progress.cc |   82 ++++++++++
 glom/utility_widgets/dialog_image_save_progress.h  |   55 +++++++
 glom/utility_widgets/imageglom.cc                  |  158 +++++++++++++++++++-
 glom/utility_widgets/imageglom.h                   |   12 +-
 glom/xsl_utils.cc                                  |    3 +-
 po/ChangeLog                                       |    6 +
 po/POTFILES.in                                     |    2 +
 tests/test_glade_derived_instantiation.cc          |    2 +
 ui/operator/dialog_image_load_progress.glade       |    4 +-
 ui/operator/dialog_image_save_progress.glade       |   69 +++++++++
 15 files changed, 399 insertions(+), 17 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index accf6da..46be0ef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2011-07-12  Murray Cumming  <murrayc murrayc com>
+
+	Image fields: Add Open, Open With, and Save context menu items.
+
+	* glom/utility_widgets/dialog_image_save_progress.[h|cc]:
+	* ui/operator/dialog_image_save_progress.glade:
+	Added a progress dialog to do image saving, though it does not yet do 
+	async saving so the dialog is never shown.
+	* Makefile.am:
+	* Makefile_glom.am:
+	* po/POTFILES.in: Mention the new files.
+  * glom/utility_widgets/imageglom.[h|cc]: Add the new context menu items,
+  using a temporary file for the Open and Open With features.
+  Open With uses AppChooserDialog to offer a choice to the user.
+  Bug #630057
+
 2011-07-11  Murray Cumming  <murrayc murrayc com>
 
 	Rename Dialog_Image_Progress to DialogImageLoadProgress
diff --git a/Makefile.am b/Makefile.am
index fd0b555..037d217 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -90,6 +90,7 @@ dist_glade_operator_DATA = \
 	ui/operator/dialog_existing_or_new.glade \
 	ui/operator/dialog_find_id.glade \
 	ui/operator/dialog_image_load_progress.glade \
+	ui/operator/dialog_image_save_progress.glade \
 	ui/operator/dialog_import_csv.glade \
 	ui/operator/dialog_import_csv_progress.glade \
 	ui/operator/window_main.glade \
diff --git a/Makefile_glom.am b/Makefile_glom.am
index 56c3748..1bc19c0 100644
--- a/Makefile_glom.am
+++ b/Makefile_glom.am
@@ -190,6 +190,8 @@ glom_source_files = \
 	glom/utility_widgets/dialog_flowtable.h				\
 	glom/utility_widgets/dialog_image_load_progress.cc			\
 	glom/utility_widgets/dialog_image_load_progress.h			\
+	glom/utility_widgets/dialog_image_save_progress.cc			\
+	glom/utility_widgets/dialog_image_save_progress.h			\
 	glom/utility_widgets/dialog_properties.cc			\
 	glom/utility_widgets/dialog_properties.h			\
 	glom/utility_widgets/flowtable.cc				\
diff --git a/glom/utility_widgets/dialog_image_load_progress.cc b/glom/utility_widgets/dialog_image_load_progress.cc
index f681f5c..a5b6222 100644
--- a/glom/utility_widgets/dialog_image_load_progress.cc
+++ b/glom/utility_widgets/dialog_image_load_progress.cc
@@ -40,7 +40,7 @@ const bool DialogImageLoadProgress::glade_developer(false);
 DialogImageLoadProgress::DialogImageLoadProgress(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& builder)
 : Gtk::Dialog(cobject)
 {
-  builder->get_widget("image_loading_progress_bar", m_progress_bar);
+  builder->get_widget("progress_bar", m_progress_bar);
 
   if(!m_progress_bar)
     throw std::runtime_error("Missing widgets from glade file for DialogImageLoadProgress");
@@ -50,6 +50,7 @@ DialogImageLoadProgress::~DialogImageLoadProgress()
 {
   if(m_data.get())
     g_free(m_data->data);
+
   if(m_loader)
   {
     try
diff --git a/glom/utility_widgets/dialog_image_load_progress.h b/glom/utility_widgets/dialog_image_load_progress.h
index 3c9f89d..3275e6b 100644
--- a/glom/utility_widgets/dialog_image_load_progress.h
+++ b/glom/utility_widgets/dialog_image_load_progress.h
@@ -61,7 +61,6 @@ private:
 
   Glib::RefPtr<Gio::File> m_file;
   Glib::RefPtr<Gio::FileInputStream> m_stream;
-  unsigned int m_stream_size;
 };
 
 } //namespace Glom
diff --git a/glom/utility_widgets/dialog_image_save_progress.cc b/glom/utility_widgets/dialog_image_save_progress.cc
new file mode 100644
index 0000000..3a5b868
--- /dev/null
+++ b/glom/utility_widgets/dialog_image_save_progress.cc
@@ -0,0 +1,82 @@
+/* Glom
+ *
+ * Copyright (C) 2001-2004 Murray Cumming
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify 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.
+ */
+
+#include "dialog_image_save_progress.h"
+
+#include <gtkmm/messagedialog.h>
+#include <iostream>
+#include <glibmm/i18n.h>
+
+namespace Glom
+{
+
+const char* DialogImageSaveProgress::glade_id("dialog_image_save_progress");
+const bool DialogImageSaveProgress::glade_developer(false);
+
+DialogImageSaveProgress::DialogImageSaveProgress(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& builder)
+: Gtk::Dialog(cobject)
+{
+  builder->get_widget("progress_bar", m_progress_bar);
+
+  if(!m_progress_bar)
+    throw std::runtime_error("Missing widgets from glade file for DialogImageSaveProgress");
+}
+
+DialogImageSaveProgress::~DialogImageSaveProgress()
+{
+}
+
+void DialogImageSaveProgress::save(const Glib::ustring& uri)
+{
+  //TODO: Support non-local URIs when we do this properly, using Gio::File.
+  const std::string filepath = Glib::filename_from_uri(uri);
+  m_progress_bar->set_text(Glib::ustring::compose("Saving %1...", 
+    Glib::filename_display_basename(filepath)));
+
+  try
+  {
+    // Open the file for reading:
+    m_pixbuf->save(filepath, GLOM_IMAGE_FORMAT);
+  }
+  catch(const Glib::Error& ex)
+  {
+    error(ex.what());
+  }
+  
+  //response(Gtk::RESPONSE_ACCEPT);
+}
+
+void DialogImageSaveProgress::error(const Glib::ustring& error_message)
+{
+  Gtk::MessageDialog dialog(*this, _("Error Saving"), Gtk::MESSAGE_ERROR);
+  dialog.set_title(_("Error saving image"));
+  dialog.set_secondary_text(error_message);
+
+  dialog.run();
+  response(Gtk::RESPONSE_REJECT);
+}
+
+
+void DialogImageSaveProgress::set_pixbuf(const Glib::RefPtr<Gdk::Pixbuf>& pixbuf)
+{
+  m_pixbuf = pixbuf;
+}
+
+} // namespace Glom
diff --git a/glom/utility_widgets/dialog_image_save_progress.h b/glom/utility_widgets/dialog_image_save_progress.h
new file mode 100644
index 0000000..a8f1ca0
--- /dev/null
+++ b/glom/utility_widgets/dialog_image_save_progress.h
@@ -0,0 +1,55 @@
+/* Glom
+ *
+ * Copyright (C) 2001-2004 Murray Cumming
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify 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.
+ */
+
+#ifndef GLOM_UTILITY_WIDGETS_DIALOG_IMAGE_SAVE_PROGRESS_H
+#define GLOM_UTILITY_WIDGETS_DIALOG_IMAGE_SAVE_PROGRESS_H
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/builder.h>
+#include <gtkmm/progressbar.h>
+#include <libglom/data_structure/layout/layoutitem_image.h> //For the file formats.
+//#include <memory>
+
+namespace Glom
+{
+
+class DialogImageSaveProgress : public Gtk::Dialog
+{
+public:
+  static const char* glade_id;
+  static const bool glade_developer;
+
+  DialogImageSaveProgress(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& builder);
+  virtual ~DialogImageSaveProgress();
+
+  void save(const Glib::ustring& uri);
+
+  void set_pixbuf(const Glib::RefPtr<Gdk::Pixbuf>& pixbuf);
+
+private:
+  void error(const Glib::ustring& error_message);
+
+  Glib::RefPtr<Gdk::Pixbuf> m_pixbuf;
+  Gtk::ProgressBar* m_progress_bar;
+};
+
+} //namespace Glom
+
+#endif // GLOM_UTILITY_WIDGETS_DIALOG_IMAGE_SAVE_PROGRESS_H
diff --git a/glom/utility_widgets/imageglom.cc b/glom/utility_widgets/imageglom.cc
index 6bfc48b..717eb4d 100644
--- a/glom/utility_widgets/imageglom.cc
+++ b/glom/utility_widgets/imageglom.cc
@@ -24,7 +24,8 @@
 #include <glom/utils_ui.h>
 #include <glom/glade_utils.h>
 #include <libglom/data_structure/glomconversions.h>
-//#include <sstream> //For stringstream
+#include <glom/utility_widgets/dialog_image_load_progress.h>
+#include <glom/utility_widgets/dialog_image_save_progress.h>
 
 #include <iostream>   // for cout, endl
 
@@ -310,19 +311,147 @@ void ImageGlom::scale()
   //  g_warning("ImageGlom::scale(): attempt to scale a null pixbuf.");
 }
 
-void ImageGlom::on_menupopup_activate_select_file()
+void ImageGlom::on_menupopup_activate_open_file()
 {
-  if(m_read_only)
+  open_with();
+}
+
+void ImageGlom::on_menupopup_activate_open_file_with()
+{
+  Application* pApp = get_application();
+
+  //Offer the user a choice of suitable applications:
+  Gtk::AppChooserDialog dialog(GLOM_IMAGE_FORMAT_MIME_TYPE);
+  if(pApp)
+    dialog.set_transient_for(*pApp);
+
+  if(dialog.run() != Gtk::RESPONSE_OK)
     return;
+  
+  Glib::RefPtr<Gio::AppInfo> app_info = dialog.get_app_info();
+  if(!app_info)
+  {
+    std::cerr << G_STRFUNC << ": app_info was null." << std::endl;
+  }
+  
+  open_with(app_info);
+}
 
-  //TODO: Use Hildon::FileChooser for Maemo.
-  Gtk::FileChooserDialog dialog(_("Choose Image"), Gtk::FILE_CHOOSER_ACTION_OPEN);
+void ImageGlom::open_with(const Glib::RefPtr<Gio::AppInfo>& app_info)
+{
+  //Get a temporary file path:
+  std::string filepath;
+  const int filehandle = Glib::file_open_tmp(filepath);
+  ::close(filehandle);
+  
+  if(filepath.empty())
+  {
+    std::cerr << G_STRFUNC << ": Glib::file_open_tmp() returned an empty filepath" << std::endl;
+    return;
+  }
+  
+  const Glib::ustring uri = Glib::filename_to_uri(filepath);
+  
+  if(!save_file(uri))
+    return;
+
+  if(app_info)
+  {
+    std::vector<std::string> vec_uris;
+    vec_uris.push_back(uri);
+    std::cout << "app_info: " << app_info->get_name() << ", uri=" << uri << std::endl;
+    app_info->launch_uris(vec_uris, 0); //TODO: Get a GdkAppLaunchContext?
+  }
+  else
+  {
+    //TODO: Avoid duplication in xsl_utils.cc, by moving this into a utility function:  
+#ifdef G_OS_WIN32
+    // gtk_show_uri doesn't seem to work on Win32, at least not for local files
+    // We use Windows API instead.
+    // TODO: Check it again and file a bug if necessary.
+    ShellExecute(0, "open", uri.c_str(), 0, 0, SW_SHOW);
+#else
+    //Use the GNOME browser:
+    GError* gerror = 0;
+    if(!gtk_show_uri(0 /* screen */, uri.c_str(), GDK_CURRENT_TIME, &gerror))
+    {
+      std::cerr << G_STRFUNC << ": " << gerror->message << std::endl;
+      g_error_free(gerror);
+    }
+#endif //G_OS_WIN32
+  }
+}
 
+
+static Glib::RefPtr<Gtk::FileFilter> get_file_filter_images()
+{
   //Get image formats only:
   Glib::RefPtr<Gtk::FileFilter> filter = Gtk::FileFilter::create();
   filter->set_name(_("Images"));
   filter->add_pixbuf_formats();
-  dialog.add_filter(filter);
+  
+  return filter;
+}
+
+void ImageGlom::on_menupopup_activate_save_file()
+{
+  Application* pApp = get_application();
+
+  Gtk::FileChooserDialog dialog(_("Save Image"), Gtk::FILE_CHOOSER_ACTION_SAVE);
+  if(pApp)
+    dialog.set_transient_for(*pApp);
+          
+  dialog.add_filter( get_file_filter_images() );
+
+  dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+  dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);
+  const int response = dialog.run();
+  dialog.hide();
+  if(response != Gtk::RESPONSE_OK)
+    return;
+    
+  const Glib::ustring uri = dialog.get_uri();
+  if(uri.empty())
+    return;
+    
+  save_file(uri);
+}
+
+bool ImageGlom::save_file(const Glib::ustring& uri)
+{
+  DialogImageSaveProgress* dialog_save = 0;
+  Utils::get_glade_widget_derived_with_warning(dialog_save);
+  if(!dialog_save)
+    return false;
+    
+  // Automatically delete the dialog when we no longer need it:
+  std::auto_ptr<Gtk::Dialog> dialog_keeper(dialog_save);
+
+  Application* pApp = get_application();
+  if(pApp)
+    dialog_save->set_transient_for(*pApp);
+
+  dialog_save->set_pixbuf(m_pixbuf_original);
+  dialog_save->save(uri);
+
+  //TODO: Use this when we do async saving:
+  //dialog_save->run();
+  return true;
+}
+
+void ImageGlom::on_menupopup_activate_select_file()
+{
+  if(m_read_only)
+    return;
+    
+  Application* pApp = get_application();
+
+  //TODO: Use Hildon::FileChooser for Maemo.
+  Gtk::FileChooserDialog dialog(_("Choose Image"), Gtk::FILE_CHOOSER_ACTION_OPEN);
+  if(pApp)
+    dialog.set_transient_for(*pApp);
+          
+  dialog.add_filter( get_file_filter_images() );
 
   dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
   dialog.add_button(_("Select"), Gtk::RESPONSE_OK);
@@ -341,7 +470,6 @@ void ImageGlom::on_menupopup_activate_select_file()
         // Automatically delete the dialog when we no longer need it:
         std::auto_ptr<Gtk::Dialog> dialog_keeper(dialog);
 
-        Application* pApp = get_application();
         if(pApp)
           dialog->set_transient_for(*pApp);
 
@@ -459,11 +587,24 @@ void ImageGlom::setup_menu_usermode()
   m_refActionGroup_UserModePopup = Gtk::ActionGroup::create();
 
   m_refActionGroup_UserModePopup->add(Gtk::Action::create("ContextMenu_UserMode", "Context Menu") );
+  
+  m_refActionOpenFile =  Gtk::Action::create("ContextOpenFile", Gtk::Stock::OPEN);
+  m_refActionOpenFileWith =  Gtk::Action::create("ContextOpenFileWith", Gtk::Stock::OPEN, _("Open With"));
+  m_refActionSaveFile =  Gtk::Action::create("ContextSaveFile", Gtk::Stock::SAVE);
   m_refActionSelectFile =  Gtk::Action::create("ContextSelectFile", Gtk::Stock::EDIT, _("Choose File"));
   m_refActionCopy = Gtk::Action::create("ContextCopy", Gtk::Stock::COPY);
   m_refActionPaste = Gtk::Action::create("ContextPaste", Gtk::Stock::PASTE);
   m_refActionClear = Gtk::Action::create("ContextClear", Gtk::Stock::CLEAR);
 
+  m_refActionGroup_UserModePopup->add(m_refActionOpenFile,
+    sigc::mem_fun(*this, &ImageGlom::on_menupopup_activate_open_file) );
+
+  m_refActionGroup_UserModePopup->add(m_refActionOpenFileWith,
+    sigc::mem_fun(*this, &ImageGlom::on_menupopup_activate_open_file_with) );
+    
+  m_refActionGroup_UserModePopup->add(m_refActionSaveFile,
+    sigc::mem_fun(*this, &ImageGlom::on_menupopup_activate_save_file) );
+    
   m_refActionGroup_UserModePopup->add(m_refActionSelectFile,
     sigc::mem_fun(*this, &ImageGlom::on_menupopup_activate_select_file) );
 
@@ -487,6 +628,9 @@ void ImageGlom::setup_menu_usermode()
     Glib::ustring ui_info = 
         "<ui>"
         "  <popup name='ContextMenu_UserMode'>"
+        "    <menuitem action='ContextOpenFile'/>"
+        "    <menuitem action='ContextOpenFileWith'/>"
+        "    <menuitem action='ContextSaveFile'/>"
         "    <menuitem action='ContextSelectFile'/>"
         "    <menuitem action='ContextCopy'/>"
         "    <menuitem action='ContextPaste'/>"
diff --git a/glom/utility_widgets/imageglom.h b/glom/utility_widgets/imageglom.h
index f6b6cb6..188044a 100644
--- a/glom/utility_widgets/imageglom.h
+++ b/glom/utility_widgets/imageglom.h
@@ -24,7 +24,6 @@
 #include <gtkmm.h>
 #include <libglom/data_structure/field.h>
 #include "layoutwidgetfield.h"
-#include "dialog_image_load_progress.h"
 #include <gtkmm/builder.h>
 
 namespace Glom
@@ -59,12 +58,13 @@ public:
 private:
   void init();
 
-  // Note that these are normal signal handlers when glibmm was compiled
-  // without default signal handler API.
   virtual bool on_draw(const Cairo::RefPtr<Cairo::Context>& cr);
 
   virtual bool on_button_press_event(GdkEventButton *event);
 
+  void on_menupopup_activate_open_file();
+  void on_menupopup_activate_open_file_with();
+  void on_menupopup_activate_save_file();
   void on_menupopup_activate_select_file();
   void on_menupopup_activate_copy();
   void on_menupopup_activate_paste();
@@ -78,7 +78,8 @@ private:
 
   void setup_menu_usermode();
   void scale();
-
+  bool save_file(const Glib::ustring& uri);
+  void open_with(const Glib::RefPtr<Gio::AppInfo>& app_info =  Glib::RefPtr<Gio::AppInfo>());
  
   Gtk::Image m_image;
   Gtk::Frame m_frame;
@@ -89,7 +90,8 @@ private:
   Gtk::Menu* m_pMenuPopup_UserMode;
   Glib::RefPtr<Gtk::ActionGroup> m_refActionGroup_UserModePopup;
   Glib::RefPtr<Gtk::UIManager> m_refUIManager_UserModePopup;
-  Glib::RefPtr<Gtk::Action> m_refActionSelectFile, m_refActionCopy, m_refActionPaste, m_refActionClear;
+  Glib::RefPtr<Gtk::Action> m_refActionOpenFile, m_refActionOpenFileWith, 
+    m_refActionSaveFile, m_refActionSelectFile, m_refActionCopy, m_refActionPaste, m_refActionClear;
 
   bool m_read_only;
 };
diff --git a/glom/xsl_utils.cc b/glom/xsl_utils.cc
index 4dec9d6..55cfc0a 100644
--- a/glom/xsl_utils.cc
+++ b/glom/xsl_utils.cc
@@ -72,7 +72,8 @@ void GlomXslUtils::transform_and_open(const xmlpp::Document& xml_document, const
   std::cout << "After xslt: " << result << std::endl;
 
   //Save it to a temporary file and show it in a browser:
-  const Glib::ustring temp_path = Glib::get_tmp_dir() + "/glom_printout.html";
+  const Glib::ustring temp_path = Glib::build_filename(
+    Glib::get_tmp_dir(), "glom_printout.html");
   //std::cout << "temp_path=" << temp_path << std::endl;
 
   Glib::RefPtr<Gio::File> file = Gio::File::create_for_path(temp_path);
diff --git a/po/ChangeLog b/po/ChangeLog
index b80a7b0..39acb66 100644
--- a/po/ChangeLog
+++ b/po/ChangeLog
@@ -1,3 +1,9 @@
+2011-07-11  Murray Cumming  <murrayc murrayc-desktop>
+
+	reviewed by: <delete if not using a buddy>
+
+	* POTFILES.in:
+
 2010-09-08  Murray Cumming  <murrayc murrayc-desktop>
 
 	reviewed by: <delete if not using a buddy>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 46ff304..1088936 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -121,6 +121,7 @@ glom/mode_data/datawidget/datawidget.cc
 glom/mode_data/db_adddel/db_adddel.cc
 glom/mode_data/datawidget/dialog_choose_id.cc
 glom/utility_widgets/dialog_image_load_progress.cc
+glom/utility_widgets/dialog_image_save_progress.cc
 glom/mode_data/datawidget/entry.cc
 glom/utility_widgets/eggspreadtable/eggspreadtable.c
 glom/utility_widgets/filechooserdialog_saveextras.cc
@@ -139,6 +140,7 @@ ui/operator/dialog_data_invalid_format.glade
 ui/operator/dialog_existing_or_new.glade
 ui/operator/dialog_find_id.glade
 ui/operator/dialog_image_load_progress.glade
+ui/operator/dialog_image_save_progress.glade
 ui/operator/dialog_import_csv.glade
 ui/operator/dialog_import_csv_progress.glade
 ui/operator/window_main.glade
diff --git a/tests/test_glade_derived_instantiation.cc b/tests/test_glade_derived_instantiation.cc
index f685336..1bbaeef 100644
--- a/tests/test_glade_derived_instantiation.cc
+++ b/tests/test_glade_derived_instantiation.cc
@@ -15,6 +15,7 @@
 #include <glom/mode_data/datawidget/dialog_choose_id.h>
 #include <glom/utility_widgets/dialog_flowtable.h>
 #include <glom/utility_widgets/dialog_image_load_progress.h>
+#include <glom/utility_widgets/dialog_image_save_progress.h>
 #include <glom/mode_design/layout/dialog_choose_field.h>
 #include <glom/mode_design/dialog_add_related_table.h>
 #include <glom/mode_design/layout/layout_item_dialogs/dialog_buttonscript.h>
@@ -88,6 +89,7 @@ int main(int argc, char *argv[])
   instantiate_widget<DataWidgetChildren::Dialog_ChooseDate>();
   instantiate_widget<Dialog_InvalidData>();
   instantiate_widget<DialogImageLoadProgress>();
+  instantiate_widget<DialogImageSaveProgress>();
   instantiate_widget<Dialog_ProgressCreating>();
 
   //Developer mode UI:
diff --git a/ui/operator/dialog_image_load_progress.glade b/ui/operator/dialog_image_load_progress.glade
index df75fbe..916f886 100644
--- a/ui/operator/dialog_image_load_progress.glade
+++ b/ui/operator/dialog_image_load_progress.glade
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <requires lib="gtk+" version="2.16"/>
-  <object class="GtkDialog" id="dialog_image_progress">
+  <object class="GtkDialog" id="dialog_image_load_progress">
     <property name="can_focus">False</property>
     <property name="border_width">6</property>
     <property name="title" translatable="yes">Loading image</property>
@@ -48,7 +48,7 @@
             <property name="can_focus">False</property>
             <property name="border_width">6</property>
             <child>
-              <object class="GtkProgressBar" id="image_loading_progress_bar">
+              <object class="GtkProgressBar" id="progress_bar">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
               </object>
diff --git a/ui/operator/dialog_image_save_progress.glade b/ui/operator/dialog_image_save_progress.glade
new file mode 100644
index 0000000..edf8ee0
--- /dev/null
+++ b/ui/operator/dialog_image_save_progress.glade
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-naming-policy toplevel-contextual -->
+  <object class="GtkDialog" id="dialog_image_save_progress">
+    <property name="can_focus">False</property>
+    <property name="border_width">6</property>
+    <property name="title" translatable="yes">Saving Image</property>
+    <property name="window_position">center-on-parent</property>
+    <property name="default_width">640</property>
+    <property name="type_hint">normal</property>
+    <child internal-child="vbox">
+      <object class="GtkVBox" id="dialog-vbox7">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="spacing">2</property>
+        <child internal-child="action_area">
+          <object class="GtkHButtonBox" id="dialog-action_area7">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="button2">
+                <property name="label">gtk-cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkAlignment" id="alignment1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="border_width">6</property>
+            <child>
+              <object class="GtkProgressBar" id="progress_bar">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="-6">button2</action-widget>
+    </action-widgets>
+  </object>
+</interface>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]