[pan2] added download meter (rough basic impl) https://bugzilla.gnome.org/show_bug.cgi?id=102402
- From: Heinrich MÃller <henmull src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pan2] added download meter (rough basic impl) https://bugzilla.gnome.org/show_bug.cgi?id=102402
- Date: Sat, 29 Sep 2012 19:05:27 +0000 (UTC)
commit e954815e5987bcbc4ae9e9dde5e6c0a5b0b5a4fe
Author: Heinrich MÃller <henmull src gnome org>
Date: Sun Sep 23 19:15:15 2012 +0200
added download meter (rough basic impl)
https://bugzilla.gnome.org/show_bug.cgi?id=102402
pan.cbp | 69 ++-----------
pan/data-impl/Makefile.am | 6 +-
pan/data-impl/data-impl.cc | 50 +++++++++-
pan/data-impl/data-impl.h | 13 ++-
pan/data-impl/data-io.cc | 18 ++++
pan/data-impl/data-io.h | 2 +
pan/data-impl/download-meter.cc | 208 ++++++++++++++++++++++++++++++++++++++
pan/data-impl/download-meter.h | 89 ++++++++++++++++
pan/data/data.h | 51 +++++++++-
pan/general/progress.cc | 4 +-
pan/general/progress.h | 11 ++-
pan/gui/Makefile.am | 6 +-
pan/gui/actions.cc | 6 +
pan/gui/dl-prefs.cc | 193 +++++++++++++++++++++++++++++++++++
pan/gui/dl-prefs.h | 61 +++++++++++
pan/gui/gui.cc | 35 +++++--
pan/gui/gui.h | 14 ++-
pan/gui/pan-ui.h | 1 +
pan/gui/pan.cc | 7 +-
pan/gui/prefs-ui.cc | 20 +---
pan/gui/prefs.cc | 23 ++++
pan/gui/prefs.h | 15 +++
pan/gui/progress-view.cc | 16 +++
pan/gui/progress-view.h | 3 +
pan/tasks/nntp-pool.cc | 10 +-
pan/tasks/nntp-pool.h | 12 +-
pan/tasks/nntp.cc | 6 +
pan/tasks/nntp.h | 10 ++-
pan/tasks/queue.cc | 20 ++++-
pan/tasks/queue.h | 13 ++-
pan/tasks/socket-impl-gio.cc | 1 +
pan/tasks/socket-impl-openssl.cc | 1 +
pan/tasks/socket.h | 9 ++-
33 files changed, 887 insertions(+), 116 deletions(-)
---
diff --git a/pan.cbp b/pan.cbp
index 704b4b4..6c7bda6 100644
--- a/pan.cbp
+++ b/pan.cbp
@@ -58,20 +58,16 @@
<Compiler>
<Add option="-Wall" />
</Compiler>
- <Unit filename="config.h">
- <Option target="all_linux" />
- </Unit>
+ <Unit filename="config.h" />
<Unit filename="pan/data-impl/add-server.cc" />
<Unit filename="pan/data-impl/article-filter.cc" />
<Unit filename="pan/data-impl/article-filter.h" />
- <Unit filename="pan/data-impl/cert-store.h">
- <Option target="all_linux" />
- </Unit>
<Unit filename="pan/data-impl/data-impl.cc" />
<Unit filename="pan/data-impl/data-impl.h" />
<Unit filename="pan/data-impl/data-io.cc" />
<Unit filename="pan/data-impl/data-io.h" />
- <Unit filename="pan/data-impl/defgroup.h" />
+ <Unit filename="pan/data-impl/download-meter.cc" />
+ <Unit filename="pan/data-impl/download-meter.h" />
<Unit filename="pan/data-impl/groups.cc" />
<Unit filename="pan/data-impl/headers-test.cc" />
<Unit filename="pan/data-impl/headers.cc" />
@@ -83,9 +79,6 @@
<Unit filename="pan/data-impl/rules-filter.h" />
<Unit filename="pan/data-impl/server.cc" />
<Unit filename="pan/data-impl/speed-test-load-group.cc" />
- <Unit filename="pan/data-impl/sql-db.h">
- <Option target="all_linux" />
- </Unit>
<Unit filename="pan/data-impl/task-archive.cc" />
<Unit filename="pan/data-impl/xover.cc" />
<Unit filename="pan/data/article-cache.cc" />
@@ -97,19 +90,14 @@
<Unit filename="pan/data/cert-store.h" />
<Unit filename="pan/data/data.cc" />
<Unit filename="pan/data/data.h" />
- <Unit filename="pan/data/defgroup.h" />
<Unit filename="pan/data/encode-cache.cc" />
<Unit filename="pan/data/encode-cache.h" />
<Unit filename="pan/data/parts.cc" />
<Unit filename="pan/data/parts.h" />
<Unit filename="pan/data/server-info.h" />
- <Unit filename="pan/data/xover-cache.h">
- <Option target="all_linux" />
- </Unit>
<Unit filename="pan/data/xref-test.cc" />
<Unit filename="pan/data/xref.cc" />
<Unit filename="pan/data/xref.h" />
- <Unit filename="pan/general/compression.h" />
<Unit filename="pan/general/debug.cc" />
<Unit filename="pan/general/debug.h" />
<Unit filename="pan/general/defgroup.h" />
@@ -117,9 +105,6 @@
<Unit filename="pan/general/e-util.h" />
<Unit filename="pan/general/file-util.cc" />
<Unit filename="pan/general/file-util.h" />
- <Unit filename="pan/general/gdk-threads.h">
- <Option target="all_linux" />
- </Unit>
<Unit filename="pan/general/line-reader.cc" />
<Unit filename="pan/general/line-reader.h" />
<Unit filename="pan/general/locking.h" />
@@ -128,9 +113,6 @@
<Unit filename="pan/general/macros.h" />
<Unit filename="pan/general/map-vector.h" />
<Unit filename="pan/general/messages.h" />
- <Unit filename="pan/general/non-gui.h">
- <Option target="all_linux" />
- </Unit>
<Unit filename="pan/general/progress-test.cc" />
<Unit filename="pan/general/progress.cc" />
<Unit filename="pan/general/progress.h" />
@@ -147,7 +129,6 @@
<Unit filename="pan/general/text-match.cc" />
<Unit filename="pan/general/text-match.h" />
<Unit filename="pan/general/time-elapsed.h" />
- <Unit filename="pan/general/typedefs.h" />
<Unit filename="pan/general/utf8-utils.cc" />
<Unit filename="pan/general/utf8-utils.h" />
<Unit filename="pan/general/worker-pool.cc" />
@@ -161,6 +142,9 @@
<Unit filename="pan/gui/defgroup.h" />
<Unit filename="pan/gui/dl-headers-ui.cc" />
<Unit filename="pan/gui/dl-headers-ui.h" />
+ <Unit filename="pan/gui/dl-prefs.cc" />
+ <Unit filename="pan/gui/dl-prefs.h" />
+ <Unit filename="pan/gui/download-meter.h" />
<Unit filename="pan/gui/e-action-combo-box.c">
<Option compilerVar="CC" />
</Unit>
@@ -188,9 +172,6 @@
<Unit filename="pan/gui/group-prefs.cc" />
<Unit filename="pan/gui/group-prefs.h" />
<Unit filename="pan/gui/gtk-compat.h" />
- <Unit filename="pan/gui/gtk_compat.h">
- <Option target="all_linux" />
- </Unit>
<Unit filename="pan/gui/gui.cc" />
<Unit filename="pan/gui/gui.h" />
<Unit filename="pan/gui/header-pane.cc" />
@@ -253,8 +234,6 @@
<Unit filename="pan/gui/xface.h" />
<Unit filename="pan/icons/pan-pixbufs-internal.h" />
<Unit filename="pan/icons/pan-pixbufs.h" />
- <Unit filename="pan/icons/pan_icons/pan-pixbufs-internal.h" />
- <Unit filename="pan/icons/pan_icons/pan-pixbufs.h" />
<Unit filename="pan/tasks/adaptable-set-test.cc" />
<Unit filename="pan/tasks/adaptable-set.cc" />
<Unit filename="pan/tasks/adaptable-set.h" />
@@ -287,9 +266,6 @@
<Unit filename="pan/tasks/task-article.h" />
<Unit filename="pan/tasks/task-groups.cc" />
<Unit filename="pan/tasks/task-groups.h" />
- <Unit filename="pan/tasks/task-multipost.h">
- <Option target="all_linux" />
- </Unit>
<Unit filename="pan/tasks/task-post.cc" />
<Unit filename="pan/tasks/task-post.h" />
<Unit filename="pan/tasks/task-upload.cc" />
@@ -339,58 +315,35 @@
<Unit filename="pan/usenet-utils/url-find.h" />
<Unit filename="uulib/crc32.c">
<Option compilerVar="CC" />
- <Option target="all_linux" />
- </Unit>
- <Unit filename="uulib/crc32.h">
- <Option target="all_linux" />
</Unit>
+ <Unit filename="uulib/crc32.h" />
<Unit filename="uulib/fptools.c">
<Option compilerVar="CC" />
- <Option target="all_linux" />
- </Unit>
- <Unit filename="uulib/fptools.h">
- <Option target="all_linux" />
</Unit>
+ <Unit filename="uulib/fptools.h" />
<Unit filename="uulib/uucheck.c">
<Option compilerVar="CC" />
- <Option target="all_linux" />
- </Unit>
- <Unit filename="uulib/uudeview.h">
- <Option target="all_linux" />
</Unit>
+ <Unit filename="uulib/uudeview.h" />
<Unit filename="uulib/uuencode.c">
<Option compilerVar="CC" />
- <Option target="all_linux" />
- </Unit>
- <Unit filename="uulib/uuencode2.c">
- <Option compilerVar="CC" />
- <Option target="all_linux" />
- </Unit>
- <Unit filename="uulib/uuint.h">
- <Option target="all_linux" />
</Unit>
+ <Unit filename="uulib/uuint.h" />
<Unit filename="uulib/uulib.c">
<Option compilerVar="CC" />
- <Option target="all_linux" />
</Unit>
<Unit filename="uulib/uunconc.c">
<Option compilerVar="CC" />
- <Option target="all_linux" />
</Unit>
<Unit filename="uulib/uuscan.c">
<Option compilerVar="CC" />
- <Option target="all_linux" />
</Unit>
<Unit filename="uulib/uustring.c">
<Option compilerVar="CC" />
- <Option target="all_linux" />
- </Unit>
- <Unit filename="uulib/uustring.h">
- <Option target="all_linux" />
</Unit>
+ <Unit filename="uulib/uustring.h" />
<Unit filename="uulib/uuutil.c">
<Option compilerVar="CC" />
- <Option target="all_linux" />
</Unit>
<Extensions>
<envvars />
diff --git a/pan/data-impl/Makefile.am b/pan/data-impl/Makefile.am
index b038814..30f97f0 100644
--- a/pan/data-impl/Makefile.am
+++ b/pan/data-impl/Makefile.am
@@ -16,7 +16,8 @@ libpandata_a_SOURCES = \
server.cc \
my-tree.cc \
task-archive.cc \
- xover.cc
+ xover.cc \
+ download-meter.cc
noinst_HEADERS = \
@@ -26,7 +27,8 @@ noinst_HEADERS = \
data-io.h \
defgroup.h \
profiles.h \
- memchunk.h
+ memchunk.h \
+ download-meter.h
#noinst_PROGRAMS = \
# add-server \
diff --git a/pan/data-impl/data-impl.cc b/pan/data-impl/data-impl.cc
index 30cadfc..c4095d4 100644
--- a/pan/data-impl/data-impl.cc
+++ b/pan/data-impl/data-impl.cc
@@ -69,16 +69,17 @@ namespace
DataImpl :: DataImpl (const StringView& cache_ext, Prefs& prefs, bool unit_test, int cache_megs, DataIO * io):
ProfilesImpl (*io),
+ DownloadMeterImpl(prefs, *this),
_cache (get_cache_path(), cache_ext, cache_megs),
_encode_cache (get_encode_cache_path(), cache_megs),
_certstore(*this),
_unit_test (unit_test),
_data_io (io),
- _prefs (prefs),
_descriptions_loaded (false),
newsrc_autosave_id (0),
newsrc_autosave_timeout (0),
- _rules_filter (prefs.get_flag("rules-autocache-mark-read", false), prefs.get_flag("rules-auto-dl-mark-read", false),
+ _rules_filter (prefs.get_flag("rules-autocache-mark-read", false),
+ prefs.get_flag("rules-auto-dl-mark-read", false),
prefs.get_flag("rules-autocache-mark-read", false))
{
@@ -104,6 +105,7 @@ DataImpl :: rebuild_backend ()
load_newsrc_files (*_data_io);
load_group_xovers (*_data_io);
load_group_permissions (*_data_io);
+ load_download_stats (*_data_io);
_descriptions.clear ();
_descriptions_loaded = false;
@@ -116,7 +118,6 @@ DataImpl :: rebuild_backend ()
DataImpl :: ~DataImpl ()
{
save_state ();
-
}
void
@@ -127,6 +128,7 @@ DataImpl :: save_state ()
debug ("data-impl dtor saving xov, newsrc...");
save_group_xovers (*_data_io);
save_newsrc_files (*_data_io);
+ save_download_stats (*_data_io);
}
}
@@ -179,3 +181,45 @@ DataImpl :: password_decrypt (PasswordData& pw) const
#endif
+/***
+ ** Download stats
+ ***/
+
+ void
+DataImpl :: load_download_stats (const DataIO& data_io)
+{
+
+ LineReader * in (data_io.read_download_stats ());
+ StringView s, line;
+ uint64_t bytes (0ul);
+ while (in && !in->fail() && in->getline(line))
+ {
+ if (line.len && *line.str=='#')
+ {
+ continue;
+ }
+ else
+ {
+ bytes = atoll(line.str);
+ break;
+ }
+ }
+
+ dl_meter_init (bytes);
+
+ delete in;
+}
+
+void
+DataImpl :: save_download_stats(DataIO& data_io) const
+{
+ if (_unit_test)
+ return;
+
+ std::ostream& out (*data_io.write_download_stats ());
+
+ out << "# Download stats (single uint64_t showing bytes downloaded so far\n";
+ out << dl_meter_get_bytes() <<"\n";
+
+ data_io.write_done (&out);
+}
diff --git a/pan/data-impl/data-impl.h b/pan/data-impl/data-impl.h
index 14ff1d1..c742269 100644
--- a/pan/data-impl/data-impl.h
+++ b/pan/data-impl/data-impl.h
@@ -44,6 +44,7 @@
#include <pan/data-impl/article-filter.h>
#include <pan/data-impl/rules-filter.h>
#include <pan/data-impl/profiles.h>
+#include <pan/data-impl/download-meter.h>
#include <pan/data-impl/memchunk.h>
#include <pan/gui/prefs.h>
@@ -68,7 +69,9 @@ namespace pan
class DataImpl:
public Data,
public TaskArchive,
- public ProfilesImpl
+ public ProfilesImpl,
+ public DownloadMeterImpl
+// public DownloadMeter::Listener
{
/**
@@ -689,6 +692,14 @@ namespace pan
newsrc_autosave_id = 0;
}
+ /**
+ *** Download stats
+ **/
+ public:
+
+ void load_download_stats (const DataIO&);
+ void save_download_stats (DataIO&) const;
+
};
}
diff --git a/pan/data-impl/data-io.cc b/pan/data-impl/data-io.cc
index 8f3aa8f..7267811 100644
--- a/pan/data-impl/data-io.cc
+++ b/pan/data-impl/data-io.cc
@@ -80,6 +80,12 @@ namespace
g_free (filename);
return retval;
}
+
+ std::string get_download_stats_filename ()
+ {
+ return get_pan_home_file ("downloads.stats");
+ }
+
}
std::string
@@ -151,6 +157,12 @@ DataIO :: read_group_permissions () const
}
LineReader*
+DataIO :: read_download_stats () const
+{
+ return read_file (get_download_stats_filename ());
+}
+
+LineReader*
DataIO :: read_group_xovers () const
{
return read_file (get_group_xovers_filename ());
@@ -258,6 +270,12 @@ DataIO :: write_group_headers (const Quark& group)
}
std::ostream*
+DataIO :: write_download_stats ()
+{
+ return write_file (get_download_stats_filename ());
+}
+
+std::ostream*
DataIO :: write_file (const StringView& filename)
{
return get_ostream (filename);
diff --git a/pan/data-impl/data-io.h b/pan/data-impl/data-io.h
index ab0b2cc..c832bea 100644
--- a/pan/data-impl/data-io.h
+++ b/pan/data-impl/data-io.h
@@ -50,12 +50,14 @@ namespace pan
virtual LineReader* read_group_headers (const Quark& group) const;
virtual LineReader* read_group_descriptions () const;
virtual LineReader* read_group_permissions () const;
+ virtual LineReader* read_download_stats () const;
virtual std::ostream* write_tasks ();
virtual std::ostream* write_server_properties ();
virtual std::ostream* write_group_xovers ();
virtual std::ostream* write_group_descriptions ();
virtual std::ostream* write_group_permissions ();
+ virtual std::ostream* write_download_stats ();
virtual std::ostream* write_group_headers (const Quark& group);
virtual void write_done (std::ostream*);
diff --git a/pan/data-impl/download-meter.cc b/pan/data-impl/download-meter.cc
new file mode 100644
index 0000000..a0910aa
--- /dev/null
+++ b/pan/data-impl/download-meter.cc
@@ -0,0 +1,208 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Pan - A Newsreader for Gtk+
+ * Copyright (C) 2002-2006 Charles Kerr <charles rebelbase com>
+ *
+ * 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; version 2 of the License.
+ *
+ * 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 <config.h>
+#include <pan/data-impl/download-meter.h>
+#include <pan/data-impl/data-impl.h>
+#include <iostream>
+#include <math.h>
+
+extern "C" {
+ #include <glib/gi18n.h>
+}
+
+using namespace pan;
+
+
+DownloadMeterImpl :: ~DownloadMeterImpl()
+{
+}
+
+
+DownloadMeterImpl :: DownloadMeterImpl (Prefs& prefs, Data& data) :
+ _view(new ProgressView()),
+ _progress(new Progress("Downloaded bytes")),
+ _prefs(prefs),
+ _data(data),
+ _downloaded_bytes(0ul),
+ _limit(1ul)
+{
+
+ dl_meter_update ();
+
+ _view->set_progress(_progress);
+ _progress->init_steps(100);
+ _progress->set_status(_("DL Init ...."));
+
+ GtkWidget* w = _button = gtk_button_new();
+ gtk_widget_set_tooltip_text (w, _("Open Download Meter Preferences"));
+ gtk_button_set_relief (GTK_BUTTON(w), GTK_RELIEF_NONE);
+
+ gtk_container_add (GTK_CONTAINER(w), _view->root());
+ GtkWidget* frame = _widget = gtk_frame_new (NULL);
+ gtk_container_set_border_width (GTK_CONTAINER(frame), 0);
+ gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
+ gtk_container_add (GTK_CONTAINER(frame), w);
+
+ gtk_widget_set_visible(_widget, prefs.get_flag("dl-meter-show", true));
+
+}
+
+namespace
+{
+
+ std::string mnemonic(int cnt)
+ {
+ std::string ret;
+
+ switch (cnt)
+ {
+ default:
+ case 0:
+ ret = _("Bytes");
+ break;
+ case 1:
+ ret = _("KB");
+ break;
+ case 2:
+ ret = _("MB");
+ break;
+ case 3:
+ ret = _("GB");
+ break;
+ case 4:
+ ret = _("TB");
+ break;
+ }
+
+ return ret;
+ }
+
+ // black magic to get declarative value (mb, gb)
+ std::string get_value(uint64_t bytes)
+ {
+ int cnt (log10f(bytes)/log10f(1024));
+ uint64_t factor = ::pow(1024ul, (uint64_t)cnt);
+ float rest = cnt > 0.0f ? (((float)bytes / (float)factor)/10.0f) : 0.0f;
+ std::stringstream str;
+
+ uint64_t ret = factor == 0ul ? ret : bytes / factor;
+ str << (ret+rest) << " " << mnemonic(cnt);
+ return str.str();
+ }
+
+}
+
+void
+DownloadMeterImpl :: set_status ()
+{
+ // check if limit reached
+ if (_downloaded_bytes > _limit && _limit > 0)
+ {
+ fire_dl_limit_reached ();
+ if (_prefs.get_flag("warn-dl-limit-reached", true))
+ _view->set_color("red");
+ }
+ else
+ {
+ _view->reset_color ();
+ }
+
+ _progress->set_status_va(_("DL %s"), get_value(_downloaded_bytes).c_str());
+
+ if (_limit > 0)
+ _progress->set_step (100ul * _downloaded_bytes/_limit);
+
+}
+
+void
+DownloadMeterImpl :: dl_meter_add (uint64_t bytes)
+{
+ _downloaded_bytes += bytes;
+ fire_xfer_bytes(bytes);
+ set_status ();
+}
+
+void
+DownloadMeterImpl :: dl_meter_reset ()
+{
+ std::cerr<<"reset\n";
+ _downloaded_bytes = 0;
+ set_status ();
+ fire_reset_xfer_bytes ();
+}
+
+void
+DownloadMeterImpl :: dl_meter_init (uint64_t bytes)
+{
+ _downloaded_bytes = bytes;
+}
+
+void
+DownloadMeterImpl :: dl_meter_update ()
+{
+ std::string limit_type (_prefs.get_string("dl-limit-type", ""));
+
+ int type_idx (0);
+ if (limit_type == "mb")
+ type_idx = 2; // 1024*1024
+ if (limit_type == "gb")
+ type_idx = 3; // 1024*1024*1024
+
+ int limit (_prefs.get_int("dl-limit", 1024));
+ _limit = limit * ::pow(1024, type_idx);
+
+ set_status ();
+}
+
+void
+DownloadMeterImpl :: fire_reset_xfer_bytes ()
+{
+ for (lit it(_listeners.begin()), end(_listeners.end()); it!=end; )
+ (*it++)->on_reset_xfer_bytes ();
+}
+
+void
+DownloadMeterImpl :: fire_dl_limit_reached ()
+{
+ for (lit it(_listeners.begin()), end(_listeners.end()); it!=end; )
+ (*it++)->on_dl_limit_reached ();
+}
+
+
+void
+DownloadMeterImpl :: fire_xfer_bytes (uint64_t bytes)
+{
+ for (lit it(_listeners.begin()), end(_listeners.end()); it!=end; )
+ (*it++)->on_xfer_bytes (bytes);
+}
+
+uint64_t
+DownloadMeterImpl :: dl_meter_get_limit()
+{
+ return _limit;
+}
+
+void
+DownloadMeterImpl :: dl_meter_set_limit (uint64_t l)
+{
+ _limit = l;
+ set_status();
+}
+
diff --git a/pan/data-impl/download-meter.h b/pan/data-impl/download-meter.h
new file mode 100644
index 0000000..dfe304e
--- /dev/null
+++ b/pan/data-impl/download-meter.h
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Pan - A Newsreader for Gtk+
+ * Copyright (C) 2002-2006 Charles Kerr <charles rebelbase com>
+ *
+ * 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; version 2 of the License.
+ *
+ * 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 _DOWNLOAD_METER_IMPL_H_
+#define _DOWNLOAD_METER_IMPL_H_
+
+#include <string>
+#include <pan/general/quark.h>
+#include <pan/general/string-view.h>
+#include <pan/gui/prefs.h>
+#include <pan/gui/progress-view.h>
+#include <pan/general/progress.h>
+#include <pan/data/data.h>
+
+namespace pan
+{
+ class DownloadMeterImpl :
+ public virtual DownloadMeter
+ {
+ public:
+
+ DownloadMeterImpl (Prefs&, Data&);
+ virtual ~DownloadMeterImpl() ;
+
+ virtual void dl_meter_add(const uint64_t bytes) ;
+ virtual void dl_meter_init (uint64_t bytes) ;
+ virtual void dl_meter_reset () ;
+ virtual void dl_meter_update () ;
+
+ private:
+
+ typedef std::set<DownloadMeter::Listener*> listeners_t;
+ typedef listeners_t::const_iterator lit;
+ listeners_t _listeners;
+
+ ProgressView* _view;
+ Progress* _progress;
+ uint64_t _limit;
+ uint64_t _downloaded_bytes;
+ GtkWidget* _widget;
+ GtkWidget* _button;
+ Prefs& _prefs;
+ Data& _data;
+
+ public:
+
+ virtual void add_listener (DownloadMeter::Listener * l) { _listeners.insert(l); }
+ virtual void remove_listener (DownloadMeter::Listener * l) { _listeners.erase(l); }
+
+ virtual ProgressView* get_view() { return _view; }
+ virtual GtkWidget* get_widget () { return _widget; }
+ virtual GtkWidget* get_button () { return _button; }
+
+ public:
+
+ virtual uint64_t dl_meter_get_limit();
+ virtual void dl_meter_set_limit (uint64_t l);
+
+ virtual uint64_t dl_meter_get_bytes() const { return _downloaded_bytes; }
+
+ private:
+
+ virtual void fire_xfer_bytes (uint64_t bytes);
+ virtual void fire_reset_xfer_bytes ();
+ virtual void fire_dl_limit_reached ();
+
+ void set_status ();
+
+
+ };
+}
+
+#endif
diff --git a/pan/data/data.h b/pan/data/data.h
index 7d4f4a8..684961d 100644
--- a/pan/data/data.h
+++ b/pan/data/data.h
@@ -35,6 +35,7 @@
#include <pan/data/cert-store.h>
#include <pan/data/server-info.h>
#include <pan/gui/prefs.h>
+#include <pan/gui/progress-view.h>
#ifdef HAVE_GKR
#include <gnome-keyring-1/gnome-keyring.h>
@@ -152,6 +153,51 @@ namespace pan
Profiles () {}
};
+ class DownloadMeter
+ {
+ public:
+
+ virtual ~DownloadMeter () {}
+
+ struct Listener {
+ Listener () {}
+ virtual ~Listener () {}
+ virtual void on_xfer_bytes (uint64_t) = 0;
+ virtual void on_reset_xfer_bytes () = 0;
+ virtual void on_dl_limit_reached () = 0;
+ };
+
+ virtual void add_listener (Listener * l) = 0;
+ virtual void remove_listener (Listener * l) = 0;
+
+ protected:
+
+ DownloadMeter() {}
+
+ public:
+ virtual void dl_meter_add (uint64_t bytes) = 0;
+ virtual void dl_meter_update () = 0;
+
+ public:
+
+ virtual ProgressView* get_view() = 0;
+ virtual GtkWidget* get_widget () = 0;
+ virtual GtkWidget* get_button () = 0;
+
+ public:
+
+ virtual uint64_t dl_meter_get_limit() = 0;
+ virtual void dl_meter_set_limit (uint64_t l) = 0;
+ virtual void dl_meter_reset () = 0;
+
+ public:
+
+ virtual void fire_xfer_bytes (uint64_t bytes) = 0;
+ virtual void fire_reset_xfer_bytes () = 0;
+ virtual void fire_dl_limit_reached () = 0;
+
+ };
+
/**
* The main interface class for Pan's data backend.
*
@@ -167,6 +213,7 @@ namespace pan
*/
class Data:
public virtual ServerInfo,
+ public virtual DownloadMeter,
public virtual GroupServer,
public virtual ArticleRead,
public virtual Profiles,
@@ -178,7 +225,6 @@ namespace pan
{
Quark server;
StringView user;
-// StringView pw;
gchar* pw;
};
@@ -668,6 +714,9 @@ namespace pan
const Quark & server,
const uint64_t low) = 0;
+ /** Sets the queue interface */
+ virtual void set_queue (Queue* q) = 0;
+
};
}
diff --git a/pan/general/progress.cc b/pan/general/progress.cc
index 4bbcc4c..ac157d3 100644
--- a/pan/general/progress.cc
+++ b/pan/general/progress.cc
@@ -123,6 +123,7 @@ Progress :: set_step (int step)
const int old_of_100 (get_progress_of_100());
_step = step;
const int new_of_100 (get_progress_of_100());
+
if (old_of_100 != new_of_100)
fire_percentage (new_of_100);
}
@@ -136,13 +137,12 @@ Progress :: increment_step (int increment)
int
Progress :: get_progress_of_100 () const
{
- int p = (int)(!_steps ? 0 : (_step*100.0)/_steps);
+ int p = (int)(!_steps ? 0 : (_step*100ul)/_steps);
if (p < 0) p = 0;
if (p > 100) p = 100;
return p;
}
-
void
Progress :: set_finished (int status)
{
diff --git a/pan/general/progress.h b/pan/general/progress.h
index 37d9365..999004f 100644
--- a/pan/general/progress.h
+++ b/pan/general/progress.h
@@ -26,6 +26,11 @@
#include <pan/general/debug.h>
#include <pan/general/string-view.h>
+extern "C"
+{
+ #include <stdint.h>
+}
+
namespace pan
{
class StringView;
@@ -72,10 +77,10 @@ namespace pan
std::string _description; // used for default describe()
std::string _status_text; // the last status text emitted
std::vector<std::string> _errors; // the emitted error strings
- int _steps; // number of steps total
- int _step; // number of steps completed so far
+ uint64_t _steps; // number of steps total
+ uint64_t _step; // number of steps completed so far
int _done; // value of set_finished()
- bool _active;
+ bool _active;
public:
diff --git a/pan/gui/Makefile.am b/pan/gui/Makefile.am
index 67c0090..39cb9a6 100644
--- a/pan/gui/Makefile.am
+++ b/pan/gui/Makefile.am
@@ -23,6 +23,7 @@ libpangui_a_SOURCES = \
pan-tree.cc \
post-ui.cc \
prefs.cc \
+ dl-prefs.cc \
prefs-file.cc \
prefs-ui.cc \
progress-view.cc \
@@ -35,7 +36,7 @@ libpangui_a_SOURCES = \
server-ui.cc \
task-pane.cc \
xface.c \
- url.cc
+ url.cc
noinst_HEADERS = \
action-manager.h \
@@ -65,6 +66,7 @@ noinst_HEADERS = \
pan.ui.h \
pan.ui.ssl.h \
prefs.h \
+ dl-prefs.h \
prefs-file.h \
prefs-ui.h \
post-ui.h \
@@ -84,7 +86,7 @@ noinst_HEADERS = \
url.h \
wait.h \
xface.h \
- pan-colors.h
+ pan-colors.h
EXTRA_DIST = \
panrc.rc
diff --git a/pan/gui/actions.cc b/pan/gui/actions.cc
index c8e136f..1539c50 100644
--- a/pan/gui/actions.cc
+++ b/pan/gui/actions.cc
@@ -121,6 +121,7 @@ namespace pan
void do_import_tasks (GtkAction*) { pan_ui->do_import_tasks(); }
void do_cancel_latest_task (GtkAction*) { pan_ui->do_cancel_latest_task(); }
void do_show_task_window (GtkAction*) { pan_ui->do_show_task_window(); }
+ void do_show_dl_meter_prefs (GtkAction*) { pan_ui->do_show_dl_meter_prefs(); }
void do_show_log_window (GtkAction*) { pan_ui->do_show_log_window(); }
void do_quit (GtkAction*) { pan_ui->do_quit(); }
void do_clear_header_pane (GtkAction*) { pan_ui->do_clear_header_pane(); }
@@ -386,6 +387,11 @@ namespace pan
NULL,
G_CALLBACK(do_show_task_window) },
+ { "show-dl-meter-prefs", NULL,
+ N_("_Download Meter Preferences"), NULL,
+ NULL,
+ G_CALLBACK(do_show_dl_meter_prefs) },
+
{ "show-log-dialog", GTK_STOCK_DIALOG_INFO,
N_("_Event Log"), NULL,
NULL,
diff --git a/pan/gui/dl-prefs.cc b/pan/gui/dl-prefs.cc
new file mode 100644
index 0000000..5e53bb6
--- /dev/null
+++ b/pan/gui/dl-prefs.cc
@@ -0,0 +1,193 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Pan - A Newsreader for Gtk+
+ * Copyright (C) 2002-2006 Charles Kerr <charles rebelbase com>
+ *
+ * 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; version 2 of the License.
+ *
+ * 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 <config.h>
+extern "C" {
+ #include <glib/gi18n.h>
+ #include "gtk-compat.h"
+}
+#include <pan/general/debug.h>
+#include <pan/general/macros.h>
+#include <pan/icons/pan-pixbufs.h>
+#include "hig.h"
+#include "pad.h"
+#include "pan-file-entry.h"
+#include "dl-prefs.h"
+#include "url.h"
+#include "gtk-compat.h"
+
+using namespace pan;
+
+namespace pan
+{
+
+ namespace
+ {
+ #define PREFS_KEY "prefs-key"
+ #define PREFS_VAL "prefs-val"
+
+ void toggled_cb (GtkToggleButton * toggle, gpointer prefs_gpointer)
+ {
+ const char * key = (const char*) g_object_get_data (G_OBJECT(toggle), PREFS_KEY);
+ if (key)
+ static_cast<Prefs*>(prefs_gpointer)->set_flag (key, gtk_toggle_button_get_active(toggle));
+ }
+
+ GtkWidget* new_check_button (const char* mnemonic, const char* key, bool fallback, Prefs& prefs)
+ {
+ GtkWidget * t = gtk_check_button_new_with_mnemonic (mnemonic);
+ g_object_set_data_full (G_OBJECT(t), PREFS_KEY, g_strdup(key), g_free);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(t), prefs.get_flag (key, fallback));
+ g_signal_connect (t, "toggled", G_CALLBACK(toggled_cb), &prefs);
+ return t;
+ }
+
+ void response_cb (GtkDialog * dialog, int, gpointer)
+ {
+ gtk_widget_destroy (GTK_WIDGET(dialog));
+ }
+
+ void delete_dialog (gpointer castme)
+ {
+ DLMeterDialog* meterdialog(static_cast<DLMeterDialog*>(castme));
+ meterdialog->meter().dl_meter_update();
+ delete meterdialog;
+ }
+
+ void spin_value_changed_cb( GtkSpinButton *spin, gpointer data)
+ {
+ const char * key = (const char*) g_object_get_data (G_OBJECT(spin), PREFS_KEY);
+ Prefs *prefs = static_cast<Prefs*>(data);
+ prefs->set_int(key, gtk_spin_button_get_value_as_int(spin));
+ }
+
+ GtkWidget* new_spin_button (const char *key, int low, int high, Prefs &prefs)
+ {
+ guint tm = prefs.get_int(key, 5 );
+ GtkAdjustment *adj = (GtkAdjustment*) gtk_adjustment_new(tm, low, high, 1.0, 1.0, 0.0);
+ GtkWidget *w = gtk_spin_button_new( adj, 1.0, 0);
+ g_object_set_data_full(G_OBJECT(w), PREFS_KEY, g_strdup(key), g_free);
+ g_signal_connect (w, "value_changed", G_CALLBACK(spin_value_changed_cb), &prefs);
+ return w;
+ }
+
+ void set_prefs_string_from_combobox (GtkComboBox * c, gpointer user_data)
+ {
+ Prefs * prefs (static_cast<Prefs*>(user_data));
+ const char * key = (const char*) g_object_get_data (G_OBJECT(c), PREFS_KEY);
+
+ const int column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT(c), "column"));
+ const int row (gtk_combo_box_get_active (c));
+ GtkTreeModel * m = gtk_combo_box_get_model (c);
+ GtkTreeIter i;
+ if (gtk_tree_model_iter_nth_child (m, &i, 0, row)) {
+ char * val (0);
+ gtk_tree_model_get (m, &i, column, &val, -1);
+ prefs->set_string (key, val);
+ g_free (val);
+ }
+ }
+
+ GtkWidget* new_bytes_combo_box (Prefs& prefs,
+ const char * mode_key)
+ {
+
+ const char* strings[2][2] =
+ {
+ {N_("MB"), "mb"},
+ {N_("GB"), "gb"}
+ };
+
+ const std::string mode (prefs.get_string (mode_key, "mb"));
+ GtkListStore * store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
+
+ int sel_index (0);
+ for (size_t i=0; i<G_N_ELEMENTS(strings); ++i) {
+ GtkTreeIter iter;
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, strings[i][0], 1, strings[i][1], -1);
+ if (mode == strings[i][1])
+ sel_index = i;
+ }
+
+ GtkWidget * c = gtk_combo_box_new_with_model (GTK_TREE_MODEL(store));
+ GtkCellRenderer * renderer (gtk_cell_renderer_text_new ());
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (c), renderer, true);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (c), renderer, "text", 0, NULL);
+ gtk_combo_box_set_active (GTK_COMBO_BOX(c), sel_index);
+ g_object_set_data_full (G_OBJECT(c), PREFS_KEY, g_strdup(mode_key), g_free);
+ g_object_set_data (G_OBJECT(c), "column", GINT_TO_POINTER(1));
+ g_signal_connect (c, "changed", G_CALLBACK(set_prefs_string_from_combobox), &prefs);
+
+ gtk_widget_show_all(c);
+
+ return c;
+ }
+
+ void reset_dl_limit_cb (GtkButton *, gpointer user_data)
+ {
+ DLMeterDialog* pd (static_cast<DLMeterDialog*>(user_data));
+ pd->prefs().set_int ("dl-limit", 0);
+ pd->meter().dl_meter_reset ();
+ }
+
+ }
+
+ DLMeterDialog :: DLMeterDialog (Prefs& prefs, DownloadMeter& meter, GtkWindow* parent):
+ _prefs (prefs), _meter(meter)
+ {
+
+ GtkWidget * dialog = gtk_dialog_new_with_buttons (_("Pan: Download Meter Preferences"), parent,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ NULL);
+ gtk_window_set_role (GTK_WINDOW(dialog), "pan-dl-preferences-dialog");
+ g_signal_connect (dialog, "response", G_CALLBACK(response_cb), this);
+ g_signal_connect_swapped (dialog, "destroy", G_CALLBACK(delete_dialog), this);
+
+ // Behavior
+ int row (0);
+ GtkWidget *h, *w, *l, *b, *t;
+ t = HIG :: workarea_create ();
+ HIG::workarea_add_section_title (t, &row, _("Download Limit reached"));
+
+ HIG :: workarea_add_section_spacer (t, row, 2);
+ w = new_check_button (_("Warn"), "warn-dl-limit-reached", true, prefs);
+ HIG :: workarea_add_wide_control (t, &row, w);
+ w = new_check_button (_("Disconnect from server"), "disconnect-on-dl-limit-reached", true, prefs);
+ HIG :: workarea_add_wide_control (t, &row, w);
+ w = _spin = new_spin_button ("dl-limit", 1, 1024, prefs);
+ HIG :: workarea_add_wide_control (t, &row, w);
+ w = new_bytes_combo_box(prefs, "dl-limit-type");
+ HIG :: workarea_add_wide_control (t, &row, w);
+ w = gtk_button_new_with_label (_("Reset"));
+ g_signal_connect (w, "clicked", G_CALLBACK(reset_dl_limit_cb), this);
+ HIG :: workarea_add_wide_control (t, &row, w);
+
+ HIG :: workarea_finish (t, &row);
+
+ gtk_widget_show_all(t);
+
+ gtk_box_pack_start (GTK_BOX(gtk_dialog_get_content_area( GTK_DIALOG(dialog))), t, true, true, 0);
+
+ _root = dialog;
+
+ }
+
+}
diff --git a/pan/gui/dl-prefs.h b/pan/gui/dl-prefs.h
new file mode 100644
index 0000000..b642f5b
--- /dev/null
+++ b/pan/gui/dl-prefs.h
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Pan - A Newsreader for Gtk+
+ * Copyright (C) 2002-2006 Charles Kerr <charles rebelbase com>
+ *
+ * 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; version 2 of the License.
+ *
+ * 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 DL_PREFS_UI_H
+#define DL_PREFS_UI_H
+
+#include "gtk-compat.h"
+#include <pan/gui/prefs.h>
+#include <pan/data/data.h>
+
+namespace pan
+{
+
+ class DLMeterDialog
+ {
+
+ public:
+
+ public:
+ DLMeterDialog (Prefs&, DownloadMeter&, GtkWindow*) ;
+ ~DLMeterDialog () { }
+
+ Prefs& prefs () { return _prefs; }
+
+ DownloadMeter& meter () { return _meter; }
+
+ GtkWidget* root() { return _root; }
+
+ uint64_t get_limit () { return _meter.dl_meter_get_limit(); }
+
+ GtkWidget* get_enable () { return _enable; }
+
+ GtkWidget* get_spin () { return _spin; }
+
+ private:
+ Prefs& _prefs;
+ GtkWidget* _root;
+ DownloadMeter& _meter;
+ GtkWidget* _enable;
+ GtkWidget* _spin;
+
+ };
+}
+
+#endif
diff --git a/pan/gui/gui.cc b/pan/gui/gui.cc
index 528a73b..b726a06 100644
--- a/pan/gui/gui.cc
+++ b/pan/gui/gui.cc
@@ -61,6 +61,7 @@ extern "C" {
#endif
#include "prefs-ui.h"
+#include "dl-prefs.h"
#include "progress-view.h"
#include "profiles-dialog.h"
#include "post-ui.h"
@@ -178,6 +179,11 @@ void GUI :: show_task_window_cb (GtkWidget *, gpointer gui_gpointer)
static_cast<GUI*>(gui_gpointer)->activate_action ("show-task-window");
}
+void GUI :: show_download_meter_prefs_cb (GtkWidget *, gpointer gui_gpointer)
+{
+ static_cast<GUI*>(gui_gpointer)->activate_action ("show-dl-meter-prefs");
+}
+
void
GUI :: root_realized_cb (GtkWidget*, gpointer self_gpointer)
{
@@ -207,7 +213,7 @@ GUI :: root_realized_cb (GtkWidget*, gpointer self_gpointer)
}
}
-GUI :: GUI (Data& data, Queue& queue, Prefs& prefs, GroupPrefs& group_prefs):
+GUI :: GUI (Data& data, Queue& queue, Prefs& prefs, GroupPrefs& group_prefs, DownloadMeter& meter):
_data (data),
_queue (queue),
_prefs (prefs),
@@ -227,7 +233,8 @@ GUI :: GUI (Data& data, Queue& queue, Prefs& prefs, GroupPrefs& group_prefs):
_queue_size_label (0),
_queue_size_button (0),
_taskbar (0),
- _certstore(data.get_certstore())
+ _certstore(data.get_certstore()),
+ _meter(meter)
{
char * filename = g_build_filename (file::get_pan_home().c_str(), "pan.ui", NULL);
@@ -295,6 +302,16 @@ GUI :: GUI (Data& data, Queue& queue, Prefs& prefs, GroupPrefs& group_prefs):
gtk_container_add (GTK_CONTAINER(frame), w);
gtk_box_pack_start (GTK_BOX(status_bar), frame, FALSE, FALSE, 0);
+ // download meter
+ w = _meter.get_widget();
+ gtk_box_pack_start (GTK_BOX(status_bar), w, FALSE, FALSE, 0);
+ g_signal_connect (_meter.get_button(), "clicked", G_CALLBACK(show_download_meter_prefs_cb), this);
+
+ // drag and drop for message-ids
+ // gtk_drag_dest_set(_workarea_bin,GTK_DEST_DEFAULT_ALL,target_list,3,GDK_ACTION_COPY);
+ // gtk_drag_dest_add_text_targets(_workarea_bin);
+ // gtk_drag_dest_add_uri_targets(_workarea_bin);
+
// queue
w = _queue_size_label = gtk_label_new (NULL);
gtk_misc_set_padding (GTK_MISC(w), PAD, 0);
@@ -303,11 +320,6 @@ GUI :: GUI (Data& data, Queue& queue, Prefs& prefs, GroupPrefs& group_prefs):
gtk_button_set_relief (GTK_BUTTON(w), GTK_RELIEF_NONE);
g_signal_connect (w, "clicked", G_CALLBACK(show_task_window_cb), this);
- // drag and drop for message-ids
-// gtk_drag_dest_set(_workarea_bin,GTK_DEST_DEFAULT_ALL,target_list,3,GDK_ACTION_COPY);
-// gtk_drag_dest_add_text_targets(_workarea_bin);
-// gtk_drag_dest_add_uri_targets(_workarea_bin);
-
gtk_container_add (GTK_CONTAINER(w), _queue_size_label);
frame = gtk_frame_new (NULL);
gtk_container_set_border_width (GTK_CONTAINER(frame), 0);
@@ -857,6 +869,13 @@ void GUI :: do_show_task_window ()
toggle_visible (task_pane->root());
}
+void GUI :: do_show_dl_meter_prefs()
+{
+ DLMeterDialog * dialog = new DLMeterDialog (_prefs, _meter, get_window(_root));
+ g_signal_connect (dialog->root(), "destroy", G_CALLBACK(prefs_dialog_destroyed_cb), this);
+ gtk_widget_show (dialog->root());
+}
+
namespace
{
void set_bin_child (GtkWidget * w, GtkWidget * new_child)
@@ -1123,6 +1142,8 @@ void GUI :: prefs_dialog_destroyed (GtkWidget *)
}
_cache.set_max_megs(_prefs.get_int("cache-size-megs",10));
+ gtk_widget_set_visible(_meter.get_widget(), _prefs.get_flag("dl-meter-show", true));
+
}
diff --git a/pan/gui/gui.h b/pan/gui/gui.h
index ff3cfd2..b5b9633 100644
--- a/pan/gui/gui.h
+++ b/pan/gui/gui.h
@@ -32,7 +32,9 @@
#include <pan/gui/prefs.h>
#include <pan/gui/group-prefs.h>
#include <pan/gui/wait.h>
-//#include <pan/general/typedefs.h>
+#include <pan/data-impl/download-meter.h>
+
+#include <stdint.h>
#include "gtk-compat.h"
@@ -63,7 +65,7 @@ namespace pan
typedef std::vector<Quark> mid_sequence_t;
- GUI (Data& data, Queue&, Prefs&, GroupPrefs&);
+ GUI (Data& data, Queue&, Prefs&, GroupPrefs&, DownloadMeter&);
virtual ~GUI ();
GtkWidget* root () { return _root; }
typedef std::vector<std::string> strings_t;
@@ -106,6 +108,7 @@ namespace pan
virtual void do_import_tasks ();
virtual void do_cancel_latest_task ();
virtual void do_show_task_window ();
+ virtual void do_show_dl_meter_prefs();
virtual void do_show_log_window ();
virtual void do_select_all_articles ();
virtual void do_unselect_all_articles ();
@@ -239,6 +242,7 @@ namespace pan
Prefs& _prefs;
GroupPrefs& _group_prefs;
CertStore& _certstore;
+ DownloadMeter& _meter;
private:
GtkWidget * _root;
@@ -260,9 +264,12 @@ namespace pan
GtkWidget * _event_log_button;
GtkWidget * _taskbar;
std::vector<ProgressView*> _views;
+ ProgressView* _meter_view;
std::list<Task*> _active_tasks;
std::string _charset;
+ GtkWidget* _meter_button;
+
void set_charset (const StringView& v);
void upkeep ();
@@ -273,6 +280,7 @@ namespace pan
static void show_event_log_cb (GtkWidget*, gpointer);
static void show_task_window_cb (GtkWidget*, gpointer);
+ static void show_download_meter_prefs_cb (GtkWidget*, gpointer);
void score_add (int);
@@ -283,6 +291,8 @@ namespace pan
public:
BodyPane* body_pane() { return _body_pane; }
+ GtkWidget* meter_button () { return _meter_button; }
+
private:
static void add_widget (GtkUIManager*, GtkWidget*, gpointer);
static void server_list_dialog_destroyed_cb (GtkWidget*, gpointer);
diff --git a/pan/gui/pan-ui.h b/pan/gui/pan-ui.h
index fe33114..e9eca00 100644
--- a/pan/gui/pan-ui.h
+++ b/pan/gui/pan-ui.h
@@ -90,6 +90,7 @@ namespace pan
virtual void do_quit () = 0;
virtual void do_show_task_window () = 0;
+ virtual void do_show_dl_meter_prefs() = 0;
virtual void do_show_log_window () = 0;
virtual void do_show_preferences_dialog () = 0;
virtual void do_show_group_preferences_dialog () = 0;
diff --git a/pan/gui/pan.cc b/pan/gui/pan.cc
index 5eaea8c..bcc12e5 100644
--- a/pan/gui/pan.cc
+++ b/pan/gui/pan.cc
@@ -967,9 +967,7 @@ main (int argc, char *argv[])
// instantiate the queue...
WorkerPool worker_pool (4, true);
SocketCreator socket_creator(data, certstore);
- Queue queue (data, data, &socket_creator, certstore, prefs, worker_pool, false, 32768);
-
- data.set_queue (&queue);
+ Queue queue (data, data, data, data, &socket_creator, certstore, prefs, worker_pool, false, 32768);
#ifdef HAVE_DBUS
Pan pan(data, queue, cache, encode_cache, prefs, group_prefs);
@@ -1075,8 +1073,7 @@ main (int argc, char *argv[])
gtk_window_set_resizable (GTK_WINDOW(window), true);
gtk_window_set_default_icon (pixbuf);
-
- gui_ptr = new GUI (data, queue, prefs, group_prefs);
+ gui_ptr = new GUI (data, queue, prefs, group_prefs, data);
#ifdef HAVE_LIBNOTIFY
if (!notify_is_initted ())
diff --git a/pan/gui/prefs-ui.cc b/pan/gui/prefs-ui.cc
index aaa2de3..812a858 100644
--- a/pan/gui/prefs-ui.cc
+++ b/pan/gui/prefs-ui.cc
@@ -271,7 +271,6 @@ namespace pan
}
-
void save_accels()
{
@@ -995,6 +994,8 @@ PrefsDialog :: PrefsDialog (Prefs& prefs, GtkWindow* parent):
HIG :: workarea_add_section_title (t, &row, _("Task Pane"));
w = new_check_button (_("Show Task Pane info popups"), "show-taskpane-popups", true, prefs);
HIG :: workarea_add_wide_control (t, &row, w);
+ w = new_check_button (_("Show Download Meter"), "dl-meter-show", true, prefs);
+ HIG :: workarea_add_wide_control (t, &row, w);
HIG::workarea_add_section_divider (t, &row);
HIG :: workarea_finish (t, &row);
gtk_notebook_append_page (GTK_NOTEBOOK(notebook), t, new_label_with_icon(_("_Panes"), _("Panes"), icon_prefs_panes, prefs));
@@ -1290,24 +1291,15 @@ PrefsDialog :: PrefsDialog (Prefs& prefs, GtkWindow* parent):
HIG :: workarea_finish (t, &row);
- GtkWidget* scroll = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(scroll), GTK_SHADOW_IN);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(scroll), t);
+ gtk_notebook_append_page (GTK_NOTEBOOK(notebook), t, new_label_with_icon(_("_Shortcuts"), _("Shortcuts"), icon_prefs_hotkeys, prefs));
- gtk_widget_show_all (scroll);
-
- gtk_notebook_append_page (GTK_NOTEBOOK(notebook), scroll, new_label_with_icon(_("_Shortcuts"), _("Shortcuts"), icon_prefs_hotkeys, prefs));
-
- scroll = gtk_scrolled_window_new (NULL, NULL);
+ GtkWidget* scroll = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
+ GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(scroll), notebook);
- GdkScreen* screen =gdk_screen_get_default ();
+ GdkScreen* screen = gdk_screen_get_default ();
gtk_widget_set_size_request (scroll, gdk_screen_get_width(screen) - 400, gdk_screen_get_height(screen) - 200);
gtk_widget_show_all (scroll);
diff --git a/pan/gui/prefs.cc b/pan/gui/prefs.cc
index 174f76b..5d21af7 100644
--- a/pan/gui/prefs.cc
+++ b/pan/gui/prefs.cc
@@ -164,6 +164,9 @@ Prefs :: to_string (int depth, std::string& setme) const
foreach_const (ints_t, _ints, it)
out << indent(depth) << "<int name='" << escaped(it->first) << "' value='" << it->second << "'/>\n";
+ foreach_const (longs_t, _longs, it)
+ out << indent(depth) << "<long name='" << escaped(it->first) << "' value='" << it->second << "'/>\n";
+
foreach_const (strings_t, _strings, it)
out << indent(depth) << "<string name='" << escaped(it->first) << "' value='" << escaped(it->second) << "'/>\n";
@@ -298,6 +301,26 @@ Prefs :: set_int (const StringView& key, int value)
}
/***
+**** LONG64
+***/
+
+uint64_t
+Prefs :: get_long64 (const StringView& key, uint64_t fallback) const
+{
+ if (!_ints.count (key))
+ _longs[key] = fallback;
+ return _longs[key];
+}
+
+void
+Prefs :: set_long64 (const StringView& key, uint64_t value)
+{
+ _longs[key] = value;
+ fire_long64_changed (key, value);
+}
+
+
+/***
**** STRINGS
***/
diff --git a/pan/gui/prefs.h b/pan/gui/prefs.h
index 26e178b..748834a 100644
--- a/pan/gui/prefs.h
+++ b/pan/gui/prefs.h
@@ -29,6 +29,10 @@
#include <pan/gui/pan-colors.h>
#include "gtk-compat.h"
+extern "C" {
+ #include <stdint.h>
+}
+
namespace pan
{
/**
@@ -45,6 +49,7 @@ namespace pan
virtual void on_prefs_string_changed (const StringView& key, const StringView& value) = 0;
virtual void on_prefs_color_changed (const StringView& key, const GdkColor& color) = 0;
virtual void on_prefs_hotkey_changed (const StringView& key, const StringView& value) {}
+ virtual void on_prefs_long64_changed(const StringView& key, const uint64_t& value) {}
};
void add_listener (Listener* l) { _listeners.insert(l); }
void remove_listener (Listener* l) {_listeners.erase(l); }
@@ -62,6 +67,10 @@ namespace pan
for (listeners_t::iterator it(_listeners.begin()), end(_listeners.end()); it!=end; )
(*it++)->on_prefs_int_changed (key, value);
}
+ void fire_long64_changed (const StringView& key, uint64_t value) {
+ for (listeners_t::iterator it(_listeners.begin()), end(_listeners.end()); it!=end; )
+ (*it++)->on_prefs_long64_changed (key, value);
+ }
void fire_string_changed (const StringView& key, const StringView& value) {
for (listeners_t::iterator it(_listeners.begin()), end(_listeners.end()); it!=end; )
(*it++)->on_prefs_string_changed (key, value);
@@ -86,10 +95,14 @@ namespace pan
public:
bool get_flag (const StringView& key, bool fallback) const;
void set_flag (const StringView& key, bool);
+
int get_int (const StringView& key, int fallback) const;
int get_int_min (const StringView& key, int fallback) const;
void set_int (const StringView& key, int);
+ uint64_t get_long64 (const StringView& key, uint64_t fallback) const;
+ void set_long64 (const StringView& key, uint64_t value);
+
std::string get_string (const StringView& key, const StringView& fallback) const;
void set_string (const StringView& key, const StringView&);
@@ -137,6 +150,8 @@ namespace pan
mutable colors_t _colors;
typedef std::map<std::string,int> ints_t;
mutable ints_t _ints;
+ typedef std::map<std::string,uint64_t> longs_t;
+ mutable longs_t _longs;
public:
colors_t& get_colors() { return _colors; }
diff --git a/pan/gui/progress-view.cc b/pan/gui/progress-view.cc
index e7f745a..e6167c3 100644
--- a/pan/gui/progress-view.cc
+++ b/pan/gui/progress-view.cc
@@ -129,3 +129,19 @@ ProgressView :: update_text_soon ()
if (!_progress_status_idle_tag)
_progress_status_idle_tag = g_timeout_add (333, on_progress_status_idle, this);
}
+
+void ProgressView :: set_color (const std::string& color)
+{
+ GtkStyle* style = gtk_style_new ();
+ gdk_color_parse (color.c_str(), &style->bg[GTK_STATE_PRELIGHT]);
+ gtk_widget_set_style (_progressbar, style);
+ g_object_unref (style);
+
+}
+
+void ProgressView :: reset_color ()
+{
+ GtkStyle* style = gtk_style_new ();
+ gtk_widget_set_style (_progressbar, style);
+ g_object_unref (style);
+}
diff --git a/pan/gui/progress-view.h b/pan/gui/progress-view.h
index 5449f90..e0debbb 100644
--- a/pan/gui/progress-view.h
+++ b/pan/gui/progress-view.h
@@ -43,6 +43,8 @@ namespace pan
void set_progress (Progress *);
Progress* get_progress () { return _progress; }
const Progress* get_progress () const { return _progress; }
+ void set_color (const std::string& color);
+ void reset_color ();
private: // inherited from progress listener
virtual void on_progress_step (Progress&, int percentage);
@@ -63,6 +65,7 @@ namespace pan
GtkWidget * _progressbar;
std::string _last_status;
Progress * _progress;
+
};
}
diff --git a/pan/tasks/nntp-pool.cc b/pan/tasks/nntp-pool.cc
index 17a7c09..4b06e4c 100644
--- a/pan/tasks/nntp-pool.cc
+++ b/pan/tasks/nntp-pool.cc
@@ -41,7 +41,8 @@ NNTP_Pool :: NNTP_Pool (const Quark & server,
ServerInfo & server_info,
Prefs & prefs,
SocketCreator * creator,
- CertStore & store):
+ CertStore & store,
+ DownloadMeter & meter):
_server_info (server_info),
_prefs (prefs),
@@ -50,7 +51,8 @@ NNTP_Pool :: NNTP_Pool (const Quark & server,
_pending_connections (0),
_active_count (0),
_time_to_allow_new_connections (0),
- _certstore(store)
+ _certstore(store),
+ _meter(meter)
{
}
@@ -191,11 +193,11 @@ NNTP_Pool :: on_socket_created (const StringView & host,
{
std::string pw (pass ? pass : "");
if (pass) g_free(pass);
- nntp = new NNTP (_server, user, pw, socket);
+ nntp = new NNTP (_server, user, pw, _meter, socket);
}
else
{
- nntp = new NNTP (_server, user, pass, socket);
+ nntp = new NNTP ( _server, user, pass, _meter, socket);
}
nntp->handshake (this);
}
diff --git a/pan/tasks/nntp-pool.h b/pan/tasks/nntp-pool.h
index 7399b72..6bd78b1 100644
--- a/pan/tasks/nntp-pool.h
+++ b/pan/tasks/nntp-pool.h
@@ -28,9 +28,10 @@
#include <pan/tasks/nntp.h>
#include <pan/tasks/socket-impl-main.h>
#include <pan/gui/prefs.h>
+#include <pan/data/data.h>
#ifdef HAVE_GNUTLS
-#include <pan/data/cert-store.h>
+ #include <pan/data/cert-store.h>
#endif
namespace pan {
@@ -48,7 +49,7 @@ class NNTP_Pool: public NNTP::Source,
public:
NNTP_Pool(const Quark & server, ServerInfo & server_info, Prefs& prefs, SocketCreator *,
- CertStore &);
+ CertStore &, DownloadMeter& meter);
virtual ~NNTP_Pool();
virtual void check_in(NNTP*, Health);
@@ -87,10 +88,8 @@ private:
private:
// Socket::Creator::Listener
- virtual void on_socket_created(const StringView& host, int port, bool ok,
- Socket*);
- virtual void on_socket_shutdown(const StringView& host, int port, Socket*) {
- }
+ virtual void on_socket_created(const StringView& host, int port, bool ok, Socket*);
+ virtual void on_socket_shutdown(const StringView& host, int port, Socket*) {}
#ifdef HAVE_GNUTLS
private:
// CertStore::Listener
@@ -116,6 +115,7 @@ private:
int _pending_connections;
CertStore& _certstore;
Prefs& _prefs;
+ DownloadMeter& _meter;
struct PoolItem {
NNTP * nntp;
diff --git a/pan/tasks/nntp.cc b/pan/tasks/nntp.cc
index fc6b560..cf426c4 100644
--- a/pan/tasks/nntp.cc
+++ b/pan/tasks/nntp.cc
@@ -265,6 +265,12 @@ NNTP :: on_socket_error (Socket * sock UNUSED)
fire_done_func (ERR_NETWORK, StringView());
}
+void
+NNTP :: on_socket_bytes_transferred (uint64_t bytes, Socket*)
+{
+ _meter.dl_meter_add (bytes);
+}
+
namespace
{
void
diff --git a/pan/tasks/nntp.h b/pan/tasks/nntp.h
index c74ae06..95b3ea1 100644
--- a/pan/tasks/nntp.h
+++ b/pan/tasks/nntp.h
@@ -27,6 +27,7 @@
#include <pan/general/string-view.h>
#include <pan/tasks/health.h>
#include <pan/tasks/socket.h>
+#include <pan/data/data.h>
namespace
{
@@ -137,7 +138,8 @@ namespace pan
const Quark & group UNUSED,
unsigned long estimated_qty UNUSED,
uint64_t low UNUSED,
- uint64_t high UNUSED) {}
+ uint64_t high
+ UNUSED) {}
};
@@ -146,8 +148,10 @@ namespace pan
NNTP (const Quark & server,
const std::string & username,
const std::string & password,
- Socket * socket):
+ DownloadMeter & meter,
+ Socket * socket):
_server(server),
+ _meter(meter),
_socket(socket),
_socket_error(false),
_listener(0),
@@ -305,6 +309,7 @@ namespace pan
Quark _group;
Quark _request_group;
Socket * _socket;
+ DownloadMeter& _meter;
bool _socket_error;
protected:
@@ -331,6 +336,7 @@ namespace pan
virtual bool on_socket_response (Socket*, const StringView& line);
virtual void on_socket_error (Socket*);
virtual void on_socket_abort (Socket*);
+ virtual void on_socket_bytes_transferred (uint64_t bytes, Socket*) ;
public:
diff --git a/pan/tasks/queue.cc b/pan/tasks/queue.cc
index cab893f..a9a59c8 100644
--- a/pan/tasks/queue.cc
+++ b/pan/tasks/queue.cc
@@ -35,6 +35,8 @@ using namespace pan;
Queue :: Queue (ServerInfo & server_info,
TaskArchive & archive,
+ Data & data,
+ DownloadMeter & meter,
SocketCreator * socket_creator,
CertStore & certstore,
Prefs & prefs,
@@ -54,11 +56,15 @@ Queue :: Queue (ServerInfo & server_info,
_needs_saving (false),
_last_time_saved (0),
_archive (archive),
+ _meter (meter),
_certstore(certstore),
_uploads_total(0),
_downloads_total(0)
{
+ data.set_queue(this);
+ meter.add_listener(this);
+
tasks_t tasks;
_archive.load_tasks (tasks);
add_tasks (tasks, BOTTOM);
@@ -69,6 +75,7 @@ Queue :: Queue (ServerInfo & server_info,
Queue :: ~Queue ()
{
_tasks.remove_listener (this);
+ _meter.remove_listener(this);
foreach (pools_t, _pools, it)
delete it->second;
@@ -106,7 +113,7 @@ Queue :: get_pool (const Quark& servername)
}
else // have to build one
{
- pool = new NNTP_Pool (servername, _server_info, _prefs, _socket_creator, _certstore);
+ pool = new NNTP_Pool (servername, _server_info, _prefs, _socket_creator, _certstore, _meter);
pool->add_listener (this);
_pools[servername] = pool;
}
@@ -979,3 +986,14 @@ Queue :: get_stats (unsigned long & queued_count,
}
}
+void
+Queue :: on_dl_limit_reached ()
+{
+ set_online (false);
+}
+
+void
+Queue :: on_reset_xfer_bytes ()
+{
+ set_online (true);
+}
diff --git a/pan/tasks/queue.h b/pan/tasks/queue.h
index 04e3b8a..de3be6b 100644
--- a/pan/tasks/queue.h
+++ b/pan/tasks/queue.h
@@ -36,6 +36,7 @@
#include <pan/tasks/task-weak-ordering.h>
#include <pan/tasks/socket-impl-main.h>
#include <pan/gui/prefs.h>
+#include <pan/data/data.h>
#ifdef HAVE_GNUTLS
#include <pan/data/cert-store.h>
@@ -72,10 +73,11 @@ namespace pan
public Task::DecoderSource,
public Task::EncoderSource,
private NNTP_Pool::Listener,
- private AdaptableSet<Task*, TaskWeakOrdering>::Listener
+ private AdaptableSet<Task*, TaskWeakOrdering>::Listener,
+ private DownloadMeter::Listener
{
public:
- Queue (ServerInfo&, TaskArchive&, SocketCreator*, CertStore&, Prefs&, WorkerPool&,
+ Queue (ServerInfo&, TaskArchive&, Data&, DownloadMeter&, SocketCreator*, CertStore&, Prefs&, WorkerPool&,
bool online, int save_delay_secs);
virtual ~Queue ();
@@ -255,6 +257,7 @@ namespace pan
int _uploads_total, _downloads_total;
CertStore& _certstore;
Prefs& _prefs;
+ DownloadMeter& _meter;
private:
typedef AdaptableSet<Task*, TaskWeakOrdering> TaskSet;
@@ -262,6 +265,12 @@ namespace pan
virtual void on_set_items_added (TaskSet&, TaskSet::items_t&, int index);
virtual void on_set_item_removed (TaskSet&, Task*&, int index);
virtual void on_set_item_moved (TaskSet&, Task*&, int index, int old_index);
+
+ public:
+
+ virtual void on_xfer_bytes (uint64_t) {}
+ virtual void on_reset_xfer_bytes () ;
+ virtual void on_dl_limit_reached () ;
};
}
diff --git a/pan/tasks/socket-impl-gio.cc b/pan/tasks/socket-impl-gio.cc
index fb2eb36..69e7456 100644
--- a/pan/tasks/socket-impl-gio.cc
+++ b/pan/tasks/socket-impl-gio.cc
@@ -336,6 +336,7 @@ GIOChannelSocket :: do_read ()
if (g_str_has_suffix (g->str, "\r\n"))
g_string_truncate (g, g->len-2);
more = _listener->on_socket_response (this, StringView (g->str, g->len));
+ _listener->on_socket_bytes_transferred(g->len, this);
}
else if (status == G_IO_STATUS_AGAIN)
{
diff --git a/pan/tasks/socket-impl-openssl.cc b/pan/tasks/socket-impl-openssl.cc
index 5a15436..390b0f2 100644
--- a/pan/tasks/socket-impl-openssl.cc
+++ b/pan/tasks/socket-impl-openssl.cc
@@ -618,6 +618,7 @@ GIOChannelSocketGnuTLS :: do_read ()
if (g_str_has_suffix (g->str, "\r\n"))
g_string_truncate (g, g->len-2);
more = _listener->on_socket_response (this, StringView (g->str, g->len));
+ _listener->on_socket_bytes_transferred(g->len, this);
}
else if (status == G_IO_STATUS_AGAIN)
{
diff --git a/pan/tasks/socket.h b/pan/tasks/socket.h
index 6947229..af26a62 100644
--- a/pan/tasks/socket.h
+++ b/pan/tasks/socket.h
@@ -23,6 +23,10 @@
#include <string>
#include <config.h>
+extern "C" {
+ #include <stdint.h>
+}
+
#ifdef HAVE_GNUTLS
#include <gnutls/gnutls.h>
#endif
@@ -30,6 +34,7 @@
namespace pan
{
class StringView;
+ class Quark;
class WorkerPool;
class Data;
@@ -49,9 +54,11 @@ namespace pan
/** Interface class for objects that listen to a Socket's events */
struct Listener {
virtual ~Listener () {}
+
virtual bool on_socket_response (Socket*, const StringView& line) = 0;
virtual void on_socket_error (Socket*) = 0;
virtual void on_socket_abort (Socket*) = 0;
+ virtual void on_socket_bytes_transferred (uint64_t bytes, Socket*) = 0;
};
public:
@@ -90,7 +97,7 @@ namespace pan
virtual ~Listener () {}
virtual void on_socket_created (const StringView& host, int port, bool ok, Socket*) = 0;
virtual void on_socket_shutdown (const StringView& host, int port, Socket*) = 0;
- };
+ };
virtual ~Creator () { }
virtual void create_socket (Data&, const StringView& host, int port, WorkerPool&, Listener*, bool) = 0;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]