1 /*
2 * e-attachment-icon-view.c
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, see <http://www.gnu.org/licenses/>.
15 *
16 *
17 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
18 *
19 */
20
21 #include "evolution-config.h"
22
23 #include "e-attachment-icon-view.h"
24
25 #include <glib/gi18n.h>
26 #include <libebackend/libebackend.h>
27
28 #include "e-attachment.h"
29 #include "e-attachment-store.h"
30 #include "e-attachment-view.h"
31
32 #define E_ATTACHMENT_ICON_VIEW_GET_PRIVATE(obj) \
33 (G_TYPE_INSTANCE_GET_PRIVATE \
34 ((obj), E_TYPE_ATTACHMENT_ICON_VIEW, EAttachmentIconViewPrivate))
35
36 struct _EAttachmentIconViewPrivate {
37 EAttachmentViewPrivate view_priv;
38 };
39
40 enum {
41 PROP_0,
42 PROP_DRAGGING,
43 PROP_EDITABLE
44 };
45
46 /* Forward Declarations */
47 static void e_attachment_icon_view_interface_init
48 (EAttachmentViewInterface *iface);
49
G_DEFINE_TYPE_WITH_CODE(EAttachmentIconView,e_attachment_icon_view,GTK_TYPE_ICON_VIEW,G_IMPLEMENT_INTERFACE (E_TYPE_ATTACHMENT_VIEW,e_attachment_icon_view_interface_init)G_IMPLEMENT_INTERFACE (E_TYPE_EXTENSIBLE,NULL))50 G_DEFINE_TYPE_WITH_CODE (
51 EAttachmentIconView,
52 e_attachment_icon_view,
53 GTK_TYPE_ICON_VIEW,
54 G_IMPLEMENT_INTERFACE (
55 E_TYPE_ATTACHMENT_VIEW,
56 e_attachment_icon_view_interface_init)
57 G_IMPLEMENT_INTERFACE (
58 E_TYPE_EXTENSIBLE, NULL))
59
60 static void
61 attachment_icon_view_set_property (GObject *object,
62 guint property_id,
63 const GValue *value,
64 GParamSpec *pspec)
65 {
66 switch (property_id) {
67 case PROP_DRAGGING:
68 e_attachment_view_set_dragging (
69 E_ATTACHMENT_VIEW (object),
70 g_value_get_boolean (value));
71 return;
72
73 case PROP_EDITABLE:
74 e_attachment_view_set_editable (
75 E_ATTACHMENT_VIEW (object),
76 g_value_get_boolean (value));
77 return;
78 }
79
80 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
81 }
82
83 static void
attachment_icon_view_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)84 attachment_icon_view_get_property (GObject *object,
85 guint property_id,
86 GValue *value,
87 GParamSpec *pspec)
88 {
89 switch (property_id) {
90 case PROP_DRAGGING:
91 g_value_set_boolean (
92 value, e_attachment_view_get_dragging (
93 E_ATTACHMENT_VIEW (object)));
94 return;
95
96 case PROP_EDITABLE:
97 g_value_set_boolean (
98 value, e_attachment_view_get_editable (
99 E_ATTACHMENT_VIEW (object)));
100 return;
101 }
102
103 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
104 }
105
106 static void
attachment_icon_view_dispose(GObject * object)107 attachment_icon_view_dispose (GObject *object)
108 {
109 e_attachment_view_dispose (E_ATTACHMENT_VIEW (object));
110
111 /* Chain up to parent's dispose() method. */
112 G_OBJECT_CLASS (e_attachment_icon_view_parent_class)->dispose (object);
113 }
114
115 static void
attachment_icon_view_finalize(GObject * object)116 attachment_icon_view_finalize (GObject *object)
117 {
118 e_attachment_view_finalize (E_ATTACHMENT_VIEW (object));
119
120 /* Chain up to parent's finalize() method. */
121 G_OBJECT_CLASS (e_attachment_icon_view_parent_class)->finalize (object);
122 }
123
124 static void
attachment_icon_view_constructed(GObject * object)125 attachment_icon_view_constructed (GObject *object)
126 {
127 GtkCellLayout *cell_layout;
128 GtkCellRenderer *renderer;
129
130 /* Chain up to parent's method. */
131 G_OBJECT_CLASS (e_attachment_icon_view_parent_class)->constructed (object);
132
133 gtk_icon_view_set_selection_mode (GTK_ICON_VIEW (object), GTK_SELECTION_MULTIPLE);
134 gtk_icon_view_set_item_width (GTK_ICON_VIEW (object), 96);
135
136 cell_layout = GTK_CELL_LAYOUT (object);
137
138 /* This needs to happen after constructor properties are set
139 * so that GtkCellLayout.get_area() returns something valid. */
140
141 renderer = gtk_cell_renderer_pixbuf_new ();
142 g_object_set (renderer,
143 "stock-size", GTK_ICON_SIZE_DIALOG,
144 "xalign", 0.5,
145 "yalign", 0.5,
146 NULL);
147 gtk_cell_layout_pack_start (cell_layout, renderer, FALSE);
148
149 gtk_cell_layout_add_attribute (
150 cell_layout, renderer, "gicon",
151 E_ATTACHMENT_STORE_COLUMN_ICON);
152
153 renderer = gtk_cell_renderer_text_new ();
154 g_object_set (renderer,
155 "alignment", PANGO_ALIGN_LEFT,
156 "ellipsize", PANGO_ELLIPSIZE_END,
157 "wrap-mode", PANGO_WRAP_WORD,
158 "wrap-width", 96,
159 "scale", 0.8,
160 "xpad", 0,
161 "xalign", 0.5,
162 "yalign", 0.0,
163 NULL);
164 gtk_cell_layout_pack_start (cell_layout, renderer, FALSE);
165
166 gtk_cell_layout_add_attribute (
167 cell_layout, renderer, "text",
168 E_ATTACHMENT_STORE_COLUMN_CAPTION);
169
170 renderer = gtk_cell_renderer_progress_new ();
171 g_object_set (renderer, "text", _("Loading"), NULL);
172 gtk_cell_layout_pack_start (cell_layout, renderer, TRUE);
173
174 gtk_cell_layout_add_attribute (
175 cell_layout, renderer, "value",
176 E_ATTACHMENT_STORE_COLUMN_PERCENT);
177
178 gtk_cell_layout_add_attribute (
179 cell_layout, renderer, "visible",
180 E_ATTACHMENT_STORE_COLUMN_LOADING);
181
182 renderer = gtk_cell_renderer_progress_new ();
183 g_object_set (renderer, "text", _("Saving"), NULL);
184 gtk_cell_layout_pack_start (cell_layout, renderer, TRUE);
185
186 gtk_cell_layout_add_attribute (
187 cell_layout, renderer, "value",
188 E_ATTACHMENT_STORE_COLUMN_PERCENT);
189
190 gtk_cell_layout_add_attribute (
191 cell_layout, renderer, "visible",
192 E_ATTACHMENT_STORE_COLUMN_SAVING);
193
194 e_extensible_load_extensions (E_EXTENSIBLE (object));
195 }
196
197 static gboolean
attachment_icon_view_button_press_event(GtkWidget * widget,GdkEventButton * event)198 attachment_icon_view_button_press_event (GtkWidget *widget,
199 GdkEventButton *event)
200 {
201 EAttachmentView *view = E_ATTACHMENT_VIEW (widget);
202
203 if (!e_attachment_view_button_press_event (view, event)) {
204 /* Chain up to parent's button_press_event() method. */
205 GTK_WIDGET_CLASS (e_attachment_icon_view_parent_class)->
206 button_press_event (widget, event);
207 }
208
209 /* Never propagate the event to the parent */
210 return TRUE;
211 }
212
213 static gboolean
attachment_icon_view_button_release_event(GtkWidget * widget,GdkEventButton * event)214 attachment_icon_view_button_release_event (GtkWidget *widget,
215 GdkEventButton *event)
216 {
217 EAttachmentView *view = E_ATTACHMENT_VIEW (widget);
218
219 if (!e_attachment_view_button_release_event (view, event)) {
220 /* Chain up to parent's button_release_event() method. */
221 GTK_WIDGET_CLASS (e_attachment_icon_view_parent_class)->
222 button_release_event (widget, event);
223 }
224
225 /* Never propagate the event to the parent */
226 return TRUE;
227 }
228
229 static gboolean
attachment_icon_view_motion_notify_event(GtkWidget * widget,GdkEventMotion * event)230 attachment_icon_view_motion_notify_event (GtkWidget *widget,
231 GdkEventMotion *event)
232 {
233 EAttachmentView *view = E_ATTACHMENT_VIEW (widget);
234
235 if (!e_attachment_view_motion_notify_event (view, event)) {
236 /* Chain up to parent's motion_notify_event() method. */
237 GTK_WIDGET_CLASS (e_attachment_icon_view_parent_class)->
238 motion_notify_event (widget, event);
239 }
240
241 /* Never propagate the event to the parent */
242 return TRUE;
243 }
244
245 static gboolean
attachment_icon_view_key_press_event(GtkWidget * widget,GdkEventKey * event)246 attachment_icon_view_key_press_event (GtkWidget *widget,
247 GdkEventKey *event)
248 {
249 EAttachmentView *view = E_ATTACHMENT_VIEW (widget);
250
251 if (e_attachment_view_key_press_event (view, event))
252 return TRUE;
253
254 /* Chain up to parent's key_press_event() method. */
255 return GTK_WIDGET_CLASS (e_attachment_icon_view_parent_class)->
256 key_press_event (widget, event);
257 }
258
259 static void
attachment_icon_view_drag_begin(GtkWidget * widget,GdkDragContext * context)260 attachment_icon_view_drag_begin (GtkWidget *widget,
261 GdkDragContext *context)
262 {
263 EAttachmentView *view = E_ATTACHMENT_VIEW (widget);
264
265 /* Chain up to parent's drag_begin() method. */
266 GTK_WIDGET_CLASS (e_attachment_icon_view_parent_class)->
267 drag_begin (widget, context);
268
269 e_attachment_view_drag_begin (view, context);
270 }
271
272 static void
attachment_icon_view_drag_end(GtkWidget * widget,GdkDragContext * context)273 attachment_icon_view_drag_end (GtkWidget *widget,
274 GdkDragContext *context)
275 {
276 EAttachmentView *view = E_ATTACHMENT_VIEW (widget);
277
278 /* Chain up to parent's drag_end() method. */
279 GTK_WIDGET_CLASS (e_attachment_icon_view_parent_class)->
280 drag_end (widget, context);
281
282 e_attachment_view_drag_end (view, context);
283 }
284
285 static void
attachment_icon_view_drag_data_get(GtkWidget * widget,GdkDragContext * context,GtkSelectionData * selection,guint info,guint time)286 attachment_icon_view_drag_data_get (GtkWidget *widget,
287 GdkDragContext *context,
288 GtkSelectionData *selection,
289 guint info,
290 guint time)
291 {
292 EAttachmentView *view = E_ATTACHMENT_VIEW (widget);
293
294 e_attachment_view_drag_data_get (
295 view, context, selection, info, time);
296 }
297
298 static gboolean
attachment_icon_view_drag_motion(GtkWidget * widget,GdkDragContext * context,gint x,gint y,guint time)299 attachment_icon_view_drag_motion (GtkWidget *widget,
300 GdkDragContext *context,
301 gint x,
302 gint y,
303 guint time)
304 {
305 EAttachmentView *view = E_ATTACHMENT_VIEW (widget);
306
307 return e_attachment_view_drag_motion (view, context, x, y, time);
308 }
309
310 static gboolean
attachment_icon_view_drag_drop(GtkWidget * widget,GdkDragContext * context,gint x,gint y,guint time)311 attachment_icon_view_drag_drop (GtkWidget *widget,
312 GdkDragContext *context,
313 gint x,
314 gint y,
315 guint time)
316 {
317 EAttachmentView *view = E_ATTACHMENT_VIEW (widget);
318
319 if (!e_attachment_view_drag_drop (view, context, x, y, time))
320 return FALSE;
321
322 /* Chain up to parent's drag_drop() method. */
323 return GTK_WIDGET_CLASS (e_attachment_icon_view_parent_class)->
324 drag_drop (widget, context, x, y, time);
325 }
326
327 static void
attachment_icon_view_drag_data_received(GtkWidget * widget,GdkDragContext * context,gint x,gint y,GtkSelectionData * selection,guint info,guint time)328 attachment_icon_view_drag_data_received (GtkWidget *widget,
329 GdkDragContext *context,
330 gint x,
331 gint y,
332 GtkSelectionData *selection,
333 guint info,
334 guint time)
335 {
336 EAttachmentView *view = E_ATTACHMENT_VIEW (widget);
337
338 e_attachment_view_drag_data_received (
339 view, context, x, y, selection, info, time);
340 }
341
342 static gboolean
attachment_icon_view_popup_menu(GtkWidget * widget)343 attachment_icon_view_popup_menu (GtkWidget *widget)
344 {
345 EAttachmentView *view = E_ATTACHMENT_VIEW (widget);
346 GtkWidget *menu;
347
348 e_attachment_view_update_actions (view);
349 menu = e_attachment_view_get_popup_menu (view);
350 gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
351
352 return TRUE;
353 }
354
355 static void
attachment_icon_view_item_activated(GtkIconView * icon_view,GtkTreePath * path)356 attachment_icon_view_item_activated (GtkIconView *icon_view,
357 GtkTreePath *path)
358 {
359 EAttachmentView *view = E_ATTACHMENT_VIEW (icon_view);
360
361 e_attachment_view_open_path (view, path, NULL);
362 }
363
364 static EAttachmentViewPrivate *
attachment_icon_view_get_private(EAttachmentView * view)365 attachment_icon_view_get_private (EAttachmentView *view)
366 {
367 EAttachmentIconViewPrivate *priv;
368
369 priv = E_ATTACHMENT_ICON_VIEW_GET_PRIVATE (view);
370
371 return &priv->view_priv;
372 }
373
374 static EAttachmentStore *
attachment_icon_view_get_store(EAttachmentView * view)375 attachment_icon_view_get_store (EAttachmentView *view)
376 {
377 GtkIconView *icon_view;
378 GtkTreeModel *model;
379
380 icon_view = GTK_ICON_VIEW (view);
381 model = gtk_icon_view_get_model (icon_view);
382
383 return E_ATTACHMENT_STORE (model);
384 }
385
386 static GtkTreePath *
attachment_icon_view_get_path_at_pos(EAttachmentView * view,gint x,gint y)387 attachment_icon_view_get_path_at_pos (EAttachmentView *view,
388 gint x,
389 gint y)
390 {
391 GtkIconView *icon_view;
392
393 icon_view = GTK_ICON_VIEW (view);
394
395 return gtk_icon_view_get_path_at_pos (icon_view, x, y);
396 }
397
398 static GList *
attachment_icon_view_get_selected_paths(EAttachmentView * view)399 attachment_icon_view_get_selected_paths (EAttachmentView *view)
400 {
401 GtkIconView *icon_view;
402
403 icon_view = GTK_ICON_VIEW (view);
404
405 return gtk_icon_view_get_selected_items (icon_view);
406 }
407
408 static gboolean
attachment_icon_view_path_is_selected(EAttachmentView * view,GtkTreePath * path)409 attachment_icon_view_path_is_selected (EAttachmentView *view,
410 GtkTreePath *path)
411 {
412 GtkIconView *icon_view;
413
414 icon_view = GTK_ICON_VIEW (view);
415
416 return gtk_icon_view_path_is_selected (icon_view, path);
417 }
418
419 static void
attachment_icon_view_select_path(EAttachmentView * view,GtkTreePath * path)420 attachment_icon_view_select_path (EAttachmentView *view,
421 GtkTreePath *path)
422 {
423 GtkIconView *icon_view;
424
425 icon_view = GTK_ICON_VIEW (view);
426
427 gtk_icon_view_select_path (icon_view, path);
428 }
429
430 static void
attachment_icon_view_unselect_path(EAttachmentView * view,GtkTreePath * path)431 attachment_icon_view_unselect_path (EAttachmentView *view,
432 GtkTreePath *path)
433 {
434 GtkIconView *icon_view;
435
436 icon_view = GTK_ICON_VIEW (view);
437
438 gtk_icon_view_unselect_path (icon_view, path);
439 }
440
441 static void
attachment_icon_view_select_all(EAttachmentView * view)442 attachment_icon_view_select_all (EAttachmentView *view)
443 {
444 GtkIconView *icon_view;
445
446 icon_view = GTK_ICON_VIEW (view);
447
448 gtk_icon_view_select_all (icon_view);
449 }
450
451 static void
attachment_icon_view_unselect_all(EAttachmentView * view)452 attachment_icon_view_unselect_all (EAttachmentView *view)
453 {
454 GtkIconView *icon_view;
455
456 icon_view = GTK_ICON_VIEW (view);
457
458 gtk_icon_view_unselect_all (icon_view);
459 }
460
461 static void
attachment_icon_view_drag_source_set(EAttachmentView * view,GdkModifierType start_button_mask,const GtkTargetEntry * targets,gint n_targets,GdkDragAction actions)462 attachment_icon_view_drag_source_set (EAttachmentView *view,
463 GdkModifierType start_button_mask,
464 const GtkTargetEntry *targets,
465 gint n_targets,
466 GdkDragAction actions)
467 {
468 GtkIconView *icon_view;
469
470 icon_view = GTK_ICON_VIEW (view);
471
472 gtk_icon_view_enable_model_drag_source (
473 icon_view, start_button_mask, targets, n_targets, actions);
474 }
475
476 static void
attachment_icon_view_drag_dest_set(EAttachmentView * view,const GtkTargetEntry * targets,gint n_targets,GdkDragAction actions)477 attachment_icon_view_drag_dest_set (EAttachmentView *view,
478 const GtkTargetEntry *targets,
479 gint n_targets,
480 GdkDragAction actions)
481 {
482 GtkIconView *icon_view;
483
484 icon_view = GTK_ICON_VIEW (view);
485
486 gtk_icon_view_enable_model_drag_dest (
487 icon_view, targets, n_targets, actions);
488 }
489
490 static void
attachment_icon_view_drag_source_unset(EAttachmentView * view)491 attachment_icon_view_drag_source_unset (EAttachmentView *view)
492 {
493 GtkIconView *icon_view;
494
495 icon_view = GTK_ICON_VIEW (view);
496
497 gtk_icon_view_unset_model_drag_source (icon_view);
498 }
499
500 static void
attachment_icon_view_drag_dest_unset(EAttachmentView * view)501 attachment_icon_view_drag_dest_unset (EAttachmentView *view)
502 {
503 GtkIconView *icon_view;
504
505 icon_view = GTK_ICON_VIEW (view);
506
507 gtk_icon_view_unset_model_drag_dest (icon_view);
508 }
509
510 static void
e_attachment_icon_view_class_init(EAttachmentIconViewClass * class)511 e_attachment_icon_view_class_init (EAttachmentIconViewClass *class)
512 {
513 GObjectClass *object_class;
514 GtkWidgetClass *widget_class;
515 GtkIconViewClass *icon_view_class;
516
517 g_type_class_add_private (class, sizeof (EAttachmentViewPrivate));
518
519 object_class = G_OBJECT_CLASS (class);
520 object_class->set_property = attachment_icon_view_set_property;
521 object_class->get_property = attachment_icon_view_get_property;
522 object_class->dispose = attachment_icon_view_dispose;
523 object_class->finalize = attachment_icon_view_finalize;
524 object_class->constructed = attachment_icon_view_constructed;
525
526 widget_class = GTK_WIDGET_CLASS (class);
527 widget_class->button_press_event = attachment_icon_view_button_press_event;
528 widget_class->button_release_event = attachment_icon_view_button_release_event;
529 widget_class->motion_notify_event = attachment_icon_view_motion_notify_event;
530 widget_class->key_press_event = attachment_icon_view_key_press_event;
531 widget_class->drag_begin = attachment_icon_view_drag_begin;
532 widget_class->drag_end = attachment_icon_view_drag_end;
533 widget_class->drag_data_get = attachment_icon_view_drag_data_get;
534 widget_class->drag_motion = attachment_icon_view_drag_motion;
535 widget_class->drag_drop = attachment_icon_view_drag_drop;
536 widget_class->drag_data_received = attachment_icon_view_drag_data_received;
537 widget_class->popup_menu = attachment_icon_view_popup_menu;
538
539 icon_view_class = GTK_ICON_VIEW_CLASS (class);
540 icon_view_class->item_activated = attachment_icon_view_item_activated;
541
542 g_object_class_override_property (
543 object_class, PROP_DRAGGING, "dragging");
544
545 g_object_class_override_property (
546 object_class, PROP_EDITABLE, "editable");
547 }
548
549 static void
e_attachment_icon_view_init(EAttachmentIconView * icon_view)550 e_attachment_icon_view_init (EAttachmentIconView *icon_view)
551 {
552 icon_view->priv = E_ATTACHMENT_ICON_VIEW_GET_PRIVATE (icon_view);
553
554 e_attachment_view_init (E_ATTACHMENT_VIEW (icon_view));
555 }
556
557 static void
e_attachment_icon_view_interface_init(EAttachmentViewInterface * iface)558 e_attachment_icon_view_interface_init (EAttachmentViewInterface *iface)
559 {
560 iface->get_private = attachment_icon_view_get_private;
561 iface->get_store = attachment_icon_view_get_store;
562
563 iface->get_path_at_pos = attachment_icon_view_get_path_at_pos;
564 iface->get_selected_paths = attachment_icon_view_get_selected_paths;
565 iface->path_is_selected = attachment_icon_view_path_is_selected;
566 iface->select_path = attachment_icon_view_select_path;
567 iface->unselect_path = attachment_icon_view_unselect_path;
568 iface->select_all = attachment_icon_view_select_all;
569 iface->unselect_all = attachment_icon_view_unselect_all;
570
571 iface->drag_source_set = attachment_icon_view_drag_source_set;
572 iface->drag_dest_set = attachment_icon_view_drag_dest_set;
573 iface->drag_source_unset = attachment_icon_view_drag_source_unset;
574 iface->drag_dest_unset = attachment_icon_view_drag_dest_unset;
575 }
576
577 GtkWidget *
e_attachment_icon_view_new(void)578 e_attachment_icon_view_new (void)
579 {
580 return g_object_new (E_TYPE_ATTACHMENT_ICON_VIEW, NULL);
581 }
582