~ubuntu-branches/ubuntu/vivid/liferea/vivid-proposed

« back to all changes in this revision

Viewing changes to src/vfolder.c

  • Committer: Package Import Robot
  • Author(s): Moray Allan, Bojo42, Rodrigo Gallardo, Moray Allan
  • Date: 2012-03-27 21:44:42 UTC
  • mfrom: (1.5.1)
  • mto: (3.3.2 experimental)
  • mto: This revision was merged to the branch mainline in revision 122.
  • Revision ID: package-import@ubuntu.com-20120327214442-g0xfh714cdmsbnts
Tags: 1.8.3-0.1
[ Bojo42 ]
* Non-maintainer upload.
* New upstream release (Closes: #502307, #623619, #631778, #651913) 
* debian/patches:
  - drop libnotify0.7 as in upstream
  - debian-example-feeds: update, move planets from "News" to "Open Source"
  - www-browser: update due to new file location
  - libtool-dont-rearange-as-needed: rebase
* debian/control:
  - update Standards-Version
  - remove obsolete Build-Depends:
    - quilt not needed for "3.0 (quilt)" source format
    - libnm-glib-dev & libdbus-glib-1-dev: upstream switched to GDBus
    - liblua5.1-0-dev: LUA scripting support got dropped
  - new Build-Depends on libunique-dev, libjson-glib-dev & dh_autoreconf
  - update version dependencies
* debian/rules: run dh_autoreconf & update translations
* debian/liferea.install: nothing to ship from /usr/lib/liferea

[ Rodrigo Gallardo ]
* Lintian love:
  - debian/control: switch from Conflicts to Breaks
  - debian/rules: redo build targets

[ Moray Allan ]
* debian/copyright: update to include additional copyright owners.
* debian/patches/www-browser: also set default external browser.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/**
2
2
 * @file vfolder.c  search folder node type
3
3
 *
4
 
 * Copyright (C) 2003-2009 Lars Lindner <lars.lindner@gmail.com>
 
4
 * Copyright (C) 2003-2011 Lars Lindner <lars.lindner@gmail.com>
5
5
 *
6
6
 * This program is free software; you can redistribute it and/or modify
7
7
 * it under the terms of the GNU General Public License as published by
18
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
19
 */
20
20
 
 
21
#include "vfolder.h"
 
22
 
21
23
#include "common.h"
22
 
#include "conf.h"
23
24
#include "db.h"
24
25
#include "debug.h"
25
26
#include "feedlist.h"
26
27
#include "itemset.h"
27
28
#include "itemlist.h"
28
29
#include "node.h"
29
 
#include "vfolder.h"
30
 
#include "ui/ui_common.h"
31
 
#include "ui/ui_feedlist.h"
 
30
#include "rule.h"
 
31
#include "vfolder_loader.h"
 
32
#include "ui/icons.h"
32
33
#include "ui/ui_node.h"
33
34
#include "ui/search_folder_dialog.h"
34
35
 
43
44
        debug_enter ("vfolder_new");
44
45
 
45
46
        vfolder = g_new0 (struct vfolder, 1);
 
47
        vfolder->itemset = g_new0 (struct itemSet, 1);
 
48
        vfolder->itemset->nodeId = node->id;
 
49
        vfolder->itemset->ids = NULL;
 
50
        vfolder->itemset->anyMatch = TRUE;
46
51
        vfolder->node = node;
47
 
        vfolder->anyMatch = TRUE;
48
52
        vfolders = g_slist_append (vfolders, vfolder);
49
53
 
50
54
        if (!node->title)
64
68
        
65
69
        matchType = xmlGetProp (cur, BAD_CAST"matchType");
66
70
        if (matchType) {
67
 
                /* currently we now only OR or AND'ing the rules,
 
71
                /* currently we only OR or AND the rules,
68
72
                   "any" is the value for OR'ing, "all" for AND'ing */
69
 
                vfolder->anyMatch = (0 != xmlStrcmp (matchType, BAD_CAST"all"));
 
73
                vfolder->itemset->anyMatch = (0 != xmlStrcmp (matchType, BAD_CAST"all"));
70
74
        } else {
71
 
                vfolder->anyMatch = TRUE;
 
75
                vfolder->itemset->anyMatch = TRUE;
72
76
        }
73
77
        xmlFree (matchType);
74
78
 
87
91
                                        debug2 (DEBUG_CACHE, "loading rule \"%s\" \"%s\"", ruleId, value);
88
92
 
89
93
                                        if (additive && !xmlStrcmp (additive, BAD_CAST"true"))
90
 
                                                vfolder_add_rule (vfolder, ruleId, value, TRUE);
 
94
                                                itemset_add_rule (vfolder->itemset, ruleId, value, TRUE);
91
95
                                        else
92
 
                                                vfolder_add_rule (vfolder, ruleId, value, FALSE);
 
96
                                                itemset_add_rule (vfolder->itemset, ruleId, value, FALSE);
93
97
                                } else {
94
98
                                        g_warning ("ignoring invalid rule entry for vfolder \"%s\"...\n", node_get_title (vfolder->node));
95
99
                                }
