[pan2/testing: 64/279] filequeue debugging, added icons and context menu popup TODO: - constify some things - perhaps emp



commit 6ec6bc0da7b5b39a465502f776ba946fe8ea8d48
Author: Heinrich MÃller <sphemuel stud informatik uni-erlangen de>
Date:   Sat May 28 12:44:35 2011 +0200

    filequeue debugging, added icons and context menu popup
    TODO:
     - constify some things
     - perhaps employ Task* in TreeView (??):
       * The Tasks could be started paused and then fired up by the destroy callback of the PostUI dialog
       * FileQueue would be gone and we could use the implemented queue functions for movement of the
         files in the queue
     - let Treeview do move actions
     - error correction with NNTP responses (network errors etc...)

 pan/data/file-queue.cc   |   47 ++++++-----
 pan/data/file-queue.h    |   15 +++-
 pan/gui/actions.cc       |    6 --
 pan/gui/group-pane.cc    |   10 +-
 pan/gui/pan.ui.h         |    5 -
 pan/gui/post-ui.cc       |  203 +++++++++++++++++++++++++++++++++++++++-------
 pan/gui/post-ui.h        |   26 ++++--
 pan/gui/post.ui.h        |   13 +++
 pan/tasks/encoder.cc     |   33 ++++----
 pan/tasks/task-upload.cc |  107 +++++++++++++++---------
 pan/tasks/task-upload.h  |    5 +-
 11 files changed, 330 insertions(+), 140 deletions(-)
---
diff --git a/pan/data/file-queue.cc b/pan/data/file-queue.cc
index 872e807..e591a52 100644
--- a/pan/data/file-queue.cc
+++ b/pan/data/file-queue.cc
@@ -58,27 +58,14 @@ FileQueue :: add (const char* filename,
     _articles_v.push_front(a);
 }
 
