glade-clipboard-view.c 10.1 KB
Newer Older
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/*
 * glade-clipboard-view.c - The View for the Clipboard.
 *
 * Copyright (C) 2001 The GNOME Foundation.
 *
 * Author(s):
 *      Archit Baweja <bighead@users.sourceforge.net>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
 * USA.
 */
25 26 27 28
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

29 30 31 32 33 34 35 36
/**
 * SECTION:glade-clipboard-view
 * @Short_Description: A widget to view and control the #GladeClipboard.
 *
 * The #GladeClipboardView is a widget to view the #GladeWidget objects
 * in the #GladeClipboard; the user can paste or delete objects on the clipboard.
 */

37
#include <glib/gi18n-lib.h>
38 39 40 41 42

#include "glade.h"
#include "glade-clipboard.h"
#include "glade-clipboard-view.h"
#include "glade-widget.h"
43
#include "glade-widget-adaptor.h"
44
#include "glade-popup.h"
45 46


47 48 49
const gint GLADE_CLIPBOARD_VIEW_WIDTH  = 230;
const gint GLADE_CLIPBOARD_VIEW_HEIGHT = 200;

50
static void
51
glade_clipboard_view_class_init (GladeClipboardViewClass *klass)
52 53 54
{

}
55 56

static void
57 58 59 60 61 62 63
glade_clipboard_view_init (GladeClipboardView *view)
{
	view->widget = NULL;
	view->clipboard = NULL;
	view->model = NULL;
}

64
GType
65 66
glade_clipboard_view_get_type ()
{
67
	static GType type = 0;
68 69

	if (!type) {
70
		static const GTypeInfo info = {
71
			sizeof (GladeClipboardViewClass),
72 73 74 75 76 77 78 79
			(GBaseInitFunc) NULL,
			(GBaseFinalizeFunc) NULL,
			(GClassInitFunc) glade_clipboard_view_class_init,
			(GClassFinalizeFunc) NULL,
			NULL,
			sizeof (GladeClipboardView),
			0,
			(GInstanceInitFunc) glade_clipboard_view_init
80 81
		};

82
		type = g_type_register_static (GTK_TYPE_WINDOW, "GladeClipboardView", &info, 0);
83 84 85 86 87 88
	}

	return type;
}

static void
89 90 91 92
gcv_foreach_add_selection (GtkTreeModel *model, 
			   GtkTreePath  *path,
			   GtkTreeIter  *iter, 
			   gpointer      data)
93
{
94 95 96 97 98
	GladeWidget        *widget = NULL;
	GladeClipboardView *view   = (GladeClipboardView *)data;
	gtk_tree_model_get (model, iter, 0, &widget, -1);
	glade_clipboard_selection_add (view->clipboard, (widget));
}
99

100 101 102 103 104 105 106 107 108 109
static void
glade_clipboard_view_selection_changed_cb (GtkTreeSelection   *sel,
					   GladeClipboardView *view)
{
	if (view->updating == FALSE)
	{
		glade_clipboard_selection_clear (view->clipboard);
		gtk_tree_selection_selected_foreach
			(sel, gcv_foreach_add_selection, view);
	}
110 111 112
}

static void
113
glade_clipboard_view_populate_model (GladeClipboardView *view)
114
{
115 116 117 118 119
	GladeClipboard   *clipboard;
	GtkTreeModel     *model;
	GladeWidget      *widget;
	GList            *list;
	GtkTreeIter       iter;
120

121
	clipboard = GLADE_CLIPBOARD (view->clipboard);
122
	model     = GTK_TREE_MODEL (view->model);
123

124 125
	for (list = clipboard->widgets; list; list = list->next) 
	{
126
		widget = list->data;
127 128 129 130
		view->updating = TRUE;
		gtk_list_store_append (GTK_LIST_STORE (model), &iter);
		gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, widget, -1);
		view->updating = FALSE;
131 132 133 134
	}
}

static void
135 136 137 138 139
glade_clipboard_view_cell_function (GtkTreeViewColumn *tree_column,
				    GtkCellRenderer *cell,
				    GtkTreeModel *tree_model,
				    GtkTreeIter *iter,
				    gpointer data)
140
{
141
	gboolean     is_icon = GPOINTER_TO_INT (data);
142
	GladeWidget *widget;
143

144
	gtk_tree_model_get (tree_model, iter, 0, &widget, -1);
145

146 147
	g_return_if_fail (GLADE_IS_WIDGET (widget));
	g_return_if_fail (widget->name != NULL);
148

149 150
	if (is_icon)
		g_object_set (G_OBJECT (cell),
Vincent Geddes's avatar
Vincent Geddes committed
151 152
			      "icon-name", widget->adaptor->icon_name,
			      "stock-size", GTK_ICON_SIZE_MENU,
153 154 155 156 157
			      NULL);
	else
		g_object_set (G_OBJECT (cell),
			      "text", widget->name,
			      NULL);
158

159 160
}

