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

« back to all changes in this revision

Viewing changes to src/ui/itemview.c

  • Committer: Package Import Robot
  • Author(s): bojo42
  • Date: 2012-03-29 14:17:21 UTC
  • mfrom: (1.3.9) (3.2.5 sid)
  • Revision ID: package-import@ubuntu.com-20120329141721-tbfopcrc5797wxt7
Tags: 1.8.3-0.1ubuntu1
* New upstream release (LP: #290666, #371754, #741543, #716688)
* Merge from Debian unstable (LP: #935147), remaining changes:
* debian/patches:
  - drop gtk-status-icon.patch & notification-append as in upstream
  - drop fix_systray_behavior as mostly upstreamed and rest seems unused
  - 01_ubuntu_feedlists: update & rename, move planets to "Open Source"  
  - add_X-Ubuntu-Gettext-Domain: rebase
  - libunity.patch: rebase, apply before indicator patch (liferea_shell.c)
  - libindicate_increase_version.patch: exclude from libindicate.patch
  - deactivate libindicate.patch, seems partly upstreamed and needs rework
* debian/control: libindicate-dev, libindicate-gtk-dev & libunity-dev
* debian/liferea.indicate & liferea.install: ship indicator desktop file
* debian/rules: enable libindicate

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/**
2
2
 * @file itemview.c  viewing feed content in different presentation modes
3
3
 * 
4
 
 * Copyright (C) 2006-2009 Lars Lindner <lars.lindner@gmail.com>
 
4
 * Copyright (C) 2006-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
31
31
#include "vfolder.h"
32
32
#include "ui/ui_common.h"
33
33
#include "ui/liferea_shell.h"
34
 
#include "ui/ui_itemlist.h"
 
34
#include "ui/item_list_view.h"
35
35
#include "ui/liferea_htmlview.h"
36
36
 
37
 
static void itemview_class_init (ItemViewClass *klass);
38
 
static void itemview_init       (ItemView *fl);
 
37
/* The item view is the layer that switches item list presentations:
 
38
   a HTML single item or list and GtkTreeView list presentation. 
 
39
   It hides the item loading behaviour of GtkTreeView and HTML view.
 
40
 
 
41
   The item view does not handle item filtering, which is done by
 
42
   the item list implementation.
 
43
 */
39
44
 
40
45
#define ITEMVIEW_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), ITEMVIEW_TYPE, ItemViewPrivate))
41
46
 
43
48
        gboolean        htmlOnly;               /**< TRUE if HTML only mode */
44
49
        guint           mode;                   /**< current item view mode */
45
50
        nodePtr         node;                   /**< the node whose item are displayed */
46
 
        gchar           *userDefinedDateFmt;    /**< user defined date formatting string */
47
51
        gboolean        needsHTMLViewUpdate;    /**< flag to be set when HTML rendering is to be 
48
52
                                                     updated, used to delay HTML updates */
 
53
        gboolean        hasEnclosures;          /**< TRUE if at least one item of the current itemset has an enclosure */
49
54
                                                     
50
55
        nodeViewType    viewMode;               /**< current viewing mode */
51
56
        guint           currentLayoutMode;      /**< layout mode (3 pane, 2 pane, wide view) */
52
57
                                                                     
53
 
        GtkWidget       *itemlistContainer;     /**< scrolled window holding item list tree view */
54
 
        GtkTreeView     *itemlist;              
 
58
        GtkWidget       *itemListViewContainer; /**< scrolled window holding item list tree view */
 
59
        ItemListView    *itemListView;          /**< widget instance used to present items in list mode */
55
60
 
56
61
        EnclosureListView       *enclosureView; /**< Enclosure list widget */
57
 
        LifereaHtmlView         *htmlview;      /**< HTML rendering widget used for item display */
 
62
        LifereaHtmlView         *htmlview;      /**< HTML rendering widget instance used to render single items and summaries mode */
58
63
 
59
64
        gfloat                  zoom;           /**< HTML rendering widget zoom level */
60
65
};
62
67
static GObjectClass *parent_class = NULL;
63
68
static ItemView *itemview = NULL;
64
69
 
65
 
GType
66
 
itemview_get_type (void) 
67
 
{
68
 
        static GType type = 0;
69
 
 
70
 
        if (G_UNLIKELY (type == 0)) 
71
 
        {
72
 
                static const GTypeInfo our_info = 
73
 
                {
74
 
                        sizeof (ItemViewClass),
75
 
                        NULL, /* base_init */
76
 
                        NULL, /* base_finalize */
77
 
                        (GClassInitFunc) itemview_class_init,
78
 
                        NULL,
79
 
                        NULL, /* class_data */
80
 
                        sizeof (ItemView),
81
 
                        0, /* n_preallocs */
82
 
                        (GInstanceInitFunc) itemview_init,
83
 
                        NULL /* value_table */
84
 
                };
85
 
 
86
 
                type = g_type_register_static (G_TYPE_OBJECT,
87
 
                                               "ItemView",
88
 
                                               &our_info, 0);
89
 
        }
90
 
 
91
 
        return type;
92
 
}
 
70
G_DEFINE_TYPE (ItemView, itemview, G_TYPE_OBJECT);
93
71
 
94
72
static void
95
73
itemview_finalize (GObject *object)
105
83
        
106
84
        if (priv->enclosureView)
107
85
                g_object_unref (priv->enclosureView);
108
 
                
109
 
        g_free (priv->userDefinedDateFmt);
 
86
        if (priv->itemListView)
 
87
                g_object_unref (priv->itemListView);
110
88
 
111
89
        G_OBJECT_CLASS (parent_class)->finalize (object);
112
90
}
126
104
void
127
105
itemview_clear (void) 
128
106
{
129
 
 
130
 
        ui_itemlist_clear ();
 
107
        item_list_view_clear (itemview->priv->itemListView);
131
108
        htmlview_clear ();
132
109
        enclosure_list_view_hide (itemview->priv->enclosureView);
133
 
        
 
110
        itemview->priv->hasEnclosures = FALSE;
134
111
        itemview->priv->needsHTMLViewUpdate = TRUE;
135
112
}
136
113
 