-namespace
-{
-  struct FileNameEqual : public std::binary_function
-                         < std::string, std::string,bool >
-
-  {
-    bool operator() (std::string a, std::string b) {return (a==b);}
-  };
-}
-
 void
 FileQueue :: remove(const articles_v& no)
 {
-  std::cerr<<"delete len "<<no.size()<<std::endl;
-
   articles_const_it it = no.begin();
   articles_it vit;
-  for ( ; it != no.end(); ++it) {
-    for ( vit = _articles_v.begin() ; vit != _articles_v.end(); ++vit) {
-      if (vit->filename == it->filename) {
-        std::cerr<<"deleting "<<it->filename<<std::endl;
+  for ( vit = _articles_v.begin() ; vit != _articles_v.end(); ++vit) {
+    for ( ; it != no.end(); ++it) {
+      if (vit->filename.compare(it->filename)==0) {
         vit = _articles_v.erase(vit);
       }
     }
@@ -86,29 +73,45 @@ FileQueue :: remove(const articles_v& no)
 }
 
 void
-FileQueue :: move_up(const articles_v& no)
+FileQueue :: move_up(const articles_v& no, int pos)
 {
+  if (size()==1) return;
+  articles_it it;
+  for (it = _articles_v.begin(); it != _articles_v.end(); ++it)
+  {
 
+  }
 }
 
 void
-FileQueue :: move_down(const articles_v& no)
+FileQueue :: move_down(const articles_v& no, int pos)
 {
+  if (size()==1) return;
+    articles_it it;
+  for (it = _articles_v.begin(); it != _articles_v.end(); ++it)
+  {
 
+  }
 }
 
 void
 FileQueue :: move_top(const articles_v& no)
 {
-
-//    foreach_const(articles_v, no, it)
-
+  if (size()==1) return;
+//  remove(no);
+//  articles_r_it rit;
+//  for ( rit=no.rbegin() ; rit != no.rend(); ++rit )
+//    _articles_v.push_front(*rit);
 }
 
 void
 FileQueue :: move_bottom(const articles_v& no)
 {
-
+  if (size()==1) return;
+//  remove(no);
+//  articles_const_it it;
+//  for ( it= no.begin() ; it != no.end(); ++it )
+//    _articles_v.push_back(*it);
 }
 
 
diff --git a/pan/data/file-queue.h b/pan/data/file-queue.h
index 04229c7..d7cf13d 100644
--- a/pan/data/file-queue.h
+++ b/pan/data/file-queue.h
@@ -49,17 +49,24 @@ namespace pan {
           std::string filename;
           std::string basename;
           unsigned long    byte_count;
-          FileData() {}
+          bool all_parts;
+          std::set<int> parts;
+          FileData() { all_parts = true; }
         };
 
         typedef std::list<FileData>::const_iterator articles_const_it;
         typedef std::list<FileData>::iterator articles_it;
+        typedef std::list<FileData>::reverse_iterator articles_r_it;
         typedef std::list<FileData> articles_v;
 
      size_t size() { return _articles_v.size(); }
      articles_it end() { return _articles_v.end(); }
      articles_it begin() { return _articles_v.begin(); }
-     const articles_v& get_files() const { return _articles_v; }
+     //todo const
+     articles_v& get_files() { return _articles_v; }
+
+     void clear() { _articles_v.clear(); }
+
      bool empty() { return _articles_v.empty(); }
 
      public:
@@ -73,8 +80,8 @@ namespace pan {
 
       void remove(const articles_v& no);
 
-      void move_up(const articles_v& no);
-      void move_down(const articles_v& no);
+      void move_up(const articles_v& no, int pos);
+      void move_down(const articles_v& no, int pos);
       void move_top(const articles_v& no);
       void move_bottom(const articles_v& no);
 
diff --git a/pan/gui/actions.cc b/pan/gui/actions.cc
index af3ad55..3bbdd63 100644
--- a/pan/gui/actions.cc
+++ b/pan/gui/actions.cc
@@ -459,12 +459,6 @@ namespace
       N_("Read More"),
       G_CALLBACK(do_read_more) },
 
-    // todo icon, move!
-//    { "binpost", "ICON_READ_MORE",
-//      N_("Post binary files"), "space",
-//      N_("Post binary files"),
-//      G_CALLBACK(do_binpost) },
-
     { "read-less", "ICON_READ_LESS",
       N_("Read _Back"), "BackSpace",
       N_("Read Back"),
diff --git a/pan/gui/group-pane.cc b/pan/gui/group-pane.cc
index e0a5df0..a7e55e2 100644
--- a/pan/gui/group-pane.cc
+++ b/pan/gui/group-pane.cc
@@ -148,7 +148,7 @@ void
 GroupPane ::  do_popup_menu (GtkWidget*, GdkEventButton *event, gpointer pane_g)
 {
   GroupPane * self (static_cast<GroupPane*>(pane_g));
-  GtkWidget * menu (self->_action_manager.get_action_widget ("/group-pane-popup"));
+  GtkWidget * menu (self->_action_manager.get_action_widget ("/filequeue-popup"));
   gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL,
                   (event ? event->button : 0),
                   (event ? event->time : 0));
@@ -214,7 +214,7 @@ namespace
     blah->path = path;
     blah->col = col;
     g_idle_add (maybe_activate_on_idle_idle, blah);
-  } 
+  }
 }
 
 gboolean
@@ -342,8 +342,8 @@ namespace
     headers[0].groupname = *sub_title_quark;
     headers[1].groupname = *other_title_quark;
     g_object_weak_ref (G_OBJECT(store), delete_rows, headers);
- 
-    // 
+
+    //
     //  subscribed
     //
 
@@ -427,7 +427,7 @@ GroupPane :: on_group_subscribe (const Quark& groupname, bool sub)
       ++pos;
     } while (gtk_tree_model_iter_next (model, &group_iter));
   }
-  
+
   // move the row
   _tree_store->reparent (_tree_store->get_row(&section_iter), find_row(groupname), pos);
 
diff --git a/pan/gui/pan.ui.h b/pan/gui/pan.ui.h
index 91aecac..a8c4a6c 100644
--- a/pan/gui/pan.ui.h
+++ b/pan/gui/pan.ui.h
@@ -74,7 +74,6 @@ const char * fallback_ui_file =
 "      </menu>\n"
 "    </menu>\n"
 "    <menu action='go-menu'>\n"