107
111
static itemSetPtr
108
112
vfolder_load (nodePtr node) 
109
113
{
110
 
        return db_view_load (node->id);
111
 
}
112
 
 
113
 
void
114
 
vfolder_update_counters (nodePtr node) 
115
 
{
116
114
        vfolderPtr vfolder = (vfolderPtr)node->data;
117
 
        
118
 
        /* Avoid throwing a "view unread count failed (error code 101, not an error)"
119
 
           warning in the database when there are no rules yet. */
120
 
        if (vfolder->rules) {
121
 
                node->unreadCount = db_view_get_unread_count (node->id);
122
 
                node->itemCount = db_view_get_item_count (node->id);
123
 
        } else {
124
 
                node->unreadCount = 0;
125
 
                node->itemCount = 0;
126
 
        }
127
 
        ui_node_update (node->id);
128
 
}
129
 
 
130
 
void
131
 
vfolder_refresh (vfolderPtr vfolder)
132
 
{
133
 
        g_return_if_fail (NULL != vfolder->node);
134
 
 
135
 
        if (0 != g_slist_length (vfolder->rules))
136
 
                rules_to_view (vfolder->rules, vfolder->anyMatch, vfolder->node->id);
137
 
        
138
 
        vfolder_update_counters (vfolder->node);
139
 
}
140
 
 
141
 
static gboolean
142
 
vfolder_is_affected (vfolderPtr vfolder, const gchar *ruleName)
143
 
{
144
 
        GSList *iter = vfolder->rules;
145
 
        while (iter) {
146
 
                rulePtr rule = (rulePtr)iter->data;
147
 
                if (g_str_equal (rule->ruleInfo->ruleId, ruleName))
148
 
                        return TRUE;
149
 
                iter = g_slist_next(iter);
150
 
        }
151
 
        return FALSE;
 
115
 
 
116
        return vfolder->itemset;
152
117
}
153
118
 
154
119
void
155
120
vfolder_foreach (nodeActionFunc func)
156
121
{
157
 
        vfolder_foreach_with_rule (NULL, func);
158
 
}
159
 
 
160
 
void
161
 
vfolder_foreach_with_rule (const gchar *ruleName, nodeActionFunc func) 
162
 
{
163
 
        GSList  *iter = vfolders;
164
 
        
165
 
        g_assert (NULL != func);
166
 
        while (iter) {
167
 
                vfolderPtr vfolder = (vfolderPtr)iter->data;
168
 
                if (!ruleName || vfolder_is_affected (vfolder, ruleName))
169
 
                        (*func) (vfolder->node);
170
 
                iter = g_slist_next (iter);
171
 
        }
172
 
}
173
 
 
174
 
void
175
 
vfolder_foreach_with_item (gulong itemId, nodeActionFunc func)
176
 
{
177
 
        GSList  *iter = vfolders;
178
 
        
179
 
        while (iter) {
180
 
                vfolderPtr vfolder = (vfolderPtr)iter->data;
181
 
                if (db_view_contains_item (vfolder->node->id, itemId))
182
 
                        (*func) (vfolder->node);        
183
 
                iter = g_slist_next (iter);
184
 
        }
 
122
        GSList  *iter = vfolders;
 
123
        
 
124
        g_assert (NULL != func);
 
125
        while (iter) {
 
126
                vfolderPtr vfolder = (vfolderPtr)iter->data;
 
127
                (*func)(vfolder->node);
 
128
                iter = g_slist_next (iter);             
 
129
        }       
 
130
}
 
