[pan2/download-meter] intermediate



commit 4506bcfc5ed2eb64fa69255c5fcbbddfa7f85aca
Author: Heinrich MÃller <henmull src gnome org>
Date:   Tue Sep 25 17:35:42 2012 +0200

    intermediate

 pan.cbp                    |    2 +
 pan/data-impl/data-impl.cc |   45 +++++++++++++-
 pan/data-impl/data-impl.h  |   20 ++++++
 pan/data-impl/data-io.cc   |   18 ++++++
 pan/data-impl/data-io.h    |    2 +
 pan/data/data.h            |   11 +++
 pan/general/progress.h     |    2 +-
 pan/gui/Makefile.am        |    2 +
 pan/gui/actions.cc         |    6 ++
 pan/gui/download-meter.cc  |  145 +++++++++++++++++++++++++++++++++++++++++---
 pan/gui/gui.cc             |   36 ++++++++---
 pan/gui/gui.h              |    8 +++
 pan/gui/pan-ui.h           |    1 +
 pan/gui/pan.cc             |    3 +-
 14 files changed, 279 insertions(+), 22 deletions(-)
---
diff --git a/pan.cbp b/pan.cbp
index 704b4b4..8476cb7 100644
--- a/pan.cbp
+++ b/pan.cbp
@@ -161,6 +161,8 @@
 		<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/download-meter.cc" />
+		<Unit filename="pan/gui/download-meter.h" />
 		<Unit filename="pan/gui/e-action-combo-box.c">
 			<Option compilerVar="CC" />
 		</Unit>
diff --git a/pan/data-impl/data-impl.cc b/pan/data-impl/data-impl.cc
index 30cadfc..d24cdf5 100644
--- a/pan/data-impl/data-impl.cc
+++ b/pan/data-impl/data-impl.cc
@@ -104,6 +104,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 +117,6 @@ DataImpl :: rebuild_backend ()
 DataImpl :: ~DataImpl ()
 {
   save_state ();
-
 }
 
 void
@@ -127,6 +127,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 +180,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;
+    }
+  }
+
+  _downloaded_bytes = 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 << _downloaded_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..d48bb16 100644
--- a/pan/data-impl/data-impl.h
+++ b/pan/data-impl/data-impl.h
@@ -689,6 +689,26 @@ namespace pan
         newsrc_autosave_id = 0;
       }
 
+    /**
+    ***  Download stats
+    **/
+    public:
+
+      void load_download_stats (const DataIO&);
+      void save_download_stats (DataIO&) const;
+
+    private:
+
+      uint64_t _downloaded_bytes;
+
+    public:
+
+      void inc_downloaded_bytes(uint64_t bytes) { _downloaded_bytes += bytes; }
+
+      uint64_t get_download_bytes() { return _downloaded_bytes; }
+
+      void reset_downloaded_bytes() { _downloaded_bytes = 0ul; }
+
   };
 }
 
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/data.h b/pan/data/data.h
index 7d4f4a8..ccea035 100644
--- a/pan/data/data.h
+++ b/pan/data/data.h
@@ -668,6 +668,17 @@ namespace pan
                                    const Quark         & server,
                                    const uint64_t   low) = 0;
 
+
+       /** Get downloaded bytes so far */
+       virtual void inc_downloaded_bytes (uint64_t) = 0;
+
+       /** Reset downloaded bytes so far */
+       virtual void reset_downloaded_bytes() = 0;
+
+       virtual uint64_t get_download_bytes() = 0;
+
+
+
   };
 }
 
diff --git a/pan/general/progress.h b/pan/general/progress.h
index 37d9365..31b83a7 100644
--- a/pan/general/progress.h
+++ b/pan/general/progress.h
@@ -75,7 +75,7 @@ namespace pan
       int _steps; // number of steps total
       int _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 93673f5..4920eb8 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 \
@@ -66,6 +67,7 @@ noinst_HEADERS = \
  pan.ui.h \
  pan.ui.ssl.h \
  prefs.h \
+ dl-prefs.h \
  prefs-file.h \
  prefs-ui.h \
  post-ui.h \
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/download-meter.cc b/pan/gui/download-meter.cc
index 09d3ff5..d16eebf 100644
--- a/pan/gui/download-meter.cc
+++ b/pan/gui/download-meter.cc
@@ -21,27 +21,143 @@
 #include "download-meter.h"
 #include <iostream>
 
+extern "C" {
+  #include <glib/gi18n.h>
+}
+
 using namespace pan;
 