-//"      <menuitem action='binpost' />\n"
 "      <menuitem action='read-more' />\n"
 "      <menuitem action='read-less' />\n"
 "      <separator />\n"
@@ -91,9 +90,6 @@ const char * fallback_ui_file =
 "      <menuitem action='read-next-thread' />\n"
 "      <menuitem action='read-previous-thread' />\n"
 "    </menu>\n"
-//"    <menu action='actions-menu'>\n"
-//"      <menuitem action='save-articles' />\n"
-//"      <separator />\n"
 "      <menu action='group-actions-menu'>\n"
 "        <menuitem action='read-selected-group' />\n"
 "        <menuitem action='mark-groups-read' />\n"
@@ -158,7 +154,6 @@ const char * fallback_ui_file =
 "    <toolitem action='post'/>\n"
 "    <toolitem action='followup-to'/>\n"
 "    <separator />\n"
-//"    <toolitem action='binpost' />\n"
 "    <toolitem action='read-more' />\n"
 "    <toolitem action='read-next-unread-article' />\n"
 "    <toolitem action='read-next-unread-thread' />\n"
diff --git a/pan/gui/post-ui.cc b/pan/gui/post-ui.cc
index a8c65ee..d778284 100644
--- a/pan/gui/post-ui.cc
+++ b/pan/gui/post-ui.cc
@@ -221,6 +221,53 @@ namespace
     { "add-files", GTK_STOCK_OPEN, N_("Add _Files to Queue"), "<control>O", N_("Add Files to Queue"), G_CALLBACK(do_add_files) },
   };
 
+  void do_remove_files       (GtkAction*, gpointer p) { static_cast<PostUI*>(p)->remove_files(); }
+  void do_clear_list         (GtkAction*, gpointer p) { static_cast<PostUI*>(p)->clear_list(); }
+  void do_select_parts       (GtkAction*, gpointer p) { static_cast<PostUI*>(p)->select_parts(); }
+  void do_move_up            (GtkAction*, gpointer p) { static_cast<PostUI*>(p)->move_up(); }
+  void do_move_down          (GtkAction*, gpointer p) { static_cast<PostUI*>(p)->move_down(); }
+  void do_move_top           (GtkAction*, gpointer p) { static_cast<PostUI*>(p)->move_top(); }
+  void do_move_bottom        (GtkAction*, gpointer p) { static_cast<PostUI*>(p)->move_bottom(); }
+
+  GtkActionEntry filequeue_popup_entries[] =
+  {
+
+    { "remove-files", NULL,
+      N_("Remove from Queue"), "",
+      N_("Remove from Queue"),
+      G_CALLBACK(do_remove_files) },
+
+    { "clear-list", NULL,
+      N_("Clear List"), "",
+      N_("Clear List"),
+      G_CALLBACK(do_clear_list) },
+
+    { "select-parts", NULL,
+      N_("Select needed Parts"), "",
+      N_("Select needed Parts"),
+      G_CALLBACK(do_select_parts) },
+
+    { "move-up", NULL,
+      N_("Move Up"), "",
+      N_("Move Up"),
+      G_CALLBACK(do_move_up) },
+
+    { "move-down", NULL,
+      N_("Move Down"), "",
+      N_("Move Down"),
+      G_CALLBACK(do_move_down) },
+
+    { "move-top", NULL,
+      N_("Move to Top"), "",
+      N_("Move to Top"),
+      G_CALLBACK(do_move_top) },
+
+    { "move-bottom", NULL,
+      N_("Move to Bottom"), "",
+      N_("Move to Bottom"),
+      G_CALLBACK(do_move_bottom) }
+  };
+
   GtkToggleActionEntry toggle_entries[] =
   {
     { "wrap", GTK_STOCK_JUSTIFY_FILL, N_("_Wrap Text"), 0, N_("Wrap Text"), G_CALLBACK(do_wrap), true },
@@ -259,6 +306,55 @@ PostUI :: prompt_for_charset ()
 }
 
 void
