[niepce] importer: API to propose a dest dir.



commit a7a19abfc23ee5b7263096eb39ada1d325e07b88
Author: Hubert Figuière <hub figuiere net>
Date:   Fri Jun 2 23:06:39 2017 -0400

    importer: API to propose a dest dir.

 src/engine/importer/cameraimporter.cpp             |   17 +++++--
 src/engine/importer/cameraimporter.hpp             |    2 +-
 src/engine/importer/directoryimporter.cpp          |    2 +-
 src/engine/importer/directoryimporter.hpp          |    2 +-
 src/engine/importer/iimporter.hpp                  |    8 +++-
 src/niepce/ui/dialogs/importdialog.cpp             |   48 +++++++++++++++-----
 src/niepce/ui/dialogs/importdialog.hpp             |   12 +++--
 .../ui/dialogs/importers/cameraimporterui.cpp      |    7 +++-
 .../ui/dialogs/importers/directoryimporterui.cpp   |    3 +-
 src/niepce/ui/dialogs/importers/iimporterui.hpp    |    6 ++-
 src/niepce/ui/niepcewindow.cpp                     |    7 ++-
 11 files changed, 85 insertions(+), 29 deletions(-)
---
diff --git a/src/engine/importer/cameraimporter.cpp b/src/engine/importer/cameraimporter.cpp
index 077f767..5e81054 100644
--- a/src/engine/importer/cameraimporter.cpp
+++ b/src/engine/importer/cameraimporter.cpp
@@ -101,12 +101,20 @@ bool CameraImporter::get_previews_for(const std::string& source,
     return false;
 }
 