-DownloadMeter :: DownloadMeter (Prefs& prefs) : _val(0ul), _view(new ProgressView()), _progress(new Progress("Downloaded bytes"))
+namespace
 {
 
-  const uint64_t MAX_BYTES (1024*1024*1024*42); // 42 GB
+  int type_idx (0); // mb = 0, gb = 1
+  int ptr(0);
+
+}
+
+DownloadMeter :: DownloadMeter (Prefs& prefs, Data& data) :
+                _view(new ProgressView()),
+                _progress(new Progress("Downloaded bytes")),
+                _enabled(prefs.get_flag("dl-limit-enable", true))
+
+{
+
+  std::string limit_type (prefs.get_string("dl-limit-type", ""));
+
+  if (limit_type == "")
+      type_idx = -1;
+  if (limit_type == "mb")
+      type_idx = 0;
+  if (limit_type == "gb")
+      type_idx = 1;
+
+  const int MAX_BYTES (1024); // 42 GB
+
+  reset();
 
   _view->set_progress(_progress);
-  _progress->add_steps (prefs.get_long64("dl-limit", MAX_BYTES));
-  _progress->set_status_va("Downloaded bytes (%lu)", 0);
+  int limit (prefs.get_int("dl-limit", MAX_BYTES));
+  set_limit (limit);
+  _progress->add_steps (limit);
+
+  add (data.get_downloaded_bytes());
+
+  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);
+
+}
+
+namespace
+{
+
+  void scale(uint64_t* range, Progress* progress)
+  {
+
+    ptr = 0;
+    for (int i=0;i<4;++i)
+    {
+      int idx (0);
+      uint64_t times = range[i] / 1024;
+      uint64_t rest = range[i] % 1024;
+      if (times != 0)
+      {
+
+        if (i == type_idx)
+        {
+          progress->increment_step(times);
+        }
+
+        range[i] = rest;
+        range[i+1] += times;
+      }
+    }
+    for (int i=4;i>0;--i)
+    {
+      std::cerr<<range[i]<<" ";
+
+      if (range[i] != 0)
+      {
+        ptr = i; // pointer to current mnemonic (field != 0)
+        break;
+      }
+    }
+    std::cerr<<"\n";
+  }
+
+  std::string mnemonic()
+  {
+    std::string ret;
+
+    switch (ptr)
+    {
+      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;
+  }
+
+  float to_float(uint64_t* vals)
+  {
+    if (ptr>0)
+    {
+      float ret = (float) vals[ptr];
+      ret += vals[ptr-1] / 1024.0f;
+      return ret;
+    }
+    return (float) vals[0];
+  }
+
 }
 
 void
 DownloadMeter :: add (uint64_t bytes)
 {
-  if (bytes > 0)
   {
-    _val += bytes;
+    _val[0] += bytes;
+    scale (_val, _progress);
     fire_xfer_bytes(bytes);
-    _progress->increment_step(bytes);
-    _progress->set_status_va("Downloaded bytes (%lu)", _val);
+    _progress->set_status_va("DL %.2f %s", to_float(_val), mnemonic().c_str());
   }
 
 }
@@ -49,7 +165,18 @@ DownloadMeter :: add (uint64_t bytes)
 void
 DownloadMeter :: reset ()
 {
-  _val = 0ul;
+  for (int i=0;i<5;++i) _val[i] = 0ul;
+  add(0ul);
+
+  fire_reset_xfer_bytes ();
+}
+
+
+void
+DownloadMeter :: fire_reset_xfer_bytes ()
+{
+  for (lit it(_listeners.begin()), end(_listeners.end()); it!=end; )
+    (*it++)->on_reset_xfer_bytes ();
 }
 
 void
diff --git a/pan/gui/gui.cc b/pan/gui/gui.cc
index 8470370..41feee0 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)
 {
@@ -297,9 +303,14 @@ GUI :: GUI (Data& data, Queue& queue, Prefs& prefs, GroupPrefs& group_prefs, Dow
   gtk_box_pack_start (GTK_BOX(status_bar), frame, FALSE, FALSE, 0);
 
   // download meter
-  w = _meter.get_view()->root();
-  gtk_box_pack_start (GTK_BOX(status_bar), w, false, true, 0);
-  gtk_widget_set_size_request (w, 250, -1);
+  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);
@@ -309,11 +320,6 @@ GUI :: GUI (Data& data, Queue& queue, Prefs& prefs, GroupPrefs& group_prefs, Dow
   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);
@@ -865,6 +871,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)
@@ -995,7 +1008,12 @@ void GUI :: on_progress_finished (Progress & p, int status)
 
 void GUI :: on_xfer_bytes (unsigned long bytes)
 {
-  // TODO : perhaps some code for prefs / UI interaction??
+  _data.inc_downloaded_bytes (bytes);
+}
+
+void GUI :: on_reset_xfer_bytes (unsigned long bytes)
+{
+  _data.reset_downloaded_bytes();
 }
 
 void GUI :: do_read_selected_article ()
diff --git a/pan/gui/gui.h b/pan/gui/gui.h
index fcc74b2..677da4b 100644
--- a/pan/gui/gui.h
+++ b/pan/gui/gui.h
@@ -34,6 +34,8 @@
 #include <pan/gui/wait.h>
 #include <pan/gui/download-meter.h>
 
+#include <stdint.h>
+
 #include "gtk-compat.h"
 
 namespace pan
@@ -107,6 +109,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 ();
@@ -269,6 +272,8 @@ namespace pan
       std::list<Task*> _active_tasks;
       std::string _charset;
 
+      GtkWidget* _meter_button;
+
       void set_charset (const StringView& v);
 
       void upkeep ();
@@ -279,6 +284,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);
 
@@ -289,6 +295,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 8c6cc54..0d284c9 100644
--- a/pan/gui/pan.cc
+++ b/pan/gui/pan.cc
@@ -967,7 +967,7 @@ main (int argc, char *argv[])
     // instantiate the queue...
     WorkerPool worker_pool (4, true);
     SocketCreator socket_creator(data, certstore);
-    DownloadMeter meter;
+    DownloadMeter meter (prefs, data);
     Queue queue (data, data, &socket_creator, certstore, prefs, worker_pool, meter, false, 32768);
 
     data.set_queue (&queue);
@@ -1076,7 +1076,6 @@ 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, meter);
 
 #ifdef HAVE_LIBNOTIFY



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