131
 
 
132
void
 
133
vfolder_foreach_data (vfolderActionDataFunc func, itemPtr item)
 
134
{
 
135
        GSList  *iter = vfolders;
 
136
        
 
137
        g_assert (NULL != func);
 
138
        while (iter) {
 
139
                vfolderPtr vfolder = (vfolderPtr)iter->data;
 
140
                (*func) (vfolder, item);
 
141
                iter = g_slist_next (iter);
 
142
        }
 
143
}
 
144
 
 
145
void
 
146
vfolder_remove_item (vfolderPtr vfolder, itemPtr item)
 
147
{
 
148
        if (!vfolder->itemset->ids)
 
149
                return;
 
150
                
 
151
        vfolder->itemset->ids = g_list_remove (vfolder->itemset->ids, GUINT_TO_POINTER (item->id));
 
152
        vfolder->node->needsUpdate = TRUE;
 
153
}
 
154
 
 
155
void
 
156
vfolder_add_item (vfolderPtr vfolder, itemPtr item)
 
157
{
 
158
        vfolder->itemset->ids = g_list_append (vfolder->itemset->ids, GUINT_TO_POINTER (item->id));
 
159
        vfolder->node->needsUpdate = TRUE;
 
160
}
 
161
 
 
162
void
 
163
vfolder_merge_item (vfolderPtr vfolder, itemPtr item)
 
164
{
 
165
        gboolean found = itemset_has_item_id (vfolder->itemset, item->id);
 
166
 
 
167
        if (itemset_check_item (vfolder->itemset, item)) {
 
168
                if (!found)
 
169
                        vfolder_add_item (vfolder, item);
 
170
        } else {
 
171
                if (found)
 
172
                        vfolder_remove_item (vfolder, item);
 
173
        }
 
174
}
 
175
 
 
176
GSList *
 
177
vfolder_get_all_with_item_id (gulong id)
 
178
{
 
179
        GSList  *result = NULL;
 
180
        GSList  *iter = vfolders;
 
181
        
 
182
        while (iter) {
 
183
                vfolderPtr vfolder = (vfolderPtr)iter->data;
 
184
                if (g_list_find (vfolder->itemset->ids, GUINT_TO_POINTER (id)))
 
185
                        result = g_slist_append (result, vfolder);
 
186
                iter = g_slist_next (iter);
 
187
        }
 
188
 
 
189
        return result;
185
190
}
186
191
 
187
192
static void
195
200
        debug1 (DEBUG_CACHE, "import vfolder: title=%s", node_get_title (node));
196
201
 
197
202
        vfolder = vfolder_new (node);
 
203
        vfolder->itemset = db_search_folder_load (node->id);
 
204
        
198
205
        vfolder_import_rules (cur, vfolder);
199
 
        vfolder_refresh (vfolder);
200
206
}
201
207
 
202
208
static void
213
219
        
214
220
        g_assert (TRUE == trusted);
215
221
        
216
 
        xmlNewProp (cur, BAD_CAST"matchType", BAD_CAST (vfolder->anyMatch?"any":"all"));
 
222
        xmlNewProp (cur, BAD_CAST"matchType", BAD_CAST (vfolder->itemset->anyMatch?"any":"all"));
217
223
 
218
 
        iter = vfolder->rules;
 
224
        iter = vfolder->itemset->rules;
219
225
        while (iter) {
220
226
                rule = iter->data;
221
227
                ruleNode = xmlNewChild (cur, NULL, BAD_CAST"outline", NULL);
237
243
}
238
244
 
239
245
void
240
 
vfolder_add_existing_rule (vfolderPtr vfolder, rulePtr rule)
241
 
{
242
 
        vfolder->rules = g_slist_append (vfolder->rules, rule);
243
 
}
244
 
 
245
 
void
246
 
