[pan2] https://bugzilla.gnome.org/show_bug.cgi?id=651307



commit 8326fee3a1affb096d1d35cbee466f43c7f67224
Author: Heinrich MÃller <sphemuel stud informatik uni-erlangen de>
Date:   Sat Dec 3 16:33:14 2011 +0100

    https://bugzilla.gnome.org/show_bug.cgi?id=651307

 pan/data-impl/headers.cc     |   28 +++++++++--
 pan/data/article.h           |   10 +++-
 pan/gui/actions.cc           |  106 ++++++++++++++++++++++++-----------------
 pan/gui/gui.cc               |   27 +++++++++++
 pan/gui/gui.h                |    5 ++
 pan/gui/header-pane.cc       |   81 +++++++++++++++++++++++++++++--
 pan/gui/header-pane.h        |    8 +++
 pan/gui/pan-ui.h             |    3 +
 pan/gui/pan.ui.h             |   10 ++++
 pan/icons/Makefile.am        |    2 +-
 pan/icons/icon_blue_flag.png |  Bin 535 -> 0 bytes
 pan/icons/icon_red_flag.png  |  Bin 0 -> 653 bytes
 12 files changed, 221 insertions(+), 59 deletions(-)
---
diff --git a/pan/data-impl/headers.cc b/pan/data-impl/headers.cc
index 868ab66..f00797f 100644
--- a/pan/data-impl/headers.cc
+++ b/pan/data-impl/headers.cc
@@ -435,7 +435,7 @@ DataImpl :: load_headers (const DataIO   & data_io,
     } while (!line.empty() && *line.str=='#');
 
     const int version (atoi (line.str));