-bool CameraImporter::do_import(const std::string & source,
+bool CameraImporter::do_import(const std::string& source, const std::string& dest_dir,
                                const FileImporter & importer)
 {
     // XXX we shouldn't have to do that.
-    list_source_content(source, [this, importer] (auto file_list) {
-            auto tmp_dir_path = fwk::make_tmp_dir("niepce-camera-import-XXXXXX");
+    list_source_content(source, [this, dest_dir, importer] (auto file_list) {
+            auto tmp_dir_path = dest_dir.empty() ?
+                fwk::make_tmp_dir("niepce-camera-import-XXXXXX") :
+                dest_dir;
+            if (!dest_dir.empty()) {
+                auto dir = Gio::File::create_for_path(tmp_dir_path);
+                dir->make_directory_with_parents();
+                // XXX check for errors.
+            }
+            DBG_ASSERT(!tmp_dir_path.empty(), "Dest dir is empty");
             // XXX check we don't return an empty string.
 
             for (auto file: file_list) {
@@ -122,7 +130,8 @@ bool CameraImporter::do_import(const std::string & source,
                 if (this->m_camera->download_file(imported_camera_file->folder(),
                                                   imported_camera_file->name(),
                                                   output_path)) {
-                    importer(output_path, IImporter::Import::SINGLE, Library::Managed::YES);
+                    // XXX else report error.
+                    importer(output_path, IImporter::Import::SINGLE, Library::Managed::NO);
                 }
             }
             return true;
diff --git a/src/engine/importer/cameraimporter.hpp b/src/engine/importer/cameraimporter.hpp
index d0d9bf8..99e9146 100644
--- a/src/engine/importer/cameraimporter.hpp
+++ b/src/engine/importer/cameraimporter.hpp
@@ -42,7 +42,7 @@ public:
                           const std::list<std::string>& paths,
                           const PreviewReady& callback) override;
 
-    bool do_import(const std::string & source,
+    bool do_import(const std::string& source, const std::string& dest_dir,
                    const FileImporter & importer) override;
 private:
     bool ensure_camera_open(const std::string&);
diff --git a/src/engine/importer/directoryimporter.cpp b/src/engine/importer/directoryimporter.cpp
index 300379f..a232b05 100644
--- a/src/engine/importer/directoryimporter.cpp
+++ b/src/engine/importer/directoryimporter.cpp
@@ -90,7 +90,7 @@ bool DirectoryImporter::get_previews_for(const std::string& /*source*/,
     return true;
 }
 
-bool DirectoryImporter::do_import(const std::string& source,
+bool DirectoryImporter::do_import(const std::string& source, const std::string& /*dest_dir*/,
                                   const FileImporter& callback)
 {
     // pretty trivial, we have the source path.
diff --git a/src/engine/importer/directoryimporter.hpp b/src/engine/importer/directoryimporter.hpp
index c691b57..c0a59bb 100644
--- a/src/engine/importer/directoryimporter.hpp
+++ b/src/engine/importer/directoryimporter.hpp
@@ -41,7 +41,7 @@ public:
                           const std::list<std::string>& paths,
                           const PreviewReady& callback) override;
 
-    bool do_import(const std::string & source,
+    bool do_import(const std::string& source, const std::string& dest_dir,
                    const FileImporter & importer) override;
 
 };
diff --git a/src/engine/importer/iimporter.hpp b/src/engine/importer/iimporter.hpp
index 04a2643..841b63a 100644
--- a/src/engine/importer/iimporter.hpp
+++ b/src/engine/importer/iimporter.hpp
@@ -58,8 +58,12 @@ public:
     };
     /** file importer callback */
     typedef std::function<void (const std::string&, Import, Library::Managed)> FileImporter;
-    /** perform import from source */
-    virtual bool do_import(const std::string& source,
+    /** perform import from source
+     * @param source the source identified by a string.
+     * @param dest_dir the suggested destination directory is the importer needs to copy
+     * @param importer the callback to import. Copy shall occur first if needed.
+     */
+    virtual bool do_import(const std::string& source, const std::string& dest_dir,
                            const FileImporter& importer) = 0;
 
 };
diff --git a/src/niepce/ui/dialogs/importdialog.cpp b/src/niepce/ui/dialogs/importdialog.cpp
index f3b2c33..43a4e77 100644
--- a/src/niepce/ui/dialogs/importdialog.cpp
+++ b/src/niepce/ui/dialogs/importdialog.cpp
@@ -18,6 +18,7 @@
  */
 
 
+#include <glibmm/miscutils.h>
 #include <gtkmm/button.h>
 #include <gtkmm/checkbutton.h>
 #include <gtkmm/combobox.h>
@@ -53,6 +54,11 @@ ImportDialog::ImportDialog()
   , m_attributes_scrolled(nullptr)
   , m_images_list_scrolled(nullptr)
 {
+    fwk::Configuration & cfg = fwk::Application::app()->config();
+    m_base_dest_dir = cfg.getValue("base_import_dest_dir",
+                                   Glib::get_user_special_dir(
+                                       Glib::USER_DIRECTORY_PICTURES));
+    DBG_OUT("base_dest_dir set to %s", m_base_dest_dir.c_str());
 }
 
 ImportDialog::~ImportDialog()
@@ -66,8 +72,9 @@ void ImportDialog::add_importer_ui(IImporterUI& importer)
         std::static_pointer_cast<Frame>(shared_from_this()));
     importer_widget->show_all();
     m_importer_ui_stack->add(*importer_widget, importer.id());
-    importer.set_source_selected_callback([this] (const std::string& source) {
-            this->set_to_import(source);
+    importer.set_source_selected_callback(
+        [this] (const std::string& source, const std::string& dest_dir) {
+            this->set_source(source, dest_dir);
         });
 }
 
@@ -130,34 +137,53 @@ void ImportDialog::setup_widget()
     m_is_setup = true;
 }
 
+void ImportDialog::clear_import_list()
+{
+    if (m_images_list_model) {
+        m_images_list_model->clear();
+    }
+    m_images_list_map.clear();
+    m_files_to_import.clear();
+    if (m_destination_folder) {
+        m_destination_folder->set_text("");
+    }
+}
+
 void ImportDialog::import_source_changed()
 {
     auto id = m_import_source_combo->get_active_id();
     m_current_importer = m_importers[id];
     m_importer_ui_stack->set_visible_child(id);
+    m_source = "";
+
+    clear_import_list();
 
     fwk::Configuration & cfg = fwk::Application::app()->config();
     cfg.setValue("last_importer", id);
 }
 
-void ImportDialog::set_to_import(const std::string& f)
+void ImportDialog::set_source(const std::string& source, const std::string& dest_dir)
 {
-    m_images_list_model->clear();
-    m_images_list_map.clear();
-    m_files_to_import.clear();
+    clear_import_list();
 
     auto importer = get_importer();
     m_files_to_import.run(
-        [this, f, importer] () {
+        [this, source, importer] () {
             return importer->list_source_content(
-                f,
+                source,
                 [this] (std::list<eng::ImportedFilePtr>&& list_to_import) {
                     this->m_files_to_import.send_data(std::move(list_to_import));
                 });
         });
 
-    m_folder_path_source = f;
-    m_destination_folder->set_text(fwk::path_basename(f));
+    m_source = source;
+    m_dest_dir = Glib::build_filename(m_base_dest_dir, dest_dir);
+    m_destination_folder->set_text(dest_dir);
+}
+
+const std::string& ImportDialog::get_dest_dir() const
+{
+    return m_dest_dir;
 }
 
 void ImportDialog::append_files_to_import()
@@ -180,7 +206,7 @@ void ImportDialog::append_files_to_import()
     }
 
     auto importer = get_importer();
-    auto source = m_folder_path_source.raw();
+    auto source = m_source;
     m_previews_to_import.run(
         [this, importer, source, paths] () {
             return importer->get_previews_for(
diff --git a/src/niepce/ui/dialogs/importdialog.hpp b/src/niepce/ui/dialogs/importdialog.hpp
index c2ef72d..7452ed5 100644
--- a/src/niepce/ui/dialogs/importdialog.hpp
+++ b/src/niepce/ui/dialogs/importdialog.hpp
@@ -80,17 +80,19 @@ public:
 
 //  const std::list<std::string> & to_import() const
 //      { return m_list_to_import; }
-    const Glib::ustring & source_path() const
-        { return m_folder_path_source; }
+    const std::string& get_source() const
+        { return m_source; }
     void import_source_changed();
-    void set_to_import(const std::string& f);
+    void set_source(const std::string&, const std::string&);
     const std::shared_ptr<IImporterUI>& importer_ui() const
         { return m_current_importer; }
     std::shared_ptr<eng::IImporter> get_importer() const
         { return m_current_importer->get_importer(); }
+    const std::string& get_dest_dir() const;
 private:
     class ImportParam;
 
+    void clear_import_list();
     void do_select_directories();
     void append_files_to_import();
     void preview_received();
@@ -98,7 +100,9 @@ private:
 
     std::map<std::string, std::shared_ptr<ui::IImporterUI>> m_importers;
     std::shared_ptr<ui::IImporterUI> m_current_importer; // as shared_ptr<> for lambda capture
-    Glib::ustring m_folder_path_source;
+    std::string m_source; /// Abstract source. The importer knows what to do.
+    std::string m_base_dest_dir;
+    std::string m_dest_dir;
 
     Gtk::Stack *m_importer_ui_stack;
     Gtk::ComboBox *m_date_tz_combo;
diff --git a/src/niepce/ui/dialogs/importers/cameraimporterui.cpp 
b/src/niepce/ui/dialogs/importers/cameraimporterui.cpp
index 75c1f54..76e653e 100644
--- a/src/niepce/ui/dialogs/importers/cameraimporterui.cpp
+++ b/src/niepce/ui/dialogs/importers/cameraimporterui.cpp
@@ -18,6 +18,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <boost/format.hpp>
+
 #include <glibmm/i18n.h>
 #include <gtkmm/label.h>
 #include <gtkmm/grid.h>
@@ -73,7 +75,10 @@ void CameraImporterUI::select_camera()
 {
     std::string source = m_camera_list_combo->get_active_id();
     if (!source.empty() && m_source_selected_cb) {
-        m_source_selected_cb(source);
+        auto datetime = Glib::DateTime::create_now_local();
+        std::string today = datetime.format("%F %H%M%S").raw();
+        std::string dest_dir = str(boost::format(_("Camera import %1%")) % today);
+        m_source_selected_cb(source, dest_dir);
     }
 }
 
diff --git a/src/niepce/ui/dialogs/importers/directoryimporterui.cpp 
b/src/niepce/ui/dialogs/importers/directoryimporterui.cpp
index da1efc2..b7b64f3 100644
--- a/src/niepce/ui/dialogs/importers/directoryimporterui.cpp
+++ b/src/niepce/ui/dialogs/importers/directoryimporterui.cpp
@@ -22,6 +22,7 @@
 #include <gtkmm/filechooserdialog.h>
 #include <gtkmm/label.h>
 
+#include "fwk/utils/pathutils.hpp"
 #include "fwk/toolkit/application.hpp"
 #include "fwk/toolkit/configuration.hpp"
 #include "engine/importer/directoryimporter.hpp"
@@ -54,7 +55,7 @@ void DirectoryImporterUI::do_select_directories()
 {
     auto source = select_source();
     if (!source.empty() && m_source_selected_cb) {
-        m_source_selected_cb(source);
+        m_source_selected_cb(source, fwk::path_basename(source));
     }
 }
 
diff --git a/src/niepce/ui/dialogs/importers/iimporterui.hpp b/src/niepce/ui/dialogs/importers/iimporterui.hpp
index 66b3880..43ba21d 100644
--- a/src/niepce/ui/dialogs/importers/iimporterui.hpp
+++ b/src/niepce/ui/dialogs/importers/iimporterui.hpp
@@ -48,7 +48,11 @@ public:
     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;
+    /** Source selected callback
+     * @param source identifier
+     * @param dest dir suggestion
+     */
+    typedef std::function<void (const std::string&, const std::string&)> SourceSelected;
     virtual void set_source_selected_callback(const SourceSelected&) = 0;
 };
 
diff --git a/src/niepce/ui/niepcewindow.cpp b/src/niepce/ui/niepcewindow.cpp
index 2325b1b..9802318 100644
--- a/src/niepce/ui/niepcewindow.cpp
+++ b/src/niepce/ui/niepcewindow.cpp
@@ -261,17 +261,20 @@ void NiepceWindow::on_action_file_import()
     {
         // import
         // XXX change the API to provide more details.
-        Glib::ustring source = import_dialog->source_path();
+        std::string source = import_dialog->get_source();
         if(source.empty()) {
             return;
         }
+        // XXX this should be a different config key
+        // specific to the importer.
         cfg.setValue("last_import_location", source);
 
         auto importer = import_dialog->get_importer();
         DBG_ASSERT(!!importer, "Import can't be null if we clicked import");
         if (importer) {
+            auto dest_dir = import_dialog->get_dest_dir();
             importer->do_import(
-                source,
+                source, dest_dir,
                 [this] (const std::string & path, IImporter::Import type, Library::Managed manage) {
                     if (type == IImporter::Import::SINGLE) {
                         m_libClient->importFile(path, manage);


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