vfolder_add_rule (vfolderPtr vfolder,
247
 
                  const gchar *ruleId,
248
 
                  const gchar *value,
249
 
                  gboolean additive)
250
 
{
251
 
        rulePtr         rule;
252
 
        
253
 
        rule = rule_new (vfolder, ruleId, value, additive);
254
 
        if (rule)
255
 
                vfolder_add_existing_rule (vfolder, rule);
256
 
        else
257
 
                g_warning ("unknown search folder rule id: \"%s\"", ruleId);
258
 
}
259
 
 
260
 
void
261
 
vfolder_remove_rule (vfolderPtr vfolder, rulePtr rule) 
262
 
{
263
 
        vfolder->rules = g_slist_remove (vfolder->rules, rule);
 
246
vfolder_reset (vfolderPtr vfolder)
 
247
{
 
248
        itemlist_unload (FALSE);
 
249
 
 
250
        g_list_free (vfolder->itemset->ids);
 
251
        vfolder->itemset->ids = NULL;
 
252
        db_search_folder_reset (vfolder->node->id);
 
253
}
 
254
 
 
255
void
 
256
vfolder_rebuild (nodePtr node)
 
257
{
 
258
        vfolderPtr      vfolder = (vfolderPtr)node->data;
 
259
 
 
260
        vfolder_reset (vfolder);
 
261
        itemlist_add_loader (vfolder_loader_new (node));
264
262
}
265
263
 
266
264
static void
267
265
vfolder_free (nodePtr node) 
268
266
{
269
267
        vfolderPtr      vfolder = (vfolderPtr) node->data;
270
 
        GSList          *rule;
271
268
 
272
269
        debug_enter ("vfolder_free");
273
270
        
274
271
        vfolders = g_slist_remove (vfolders, vfolder);
275
 
        
276
 
        /* free vfolder rules */
277
 
        rule = vfolder->rules;
278
 
        while (rule) {
279
 
                rule_free (rule->data);
280
 
                rule = g_slist_next (rule);
281
 
        }
282
 
        g_slist_free (vfolder->rules);
283
 
        vfolder->rules = NULL;
284
 
        
 
272
        itemset_free (vfolder->itemset);
 
273
                
285
274
        debug_exit ("vfolder_free");
286
275
}
287
276
 
290
279
static void vfolder_save (nodePtr node) { }
291
280
 
292
281
static void
293
 
vfolder_update_unread_count (nodePtr node) 
 
282
vfolder_update_counters (nodePtr node) 
294
283
{
295
 
        g_warning("Should never be called!");
 
284
        vfolderPtr vfolder = (vfolderPtr) node->data;
 
285
        
 
286
        /* There is no unread handling for search folders
 
287
           for performance reasons. So set everything to 0 
 
288
           here and don't bother with GUI updates... */
 
289
        vfolder->node->needsUpdate = TRUE;
 
290
        vfolder->node->unreadCount = 0;
 
291
        vfolder->node->itemCount = g_list_length (vfolder->itemset->ids);
296
292
}
297
293
 
298
294
static void
299
295
vfolder_remove (nodePtr node) 
300
296
{
301
 
        db_view_remove (node->id);
 
297
        vfolder_reset (node->data);
302
298
}
303
299
 
304
300
static void
324
320
325
321
        static struct nodeType nti = {
326
322
                NODE_CAPABILITY_SHOW_ITEM_FAVICONS |
327
 
                NODE_CAPABILITY_SHOW_UNREAD_COUNT |
328
323
                NODE_CAPABILITY_SHOW_ITEM_COUNT,
329
324
                "vfolder",
330
325
                NULL,
332
327
                vfolder_export,
333
328
                vfolder_load,
334
329
                vfolder_save,
335
 
                vfolder_update_unread_count,
 
330
                vfolder_update_counters,
336
331
                vfolder_remove,
337
332
                node_default_render,
338
333
                vfolder_add,
339
334
                vfolder_properties,
340
335
                vfolder_free
341
336
        };
342
 
        nti.icon = icons[ICON_VFOLDER];
 
337
        nti.icon = icon_get (ICON_VFOLDER);
343
338
 
344
339
        return &nti; 
345
340
}