evolution-3.6.4/widgets/misc/e-attachment-tree-view.c

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 }