-    if (version==1 || version==2)
+    if (version==1 || version==2 || version == 3)
     {
       // build the symbolic server / group lookup table
       in->getline (line);
@@ -478,13 +478,26 @@ DataImpl :: load_headers (const DataIO   & data_io,
         StringView s;
         if (!in->getline (s)) // end of file
           break;
+
+        Article& a (h->alloc_new_article());
+
+
+        // flag line
+        a.flag = false;
+        if (version == 3)
+        {
+          a.flag = atoi(s.str) == 1 ? true : false;
+          in->getline(s);
+        }
+
         if (s.empty() || *s.str!='<') // not a message-id...
           continue;
 
-        Article& a (h->alloc_new_article());
-        a.message_id = s;
+        //message id
+        s.ltrim(); a.message_id = s;
 
         // subject line
+
         in->getline (s); s.ltrim(); a.subject = s;
 
         // author line
@@ -716,10 +729,12 @@ DataImpl :: save_headers (DataIO                       & data_io,
            "#       If has-attachments isn't 't' (for true), fields 2 and 3 are omitted.\n"
            "#       If fields 2 and 3 are equal, the article is `complete'.\n"
            "#    8. One line per parts-found-count: part-index message-id byte-count\n"
+           "#\n"
            "#\n";
 
     // lines moved from line 8 to line 7 in 0.115, causing version 2
-    out << "2\t # file format version number\n";
+    // flag added, version 3 (12/2011, imhotep)
+    out << "3\t # file format version number\n";
 
     // xref lookup section
     frequency_t frequency;
@@ -749,8 +764,9 @@ DataImpl :: save_headers (DataIO                       & data_io,
       const Quark& message_id (a->message_id);
       h->build_references_header (a, references);
 
-      // message-id, subject, author
-      out << message_id << "\n\t"
+      // flag, message-id, subject, author
+      out <<a->flag<<"\n"
+          << message_id << "\n\t"
           << a->subject << "\n\t"
           << author_qts(a->author) << "\n\t";
       // references line *IF* the article has a References header
diff --git a/pan/data/article.h b/pan/data/article.h
index 0d905b9..0d2ff62 100644
--- a/pan/data/article.h
+++ b/pan/data/article.h
@@ -31,7 +31,7 @@ namespace pan
 {
   /**
    * A Usenet article, either single-part or multipart.
-   * 
+   *
    * To lessen the memory footprint of large binaries groups,
    * Pan folds multipart posts into a single Article object.
    * Only minimal information for any one part is kept
@@ -73,6 +73,7 @@ namespace pan
       unsigned int lines;
       int score;
       bool is_binary;
+      bool flag;
       static bool has_reply_leader (const StringView&);
 
     public:
@@ -85,9 +86,14 @@ namespace pan
       Xref xref;
 
     public:
-      Article (): time_posted(0), lines(0), score(0), is_binary(false)  {}
+      Article (): time_posted(0), lines(0), score(0), is_binary(false), flag(false)  {}
       void clear ();
 
+      /* Functions to bookmark an article */
+      void toggle_flag() { flag = !flag; }
+      bool get_flag() const { return flag; }
+      void set_flag(bool setme) { flag = setme; }
+
     private:
       Parts parts;
 
diff --git a/pan/gui/actions.cc b/pan/gui/actions.cc
index 61b6403..486465d 100644
--- a/pan/gui/actions.cc
+++ b/pan/gui/actions.cc
@@ -46,23 +46,23 @@ namespace
   {
     { icon_article_read, "ICON_ARTICLE_READ" },
     { icon_article_unread, "ICON_ARTICLE_UNREAD" },
-    { icon_compose_followup, "ICON_COMPOSE_FOLLOWUP" }, 
-    { icon_compose_post, "ICON_COMPOSE_POST" }, 
-    { icon_disk, "ICON_DISK" }, 
-    { icon_filter_only_attachments, "ICON_ONLY_ATTACHMENTS" }, 
-    { icon_filter_only_cached, "ICON_ONLY_CACHED" }, 
-    { icon_filter_only_me, "ICON_ONLY_ME" }, 
-    { icon_filter_only_unread, "ICON_ONLY_UNREAD" }, 
-    { icon_filter_only_watched, "ICON_ONLY_WATCHED" }, 
-    { icon_get_dialog, "ICON_GET_DIALOG" }, 
-    { icon_get_selected, "ICON_GET_SELECTED" }, 
-    { icon_get_subscribed, "ICON_GET_SUBSCRIBED" }, 
-    { icon_read_group, "ICON_READ_GROUP" }, 
-    { icon_read_more, "ICON_READ_MORE" }, 
-    { icon_read_less, "ICON_READ_LESS" }, 
-    { icon_read_unread_article, "ICON_READ_UNREAD_ARTICLE" }, 
-    { icon_read_unread_thread, "ICON_READ_UNREAD_THREAD" }, 
-    { icon_score, "ICON_SCORE" }, 
+    { icon_compose_followup, "ICON_COMPOSE_FOLLOWUP" },
+    { icon_compose_post, "ICON_COMPOSE_POST" },
+    { icon_disk, "ICON_DISK" },
+    { icon_filter_only_attachments, "ICON_ONLY_ATTACHMENTS" },
+    { icon_filter_only_cached, "ICON_ONLY_CACHED" },
+    { icon_filter_only_me, "ICON_ONLY_ME" },
+    { icon_filter_only_unread, "ICON_ONLY_UNREAD" },
+    { icon_filter_only_watched, "ICON_ONLY_WATCHED" },
+    { icon_get_dialog, "ICON_GET_DIALOG" },
+    { icon_get_selected, "ICON_GET_SELECTED" },
+    { icon_get_subscribed, "ICON_GET_SUBSCRIBED" },
+    { icon_read_group, "ICON_READ_GROUP" },
+    { icon_read_more, "ICON_READ_MORE" },
+    { icon_read_less, "ICON_READ_LESS" },
+    { icon_read_unread_article, "ICON_READ_UNREAD_ARTICLE" },
+    { icon_read_unread_thread, "ICON_READ_UNREAD_THREAD" },
+    { icon_score, "ICON_SCORE" },
     { icon_search_pulldown, "ICON_SEARCH_PULLDOWN" }
   };
 
@@ -147,6 +147,9 @@ namespace
   void do_plonk                        (GtkAction*) { pan_ui->do_plonk(); }
   void do_ignore                       (GtkAction*) { pan_ui->do_ignore(); }
   void do_watch                        (GtkAction*) { pan_ui->do_watch(); }
+  void do_flag                         (GtkAction*) { pan_ui->do_flag(); }
+  void do_next_flag                    (GtkAction*) { pan_ui->do_next_flag(); }
+  void do_last_flag                    (GtkAction*) { pan_ui->do_last_flag(); }
   void do_show_score_dialog            (GtkAction*) { pan_ui->do_show_score_dialog(); }
   void do_show_new_score_dialog        (GtkAction*) { pan_ui->do_show_new_score_dialog(); }
   void do_cancel_article               (GtkAction*) { pan_ui->do_cancel_article(); }
@@ -435,22 +438,22 @@ namespace
       NULL,
       G_CALLBACK(do_clear_header_pane) },
     { "clear-body-pane", NULL,
-      N_("Clear _Body Pane"), NULL, 
+      N_("Clear _Body Pane"), NULL,
       NULL,
       G_CALLBACK(do_clear_body_pane) },
 
     { "download-selected-article", "ICON_DISK",
-      N_("Cache Article"), NULL, 
+      N_("Cache Article"), NULL,
       NULL,
       G_CALLBACK(do_download_selected_article) },
 
     { "read-selected-article", "ICON_READ_MORE",
-      N_("Read Article"), NULL, 
+      N_("Read Article"), NULL,
       NULL,
       G_CALLBACK(do_read_selected_article) },
 
     { "show-selected-article-info", NULL,
-      N_("Show Article Information"), NULL, 
+      N_("Show Article Information"), NULL,
       NULL,
       G_CALLBACK(do_show_selected_article_info) },
 
@@ -465,12 +468,12 @@ namespace
       G_CALLBACK(do_read_less) },
 
     { "read-next-unread-group", "ICON_READ_UNREAD_GROUP",
-      N_("Next _Unread Group"), "G", 
+      N_("Next _Unread Group"), "G",
       NULL,
       G_CALLBACK(do_read_next_unread_group) },
 
     { "read-next-group", "ICON_READ_GROUP",
-      N_("Next _Group"), "<shift>G", 
+      N_("Next _Group"), "<shift>G",
       NULL,
       G_CALLBACK(do_read_next_group) },
 
@@ -485,7 +488,7 @@ namespace
       G_CALLBACK(do_read_next_article) },
 
     { "read-next-watched-article", NULL,
-      N_("Next _Watched Article"), "<control><shift>N", 
+      N_("Next _Watched Article"), "<control><shift>N",
       NULL,
       G_CALLBACK(do_read_next_watched_article) },
 
@@ -495,76 +498,91 @@ namespace
       G_CALLBACK(do_read_next_unread_thread) },
 
     { "read-next-thread", NULL,
-      N_("Next Threa_d"), "<control>T", 
+      N_("Next Threa_d"), "<control>T",
       NULL,
       G_CALLBACK(do_read_next_thread) },
 
     { "read-previous-article", NULL,
-      N_("Pre_vious Article"), "V", 
+      N_("Pre_vious Article"), "V",
       NULL,
       G_CALLBACK(do_read_previous_article) },
 
     { "read-previous-thread", NULL,
-      N_("Previous _Thread"), "<control>V", 
+      N_("Previous _Thread"), "<control>V",
       NULL,
 
       G_CALLBACK(do_read_previous_thread) },
     { "read-parent-article", NULL,
-      N_("_Parent Article"), "U", 
+      N_("_Parent Article"), "U",
       NULL,
       G_CALLBACK(do_read_parent_article) },
 
     { "plonk", NULL,
-      N_("Ignore _Author"), NULL, 
+      N_("Ignore _Author"), NULL,
       NULL,
       G_CALLBACK(do_plonk) },
     { "watch-thread", NULL,
-      N_("_Watch Thread"), NULL, 
+      N_("_Watch Thread"), NULL,
       NULL,
       G_CALLBACK(do_watch) },
 
     { "ignore-thread", NULL,
-      N_("_Ignore Thread"), NULL, 
+      N_("_Ignore Thread"), NULL,
       NULL,
       G_CALLBACK(do_ignore) },
 
+    { "flag-thread", NULL,
+      N_("_Flag Thread"), "X",
+      N_("_Flag Thread"),
+      G_CALLBACK(do_flag) },
+
+    { "next-flagged", NULL,
+      N_("_Goto next flagged Thread"), "plus",
+      N_("_Goto next flagged Thread"),
+      G_CALLBACK(do_next_flag) },
+
+    { "last-flagged", NULL,
+      N_("_Goto last flagged Thread"), "minus",
+      N_("_Goto last flagged Thread"),
+      G_CALLBACK(do_last_flag) },
+
     { "view-article-score", "ICON_SCORE",
-      N_("Edit Article's Watch/Ignore/Score..."), "<control><shift>C", 
+      N_("Edit Article's Watch/Ignore/Score..."), "<control><shift>C",
       NULL,
       G_CALLBACK(do_show_score_dialog) },
 
     { "add-article-score", "ICON_SCORE",
-      N_("Add a _Scoring Rule..."), "S", 
+      N_("Add a _Scoring Rule..."), "S",
       NULL,
       G_CALLBACK(do_show_new_score_dialog) },
 
     { "cancel-article", NULL,
-      N_("Cance_l Article..."), NULL, 
+      N_("Cance_l Article..."), NULL,
       NULL,
       G_CALLBACK(do_cancel_article) },
 
     { "supersede-article", NULL,
-      N_("_Supersede Article..."), NULL, 
+      N_("_Supersede Article..."), NULL,
       NULL,
       G_CALLBACK(do_supersede_article) },
 
     { "delete-article", GTK_STOCK_DELETE,
-      N_("_Delete Article"), "Delete", 
+      N_("_Delete Article"), "Delete",
       NULL,
       G_CALLBACK(do_delete_article) },
 
     { "clear-article-cache", NULL,
-      N_("Clear Article Cache"), NULL, 
+      N_("Clear Article Cache"), NULL,
       NULL,
       G_CALLBACK(do_clear_article_cache) },
 
     { "mark-article-read", "ICON_ARTICLE_READ",
-      N_("_Mark Article as Read"), "M", 
+      N_("_Mark Article as Read"), "M",
       NULL,
       G_CALLBACK(do_mark_article_read) },
 
     { "mark-article-unread", "ICON_ARTICLE_UNREAD",
-      N_("Mark Article as _Unread"), "<control>M", 
+      N_("Mark Article as _Unread"), "<control>M",
       NULL,
       G_CALLBACK(do_mark_article_unread) },
 
@@ -579,27 +597,27 @@ namespace
       G_CALLBACK(do_followup_to) },
 
     { "reply-to", NULL,
-      N_("_Reply to Author in Mail"), "R", 
+      N_("_Reply to Author in Mail"), "R",
       NULL,
       G_CALLBACK(do_reply_to) },
 
     { "pan-web-page", NULL,
-      N_("_Pan Home Page"), NULL, 
+      N_("_Pan Home Page"), NULL,
       NULL,
       G_CALLBACK(do_pan_web) },
 
     { "bug-report", NULL,
-      N_("Give _Feedback or Report a Bug..."), NULL, 
+      N_("Give _Feedback or Report a Bug..."), NULL,
       NULL,
       G_CALLBACK(do_bug_report) },
 
     { "tip-jar", NULL,
-      N_("_Tip Jar..."), NULL, 
+      N_("_Tip Jar..."), NULL,
       NULL,
       G_CALLBACK(do_tip_jar) },
 
     { "about-pan", GTK_STOCK_ABOUT,
-      N_("_About"), NULL, 
+      N_("_About"), NULL,
       NULL,
       G_CALLBACK(do_about_pan) }
   };
