static void modest_header_view_init (ModestHeaderView *obj);
static void modest_header_view_finalize (GObject *obj);
-static gboolean on_header_clicked (GtkWidget *widget,
+static gboolean on_header_clicked (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data);
-static gint cmp_rows (GtkTreeModel *tree_model,
- GtkTreeIter *iter1,
- GtkTreeIter *iter2,
- gpointer user_data);
+static gint cmp_rows (GtkTreeModel *tree_model,
+ GtkTreeIter *iter1,
+ GtkTreeIter *iter2,
+ gpointer user_data);
-static void on_selection_changed (GtkTreeSelection *sel,
- gpointer user_data);
+static void on_selection_changed (GtkTreeSelection *sel,
+ gpointer user_data);
+
+static void setup_drag_and_drop (GtkTreeView *self);
-static void setup_drag_and_drop (GtkTreeView *self);
+static GtkTreePath * get_selected_row (GtkTreeView *self, GtkTreeModel **model);
+static gboolean on_focus_in (GtkWidget *sef,
+ GdkEventFocus *event,
+ gpointer user_data);
typedef struct _ModestHeaderViewPrivate ModestHeaderViewPrivate;
struct _ModestHeaderViewPrivate {
{
GtkTreeModel *sortable;
GtkTreeViewColumn *column=NULL;
+ GtkTreeSelection *selection = NULL;
GtkCellRenderer *renderer_msgtype,*renderer_header,
- *renderer_attach;
+ *renderer_attach, *renderer_comptact_flag,
+ *renderer_compact_date;
ModestHeaderViewPrivate *priv;
const GList *cursor;
renderer_msgtype = gtk_cell_renderer_pixbuf_new ();
renderer_attach = gtk_cell_renderer_pixbuf_new ();
renderer_header = gtk_cell_renderer_text_new ();
+ renderer_comptact_flag = gtk_cell_renderer_pixbuf_new ();
+ renderer_compact_date = gtk_cell_renderer_text_new ();
+
+ g_object_set(G_OBJECT(renderer_header),
+ "ellipsize", PANGO_ELLIPSIZE_END,
+ NULL);
+ g_object_set(G_OBJECT(renderer_compact_date),
+ "xalign", 1.0,
+ NULL);
remove_all_columns (self);
+ selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(self));
+ gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
sortable = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
/* Add new columns */
GINT_TO_POINTER(FALSE));
break;
+ case MODEST_HEADER_VIEW_COLUMN_COMPACT_FLAG:
+ column = get_new_column (_("F"), renderer_comptact_flag, FALSE,
+ TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN,
+ FALSE,
+ (GtkTreeCellDataFunc)_modest_header_view_compact_flag_cell_data,
+ NULL);
+ gtk_tree_view_column_set_fixed_width (column, 45);
+ break;
+
case MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER_IN:
column = get_new_column (_("Header"), renderer_header, TRUE,
TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN,
GINT_TO_POINTER(TRUE));
break;
- case MODEST_HEADER_VIEW_COLUMN_SENT_DATE:
+ case MODEST_HEADER_VIEW_COLUMN_SENT_DATE:
column = get_new_column (_("Sent"), renderer_header, TRUE,
TNY_GTK_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN,
TRUE,
GINT_TO_POINTER(FALSE));
break;
+ case MODEST_HEADER_VIEW_COLUMN_COMPACT_RECEIVED_DATE:
+ column = get_new_column (_("Received"), renderer_compact_date, FALSE,
+ TNY_GTK_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN,
+ TRUE,
+ (GtkTreeCellDataFunc)_modest_header_view_compact_date_cell_data,
+ GINT_TO_POINTER(TRUE));
+ gtk_tree_view_column_set_fixed_width (column, 130);
+ break;
+
+ case MODEST_HEADER_VIEW_COLUMN_COMPACT_SENT_DATE:
+ column = get_new_column (_("Sent"), renderer_compact_date, FALSE,
+ TNY_GTK_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN,
+ TRUE,
+ (GtkTreeCellDataFunc)_modest_header_view_compact_date_cell_data,
+ GINT_TO_POINTER(FALSE));
+ gtk_tree_view_column_set_fixed_width (column, 130);
+ break;
case MODEST_HEADER_VIEW_COLUMN_SIZE:
column = get_new_column (_("Size"), renderer_header, TRUE,
TNY_GTK_HEADER_LIST_MODEL_MESSAGE_SIZE_COLUMN,
(GtkTreeCellDataFunc)_modest_header_view_size_cell_data,
NULL);
break;
+ case MODEST_HEADER_VIEW_COLUMN_STATUS:
+ column = get_new_column (_("Status"), renderer_compact_date, TRUE,
+ TNY_GTK_HEADER_LIST_MODEL_MESSAGE_SIZE_COLUMN,
+ FALSE,
+ (GtkTreeCellDataFunc)_modest_header_view_status_cell_data,
+ NULL);
+ break;
default:
g_return_val_if_reached(FALSE);
g_signal_connect (self, "button-press-event",
G_CALLBACK(on_header_clicked), NULL);
+
+ g_signal_connect (self, "focus-in-event",
+ G_CALLBACK(on_focus_in), NULL);
return GTK_WIDGET(self);
}
GtkTreeSelection *sel;
GtkTreeIter iter;
GtkTreeModel *model;
+ GtkTreePath *path;
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (self));
- if (gtk_tree_selection_get_selected (sel, &model, &iter)) {
+ path = get_selected_row (GTK_TREE_VIEW(self), &model);
+ if ((path != NULL) && (gtk_tree_model_get_iter(model, &iter, path))) {
+ /* Unselect previous path */
+ gtk_tree_selection_unselect_path (sel, path);
+
+ /* Move path down and selects new one */
if (gtk_tree_model_iter_next (model, &iter)) {
gtk_tree_selection_select_iter (sel, &iter);
scroll_to_selected (self, &iter, FALSE);
}
+ gtk_tree_path_free(path);
}
+
}
void
GtkTreePath *path;
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (self));
- if (gtk_tree_selection_get_selected (sel, &model, &iter)) {
- path = gtk_tree_model_get_path (model, &iter);
+ path = get_selected_row (GTK_TREE_VIEW(self), &model);
+ if ((path != NULL) && (gtk_tree_model_get_iter(model, &iter, path))) {
+ /* Unselect previous path */
+ gtk_tree_selection_unselect_path (sel, path);
/* Move path up */
if (gtk_tree_path_prev (path)) {
static gboolean
on_header_clicked (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
{
- ModestHeaderView *self;
- ModestHeaderViewPrivate *priv;
+ ModestHeaderView *self = NULL;
+ ModestHeaderViewPrivate *priv = NULL;
+ GtkTreePath *path = NULL;
GtkTreeIter iter;
- GtkTreeSelection *sel;
- GtkTreeModel *model;
+ GtkTreeModel *model = NULL;
TnyHeader *header;
-
/* ignore everything but doubleclick */
if (event->type != GDK_2BUTTON_PRESS)
return FALSE;
self = MODEST_HEADER_VIEW (widget);
priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
- sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(self));
- model = gtk_tree_view_get_model (GTK_TREE_VIEW(self));
-
- if (!gtk_tree_selection_get_selected (sel, &model, &iter))
- return FALSE; /* msg was _un_selected */
-
+ path = get_selected_row (GTK_TREE_VIEW(self), &model);
+ if ((path == NULL) || (!gtk_tree_model_get_iter(model, &iter, path)))
+ return FALSE;
+
/* get the first selected item */
gtk_tree_model_get (model, &iter,
TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN,
/* Free */
g_object_unref (G_OBJECT (header));
+ gtk_tree_path_free(path);
return TRUE;
}
{
GtkTreeModel *model;
TnyHeader *header;
+ GtkTreePath *path = NULL;
GtkTreeIter iter;
ModestHeaderView *self;
ModestHeaderViewPrivate *priv;
self = MODEST_HEADER_VIEW (user_data);
priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
-
- if (!gtk_tree_selection_get_selected (sel, &model, &iter))
+
+ path = get_selected_row (GTK_TREE_VIEW(self), &model);
+ if ((path == NULL) || (!gtk_tree_model_get_iter(model, &iter, path)))
return; /* msg was _un_selected */
gtk_tree_model_get (model, &iter,
0, header);
g_object_unref (G_OBJECT (header));
+ gtk_tree_path_free(path);
}
GtkSelectionData *selection_data,
guint info, guint time, gpointer data)
{
- GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
GtkTreePath *source_row;
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
- gtk_tree_selection_get_selected (selection, &model, &iter);
- source_row = gtk_tree_model_get_path (model, &iter);
+
+ source_row = get_selected_row (GTK_TREE_VIEW(widget), &model);
+ if ((source_row == NULL) || (!gtk_tree_model_get_iter(model, &iter, source_row))) return;
switch (info) {
case MODEST_HEADER_ROW:
g_signal_connect(G_OBJECT (self), "drag_data_get",
G_CALLBACK(drag_data_get_cb), NULL);
}
+
+static GtkTreePath *
+get_selected_row (GtkTreeView *self, GtkTreeModel **model)
+{
+ GtkTreePath *path = NULL;
+ GtkTreeSelection *sel = NULL;
+ GList *rows = NULL;
+
+ sel = gtk_tree_view_get_selection(self);
+ rows = gtk_tree_selection_get_selected_rows (sel, model);
+
+ if ((rows == NULL) || (g_list_length(rows) != 1))
+ goto frees;
+
+ path = gtk_tree_path_copy(g_list_nth_data (rows, 0));
+
+
+ /* Free */
+ frees:
+ g_list_foreach(rows,(GFunc) gtk_tree_path_free, NULL);
+ g_list_free(rows);
+
+ return path;
+}
+
+/*
+ * This function moves the tree view scroll to the current selected
+ * row when the widget grabs the focus
+ */
+static gboolean
+on_focus_in (GtkWidget *self,
+ GdkEventFocus *event,
+ gpointer user_data)
+{
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GList *selected = NULL;
+ GtkTreePath *selected_path = NULL;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
+ if (!model)
+ return FALSE;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self));
+ /* If none selected yet, pick the first one */
+ if (gtk_tree_selection_count_selected_rows (selection) == 0) {
+ GtkTreeIter iter;
+ GtkTreePath *path;
+
+ /* Return if the model is empty */
+ if (!gtk_tree_model_get_iter_first (model, &iter))
+ return FALSE;
+
+ path = gtk_tree_model_get_path (model, &iter);
+ gtk_tree_selection_select_path (selection, path);
+ gtk_tree_path_free (path);
+ }
+
+ /* Need to get the all the rows because is selection multiple */
+ selected = gtk_tree_selection_get_selected_rows (selection, &model);
+ selected_path = (GtkTreePath *) selected->data;
+
+ /* Check if we need to scroll */
+ #if GTK_CHECK_VERSION(2, 8, 0) /* TODO: gtk_tree_view_get_visible_range() is only available in GTK+ 2.8 */
+ GtkTreePath *start_path = NULL;
+ GtkTreePath *end_path = NULL;
+ if (gtk_tree_view_get_visible_range (GTK_TREE_VIEW (self),
+ &start_path,
+ &end_path)) {
+
+ if ((gtk_tree_path_compare (start_path, selected_path) != -1) ||
+ (gtk_tree_path_compare (end_path, selected_path) != 1)) {
+
+ /* Scroll to first path */
+ gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (self),
+ selected_path,
+ NULL,
+ TRUE,
+ 0.5,
+ 0.0);
+ }
+ }
+ #endif /* GTK_CHECK_VERSION */
+
+ /* Frees */
+ g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL);
+ g_list_free (selected);
+
+ return FALSE;
+}