[glom] ImageGlom: Saving is now mostly async.
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glom] ImageGlom: Saving is now mostly async.
- Date: Tue, 12 Jul 2011 13:05:48 +0000 (UTC)
commit dd8e028758d1fa01599c64f353b965090e421388
Author: Murray Cumming <murrayc murrayc com>
Date: Tue Jul 12 15:05:42 2011 +0200
ImageGlom: Saving is now mostly async.
* glom/utility_widgets/dialog_image_save_progress.[h|cc]: Doing the actual
writing in callbacks, like in the loader.
* glom/utility_widgets/imageglom.cc: Show the dialog, so we can use the
idle callbacks, and give user feedback.
ChangeLog | 9 ++++
glom/utility_widgets/dialog_image_load_progress.cc | 5 ++
glom/utility_widgets/dialog_image_save_progress.cc | 48 +++++++++++++++++---
glom/utility_widgets/dialog_image_save_progress.h | 2 +
glom/utility_widgets/imageglom.cc | 3 +-
5 files changed, 58 insertions(+), 9 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 6f2939f..f7bf002 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
2011-07-12 Murray Cumming <murrayc murrayc com>
+ ImageGlom: Saving is now mostly async.
+
+ * glom/utility_widgets/dialog_image_save_progress.[h|cc]: Doing the actual
+ writing in callbacks, like in the loader.
+ * glom/utility_widgets/imageglom.cc: Show the dialog, so we can use the
+ idle callbacks, and give user feedback.
+
+2011-07-12 Murray Cumming <murrayc murrayc com>
+
ImageGlom: Allow the user to choose any file.
* glom/utility_widgets/imageglom.cc: However, we are still restricted to
diff --git a/glom/utility_widgets/dialog_image_load_progress.cc b/glom/utility_widgets/dialog_image_load_progress.cc
index 71148a9..83558b2 100644
--- a/glom/utility_widgets/dialog_image_load_progress.cc
+++ b/glom/utility_widgets/dialog_image_load_progress.cc
@@ -132,12 +132,16 @@ void DialogImageLoadProgress::on_stream_read(const Glib::RefPtr<Gio::AsyncResult
{
gssize size = m_stream->read_finish(result);
g_assert(size >= 0); // Would have thrown an exception otherwise
+
// Cannot read more data than there is available in the file:
g_assert( static_cast<gssize>(offset + size) <= static_cast<gssize>(m_data->binary_length));
+
// Load image
m_loader->write(m_data->data + offset, size);
+
// Set progress
m_progress_bar->set_fraction(static_cast<double>(offset + size) / m_data->binary_length);
+
// Read next chunk, if any
if( static_cast<gssize>(offset + size) < static_cast<gssize>(m_data->binary_length))
// Even if choose a priority lower than GDK_PRIORITY_REDRAW + 10 for the
@@ -151,6 +155,7 @@ void DialogImageLoadProgress::on_stream_read(const Glib::RefPtr<Gio::AsyncResult
catch(const Glib::Error& ex)
{
error(ex.what());
+ response(Gtk::RESPONSE_REJECT);
}
}
diff --git a/glom/utility_widgets/dialog_image_save_progress.cc b/glom/utility_widgets/dialog_image_save_progress.cc
index 4e7753b..245f0d7 100644
--- a/glom/utility_widgets/dialog_image_save_progress.cc
+++ b/glom/utility_widgets/dialog_image_save_progress.cc
@@ -24,6 +24,14 @@
#include <iostream>
#include <glibmm/i18n.h>
+namespace
+{
+
+// Write the file in chunks of this size:
+const unsigned int CHUNK_SIZE = 2048;
+
+} // anonymous namespace
+
namespace Glom
{
@@ -80,10 +88,11 @@ void DialogImageSaveProgress::save(const Glib::ustring& uri)
}
//Write the data to the output uri
- gssize bytes_written = 0;
try
{
- bytes_written = m_stream->write(m_data->data, m_data->binary_length);
+ m_stream->write_async(m_data->data,
+ std::min<gsize>(CHUNK_SIZE, m_data->binary_length),
+ sigc::bind(sigc::mem_fun(*this, &DialogImageSaveProgress::on_stream_write), 0));
}
catch(const Gio::Error& ex)
{
@@ -91,14 +100,33 @@ void DialogImageSaveProgress::save(const Glib::ustring& uri)
response(Gtk::RESPONSE_REJECT);
return;
}
+}
- if(bytes_written != m_data->binary_length)
+void DialogImageSaveProgress::on_stream_write(const Glib::RefPtr<Gio::AsyncResult>& result, unsigned int offset)
+{
+ try
{
- std::cerr << G_STRFUNC << ": unexpected number of bytes written: bytes_written=" << bytes_written <<
- ", binary_length=" << m_data->binary_length << std::endl;
+ const gssize size = m_stream->write_finish(result);
+ g_assert(size >= 0); // Would have thrown an exception otherwise
+
+ // Set progress
+ m_progress_bar->set_fraction(static_cast<double>(offset + size) / m_data->binary_length);
+
+ // Write next chunk, if any
+ if( static_cast<gssize>(offset + size) < static_cast<gssize>(m_data->binary_length))
+ // Even if choose a priority lower than GDK_PRIORITY_REDRAW + 10 for the
+ // write_async we don't see the progressbar progressing while the image
+ // is loading. Therefore we put an idle inbetween.
+ Glib::signal_idle().connect(sigc::bind_return(sigc::bind(sigc::mem_fun(*this, &DialogImageSaveProgress::on_write_next), offset + size), false));
+ else
+ // We are done saving the image, close the progress dialog
+ response(Gtk::RESPONSE_ACCEPT);
+ }
+ catch(const Glib::Error& ex)
+ {
+ error(ex.what());
+ response(Gtk::RESPONSE_REJECT);
}
-
- response(Gtk::RESPONSE_ACCEPT);
}
void DialogImageSaveProgress::error(const Glib::ustring& error_message)
@@ -111,6 +139,12 @@ void DialogImageSaveProgress::error(const Glib::ustring& error_message)
response(Gtk::RESPONSE_REJECT);
}
+void DialogImageSaveProgress::on_write_next(unsigned int at)
+{
+ g_assert(at < static_cast<gsize>(m_data->binary_length));
+
+ m_stream->write_async(m_data->data + at, std::min<gsize>(CHUNK_SIZE, m_data->binary_length - at), sigc::bind(sigc::mem_fun(*this, &DialogImageSaveProgress::on_stream_write), at));
+}
void DialogImageSaveProgress::set_image_data(const GdaBinary& data)
{
diff --git a/glom/utility_widgets/dialog_image_save_progress.h b/glom/utility_widgets/dialog_image_save_progress.h
index 7506606..42acee7 100644
--- a/glom/utility_widgets/dialog_image_save_progress.h
+++ b/glom/utility_widgets/dialog_image_save_progress.h
@@ -45,7 +45,9 @@ public:
void set_image_data(const GdaBinary& data);
private:
+ void on_stream_write(const Glib::RefPtr<Gio::AsyncResult>& result, unsigned int offset);
void error(const Glib::ustring& error_message);
+ void on_write_next(unsigned int at);
Gtk::ProgressBar* m_progress_bar;
const GdaBinary* m_data;
diff --git a/glom/utility_widgets/imageglom.cc b/glom/utility_widgets/imageglom.cc
index ecada37..fc9743b 100644
--- a/glom/utility_widgets/imageglom.cc
+++ b/glom/utility_widgets/imageglom.cc
@@ -453,8 +453,7 @@ bool ImageGlom::save_file(const Glib::ustring& uri)
dialog_save->set_image_data(*gda_binary);
dialog_save->save(uri);
- //TODO: Use this when we do async saving:
- //dialog_save->run();
+ dialog_save->run();
return true;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]