161 162 163 164 165 166 167 168 169 170
static gint
glade_clipboard_view_button_press_cb (GtkWidget          *widget,
				      GdkEventButton     *event,
				      GladeClipboardView *view)
{
	GtkTreeView      *tree_view = GTK_TREE_VIEW (widget);
	GtkTreePath      *path      = NULL;
	gboolean          handled   = FALSE;

	if (event->window == gtk_tree_view_get_bin_window (tree_view) &&
171 172
	    gtk_tree_view_get_path_at_pos (tree_view,
					   (gint) event->x, (gint) event->y,
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
					   &path, NULL, 
					   NULL, NULL) && path != NULL)
	{
		GtkTreeIter  iter;
		GladeWidget *widget = NULL;
		if (gtk_tree_model_get_iter (GTK_TREE_MODEL (view->model),
					     &iter, path))
		{
			/* Alright, now we can obtain 
			 * the widget from the iter.
			 */
			gtk_tree_model_get (GTK_TREE_MODEL (view->model), &iter,
					    0, &widget, -1);
			if (widget != NULL &&
				    event->button == 3)
			{
				glade_popup_clipboard_pop (widget, event);
				handled = TRUE;
			}
			gtk_tree_path_free (path);
		}
	}
	return handled;
}

198
static void
199
glade_clipboard_view_create_tree_view (GladeClipboardView *view)
200
{
201 202
	GtkTreeSelection  *sel;
	GtkCellRenderer   *renderer;
203
	GtkTreeViewColumn *column;
204 205 206 207

	view->widget =
	    gtk_tree_view_new_with_model (GTK_TREE_MODEL (view->model));

208 209 210 211 212 213
	column = gtk_tree_view_column_new ();
	gtk_tree_view_column_set_title (column, _("Widget"));

	renderer = gtk_cell_renderer_pixbuf_new ();
	gtk_tree_view_column_pack_start (column, renderer, FALSE);
	gtk_tree_view_column_set_cell_data_func (column, renderer,
214
						 glade_clipboard_view_cell_function,
215 216 217
						 GINT_TO_POINTER (1), NULL);

	renderer = gtk_cell_renderer_text_new ();
218 219
	g_object_set (G_OBJECT (renderer), 
		      "xpad", 6, NULL);
220 221 222 223 224 225
	gtk_tree_view_column_pack_start (column, renderer, TRUE);
	gtk_tree_view_column_set_cell_data_func (column, renderer,
						 glade_clipboard_view_cell_function,
						 GINT_TO_POINTER (0), NULL);

	gtk_tree_view_append_column (GTK_TREE_VIEW (view->widget), column);
226 227

	sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view->widget));
228
	gtk_tree_selection_set_mode (sel, GTK_SELECTION_MULTIPLE);
229
	
230
	g_signal_connect_data (G_OBJECT (sel), "changed",
231
			       G_CALLBACK (glade_clipboard_view_selection_changed_cb),
232
			       view, NULL, 0);
233 234 235 236 237

	/* Popup menu */
	g_signal_connect (G_OBJECT (view->widget), "button-press-event",
			  G_CALLBACK (glade_clipboard_view_button_press_cb), view);

238 239 240
}

static void
241
glade_clipboard_view_construct (GladeClipboardView *view)
242
{
Tristan Van Berkom's avatar
Tristan Van Berkom committed
243
	GtkWidget *scrolled_window, *viewport;
244

245 246
	view->model = gtk_list_store_new (1, G_TYPE_POINTER);

247
	glade_clipboard_view_populate_model (view);
248
	glade_clipboard_view_create_tree_view (view);
249
	glade_clipboard_view_refresh_sel (view);
250

Tristan Van Berkom's avatar
Tristan Van Berkom committed
251 252 253
	viewport = gtk_viewport_new (NULL, NULL);
	gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport), GTK_SHADOW_OUT);

254
	scrolled_window = gtk_scrolled_window_new (NULL, NULL);
Tristan Van Berkom's avatar
Tristan Van Berkom committed
255 256 257
	gtk_scrolled_window_set_shadow_type
		(GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN);
	gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 
258
					6);
