[pan2/testing: 173/279] nearly complete support for filtering actions based on score
- From: Heinrich MÃller <henmull src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pan2/testing: 173/279] nearly complete support for filtering actions based on score
- Date: Sat, 3 Dec 2011 22:36:42 +0000 (UTC)
commit 9148e3ea66857d8915d2d648cce107f7b6a9d0dc
Author: Heinrich MÃller <sphemuel stud informatik uni-erlangen de>
Date: Tue Jul 19 12:03:50 2011 +0200
nearly complete support for filtering actions based on score
pan/data-impl/data-impl.h | 22 +++++--
pan/data-impl/headers.cc | 9 ++-
pan/data-impl/my-tree.cc | 121 ++++++++++++++++++++++----------------
pan/data-impl/rules-filter.cc | 75 +++++++++++++++++-------
pan/data-impl/rules-filter.h | 16 ++++-
pan/data/data.h | 13 ++++-
pan/gui/actions.cc | 13 +++-
pan/gui/gui.cc | 94 +++++++-----------------------
pan/gui/gui.h | 1 +
pan/gui/header-pane.cc | 97 ++++++++++++++++++++-----------
pan/gui/header-pane.h | 5 +-
pan/gui/pan-ui.h | 2 +
pan/gui/pan.ui.h | 2 +
pan/gui/prefs-ui.cc | 7 +-
pan/gui/prefs.h | 1 +
pan/gui/save-ui.cc | 2 +-
pan/tasks/task-article.h | 2 +
pan/tasks/task-xover.cc | 10 ---
pan/usenet-utils/filter-info.cc | 1 +
pan/usenet-utils/filter-info.h | 2 +-
pan/usenet-utils/rules-info.cc | 44 +++++++++++++-
pan/usenet-utils/rules-info.h | 16 ++++--
22 files changed, 332 insertions(+), 223 deletions(-)
---
diff --git a/pan/data-impl/data-impl.h b/pan/data-impl/data-impl.h
index ab00f7d..655cca0 100644
--- a/pan/data-impl/data-impl.h
+++ b/pan/data-impl/data-impl.h
@@ -431,7 +431,9 @@ namespace pan
MyTree (DataImpl & data_impl,
const Quark & group,
const Data::ShowType show_type,
- const FilterInfo * filter_info);
+ const FilterInfo * filter_info=0,
+ const RulesInfo * rules=0,
+ Queue * queue=0);
virtual ~MyTree ();
public: // from ArticleTree
@@ -441,7 +443,8 @@ namespace pan
virtual size_t size () const;
virtual void set_filter (const ShowType show_type = SHOW_ARTICLES,
const FilterInfo * criteria = 0);
- virtual void set_rules (const RulesInfo * criteria = 0);
+ virtual void set_rules (const ShowType show_type = SHOW_ARTICLES,
+ const RulesInfo * rules = 0);
public:
void articles_changed (const quarks_t& mids, bool do_refilter);
@@ -464,9 +467,15 @@ namespace pan
void accumulate_descendants (unique_nodes_t&, const ArticleNode*) const;
void add_articles (const const_nodes_v&);
void apply_filter (const const_nodes_v&);
- void apply_rules (const const_nodes_v& candidates);
+ void apply_rules (const_nodes_v& candidates);
+
+ private:
+ void cache_articles (std::set<const Article*> s);
+ void download_articles (std::set<const Article*> s);
};
+
+
std::set<MyTree*> _trees;
void on_articles_removed (const quarks_t& mids) const;
void on_articles_added (const Quark& group, const quarks_t& mids);
@@ -474,14 +483,15 @@ namespace pan
void remove_articles_from_tree (MyTree*, const quarks_t& mids) const;
void add_articles_to_tree (MyTree*, const quarks_t& mids);
-
public: // Data interface
virtual void delete_articles (const unique_articles_t&);
virtual ArticleTree* group_get_articles (const Quark & group,
const ShowType show_type = SHOW_ARTICLES,
- const FilterInfo * criteria=0) const;
+ const FilterInfo * criteria=0,
+ const RulesInfo * rules=0,
+ Queue * queue=0) const;
virtual void group_clear_articles (const Quark & group);
@@ -625,7 +635,7 @@ namespace pan
public:
const ArticleFilter _article_filter;
- const RulesFilter _rules_filter;
+ RulesFilter _rules_filter;
private:
guint newsrc_autosave_id;
diff --git a/pan/data-impl/headers.cc b/pan/data-impl/headers.cc
index 3430352..a81dc3d 100644
--- a/pan/data-impl/headers.cc
+++ b/pan/data-impl/headers.cc
@@ -922,6 +922,7 @@ DataImpl :: get_article_scores (const Quark & group,
void
DataImpl :: rescore_articles (const Quark& group, const quarks_t mids)
{
+
GroupHeaders * gh (get_group_headers (group));
if (!gh) // group isn't loaded
return;
@@ -1075,6 +1076,7 @@ DataImpl :: group_clear_articles (const Quark& group)
void
DataImpl :: delete_articles (const unique_articles_t& articles)
{
+
quarks_t all_mids;
// info we need to batch these deletions per group...
@@ -1136,6 +1138,7 @@ DataImpl :: on_articles_changed (const Quark& group, const quarks_t& mids, bool
void
DataImpl :: on_articles_added (const Quark& group, const quarks_t& mids)
{
+
if (!mids.empty())
{
Log::add_info_va (_("Added %lu articles to %s."),
@@ -1192,8 +1195,10 @@ DataImpl :: find_closest_ancestor (const ArticleNode * node,
Data::ArticleTree*
DataImpl :: group_get_articles (const Quark & group,
const ShowType show_type,
- const FilterInfo * filter) const
+ const FilterInfo * filter,
+ const RulesInfo * rules,
+ Queue * queue) const
{
// cast const away for group_ref()... consider _groups mutable
- return new MyTree (*const_cast<DataImpl*>(this), group, show_type, filter);
+ return new MyTree (*const_cast<DataImpl*>(this), group, show_type, filter, rules,queue);
}
diff --git a/pan/data-impl/my-tree.cc b/pan/data-impl/my-tree.cc
index ebe1caf..a52a539 100644
--- a/pan/data-impl/my-tree.cc
+++ b/pan/data-impl/my-tree.cc
@@ -84,12 +84,27 @@ DataImpl :: MyTree :: size () const
}
void
-DataImpl :: MyTree :: set_rules (const RulesInfo * criteria )
+DataImpl :: MyTree :: set_rules (const Data::ShowType show_type,
+ const RulesInfo * rules )
{
- if (criteria)
- _rules = *criteria;
+
+ if (rules)
+ _rules = *rules;
else
_rules.clear ();
+ _show_type = show_type;
+
+ const GroupHeaders * h (_data.get_group_headers (_group));
+ g_assert (h != 0);
+ const_nodes_v candidates;
+ candidates.reserve (h->_nodes.size());
+ foreach_const (nodes_t, h->_nodes, it) {
+ const ArticleNode * node (it->second);
+ if (node->_article)
+ candidates.push_back ((ArticleNode*)node);
+ }
+
+ apply_rules(candidates);
}
void
@@ -124,14 +139,19 @@ DataImpl :: MyTree :: set_filter (const Data::ShowType show_type,
DataImpl :: MyTree :: MyTree (DataImpl & data_impl,
const Quark & group,
const Data::ShowType show_type,
- const FilterInfo * filter):
+ const FilterInfo * filter,
+ const RulesInfo * rules,
+ Queue * queue):
_group (group),
_data (data_impl)
{
+
+ _data.set_queue(queue);
_data.ref_group (_group);
_data._trees.insert (this);
+
set_filter (show_type, filter);
- // set_rules (rules)
+ set_rules (show_type, rules);
}
DataImpl :: MyTree :: ~MyTree ()
@@ -165,23 +185,21 @@ DataImpl :: MyTree :: NodeMidCompare
};
void
-DataImpl :: MyTree :: apply_rules (const const_nodes_v& candidates)
+DataImpl :: MyTree :: apply_rules (const_nodes_v& candidates)
{
+
NodeMidCompare compare;
const_nodes_v pass;
- const_nodes_v fail;
pass.reserve (candidates.size());
- fail.reserve (candidates.size());
// apply the rules to the whole tree
- foreach_const (const_nodes_v, candidates, it) {
+ foreach (const_nodes_v, candidates, it) {
if (!(*it)->_article)
continue;
- else if (_data._rules_filter.test_article (_data, _rules, _group, *(*it)->_article))
+ if (_data._rules_filter.test_article (_data, _rules, _group, *(*it)->_article))
pass.push_back (*it);
- else
- fail.push_back (*it);
}
+
//std::cerr << LINE_ID << " " << pass.size() << " of "
// << (pass.size() + fail.size()) << " articles pass\n";
@@ -201,50 +219,46 @@ DataImpl :: MyTree :: apply_rules (const const_nodes_v& candidates)
if (_show_type == Data::SHOW_THREADS || _show_type == Data::SHOW_SUBTHREADS)
{
unique_nodes_t d;
- foreach_const (const_nodes_v, pass, it)
+ foreach (const_nodes_v, pass, it)
accumulate_descendants (d, *it);
//std::cerr << LINE_ID << " expands into " << d.size() << " articles\n";
const_nodes_v fail2;
pass.clear ();
- foreach_const (unique_nodes_t, d, it) {
- const Article * a ((*it)->_article);
- if (a->score > -9999 || _data._rules_filter.test_article (_data, _rules, _group, *a))
- pass.push_back (*it); // pass is now sorted by mid because d was too
- else
- fail2.push_back (*it); // fail2 is sorted by mid because d was too
+ foreach (unique_nodes_t, d, it) {
+ Article * a ((*it)->_article);
+ _data._rules_filter.test_article (_data, _rules, _group, *a);
}
-
- // fail cleanup: add fail2 and remove duplicates.
- // both are sorted by mid, so set_union will do the job
- const_nodes_v tmp;
- tmp.reserve (fail.size() + fail2.size());
- std::set_union (fail.begin(), fail.end(),
- fail2.begin(), fail2.end(),
- inserter (tmp, tmp.begin()), compare);
- fail.swap (tmp);
-
- // fail cleanup: remove newly-passing articles
- tmp.clear ();
- std::set_difference (fail.begin(), fail.end(),
- pass.begin(), pass.end(),
- inserter (tmp, tmp.begin()), compare);
- fail.swap (tmp);
- //std::cerr << LINE_ID << ' ' << pass.size() << " of "
- // << (pass.size() + fail.size())
- // << " make it past the show-thread block\n";
}
+ cache_articles(_data._rules_filter._cached);
+ download_articles(_data._rules_filter._downloaded);
+ _data._rules_filter.finalize(_data);
+}
+void
+DataImpl :: MyTree :: cache_articles (std::set<const Article*> s)
+{
+ if (!_data._queue) return;
+
+ Queue::tasks_t tasks;
+ ArticleCache& cache(_data.get_cache());
+ foreach_const (std::set<const Article*>, s, it)
+ tasks.push_back (new TaskArticle (_data, _data, **it, cache, _data));
+ if (!tasks.empty())
+ _data._queue->add_tasks (tasks, Queue::TOP);
+}
- // passing articles not in the tree should be added...
- add_articles (pass);
-
- // failing articles in the tree should be removed...
- quarks_t mids;
- foreach_const (const_nodes_v, fail, it)
- mids.insert (mids.end(), (*it)->_mid);
- remove_articles (mids);
-
+void
+DataImpl :: MyTree :: download_articles (std::set<const Article*> s)
+{
+ if (!_data._queue) return;
+
+ Queue::tasks_t tasks;
+ ArticleCache& cache(_data.get_cache());
+ foreach_const (std::set<const Article*>, s, it)
+ tasks.push_back (new TaskArticle (_data, _data, **it, cache, _data));
+ if (!tasks.empty())
+ _data._queue->add_tasks (tasks, Queue::TOP);
}
@@ -419,17 +433,21 @@ DataImpl :: MyTree :: accumulate_descendants (unique_nodes_t& descendants,
void
DataImpl :: MyTree :: articles_changed (const quarks_t& mids, bool do_refilter)
{
- if (do_refilter) {
- // refilter... this may cause articles to be shown or hidden
+
+ if (do_refilter)
+ {
const_nodes_v nodes;
_data.find_nodes (mids, _data.get_group_headers(_group)->_nodes, nodes);
- apply_filter (nodes);
apply_rules (nodes);
+ // refilter... this may cause articles to be shown or hidden
+ apply_filter (nodes);
}
+
// fire an update event for any of those mids in our tree...
nodes_v my_nodes;
_data.find_nodes (mids, _nodes, my_nodes);
+
if (!my_nodes.empty()) {
ArticleTree::Diffs diffs;
foreach_const (nodes_v, my_nodes, it)
@@ -443,8 +461,9 @@ DataImpl :: MyTree :: add_articles (const quarks_t& mids)
{
const_nodes_v nodes;
_data.find_nodes (mids, _data.get_group_headers(_group)->_nodes, nodes);
- apply_filter (nodes);
apply_rules (nodes);
+ apply_filter (nodes);
+
}
diff --git a/pan/data-impl/rules-filter.cc b/pan/data-impl/rules-filter.cc
index 05ca5c2..b7598cb 100644
--- a/pan/data-impl/rules-filter.cc
+++ b/pan/data-impl/rules-filter.cc
@@ -28,27 +28,36 @@
using namespace pan;
+void
+RulesFilter :: finalize (Data& data)
+{
+
+ data.delete_articles (_delete);
+ _delete.clear();
+
+ const std::vector<const Article*> tmp (_mark_read.begin(), _mark_read.end());
+ data.mark_read ((const Article**)&tmp.front(), tmp.size());
+ _mark_read.clear();
+
+ _cached.clear();
+ _downloaded.clear();
+}
+
bool
-RulesFilter :: test_article (const Data & data,
- const RulesInfo & rules,
- const Quark & group,
- const Article & article) const
+RulesFilter :: test_article ( Data & data,
+ RulesInfo & rules,
+ const Quark & group,
+ Article & article)
{
- bool pass (false);
- const ArticleCache& cache(data.get_cache());
+
+ bool pass (article.score >= rules._lb && article.score <= rules._hb);
switch (rules._type)
{
case RulesInfo::AGGREGATE_AND:
pass = true;
- foreach_const (RulesInfo::aggregates_t, rules._aggregates, it) {
- // assume test passes if test needs body but article not cached
- if (!it->_needs_body || cache.contains(article.message_id) )
- if (!test_article (data, *it, group, article)) {
- pass = false;
- break;
- }
- }
+ foreach (RulesInfo::aggregates_t, rules._aggregates, it)
+ test_article (data, *it, group, article);
break;
case RulesInfo::AGGREGATE_OR:
@@ -56,20 +65,40 @@ RulesFilter :: test_article (const Data & data,
pass = true;
else {
pass = false;
- foreach_const (RulesInfo::aggregates_t, rules._aggregates, it) {
- // assume test fails if test needs body but article not cached
- if (!it->_needs_body || cache.contains(article.message_id) )
- if (test_article (data, *it, group, article)) {
- pass = true;
- break;
- }
+ foreach (RulesInfo::aggregates_t, rules._aggregates, it) {
+ if (test_article (data, *it, group, article)) {
+ pass = true;
+ break;
+ }
}
}
break;
case RulesInfo::MARK_READ:
- pass = article.score == Article::COMPLETE;
- break;
+
+ if (pass)
+ _mark_read.insert(&article);
+ break;
+
+ case RulesInfo::AUTOCACHE:
+ if (pass)
+ _cached.insert (&article);
+ break;
+
+ case RulesInfo::AUTODOWNLOAD:
+ if (pass)
+ _downloaded.insert (&article);
+ break;
+
+ case RulesInfo::DELETE:
+ if (pass)
+ _delete.insert (&article);
+ break;
+
+ default:
+ debug("error : unknown rules type "<<rules._type);
+ return true;
+ break;
}
return pass;
diff --git a/pan/data-impl/rules-filter.h b/pan/data-impl/rules-filter.h
index c0f4b40..2913fb6 100644
--- a/pan/data-impl/rules-filter.h
+++ b/pan/data-impl/rules-filter.h
@@ -21,6 +21,7 @@
#define __RulesFilter_h__
#include <pan/general/quark.h>
+#include <pan/tasks/queue.h>
#include <pan/usenet-utils/filter-info.h>
#include <pan/usenet-utils/rules-info.h>
#include <pan/usenet-utils/scorefile.h>
@@ -39,11 +40,20 @@ namespace pan
RulesFilter() { }
- bool test_article (const Data& data,
- const RulesInfo & rules,
+ bool test_article (Data & data,
+ RulesInfo & rules,
const Quark& group,
- const Article& article) const;
+ Article& article);
+ private:
+ std::set<const Article*> _mark_read;
+ std::set<const Article*> _delete;
+
+ public:
+
+ std::set<const Article*> _cached;
+ std::set<const Article*> _downloaded;
+ void finalize (Data& data) ;
};
}
diff --git a/pan/data/data.h b/pan/data/data.h
index e2db9be..e33a096 100644
--- a/pan/data/data.h
+++ b/pan/data/data.h
@@ -38,6 +38,7 @@ namespace pan
{
class FilterInfo;
class RulesInfo;
+ class Queue;
/**
* Data Interface class for seeing the mapping between groups and servers.
@@ -470,7 +471,8 @@ namespace pan
virtual void set_filter (const ShowType show_type = SHOW_ARTICLES,
const FilterInfo * filter_or_null_to_reset = 0) = 0;
- virtual void set_rules (const RulesInfo * filterme = 0) = 0;
+ virtual void set_rules (const ShowType show_type = SHOW_ARTICLES,
+ const RulesInfo * filter_or_null_to_reset = 0) = 0;
};
/**
@@ -478,7 +480,9 @@ namespace pan
*/
virtual ArticleTree* group_get_articles (const Quark & group,
const ShowType show_type = SHOW_ARTICLES,
- const FilterInfo * criteria = 0) const=0;
+ const FilterInfo * criteria = 0,
+ const RulesInfo * rules = 0,
+ Queue * queue = 0) const=0;
virtual void group_clear_articles (const Quark& group) = 0;
@@ -506,6 +510,11 @@ namespace pan
virtual void rescore () = 0;
+ ///TODO private!
+ public:
+ Queue * _queue;
+ void set_queue (Queue* q) { _queue = q; }
+
/*****************************************************************
diff --git a/pan/gui/actions.cc b/pan/gui/actions.cc
index 04411af..eb00c95 100644
--- a/pan/gui/actions.cc
+++ b/pan/gui/actions.cc
@@ -82,9 +82,6 @@ namespace
GtkIconSet * icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
gtk_icon_factory_add (factory, my_builtin_icons[i].name, icon_set);
g_object_unref (pixbuf);
-
- //std::cerr << "registered icon " << my_builtin_icons[i].name << std::endl;
-
g_object_unref (pixbuf);
gtk_icon_set_unref (icon_set);
}
@@ -230,6 +227,12 @@ namespace
set_new_match_on_score_state (new_state);
}
+ void do_toggle_rules (GtkToggleAction * a)
+ {
+ prefs->_rules_enabled = gtk_toggle_action_get_active (a);
+ pan_ui->do_enable_toggle_rules(prefs->_rules_enabled);
+ }
+
void do_match_only_watched_articles (GtkToggleAction * a) { set_new_match_on_score_state (gtk_toggle_action_get_active(a) ? MATCH_WATCHED : prev_score_state); }
void do_match_watched_articles (GtkToggleAction * a) { set_score_state_bit_from_toggle (a, MATCH_WATCHED); }
void do_match_high_scoring_articles (GtkToggleAction * a) { set_score_state_bit_from_toggle (a, MATCH_HIGH_SCORING); }
@@ -645,7 +648,9 @@ namespace
{ "match-medium-scoring-articles", NULL, N_("Match Scores of 1...4999 (Me_dium)"), NULL, NULL, G_CALLBACK(do_match_medium_scoring_articles), true },
{ "match-normal-scoring-articles", NULL, N_("Match Scores of 0 (_Normal)"), NULL, NULL, G_CALLBACK(do_match_normal_scoring_articles), true },
{ "match-low-scoring-articles", NULL, N_("Match Scores of -9998...-1 (_Low)"), NULL, NULL, G_CALLBACK(do_match_low_scoring_articles), true },
- { "match-ignored-articles", NULL, N_("Match Scores of -9999 (_Ignored)"), NULL, NULL, G_CALLBACK(do_match_ignored_articles), false }
+ { "match-ignored-articles", NULL, N_("Match Scores of -9999 (_Ignored)"), NULL, NULL, G_CALLBACK(do_match_ignored_articles), false },
+
+ { "enable-rules", NULL, N_("Enable/Disable all _Rules"), "R", NULL, G_CALLBACK(do_toggle_rules), true }
};
const guint n_toggle_entries (G_N_ELEMENTS(toggle_entries));
diff --git a/pan/gui/gui.cc b/pan/gui/gui.cc
index fb1aa0a..421ae02 100644
--- a/pan/gui/gui.cc
+++ b/pan/gui/gui.cc
@@ -588,6 +588,7 @@ GUI :: prompt_user_for_filename (GtkWindow * parent, const Prefs& prefs)
return file;
}
+/// TODO drag-n-drop of nzb files
gboolean GUI ::dragged(GtkWidget *wgt, GdkDragContext *context, int x, int y,
GtkSelectionData *seldata, guint info, guint time,
gpointer userdata)
@@ -597,8 +598,6 @@ gboolean GUI ::dragged(GtkWidget *wgt, GdkDragContext *context, int x, int y,
GUI * p(static_cast<GUI*>(userdata));
- std::cerr<<"dragged\n";
-
GdkAtom target_type;
/* If the source offers a target */
@@ -621,25 +620,23 @@ void GUI ::dragged_rcvd(GtkWidget *wgt, GdkDragContext *context, int x, int y,
gtk_drag_finish (context, true, true, time);
- std::cerr<<"dragged rcvd\n";
-
- GUI * p(static_cast<GUI*>(userdata));
-
- GtkWidget * header_pane;
- GtkTreeIter iter;
-
- header_pane = GTK_WIDGET(userdata);
- std::cerr<<"data : "<<(gchar*)seldata->data<<std::endl;
- Article a;
- a.message_id = Quark((gchar*)seldata->data);
- a.xref.insert ("2", "alt.binaries.test", 0);
- a.set_part_count (1);
- a.is_binary = true;
- std::vector<Article> v;
- v.push_back(a);
- SaveDialog * dialog = new SaveDialog (p->_prefs, p->_group_prefs, p->_data, p->_data,
- p->_cache, p->_data, p->_queue, get_window(p->_root), p->_header_pane->get_group(), v);
- gtk_widget_show (dialog->root());
+// GUI * p(static_cast<GUI*>(userdata));
+//
+// GtkWidget * header_pane;
+// GtkTreeIter iter;
+//
+// header_pane = GTK_WIDGET(userdata);
+//// std::cerr<<"data : "<<(gchar*)seldata->data<<std::endl;
+// Article a;
+// a.message_id = Quark((gchar*)seldata->data);
+// a.xref.insert ("2", "alt.binaries.test", 0);
+// a.set_part_count (1);
+// a.is_binary = true;
+// std::vector<Article> v;
+// v.push_back(a);
+// SaveDialog * dialog = new SaveDialog (p->_prefs, p->_group_prefs, p->_data, p->_data,
+// p->_cache, p->_data, p->_queue, get_window(p->_root), p->_header_pane->get_group(), v);
+// gtk_widget_show (dialog->root());
gtk_drag_finish (context, true, false, time);
@@ -1072,26 +1069,6 @@ void GUI :: prefs_dialog_destroyed_cb (GtkWidget * w, gpointer self)
static_cast<GUI*>(self)->prefs_dialog_destroyed (w);
}
-/*
- w = score_handler_new (prefs, "rules-delete-score-value", "never", b);
- w = score_handler_new (prefs, "rules-mark-read-value", "never", b);
- w = score_handler_new (prefs, "rules-mark-unread-value", "never", b);
- w = score_handler_new (prefs, "rules-autocache-value", "never", b);
- w = score_handler_new (prefs, "rules-auto-dl-value", "never", b);
-*/
-
-#define NUM_RULES 6
-
-//int GUI :: score_int_from_string(std::string val, const char* rules[])
-//{
-// const char* tmp (val.c_str());
-// int res(-1);
-// for (int i=0;i<NUM_RULES;++i) {
-// if (!strcmp(rules[i],tmp)) { res = i; break; }
-// }
-// return res;
-//}
-
void GUI :: prefs_dialog_destroyed (GtkWidget *)
{
@@ -1099,39 +1076,9 @@ void GUI :: prefs_dialog_destroyed (GtkWidget *)
if (!group.empty() && _prefs._rules_changed)
{
_prefs._rules_changed = !_prefs._rules_changed;
- std::string text;
- int no(0);
- _header_pane->rules(no);
+ _header_pane->rules(_prefs._rules_enabled);
}
-// // apply filters
-// if (_prefs._rules_changed && !group.empty())
-// {
-// _prefs._rules_changed = !_prefs._rules_changed;
-// std::map<int, const char*> rules_map;
-//
-// const char* rules [NUM_RULES] = { "never",
-// "watched",
-// "high" ,
-// "medium",
-// "low" ,
-// "ignored" };
-// for (int i=0;i<NUM_RULES;++i)
-// rules_map.insert(std::pair<int,const char*>(i,rules[i]));
-// int val_delete(score_int_from_string(_prefs.get_string("rules-delete-score-value", "never"),rules));
-// int val_read(score_int_from_string(_prefs.get_string("rules-mark-read-value", "never"),rules));
-// int val_unread(score_int_from_string(_prefs.get_string("rules-mark-unread-value", "never"),rules));
-// int val_cache(score_int_from_string(_prefs.get_string("rules-autocache-value", "never"),rules));
-// int val_dl(score_int_from_string(_prefs.get_string("rules-auto-dl-value", "never"),rules));
-//
-// std::cerr<<val_delete<<" "<<val_read<<std::endl;
-//
-// std::vector<const Article*> articles_v (_header_pane->get_full_selection_v());
-//
-// foreach (std::vector<const Article*>, articles_v, vit)
-// {
-//// foreach
-// }
-// }
+
}
@@ -1654,6 +1601,7 @@ void GUI :: do_match_only_cached_articles (bool) { _header_pane->refilter (); }
void GUI :: do_match_only_binary_articles (bool) { _header_pane->refilter (); }
void GUI :: do_match_only_my_articles (bool) { _header_pane->refilter (); }
void GUI :: do_match_on_score_state (int) { _header_pane->refilter (); }
+void GUI :: do_enable_toggle_rules (bool enable) { _header_pane -> rules (enable); }
void GUI :: do_show_matches (const Data::ShowType show_type)
{
diff --git a/pan/gui/gui.h b/pan/gui/gui.h
index 542aa13..7cdfe80 100644
--- a/pan/gui/gui.h
+++ b/pan/gui/gui.h
@@ -144,6 +144,7 @@ namespace pan
virtual void do_match_only_binary_articles (bool);
virtual void do_match_only_my_articles (bool);
virtual void do_match_only_unread_articles (bool);
+ virtual void do_enable_toggle_rules (bool enable);
virtual void do_match_on_score_state (int);
virtual void do_show_matches (const Data::ShowType);
virtual void do_read_selected_group ();
diff --git a/pan/gui/header-pane.cc b/pan/gui/header-pane.cc
index 3e54483..1c7bd50 100644
--- a/pan/gui/header-pane.cc
+++ b/pan/gui/header-pane.cc
@@ -362,8 +362,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)));
@@ -542,7 +540,7 @@ HeaderPane :: set_group (const Quark& new_group)
if (!_group.empty())
{
- _atree = _data.group_get_articles (new_group, _show_type, &_filter);
+ _atree = _data.group_get_articles (new_group, _show_type, &_filter,&_rules,&_queue);
_atree->add_listener (this);
rebuild ();
@@ -1025,38 +1023,63 @@ namespace
MESSAGE_ID
};
- enum
- {
- RULES_MARK_READ,
- RULES_MARK_UNREAD,
- RULES_AUTOCACHE,
- RULES_AUTODL,
- RULES_DELETE
- };
+}
+
+#define RANGE 4998
+int
+HeaderPane :: get_int_from_rules_str(std::string val)
+{
+ if (val == "new") return 0;
+ if (val == "never") return 9999+RANGE+1;
+ if (val == "watched") return 9999;
+ if (val == "high") return 5000;
+ if (val == "medium") return 1;
+ if (val == "low") return -4999;
+ if (val == "ignored") return -9999;
}
void
-HeaderPane :: rebuild_rules (int mode)
+HeaderPane :: rebuild_rules (bool enable)
{
- RulesInfo &f (_rules);
- f.set_type_aggregate_and ();
+ if (!enable)
+ {
+ _rules.clear();
+ return;
+ }
+
+ RulesInfo &r (_rules);
+ r.set_type_aggregate_and ();
RulesInfo tmp;
- if (mode == RULES_MARK_READ) {
- tmp.set_type_mark_read ();
- f._aggregates.push_back (tmp);
- }
-// if (mode == RULES_MARK_UNREAD) {
-// tmp.set_type_mark_unread ();
-// f._aggregates.push_back (tmp);
-// }
+ int backup (get_int_from_rules_str("never"));
+ int val_mark_read(get_int_from_rules_str(_prefs.get_string("rules-mark-read-value", "never")));
+ if (!enable) val_mark_read = backup;
+ int val_delete(get_int_from_rules_str(_prefs.get_string("rules-delete-value", "never")));
+ if (!enable) val_delete = backup;
+ int val_cache(get_int_from_rules_str(_prefs.get_string("rules-autocache-value", "never")));
+ if (!enable) val_cache = backup;
+ int val_dl(get_int_from_rules_str(_prefs.get_string("rules-auto-dl-value", "never")));
+ if (!enable) val_dl = backup;
+
+ tmp.set_type_mark_read_b (val_mark_read, val_mark_read == 0 ? 0 : val_mark_read+RANGE);
+ r._aggregates.push_back (tmp);
+
+ tmp.set_type_delete_b (val_delete, val_delete == 0 ? 0 : val_delete+RANGE);
+ r._aggregates.push_back (tmp);
+
+ tmp.set_type_autocache_b (val_cache, val_cache == 0 ? 0 : val_cache+RANGE);
+ r._aggregates.push_back (tmp);
+
+ tmp.set_type_dl_b (val_dl, val_dl == 0 ? 0 : val_dl+RANGE);
+ r._aggregates.push_back (tmp);
}
void
HeaderPane :: rebuild_filter (const std::string& text, int mode)
{
+
TextMatch::Description d;
d.negate = false;
d.case_sensitive = false;
@@ -1204,16 +1227,22 @@ HeaderPane :: filter (const std::string& text, int mode)
}
void
-HeaderPane :: rules(int mode)
+HeaderPane :: rules(bool enable)
{
- if (_prefs.get_string("rules-mark-read-value","never") != "never")
- rebuild_rules(RULES_MARK_READ);
+ rebuild_rules(enable);
- if (_rules._aggregates.empty())
- _atree->set_rules();
- else
- _atree->set_rules(&_rules);
+ if (_atree)
+ {
+ _wait.watch_cursor_on ();
+ if (_rules._aggregates.empty()) {
+ _atree->set_rules();
+ }
+ else
+ _atree->set_rules(_show_type, &_rules);
+
+ _wait.watch_cursor_off ();
+ }
}
namespace
@@ -1691,6 +1720,7 @@ HeaderPane :: HeaderPane (ActionManager & action_manager,
_root = scroll;
search_activate (this); // calls rebuild_filter
+ rules();
_data.add_listener (this);
_prefs.add_listener (this);
@@ -2113,10 +2143,11 @@ HeaderPane :: on_queue_task_removed (Queue&, Task& task, int)
void
HeaderPane :: on_cache_added (const Quark& message_id)
{
- quarks_t q;
- q.insert(message_id);
- _data.rescore_articles ( _group, q );
- rebuild_article_action (message_id);
+ /// SLOOOOW!
+// quarks_t q;
+// q.insert(message_id);
+// _data.rescore_articles ( _group, q );
+// rebuild_article_action (message_id);
}
void
HeaderPane :: on_cache_removed (const quarks_t& message_ids)
diff --git a/pan/gui/header-pane.h b/pan/gui/header-pane.h
index 532226d..37ccfcb 100644
--- a/pan/gui/header-pane.h
+++ b/pan/gui/header-pane.h
@@ -304,12 +304,13 @@ namespace pan
private:
void rebuild_filter (const std::string&, int);
- void rebuild_rules (int mode);
+ void rebuild_rules (bool enable=false);
+ int get_int_from_rules_str(std::string val);
void refresh_font ();
public: // public so that anonymous namespace can reach -- don't call
void filter (const std::string& text, int mode);
- void rules (int mode);
+ void rules (bool enable=false);
static void do_popup_menu (GtkWidget*, GdkEventButton*, gpointer);
static void on_row_activated (GtkTreeView*, GtkTreePath*, GtkTreeViewColumn*, gpointer);
static gboolean on_button_pressed (GtkWidget*, GdkEventButton*, gpointer);
diff --git a/pan/gui/pan-ui.h b/pan/gui/pan-ui.h
index 47c7ab5..8c56d35 100644
--- a/pan/gui/pan-ui.h
+++ b/pan/gui/pan-ui.h
@@ -116,6 +116,8 @@ namespace pan
virtual void do_match_only_my_articles (bool) = 0;
virtual void do_show_matches (const Data::ShowType) = 0;
+ virtual void do_enable_toggle_rules (bool enable) = 0;
+
#define MATCH_IGNORED (1<<0)
#define MATCH_LOW_SCORING (1<<1)
#define MATCH_NORMAL_SCORING (1<<2)
diff --git a/pan/gui/pan.ui.h b/pan/gui/pan.ui.h
index b2f8479..b2da2b7 100644
--- a/pan/gui/pan.ui.h
+++ b/pan/gui/pan.ui.h
@@ -42,6 +42,8 @@ const char * fallback_ui_file =
" <menu action='view-header-pane-menu'>\n"
" <menuitem action='thread-headers' />\n"
" <separator />\n"
+" <menuitem action='enable-rules' />\n"
+" <separator />\n"
" <menuitem action='show-matching-articles' />\n"
" <menuitem action='show-matching-threads' />\n"
" <menuitem action='show-matching-subthreads' />\n"
diff --git a/pan/gui/prefs-ui.cc b/pan/gui/prefs-ui.cc
index 3144e34..cdeeb52 100644
--- a/pan/gui/prefs-ui.cc
+++ b/pan/gui/prefs-ui.cc
@@ -256,7 +256,8 @@ namespace
// build the combo box...
const std::string mode (prefs.get_string (mode_key, mode_fallback));
GtkListStore * store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
- const char* strings[6][2] = { { N_("Disabled"),"never" },
+ const char* strings[7][2] = { { N_("Disabled"),"never" },
+ { N_("Only new (Score == 0)"),"new" },
{ N_("9999 or more"), "watched" },
{ N_("5000 to 9998"), "high" },
{ N_("1 to 4999"), "medium" },
@@ -586,12 +587,10 @@ PrefsDialog :: PrefsDialog (Prefs& prefs, GtkWindow* parent):
gtk_widget_set_tooltip_text (t, _("This menu lets you configure Pan to take certain actions on your behalf automatically, based on a post's score."));
- w = score_handler_new (prefs, "rules-delete-score-value", "never", b);
+ w = score_handler_new (prefs, "rules-delete-value", "never", b);
HIG :: workarea_add_row (t, &row, _("_Delete Posts scoring at: "), w);
w = score_handler_new (prefs, "rules-mark-read-value", "never", b);
HIG :: workarea_add_row (t, &row, _("Mark Posts _read scoring at: "), w);
- w = score_handler_new (prefs, "rules-mark-unread-value", "never", b);
- HIG :: workarea_add_row (t, &row, _("Mark Posts _unread scoring at: "), w);
w = score_handler_new (prefs, "rules-autocache-value", "never", b);
HIG :: workarea_add_row (t, &row, _("_Cache Posts scoring at: "), w);
w = score_handler_new (prefs, "rules-auto-dl-value", "never", b);
diff --git a/pan/gui/prefs.h b/pan/gui/prefs.h
index a4527d3..a3215a7 100644
--- a/pan/gui/prefs.h
+++ b/pan/gui/prefs.h
@@ -131,6 +131,7 @@ namespace pan
public:
bool _rules_changed;
+ bool _rules_enabled;
};
}
diff --git a/pan/gui/save-ui.cc b/pan/gui/save-ui.cc
index 339aa41..21a4cf3 100644
--- a/pan/gui/save-ui.cc
+++ b/pan/gui/save-ui.cc
@@ -141,7 +141,7 @@ SaveDialog :: response_cb (GtkDialog * dialog,
std::string sep( self->_prefs.get_string("save-subj-seperator", "-") );
- // make the tasks...
+ // make the tasks...
Queue::tasks_t tasks;
foreach_const (std::vector<Article>, self->_articles, it)
{
diff --git a/pan/tasks/task-article.h b/pan/tasks/task-article.h
index 37298a8..73befae 100644
--- a/pan/tasks/task-article.h
+++ b/pan/tasks/task-article.h
@@ -27,6 +27,7 @@
#include <pan/general/worker-pool.h>
#include <pan/data/article.h>
#include <pan/data/article-cache.h>
+#include <pan/data/server-info.h>
#include <pan/data/data.h>
#include <pan/data/xref.h>
#include <pan/tasks/nntp.h>
@@ -35,6 +36,7 @@
namespace pan
{
struct Decoder;
+ class Data;
/**
* Task for downloading, and optionally decoding, articles
diff --git a/pan/tasks/task-xover.cc b/pan/tasks/task-xover.cc
index a027d89..46ce503 100644
--- a/pan/tasks/task-xover.cc
+++ b/pan/tasks/task-xover.cc
@@ -85,16 +85,6 @@ namespace
}
}
-namespace
-{
- char* build_cachename (char* buf, size_t len, const char* name)
- {
- const char * home(file::get_pan_home().c_str());
- g_snprintf(buf,len,"%s%c%s%c%s",home, G_DIR_SEPARATOR, "encode-cache", G_DIR_SEPARATOR, name);
- return buf;
- }
-}
-
TaskXOver :: TaskXOver (Data & data,
const Quark & group,
Mode mode,
diff --git a/pan/usenet-utils/filter-info.cc b/pan/usenet-utils/filter-info.cc
index 2e25835..f83b939 100644
--- a/pan/usenet-utils/filter-info.cc
+++ b/pan/usenet-utils/filter-info.cc
@@ -54,6 +54,7 @@ FilterInfo :: set_type_ge (Type type, unsigned long ge) {
_type = type;
_ge = ge;
}
+
void
FilterInfo :: set_type_le (Type type, unsigned long le) {
clear ();
diff --git a/pan/usenet-utils/filter-info.h b/pan/usenet-utils/filter-info.h
index 13e53ac..408b6ae 100644
--- a/pan/usenet-utils/filter-info.h
+++ b/pan/usenet-utils/filter-info.h
@@ -29,7 +29,7 @@ namespace pan
{
/**
* Interface class describing a filter that can be applied to a set of articles.
- * @ingroup usenet_utils
+ * @ingroup usenet_utils
*/
class FilterInfo
{
diff --git a/pan/usenet-utils/rules-info.cc b/pan/usenet-utils/rules-info.cc
index e6d2ec2..bb3c2a3 100644
--- a/pan/usenet-utils/rules-info.cc
+++ b/pan/usenet-utils/rules-info.cc
@@ -17,6 +17,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <iostream>
+#include <pan/general/debug.h>
+#include <pan/tasks/queue.h>
+
#include <config.h>
extern "C" {
#include <glib.h>
@@ -36,8 +40,9 @@ RulesInfo :: clear ()
{
_type = RulesInfo::TYPE_ERR;
_aggregates.clear ();
+ _lb = _hb = 0;
+ _ge = 0;
_negate = false;
- _needs_body = false;
}
void
@@ -47,10 +52,26 @@ RulesInfo :: set_type_is (Type type) {
}
void
+RulesInfo :: set_type_ge (Type type, unsigned long ge) {
+ clear ();
+ _type = type;
+ _ge = ge;
+}
+
+void
RulesInfo :: set_type_le (Type type, unsigned long le) {
clear ();
_type = type;
_negate = true;
+ _ge = le+1; // le N == !ge N+1
+}
+
+void
+RulesInfo :: set_type_bounds (Type type, int low, int high)
+{
+ clear ();
+ _type = type;
+ _lb = low; _hb = high;
}
void
@@ -70,8 +91,25 @@ RulesInfo :: set_type_aggregate_or () {
void
-RulesInfo :: set_type_mark_read ()
+RulesInfo :: set_type_mark_read_b (int lb, int hb)
{
- set_type_is (MARK_READ);
+ set_type_bounds (MARK_READ, lb, hb);
}
+void
+RulesInfo :: set_type_autocache_b (int lb, int hb)
+{
+ set_type_bounds (AUTOCACHE, lb, hb);
+}
+
+void
+RulesInfo :: set_type_dl_b (int lb, int hb)
+{
+ set_type_bounds (AUTODOWNLOAD, lb, hb);
+}
+
+void
+RulesInfo :: set_type_delete_b (int lb, int hb)
+{
+ set_type_bounds (DELETE, lb, hb);
+}
diff --git a/pan/usenet-utils/rules-info.h b/pan/usenet-utils/rules-info.h
index 3165c82..ebc71d8 100644
--- a/pan/usenet-utils/rules-info.h
+++ b/pan/usenet-utils/rules-info.h
@@ -41,7 +41,6 @@ namespace pan
AGGREGATE_AND,
AGGREGATE_OR,
MARK_READ,
- MARK_UNREAD,
AUTOCACHE,
AUTODOWNLOAD,
DELETE
@@ -67,18 +66,25 @@ namespace pan
/** When this is true, the results of the test should be negated. */
bool _negate;
- /** When this is true the test needs the article body. */
- bool _needs_body;
-
private:
void set_type_is (Type type);
void set_type_le (Type type, unsigned long le);
+ void set_type_ge (Type type, unsigned long ge);
+ void set_type_bounds (Type type, int low, int high);
+
public:
+
+ unsigned long _ge;
+ int _lb, _hb;
+
void clear ();
void set_type_aggregate_and ();
void set_type_aggregate_or ();
- void set_type_mark_read ();
+ void set_type_mark_read_b (int lb, int hb);
+ void set_type_autocache_b (int lb, int hb);
+ void set_type_dl_b (int lb, int hb);
+ void set_type_delete_b (int lb, int hb);
};
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]