No issues found
1 /*
2 * e-attachment-tree-view.c
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with the program; if not, see <http://www.gnu.org/licenses/>
16 *
17 *
18 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
19 *
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include "e-attachment-tree-view.h"
27
28 #include <glib/gi18n.h>
29 #include <libebackend/libebackend.h>
30
31 #include "e-attachment.h"
32 #include "e-attachment-store.h"
33 #include "e-attachment-view.h"
34
35 #define E_ATTACHMENT_TREE_VIEW_GET_PRIVATE(obj) \
36 (G_TYPE_INSTANCE_GET_PRIVATE \
37 ((obj), E_TYPE_ATTACHMENT_TREE_VIEW, EAttachmentTreeViewPrivate))
38
39 struct _EAttachmentTreeViewPrivate {
40 EAttachmentViewPrivate view_priv;
41 };
42
43 enum {
44 PROP_0,
45 PROP_DRAGGING,
46 PROP_EDITABLE
47 };
48
49 /* Forward Declarations */
50 static void e_attachment_tree_view_interface_init
51 (EAttachmentViewInterface *interface);
52
53 G_DEFINE_TYPE_WITH_CODE (
54 EAttachmentTreeView,
55 e_attachment_tree_view,
56 GTK_TYPE_TREE_VIEW,
57 G_IMPLEMENT_INTERFACE (
58 E_TYPE_ATTACHMENT_VIEW,
59 e_attachment_tree_view_interface_init)
60 G_IMPLEMENT_INTERFACE (
61 E_TYPE_EXTENSIBLE, NULL))
62
63 static void
64 attachment_tree_view_set_property (GObject *object,
65 guint property_id,
66 const GValue *value,
67 GParamSpec *pspec)
68 {
69 switch (property_id) {
70 case PROP_DRAGGING:
71 e_attachment_view_set_dragging (
72 E_ATTACHMENT_VIEW (object),
73 g_value_get_boolean (value));
74 return;
75
76 case PROP_EDITABLE:
77 e_attachment_view_set_editable (
78 E_ATTACHMENT_VIEW (object),
79 g_value_get_boolean (value));
80 return;
81 }
82
83 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
84 }
85
86 static void
87 attachment_tree_view_get_property (GObject *object,
88 guint property_id,
89 GValue *value,
90 GParamSpec *pspec)
91 {
92 switch (property_id) {
93 case PROP_DRAGGING:
94 g_value_set_boolean (
95 value, e_attachment_view_get_dragging (
96 E_ATTACHMENT_VIEW (object)));
97 return;
98
99 case PROP_EDITABLE:
100 g_value_set_boolean (
101 value, e_attachment_view_get_editable (
102 E_ATTACHMENT_VIEW (object)));
103 return;
104 }
105
106 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
107 }
108
109 static void
110 attachment_tree_view_dispose (GObject *object)
111 {
112 e_attachment_view_dispose (E_ATTACHMENT_VIEW (object));
113
114 /* Chain up to parent's dispose() method. */
115 G_OBJECT_CLASS (e_attachment_tree_view_parent_class)->dispose (object);
116 }
117
118 static void
119 attachment_tree_view_finalize (GObject *object)
120 {
121 e_attachment_view_finalize (E_ATTACHMENT_VIEW (object));
122
123 /* Chain up to parent's finalize() method. */
124 G_OBJECT_CLASS (e_attachment_tree_view_parent_class)->finalize (object);
125 }
126
127 static void
128 attachment_tree_view_render_size (GtkTreeViewColumn *column,
129 GtkCellRenderer *renderer,
130 GtkTreeModel *model,
131 GtkTreeIter *iter)
132 {
133 gchar *display_size = NULL;
134 gint column_id;
135 guint64 size;
136
137 column_id = E_ATTACHMENT_STORE_COLUMN_SIZE;
138 gtk_tree_model_get (model, iter, column_id, &size, -1);
139
140 if (size > 0)
141 display_size = g_format_size_for_display ((goffset) size);
142
143 g_object_set (renderer, "text", display_size, NULL);
144
145 g_free (display_size);
146 }
147
148 static gboolean
149 attachment_tree_view_button_press_event (GtkWidget *widget,
150 GdkEventButton *event)
151 {
152 EAttachmentView *view = E_ATTACHMENT_VIEW (widget);
153
154 if (e_attachment_view_button_press_event (view, event))
155 return TRUE;
156
157 /* Chain up to parent's button_press_event() method. */
158 return GTK_WIDGET_CLASS (e_attachment_tree_view_parent_class)->
159 button_press_event (widget, event);
160 }
161
162 static gboolean
163 attachment_tree_view_button_release_event (GtkWidget *widget,
164 GdkEventButton *event)
165 {
166 EAttachmentView *view = E_ATTACHMENT_VIEW (widget);
167
168 if (e_attachment_view_button_release_event (view, event))
169 return TRUE;
170
171 /* Chain up to parent's button_release_event() method. */
172 return GTK_WIDGET_CLASS (e_attachment_tree_view_parent_class)->
173 button_release_event (widget, event);
174 }
175
176 static gboolean
177 attachment_tree_view_motion_notify_event (GtkWidget *widget,
178 GdkEventMotion *event)
179 {
180 EAttachmentView *view = E_ATTACHMENT_VIEW (widget);
181
182 if (e_attachment_view_motion_notify_event (view, event))
183 return TRUE;
184
185 /* Chain up to parent's motion_notify_event() method. */
186 return GTK_WIDGET_CLASS (e_attachment_tree_view_parent_class)->
187 motion_notify_event (widget, event);
188 }
189
190 static gboolean
191 attachment_tree_view_key_press_event (GtkWidget *widget,
192 GdkEventKey *event)
193 {
194 EAttachmentView *view = E_ATTACHMENT_VIEW (widget);
195
196 if (e_attachment_view_key_press_event (view, event))
197 return TRUE;
198
199 /* Chain up to parent's key_press_event() method. */
200 return GTK_WIDGET_CLASS (e_attachment_tree_view_parent_class)->
201 key_press_event (widget, event);
202 }
203
204 static void
205 attachment_tree_view_drag_begin (GtkWidget *widget,
206 GdkDragContext *context)
207 {
208 EAttachmentView *view = E_ATTACHMENT_VIEW (widget);
209
210 /* Chain up to parent's drag_begin() method. */
211 GTK_WIDGET_CLASS (e_attachment_tree_view_parent_class)->
212 drag_begin (widget, context);
213
214 e_attachment_view_drag_begin (view, context);
215 }
216
217 static void
218 attachment_tree_view_drag_end (GtkWidget *widget,
219 GdkDragContext *context)
220 {
221 EAttachmentView *view = E_ATTACHMENT_VIEW (widget);
222
223 /* Chain up to parent's drag_end() method. */
224 GTK_WIDGET_CLASS (e_attachment_tree_view_parent_class)->
225 drag_end (widget, context);
226
227 e_attachment_view_drag_end (view, context);
228 }
229
230 static void
231 attachment_tree_view_drag_data_get (GtkWidget *widget,
232 GdkDragContext *context,
233 GtkSelectionData *selection,
234 guint info,
235 guint time)
236 {
237 EAttachmentView *view = E_ATTACHMENT_VIEW (widget);
238
239 e_attachment_view_drag_data_get (
240 view, context, selection, info, time);
241 }
242
243 static gboolean
244 attachment_tree_view_drag_motion (GtkWidget *widget,
245 GdkDragContext *context,
246 gint x,
247 gint y,
248 guint time)
249 {
250 EAttachmentView *view = E_ATTACHMENT_VIEW (widget);
251
252 return e_attachment_view_drag_motion (view, context, x, y, time);
253 }
254
255 static gboolean
256 attachment_tree_view_drag_drop (GtkWidget *widget,
257 GdkDragContext *context,
258 gint x,
259 gint y,
260 guint time)
261 {
262 EAttachmentView *view = E_ATTACHMENT_VIEW (widget);
263
264 if (!e_attachment_view_drag_drop (view, context, x, y, time))
265 return FALSE;
266
267 /* Chain up to parent's drag_drop() method. */
268 return GTK_WIDGET_CLASS (e_attachment_tree_view_parent_class)->
269 drag_drop (widget, context, x, y, time);
270 }
271
272 static void
273 attachment_tree_view_drag_data_received (GtkWidget *widget,
274 GdkDragContext *context,
275 gint x,
276 gint y,
277 GtkSelectionData *selection,
278 guint info,
279 guint time)
280 {
281 EAttachmentView *view = E_ATTACHMENT_VIEW (widget);
282
283 e_attachment_view_drag_data_received (
284 view, context, x, y, selection, info, time);
285 }
286
287 static gboolean
288 attachment_tree_view_popup_menu (GtkWidget *widget)
289 {
290 EAttachmentView *view = E_ATTACHMENT_VIEW (widget);
291
292 e_attachment_view_show_popup_menu (view, NULL, NULL, NULL);
293
294 return TRUE;
295 }
296
297 static void
298 attachment_tree_view_row_activated (GtkTreeView *tree_view,
299 GtkTreePath *path,
300 GtkTreeViewColumn *column)
301 {
302 EAttachmentView *view = E_ATTACHMENT_VIEW (tree_view);
303
304 e_attachment_view_open_path (view, path, NULL);
305 }
306
307 static EAttachmentViewPrivate *
308 attachment_tree_view_get_private (EAttachmentView *view)
309 {
310 EAttachmentTreeViewPrivate *priv;
311
312 priv = E_ATTACHMENT_TREE_VIEW_GET_PRIVATE (view);
313
314 return &priv->view_priv;
315 }
316
317 static EAttachmentStore *
318 attachment_tree_view_get_store (EAttachmentView *view)
319 {
320 GtkTreeView *tree_view;
321 GtkTreeModel *model;
322
323 tree_view = GTK_TREE_VIEW (view);
324 model = gtk_tree_view_get_model (tree_view);
325
326 return E_ATTACHMENT_STORE (model);
327 }
328
329 static GtkTreePath *
330 attachment_tree_view_get_path_at_pos (EAttachmentView *view,
331 gint x,
332 gint y)
333 {
334 GtkTreeView *tree_view;
335 GtkTreePath *path;
336 gboolean row_exists;
337
338 tree_view = GTK_TREE_VIEW (view);
339
340 row_exists = gtk_tree_view_get_path_at_pos (
341 tree_view, x, y, &path, NULL, NULL, NULL);
342
343 return row_exists ? path : NULL;
344 }
345
346 static GList *
347 attachment_tree_view_get_selected_paths (EAttachmentView *view)
348 {
349 GtkTreeView *tree_view;
350 GtkTreeSelection *selection;
351
352 tree_view = GTK_TREE_VIEW (view);
353 selection = gtk_tree_view_get_selection (tree_view);
354
355 return gtk_tree_selection_get_selected_rows (selection, NULL);
356 }
357
358 static gboolean
359 attachment_tree_view_path_is_selected (EAttachmentView *view,
360 GtkTreePath *path)
361 {
362 GtkTreeView *tree_view;
363 GtkTreeSelection *selection;
364
365 tree_view = GTK_TREE_VIEW (view);
366 selection = gtk_tree_view_get_selection (tree_view);
367
368 return gtk_tree_selection_path_is_selected (selection, path);
369 }
370
371 static void
372 attachment_tree_view_select_path (EAttachmentView *view,
373 GtkTreePath *path)
374 {
375 GtkTreeView *tree_view;
376 GtkTreeSelection *selection;
377
378 tree_view = GTK_TREE_VIEW (view);
379 selection = gtk_tree_view_get_selection (tree_view);
380
381 gtk_tree_selection_select_path (selection, path);
382 }
383
384 static void
385 attachment_tree_view_unselect_path (EAttachmentView *view,
386 GtkTreePath *path)
387 {
388 GtkTreeView *tree_view;
389 GtkTreeSelection *selection;
390
391 tree_view = GTK_TREE_VIEW (view);
392 selection = gtk_tree_view_get_selection (tree_view);
393
394 gtk_tree_selection_unselect_path (selection, path);
395 }
396
397 static void
398 attachment_tree_view_select_all (EAttachmentView *view)
399 {
400 GtkTreeView *tree_view;
401 GtkTreeSelection *selection;
402
403 tree_view = GTK_TREE_VIEW (view);
404 selection = gtk_tree_view_get_selection (tree_view);
405
406 gtk_tree_selection_select_all (selection);
407 }
408
409 static void
410 attachment_tree_view_unselect_all (EAttachmentView *view)
411 {
412 GtkTreeView *tree_view;
413 GtkTreeSelection *selection;
414
415 tree_view = GTK_TREE_VIEW (view);
416 selection = gtk_tree_view_get_selection (tree_view);
417
418 gtk_tree_selection_unselect_all (selection);
419 }
420
421 static void
422 attachment_tree_view_drag_source_set (EAttachmentView *view,
423 GdkModifierType start_button_mask,
424 const GtkTargetEntry *targets,
425 gint n_targets,
426 GdkDragAction actions)
427 {
428 GtkTreeView *tree_view;
429
430 tree_view = GTK_TREE_VIEW (view);
431
432 gtk_tree_view_enable_model_drag_source (
433 tree_view, start_button_mask, targets, n_targets, actions);
434 }
435
436 static void
437 attachment_tree_view_drag_dest_set (EAttachmentView *view,
438 const GtkTargetEntry *targets,
439 gint n_targets,
440 GdkDragAction actions)
441 {
442 GtkTreeView *tree_view;
443
444 tree_view = GTK_TREE_VIEW (view);
445
446 gtk_tree_view_enable_model_drag_dest (
447 tree_view, targets, n_targets, actions);
448 }
449
450 static void
451 attachment_tree_view_drag_source_unset (EAttachmentView *view)
452 {
453 GtkTreeView *tree_view;
454
455 tree_view = GTK_TREE_VIEW (view);
456
457 gtk_tree_view_unset_rows_drag_source (tree_view);
458 }
459
460 static void
461 attachment_tree_view_drag_dest_unset (EAttachmentView *view)
462 {
463 GtkTreeView *tree_view;
464
465 tree_view = GTK_TREE_VIEW (view);
466
467 gtk_tree_view_unset_rows_drag_dest (tree_view);
468 }
469
470 static void
471 e_attachment_tree_view_class_init (EAttachmentTreeViewClass *class)
472 {
473 GObjectClass *object_class;
474 GtkWidgetClass *widget_class;
475 GtkTreeViewClass *tree_view_class;
476
477 g_type_class_add_private (class, sizeof (EAttachmentViewPrivate));
478
479 object_class = G_OBJECT_CLASS (class);
480 object_class->set_property = attachment_tree_view_set_property;
481 object_class->get_property = attachment_tree_view_get_property;
482 object_class->dispose = attachment_tree_view_dispose;
483 object_class->finalize = attachment_tree_view_finalize;
484
485 widget_class = GTK_WIDGET_CLASS (class);
486 widget_class->button_press_event = attachment_tree_view_button_press_event;
487 widget_class->button_release_event = attachment_tree_view_button_release_event;
488 widget_class->motion_notify_event = attachment_tree_view_motion_notify_event;
489 widget_class->key_press_event = attachment_tree_view_key_press_event;
490 widget_class->drag_begin = attachment_tree_view_drag_begin;
491 widget_class->drag_end = attachment_tree_view_drag_end;
492 widget_class->drag_data_get = attachment_tree_view_drag_data_get;
493 widget_class->drag_motion = attachment_tree_view_drag_motion;
494 widget_class->drag_drop = attachment_tree_view_drag_drop;
495 widget_class->drag_data_received = attachment_tree_view_drag_data_received;
496 widget_class->popup_menu = attachment_tree_view_popup_menu;
497
498 tree_view_class = GTK_TREE_VIEW_CLASS (class);
499 tree_view_class->row_activated = attachment_tree_view_row_activated;
500
501 g_object_class_override_property (
502 object_class, PROP_DRAGGING, "dragging");
503
504 g_object_class_override_property (
505 object_class, PROP_EDITABLE, "editable");
506 }
507
508 static void
509 e_attachment_tree_view_init (EAttachmentTreeView *tree_view)
510 {
511 GtkTreeSelection *selection;
512 GtkTreeViewColumn *column;
513 GtkCellRenderer *renderer;
514
515 tree_view->priv = E_ATTACHMENT_TREE_VIEW_GET_PRIVATE (tree_view);
516
517 e_attachment_view_init (E_ATTACHMENT_VIEW (tree_view));
518
519 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree_view), TRUE);
520
521 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
522 gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
523
524 /* Name Column */
525 column = gtk_tree_view_column_new ();
526 gtk_tree_view_column_set_expand (column, TRUE);
527 gtk_tree_view_column_set_spacing (column, 3);
528 gtk_tree_view_column_set_title (column, _("Description"));
529 gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
530
531 renderer = gtk_cell_renderer_pixbuf_new ();
532 gtk_tree_view_column_pack_start (column, renderer, FALSE);
533
534 g_object_set (renderer, "stock-size", GTK_ICON_SIZE_MENU, NULL);
535
536 gtk_tree_view_column_add_attribute (
537 column, renderer, "gicon",
538 E_ATTACHMENT_STORE_COLUMN_ICON);
539
540 renderer = gtk_cell_renderer_text_new ();
541 g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
542 gtk_tree_view_column_pack_start (column, renderer, TRUE);
543
544 gtk_tree_view_column_add_attribute (
545 column, renderer, "text",
546 E_ATTACHMENT_STORE_COLUMN_DESCRIPTION);
547
548 renderer = gtk_cell_renderer_progress_new ();
549 g_object_set (renderer, "text", _("Loading"), NULL);
550 gtk_tree_view_column_pack_start (column, renderer, TRUE);
551
552 gtk_tree_view_column_add_attribute (
553 column, renderer, "value",
554 E_ATTACHMENT_STORE_COLUMN_PERCENT);
555
556 gtk_tree_view_column_add_attribute (
557 column, renderer, "visible",
558 E_ATTACHMENT_STORE_COLUMN_LOADING);
559
560 renderer = gtk_cell_renderer_progress_new ();
561 g_object_set (renderer, "text", _("Saving"), NULL);
562 gtk_tree_view_column_pack_start (column, renderer, TRUE);
563
564 gtk_tree_view_column_add_attribute (
565 column, renderer, "value",
566 E_ATTACHMENT_STORE_COLUMN_PERCENT);
567
568 gtk_tree_view_column_add_attribute (
569 column, renderer, "visible",
570 E_ATTACHMENT_STORE_COLUMN_SAVING);
571
572 /* Size Column */
573 column = gtk_tree_view_column_new ();
574 gtk_tree_view_column_set_title (column, _("Size"));
575 gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
576
577 renderer = gtk_cell_renderer_text_new ();
578 gtk_tree_view_column_pack_start (column, renderer, TRUE);
579
580 gtk_tree_view_column_set_cell_data_func (
581 column, renderer, (GtkTreeCellDataFunc)
582 attachment_tree_view_render_size, NULL, NULL);
583
584 /* Type Column */
585 column = gtk_tree_view_column_new ();
586 gtk_tree_view_column_set_title (column, _("Type"));
587 gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
588
589 renderer = gtk_cell_renderer_text_new ();
590 gtk_tree_view_column_pack_start (column, renderer, TRUE);
591
592 gtk_tree_view_column_add_attribute (
593 column, renderer, "text",
594 E_ATTACHMENT_STORE_COLUMN_CONTENT_TYPE);
595
596 e_extensible_load_extensions (E_EXTENSIBLE (tree_view));
597 }
598
599 static void
600 e_attachment_tree_view_interface_init (EAttachmentViewInterface *interface)
601 {
602 interface->get_private = attachment_tree_view_get_private;
603 interface->get_store = attachment_tree_view_get_store;
604
605 interface->get_path_at_pos = attachment_tree_view_get_path_at_pos;
606 interface->get_selected_paths = attachment_tree_view_get_selected_paths;
607 interface->path_is_selected = attachment_tree_view_path_is_selected;
608 interface->select_path = attachment_tree_view_select_path;
609 interface->unselect_path = attachment_tree_view_unselect_path;
610 interface->select_all = attachment_tree_view_select_all;
611 interface->unselect_all = attachment_tree_view_unselect_all;
612
613 interface->drag_source_set = attachment_tree_view_drag_source_set;
614 interface->drag_dest_set = attachment_tree_view_drag_dest_set;
615 interface->drag_source_unset = attachment_tree_view_drag_source_unset;
616 interface->drag_dest_unset = attachment_tree_view_drag_dest_unset;
617 }
618
619 GtkWidget *
620 e_attachment_tree_view_new (void)
621 {
622 return g_object_new (E_TYPE_ATTACHMENT_TREE_VIEW, NULL);
623 }