+PostUI::  do_popup_menu (GtkWidget *treeview, GdkEventButton *event, gpointer userdata)
+{
+  PostUI * self (static_cast<PostUI*>(userdata));
+  GtkWidget * menu (gtk_ui_manager_get_widget (self->_uim, "/filequeue-popup"));
+  gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL,
+                  (event ? event->button : 0),
+                  (event ? event->time : 0));
+}
+
+namespace
+{
+  gboolean on_popup_menu (GtkWidget * treeview, gpointer userdata)
+  {
+    PostUI::do_popup_menu (treeview, NULL, userdata);
+    return true;
+  }
+}
+
+gboolean
+PostUI :: on_button_pressed (GtkWidget *treeview, GdkEventButton *event, gpointer userdata)
+  {
+  if (event->type == GDK_BUTTON_PRESS  &&  event->button == 3)
+  {
+    if (1)
+    {
+      GtkTreeSelection *selection;
+      selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
+      if (gtk_tree_selection_count_selected_rows(selection)  <= 1)
+      {
+         GtkTreePath *path;
+         /* Get tree path for row that was clicked */
+         if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeview),
+                                           (gint) event->x,
+                                           (gint) event->y,
+                                           &path, NULL, NULL, NULL))
+         {
+           gtk_tree_selection_unselect_all(selection);
+           gtk_tree_selection_select_path(selection, path);
+           gtk_tree_path_free(path);
+         }
+      }
+    }
+    do_popup_menu(treeview, event, userdata);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+void
 PostUI :: add_actions (GtkWidget * box)
 {
   _uim = gtk_ui_manager_new ();
@@ -273,6 +369,7 @@ PostUI :: add_actions (GtkWidget * box)
   if (err) {
     Log::add_err_va (_("Error reading file \"%s\": %s"), filename, err->message);
     g_clear_error (&err);
+
   }
   g_free (filename);
 
@@ -290,6 +387,13 @@ PostUI :: add_actions (GtkWidget * box)
   gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (gtk_action_group_get_action (_agroup, "wrap")),
                                 _prefs.get_flag ("compose-wrap-enabled", true));
   gtk_ui_manager_insert_action_group (_uim, _agroup, 0);
+
+   //add popup actions
+  _pgroup = gtk_action_group_new ("fq");
+  gtk_action_group_set_translation_domain (_pgroup, NULL);
+  gtk_action_group_add_actions (_agroup, filequeue_popup_entries, G_N_ELEMENTS(filequeue_popup_entries), this);
+  gtk_ui_manager_insert_action_group (_uim, _pgroup, 0);
+
 }
 
 void
@@ -643,9 +747,8 @@ PostUI :: maybe_post_message (GMimeMessage * message)
   ***  Make sure the message is OK...
   **/
 
-  if (_file_queue_empty)
-    if (!check_message (server, message))
-      return false;
+  if (!check_message (server, message))
+    return false;
 
   /**
   *** If this is email only, skip the rest of the posting...
@@ -1075,12 +1178,12 @@ PostUI :: new_message_from_ui (Mode mode)
   }
   GMimeDataWrapper * content_object = g_mime_data_wrapper_new_with_stream (stream, GMIME_CONTENT_ENCODING_DEFAULT);
   g_object_unref (stream);
+  /* NOTE (imhotep): Text gets ignored when posting binary data, ATM.
+   * Perhaps this could be changed but I don't really care right now. It would be the same message for all binary files
+   * anyway, so this would be kind of useless...
+   */
   GMimePart * part = g_mime_part_new ();
-  //todo ??
-  if (_file_queue_empty)
-    pch = g_strdup_printf ("text/plain; charset=%s", charset.c_str());
-  else
-    pch = g_strdup_printf ("message/partial; charset=%s", charset.c_str());
+  pch = g_strdup_printf ("text/plain; charset=%s", charset.c_str());
 
   GMimeContentType * type = g_mime_content_type_new_from_string (pch);
   g_free (pch);
