[niepce] importer: implement DirectoryImporterUI (part 2)



commit 597b2ddd44e04d909b887a279b687bc3139cd517
Author: Hubert Figuière <hub figuiere net>
Date:   Sat May 20 20:36:03 2017 -0400

    importer: implement DirectoryImporterUI (part 2)

 src/engine/importer/directoryimporter.cpp          |    5 +-
 src/engine/importer/directoryimporter.hpp          |    3 +-
 src/engine/importer/iimporter.hpp                  |    5 +-
 src/niepce/ui/Makefile.am                          |    1 +
 src/niepce/ui/dialogs/importdialog.cpp             |   66 +++++++------
 src/niepce/ui/dialogs/importdialog.hpp             |   13 ++-
 src/niepce/ui/dialogs/importdialog.ui              |   70 +------------
 .../ui/dialogs/importers/directoryimporterui.cpp   |  107 ++++++++++++++------
 .../ui/dialogs/importers/directoryimporterui.hpp   |   19 ++++-
 .../ui/dialogs/importers/directoryimporterui.ui    |   54 ++++++++++
 src/niepce/ui/dialogs/importers/iimporterui.hpp    |   13 ++-
 11 files changed, 216 insertions(+), 140 deletions(-)
---
diff --git a/src/engine/importer/directoryimporter.cpp b/src/engine/importer/directoryimporter.cpp
index d39e539..07178d8 100644
--- a/src/engine/importer/directoryimporter.cpp
+++ b/src/engine/importer/directoryimporter.cpp
@@ -54,9 +54,10 @@ DirectoryImporter::~DirectoryImporter()
 {
 }
 
