[niepce] importer: show the picture thumbnails.
- From: Hubert Figuière <hub src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [niepce] importer: show the picture thumbnails.
- Date: Tue, 16 May 2017 04:48:54 +0000 (UTC)
commit 8e6ec3e3810c414ad4e31099e1021478222ec1c2
Author: Hubert Figuière <hub figuiere net>
Date: Mon May 15 21:23:25 2017 -0400
importer: show the picture thumbnails.
- move thumbnailing to fwk
- Thumbnail class
src/engine/Makefile.am | 1 -
src/engine/importer/directoryimporter.cpp | 13 +++
src/engine/importer/directoryimporter.hpp | 7 ++-
src/engine/importer/iimporter.hpp | 10 +++
src/engine/library/thumbnailcache.cpp | 83 ++++-----------------
src/engine/library/thumbnailnotification.hpp | 21 +++---
src/fwk/toolkit/Makefile.am | 3 +
src/fwk/toolkit/thumbnail.cpp | 93 +++++++++++++++++++++++
src/fwk/toolkit/thumbnail.hpp | 58 +++++++++++++++
src/fwk/toolkit/uiresult.hpp | 102 ++++++++++++++++++++++++++
src/niepce/ui/dialogs/importdialog.cpp | 74 +++++++++++++++----
src/niepce/ui/dialogs/importdialog.hpp | 9 ++-
src/niepce/ui/imageliststore.cpp | 5 +-
13 files changed, 378 insertions(+), 101 deletions(-)
---
diff --git a/src/engine/Makefile.am b/src/engine/Makefile.am
index c980ffc..96e891f 100644
--- a/src/engine/Makefile.am
+++ b/src/engine/Makefile.am
@@ -1,7 +1,6 @@
AM_CPPFLAGS = -I$(top_srcdir)/src/ @FRAMEWORK_CFLAGS@ \
- @OPENRAW_CFLAGS@ \
$(NULL)
TESTS = test_library test_filebundle test_opqueue
diff --git a/src/engine/importer/directoryimporter.cpp b/src/engine/importer/directoryimporter.cpp
index 6bb5aaa..2807786 100644
--- a/src/engine/importer/directoryimporter.cpp
+++ b/src/engine/importer/directoryimporter.cpp
@@ -18,6 +18,7 @@
*/
#include <glibmm/i18n.h>
+#include <glibmm/miscutils.h>
#include "fwk/base/debug.hpp"
#include "fwk/utils/pathutils.hpp"
@@ -75,6 +76,18 @@ bool DirectoryImporter::listSourceContent(const std::string & source,
return true;
}
+bool DirectoryImporter::get_previews_for(const std::string& source,
+ const std::list<std::string>& paths,
+ const PreviewReady& callback)
+{
+ for (auto path : paths) {
+ auto full_path = Glib::build_filename(source, path);
+ auto thumbnail = fwk::Thumbnail::thumbnail_file(full_path, 160, 160, 0);
+ callback(path, thumbnail);
+ }
+ return true;
+}
+
bool DirectoryImporter::doImport(const std::string& source,
const FileImporter& callback)
{
diff --git a/src/engine/importer/directoryimporter.hpp b/src/engine/importer/directoryimporter.hpp
index b778868..a20348c 100644
--- a/src/engine/importer/directoryimporter.hpp
+++ b/src/engine/importer/directoryimporter.hpp
@@ -20,7 +20,8 @@
#pragma once
-#include <mutex>
+#include <string>
+#include <list>
#include "fwk/utils/files.hpp"
#include "engine/importer/iimporter.hpp"
@@ -38,9 +39,13 @@ public:
bool listSourceContent(const std::string & source,
const SourceContentReady& callback) override;
+ bool get_previews_for(const std::string & source,
+ const std::list<std::string>& paths,
+ const PreviewReady& callback) override;
bool doImport(const std::string & source,
const FileImporter & importer) override;
+
};
}
diff --git a/src/engine/importer/iimporter.hpp b/src/engine/importer/iimporter.hpp
index e5f16ff..03746a6 100644
--- a/src/engine/importer/iimporter.hpp
+++ b/src/engine/importer/iimporter.hpp
@@ -20,6 +20,11 @@
#pragma once
+#include <string>
+#include <list>
+#include <functional>
+
+#include "fwk/toolkit/thumbnail.hpp"
#include "engine/importer/importedfile.hpp"
namespace eng {
@@ -41,6 +46,11 @@ public:
virtual bool listSourceContent(const std::string & source,
const SourceContentReady& callback) = 0;
+ typedef std::function<void (const std::string& path,
+ const fwk::Thumbnail&)> PreviewReady;
+ virtual bool get_previews_for(const std::string& source,
+ const std::list<std::string>& paths,
+ const PreviewReady& callback) = 0;
/** file importer callback */
typedef std::function<void (const std::string&, bool)> FileImporter;
diff --git a/src/engine/library/thumbnailcache.cpp b/src/engine/library/thumbnailcache.cpp
index 2da56e9..ecff92a 100644
--- a/src/engine/library/thumbnailcache.cpp
+++ b/src/engine/library/thumbnailcache.cpp
@@ -22,16 +22,12 @@
#include <boost/any.hpp>
#include <boost/format.hpp>
-#include <gdkmm/pixbuf.h>
#include <glibmm/miscutils.h>
-#include <libopenraw-gnome/gdkpixbuf.h>
#include "niepce/notifications.hpp"
#include "fwk/base/debug.hpp"
#include "fwk/utils/pathutils.hpp"
-#include "fwk/toolkit/mimetype.hpp"
-#include "fwk/toolkit/gdkutils.hpp"
-#include "fwk/toolkit/movieutils.hpp"
+#include "fwk/toolkit/thumbnail.hpp"
#include "thumbnailcache.hpp"
#include "thumbnailnotification.hpp"
@@ -60,72 +56,28 @@ void ThumbnailCache::request(const LibFile::ListPtr & fl)
namespace {
-// TODO see about 1. moving this out 2. abstracting the type away from Gdk::Pixbuf
-// Gdk does not belong to eng.
-Glib::RefPtr<Gdk::Pixbuf> getThumbnail(const LibFile::Ptr & f, int w, int h, const std::string & cached)
+fwk::Thumbnail getThumbnail(const LibFile::Ptr & f, int w, int h, const std::string & cached)
{
+ const std::string & filename = f->path();
+
if(ThumbnailCache::is_thumbnail_cached(f->path(), cached)) {
- DBG_OUT("cached!");
+ DBG_OUT("thumbnail for %s is cached!", filename.c_str());
return Gdk::Pixbuf::create_from_file(cached);
}
- const std::string & filename = f->path();
- DBG_OUT("creating thumbnail for %s",filename.c_str());
- fwk::MimeType mime_type(filename);
+ DBG_OUT("creating thumbnail for %s", filename.c_str());
+
if(!fwk::ensure_path_for_file(cached)) {
ERR_OUT("coudln't create directories for %s", cached.c_str());
}
- DBG_OUT("MIME type %s", mime_type.string().c_str());
-
- Glib::RefPtr<Gdk::Pixbuf> pix;
-
- if(mime_type.isUnknown()) {
- DBG_OUT("unknown file type %s", filename.c_str());
- }
- else if(mime_type.isMovie()) {
- try {
- if(fwk::thumbnail_movie(filename, w, h, cached)) {
- pix = Gdk::Pixbuf::create_from_file(cached, w, h, true);
- }
- }
- catch(const Glib::Error & e) {
- ERR_OUT("exception thumbnailing video %s", e.what().c_str());
- }
- }
- else if(!mime_type.isImage()) {
- DBG_OUT("not an image type");
- }
- else if(!mime_type.isDigicamRaw()) {
- DBG_OUT("not a raw type, trying GdkPixbuf loaders");
- try {
- pix = Gdk::Pixbuf::create_from_file(filename, w, h, true);
- if(pix) {
- pix = fwk::gdkpixbuf_exif_rotate(pix, f->orientation());
- }
- }
- catch(const Glib::Error & e) {
- ERR_OUT("exception thumbnailing image %s", e.what().c_str());
- }
- }
- else {
- GdkPixbuf *pixbuf = or_gdkpixbuf_extract_rotated_thumbnail(filename.c_str(),
- std::min(w, h));
- if(pixbuf) {
- pix = Glib::wrap(pixbuf, true); // take ownership
- if((w < pix->get_width()) || (h < pix->get_height())) {
- pix = fwk::gdkpixbuf_scale_to_fit(pix, std::min(w,h));
- }
- }
- }
- if(pix)
- {
- pix->save(cached, "png");
- }
- else {
+ auto thumbnail = fwk::Thumbnail::thumbnail_file(filename, w, h, f->orientation());
+ if (thumbnail.ok()) {
+ thumbnail.save(cached, "png");
+ } else {
DBG_OUT("couldn't get the thumbnail for %s", filename.c_str());
}
- return pix;
+ return thumbnail;
}
}
@@ -136,22 +88,19 @@ void ThumbnailCache::execute(const ptr_t & task)
w = task->width();
h = task->height();
- Glib::RefPtr<Gdk::Pixbuf> pix;
-
std::string dest = path_for_thumbnail(task->file()->path(), task->file()->id(), std::max(w,h));
DBG_OUT("cached thumbnail %s", dest.c_str());
- pix = getThumbnail(task->file(), w, h, dest);
-
- if(pix) {
+ fwk::Thumbnail pix = getThumbnail(task->file(), w, h, dest);
+ if(pix.ok()) {
fwk::NotificationCenter::Ptr nc(m_notif_center);
if(nc) {
// pass the notification
fwk::Notification::Ptr n(new fwk::Notification(niepce::NOTIFICATION_THUMBNAIL));
ThumbnailNotification tn;
tn.id = task->file()->id();
- tn.width = pix->get_width();
- tn.height = pix->get_height();
+ tn.width = pix.get_width();
+ tn.height = pix.get_height();
tn.pixmap = pix;
n->setData(boost::any(tn));
DBG_OUT("notify thumbnail for id=%Ld", (long long)tn.id);
diff --git a/src/engine/library/thumbnailnotification.hpp b/src/engine/library/thumbnailnotification.hpp
index 7a4807e..8de0391 100644
--- a/src/engine/library/thumbnailnotification.hpp
+++ b/src/engine/library/thumbnailnotification.hpp
@@ -1,7 +1,7 @@
/*
- * niepce - library/thumbnailnotification.h
+ * niepce - engine/library/thumbnailnotification.hpp
*
- * Copyright (C) 2007 Hubert Figuiere
+ * Copyright (C) 2007-2017 Hubert Figuiere
*
* 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
@@ -21,19 +21,18 @@
#ifndef _LIBRARY_THUMBNAILNOTIFICATION_H__
#define _LIBRARY_THUMBNAILNOTIFICATION_H__
-#include <gdkmm/pixbuf.h>
-
+#include "fwk/toolkit/thumbnail.hpp"
#include "engine/db/librarytypes.hpp"
namespace eng {
- struct ThumbnailNotification
- {
- eng::library_id_t id;
- int width;
- int height;
- Glib::RefPtr<Gdk::Pixbuf> pixmap;
- };
+struct ThumbnailNotification
+{
+ eng::library_id_t id;
+ int width;
+ int height;
+ fwk::Thumbnail pixmap;
+};
}
diff --git a/src/fwk/toolkit/Makefile.am b/src/fwk/toolkit/Makefile.am
index fc3ac6e..f153d95 100644
--- a/src/fwk/toolkit/Makefile.am
+++ b/src/fwk/toolkit/Makefile.am
@@ -5,6 +5,7 @@
AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/ext \
-DDATADIR=\"$(datadir)\" \
@FRAMEWORK_CFLAGS@ \
+ @OPENRAW_CFLAGS@ \
$(NULL)
noinst_LIBRARIES = libniepceframework.a
@@ -29,6 +30,8 @@ libniepceframework_a_SOURCES = configuration.hpp configuration.cpp \
frame.hpp frame.cpp \
controller.hpp controller.cpp \
uicontroller.hpp uicontroller.cpp \
+ uiresult.hpp \
+ thumbnail.hpp thumbnail.cpp \
mapcontroller.hpp mapcontroller.cpp \
notification.hpp \
mimetype.hpp mimetype.cpp \
diff --git a/src/fwk/toolkit/thumbnail.cpp b/src/fwk/toolkit/thumbnail.cpp
new file mode 100644
index 0000000..019e2f3
--- /dev/null
+++ b/src/fwk/toolkit/thumbnail.cpp
@@ -0,0 +1,93 @@
+/* -*- mode: C++; tab-width: 2; c-basic-offset: 2; indent-tabs-mode:nil; -*- */
+/*
+ * niepce - fwk/toolkit/thumbnail.cpp
+ *
+ * Copyright (C) 2017 Hubert Figuière
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "thumbnail.hpp"
+
+#include <glibmm/miscutils.h>
+#include <libopenraw-gnome/gdkpixbuf.h>
+
+#include "fwk/base/debug.hpp"
+#include "fwk/toolkit/mimetype.hpp"
+#include "fwk/toolkit/gdkutils.hpp"
+#include "fwk/toolkit/movieutils.hpp"
+
+namespace fwk {
+
+Thumbnail::Thumbnail(const Glib::RefPtr<Gdk::Pixbuf>& pixbuf)
+ : m_pixbuf(pixbuf)
+{
+}
+
+void Thumbnail::save(const std::string& path, const std::string& format)
+{
+ if (m_pixbuf) {
+ m_pixbuf->save(path, format);
+ }
+}
+
+Thumbnail Thumbnail::thumbnail_file(const std::string& filename,
+ int w, int h, int32_t orientation)
+{
+ fwk::MimeType mime_type(filename);
+ DBG_OUT("MIME type %s", mime_type.string().c_str());
+
+ Glib::RefPtr<Gdk::Pixbuf> pix;
+
+ if(mime_type.isUnknown()) {
+ DBG_OUT("unknown file type %s", filename.c_str());
+ } else if(mime_type.isMovie()) {
+ try {
+ // XXX FIXME
+ std::string cached = Glib::get_tmp_dir() + "/temp-1234";
+ if(fwk::thumbnail_movie(filename, w, h, cached)) {
+ pix = Gdk::Pixbuf::create_from_file(cached, w, h, true);
+ }
+ }
+ catch(const Glib::Error & e) {
+ ERR_OUT("exception thumbnailing video %s", e.what().c_str());
+ }
+ } else if(!mime_type.isImage()) {
+ DBG_OUT("not an image type");
+ } else if(!mime_type.isDigicamRaw()) {
+ DBG_OUT("not a raw type, trying GdkPixbuf loaders");
+ try {
+ pix = Gdk::Pixbuf::create_from_file(filename, w, h, true);
+ if(pix) {
+ pix = fwk::gdkpixbuf_exif_rotate(pix, orientation);
+ }
+ }
+ catch(const Glib::Error & e) {
+ ERR_OUT("exception thumbnailing image %s", e.what().c_str());
+ }
+ } else {
+ GdkPixbuf *pixbuf = or_gdkpixbuf_extract_rotated_thumbnail(filename.c_str(),
+ std::min(w, h));
+ if(pixbuf) {
+ pix = Glib::wrap(pixbuf, true); // take ownership
+ if((w < pix->get_width()) || (h < pix->get_height())) {
+ pix = fwk::gdkpixbuf_scale_to_fit(pix, std::min(w,h));
+ }
+ }
+ }
+
+ return Thumbnail(pix);
+}
+
+}
diff --git a/src/fwk/toolkit/thumbnail.hpp b/src/fwk/toolkit/thumbnail.hpp
new file mode 100644
index 0000000..c039015
--- /dev/null
+++ b/src/fwk/toolkit/thumbnail.hpp
@@ -0,0 +1,58 @@
+/* -*- mode: C++; tab-width: 2; c-basic-offset: 2; indent-tabs-mode:nil; -*- */
+/*
+ * niepce - fwk/toolkit/thumbnail.cpp
+ *
+ * Copyright (C) 2017 Hubert Figuière
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#include <string>
+
+#include <gdkmm/pixbuf.h>
+
+namespace fwk {
+
+class Thumbnail {
+public:
+ Thumbnail() = default;
+ Thumbnail(const Glib::RefPtr<Gdk::Pixbuf>& pixbuf);
+
+ bool ok() const {
+ return !!m_pixbuf;
+ }
+
+ int get_width() const {
+ return m_pixbuf->get_width();
+ }
+ int get_height() const {
+ return m_pixbuf->get_height();
+ }
+ const Glib::RefPtr<Gdk::Pixbuf>& pixbuf() const {
+ return m_pixbuf;
+ }
+
+ void save(const std::string& path, const std::string& format);
+
+ static Thumbnail thumbnail_file(const std::string& path, int w, int h, int32_t orientation);
+
+private:
+ Glib::RefPtr<Gdk::Pixbuf> m_pixbuf;
+};
+
+}
diff --git a/src/fwk/toolkit/uiresult.hpp b/src/fwk/toolkit/uiresult.hpp
new file mode 100644
index 0000000..e1cbdb3
--- /dev/null
+++ b/src/fwk/toolkit/uiresult.hpp
@@ -0,0 +1,102 @@
+/* -*- mode: C++; tab-width: 2; c-basic-offset: 2; indent-tabs-mode:nil; -*- */
+/*
+ * niepce - fwk/toolkit/uiresult.hpp
+ *
+ * Copyright (C) 2017 Hubert Figuière
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+
+
+#pragma once
+
+#include <deque>
+#include <mutex>
+
+#include <glibmm/dispatcher.h>
+
+#include "fwk/base/option.hpp"
+
+namespace fwk {
+
+class UIResult
+{
+public:
+ virtual void clear() = 0;
+
+ sigc::connection connect(sigc::slot<void>&& slot) {
+ return m_notifier.connect(std::move(slot));
+ }
+protected:
+ Glib::Dispatcher m_notifier;
+ std::mutex m_data_mutex;
+};
+
+template<class T>
+class UIResultSingle
+ : public UIResult
+{
+public:
+ void clear() override {
+ m_data = T();
+ }
+
+ void send_data(T&& d) {
+ {
+ std::lock_guard<std::mutex> lock(m_data_mutex);
+ m_data = std::move(d);
+ }
+ m_notifier.emit();
+ };
+ T recv_data() {
+ {
+ std::lock_guard<std::mutex> lock(m_data_mutex);
+ return m_data;
+ }
+ };
+private:
+ T m_data;
+};
+
+template<class T>
+class UIResults
+ : public UIResult
+{
+public:
+ void clear() override {
+ m_data.clear();
+ }
+
+ void send_data(T&& d) {
+ {
+ std::lock_guard<std::mutex> lock(m_data_mutex);
+ m_data.push_back(std::move(d));
+ }
+ m_notifier.emit();
+ };
+ Option<T> recv_data() {
+ std::lock_guard<std::mutex> lock(m_data_mutex);
+ if (m_data.empty()) {
+ return Option<T>();
+ }
+ auto result = Option<T>(m_data.front());
+ m_data.pop_front();
+ return result;
+ };
+private:
+ std::deque<T> m_data;
+};
+
+}
diff --git a/src/niepce/ui/dialogs/importdialog.cpp b/src/niepce/ui/dialogs/importdialog.cpp
index ea4085b..3d2eb11 100644
--- a/src/niepce/ui/dialogs/importdialog.cpp
+++ b/src/niepce/ui/dialogs/importdialog.cpp
@@ -55,8 +55,6 @@ ImportDialog::ImportDialog()
, m_attributesScrolled(nullptr)
, m_images_list_scrolled(nullptr)
{
- m_received_files_to_import.connect(
- sigc::mem_fun(this, &ImportDialog::append_files_to_import));
}
ImportDialog::~ImportDialog()
@@ -99,35 +97,48 @@ void ImportDialog::setup_widget()
m_gridview->set_text_column(m_grid_columns.filename);
m_gridview->show();
m_images_list_scrolled->add(*m_gridview);
+ m_images_list_scrolled->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+
+ m_previews_to_import.connect(
+ sigc::mem_fun(this, &ImportDialog::preview_received));
+ m_files_to_import.connect(
+ sigc::mem_fun(this, &ImportDialog::append_files_to_import));
+
m_is_setup = true;
}
// XXX doesn't belong here
void ImportDialog::doSelectDirectories()
{
- Configuration & cfg = Application::app()->config();
+ Configuration & cfg = Application::app()->config();
+ Glib::ustring filename;
+ {
Gtk::FileChooserDialog dialog(gtkWindow(), _("Import picture folder"),
Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
dialog.add_button(_("Cancel"), Gtk::RESPONSE_CANCEL);
- dialog.add_button(_("Import"), Gtk::RESPONSE_OK);
+ 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);
+ if (!last_import_location.empty()) {
+ dialog.set_filename(last_import_location);
}
int result = dialog.run();
switch(result)
{
case Gtk::RESPONSE_OK:
- setToImport(dialog.get_filename());
- break;
+ filename = dialog.get_filename();
+ break;
default:
- break;
+ break;
}
+ }
+ if (!filename.empty()) {
+ setToImport(filename);
+ }
}
// XXX doesn't belong here. Or must be deeply modified to deal with the Importer
@@ -140,15 +151,12 @@ void ImportDialog::setToImport(const Glib::ustring & f)
eng::IImporter::SourceContentReady source_content_ready =
[this] (std::list<eng::ImportedFile::Ptr>&& list_to_import) {
- {
- std::lock_guard<std::mutex> lock(this->m_files_to_import_lock);
- this->m_files_to_import = list_to_import;
- }
- this->m_received_files_to_import.emit();
+ this->m_files_to_import.send_data(std::move(list_to_import));
};
m_images_list_model->clear();
+ m_images_list_map.clear();
m_files_to_import.clear();
auto importer = m_importer;
@@ -165,15 +173,49 @@ void ImportDialog::setToImport(const Glib::ustring & f)
void ImportDialog::append_files_to_import()
{
- std::lock_guard<std::mutex> lock(this->m_files_to_import_lock);
- for(const auto & f : m_files_to_import) {
+ auto files_to_import = m_files_to_import.recv_data();
+
+ if (!m_images_list_model) {
+ ERR_OUT("No image list model");
+ return;
+ }
+ // request the previews to the importer.tn.pixmap.pixbuf()
+ std::list<std::string> paths;
+ for(const auto & f : files_to_import) {
DBG_OUT("selected %s", f->name().c_str());
+ paths.push_back(f->name());
Gtk::TreeIter iter = m_images_list_model->append();
+ m_images_list_map.insert(std::make_pair(f->name(), iter));
iter->set_value(m_grid_columns.filename, Glib::ustring(f->name()));
iter->set_value(m_grid_columns.file, std::move(f));
}
+
+ eng::IImporter::PreviewReady preview_ready = [this] (const std::string& path,
+ const fwk::Thumbnail& thumbnail) {
+ this->m_previews_to_import.send_data(std::make_pair(path, thumbnail));
+ };
+
+ auto importer = m_importer;
+ auto source = m_folder_path_source.raw();
+ std::async(std::launch::async,
+ [importer, source, paths, preview_ready] () {
+ return importer->get_previews_for(source, paths, preview_ready);
+ });
}
+void ImportDialog::preview_received()
+{
+ auto result = m_previews_to_import.recv_data();
+ if (!result.empty()) {
+ auto preview = result.unwrap();
+ auto iter = m_images_list_map.find(preview.first);
+ if (iter != m_images_list_map.end()) {
+ iter->second->set_value(m_grid_columns.pixbuf, preview.second.pixbuf());
+ }
+ }
+}
+
+
}
/*
diff --git a/src/niepce/ui/dialogs/importdialog.hpp b/src/niepce/ui/dialogs/importdialog.hpp
index c02ef0c..2ae942d 100644
--- a/src/niepce/ui/dialogs/importdialog.hpp
+++ b/src/niepce/ui/dialogs/importdialog.hpp
@@ -31,6 +31,7 @@
#include "engine/importer/importedfile.hpp"
#include "fwk/toolkit/gtkutils.hpp"
#include "fwk/toolkit/dialog.hpp"
+#include "fwk/toolkit/uiresult.hpp"
#include "imageliststore.hpp"
#include "metadatapanecontroller.hpp"
@@ -43,6 +44,7 @@ class TreeView;
namespace fwk {
class ImageGridView;
+class Thumbnail;
}
namespace eng {
@@ -85,6 +87,7 @@ private:
void doSelectDirectories();
void append_files_to_import();
+ void preview_received();
std::shared_ptr<eng::IImporter> m_importer; // as shared_ptr<> for lambda capture
Glib::ustring m_folder_path_source;
@@ -98,14 +101,14 @@ private:
Gtk::ScrolledWindow *m_images_list_scrolled;
PreviewGridModel m_grid_columns;
Glib::RefPtr<Gtk::ListStore> m_images_list_model;
+ std::map<std::string, Gtk::TreeIter> m_images_list_map;
Gtk::IconView *m_gridview;
MetaDataPaneController::Ptr m_metadata_pane;
- Glib::Dispatcher m_received_files_to_import;
- std::mutex m_files_to_import_lock;
- std::list<eng::ImportedFile::Ptr> m_files_to_import;
+ fwk::UIResultSingle<std::list<eng::ImportedFile::Ptr>> m_files_to_import;
+ fwk::UIResults<std::pair<std::string, fwk::Thumbnail>> m_previews_to_import;
};
}
diff --git a/src/niepce/ui/imageliststore.cpp b/src/niepce/ui/imageliststore.cpp
index 329bde3..4fb2b0b 100644
--- a/src/niepce/ui/imageliststore.cpp
+++ b/src/niepce/ui/imageliststore.cpp
@@ -160,9 +160,10 @@ void ImageListStore::on_tnail_notification(const eng::ThumbnailNotification &tn)
= m_idmap.find( tn.id );
if(iter != m_idmap.end()) {
// found the icon view item
+ auto pixbuf = tn.pixmap.pixbuf();
Gtk::TreeRow row = *(iter->second);
- row[m_columns.m_pix] = tn.pixmap;
- row[m_columns.m_strip_thumb] = fwk::gdkpixbuf_scale_to_fit(tn.pixmap, 100);
+ row[m_columns.m_pix] = pixbuf;
+ row[m_columns.m_strip_thumb] = fwk::gdkpixbuf_scale_to_fit(pixbuf, 100);
}
else {
DBG_OUT("row %Ld not found", (long long)tn.id);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]