259
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
260 261 262
					GTK_POLICY_AUTOMATIC,
					GTK_POLICY_AUTOMATIC);
	gtk_container_add (GTK_CONTAINER (scrolled_window), view->widget);
Tristan Van Berkom's avatar
Tristan Van Berkom committed
263 264
	gtk_container_add (GTK_CONTAINER (viewport), scrolled_window);
	gtk_container_add (GTK_CONTAINER (view), viewport);
265

266 267 268 269
	gtk_window_set_default_size (GTK_WINDOW (view),
				     GLADE_CLIPBOARD_VIEW_WIDTH,
				     GLADE_CLIPBOARD_VIEW_HEIGHT);

270 271
	gtk_window_set_type_hint (GTK_WINDOW (view), GDK_WINDOW_TYPE_HINT_UTILITY);

272
	gtk_widget_show_all (scrolled_window);
273

274
	return;
275 276 277 278
}

/**
 * glade_clipboard_view_new:
279
 * @clipboard: a #GladeClipboard
280
 * 
281
 * Create a new #GladeClipboardView widget for @clipboard.
282
 *
283 284
 * Returns: a new #GladeClipboardView cast to be a #GtkWidget
 */
285
GtkWidget *
286
glade_clipboard_view_new (GladeClipboard *clipboard)
287 288 289
{
	GladeClipboardView *view;

290
	g_return_val_if_fail (GLADE_IS_CLIPBOARD (clipboard), NULL);
291 292 293 294 295 296 297 298

	view = gtk_type_new (glade_clipboard_view_get_type ());
	view->clipboard = clipboard;
	glade_clipboard_view_construct (view);

	return GTK_WIDGET (view);
}

299 300 301 302 303 304 305
/**
 * glade_clipboard_view_add:
 * @view: a #GladeClipboardView
 * @widget: a #GladeWidget
 *
 * Adds @widget to @view.
 */
306
void
307
glade_clipboard_view_add (GladeClipboardView *view, GladeWidget *widget)
308 309 310 311 312 313
{
	GtkTreeIter iter;

	g_return_if_fail (GLADE_IS_CLIPBOARD_VIEW (view));
	g_return_if_fail (GLADE_IS_WIDGET (widget));

314
	view->updating = TRUE;
315
	gtk_list_store_append (view->model, &iter);
316 317
	gtk_list_store_set    (view->model, &iter, 0, widget, -1);
	view->updating = FALSE;
318 319
}

320 321 322 323 324 325 326
/**
 * glade_cliboard_view_remove:
 * @view: a #GladeClipboardView
 * @widget: a #GladeWidget
 *
 * Removes @widget from @view.
 */
327
void
328
glade_clipboard_view_remove (GladeClipboardView *view, GladeWidget *widget)
329
{
330
	GtkTreeIter   iter;
331
	GtkTreeModel *model;
332
	GladeWidget  *clip_widget;
333 334 335 336

	g_return_if_fail (GLADE_IS_CLIPBOARD_VIEW (view));
	g_return_if_fail (GLADE_IS_WIDGET (widget));

337
	model = GTK_TREE_MODEL (view->model);
338 339 340 341
	if (gtk_tree_model_get_iter_first (model, &iter)) 
	{
		do 
		{
342 343 344
			gtk_tree_model_get (model, &iter, 0, &clip_widget, -1);
			if (widget == clip_widget)
				break;
345 346
		}
		while (gtk_tree_model_iter_next (model, &iter));
347 348
	}

349
	view->updating = TRUE;
350
	gtk_list_store_remove (view->model, &iter);
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
	view->updating = FALSE;
}

/**
 * glade_clipboard_view_refresh_sel:
 * @view: a #GladeClipboardView
 *
 * Synchronizes the treeview selection to the clipboard selection.
 */
void
glade_clipboard_view_refresh_sel (GladeClipboardView *view)
{
	GladeWidget      *widget;
	GtkTreeSelection *sel;
	GList            *list;
	GtkTreeIter      *iter;
	
	g_return_if_fail (GLADE_IS_CLIPBOARD_VIEW (view));

	if (view->updating) return;
	view->updating = TRUE;

	sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view->widget));

	gtk_tree_selection_unselect_all (sel);
	for (list = view->clipboard->selection; 
	     list && list->data; list = list->next)
	{
		widget = list->data;
		if ((iter = glade_util_find_iter_by_widget 
		     (GTK_TREE_MODEL (view->model), widget, 0)) != NULL)
		{
			gtk_tree_selection_select_iter (sel, iter);
384
			/* gtk_tree_iter_free (iter); */
385 386 387
		}
	}
	view->updating = FALSE;
388
}