diff --git a/pan/gui/gui.cc b/pan/gui/gui.cc
index b614301..b5d866c 100644
--- a/pan/gui/gui.cc
+++ b/pan/gui/gui.cc
@@ -1036,6 +1036,33 @@ void GUI :: do_ignore ()
 {
   set_selected_thread_score (-9999);
 }
+
+void
+GUI :: do_flag ()
+{
+  Article* a = _header_pane->get_first_selected_article();
+  a->toggle_flag();
+  _header_pane->on_article_flag_toggled(a);
+}
+
+void
+GUI :: step_bookmarks(int step)
+{
+  _header_pane->move_to_next_bookmark(step);
+}
+
+void
+GUI :: do_next_flag ()
+{
+  step_bookmarks(1);
+}
+
+void
+GUI :: do_last_flag ()
+{
+  step_bookmarks(-1);
+}
+
 void GUI :: do_plonk ()
 {
   score_add (ScoreAddDialog::PLONK);
diff --git a/pan/gui/gui.h b/pan/gui/gui.h
index bcdc6e2..2c07a15 100644
--- a/pan/gui/gui.h
+++ b/pan/gui/gui.h
@@ -116,6 +116,9 @@ namespace pan
       virtual void do_plonk ();
       virtual void do_watch ();
       virtual void do_ignore ();
+      virtual void do_flag ();
+      virtual void do_next_flag ();
+      virtual void do_last_flag ();
       virtual void do_show_score_dialog ();
       virtual void do_show_new_score_dialog ();
       virtual void do_cancel_article ();
@@ -154,6 +157,8 @@ namespace pan
       virtual void do_subscribe_selected_groups ();
       virtual void do_unsubscribe_selected_groups ();
 
+      void step_bookmarks(int step);
+
     public:
       static std::string prompt_user_for_save_path (GtkWindow * parent, const Prefs& prefs);
 	  static std::string prompt_user_for_filename  (GtkWindow * parent, const Prefs& prefs);
diff --git a/pan/gui/header-pane.cc b/pan/gui/header-pane.cc
index 98ac6a4..6c6835d 100644
--- a/pan/gui/header-pane.cc
+++ b/pan/gui/header-pane.cc
@@ -75,14 +75,18 @@ namespace
   {
     ICON_READ,
     ICON_UNREAD,
+
     ICON_COMPLETE,
     ICON_COMPLETE_READ,
+
     ICON_INCOMPLETE,
     ICON_INCOMPLETE_READ,
+
     ICON_CACHED,
     ICON_QUEUED,
     ICON_ERROR,
     ICON_EMPTY,
+    ICON_FLAGGED,
     ICON_QTY
    };
 
@@ -92,14 +96,18 @@ namespace
   } _icons[ICON_QTY] = {
     { icon_article_read,           0 },
     { icon_article_unread,         0 },
+
     { icon_binary_complete,        0 },
     { icon_binary_complete_read,   0 },
+
     { icon_binary_incomplete,      0 },
     { icon_binary_incomplete_read, 0 },
+
     { icon_disk,                   0 },
     { icon_bluecheck,              0 },
     { icon_x,                      0 },
-    { icon_empty,                  0 }
+    { icon_empty,                  0 },
+    { icon_red_flag,               0 }
   };
 
   int