-std::string DirectoryImporter::name() const
+const std::string& DirectoryImporter::id() const
 {
-  return _("Directory");
+  static std::string _id = "DirectoryImporter";
+  return _id;
 }
 
 bool DirectoryImporter::list_source_content(const std::string & source,
diff --git a/src/engine/importer/directoryimporter.hpp b/src/engine/importer/directoryimporter.hpp
index 65aefff..e9a17fa 100644
--- a/src/engine/importer/directoryimporter.hpp
+++ b/src/engine/importer/directoryimporter.hpp
@@ -35,8 +35,7 @@ public:
   DirectoryImporter();
   virtual ~DirectoryImporter();
 
-  std::string name() const override;
-
+  const std::string& id() const override;
   bool list_source_content(const std::string & source,
                            const SourceContentReady& callback) override;
   bool get_previews_for(const std::string& source,
diff --git a/src/engine/importer/iimporter.hpp b/src/engine/importer/iimporter.hpp
index 0ed963b..17772d7 100644
--- a/src/engine/importer/iimporter.hpp
+++ b/src/engine/importer/iimporter.hpp
@@ -36,9 +36,8 @@ class IImporter {
 public:
   virtual ~IImporter() {}
 
-
-  /** User visible importer name. */
-  virtual std::string name() const = 0;
+  /** Return the id string */
+  virtual const std::string& id() const = 0;
 
   /** Source content is ready */
   typedef std::function<void (std::list<ImportedFile::Ptr>&&)> SourceContentReady;
diff --git a/src/niepce/ui/Makefile.am b/src/niepce/ui/Makefile.am
index fd22a80..11e7b64 100644
--- a/src/niepce/ui/Makefile.am
+++ b/src/niepce/ui/Makefile.am
@@ -3,6 +3,7 @@
 gladefiles = dialogs/preferences.ui \
        dialogs/importdialog.ui \
        dialogs/editlabels.ui \
+       dialogs/importers/directoryimporterui.ui \
        $(NULL)
 
 gladedir = @datarootdir@/niepce/glade/
diff --git a/src/niepce/ui/dialogs/importdialog.cpp b/src/niepce/ui/dialogs/importdialog.cpp
index 1221180..4213bdc 100644
--- a/src/niepce/ui/dialogs/importdialog.cpp
+++ b/src/niepce/ui/dialogs/importdialog.cpp
@@ -23,10 +23,12 @@
 #include <gtkmm/button.h>
 #include <gtkmm/checkbutton.h>
 #include <gtkmm/combobox.h>
+#include <gtkmm/comboboxtext.h>
 #include <gtkmm/iconview.h>
 #include <gtkmm/label.h>
 #include <gtkmm/liststore.h>
 #include <gtkmm/builder.h>
+#include <gtkmm/stack.h>
 
 #include "fwk/base/debug.hpp"
 #include "fwk/utils/pathutils.hpp"
@@ -39,15 +41,16 @@
 namespace ui {
 
 ImportDialog::ImportDialog()
-    : fwk::Dialog(GLADEDIR"importdialog.ui", "importDialog")
-    , m_importer(nullptr)
-    , m_date_tz_combo(nullptr)
-    , m_ufraw_import_check(nullptr)
-    , m_rawstudio_import_check(nullptr)
-    , m_directory_name(nullptr)
-    , m_destination_folder(nullptr)
-    , m_attributes_scrolled(nullptr)
-    , m_images_list_scrolled(nullptr)
+  : fwk::Dialog(GLADEDIR"importdialog.ui", "importDialog")
+  , m_current_importer(nullptr)
+  , m_importer_ui_stack(nullptr)
+  , m_date_tz_combo(nullptr)
+  , m_ufraw_import_check(nullptr)
+  , m_rawstudio_import_check(nullptr)
+  , m_destination_folder(nullptr)
+  , m_import_source_combo(nullptr)
+  , m_attributes_scrolled(nullptr)
+  , m_images_list_scrolled(nullptr)
 {
 }
 
@@ -55,6 +58,17 @@ ImportDialog::~ImportDialog()
 {
 }
 
+void ImportDialog::add_importer_ui(IImporterUI& importer)
+{
+  m_import_source_combo->append(importer.id(), importer.name());
+  Gtk::Widget* importer_widget = importer.setup_widget(
+    std::static_pointer_cast<Frame>(shared_from_this()));
+  m_importer_ui_stack->add(*importer_widget, importer.name());
+  importer.set_source_selected_callback([this] (const std::string& source) {
+      this->set_to_import(source);
+    });
+}
+
 void ImportDialog::setup_widget()
 {
     if(m_is_setup) {
@@ -62,17 +76,25 @@ void ImportDialog::setup_widget()
     }
 
     Glib::RefPtr<Gtk::Builder> a_builder = builder();
-    Gtk::Button *select_directories = nullptr;
-
-    a_builder->get_widget("select_directories", select_directories);
-    select_directories->signal_clicked().connect(
-        sigc::mem_fun(*this, &ImportDialog::do_select_directories));
     a_builder->get_widget("date_tz_combo", m_date_tz_combo);
     a_builder->get_widget("ufraw_import_check", m_ufraw_import_check);
     a_builder->get_widget("rawstudio_import_check", m_rawstudio_import_check);
-    a_builder->get_widget("directory_name", m_directory_name);
     a_builder->get_widget("destinationFolder", m_destination_folder);
 
+    // Sources
+    a_builder->get_widget("importer_ui_stack", m_importer_ui_stack);
+    a_builder->get_widget("import_source_combo", m_import_source_combo);
+    m_import_source_combo->signal_changed().connect([] {});
+
+    // Directory source, hardcoded.
+    // XXX fix it
+    m_importers[0] = std::make_shared<DirectoryImporterUI>();
+    add_importer_ui(*m_importers[0]);
+
+    // XXX restore from preferences.
+    m_current_importer = m_importers[0];
+    m_import_source_combo->set_active_id(m_current_importer->id());
+
     // Metadata pane.
     a_builder->get_widget("attributes_scrolled", m_attributes_scrolled);
     m_metadata_pane = MetaDataPaneController::Ptr(new MetaDataPaneController);
@@ -102,19 +124,6 @@ void ImportDialog::setup_widget()
     m_is_setup = true;
 }
 
-// XXX doesn't belong here
-void ImportDialog::do_select_directories()
-{
-    if (!m_importer) {
-        // FIXME this should be the right kind
-        m_importer = std::make_shared<DirectoryImporterUI>();
-    }
-    auto source = m_importer->select_source(*this);
-    if (!source.empty()) {
-      set_to_import(source);
-    }
-}
-
 void ImportDialog::set_to_import(const std::string& f)
 {
     m_images_list_model->clear();
@@ -133,7 +142,6 @@ void ImportDialog::set_to_import(const std::string& f)
 
     m_folder_path_source = f;
     m_destination_folder->set_text(fwk::path_basename(f));
-    m_directory_name->set_text(f);
 }
 
 void ImportDialog::append_files_to_import()
diff --git a/src/niepce/ui/dialogs/importdialog.hpp b/src/niepce/ui/dialogs/importdialog.hpp
index e942961..33d821c 100644
--- a/src/niepce/ui/dialogs/importdialog.hpp
+++ b/src/niepce/ui/dialogs/importdialog.hpp
@@ -39,8 +39,10 @@
 namespace Gtk {
 class Dialog;
 class ComboBox;
+class ComboBoxText;
 class CheckButton;
 class TreeView;
+class Stack;
 }
 
 namespace fwk {
@@ -82,24 +84,27 @@ public:
         { return m_folder_path_source; }
     void set_to_import(const std::string& f);
     const std::shared_ptr<IImporterUI>& importer_ui() const
-        { return m_importer; }
+        { return m_current_importer; }
     std::shared_ptr<eng::IImporter> get_importer() const
-        { return m_importer->get_importer(); }
+        { return m_current_importer->get_importer(); }
 private:
     class ImportParam;
 
     void do_select_directories();
     void append_files_to_import();
     void preview_received();
+    void add_importer_ui(IImporterUI& importer);
 
-    std::shared_ptr<ui::IImporterUI> m_importer; // as shared_ptr<> for lambda capture
+    std::array<std::shared_ptr<ui::IImporterUI>, 1> m_importers;
+    std::shared_ptr<ui::IImporterUI> m_current_importer; // as shared_ptr<> for lambda capture
     Glib::ustring m_folder_path_source;
 
+    Gtk::Stack *m_importer_ui_stack;
     Gtk::ComboBox *m_date_tz_combo;
     Gtk::CheckButton *m_ufraw_import_check;
     Gtk::CheckButton *m_rawstudio_import_check;
-    Gtk::Label *m_directory_name;
     Gtk::Entry *m_destination_folder;
+    Gtk::ComboBoxText *m_import_source_combo;
     Gtk::ScrolledWindow *m_attributes_scrolled;
     Gtk::ScrolledWindow *m_images_list_scrolled;
     PreviewGridModel m_grid_columns;
diff --git a/src/niepce/ui/dialogs/importdialog.ui b/src/niepce/ui/dialogs/importdialog.ui
index d19bfb1..5dc59aa 100644
--- a/src/niepce/ui/dialogs/importdialog.ui
+++ b/src/niepce/ui/dialogs/importdialog.ui
@@ -2,24 +2,6 @@
 <!-- Generated with glade 3.20.0 -->
 <interface>
   <requires lib="gtk+" version="3.20"/>
-  <object class="GtkListStore" id="import_source_model">
-    <columns>
-      <!-- column-name label -->
-      <column type="gchararray"/>
-      <!-- column-name id -->
-      <column type="gint"/>
-    </columns>
-    <data>
-      <row>
-        <col id="0" translatable="yes">Directory</col>
-        <col id="1">0</col>
-      </row>
-      <row>
-        <col id="0" translatable="yes">Camera</col>
-        <col id="1">1</col>
-      </row>
-    </data>
-  </object>
   <object class="GtkListStore" id="preset_combo_model">
     <columns>
       <!-- column-name label -->
@@ -121,23 +103,16 @@
             <property name="can_focus">False</property>
             <property name="spacing">8</property>
             <child>
-              <object class="GtkBox" id="box2">
+              <object class="GtkBox" id="source_box">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
                 <property name="orientation">vertical</property>
                 <property name="spacing">8</property>
                 <child>
-                  <object class="GtkComboBox" id="import_source_combo">
+                  <object class="GtkComboBoxText" id="import_source_combo">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="model">import_source_model</property>
                     <property name="active">0</property>
-                    <child>
-                      <object class="GtkCellRendererText" id="cellrenderertext2"/>
-                      <attributes>
-                        <attribute name="text">0</attribute>
-                      </attributes>
-                    </child>
                   </object>
                   <packing>
                     <property name="expand">False</property>
@@ -146,48 +121,11 @@
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkBox" id="hbox1">
+                  <object class="GtkStack" id="importer_ui_stack">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="spacing">8</property>
                     <child>
-                      <object class="GtkLabel" id="label2">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">_Directory:</property>
-                        <property name="use_underline">True</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="directory_name">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | 
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                      </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkButton" id="select_directories">
-                        <property name="label" translatable="yes">...</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | 
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">2</property>
-                      </packing>
+                      <placeholder/>
                     </child>
                   </object>
                   <packing>
diff --git a/src/niepce/ui/dialogs/importers/directoryimporterui.cpp 
b/src/niepce/ui/dialogs/importers/directoryimporterui.cpp
index 5333785..13bd70d 100644
--- a/src/niepce/ui/dialogs/importers/directoryimporterui.cpp
+++ b/src/niepce/ui/dialogs/importers/directoryimporterui.cpp
@@ -19,6 +19,7 @@
 
 #include <glibmm/i18n.h>
 #include <gtkmm/filechooserdialog.h>
+#include <gtkmm/label.h>
 
 #include "fwk/toolkit/application.hpp"
 #include "fwk/toolkit/configuration.hpp"
@@ -27,44 +28,86 @@
 
 namespace ui {
 
-  DirectoryImporterUI::DirectoryImporterUI()
-    : m_importer(std::make_shared<eng::DirectoryImporter>())
-  {
-  }
+DirectoryImporterUI::DirectoryImporterUI()
+  : m_importer(std::make_shared<eng::DirectoryImporter>())
+  , m_name(_("Directory"))
+{
+}
 
-  std::shared_ptr<eng::IImporter> DirectoryImporterUI::get_importer()
-  {
-    return m_importer;
+std::shared_ptr<eng::IImporter> DirectoryImporterUI::get_importer()
+{
+  return m_importer;
+}
+
+const std::string& DirectoryImporterUI::name() const
+{
+  return m_name;
+}
+
+const std::string& DirectoryImporterUI::id() const
+{
+  return m_importer->id();
+}
+
+Gtk::Widget* DirectoryImporterUI::setup_widget(const fwk::Frame::Ptr& frame)
+{
+  m_frame = frame;
+  Gtk::Button* select_directories = nullptr;
+  m_builder = Gtk::Builder::create_from_file(GLADEDIR"directoryimporterui.ui",
+                                             "main_widget");
+  Gtk::Box* main_widget = nullptr;
+  m_builder->get_widget("main_widget", main_widget);
+  m_builder->get_widget("select_directories", select_directories);
+  select_directories->signal_clicked().connect(
+    sigc::mem_fun(*this, &DirectoryImporterUI::do_select_directories));
+  m_builder->get_widget("directory_name", m_directory_name);
+  return main_widget;
+}
+
+void DirectoryImporterUI::set_source_selected_callback(const SourceSelected& cb)
+{
+  m_source_selected_cb = cb;
+}
+
+void DirectoryImporterUI::do_select_directories()
+{
+  auto source = select_source();
+  if (!source.empty() && m_source_selected_cb) {
+    m_source_selected_cb(source);
   }
+}
+
+std::string DirectoryImporterUI::select_source()
+{
+  fwk::Configuration & cfg = fwk::Application::app()->config();
 
-  std::string DirectoryImporterUI::select_source(const fwk::Frame& frame)
+  Glib::ustring filename;
   {
-    fwk::Configuration & cfg = fwk::Application::app()->config();
+    auto frame = m_frame.lock();
+    Gtk::FileChooserDialog dialog(frame->gtkWindow(), _("Import picture folder"),
+                                  Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
 
-    Glib::ustring filename;
+    dialog.add_button(_("Cancel"), Gtk::RESPONSE_CANCEL);
+    dialog.add_button(_("Select"), Gtk::RESPONSE_OK);
+    dialog.set_select_multiple(false);
+
+    std::string last_import_location = cfg.getValue("last_import_location", "");
+    if (!last_import_location.empty()) {
+      dialog.set_filename(last_import_location);
+    }
+
+    int result = dialog.run();
+    switch(result)
     {
-      Gtk::FileChooserDialog dialog(frame.gtkWindow(), _("Import picture folder"),
-                                    Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
-
-      dialog.add_button(_("Cancel"), Gtk::RESPONSE_CANCEL);
-      dialog.add_button(_("Select"), Gtk::RESPONSE_OK);
-      dialog.set_select_multiple(false);
-
-      std::string last_import_location = cfg.getValue("last_import_location", "");
-      if (!last_import_location.empty()) {
-        dialog.set_filename(last_import_location);
-      }
-
-      int result = dialog.run();
-      switch(result)
-      {
-      case Gtk::RESPONSE_OK:
-        filename = dialog.get_filename();
-        break;
-      default:
-        break;
-      }
+    case Gtk::RESPONSE_OK:
+      filename = dialog.get_filename();
+      break;
+    default:
+      break;
     }
-    return filename.raw();
   }
+  m_directory_name->set_text(filename);
+  return filename.raw();
+}
+
 }
diff --git a/src/niepce/ui/dialogs/importers/directoryimporterui.hpp 
b/src/niepce/ui/dialogs/importers/directoryimporterui.hpp
index 54da34a..8b179be 100644
--- a/src/niepce/ui/dialogs/importers/directoryimporterui.hpp
+++ b/src/niepce/ui/dialogs/importers/directoryimporterui.hpp
@@ -21,6 +21,10 @@
 
 #include "iimporterui.hpp"
 
+namespace fwk {
+class Frame;
+}
+
 namespace ui {
 
 class DirectoryImporterUI
@@ -30,10 +34,23 @@ public:
   DirectoryImporterUI();
 
   std::shared_ptr<eng::IImporter> get_importer() override;
-  std::string select_source(const fwk::Frame&) override;
+
+  const std::string& name() const override;
+  const std::string& id() const override;
+  Gtk::Widget* setup_widget(const fwk::Frame::Ptr&) override;
+  void set_source_selected_callback(const SourceSelected&) override;
 
 private:
+  std::string select_source();
+  void do_select_directories();
+
   std::shared_ptr<eng::DirectoryImporter> m_importer;
+  std::string m_name;
+  SourceSelected m_source_selected_cb;
+
+  std::weak_ptr<fwk::Frame> m_frame;
+  Glib::RefPtr<Gtk::Builder> m_builder;
+  Gtk::Label *m_directory_name;
 };
 
 }
diff --git a/src/niepce/ui/dialogs/importers/directoryimporterui.ui 
b/src/niepce/ui/dialogs/importers/directoryimporterui.ui
new file mode 100644
index 0000000..1e5e177
--- /dev/null
+++ b/src/niepce/ui/dialogs/importers/directoryimporterui.ui
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <object class="GtkOffscreenWindow">
+    <property name="can_focus">False</property>
+    <child>
+      <object class="GtkBox" id="main_widget">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="spacing">8</property>
+        <child>
+          <object class="GtkLabel" id="label2">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">_Directory:</property>
+            <property name="use_underline">True</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="directory_name">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | 
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButton" id="select_directories">
+            <property name="label" translatable="yes">...</property>
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">False</property>
+            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | 
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/src/niepce/ui/dialogs/importers/iimporterui.hpp b/src/niepce/ui/dialogs/importers/iimporterui.hpp
index da203d1..fb4ab0f 100644
--- a/src/niepce/ui/dialogs/importers/iimporterui.hpp
+++ b/src/niepce/ui/dialogs/importers/iimporterui.hpp
@@ -6,6 +6,9 @@
 
 #include "engine/importer/iimporter.hpp"
 
+namespace Gtk {
+class Widget;
+}
 namespace fwk {
 class Frame;
 }
@@ -15,9 +18,17 @@ namespace ui {
 class IImporterUI {
 public:
 
+  virtual ~IImporterUI() {}
+
   virtual std::shared_ptr<eng::IImporter> get_importer() = 0;
-  virtual std::string select_source(const fwk::Frame&) = 0;
 
+  /** User visible importer name. */
+  virtual const std::string& name() const = 0;
+  virtual const std::string& id() const = 0;
+  virtual Gtk::Widget* setup_widget(const fwk::Frame::Ptr&) = 0;
+
+  typedef std::function<void (const std::string&)> SourceSelected;
+  virtual void set_source_selected_callback(const SourceSelected&) = 0;
 };
 
 }


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