@@ -1968,11 +2071,10 @@ PostUI :: get_selected_files_foreach (GtkTreeModel *model, GtkTreePath *, GtkTre
 {
   FileQueue::FileData* file (0);
   gtk_tree_model_get (model, iter, 0, &file, -1);
-  std::cerr<<"foreach got "<<file->filename.c_str()<<std::endl;
   static_cast<FileQueue*>(list_g)->add (file->filename.c_str(), FileQueue::END);
 }
 
-FileQueue::articles_v
+FileQueue::articles_v&
 PostUI :: get_selected_files () const
 {
   FileQueue files;
@@ -1982,56 +2084,93 @@ PostUI :: get_selected_files () const
   return files.get_files();
 }
 
+int
+PostUI :: get_top()
+{
+  int pos(0);
+
+  return pos;
+}
+
+int
+PostUI :: get_bottom()
+{
+  int pos(0);
+
+
+  return pos;
+}
+
+void
+PostUI :: remove_files(void)
+{
+  _file_queue.remove(get_selected_files());
+  update_filequeue_tab();
+}
+
 void
-PostUI :: remove_files(const FileQueue::articles_v& no)
+PostUI :: move_up(void)
 {
-  _file_queue.remove(no);
+  _file_queue.move_up(get_selected_files(),get_top());
   update_filequeue_tab();
 }
 
 void
-PostUI :: move_up(const FileQueue::articles_v& no)
+PostUI :: move_down(void)
 {
-  _file_queue.move_up(no);
+  _file_queue.move_down(get_selected_files(),get_bottom());
+  update_filequeue_tab();
 }
 
 void
-PostUI :: move_down(const FileQueue::articles_v& no)
+PostUI :: move_top(void)
 {
-  _file_queue.move_down(no);
+  _file_queue.move_top(get_selected_files());
+  update_filequeue_tab();
 }
 
 void
-PostUI :: move_top(const FileQueue::articles_v& no)
+PostUI :: move_bottom(void)
 {
-  _file_queue.move_top(no);
+  _file_queue.move_bottom(get_selected_files());
+  update_filequeue_tab();
 }
 
 void
-PostUI :: move_bottom(const FileQueue::articles_v& no)
+PostUI :: select_parts (void)
 {
-  _file_queue.move_bottom(no);
+  //get parts from dialog result
+  //_file_queue.remove_parts(_parts_dialog->selection);
+  update_filequeue_tab();
+}
+
+void
+PostUI :: clear_list (void)
+{
+  _file_queue.clear();
+    update_filequeue_tab();
+
 }
 
 void PostUI :: up_clicked_cb (GtkButton*, PostUI* pane)
 {
-  pane->move_up (pane->get_selected_files());
+  pane->move_up ();
 }
 void PostUI :: down_clicked_cb (GtkButton*, PostUI* pane)
 {
-  pane->move_down (pane->get_selected_files());
+  pane->move_down ();
 }
 void PostUI :: top_clicked_cb (GtkButton*, PostUI* pane)
 {
-  pane->move_top (pane->get_selected_files());
+  pane->move_top ();
 }
 void PostUI :: bottom_clicked_cb (GtkButton*, PostUI* pane)
 {
-  pane->move_bottom (pane->get_selected_files());
+  pane->move_bottom ();
 }
 void PostUI :: delete_clicked_cb (GtkButton*, PostUI* pane)
 {
-  pane->remove_files (pane->get_selected_files());
+  pane->remove_files ();
 }
 
 namespace
@@ -2048,7 +2187,8 @@ namespace
     unsigned int size;
     gtk_tree_model_get (model, iter, 0, &fd, 1, &size, -1);
     if (fd)
-      g_object_set (renderer, "text", fd->basename.c_str(), NULL);
+      g_object_set (renderer, "text", fd->basename.c_str(),
+                    "weight", fd->all_parts ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_LIGHT, NULL);
   }
 }
 
@@ -2088,6 +2228,11 @@ PostUI :: create_filequeue_tab ()
   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (w), 1,
                           (_("Size (kB)")),renderer,"text", 1,NULL);
 
+
+  // connect signals for popup menu
+  g_signal_connect (w, "popup-menu", G_CALLBACK(on_popup_menu), this);
+  g_signal_connect (w, "button-press-event", G_CALLBACK(on_button_pressed), this);
+
   //set hint and selection
   gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(w),TRUE);
   GtkTreeSelection * selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (w));
@@ -2100,6 +2245,7 @@ PostUI :: create_filequeue_tab ()
   gtk_container_add (GTK_CONTAINER(w), _filequeue_store);
   gtk_box_pack_start (GTK_BOX(vbox), w, true, true, 0);
 
