Text samples
[dia.git] / app / select.c
blob0da89fd1272d2640349f1cff9699e111044ddb0c
1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
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
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 /* select.c -- callbacks to implement the Select menu */
20 #include <config.h>
22 #include <assert.h>
24 #include "select.h"
25 #include "menus.h"
26 #include "intl.h"
27 #include "object_ops.h"
29 enum SelectionStyle selection_style = SELECT_REPLACE;
31 void
32 select_all_callback(gpointer data, guint action, GtkWidget *widget)
34 Diagram *dia;
35 GList *objects;
36 DDisplay * ddisp = ddisplay_active();
38 if (!ddisp) return;
39 dia = ddisp->diagram;
41 objects = dia->data->active_layer->objects;
43 while (objects != NULL) {
44 DiaObject *obj = (DiaObject *)objects->data;
46 if (!diagram_is_selected(dia, obj))
47 diagram_select(dia, obj);
49 objects = g_list_next(objects);
52 ddisplay_do_update_menu_sensitivity(ddisp);
53 object_add_updates_list(dia->data->selected, dia);
54 diagram_flush(dia);
57 void
58 select_none_callback(gpointer data, guint action, GtkWidget *widget)
60 Diagram * dia;
61 DDisplay * ddisp = ddisplay_active();
63 if (!ddisp) return;
64 dia = ddisp->diagram;
66 diagram_remove_all_selected(dia, TRUE);
68 ddisplay_do_update_menu_sensitivity(ddisp);
69 object_add_updates_list(dia->data->selected, dia);
70 diagram_flush(dia);
73 void
74 select_invert_callback(gpointer data, guint action, GtkWidget *widget)
76 Diagram *dia;
77 GList *tmp;
78 DDisplay * ddisp = ddisplay_active();
80 if (!ddisp) return;
81 dia = ddisp->diagram;
83 tmp = dia->data->active_layer->objects;
85 for (; tmp != NULL; tmp = g_list_next(tmp)) {
86 DiaObject *obj = (DiaObject *)tmp->data;
88 if (!diagram_is_selected(dia, obj))
89 diagram_select(dia, obj);
90 else
91 diagram_unselect_object(dia, obj);
94 ddisplay_do_update_menu_sensitivity(ddisp);
95 object_add_updates_list(dia->data->selected, dia);
96 diagram_flush(dia);
100 /** Select objects that are directly connected to the currently selected
101 * objects, but only in the active layer.
103 void
104 select_connected_callback(gpointer data, guint action, GtkWidget *widget)
106 Diagram *dia;
107 DDisplay * ddisp = ddisplay_active();
108 GList *objects, *tmp;
110 if (!ddisp) return;
111 dia = ddisp->diagram;
113 objects = dia->data->selected;
115 for (tmp = objects; tmp != NULL; tmp = g_list_next(tmp)) {
116 DiaObject *obj = (DiaObject *)tmp->data;
117 int i;
119 for (i = 0; i < obj->num_handles; i++) {
120 Handle *handle = obj->handles[i];
122 if (handle->connected_to != NULL &&
123 handle->connected_to->object->parent_layer == dia->data->active_layer) {
124 if (!diagram_is_selected(dia, handle->connected_to->object)) {
125 diagram_select(dia, handle->connected_to->object);
131 for (tmp = objects; tmp != NULL; tmp = tmp->next) {
132 DiaObject *obj = (DiaObject *)tmp->data;
133 int i;
135 for (i = 0; i < obj->num_connections; i++) {
136 ConnectionPoint *connection = obj->connections[i];
137 GList *conns = connection->connected;
139 for (; conns != NULL; conns = g_list_next(conns)) {
140 DiaObject *obj2 = (DiaObject *)conns->data;
142 if (obj2->parent_layer == dia->data->active_layer
143 && !diagram_is_selected(dia, obj2)) {
144 diagram_select(dia, obj2);
150 ddisplay_do_update_menu_sensitivity(ddisp);
151 object_add_updates_list(dia->data->selected, dia);
152 diagram_flush(dia);
155 static void
156 select_transitively(Diagram *dia, DiaObject *obj)
158 int i;
159 /* Do breadth-first to avoid overly large stack */
160 GList *newly_selected = NULL;
162 for (i = 0; i < obj->num_handles; i++) {
163 Handle *handle = obj->handles[i];
165 if (handle->connected_to != NULL &&
166 handle->connected_to->object->parent_layer == dia->data->active_layer) {
167 if (!diagram_is_selected(dia, handle->connected_to->object)) {
168 diagram_select(dia, handle->connected_to->object);
169 newly_selected = g_list_prepend(newly_selected, handle->connected_to->object);
174 for (i = 0; i < obj->num_connections; i++) {
175 ConnectionPoint *connection = obj->connections[i];
176 GList *conns = connection->connected;
178 for (; conns != NULL; conns = g_list_next(conns)) {
179 DiaObject *obj2 = (DiaObject *)conns->data;
181 if (obj2->parent_layer == dia->data->active_layer
182 && !diagram_is_selected(dia, obj2)) {
183 diagram_select(dia, obj2);
184 newly_selected = g_list_prepend(newly_selected, obj2);
189 while (newly_selected != NULL) {
190 select_transitively(dia, (DiaObject *)newly_selected->data);
191 newly_selected = g_list_next(newly_selected);
195 /** Select objects that are in any way connected with a currently selected
196 * object, but only in the active layer.
198 void
199 select_transitive_callback(gpointer data, guint action, GtkWidget *widget)
201 DDisplay *ddisp = ddisplay_active();
202 Diagram *dia;
203 GList *objects, *tmp;
205 if (!ddisp) return;
206 dia = ddisp->diagram;
208 objects = dia->data->selected;
210 for (tmp = objects; tmp != NULL; tmp = g_list_next(tmp)) {
211 select_transitively(dia, (DiaObject *)tmp->data);
214 ddisplay_do_update_menu_sensitivity(ddisp);
215 object_add_updates_list(dia->data->selected, dia);
216 diagram_flush(dia);
219 void
220 select_same_type_callback(gpointer data, guint action, GtkWidget *widget)
222 /* For now, do a brute force version: Check vs. all earlier selected.
223 Later, we should really sort the selecteds first to avoid n^2 */
224 DDisplay *ddisp = ddisplay_active();
225 Diagram *dia;
226 GList *objects, *tmp, *tmp2;
228 if (!ddisp) return;
229 dia = ddisp->diagram;
231 tmp = dia->data->active_layer->objects;
233 objects = dia->data->selected;
235 for (; tmp != NULL; tmp = g_list_next(tmp)) {
236 DiaObject *obj = (DiaObject *)tmp->data;
238 if (!diagram_is_selected(dia, obj)) {
239 for (tmp2 = objects; tmp2 != NULL; tmp2 = g_list_next(tmp2)) {
240 DiaObject *obj2 = (DiaObject *)tmp2->data;
242 if (obj->type == obj2->type) {
243 diagram_select(dia, obj);
244 break;
250 ddisplay_do_update_menu_sensitivity(ddisp);
251 object_add_updates_list(dia->data->selected, dia);
252 diagram_flush(dia);
255 void
256 select_style_callback(gpointer data, guint action, GtkWidget *widget)
258 if (ddisplay_active () == NULL) return;
260 /* simply set the selection style to the value of `action' */
261 selection_style = action;