151
128
                
152
129
        itemview->priv->node = node;
153
130
 
154
 
        /* 1. Perform UI item list preparations ... */
155
 
 
156
 
        /* Free the old itemstore and create a new one; this is the only way to disable sorting */
157
 
        ui_itemlist_reset_tree_store ();         /* this also clears the itemlist. */
158
 
 
159
 
        /* Disable attachment icon column (will be enabled when loading first item with an enclosure) */
160
 
        ui_itemlist_enable_encicon_column (FALSE);
161
 
 
162
 
        if (node) {
163
 
                ui_itemlist_enable_favicon_column (NODE_TYPE (node)->capabilities & NODE_CAPABILITY_SHOW_ITEM_FAVICONS);
164
 
                ui_itemlist_set_sort_column (node->sortColumn, node->sortReversed);
165
 
        }
166
 
 
167
 
        /* 2. Reset view state */
 
131
        /* 1. Reset view state */
168
132
        itemview_clear ();
169
133
 
170
 
        /* 3. And prepare HTML view */
 
134
        /* 2. And prepare HTML view */
171
135
        htmlview_set_displayed_node (node);
172
136
}
173
137
 
174
138
void
175
139
itemview_add_item (itemPtr item)
176
140
{
 
141
        itemview->priv->hasEnclosures |= item->hasEnclosure;
 
142
 
177
143
        if (ITEMVIEW_ALL_ITEMS != itemview->priv->mode)
178
144
                /* add item in 3 pane mode */
179
 
                ui_itemlist_add_item (item);
 
145
                item_list_view_add_item (itemview->priv->itemListView, item);
180
146
        else
181
147
                /* force HTML update in 2 pane mode */
182
148
                itemview->priv->needsHTMLViewUpdate = TRUE;
187
153
void
188
154
itemview_remove_item (itemPtr item)
189
155
{
190
 
        if (!ui_itemlist_contains_item (item->id))
 
156
        if (!item_list_view_contains_id (itemview->priv->itemListView, item->id))
191
157
                return;
192
158
 
193
159
        if (ITEMVIEW_ALL_ITEMS != itemview->priv->mode)
194
160
                /* remove item in 3 pane mode */
195
 
                ui_itemlist_remove_item (item);
 
161
                item_list_view_remove_item (itemview->priv->itemListView, item);
196
162
        else
197
163
                /* force HTML update in 2 pane mode */
198
164
                itemview->priv->needsHTMLViewUpdate = TRUE;
207
173
                
208
174
        ivp->needsHTMLViewUpdate = TRUE;
209
175
        
210
 
        ui_itemlist_select (item);
 
176
        item_list_view_select (ivp->itemListView, item);
211
177
        htmlview_select_item (item);
212
178
 
213
179
        if (item)
221
187
{
222
188
        /* Always update the GtkTreeView (bail-out done in ui_itemlist_update_item() */
223
189
        if (ITEMVIEW_ALL_ITEMS != itemview->priv->mode)
224
 
                ui_itemlist_update_item (item);
 
190
                item_list_view_update_item (itemview->priv->itemListView, item);
225
191
 
226
192
        /* Bail out if no HTML update necessary */
227
193
        switch (itemview->priv->mode) {
228
194
                case ITEMVIEW_ALL_ITEMS:
229
195
                        /* No HTML update needed if 2 pane mode and item not in item set */
230
 
                        if (!ui_itemlist_contains_item (item->id))
 
196
                        if (!item_list_view_contains_id (itemview->priv->itemListView, item->id))
231
197
                                return;
232
198
                        break;
233
199
                case ITEMVIEW_SINGLE_ITEM:              
250
216
{
251
217
        /* Always update the GtkTreeView (bail-out done in ui_itemlist_update_item() */
252
218
        if (ITEMVIEW_ALL_ITEMS != itemview->priv->mode)
253
 
                ui_itemlist_update_all_items ();
 
219
                item_list_view_update_all_items (itemview->priv->itemListView);
254
220
                
255
221
        itemview->priv->needsHTMLViewUpdate = TRUE;
256
222
        htmlview_update_all_items ();
275
241
void
276
242
itemview_update (void)
277
243
{
 
244
        item_list_view_update (itemview->priv->itemListView, itemview->priv->hasEnclosures);
 
245
        
 
246
        if (itemview->priv->node) {
 
247
                item_list_view_enable_favicon_column (itemview->priv->itemListView, NODE_TYPE (itemview->priv->node)->capabilities & NODE_CAPABILITY_SHOW_ITEM_FAVICONS);
 
248
                item_list_view_set_sort_column (itemview->priv->itemListView, itemview->priv->node->sortColumn, itemview->priv->node->sortReversed);
 
249
        }
 
250
        
278
251
        if (itemview->priv->needsHTMLViewUpdate) {
279
252
                itemview->priv->needsHTMLViewUpdate = FALSE;
280
253
                htmlview_update (itemview->priv->htmlview, itemview->priv->mode);
289
262
        liferea_htmlview_write (itemview->priv->htmlview, html, NULL);
290
263
}
291
264
 
292
 
/* date format handling (not sure if this is the right place) */
 
265
/* next unread selection logic */
293
266
 
294
 
gchar *
295
 
itemview_format_date (time_t date)
 
267
itemPtr
 
268
itemview_find_unread_item (gulong startId) 
296
269
{
297
 
        gchar           *timestr;
298
 
 
299
 
        if (itemview->priv->userDefinedDateFmt)
300
 
                timestr = common_format_date (date, itemview->priv->userDefinedDateFmt);
301
 
        else
302
 
                timestr = common_format_nice_date (date);
303
 
        
304
 
        return timestr;
 
270
        itemPtr result = NULL;
 
271
        
 
272
        /* Note: to select in sorting order we need to do it in the ItemListView
 
273
           otherwise we would have to sort the item list here... */
 
274
 
 
275
        /* First do a scan from the start position (usually the selected 
 
276
           item to the end of the sorted item list) if one is given. */ 
 
277
        if (startId)
 
278
                result = item_list_view_find_unread_item (itemview->priv->itemListView, startId);
 
279
        
 
280
        /* Now perform a wrap around by searching again from the top */
 
281
        if (!result)
 
282
                result = item_list_view_find_unread_item (itemview->priv->itemListView, 0);
 
283
 
 
284
        return result;
305
285
}
306
286
 
307
287
void
319
299
void
320
300
itemview_move_cursor (int step)
321
301
{
322
 
        ui_common_treeview_move_cursor (itemview->priv->itemlist, step);
 
302
        ui_common_treeview_move_cursor (item_list_view_get_widget (itemview->priv->itemListView), step);
323
303
}
324
304
 
325
305
void
326
306
itemview_move_cursor_to_first (void)
327
307
{
328
 
        ui_common_treeview_move_cursor_to_first (itemview->priv->itemlist);
 
308
        ui_common_treeview_move_cursor_to_first (item_list_view_get_widget (itemview->priv->itemListView));
329
309
}
330
310
 
331
311
static void
396
376
                        ilWidgetName = NULL;
397
377
                        encViewVBoxName = NULL;
398
378
                        break;
 
379
                case NODE_VIEW_MODE_INVALID:
399
380
                default:
400
381
                        g_warning("fatal: illegal viewing mode!");
401
382
                        return;
406
387
        gtk_notebook_set_current_page (GTK_NOTEBOOK (liferea_shell_lookup ("itemtabs")), newMode);
407
388
        gtk_widget_reparent (liferea_htmlview_get_widget (ivp->htmlview), liferea_shell_lookup (htmlWidgetName));
408
389
        if (ilWidgetName)
409
 
                gtk_widget_reparent (GTK_WIDGET (ivp->itemlistContainer), liferea_shell_lookup (ilWidgetName));
 
390
                gtk_widget_reparent (GTK_WIDGET (ivp->itemListViewContainer), liferea_shell_lookup (ilWidgetName));
410
391
        
411
392
        /* Destroy previous enclosure list. */
412
393
        if (ivp->enclosureView) {
425
406
}
426
407
 
427
408
ItemView *
428
 
itemview_create (GtkWidget *ilc)
 
409
itemview_create (GtkWidget *window)
429
410
{
 
411
        gint zoom;
 
412
 
430
413
        /* 1. Create widgets, load preferences */
431
414
        
432
415
        g_object_new (ITEMVIEW_TYPE, NULL);
433
416
        
434
417
        itemview->priv->currentLayoutMode = NODE_VIEW_MODE_INVALID;
435
 
        itemview->priv->itemlistContainer = ilc;
436
 
        itemview->priv->itemlist = GTK_TREE_VIEW (gtk_bin_get_child (GTK_BIN (itemview->priv->itemlistContainer)));
437
 
        itemview->priv->zoom = conf_get_int_value (LAST_ZOOMLEVEL);
438
 
        itemview->priv->userDefinedDateFmt = conf_get_str_value (DATE_FORMAT);
439
 
 
 
418
        itemview->priv->itemListView = item_list_view_create (window);
 
419
        itemview->priv->itemListViewContainer = gtk_widget_get_parent (GTK_WIDGET (item_list_view_get_widget (itemview->priv->itemListView)));
 
420
        conf_get_int_value (LAST_ZOOMLEVEL, &zoom);
 
421
        
 
422
        if (zoom == 0) {
 
423
                zoom = 100;
 
424
                conf_set_int_value (LAST_ZOOMLEVEL, zoom);
 
425
        }
 
426
        itemview->priv->zoom = zoom;
 
427
        
440
428
        /* initially we pack the item list in the normal view pane,
441
429
           which is later changed in itemview_set_layout() */
442
 
        gtk_container_add (GTK_CONTAINER (liferea_shell_lookup ("normalViewItems")), itemview->priv->itemlistContainer);
443
 
 
444
 
        /* 2. Sanity checks on the settings... */
445
 
        
446
 
        /* We now have an empty string or a format string... */
447
 
        if (itemview->priv->userDefinedDateFmt && !strlen (itemview->priv->userDefinedDateFmt)) {
448
 
                /* It's empty and useless... */
449
 
                g_free (itemview->priv->userDefinedDateFmt);
450
 
                itemview->priv->userDefinedDateFmt = NULL;
451
 
        }
452
 
        
453
 
        if (itemview->priv->userDefinedDateFmt) {
454
 
                debug1 (DEBUG_GUI, "user defined date format is: >>>%s<<<", itemview->priv->userDefinedDateFmt);
455
 
        } else {
456
 
                debug0 (DEBUG_GUI, "using default date format");
457
 
        }
458
 
 
459
 
        if (0 == itemview->priv->zoom) {        /* workaround for scheme problem with the last releases */
460
 
                itemview->priv->zoom = 100;
461
 
                conf_set_int_value (LAST_ZOOMLEVEL, 100);
462
 
        }
463
 
        
464
 
        /* 3. Prepare HTML rendering */
 
430
        gtk_container_add (GTK_CONTAINER (liferea_shell_lookup ("normalViewItems")), itemview->priv->itemListViewContainer);
 
431
 
 
432
        /* 2. Prepare HTML rendering */
465
433
        htmlview_init ();
466
434
        
467
435
        return itemview;
493
461
void
494
462
itemview_do_zoom (gboolean in)
495
463
{
496
 
g_assert(itemview->priv->htmlview != NULL);
 
464
        g_assert(itemview->priv->htmlview != NULL);
497
465
        liferea_htmlview_do_zoom (itemview->priv->htmlview, in);
498
466
}