+
   return vbox;
 }
 
@@ -2120,18 +2266,13 @@ PostUI :: update_filequeue_tab()
   for (; it != _file_queue.end(); ++it, ++i )
   {
     fd = &(*it);
-    std::cerr<<"updating file "<<fd->basename<<std::endl;
     gtk_list_store_append (store, &iter);
     gtk_list_store_set (store, &iter,
                       0, fd,
                       1, (*it).byte_count/1024,
                       -1);
   }
-
-  std::cerr<<"updated "<<i<<" elements in store.\n";
-
   _file_queue_empty = (i == 0);
-
 }
 
 
diff --git a/pan/gui/post-ui.h b/pan/gui/post-ui.h
index f43f9e8..59fb7de 100644
--- a/pan/gui/post-ui.h
+++ b/pan/gui/post-ui.h
@@ -70,6 +70,18 @@ namespace pan
       void set_always_run_editor (bool);
       void update_filequeue_tab();
 
+      //popup action entries
+      void remove_files (void);
+      void clear_list   (void);
+      void select_parts (void);
+      void move_up      (void);
+      void move_down    (void);
+      void move_top     (void);
+      void move_bottom  (void);
+
+      static void do_popup_menu (GtkWidget*, GdkEventButton *event, gpointer pane_g);
+      static gboolean on_button_pressed (GtkWidget * treeview, GdkEventButton *event, gpointer userdata);
+
     private:
       void done_sending_message (GMimeMessage*, bool);
       void maybe_mail_message (GMimeMessage*);
@@ -111,7 +123,7 @@ namespace pan
       std::string _charset;
       TextMassager _tm;
       GtkUIManager * _uim;
-      GtkActionGroup * _agroup;
+      GtkActionGroup * _agroup, * _pgroup;
       std::string _current_signature;
       GtkWidget * _post_dialog;
       TaskPost * _post_task;
@@ -160,20 +172,18 @@ namespace pan
       void spawn_editor_dead(char *);
 
     private:
-      FileQueue::articles_v  get_selected_files () const;
+      FileQueue::articles_v&  get_selected_files () const;
       static void get_selected_files_foreach (GtkTreeModel*,
                       GtkTreePath*, GtkTreeIter*, gpointer);
-      void remove_files(const FileQueue::articles_v& no);
+
+      int get_top() ;
+      int get_bottom() ;
+
       static void up_clicked_cb      (GtkButton*, PostUI*);
       static void down_clicked_cb    (GtkButton*, PostUI*);
       static void top_clicked_cb     (GtkButton*, PostUI*);
       static void bottom_clicked_cb  (GtkButton*, PostUI*);
       static void delete_clicked_cb  (GtkButton*, PostUI*);
-
-      void move_up(const FileQueue::articles_v& no);
-      void move_down(const FileQueue::articles_v& no);
-      void move_top(const FileQueue::articles_v& no);
-      void move_bottom(const FileQueue::articles_v& no);
   };
 }
 
diff --git a/pan/gui/post.ui.h b/pan/gui/post.ui.h
index 3b7eab0..1a313c6 100644
--- a/pan/gui/post.ui.h
+++ b/pan/gui/post.ui.h
@@ -42,4 +42,17 @@ const char * fallback_post_ui =
 "    <toolitem action='add-files' />\n"
 "  </toolbar>\n"
 "\n"
+"  <popup name='filequeue-popup'>\n"
+"    <menuitem action='remove-files' />\n"
+"    <menuitem action='clear-list' />\n"
+"    <separator />\n"
+"    <menuitem action='select-parts' />\n"
+"    <separator />\n"
+"    <menuitem action='move-up' />\n"
+"    <menuitem action='move-down' />\n"
+"    <separator />\n"
+"    <menuitem action='move-top' />\n"
+"    <menuitem action='move-bottom' />\n"
+"  </popup>\n"
+"\n"
 "</ui>\n";