@@ -126,7 +134,8 @@ namespace
   }
 
   int
-  get_article_action (const ArticleCache  & cache,
+  get_article_action (const Article       * article,
+                      const ArticleCache  & cache,
                       const Queue         & queue,
                       const Quark         & message_id)
   {
@@ -137,6 +146,10 @@ namespace
     else if (cache.contains (message_id))
       offset = ICON_CACHED;
 
+    if (article)
+      if (article->flag)
+        offset = ICON_FLAGGED;
+
     return offset;
   }
 };
@@ -312,7 +325,7 @@ HeaderPane::Row*
 HeaderPane :: create_row (const EvolutionDateMaker & e,
                           const Article            * a)
 {
-  const int action (get_article_action (_cache, _queue, a->message_id));
+  const int action (get_article_action (a, _cache, _queue, a->message_id));
   const int state (get_article_state (_data, a));
   char * date_str (e.get_date_string (a->time_posted));
   Row * row = new Row (_data, a, date_str, action, state);
@@ -362,8 +375,6 @@ HeaderPane :: column_compare_func (GtkTreeModel  * model,
 {
   int ret (0);
   const PanTreeStore * store (reinterpret_cast<PanTreeStore*>(model));
-  //const Row& row_a (*dynamic_cast<const Row*>(store->get_row (iter_a)));
-  //const Row& row_b (*dynamic_cast<const Row*>(store->get_row (iter_b)));
   const Row& row_a (*static_cast<const Row*>(store->get_row (iter_a)));
   const Row& row_b (*static_cast<const Row*>(store->get_row (iter_b)));
 
@@ -754,6 +765,16 @@ HeaderPane :: get_first_selected_article () const
    return a;
 }
 
+Article*
+HeaderPane :: get_first_selected_article ()
+{
+   Article * a (0);
+   std::set<const Article*> articles (get_full_selection ());
+   if (!articles.empty())
+     a = (Article*)*articles.begin ();
+   return a;
+}
+
 void
 HeaderPane :: get_full_selection_v_foreach (GtkTreeModel * model,
                                             GtkTreePath  * ,
@@ -1799,6 +1820,14 @@ namespace
     virtual bool operator()(const Article&) const { return true; }
   };
 
+  struct ArticleIsFlagged: public ArticleTester {
+    virtual ~ArticleIsFlagged () {}
+    const Article* article;
+    ArticleIsFlagged (const Article* a) : article(a) {}
+    virtual bool operator()(const Article& a) const
+      { return a.get_flag() && a.message_id != article->message_id; }
+  };
+
   struct ArticleIsParentOf: public ArticleTester {
     virtual ~ArticleIsParentOf () {}
     ArticleIsParentOf (const Data::ArticleTree& tree, const Article* a) {
@@ -1967,6 +1996,22 @@ HeaderPane :: read_prev_if (const ArticleTester & test)
 }
 
 void
+HeaderPane :: select_next_if (const ArticleTester& test)
+{
+  GtkTreeView * v (GTK_TREE_VIEW(_tree_view));
+  SelectFunctor sel (v);
+  action_next_if (test, sel);
+}
+
+void
+HeaderPane :: select_prev_if (const ArticleTester& test)
+{
+  GtkTreeView * v (GTK_TREE_VIEW(_tree_view));
+  SelectFunctor sel (v);
+  action_next_if (test, sel);
+}
+
+void
 HeaderPane :: read_next_unread_article ()
 {
   read_next_if (ArticleIsUnread(_data));
@@ -2017,6 +2062,23 @@ HeaderPane :: read_parent_article ()
 ***/
 
 void
+HeaderPane :: move_to_next_bookmark(int step)
+{
+  const bool forward(step == 1);
+  Article * a (get_first_selected_article());
+  if (!a) return;
+
+  if (forward)
+    select_next_if (ArticleIsFlagged(get_first_selected_article()));
+  else
+    select_prev_if (ArticleIsFlagged(get_first_selected_article()));
+}
+
+/***
+****
+***/
+
+void
 HeaderPane :: refresh_font ()
 {
   if (!_prefs.get_flag ("header-pane-font-enabled", false))
@@ -2056,12 +2118,19 @@ HeaderPane :: rebuild_article_action (const Quark& message_id)
 {
   Row * row (get_row (message_id));
   if (row) {
-    row->action = get_article_action (_cache, _queue, message_id);
+    row->action = get_article_action (row->article, _cache, _queue, message_id);
     _tree_store->row_changed (row);
   }
 }
 
 void
+HeaderPane :: on_article_flag_toggled (Article* a)
+{
+  g_return_if_fail(a);
+  rebuild_article_action (a->message_id);
+}
+
+void
 HeaderPane :: on_queue_tasks_added (Queue& queue, int index, int count)
 {
   for (size_t i(index), end(index+count); i!=end; ++i) {
diff --git a/pan/gui/header-pane.h b/pan/gui/header-pane.h
index 70de04c..a105ef2 100644
--- a/pan/gui/header-pane.h
+++ b/pan/gui/header-pane.h
@@ -99,16 +99,21 @@ namespace pan
       void read_previous_thread ();
       void read_parent_article ();
 
+      void move_to_next_bookmark(int);
+
     private:
       void action_next_if (const ArticleTester& test, RowActionFunctor& action);
       void read_next_if (const ArticleTester&);
       void read_prev_if (const ArticleTester&);
+      void select_next_if (const ArticleTester& test);
+      void select_prev_if (const ArticleTester& test);
 
     public:
       GtkWidget* root () { return _root; }
       GtkWidget* get_default_focus_widget() { return _tree_view; }
       GtkWidget* create_filter_entry ();
       const Article* get_first_selected_article () const;
+      Article* get_first_selected_article ();
       std::set<const Article*> get_full_selection () const;
       std::vector<const Article*> get_full_selection_v () const;
       std::set<const Article*> get_nested_selection () const;
@@ -136,6 +141,9 @@ namespace pan
       virtual void on_prefs_string_changed (const StringView&, const StringView&);
       virtual void on_prefs_color_changed  (const StringView&, const GdkColor&) {}
 
+    public:
+      void on_article_flag_toggled(Article*) ;
+
     private:
       virtual void on_queue_task_active_changed (Queue&, Task&, bool active UNUSED) { }
       virtual void on_queue_tasks_added (Queue&, int index, int count);
diff --git a/pan/gui/pan-ui.h b/pan/gui/pan-ui.h
index 47c7ab5..fa432a5 100644
--- a/pan/gui/pan-ui.h
+++ b/pan/gui/pan-ui.h
@@ -66,6 +66,9 @@ namespace pan
     virtual void do_plonk () = 0;
     virtual void do_watch () = 0;
     virtual void do_ignore () = 0;
+    virtual void do_flag () = 0;
+    virtual void do_next_flag () = 0;
+    virtual void do_last_flag () = 0;
     virtual void do_cancel_article () = 0;
     virtual void do_supersede_article () = 0;
     virtual void do_delete_article () = 0;
diff --git a/pan/gui/pan.ui.h b/pan/gui/pan.ui.h
index 7284308..a32e09f 100644
--- a/pan/gui/pan.ui.h
+++ b/pan/gui/pan.ui.h
@@ -126,6 +126,11 @@ const char * fallback_ui_file =
 "        <menuitem action='add-article-score' />\n"
 "        <menuitem action='watch-thread' />\n"
 "        <menuitem action='ignore-thread' />\n"
+"        <separator />\n"
+"        <menuitem action='flag-thread' />\n"
+"        <menuitem action='next-flagged' />\n"
+"        <menuitem action='last-flagged' />\n"
+"        <separator />\n"
 "        <menuitem action='plonk' />\n"
 "        <menuitem action='view-article-score' />\n"
 "        <separator />\n"
@@ -188,6 +193,11 @@ const char * fallback_ui_file =
 "    <menuitem action='add-article-score' />\n"
 "    <menuitem action='watch-thread' />\n"
 "    <menuitem action='ignore-thread' />\n"
+"    <separator />\n"
+"    <menuitem action='flag-thread' />\n"
+"    <menuitem action='next-flagged' />\n"
+"    <menuitem action='last-flagged' />\n"
+"    <separator />\n"
 "    <menuitem action='plonk' />\n"
 "    <menuitem action='view-article-score' />\n"
 "    <separator />\n"
diff --git a/pan/icons/Makefile.am b/pan/icons/Makefile.am
index 040a872..0e3680e 100644
--- a/pan/icons/Makefile.am
+++ b/pan/icons/Makefile.am
@@ -7,7 +7,7 @@ stock_images = \
 	icon_binary_incomplete.png \
 	icon_binary_incomplete_read.png \
 	icon_bluecheck.png \
-	icon_blue_flag.png \
+	icon_red_flag.png \
 	icon_by_me.png \
 	icon_by_others.png \
 	icon_compose_followup.png \
diff --git a/pan/icons/icon_red_flag.png b/pan/icons/icon_red_flag.png
new file mode 100644
index 0000000..9c0dc49
Binary files /dev/null and b/pan/icons/icon_red_flag.png differ



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