2
2
* @file itemview.c viewing feed content in different presentation modes
4
* Copyright (C) 2006-2009 Lars Lindner <lars.lindner@gmail.com>
4
* Copyright (C) 2006-2011 Lars Lindner <lars.lindner@gmail.com>
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"
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.
41
The item view does not handle item filtering, which is done by
42
the item list implementation.
40
45
#define ITEMVIEW_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), ITEMVIEW_TYPE, ItemViewPrivate))
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 */
50
55
nodeViewType viewMode; /**< current viewing mode */
51
56
guint currentLayoutMode; /**< layout mode (3 pane, 2 pane, wide view) */
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 */
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 */
59
64
gfloat zoom; /**< HTML rendering widget zoom level */
62
67
static GObjectClass *parent_class = NULL;
63
68
static ItemView *itemview = NULL;
66
itemview_get_type (void)
68
static GType type = 0;
70
if (G_UNLIKELY (type == 0))
72
static const GTypeInfo our_info =
74
sizeof (ItemViewClass),
76
NULL, /* base_finalize */
77
(GClassInitFunc) itemview_class_init,
79
NULL, /* class_data */
82
(GInstanceInitFunc) itemview_init,
83
NULL /* value_table */
86
type = g_type_register_static (G_TYPE_OBJECT,
70
G_DEFINE_TYPE (ItemView, itemview, G_TYPE_OBJECT);
95
73
itemview_finalize (GObject *object)
152
129
itemview->priv->node = node;
154
/* 1. Perform UI item list preparations ... */
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. */
159
/* Disable attachment icon column (will be enabled when loading first item with an enclosure) */
160
ui_itemlist_enable_encicon_column (FALSE);
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);
167
/* 2. Reset view state */
131
/* 1. Reset view state */
168
132
itemview_clear ();
170
/* 3. And prepare HTML view */
134
/* 2. And prepare HTML view */
171
135
htmlview_set_displayed_node (node);
175
139
itemview_add_item (itemPtr item)
141
itemview->priv->hasEnclosures |= item->hasEnclosure;
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);
181
147
/* force HTML update in 2 pane mode */
182
148
itemview->priv->needsHTMLViewUpdate = TRUE;
188
154
itemview_remove_item (itemPtr item)
190
if (!ui_itemlist_contains_item (item->id))
156
if (!item_list_view_contains_id (itemview->priv->itemListView, item->id))
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);
197
163
/* force HTML update in 2 pane mode */
198
164
itemview->priv->needsHTMLViewUpdate = TRUE;
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);
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))
233
199
case ITEMVIEW_SINGLE_ITEM:
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);
255
221
itemview->priv->needsHTMLViewUpdate = TRUE;
256
222
htmlview_update_all_items ();
276
242
itemview_update (void)
244
item_list_view_update (itemview->priv->itemListView, itemview->priv->hasEnclosures);
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);
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);
292
/* date format handling (not sure if this is the right place) */
265
/* next unread selection logic */
295
itemview_format_date (time_t date)
268
itemview_find_unread_item (gulong startId)
299
if (itemview->priv->userDefinedDateFmt)
300
timestr = common_format_date (date, itemview->priv->userDefinedDateFmt);
302
timestr = common_format_nice_date (date);
270
itemPtr result = NULL;
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... */
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. */
278
result = item_list_view_find_unread_item (itemview->priv->itemListView, startId);
280
/* Now perform a wrap around by searching again from the top */
282
result = item_list_view_find_unread_item (itemview->priv->itemListView, 0);
320
300
itemview_move_cursor (int step)
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);
326
306
itemview_move_cursor_to_first (void)
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));
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));
411
392
/* Destroy previous enclosure list. */
412
393
if (ivp->enclosureView) {
428
itemview_create (GtkWidget *ilc)
409
itemview_create (GtkWidget *window)
430
413
/* 1. Create widgets, load preferences */
432
415
g_object_new (ITEMVIEW_TYPE, NULL);
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);
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);
424
conf_set_int_value (LAST_ZOOMLEVEL, zoom);
426
itemview->priv->zoom = zoom;
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);
444
/* 2. Sanity checks on the settings... */
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;
453
if (itemview->priv->userDefinedDateFmt) {
454
debug1 (DEBUG_GUI, "user defined date format is: >>>%s<<<", itemview->priv->userDefinedDateFmt);
456
debug0 (DEBUG_GUI, "using default date format");
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);
464
/* 3. Prepare HTML rendering */
430
gtk_container_add (GTK_CONTAINER (liferea_shell_lookup ("normalViewItems")), itemview->priv->itemListViewContainer);
432
/* 2. Prepare HTML rendering */
465
433
htmlview_init ();
494
462
itemview_do_zoom (gboolean in)
496
g_assert(itemview->priv->htmlview != NULL);
464
g_assert(itemview->priv->htmlview != NULL);
497
465
liferea_htmlview_do_zoom (itemview->priv->htmlview, in);