diff --git a/pan/tasks/encoder.cc b/pan/tasks/encoder.cc
index 9fa41ab..fa857f2 100644
--- a/pan/tasks/encoder.cc
+++ b/pan/tasks/encoder.cc
@@ -72,8 +72,6 @@ Encoder :: enqueue (TaskUpload                * task,
   this->subject = subject;
   this->author = author;
 
-  std::cerr<<"encoder begin: "<<this->groups<<" "<<this->subject<<" "<<this->author<<" "<<std::endl;
-
   percent = 0;
   current_file.clear ();
   log_infos.clear();
@@ -115,22 +113,22 @@ Encoder :: do_work()
       g_snprintf(buf,bufsz,"%s/%s.%d", uulib.c_str(), basename, cnt);
       outfile = fopen(buf,"wb");
       while (1) {
-        /*
-        UUE_PrepPartial (FILE *outfile, FILE *infile,
-        char *infname, int encoding,
-        char *outfname, int filemode,
-        int partno, long linperfile, long filesize,
-        char *destination, char *from, char *subject,
-        int isemail) */
+
+        // skip not wanted parts of binary file
+        if (file_data.parts.end() != file_data.parts.find(cnt))
+        {
+          ++cnt;
+          res = UURET_CONT;
+          goto _end;
+        }
+        // 4000 lines SHOULD be OK for ANY nntp server ...
         res = UUE_PrepPartial (outfile, NULL, (char*)filename,YENC_ENCODED,
                                (char*)basename,0644, cnt, 4000,
                                file_data.byte_count, (char*)groups.c_str(),
                                (char*)author.c_str(), (char*)subject.c_str(),
                                0);
 
-//        res = UUEncodePartial( outfile, NULL, (char*)file_data.filename.c_str(),
-//                               YENC_ENCODED, (char*)file_data.basename.c_str(), const_cast<char*>("message/partial"),
-//                               0, cnt, 4000, &crcptr);
+        _end:
         if (outfile) fclose(outfile);
         if (res != UURET_CONT) break;
         g_snprintf(buf,bufsz,"%s/%s.%d", uulib.c_str(), basename, ++cnt);
@@ -177,8 +175,9 @@ Encoder :: uu_log (void* data, char* message, int severity)
 double
 Encoder :: get_percentage (const uuprogress& p) const
 {
-  static const double WEIGHT_SCANNING = 30;
-  static const double WEIGHT_ENCODING = 70;
+  // don't know if this is accurate, but i just take a guess ;)
+  static const double WEIGHT_SCANNING = 50;
+  static const double WEIGHT_ENCODING = 50;
 
   double base = 0;
 
@@ -207,9 +206,9 @@ Encoder :: uu_busy_poll (void * d, uuprogress *p)
 {
   Encoder * self (static_cast<Encoder*>(d));
   self->mut.lock();
-  self->percent = self->get_percentage(*p);
-  self->current_file = p->curfile;
-  self->parts  = (int)p->numparts;
+    self->percent = self->get_percentage(*p);
+    self->current_file = p->curfile;
+    self->parts  = (int)p->numparts - self->file_data.parts.size();
   self->mut.unlock();
 
   return self->was_cancelled(); // returning true tells uulib to abort
diff --git a/pan/tasks/task-upload.cc b/pan/tasks/task-upload.cc
index 29234b7..c915594 100644
--- a/pan/tasks/task-upload.cc
+++ b/pan/tasks/task-upload.cc
@@ -84,11 +84,23 @@ TaskUpload :: TaskUpload ( const FileQueue::FileData & file_data,
 }
 
 void
-TaskUpload :: update_work (void)
+TaskUpload :: update_work (NNTP* checkin_pending)
 {
+
+  int working(0);
+  foreach (needed_t, _needed, nit)
+  {
+    Needed& n (*nit);
+    if (n.nntp && n.nntp!=checkin_pending)
+      ++working;
+  }
+
   if (!_encoder && !_encoder_has_run)
   {
     _state.set_need_encoder();
+  } else if(working)
+  {
+    _state.set_working();
   } else if (_encoder_has_run && !_needed.empty())
   {
     set_status_va (_("Uploading %s"), _basename.c_str());
@@ -107,21 +119,30 @@ TaskUpload :: update_work (void)
 void
 TaskUpload :: use_nntp (NNTP * nntp)
 {
-    Needed cur;
-      if (!_needed.empty()) {
-        cur = *(_needed.begin());
-      } else {
-        update_work();
-        return;
-      }
+
+  Needed * needed (0);
+  needed_t::iterator it = _needed.begin();
+  for (; it != _needed.end(); ++it)
+    if (it->nntp==0)
+      needed = &*it;
+
+  if (!needed)
+  {
+    update_work (nntp);
+    check_in (nntp, OK);
+  }
+  else
+  {
+    needed->nntp = nntp;
 
     std::stringstream tmp;
-    std::ifstream in(cur.filename.c_str(), std::ifstream::in);
+    std::ifstream in(needed->filename.c_str(), std::ifstream::in);
     while (in.good())
       tmp << (char) in.get();
     in.close();
     nntp->post(StringView(tmp.str()), this);
     update_work ();
+  }
 }
 
 /***
@@ -143,38 +164,46 @@ TaskUpload :: on_nntp_done  (NNTP             * nntp,
                              const StringView & response)
 {
 
-//  switch (atoi(response.str))
-//  {
-//    case NO_POSTING:
-//      Log :: add_err(_("Posting failed: No Posts allowed by server."));
-//      this->stop();
-//      break;
-//    case POSTING_FAILED:
-//      Log :: add_err_va (_("Posting failed: %s"), response.str);
-//      break;
-//    case ARTICLE_POSTED_OK:
+  needed_t::iterator it;
+  for (it=_needed.begin(); it!=_needed.end(); ++it)
+    if (it->nntp == nntp)
+      break;
+
+  switch (atoi(response.str))
+  {
+    case NO_POSTING:
+      Log :: add_err(_("Posting failed: No Posts allowed by server."));
+      this->stop();
+      break;
+    case POSTING_FAILED:
+      Log :: add_err_va (_("Posting failed: %s"), response.str);
+      break;
+    case ARTICLE_POSTED_OK:
       if (_needed.empty())
         Log :: add_info_va(_("Posting of file %s succesful: %s"),
-                           _file_data.basename.c_str(), response.str);
-      else
-        _needed.pop_front();
-//      break;
-//    case TOO_MANY_CONNECTIONS: //todo
-//    break;
-//  }
-
-//  switch (health)
-//  {
-//    case OK:
-      check_in (nntp, health);
-      increment_step(1);
-//      break;
-
-//    case ERR_NETWORK:
-//      _state.set_need_nntp(nntp->_server);
-//      break;
-//  }
+               _file_data.basename.c_str(), response.str);
+      break;
+    case TOO_MANY_CONNECTIONS:
+      // lockout for 120 secs, but try
+      _state.set_need_nntp(nntp->_server);
+      break;
+  }
+
+  switch (health)
+  {
+    case OK:
+      _needed.erase (it);
+      break;
+
+    case ERR_NETWORK:
+      _state.set_need_nntp(nntp->_server);
+      break;
+  }
+
   update_work();
+  increment_step(1);
+  check_in (nntp, health);
+
 }
 
 /***
@@ -201,8 +230,6 @@ TaskUpload :: use_encoder (Encoder* encoder)
   _encoder = encoder;
   init_steps(100);
   _state.set_working();
-
-  std::cerr<<"enqueue: "<<_groups<<" "<<_subject<<" "<<_author<<std::endl;
   _encoder->enqueue (this, _file_data, _groups, _subject, _author, YENC);
   debug ("encoder thread was free, enqueued work");
 }
diff --git a/pan/tasks/task-upload.h b/pan/tasks/task-upload.h
index 171f060..17ffaff 100644
--- a/pan/tasks/task-upload.h
+++ b/pan/tasks/task-upload.h
@@ -105,12 +105,13 @@ namespace pan
         std::string filename;
         unsigned long bytes;
         int partno;
-        Needed (): partno(0) {}
+        NNTP* nntp;
+        Needed (): nntp(0), partno(0) {}
       };
       typedef std::deque<Needed> needed_t;
       needed_t _needed;
 
-      void update_work (void);
+      void update_work (NNTP * checkin_pending = 0);
   };
 
 // from mime-utils.cc



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