Bug Summary

File:libbaul-private/baul-icon-container.c
Warning:line 1518, column 9
Value stored to 'y' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name baul-icon-container.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/rootdir/libbaul-private -fcoverage-compilation-dir=/rootdir/libbaul-private -resource-dir /usr/lib/llvm-19/lib/clang/19 -D HAVE_CONFIG_H -I . -I .. -I .. -I .. -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/cafe-desktop-2.0 -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/startup-notification-1.0 -I /usr/include/dconf -I /usr/include/cail-3.0 -I /usr/include/libxml2 -D G_DISABLE_DEPRECATED -D GDK_PIXBUF_DISABLE_DEPRECATED -D DATADIR="/usr/share" -D SYSCONFDIR="/usr/etc" -D BAUL_DATADIR="/usr/share/baul" -D BAUL_EXTENSIONDIR="/usr/lib/baul/extensions-2.0" -D PIC -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2025-09-05-155501-27616-1 -x c baul-icon-container.c
1/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2
3/* baul-icon-container.c - Icon container widget.
4
5 Copyright (C) 1999, 2000 Free Software Foundation
6 Copyright (C) 2000, 2001 Eazel, Inc.
7 Copyright (C) 2002, 2003 Red Hat, Inc.
8
9 The Cafe Library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version.
13
14 The Cafe Library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Library General Public License for more details.
18
19 You should have received a copy of the GNU Library General Public
20 License along with the Cafe Library; see the file COPYING.LIB. If not,
21 write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22 Boston, MA 02110-1301, USA.
23
24 Authors: Ettore Perazzoli <ettore@gnu.org>,
25 Darin Adler <darin@bentspoon.com>
26*/
27
28#include <config.h>
29#include <math.h>
30#include <atk/atkaction.h>
31#include <cdk/cdkkeysyms.h>
32#include <ctk/ctk.h>
33#include <cdk/cdkx.h>
34#include <glib/gi18n.h>
35#include <stdio.h>
36#include <string.h>
37
38#include <eel/eel-accessibility.h>
39#include <eel/eel-background.h>
40#include <eel/eel-vfs-extensions.h>
41#include <eel/eel-gdk-pixbuf-extensions.h>
42#include <eel/eel-cafe-extensions.h>
43#include <eel/eel-ctk-extensions.h>
44#include <eel/eel-art-extensions.h>
45#include <eel/eel-editable-label.h>
46#include <eel/eel-string.h>
47#include <eel/eel-canvas.h>
48#include <eel/eel-canvas-rect-ellipse.h>
49
50#include "baul-icon-container.h"
51#include "baul-debug-log.h"
52#include "baul-global-preferences.h"
53#include "baul-icon-private.h"
54#include "baul-lib-self-check-functions.h"
55#include "baul-marshal.h"
56
57#define TAB_NAVIGATION_DISABLED
58
59/* Interval for updating the rubberband selection, in milliseconds. */
60#define RUBBERBAND_TIMEOUT_INTERVAL10 10
61
62/* Initial unpositioned icon value */
63#define ICON_UNPOSITIONED_VALUE-1 -1
64
65/* Timeout for making the icon currently selected for keyboard operation visible.
66 * If this is 0, you can get into trouble with extra scrolling after holding
67 * down the arrow key for awhile when there are many items.
68 */
69#define KEYBOARD_ICON_REVEAL_TIMEOUT10 10
70
71#define CONTEXT_MENU_TIMEOUT_INTERVAL500 500
72
73/* Maximum amount of milliseconds the mouse button is allowed to stay down
74 * and still be considered a click.
75 */
76#define MAX_CLICK_TIME1500 1500
77
78/* Button assignments. */
79#define DRAG_BUTTON1 1
80#define RUBBERBAND_BUTTON1 1
81#define MIDDLE_BUTTON2 2
82#define CONTEXTUAL_MENU_BUTTON3 3
83#define DRAG_MENU_BUTTON2 2
84
85/* Maximum size (pixels) allowed for icons at the standard zoom level. */
86#define MINIMUM_IMAGE_SIZE24 24
87#define MAXIMUM_IMAGE_SIZE96 96
88
89#define ICON_PAD_LEFT4 4
90#define ICON_PAD_RIGHT4 4
91#define ICON_BASE_WIDTH96 96
92
93#define ICON_PAD_TOP4 4
94#define ICON_PAD_BOTTOM4 4
95
96#define CONTAINER_PAD_LEFT4 4
97#define CONTAINER_PAD_RIGHT4 4
98#define CONTAINER_PAD_TOP4 4
99#define CONTAINER_PAD_BOTTOM4 4
100
101#define STANDARD_ICON_GRID_WIDTH155 155
102
103#define TEXT_BESIDE_ICON_GRID_WIDTH205 205
104
105/* Desktop layout mode defines */
106#define DESKTOP_PAD_HORIZONTAL10 10
107#define DESKTOP_PAD_VERTICAL10 10
108#define SNAP_SIZE_X78 78
109#define SNAP_SIZE_Y20 20
110
111#define DEFAULT_SELECTION_BOX_ALPHA0x40 0x40
112#define DEFAULT_HIGHLIGHT_ALPHA0xff 0xff
113#define DEFAULT_NORMAL_ALPHA0xff 0xff
114#define DEFAULT_PRELIGHT_ALPHA0xff 0xff
115#define DEFAULT_LIGHT_INFO_COLOR"#AAAAFD" "#AAAAFD"
116#define DEFAULT_DARK_INFO_COLOR"#33337F" "#33337F"
117
118#define MINIMUM_EMBEDDED_TEXT_RECT_WIDTH20 20
119#define MINIMUM_EMBEDDED_TEXT_RECT_HEIGHT20 20
120
121/* If icon size is bigger than this, request large embedded text.
122 * Its selected so that the non-large text should fit in "normal" icon sizes
123 */
124#define ICON_SIZE_FOR_LARGE_EMBEDDED_TEXT55 55
125
126/* From baul-icon-canvas-item.c */
127#define MAX_TEXT_WIDTH_BESIDE90 90
128
129#define SNAP_HORIZONTAL(func,x)((func ((double)((x) - 10) / 78) * 78) + 10) ((func ((double)((x) - DESKTOP_PAD_HORIZONTAL10) / SNAP_SIZE_X78) * SNAP_SIZE_X78) + DESKTOP_PAD_HORIZONTAL10)
130#define SNAP_VERTICAL(func, y)((func ((double)((y) - 10) / 20) * 20) + 10) ((func ((double)((y) - DESKTOP_PAD_VERTICAL10) / SNAP_SIZE_Y20) * SNAP_SIZE_Y20) + DESKTOP_PAD_VERTICAL10)
131
132#define SNAP_NEAREST_HORIZONTAL(x)((eel_round ((double)((x) - 10) / 78) * 78) + 10) SNAP_HORIZONTAL (eel_round, x)((eel_round ((double)((x) - 10) / 78) * 78) + 10)
133#define SNAP_NEAREST_VERTICAL(y)((eel_round ((double)((y) - 10) / 20) * 20) + 10) SNAP_VERTICAL (eel_round, y)((eel_round ((double)((y) - 10) / 20) * 20) + 10)
134
135#define SNAP_CEIL_HORIZONTAL(x)((ceil ((double)((x) - 10) / 78) * 78) + 10) SNAP_HORIZONTAL (ceil, x)((ceil ((double)((x) - 10) / 78) * 78) + 10)
136#define SNAP_CEIL_VERTICAL(y)((ceil ((double)((y) - 10) / 20) * 20) + 10) SNAP_VERTICAL (ceil, y)((ceil ((double)((y) - 10) / 20) * 20) + 10)
137
138/* Copied from BaulIconContainer */
139#define BAUL_ICON_CONTAINER_SEARCH_DIALOG_TIMEOUT5 5
140
141/* Copied from BaulFile */
142#define UNDEFINED_TIME((time_t) (-1)) ((time_t) (-1))
143
144enum
145{
146 ACTION_ACTIVATE,
147 ACTION_MENU,
148 LAST_ACTION
149};
150
151typedef struct
152{
153 GList *selection;
154 char *action_descriptions[LAST_ACTION];
155} BaulIconContainerAccessiblePrivate;
156
157static GType baul_icon_container_accessible_get_type (void);
158
159typedef struct _BaulIconContainerAccessible BaulIconContainerAccessible;
160typedef struct _BaulIconContainerAccessibleClass BaulIconContainerAccessibleClass;
161
162struct _BaulIconContainerAccessible
163{
164 EelCanvasAccessible parent;
165};
166
167struct _BaulIconContainerAccessibleClass
168{
169 EelCanvasAccessibleClass parent_class;
170};
171
172static void activate_selected_items (BaulIconContainer *container);
173static void activate_selected_items_alternate (BaulIconContainer *container,
174 BaulIcon *icon);
175static void compute_stretch (StretchState *start,
176 StretchState *current);
177static BaulIcon *get_first_selected_icon (BaulIconContainer *container);
178static BaulIcon *get_nth_selected_icon (BaulIconContainer *container,
179 int index);
180static gboolean has_multiple_selection (BaulIconContainer *container);
181static gboolean all_selected (BaulIconContainer *container);
182static gboolean has_selection (BaulIconContainer *container);
183static void icon_destroy (BaulIconContainer *container,
184 BaulIcon *icon);
185static void end_renaming_mode (BaulIconContainer *container,
186 gboolean commit);
187static BaulIcon *get_icon_being_renamed (BaulIconContainer *container);
188static void finish_adding_new_icons (BaulIconContainer *container);
189static inline void icon_get_bounding_box (BaulIcon *icon,
190 int *x1_return,
191 int *y1_return,
192 int *x2_return,
193 int *y2_return,
194 BaulIconCanvasItemBoundsUsage usage);
195static gboolean is_renaming (BaulIconContainer *container);
196static gboolean is_renaming_pending (BaulIconContainer *container);
197static void process_pending_icon_to_rename (BaulIconContainer *container);
198static void handle_hadjustment_changed (CtkAdjustment *adjustment,
199 BaulIconContainer *container);
200static void handle_vadjustment_changed (CtkAdjustment *adjustment,
201 BaulIconContainer *container);
202static GList * baul_icon_container_get_selected_icons (BaulIconContainer *container);
203static void baul_icon_container_update_visible_icons (BaulIconContainer *container);
204static void reveal_icon (BaulIconContainer *container,
205 BaulIcon *icon);
206
207static void baul_icon_container_set_rtl_positions (BaulIconContainer *container);
208static double get_mirror_x_position (BaulIconContainer *container,
209 BaulIcon *icon,
210 double x);
211static void text_ellipsis_limit_changed_container_callback (gpointer callback_data);
212
213static int compare_icons_horizontal (BaulIconContainer *container,
214 BaulIcon *icon_a,
215 BaulIcon *icon_b);
216
217static int compare_icons_vertical (BaulIconContainer *container,
218 BaulIcon *icon_a,
219 BaulIcon *icon_b);
220
221static void store_layout_timestamps_now (BaulIconContainer *container);
222
223static gpointer accessible_parent_class;
224
225static GQuark accessible_private_data_quark = 0;
226
227static const char *baul_icon_container_accessible_action_names[] =
228{
229 "activate",
230 "menu",
231 NULL((void*)0)
232};
233
234static const char *baul_icon_container_accessible_action_descriptions[] =
235{
236 "Activate selected items",
237 "Popup context menu",
238 NULL((void*)0)
239};
240
241G_DEFINE_TYPE (BaulIconContainer, baul_icon_container, EEL_TYPE_CANVAS)static void baul_icon_container_init (BaulIconContainer *self
); static void baul_icon_container_class_init (BaulIconContainerClass
*klass); static GType baul_icon_container_get_type_once (void
); static gpointer baul_icon_container_parent_class = ((void*
)0); static gint BaulIconContainer_private_offset; static void
baul_icon_container_class_intern_init (gpointer klass) { baul_icon_container_parent_class
= g_type_class_peek_parent (klass); if (BaulIconContainer_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &BaulIconContainer_private_offset
); baul_icon_container_class_init ((BaulIconContainerClass*) klass
); } __attribute__ ((__unused__)) static inline gpointer baul_icon_container_get_instance_private
(BaulIconContainer *self) { return (((gpointer) ((guint8*) (
self) + (glong) (BaulIconContainer_private_offset)))); } GType
baul_icon_container_get_type (void) { static GType static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) * (&static_g_define_type_id) : ((void*)
0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= baul_icon_container_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType baul_icon_container_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((eel_canvas_get_type ()), g_intern_static_string ("BaulIconContainer"
), sizeof (BaulIconContainerClass), (GClassInitFunc)(void (*)
(void)) baul_icon_container_class_intern_init, sizeof (BaulIconContainer
), (GInstanceInitFunc)(void (*)(void)) baul_icon_container_init
, (GTypeFlags) 0); { {{};} } return g_define_type_id; }
;
242
243/* The BaulIconContainer signals. */
244enum
245{
246 ACTIVATE,
247 ACTIVATE_ALTERNATE,
248 BAND_SELECT_STARTED,
249 BAND_SELECT_ENDED,
250 BUTTON_PRESS,
251 CAN_ACCEPT_ITEM,
252 CONTEXT_CLICK_BACKGROUND,
253 CONTEXT_CLICK_SELECTION,
254 MIDDLE_CLICK,
255 GET_CONTAINER_URI,
256 GET_ICON_URI,
257 GET_ICON_DROP_TARGET_URI,
258 GET_STORED_ICON_POSITION,
259 ICON_POSITION_CHANGED,
260 GET_STORED_LAYOUT_TIMESTAMP,
261 STORE_LAYOUT_TIMESTAMP,
262 ICON_TEXT_CHANGED,
263 ICON_STRETCH_STARTED,
264 ICON_STRETCH_ENDED,
265 RENAMING_ICON,
266 LAYOUT_CHANGED,
267 MOVE_COPY_ITEMS,
268 HANDLE_NETSCAPE_URL,
269 HANDLE_URI_LIST,
270 HANDLE_TEXT,
271 HANDLE_RAW,
272 PREVIEW,
273 SELECTION_CHANGED,
274 ICON_ADDED,
275 ICON_REMOVED,
276 CLEARED,
277 START_INTERACTIVE_SEARCH,
278 LAST_SIGNAL
279};
280
281typedef struct
282{
283 int **icon_grid;
284 int *grid_memory;
285 int num_rows;
286 int num_columns;
287 gboolean tight;
288} PlacementGrid;
289
290static guint signals[LAST_SIGNAL] = { 0 };
291
292/* Functions dealing with BaulIcons. */
293
294static void
295icon_free (BaulIcon *icon)
296{
297 /* Destroy this canvas item; the parent will unref it. */
298 eel_canvas_item_destroy (EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
);
299 g_free (icon);
300}
301
302static gboolean
303icon_is_positioned (const BaulIcon *icon)
304{
305 return icon->x != ICON_UNPOSITIONED_VALUE-1 && icon->y != ICON_UNPOSITIONED_VALUE-1;
306}
307
308
309/* x, y are the top-left coordinates of the icon. */
310static void
311icon_set_position (BaulIcon *icon,
312 double x, double y)
313{
314 BaulIconContainer *container;
315 int x1, x2, y1, y2;
316 EelDRect icon_bounds;
317
318 if (icon->x == x && icon->y == y)
319 {
320 return;
321 }
322
323 container = BAUL_ICON_CONTAINER (EEL_CANVAS_ITEM (icon->item)->canvas)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((((((EelCanvasItem*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((icon->item)), ((eel_canvas_item_get_type
()))))))->canvas)), (baul_icon_container_get_type())))))
;
324
325 if (icon == get_icon_being_renamed (container))
326 {
327 end_renaming_mode (container, TRUE(!(0)));
328 }
329
330 if (baul_icon_container_get_is_fixed_size (container))
331 {
332 double pixels_per_unit;
333 int container_left, container_top, container_right, container_bottom;
334 int container_x, container_y, container_width, container_height;
335 int item_width, item_height;
336 int height_above, width_left;
337 int min_x, max_x, min_y, max_y;
338 int scale;
339
340 /* FIXME: This should be:
341
342 container_x = CTK_WIDGET (container)->allocation.x;
343 container_y = CTK_WIDGET (container)->allocation.y;
344 container_width = CTK_WIDGET (container)->allocation.width;
345 container_height = CTK_WIDGET (container)->allocation.height;
346
347 But for some reason the widget allocation is sometimes not done
348 at startup, and the allocation is then only 45x60. which is
349 really bad.
350
351 For now, we have a cheesy workaround:
352 */
353 scale = ctk_widget_get_scale_factor (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
);
354 container_x = 0;
355 container_y = 0;
356 container_width = WidthOfScreen (cdk_x11_screen_get_xscreen (cdk_screen_get_default ()))((cdk_x11_screen_get_xscreen (cdk_screen_get_default ()))->
width)
/ scale - container_x
357 - container->details->left_margin
358 - container->details->right_margin;
359 container_height = HeightOfScreen (cdk_x11_screen_get_xscreen (cdk_screen_get_default ()))((cdk_x11_screen_get_xscreen (cdk_screen_get_default ()))->
height)
/ scale - container_y
360 - container->details->top_margin
361 - container->details->bottom_margin;
362 pixels_per_unit = EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
->pixels_per_unit;
363 /* Clip the position of the icon within our desktop bounds */
364 container_left = container_x / pixels_per_unit;
365 container_top = container_y / pixels_per_unit;
366 container_right = container_left + container_width / pixels_per_unit;
367 container_bottom = container_top + container_height / pixels_per_unit;
368
369 icon_get_bounding_box (icon, &x1, &y1, &x2, &y2,
370 BOUNDS_USAGE_FOR_ENTIRE_ITEM);
371 item_width = x2 - x1;
372 item_height = y2 - y1;
373
374 icon_bounds = baul_icon_canvas_item_get_icon_rectangle (icon->item);
375
376 /* determine icon rectangle relative to item rectangle */
377 height_above = icon_bounds.y0 - y1;
378 width_left = icon_bounds.x0 - x1;
379
380 min_x = container_left + DESKTOP_PAD_HORIZONTAL10 + width_left;
381 max_x = container_right - DESKTOP_PAD_HORIZONTAL10 - item_width + width_left;
382 x = CLAMP (x, min_x, max_x)(((x) > (max_x)) ? (max_x) : (((x) < (min_x)) ? (min_x)
: (x)))
;
383
384 min_y = container_top + height_above + DESKTOP_PAD_VERTICAL10;
385 max_y = container_bottom - DESKTOP_PAD_VERTICAL10 - item_height + height_above;
386 y = CLAMP (y, min_y, max_y)(((y) > (max_y)) ? (max_y) : (((y) < (min_y)) ? (min_y)
: (y)))
;
387 }
388
389 if (icon->x == ICON_UNPOSITIONED_VALUE-1)
390 {
391 icon->x = 0;
392 }
393 if (icon->y == ICON_UNPOSITIONED_VALUE-1)
394 {
395 icon->y = 0;
396 }
397
398 eel_canvas_item_move (EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
,
399 x - icon->x,
400 y - icon->y);
401
402 icon->x = x;
403 icon->y = y;
404}
405
406static void
407icon_get_size (BaulIconContainer *container,
408 BaulIcon *icon,
409 guint *size)
410{
411 if (size != NULL((void*)0))
412 {
413 *size = MAX (baul_get_icon_size_for_zoom_level (container->details->zoom_level)(((baul_get_icon_size_for_zoom_level (container->details->
zoom_level) * icon->scale) > (16)) ? (baul_get_icon_size_for_zoom_level
(container->details->zoom_level) * icon->scale) : (
16))
414 * icon->scale, BAUL_ICON_SIZE_SMALLEST)(((baul_get_icon_size_for_zoom_level (container->details->
zoom_level) * icon->scale) > (16)) ? (baul_get_icon_size_for_zoom_level
(container->details->zoom_level) * icon->scale) : (
16))
;
415 }
416}
417
418/* The icon_set_size function is used by the stretching user
419 * interface, which currently stretches in a way that keeps the aspect
420 * ratio. Later we might have a stretching interface that stretches Y
421 * separate from X and we will change this around.
422 */
423static void
424icon_set_size (BaulIconContainer *container,
425 BaulIcon *icon,
426 guint icon_size,
427 gboolean snap,
428 gboolean update_position)
429{
430 guint old_size;
431 double scale;
432
433 icon_get_size (container, icon, &old_size);
434 if (icon_size == old_size)
435 {
436 return;
437 }
438
439 scale = (double) icon_size /
440 baul_get_icon_size_for_zoom_level
441 (container->details->zoom_level);
442 baul_icon_container_move_icon (container, icon,
443 icon->x, icon->y,
444 scale, FALSE(0),
445 snap, update_position);
446}
447
448static void
449icon_raise (BaulIcon *icon)
450{
451 EelCanvasItem *item, *band;
452
453 item = EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
;
454 band = BAUL_ICON_CONTAINER (item->canvas)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((item->canvas)), (baul_icon_container_get_type
())))))
->details->rubberband_info.selection_rectangle;
455
456 eel_canvas_item_send_behind (item, band);
457}
458
459static void
460emit_stretch_started (BaulIconContainer *container, BaulIcon *icon)
461{
462 g_signal_emit (container,
463 signals[ICON_STRETCH_STARTED], 0,
464 icon->data);
465}
466
467static void
468emit_stretch_ended (BaulIconContainer *container, BaulIcon *icon)
469{
470 g_signal_emit (container,
471 signals[ICON_STRETCH_ENDED], 0,
472 icon->data);
473}
474
475static void
476icon_toggle_selected (BaulIconContainer *container,
477 BaulIcon *icon)
478{
479 end_renaming_mode (container, TRUE(!(0)));
480
481 icon->is_selected = !icon->is_selected;
482 eel_canvas_item_set (EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
,
483 "highlighted_for_selection", (gboolean) icon->is_selected,
484 NULL((void*)0));
485
486 /* If the icon is deselected, then get rid of the stretch handles.
487 * No harm in doing the same if the item is newly selected.
488 */
489 if (icon == container->details->stretch_icon)
490 {
491 container->details->stretch_icon = NULL((void*)0);
492 baul_icon_canvas_item_set_show_stretch_handles (icon->item, FALSE(0));
493 /* snap the icon if necessary */
494 if (container->details->keep_aligned)
495 {
496 baul_icon_container_move_icon (container,
497 icon,
498 icon->x, icon->y,
499 icon->scale,
500 FALSE(0), TRUE(!(0)), TRUE(!(0)));
501 }
502
503 emit_stretch_ended (container, icon);
504 }
505
506 /* Raise each newly-selected icon to the front as it is selected. */
507 if (icon->is_selected)
508 {
509 icon_raise (icon);
510 }
511}
512
513/* Select an icon. Return TRUE if selection has changed. */
514static gboolean
515icon_set_selected (BaulIconContainer *container,
516 BaulIcon *icon,
517 gboolean select)
518{
519 g_assert (select == FALSE || select == TRUE)do { if (select == (0) || select == (!(0))) ; else g_assertion_message_expr
(((gchar*) 0), "baul-icon-container.c", 519, ((const char*) (
__func__)), "select == FALSE || select == TRUE"); } while (0)
;
520 g_assert (icon->is_selected == FALSE || icon->is_selected == TRUE)do { if (icon->is_selected == (0) || icon->is_selected ==
(!(0))) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 520, ((const char*) (__func__)), "icon->is_selected == FALSE || icon->is_selected == TRUE"
); } while (0)
;
521
522 if (select == icon->is_selected)
523 {
524 return FALSE(0);
525 }
526
527 icon_toggle_selected (container, icon);
528 g_assert (select == icon->is_selected)do { if (select == icon->is_selected) ; else g_assertion_message_expr
(((gchar*) 0), "baul-icon-container.c", 528, ((const char*) (
__func__)), "select == icon->is_selected"); } while (0)
;
529 return TRUE(!(0));
530}
531
532static inline void
533icon_get_bounding_box (BaulIcon *icon,
534 int *x1_return, int *y1_return,
535 int *x2_return, int *y2_return,
536 BaulIconCanvasItemBoundsUsage usage)
537{
538 double x1, y1, x2, y2;
539
540 if (usage == BOUNDS_USAGE_FOR_DISPLAY)
541 {
542 eel_canvas_item_get_bounds (EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
,
543 &x1, &y1, &x2, &y2);
544 }
545 else if (usage == BOUNDS_USAGE_FOR_LAYOUT)
546 {
547 baul_icon_canvas_item_get_bounds_for_layout (icon->item,
548 &x1, &y1, &x2, &y2);
549 }
550 else if (usage == BOUNDS_USAGE_FOR_ENTIRE_ITEM)
551 {
552 baul_icon_canvas_item_get_bounds_for_entire_item (icon->item,
553 &x1, &y1, &x2, &y2);
554 }
555 else
556 {
557 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 557, ((const char*) (__func__)), ((void*)0)); } while (0)
;
558 }
559
560 if (x1_return != NULL((void*)0))
561 {
562 *x1_return = x1;
563 }
564
565 if (y1_return != NULL((void*)0))
566 {
567 *y1_return = y1;
568 }
569
570 if (x2_return != NULL((void*)0))
571 {
572 *x2_return = x2;
573 }
574
575 if (y2_return != NULL((void*)0))
576 {
577 *y2_return = y2;
578 }
579}
580
581/* Utility functions for BaulIconContainer. */
582
583gboolean
584baul_icon_container_scroll (BaulIconContainer *container,
585 int delta_x, int delta_y)
586{
587 CtkAdjustment *hadj, *vadj;
588 int old_h_value, old_v_value;
589
590 hadj = ctk_scrollable_get_hadjustment (CTK_SCROLLABLE (container)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_scrollable_get_type ()))))))
);
591 vadj = ctk_scrollable_get_vadjustment (CTK_SCROLLABLE (container)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_scrollable_get_type ()))))))
);
592
593 /* Store the old ajustment values so we can tell if we
594 * ended up actually scrolling. We may not have in a case
595 * where the resulting value got pinned to the adjustment
596 * min or max.
597 */
598 old_h_value = ctk_adjustment_get_value (hadj);
599 old_v_value = ctk_adjustment_get_value (vadj);
600
601 ctk_adjustment_set_value (hadj, ctk_adjustment_get_value (hadj) + delta_x);
602 ctk_adjustment_set_value (vadj, ctk_adjustment_get_value (vadj) + delta_y);
603
604 /* return TRUE if we did scroll */
605 return ctk_adjustment_get_value (hadj) != old_h_value || ctk_adjustment_get_value (vadj) != old_v_value;
606}
607
608static void
609pending_icon_to_reveal_destroy_callback (BaulIconCanvasItem *item,
610 BaulIconContainer *container)
611{
612 g_assert (BAUL_IS_ICON_CONTAINER (container))do { if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 612, ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); } while (0)
;
613 g_assert (container->details->pending_icon_to_reveal != NULL)do { if (container->details->pending_icon_to_reveal != (
(void*)0)) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 613, ((const char*) (__func__)), "container->details->pending_icon_to_reveal != NULL"
); } while (0)
;
614 g_assert (container->details->pending_icon_to_reveal->item == item)do { if (container->details->pending_icon_to_reveal->
item == item) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 614, ((const char*) (__func__)), "container->details->pending_icon_to_reveal->item == item"
); } while (0)
;
615
616 container->details->pending_icon_to_reveal = NULL((void*)0);
617}
618
619static BaulIcon*
620get_pending_icon_to_reveal (BaulIconContainer *container)
621{
622 return container->details->pending_icon_to_reveal;
623}
624
625static void
626set_pending_icon_to_reveal (BaulIconContainer *container, BaulIcon *icon)
627{
628 BaulIcon *old_icon;
629
630 old_icon = container->details->pending_icon_to_reveal;
631
632 if (icon == old_icon)
633 {
634 return;
635 }
636
637 if (old_icon != NULL((void*)0))
638 {
639 g_signal_handlers_disconnect_by_funcg_signal_handlers_disconnect_matched ((old_icon->item), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (((GCallback) (pending_icon_to_reveal_destroy_callback)))
, (container))
640 (old_icon->item,g_signal_handlers_disconnect_matched ((old_icon->item), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (((GCallback) (pending_icon_to_reveal_destroy_callback)))
, (container))
641 G_CALLBACK (pending_icon_to_reveal_destroy_callback),g_signal_handlers_disconnect_matched ((old_icon->item), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (((GCallback) (pending_icon_to_reveal_destroy_callback)))
, (container))
642 container)g_signal_handlers_disconnect_matched ((old_icon->item), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (((GCallback) (pending_icon_to_reveal_destroy_callback)))
, (container))
;
643 }
644
645 if (icon != NULL((void*)0))
646 {
647 g_signal_connect (icon->item, "destroy",g_signal_connect_data ((icon->item), ("destroy"), (((GCallback
) (pending_icon_to_reveal_destroy_callback))), (container), (
(void*)0), (GConnectFlags) 0)
648 G_CALLBACK (pending_icon_to_reveal_destroy_callback),g_signal_connect_data ((icon->item), ("destroy"), (((GCallback
) (pending_icon_to_reveal_destroy_callback))), (container), (
(void*)0), (GConnectFlags) 0)
649 container)g_signal_connect_data ((icon->item), ("destroy"), (((GCallback
) (pending_icon_to_reveal_destroy_callback))), (container), (
(void*)0), (GConnectFlags) 0)
;
650 }
651
652 container->details->pending_icon_to_reveal = icon;
653}
654
655static void
656item_get_canvas_bounds (EelCanvasItem *item,
657 EelIRect *bounds,
658 gboolean safety_pad)
659{
660 EelDRect world_rect;
661
662 eel_canvas_item_get_bounds (item,
663 &world_rect.x0,
664 &world_rect.y0,
665 &world_rect.x1,
666 &world_rect.y1);
667 eel_canvas_item_i2w (item->parent,
668 &world_rect.x0,
669 &world_rect.y0);
670 eel_canvas_item_i2w (item->parent,
671 &world_rect.x1,
672 &world_rect.y1);
673 if (safety_pad)
674 {
675 world_rect.x0 -= ICON_PAD_LEFT4 + ICON_PAD_RIGHT4;
676 world_rect.x1 += ICON_PAD_LEFT4 + ICON_PAD_RIGHT4;
677
678 world_rect.y0 -= ICON_PAD_TOP4 + ICON_PAD_BOTTOM4;
679 world_rect.y1 += ICON_PAD_TOP4 + ICON_PAD_BOTTOM4;
680 }
681
682 eel_canvas_w2c (item->canvas,
683 world_rect.x0,
684 world_rect.y0,
685 &bounds->x0,
686 &bounds->y0);
687 eel_canvas_w2c (item->canvas,
688 world_rect.x1,
689 world_rect.y1,
690 &bounds->x1,
691 &bounds->y1);
692}
693
694static void
695icon_get_row_and_column_bounds (BaulIconContainer *container,
696 BaulIcon *icon,
697 EelIRect *bounds,
698 gboolean safety_pad)
699{
700 GList *p;
701 EelIRect one_bounds;
702 BaulIcon *one_icon = NULL((void*)0);
703
704 item_get_canvas_bounds (EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
, bounds, safety_pad);
705
706 for (p = container->details->icons; p != NULL((void*)0); p = p->next) {
707 one_icon = p->data;
708
709 if (icon == one_icon) {
710 continue;
711 }
712
713 if (compare_icons_horizontal (container, icon, one_icon) == 0) {
714 item_get_canvas_bounds (EEL_CANVAS_ITEM (one_icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((one_icon->item)), ((eel_canvas_item_get_type ()))))))
, &one_bounds, safety_pad);
715 bounds->x0 = MIN (bounds->x0, one_bounds.x0)(((bounds->x0) < (one_bounds.x0)) ? (bounds->x0) : (
one_bounds.x0))
;
716 bounds->x1 = MAX (bounds->x1, one_bounds.x1)(((bounds->x1) > (one_bounds.x1)) ? (bounds->x1) : (
one_bounds.x1))
;
717 }
718
719 if (compare_icons_vertical (container, icon, one_icon) == 0) {
720 item_get_canvas_bounds (EEL_CANVAS_ITEM (one_icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((one_icon->item)), ((eel_canvas_item_get_type ()))))))
, &one_bounds, safety_pad);
721 bounds->y0 = MIN (bounds->y0, one_bounds.y0)(((bounds->y0) < (one_bounds.y0)) ? (bounds->y0) : (
one_bounds.y0))
;
722 bounds->y1 = MAX (bounds->y1, one_bounds.y1)(((bounds->y1) > (one_bounds.y1)) ? (bounds->y1) : (
one_bounds.y1))
;
723 }
724 }
725
726
727}
728
729static void
730reveal_icon (BaulIconContainer *container,
731 BaulIcon *icon)
732{
733 CtkAllocation allocation;
734 CtkAdjustment *hadj, *vadj;
735 EelIRect bounds;
736
737 if (!icon_is_positioned (icon)) {
738 set_pending_icon_to_reveal (container, icon);
739 return;
740 }
741
742 set_pending_icon_to_reveal (container, NULL((void*)0));
743
744 ctk_widget_get_allocation (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
, &allocation);
745
746 hadj = ctk_scrollable_get_hadjustment (CTK_SCROLLABLE (container)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_scrollable_get_type ()))))))
);
747 vadj = ctk_scrollable_get_vadjustment (CTK_SCROLLABLE (container)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_scrollable_get_type ()))))))
);
748
749 if (baul_icon_container_is_auto_layout (container)) {
750 /* ensure that we reveal the entire row/column */
751 icon_get_row_and_column_bounds (container, icon, &bounds, TRUE(!(0)));
752 } else {
753 item_get_canvas_bounds (EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
, &bounds, TRUE(!(0)));
754 }
755 if (bounds.y0 < ctk_adjustment_get_value (vadj)) {
756 ctk_adjustment_set_value (vadj, bounds.y0);
757 } else if (bounds.y1 > ctk_adjustment_get_value (vadj) + allocation.height) {
758 ctk_adjustment_set_value (vadj, bounds.y1 - allocation.height);
759 }
760
761 if (bounds.x0 < ctk_adjustment_get_value (hadj)) {
762 ctk_adjustment_set_value (hadj, bounds.x0);
763 } else if (bounds.x1 > ctk_adjustment_get_value (hadj) + allocation.width) {
764 if (bounds.x1 - allocation.width > bounds.x0) {
765 ctk_adjustment_set_value (hadj, bounds.x0);
766 } else {
767 ctk_adjustment_set_value (hadj, bounds.x1 - allocation.width);
768 }
769 }
770}
771
772static void
773process_pending_icon_to_reveal (BaulIconContainer *container)
774{
775 BaulIcon *pending_icon_to_reveal;
776
777 pending_icon_to_reveal = get_pending_icon_to_reveal (container);
778
779 if (pending_icon_to_reveal != NULL((void*)0)) {
780 reveal_icon (container, pending_icon_to_reveal);
781 }
782}
783
784static gboolean
785keyboard_icon_reveal_timeout_callback (gpointer data)
786{
787 BaulIconContainer *container;
788 BaulIcon *icon;
789
790 container = BAUL_ICON_CONTAINER (data)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((data)), (baul_icon_container_get_type())))
))
;
791 icon = container->details->keyboard_icon_to_reveal;
792
793 g_assert (icon != NULL)do { if (icon != ((void*)0)) ; else g_assertion_message_expr (
((gchar*) 0), "baul-icon-container.c", 793, ((const char*) (__func__
)), "icon != NULL"); } while (0)
;
794
795 /* Only reveal the icon if it's still the keyboard focus or if
796 * it's still selected. Someone originally thought we should
797 * cancel this reveal if the user manages to sneak a direct
798 * scroll in before the timeout fires, but we later realized
799 * this wouldn't actually be an improvement
800 * (see bugzilla.gnome.org 40612).
801 */
802 if (icon == container->details->keyboard_focus
803 || icon->is_selected) {
804 reveal_icon (container, icon);
805 }
806 container->details->keyboard_icon_reveal_timer_id = 0;
807
808 return FALSE(0);
809}
810
811static void
812unschedule_keyboard_icon_reveal (BaulIconContainer *container)
813{
814 BaulIconContainerDetails *details;
815
816 details = container->details;
817
818 if (details->keyboard_icon_reveal_timer_id != 0) {
819 g_source_remove (details->keyboard_icon_reveal_timer_id);
820 }
821}
822
823static void
824schedule_keyboard_icon_reveal (BaulIconContainer *container,
825 BaulIcon *icon)
826{
827 BaulIconContainerDetails *details;
828
829 details = container->details;
830
831 unschedule_keyboard_icon_reveal (container);
832
833 details->keyboard_icon_to_reveal = icon;
834 details->keyboard_icon_reveal_timer_id
835 = g_timeout_add (KEYBOARD_ICON_REVEAL_TIMEOUT10,
836 keyboard_icon_reveal_timeout_callback,
837 container);
838}
839
840static void
841clear_keyboard_focus (BaulIconContainer *container)
842{
843 if (container->details->keyboard_focus != NULL((void*)0))
844 {
845 eel_canvas_item_set (EEL_CANVAS_ITEM (container->details->keyboard_focus->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container->details->keyboard_focus->item)), ((eel_canvas_item_get_type
()))))))
,
846 "highlighted_as_keyboard_focus", 0,
847 NULL((void*)0));
848 }
849
850 container->details->keyboard_focus = NULL((void*)0);
851}
852
853static void inline
854emit_atk_focus_state_change (BaulIcon *icon, gboolean focused)
855{
856 AtkObject *atk_object = atk_gobject_accessible_for_object (G_OBJECT (icon->item)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), (((GType) ((20) << (2))))))))
);
857 atk_object_notify_state_change (atk_object, ATK_STATE_FOCUSED, focused);
858}
859
860/* Set @icon as the icon currently selected for keyboard operations. */
861static void
862set_keyboard_focus (BaulIconContainer *container,
863 BaulIcon *icon)
864{
865 g_assert (icon != NULL)do { if (icon != ((void*)0)) ; else g_assertion_message_expr (
((gchar*) 0), "baul-icon-container.c", 865, ((const char*) (__func__
)), "icon != NULL"); } while (0)
;
866
867 if (icon == container->details->keyboard_focus)
868 {
869 return;
870 }
871
872 clear_keyboard_focus (container);
873
874 container->details->keyboard_focus = icon;
875
876 eel_canvas_item_set (EEL_CANVAS_ITEM (container->details->keyboard_focus->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container->details->keyboard_focus->item)), ((eel_canvas_item_get_type
()))))))
,
877 "highlighted_as_keyboard_focus", 1,
878 NULL((void*)0));
879
880 emit_atk_focus_state_change (icon, TRUE(!(0)));
881}
882
883static void
884set_keyboard_rubberband_start (BaulIconContainer *container,
885 BaulIcon *icon)
886{
887 container->details->keyboard_rubberband_start = icon;
888}
889
890static void
891clear_keyboard_rubberband_start (BaulIconContainer *container)
892{
893 container->details->keyboard_rubberband_start = NULL((void*)0);
894}
895
896/* carbon-copy of eel_canvas_group_bounds(), but
897 * for BaulIconContainerItems it returns the
898 * bounds for the “entire item”.
899 */
900static void
901get_icon_bounds_for_canvas_bounds (EelCanvasGroup *group,
902 double *x1, double *y1,
903 double *x2, double *y2,
904 BaulIconCanvasItemBoundsUsage usage)
905{
906 EelCanvasItem *child;
907 GList *list;
908 double tx1, ty1, tx2, ty2;
909 double minx, miny, maxx, maxy;
910 int set;
911
912 /* Get the bounds of the first visible item */
913
914 child = NULL((void*)0); /* Unnecessary but eliminates a warning. */
915
916 set = FALSE(0);
917
918 for (list = group->item_list; list; list = list->next)
919 {
920 child = list->data;
921
922 if (child->flags & EEL_CANVAS_ITEM_VISIBLE)
923 {
924 set = TRUE(!(0));
925 if (!BAUL_IS_ICON_CANVAS_ITEM (child)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(child)); GType __t = (baul_icon_canvas_item_get_type()); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
||
926 usage == BOUNDS_USAGE_FOR_DISPLAY)
927 {
928 eel_canvas_item_get_bounds (child, &minx, &miny, &maxx, &maxy);
929 }
930 else if (usage == BOUNDS_USAGE_FOR_LAYOUT)
931 {
932 baul_icon_canvas_item_get_bounds_for_layout (BAUL_ICON_CANVAS_ITEM (child)((((BaulIconCanvasItem*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((child)), (baul_icon_canvas_item_get_type()
)))))
,
933 &minx, &miny, &maxx, &maxy);
934 }
935 else if (usage == BOUNDS_USAGE_FOR_ENTIRE_ITEM)
936 {
937 baul_icon_canvas_item_get_bounds_for_entire_item (BAUL_ICON_CANVAS_ITEM (child)((((BaulIconCanvasItem*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((child)), (baul_icon_canvas_item_get_type()
)))))
,
938 &minx, &miny, &maxx, &maxy);
939 }
940 else
941 {
942 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 942, ((const char*) (__func__)), ((void*)0)); } while (0)
;
943 }
944 break;
945 }
946 }
947
948 /* If there were no visible items, return an empty bounding box */
949
950 if (!set)
951 {
952 *x1 = *y1 = *x2 = *y2 = 0.0;
953 return;
954 }
955
956 /* Now we can grow the bounds using the rest of the items */
957
958 list = list->next;
959
960 for (; list; list = list->next)
961 {
962 child = list->data;
963
964 if (!(child->flags & EEL_CANVAS_ITEM_VISIBLE))
965 continue;
966
967 if (!BAUL_IS_ICON_CANVAS_ITEM (child)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(child)); GType __t = (baul_icon_canvas_item_get_type()); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
||
968 usage == BOUNDS_USAGE_FOR_DISPLAY)
969 {
970 eel_canvas_item_get_bounds (child, &tx1, &ty1, &tx2, &ty2);
971 }
972 else if (usage == BOUNDS_USAGE_FOR_LAYOUT)
973 {
974 baul_icon_canvas_item_get_bounds_for_layout (BAUL_ICON_CANVAS_ITEM (child)((((BaulIconCanvasItem*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((child)), (baul_icon_canvas_item_get_type()
)))))
,
975 &tx1, &ty1, &tx2, &ty2);
976 }
977 else if (usage == BOUNDS_USAGE_FOR_ENTIRE_ITEM)
978 {
979 baul_icon_canvas_item_get_bounds_for_entire_item (BAUL_ICON_CANVAS_ITEM (child)((((BaulIconCanvasItem*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((child)), (baul_icon_canvas_item_get_type()
)))))
,
980 &tx1, &ty1, &tx2, &ty2);
981 }
982 else
983 {
984 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 984, ((const char*) (__func__)), ((void*)0)); } while (0)
;
985 }
986
987 if (tx1 < minx)
988 minx = tx1;
989
990 if (ty1 < miny)
991 miny = ty1;
992
993 if (tx2 > maxx)
994 maxx = tx2;
995
996 if (ty2 > maxy)
997 maxy = ty2;
998 }
999
1000 /* Make the bounds be relative to our parent's coordinate system */
1001
1002 if (EEL_CANVAS_ITEM (group)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((group)), ((eel_canvas_item_get_type ()))))))
->parent)
1003 {
1004 minx += group->xpos;
1005 miny += group->ypos;
1006 maxx += group->xpos;
1007 maxy += group->ypos;
1008 }
1009
1010 if (x1 != NULL((void*)0))
1011 {
1012 *x1 = minx;
1013 }
1014
1015 if (y1 != NULL((void*)0))
1016 {
1017 *y1 = miny;
1018 }
1019
1020 if (x2 != NULL((void*)0))
1021 {
1022 *x2 = maxx;
1023 }
1024
1025 if (y2 != NULL((void*)0))
1026 {
1027 *y2 = maxy;
1028 }
1029}
1030
1031static void
1032get_all_icon_bounds (BaulIconContainer *container,
1033 double *x1, double *y1,
1034 double *x2, double *y2,
1035 BaulIconCanvasItemBoundsUsage usage)
1036{
1037 /* FIXME bugzilla.gnome.org 42477: Do we have to do something about the rubberband
1038 * here? Any other non-icon items?
1039 */
1040 get_icon_bounds_for_canvas_bounds (EEL_CANVAS_GROUP (EEL_CANVAS (container)->root)((((EelCanvasGroup*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))->root)), (
(eel_canvas_group_get_type ()))))))
,
1041 x1, y1, x2, y2, usage);
1042}
1043
1044/* Don't preserve visible white space the next time the scroll region
1045 * is recomputed when the container is not empty. */
1046void
1047baul_icon_container_reset_scroll_region (BaulIconContainer *container)
1048{
1049 container->details->reset_scroll_region_trigger = TRUE(!(0));
1050}
1051
1052/* Set a new scroll region without eliminating any of the currently-visible area. */
1053static void
1054canvas_set_scroll_region_include_visible_area (EelCanvas *canvas,
1055 double x1, double y1,
1056 double x2, double y2)
1057{
1058 double old_x1, old_y1, old_x2, old_y2;
1059 double old_scroll_x, old_scroll_y;
1060 double height, width;
1061 CtkAllocation allocation;
1062
1063 eel_canvas_get_scroll_region (canvas, &old_x1, &old_y1, &old_x2, &old_y2);
1064 ctk_widget_get_allocation (CTK_WIDGET (canvas)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((canvas)), ((ctk_widget_get_type ()))))))
, &allocation);
1065
1066 width = (allocation.width) / canvas->pixels_per_unit;
1067 height = (allocation.height) / canvas->pixels_per_unit;
1068
1069 old_scroll_x = ctk_adjustment_get_value (ctk_scrollable_get_hadjustment (CTK_SCROLLABLE (canvas)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((canvas)), ((ctk_scrollable_get_type ()))))))
));
1070 old_scroll_y = ctk_adjustment_get_value (ctk_scrollable_get_vadjustment (CTK_SCROLLABLE (canvas)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((canvas)), ((ctk_scrollable_get_type ()))))))
));
1071
1072 x1 = MIN (x1, old_x1 + old_scroll_x)(((x1) < (old_x1 + old_scroll_x)) ? (x1) : (old_x1 + old_scroll_x
))
;
1073 y1 = MIN (y1, old_y1 + old_scroll_y)(((y1) < (old_y1 + old_scroll_y)) ? (y1) : (old_y1 + old_scroll_y
))
;
1074 x2 = MAX (x2, old_x1 + old_scroll_x + width)(((x2) > (old_x1 + old_scroll_x + width)) ? (x2) : (old_x1
+ old_scroll_x + width))
;
1075 y2 = MAX (y2, old_y1 + old_scroll_y + height)(((y2) > (old_y1 + old_scroll_y + height)) ? (y2) : (old_y1
+ old_scroll_y + height))
;
1076
1077 eel_canvas_set_scroll_region
1078 (canvas, x1, y1, x2, y2);
1079}
1080
1081void
1082baul_icon_container_update_scroll_region (BaulIconContainer *container)
1083{
1084 double x1, y1, x2, y2;
1085 double pixels_per_unit;
1086 CtkAdjustment *hadj, *vadj;
1087 float step_increment;
1088 gboolean reset_scroll_region;
1089 CtkAllocation allocation;
1090
1091 pixels_per_unit = EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
->pixels_per_unit;
1092
1093 if (baul_icon_container_get_is_fixed_size (container))
1094 {
1095 /* Set the scroll region to the size of the container allocation */
1096 ctk_widget_get_allocation (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
, &allocation);
1097 eel_canvas_set_scroll_region
1098 (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
,
1099 (double) - container->details->left_margin / pixels_per_unit,
1100 (double) - container->details->top_margin / pixels_per_unit,
1101 ((double) (allocation.width - 1)
1102 - container->details->left_margin
1103 - container->details->right_margin)
1104 / pixels_per_unit,
1105 ((double) (allocation.height - 1)
1106 - container->details->top_margin
1107 - container->details->bottom_margin)
1108 / pixels_per_unit);
1109 return;
1110 }
1111
1112 reset_scroll_region = container->details->reset_scroll_region_trigger
1113 || baul_icon_container_is_empty (container)
1114 || baul_icon_container_is_auto_layout (container);
1115
1116 /* The trigger is only cleared when container is non-empty, so
1117 * callers can reliably reset the scroll region when an item
1118 * is added even if extraneous relayouts are called when the
1119 * window is still empty.
1120 */
1121 if (!baul_icon_container_is_empty (container))
1122 {
1123 container->details->reset_scroll_region_trigger = FALSE(0);
1124 }
1125
1126 get_all_icon_bounds (container, &x1, &y1, &x2, &y2, BOUNDS_USAGE_FOR_ENTIRE_ITEM);
1127
1128 /* Add border at the "end"of the layout (i.e. after the icons), to
1129 * ensure we get some space when scrolled to the end.
1130 * For horizontal layouts, we add a bottom border.
1131 * Vertical layout is used by the compact view so the end
1132 * depends on the RTL setting.
1133 */
1134 if (baul_icon_container_is_layout_vertical (container))
1135 {
1136 if (baul_icon_container_is_layout_rtl (container))
1137 {
1138 x1 -= ICON_PAD_LEFT4 + CONTAINER_PAD_LEFT4;
1139 }
1140 else
1141 {
1142 x2 += ICON_PAD_RIGHT4 + CONTAINER_PAD_RIGHT4;
1143 }
1144 }
1145 else
1146 {
1147 y2 += ICON_PAD_BOTTOM4 + CONTAINER_PAD_BOTTOM4;
1148 }
1149
1150 /* Auto-layout assumes a 0, 0 scroll origin and at least allocation->width.
1151 * Then we lay out to the right or to the left, so
1152 * x can be < 0 and > allocation */
1153 if (baul_icon_container_is_auto_layout (container))
1154 {
1155 ctk_widget_get_allocation (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
, &allocation);
1156 x1 = MIN (x1, 0)(((x1) < (0)) ? (x1) : (0));
1157 x2 = MAX (x2, allocation.width / pixels_per_unit)(((x2) > (allocation.width / pixels_per_unit)) ? (x2) : (allocation
.width / pixels_per_unit))
;
1158 y1 = 0;
1159 }
1160 else
1161 {
1162 /* Otherwise we add the padding that is at the start of the
1163 layout */
1164 if (baul_icon_container_is_layout_rtl (container))
1165 {
1166 x2 += ICON_PAD_RIGHT4 + CONTAINER_PAD_RIGHT4;
1167 }
1168 else
1169 {
1170 x1 -= ICON_PAD_LEFT4 + CONTAINER_PAD_LEFT4;
1171 }
1172 y1 -= ICON_PAD_TOP4 + CONTAINER_PAD_TOP4;
1173 }
1174
1175 x2 -= 1;
1176 x2 = MAX(x1, x2)(((x1) > (x2)) ? (x1) : (x2));
1177
1178 y2 -= 1;
1179 y2 = MAX(y1, y2)(((y1) > (y2)) ? (y1) : (y2));
1180
1181 if (reset_scroll_region)
1182 {
1183 eel_canvas_set_scroll_region
1184 (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
,
1185 x1, y1, x2, y2);
1186 }
1187 else
1188 {
1189 canvas_set_scroll_region_include_visible_area
1190 (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
,
1191 x1, y1, x2, y2);
1192 }
1193
1194 hadj = ctk_scrollable_get_hadjustment (CTK_SCROLLABLE (container)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_scrollable_get_type ()))))))
);
1195 vadj = ctk_scrollable_get_vadjustment (CTK_SCROLLABLE (container)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_scrollable_get_type ()))))))
);
1196
1197 /* Scroll by 1/4 icon each time you click. */
1198 step_increment = baul_get_icon_size_for_zoom_level
1199 (container->details->zoom_level) / 4;
1200 if (ctk_adjustment_get_step_increment (hadj) != step_increment)
1201 {
1202 ctk_adjustment_set_step_increment (hadj, step_increment);
1203 }
1204 if (ctk_adjustment_get_step_increment (vadj) != step_increment)
1205 {
1206 ctk_adjustment_set_step_increment (vadj, step_increment);
1207 }
1208}
1209
1210static int
1211compare_icons (gconstpointer a, gconstpointer b, gpointer icon_container)
1212{
1213 BaulIconContainerClass *klass;
1214 const BaulIcon *icon_a, *icon_b;
1215
1216 icon_a = a;
1217 icon_b = b;
1218 klass = BAUL_ICON_CONTAINER_GET_CLASS (icon_container)((((BaulIconContainerClass*) (((GTypeInstance*) ((icon_container
)))->g_class))))
;
1219
1220 return klass->compare_icons (icon_container, icon_a->data, icon_b->data);
1221}
1222
1223static void
1224sort_icons (BaulIconContainer *container,
1225 GList **icons)
1226{
1227 BaulIconContainerClass *klass;
1228
1229 klass = BAUL_ICON_CONTAINER_GET_CLASS (container)((((BaulIconContainerClass*) (((GTypeInstance*) ((container))
)->g_class))))
;
1230 g_assert (klass->compare_icons != NULL)do { if (klass->compare_icons != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-icon-container.c", 1230, ((const char*)
(__func__)), "klass->compare_icons != NULL"); } while (0)
;
1231
1232 *icons = g_list_sort_with_data (*icons, compare_icons, container);
1233}
1234
1235static void
1236resort (BaulIconContainer *container)
1237{
1238 sort_icons (container, &container->details->icons);
1239}
1240
1241typedef struct
1242{
1243 double width;
1244 double height;
1245 double x_offset;
1246 double y_offset;
1247} IconPositions;
1248
1249static void
1250lay_down_one_line (BaulIconContainer *container,
1251 GList *line_start,
1252 GList *line_end,
1253 double y,
1254 double max_height,
1255 GArray *positions,
1256 gboolean whole_text)
1257{
1258 GList *p;
1259 double x, y_offset;
1260 IconPositions *position;
1261 int i;
1262 gboolean is_rtl;
1263 BaulIcon *icon = NULL((void*)0);
1264
1265 is_rtl = baul_icon_container_is_layout_rtl (container);
1266
1267 /* Lay out the icons along the baseline. */
1268 x = ICON_PAD_LEFT4;
1269 i = 0;
1270 for (p = line_start; p != line_end; p = p->next)
1271 {
1272 icon = p->data;
1273
1274 position = &g_array_index (positions, IconPositions, i++)(((IconPositions*) (void *) (positions)->data) [(i++)]);
1275
1276 if (container->details->label_position == BAUL_ICON_LABEL_POSITION_BESIDE)
1277 {
1278 y_offset = (max_height - position->height) / 2;
1279 }
1280 else
1281 {
1282 y_offset = position->y_offset;
1283 }
1284
1285 icon_set_position
1286 (icon,
1287 is_rtl ? get_mirror_x_position (container, icon, x + position->x_offset) : x + position->x_offset,
1288 y + y_offset);
1289 baul_icon_canvas_item_set_entire_text (icon->item, whole_text);
1290
1291 icon->saved_ltr_x = is_rtl ? get_mirror_x_position (container, icon, icon->x) : icon->x;
1292
1293 x += position->width;
1294 }
1295}
1296
1297static void
1298lay_down_one_column (BaulIconContainer *container,
1299 GList *line_start,
1300 GList *line_end,
1301 double x,
1302 double y_start,
1303 double y_iter,
1304 GArray *positions)
1305{
1306 GList *p;
1307 double y;
1308 int i;
1309 gboolean is_rtl;
1310 IconPositions *position = NULL((void*)0);
1311 BaulIcon *icon = NULL((void*)0);
1312
1313 is_rtl = baul_icon_container_is_layout_rtl (container);
1314
1315 /* Lay out the icons along the baseline. */
1316 y = y_start;
1317 i = 0;
1318 for (p = line_start; p != line_end; p = p->next)
1319 {
1320 icon = p->data;
1321
1322 position = &g_array_index (positions, IconPositions, i++)(((IconPositions*) (void *) (positions)->data) [(i++)]);
1323
1324 icon_set_position
1325 (icon,
1326 is_rtl ? get_mirror_x_position (container, icon, x + position->x_offset) : x + position->x_offset,
1327 y + position->y_offset);
1328
1329 icon->saved_ltr_x = is_rtl ? get_mirror_x_position (container, icon, icon->x) : icon->x;
1330
1331 y += y_iter;
1332 }
1333}
1334
1335static void
1336lay_down_icons_horizontal (BaulIconContainer *container,
1337 GList *icons,
1338 double start_y)
1339{
1340 GList *p, *line_start;
1341 BaulIcon *icon;
1342 double canvas_width, y;
1343 EelDRect bounds;
1344 EelDRect icon_bounds;
1345 EelDRect text_bounds;
1346 double max_height_above, max_height_below;
1347 double line_width;
1348 gboolean gridded_layout;
1349 double grid_width;
1350 double max_text_width, max_icon_width;
1351 int icon_width;
1352 int i;
1353 CtkAllocation allocation;
1354 GArray *positions;
1355 IconPositions *position = NULL((void*)0);
1356
1357 g_assert (BAUL_IS_ICON_CONTAINER (container))do { if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 1357, ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); } while (0)
;
1358
1359 if (icons == NULL((void*)0))
1360 {
1361 return;
1362 }
1363
1364 positions = g_array_new (FALSE(0), FALSE(0), sizeof (IconPositions));
1365 ctk_widget_get_allocation (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
, &allocation);
1366
1367 /* Lay out icons a line at a time. */
1368 canvas_width = CANVAS_WIDTH(container, allocation)((allocation.width - container->details->left_margin - container
->details->right_margin) / ((((EelCanvas*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), ((eel_canvas_get_type ())))
)))->pixels_per_unit)
;
1369 max_icon_width = max_text_width = 0.0;
1370
1371 if (container->details->label_position == BAUL_ICON_LABEL_POSITION_BESIDE)
1372 {
1373 /* Would it be worth caching these bounds for the next loop? */
1374 for (p = icons; p != NULL((void*)0); p = p->next)
1375 {
1376 icon = p->data;
1377
1378 icon_bounds = baul_icon_canvas_item_get_icon_rectangle (icon->item);
1379 max_icon_width = MAX (max_icon_width, ceil (icon_bounds.x1 - icon_bounds.x0))(((max_icon_width) > (ceil (icon_bounds.x1 - icon_bounds.x0
))) ? (max_icon_width) : (ceil (icon_bounds.x1 - icon_bounds.
x0)))
;
1380
1381 text_bounds = baul_icon_canvas_item_get_text_rectangle (icon->item, TRUE(!(0)));
1382 max_text_width = MAX (max_text_width, ceil (text_bounds.x1 - text_bounds.x0))(((max_text_width) > (ceil (text_bounds.x1 - text_bounds.x0
))) ? (max_text_width) : (ceil (text_bounds.x1 - text_bounds.
x0)))
;
1383 }
1384
1385 grid_width = max_icon_width + max_text_width + ICON_PAD_LEFT4 + ICON_PAD_RIGHT4;
1386 }
1387 else
1388 {
1389 grid_width = STANDARD_ICON_GRID_WIDTH155;
1390 ctk_widget_queue_resize (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
);
1391 }
1392
1393 gridded_layout = !baul_icon_container_is_tighter_layout (container);
1394
1395 line_width = container->details->label_position == BAUL_ICON_LABEL_POSITION_BESIDE ? ICON_PAD_LEFT4 : 0;
1396 line_start = icons;
1397 y = start_y + CONTAINER_PAD_TOP4;
1398 i = 0;
1399
1400 max_height_above = 0;
1401 max_height_below = 0;
1402 for (p = icons; p != NULL((void*)0); p = p->next)
1403 {
1404 double height_above, height_below;
1405
1406 icon = p->data;
1407
1408 /* Assume it's only one level hierarchy to avoid costly affine calculations */
1409 baul_icon_canvas_item_get_bounds_for_layout (icon->item,
1410 &bounds.x0, &bounds.y0,
1411 &bounds.x1, &bounds.y1);
1412
1413 icon_bounds = baul_icon_canvas_item_get_icon_rectangle (icon->item);
1414 text_bounds = baul_icon_canvas_item_get_text_rectangle (icon->item, TRUE(!(0)));
1415
1416 if (gridded_layout)
1417 {
1418 icon_width = ceil ((bounds.x1 - bounds.x0)/grid_width) * grid_width;
1419
1420
1421 }
1422 else
1423 {
1424 icon_width = (bounds.x1 - bounds.x0) + ICON_PAD_RIGHT4 + 8; /* 8 pixels extra for fancy selection box */
1425 }
1426
1427 /* Calculate size above/below baseline */
1428 height_above = icon_bounds.y1 - bounds.y0;
1429 height_below = bounds.y1 - icon_bounds.y1;
1430
1431 /* If this icon doesn't fit, it's time to lay out the line that's queued up. */
1432 if (line_start != p && line_width + icon_width >= canvas_width )
1433 {
1434 if (container->details->label_position == BAUL_ICON_LABEL_POSITION_BESIDE)
1435 {
1436 y += ICON_PAD_TOP4;
1437 }
1438 else
1439 {
1440 /* Advance to the baseline. */
1441 y += ICON_PAD_TOP4 + max_height_above;
1442 }
1443
1444 lay_down_one_line (container, line_start, p, y, max_height_above, positions, FALSE(0));
1445
1446 if (container->details->label_position == BAUL_ICON_LABEL_POSITION_BESIDE)
1447 {
1448 y += max_height_above + max_height_below + ICON_PAD_BOTTOM4;
1449 }
1450 else
1451 {
1452 /* Advance to next line. */
1453 y += max_height_below + ICON_PAD_BOTTOM4;
1454 }
1455
1456 line_width = container->details->label_position == BAUL_ICON_LABEL_POSITION_BESIDE ? ICON_PAD_LEFT4 : 0;
1457 line_start = p;
1458 i = 0;
1459
1460 max_height_above = height_above;
1461 max_height_below = height_below;
1462 }
1463 else
1464 {
1465 if (height_above > max_height_above)
1466 {
1467 max_height_above = height_above;
1468 }
1469 if (height_below > max_height_below)
1470 {
1471 max_height_below = height_below;
1472 }
1473 }
1474
1475 g_array_set_size (positions, i + 1);
1476 position = &g_array_index (positions, IconPositions, i++)(((IconPositions*) (void *) (positions)->data) [(i++)]);
1477 position->width = icon_width;
1478 position->height = icon_bounds.y1 - icon_bounds.y0;
1479
1480 if (container->details->label_position == BAUL_ICON_LABEL_POSITION_BESIDE)
1481 {
1482 if (gridded_layout)
1483 {
1484 position->x_offset = max_icon_width + ICON_PAD_LEFT4 + ICON_PAD_RIGHT4 - (icon_bounds.x1 - icon_bounds.x0);
1485 }
1486 else
1487 {
1488 position->x_offset = icon_width - ((icon_bounds.x1 - icon_bounds.x0) + (text_bounds.x1 - text_bounds.x0));
1489 }
1490 position->y_offset = 0;
1491 }
1492 else
1493 {
1494 position->x_offset = (icon_width - (icon_bounds.x1 - icon_bounds.x0)) / 2;
1495 position->y_offset = icon_bounds.y0 - icon_bounds.y1;
1496 }
1497
1498 /* Add this icon. */
1499 line_width += icon_width;
1500 }
1501
1502 /* Lay down that last line of icons. */
1503 if (line_start != NULL((void*)0))
1504 {
1505 if (container->details->label_position == BAUL_ICON_LABEL_POSITION_BESIDE)
1506 {
1507 y += ICON_PAD_TOP4;
1508 }
1509 else
1510 {
1511 /* Advance to the baseline. */
1512 y += ICON_PAD_TOP4 + max_height_above;
1513 }
1514
1515 lay_down_one_line (container, line_start, NULL((void*)0), y, max_height_above, positions, TRUE(!(0)));
1516
1517 /* Advance to next line. */
1518 y += max_height_below + ICON_PAD_BOTTOM4;
Value stored to 'y' is never read
1519 }
1520
1521 g_array_free (positions, TRUE(!(0)));
1522}
1523
1524static void
1525get_max_icon_dimensions (GList *icon_start,
1526 GList *icon_end,
1527 double *max_icon_width,
1528 double *max_icon_height,
1529 double *max_text_width,
1530 double *max_text_height,
1531 double *max_bounds_height)
1532{
1533 EelDRect icon_bounds;
1534 EelDRect text_bounds;
1535 GList *p;
1536 double y1, y2;
1537 BaulIcon *icon = NULL((void*)0);
1538
1539 *max_icon_width = *max_text_width = 0.0;
1540 *max_icon_height = *max_text_height = 0.0;
1541 *max_bounds_height = 0.0;
1542
1543 /* Would it be worth caching these bounds for the next loop? */
1544 for (p = icon_start; p != icon_end; p = p->next)
1545 {
1546 icon = p->data;
1547
1548 icon_bounds = baul_icon_canvas_item_get_icon_rectangle (icon->item);
1549 *max_icon_width = MAX (*max_icon_width, ceil (icon_bounds.x1 - icon_bounds.x0))(((*max_icon_width) > (ceil (icon_bounds.x1 - icon_bounds.
x0))) ? (*max_icon_width) : (ceil (icon_bounds.x1 - icon_bounds
.x0)))
;
1550 *max_icon_height = MAX (*max_icon_height, ceil (icon_bounds.y1 - icon_bounds.y0))(((*max_icon_height) > (ceil (icon_bounds.y1 - icon_bounds
.y0))) ? (*max_icon_height) : (ceil (icon_bounds.y1 - icon_bounds
.y0)))
;
1551
1552 text_bounds = baul_icon_canvas_item_get_text_rectangle (icon->item, TRUE(!(0)));
1553 *max_text_width = MAX (*max_text_width, ceil (text_bounds.x1 - text_bounds.x0))(((*max_text_width) > (ceil (text_bounds.x1 - text_bounds.
x0))) ? (*max_text_width) : (ceil (text_bounds.x1 - text_bounds
.x0)))
;
1554 *max_text_height = MAX (*max_text_height, ceil (text_bounds.y1 - text_bounds.y0))(((*max_text_height) > (ceil (text_bounds.y1 - text_bounds
.y0))) ? (*max_text_height) : (ceil (text_bounds.y1 - text_bounds
.y0)))
;
1555
1556 baul_icon_canvas_item_get_bounds_for_layout (icon->item,
1557 NULL((void*)0), &y1,
1558 NULL((void*)0), &y2);
1559 *max_bounds_height = MAX (*max_bounds_height, y2 - y1)(((*max_bounds_height) > (y2 - y1)) ? (*max_bounds_height)
: (y2 - y1))
;
1560 }
1561}
1562
1563/* column-wise layout. At the moment, this only works with label-beside-icon (used by "Compact View"). */
1564static void
1565lay_down_icons_vertical (BaulIconContainer *container,
1566 GList *icons,
1567 double start_y G_GNUC_UNUSED__attribute__ ((__unused__)))
1568{
1569 GList *p, *line_start;
1570 double x, canvas_height;
1571 GArray *positions;
1572 IconPositions *position;
1573 EelDRect icon_bounds;
1574 EelDRect text_bounds;
1575 CtkAllocation allocation;
1576
1577 double line_height;
1578
1579 double max_height;
1580 double max_height_with_borders;
1581 double max_width;
1582 double max_width_in_column;
1583
1584 double max_bounds_height;
1585 double max_bounds_height_with_borders;
1586
1587 double max_text_width, max_icon_width;
1588 double max_text_height, max_icon_height;
1589 int i;
1590
1591 BaulIcon *icon = NULL((void*)0);
1592
1593 g_assert (BAUL_IS_ICON_CONTAINER (container))do { if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 1593, ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); } while (0)
;
1594 g_assert (container->details->label_position == BAUL_ICON_LABEL_POSITION_BESIDE)do { if (container->details->label_position == BAUL_ICON_LABEL_POSITION_BESIDE
) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 1594, ((const char*) (__func__)), "container->details->label_position == BAUL_ICON_LABEL_POSITION_BESIDE"
); } while (0)
;
1595
1596 if (icons == NULL((void*)0))
1597 {
1598 return;
1599 }
1600
1601 positions = g_array_new (FALSE(0), FALSE(0), sizeof (IconPositions));
1602 ctk_widget_get_allocation (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
, &allocation);
1603
1604 /* Lay out icons a column at a time. */
1605 canvas_height = CANVAS_HEIGHT(container, allocation)((allocation.height - container->details->top_margin - container
->details->bottom_margin) / ((((EelCanvas*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), ((eel_canvas_get_type ())))
)))->pixels_per_unit)
;
1606
1607 max_icon_width = max_text_width = 0.0;
1608 max_icon_height = max_text_height = 0.0;
1609 max_bounds_height = 0.0;
1610
1611 get_max_icon_dimensions (icons, NULL((void*)0),
1612 &max_icon_width, &max_icon_height,
1613 &max_text_width, &max_text_height,
1614 &max_bounds_height);
1615
1616 max_width = max_icon_width + max_text_width;
1617 max_height = MAX (max_icon_height, max_text_height)(((max_icon_height) > (max_text_height)) ? (max_icon_height
) : (max_text_height))
;
1618 max_height_with_borders = ICON_PAD_TOP4 + max_height;
1619
1620 max_bounds_height_with_borders = ICON_PAD_TOP4 + max_bounds_height;
1621
1622 line_height = ICON_PAD_TOP4;
1623 line_start = icons;
1624 x = 0;
1625 i = 0;
1626
1627 max_width_in_column = 0.0;
1628
1629 for (p = icons; p != NULL((void*)0); p = p->next)
1630 {
1631 int height;
1632
1633 icon = p->data;
1634
1635 /* If this icon doesn't fit, it's time to lay out the column that's queued up. */
1636
1637 /* We use the bounds height here, since for wrapping we also want to consider
1638 * overlapping emblems at the bottom. We may wrap a little bit too early since
1639 * the icon with the max. bounds height may actually not be in the last row, but
1640 * it is better than visual glitches
1641 */
1642 if (line_start != p && line_height + (max_bounds_height_with_borders-1) >= canvas_height )
1643 {
1644 x += ICON_PAD_LEFT4;
1645
1646 /* correctly set (per-column) width */
1647 if (!container->details->all_columns_same_width)
1648 {
1649 for (i = 0; i < (int) positions->len; i++)
1650 {
1651 position = &g_array_index (positions, IconPositions, i)(((IconPositions*) (void *) (positions)->data) [(i)]);
1652 position->width = max_width_in_column;
1653 }
1654 }
1655
1656 lay_down_one_column (container, line_start, p, x, CONTAINER_PAD_TOP4, max_height_with_borders, positions);
1657
1658 /* Advance to next column. */
1659 if (container->details->all_columns_same_width)
1660 {
1661 x += max_width + ICON_PAD_RIGHT4;
1662 }
1663 else
1664 {
1665 x += max_width_in_column + ICON_PAD_RIGHT4;
1666 }
1667
1668 line_height = ICON_PAD_TOP4;
1669 line_start = p;
1670 i = 0;
1671
1672 max_width_in_column = 0;
1673 }
1674
1675 icon_bounds = baul_icon_canvas_item_get_icon_rectangle (icon->item);
1676 text_bounds = baul_icon_canvas_item_get_text_rectangle (icon->item, TRUE(!(0)));
1677
1678 max_width_in_column = MAX (max_width_in_column,(((max_width_in_column) > (ceil (icon_bounds.x1 - icon_bounds
.x0) + ceil (text_bounds.x1 - text_bounds.x0))) ? (max_width_in_column
) : (ceil (icon_bounds.x1 - icon_bounds.x0) + ceil (text_bounds
.x1 - text_bounds.x0)))
1679 ceil (icon_bounds.x1 - icon_bounds.x0) +(((max_width_in_column) > (ceil (icon_bounds.x1 - icon_bounds
.x0) + ceil (text_bounds.x1 - text_bounds.x0))) ? (max_width_in_column
) : (ceil (icon_bounds.x1 - icon_bounds.x0) + ceil (text_bounds
.x1 - text_bounds.x0)))
1680 ceil (text_bounds.x1 - text_bounds.x0))(((max_width_in_column) > (ceil (icon_bounds.x1 - icon_bounds
.x0) + ceil (text_bounds.x1 - text_bounds.x0))) ? (max_width_in_column
) : (ceil (icon_bounds.x1 - icon_bounds.x0) + ceil (text_bounds
.x1 - text_bounds.x0)))
;
1681
1682 g_array_set_size (positions, i + 1);
1683 position = &g_array_index (positions, IconPositions, i++)(((IconPositions*) (void *) (positions)->data) [(i++)]);
1684 if (container->details->all_columns_same_width)
1685 {
1686 position->width = max_width;
1687 }
1688 position->height = max_height;
1689 position->y_offset = ICON_PAD_TOP4;
1690 position->x_offset = ICON_PAD_LEFT4;
1691
1692 position->x_offset += max_icon_width - ceil (icon_bounds.x1 - icon_bounds.x0);
1693
1694 height = MAX (ceil (icon_bounds.y1 - icon_bounds.y0), ceil(text_bounds.y1 - text_bounds.y0))(((ceil (icon_bounds.y1 - icon_bounds.y0)) > (ceil(text_bounds
.y1 - text_bounds.y0))) ? (ceil (icon_bounds.y1 - icon_bounds
.y0)) : (ceil(text_bounds.y1 - text_bounds.y0)))
;
1695 position->y_offset += (max_height - height) / 2;
1696
1697 /* Add this icon. */
1698 line_height += max_height_with_borders;
1699 }
1700
1701 /* Lay down that last column of icons. */
1702 if (line_start != NULL((void*)0))
1703 {
1704 x += ICON_PAD_LEFT4;
1705 lay_down_one_column (container, line_start, NULL((void*)0), x, CONTAINER_PAD_TOP4, max_height_with_borders, positions);
1706 }
1707
1708 g_array_free (positions, TRUE(!(0)));
1709}
1710
1711static void
1712snap_position (BaulIconContainer *container,
1713 BaulIcon *icon,
1714 int *x, int *y)
1715{
1716 int center_x;
1717 int baseline_y;
1718 int icon_width;
1719 int icon_height;
1720 int total_width;
1721 int total_height;
1722 EelDRect icon_position;
1723 CtkAllocation allocation;
1724
1725 icon_position = baul_icon_canvas_item_get_icon_rectangle (icon->item);
1726 icon_width = icon_position.x1 - icon_position.x0;
1727 icon_height = icon_position.y1 - icon_position.y0;
1728
1729 ctk_widget_get_allocation (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
, &allocation);
1730 total_width = CANVAS_WIDTH (container, allocation)((allocation.width - container->details->left_margin - container
->details->right_margin) / ((((EelCanvas*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), ((eel_canvas_get_type ())))
)))->pixels_per_unit)
;
1731 total_height = CANVAS_HEIGHT (container, allocation)((allocation.height - container->details->top_margin - container
->details->bottom_margin) / ((((EelCanvas*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), ((eel_canvas_get_type ())))
)))->pixels_per_unit)
;
1732
1733 if (baul_icon_container_is_layout_rtl (container))
1734 *x = get_mirror_x_position (container, icon, *x);
1735
1736 if (*x + icon_width / 2 < DESKTOP_PAD_HORIZONTAL10 + SNAP_SIZE_X78)
1737 {
1738 *x = DESKTOP_PAD_HORIZONTAL10 + SNAP_SIZE_X78 - icon_width / 2;
1739 }
1740
1741 if (*x + icon_width / 2 > total_width - (DESKTOP_PAD_HORIZONTAL10 + SNAP_SIZE_X78))
1742 {
1743 *x = total_width - (DESKTOP_PAD_HORIZONTAL10 + SNAP_SIZE_X78 + (icon_width / 2));
1744 }
1745
1746 if (*y + icon_height < DESKTOP_PAD_VERTICAL10 + SNAP_SIZE_Y20)
1747 {
1748 *y = DESKTOP_PAD_VERTICAL10 + SNAP_SIZE_Y20 - icon_height;
1749 }
1750
1751 if (*y + icon_height > total_height - (DESKTOP_PAD_VERTICAL10 + SNAP_SIZE_Y20))
1752 {
1753 *y = total_height - (DESKTOP_PAD_VERTICAL10 + SNAP_SIZE_Y20 + (icon_height / 2));
1754 }
1755
1756 center_x = *x + icon_width / 2;
1757 *x = SNAP_NEAREST_HORIZONTAL (center_x)((eel_round ((double)((center_x) - 10) / 78) * 78) + 10) - (icon_width / 2);
1758 if (baul_icon_container_is_layout_rtl (container))
1759 {
1760 *x = get_mirror_x_position (container, icon, *x);
1761 }
1762
1763
1764 /* Find the grid position vertically and place on the proper baseline */
1765 baseline_y = *y + icon_height;
1766 baseline_y = SNAP_NEAREST_VERTICAL (baseline_y)((eel_round ((double)((baseline_y) - 10) / 20) * 20) + 10);
1767 *y = baseline_y - icon_height;
1768}
1769
1770static int
1771compare_icons_by_position (gconstpointer a, gconstpointer b)
1772{
1773 BaulIcon *icon_a, *icon_b;
1774 int x1, y1, x2, y2;
1775 int center_a;
1776 int center_b;
1777
1778 icon_a = (BaulIcon*)a;
1779 icon_b = (BaulIcon*)b;
1780
1781 icon_get_bounding_box (icon_a, &x1, &y1, &x2, &y2,
1782 BOUNDS_USAGE_FOR_DISPLAY);
1783 center_a = x1 + (x2 - x1) / 2;
1784 icon_get_bounding_box (icon_b, &x1, &y1, &x2, &y2,
1785 BOUNDS_USAGE_FOR_DISPLAY);
1786 center_b = x1 + (x2 - x1) / 2;
1787
1788 return center_a == center_b ?
1789 icon_a->y - icon_b->y :
1790 center_a - center_b;
1791}
1792
1793static PlacementGrid *
1794placement_grid_new (BaulIconContainer *container, gboolean tight)
1795{
1796 PlacementGrid *grid;
1797 int width, height;
1798 int num_columns;
1799 int num_rows;
1800 int i;
1801 CtkAllocation allocation;
1802
1803 /* Get container dimensions */
1804 ctk_widget_get_allocation (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
, &allocation);
1805 width = CANVAS_WIDTH(container, allocation)((allocation.width - container->details->left_margin - container
->details->right_margin) / ((((EelCanvas*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), ((eel_canvas_get_type ())))
)))->pixels_per_unit)
;
1806 height = CANVAS_HEIGHT(container, allocation)((allocation.height - container->details->top_margin - container
->details->bottom_margin) / ((((EelCanvas*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), ((eel_canvas_get_type ())))
)))->pixels_per_unit)
;
1807
1808 num_columns = width / SNAP_SIZE_X78;
1809 num_rows = height / SNAP_SIZE_Y20;
1810
1811 if (num_columns == 0 || num_rows == 0)
1812 {
1813 return NULL((void*)0);
1814 }
1815
1816 grid = g_new0 (PlacementGrid, 1)((PlacementGrid *) g_malloc0_n ((1), sizeof (PlacementGrid)));
1817 grid->tight = tight;
1818 grid->num_columns = num_columns;
1819 grid->num_rows = num_rows;
1820
1821 grid->grid_memory = g_new0 (int, (num_rows * num_columns))((int *) g_malloc0_n (((num_rows * num_columns)), sizeof (int
)))
;
1822 grid->icon_grid = g_new0 (int *, num_columns)((int * *) g_malloc0_n ((num_columns), sizeof (int *)));
1823
1824 for (i = 0; i < num_columns; i++)
1825 {
1826 grid->icon_grid[i] = grid->grid_memory + (i * num_rows);
1827 }
1828
1829 return grid;
1830}
1831
1832static void
1833placement_grid_free (PlacementGrid *grid)
1834{
1835 g_free (grid->icon_grid);
1836 g_free (grid->grid_memory);
1837 g_free (grid);
1838}
1839
1840static gboolean
1841placement_grid_position_is_free (PlacementGrid *grid, EelIRect pos)
1842{
1843 int x, y;
1844
1845 g_assert (pos.x0 >= 0 && pos.x0 < grid->num_columns)do { if (pos.x0 >= 0 && pos.x0 < grid->num_columns
) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 1845, ((const char*) (__func__)), "pos.x0 >= 0 && pos.x0 < grid->num_columns"
); } while (0)
;
1846 g_assert (pos.y0 >= 0 && pos.y0 < grid->num_rows)do { if (pos.y0 >= 0 && pos.y0 < grid->num_rows
) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 1846, ((const char*) (__func__)), "pos.y0 >= 0 && pos.y0 < grid->num_rows"
); } while (0)
;
1847 g_assert (pos.x1 >= 0 && pos.x1 < grid->num_columns)do { if (pos.x1 >= 0 && pos.x1 < grid->num_columns
) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 1847, ((const char*) (__func__)), "pos.x1 >= 0 && pos.x1 < grid->num_columns"
); } while (0)
;
1848 g_assert (pos.y1 >= 0 && pos.y1 < grid->num_rows)do { if (pos.y1 >= 0 && pos.y1 < grid->num_rows
) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 1848, ((const char*) (__func__)), "pos.y1 >= 0 && pos.y1 < grid->num_rows"
); } while (0)
;
1849
1850 for (x = pos.x0; x <= pos.x1; x++)
1851 {
1852 for (y = pos.y0; y <= pos.y1; y++)
1853 {
1854 if (grid->icon_grid[x][y] != 0)
1855 {
1856 return FALSE(0);
1857 }
1858 }
1859 }
1860
1861 return TRUE(!(0));
1862}
1863
1864static void
1865placement_grid_mark (PlacementGrid *grid, EelIRect pos)
1866{
1867 int x, y;
1868
1869 g_assert (pos.x0 >= 0 && pos.x0 < grid->num_columns)do { if (pos.x0 >= 0 && pos.x0 < grid->num_columns
) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 1869, ((const char*) (__func__)), "pos.x0 >= 0 && pos.x0 < grid->num_columns"
); } while (0)
;
1870 g_assert (pos.y0 >= 0 && pos.y0 < grid->num_rows)do { if (pos.y0 >= 0 && pos.y0 < grid->num_rows
) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 1870, ((const char*) (__func__)), "pos.y0 >= 0 && pos.y0 < grid->num_rows"
); } while (0)
;
1871 g_assert (pos.x1 >= 0 && pos.x1 < grid->num_columns)do { if (pos.x1 >= 0 && pos.x1 < grid->num_columns
) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 1871, ((const char*) (__func__)), "pos.x1 >= 0 && pos.x1 < grid->num_columns"
); } while (0)
;
1872 g_assert (pos.y1 >= 0 && pos.y1 < grid->num_rows)do { if (pos.y1 >= 0 && pos.y1 < grid->num_rows
) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 1872, ((const char*) (__func__)), "pos.y1 >= 0 && pos.y1 < grid->num_rows"
); } while (0)
;
1873
1874 for (x = pos.x0; x <= pos.x1; x++)
1875 {
1876 for (y = pos.y0; y <= pos.y1; y++)
1877 {
1878 grid->icon_grid[x][y] = 1;
1879 }
1880 }
1881}
1882
1883static void
1884canvas_position_to_grid_position (PlacementGrid *grid,
1885 EelIRect canvas_position,
1886 EelIRect *grid_position)
1887{
1888 /* The first causes minimal moving around during a snap, but
1889 * can end up with partially overlapping icons. The second one won't
1890 * allow any overlapping, but can cause more movement to happen
1891 * during a snap. */
1892 if (grid->tight)
1893 {
1894 grid_position->x0 = ceil ((double)(canvas_position.x0 - DESKTOP_PAD_HORIZONTAL10) / SNAP_SIZE_X78);
1895 grid_position->y0 = ceil ((double)(canvas_position.y0 - DESKTOP_PAD_VERTICAL10) / SNAP_SIZE_Y20);
1896 grid_position->x1 = floor ((double)(canvas_position.x1 - DESKTOP_PAD_HORIZONTAL10) / SNAP_SIZE_X78);
1897 grid_position->y1 = floor ((double)(canvas_position.y1 - DESKTOP_PAD_VERTICAL10) / SNAP_SIZE_Y20);
1898 }
1899 else
1900 {
1901 grid_position->x0 = floor ((double)(canvas_position.x0 - DESKTOP_PAD_HORIZONTAL10) / SNAP_SIZE_X78);
1902 grid_position->y0 = floor ((double)(canvas_position.y0 - DESKTOP_PAD_VERTICAL10) / SNAP_SIZE_Y20);
1903 grid_position->x1 = floor ((double)(canvas_position.x1 - DESKTOP_PAD_HORIZONTAL10) / SNAP_SIZE_X78);
1904 grid_position->y1 = floor ((double)(canvas_position.y1 - DESKTOP_PAD_VERTICAL10) / SNAP_SIZE_Y20);
1905 }
1906
1907 grid_position->x0 = CLAMP (grid_position->x0, 0, grid->num_columns - 1)(((grid_position->x0) > (grid->num_columns - 1)) ? (
grid->num_columns - 1) : (((grid_position->x0) < (0)
) ? (0) : (grid_position->x0)))
;
1908 grid_position->y0 = CLAMP (grid_position->y0, 0, grid->num_rows - 1)(((grid_position->y0) > (grid->num_rows - 1)) ? (grid
->num_rows - 1) : (((grid_position->y0) < (0)) ? (0)
: (grid_position->y0)))
;
1909 grid_position->x1 = CLAMP (grid_position->x1, grid_position->x0, grid->num_columns - 1)(((grid_position->x1) > (grid->num_columns - 1)) ? (
grid->num_columns - 1) : (((grid_position->x1) < (grid_position
->x0)) ? (grid_position->x0) : (grid_position->x1)))
;
1910 grid_position->y1 = CLAMP (grid_position->y1, grid_position->y0, grid->num_rows - 1)(((grid_position->y1) > (grid->num_rows - 1)) ? (grid
->num_rows - 1) : (((grid_position->y1) < (grid_position
->y0)) ? (grid_position->y0) : (grid_position->y1)))
;
1911}
1912
1913static void
1914placement_grid_mark_icon (PlacementGrid *grid, BaulIcon *icon)
1915{
1916 EelIRect icon_pos;
1917 EelIRect grid_pos;
1918
1919 icon_get_bounding_box (icon,
1920 &icon_pos.x0, &icon_pos.y0,
1921 &icon_pos.x1, &icon_pos.y1,
1922 BOUNDS_USAGE_FOR_LAYOUT);
1923 canvas_position_to_grid_position (grid,
1924 icon_pos,
1925 &grid_pos);
1926 placement_grid_mark (grid, grid_pos);
1927}
1928
1929static void
1930find_empty_location (BaulIconContainer *container,
1931 PlacementGrid *grid,
1932 BaulIcon *icon,
1933 int start_x,
1934 int start_y,
1935 int *x,
1936 int *y)
1937{
1938 double icon_width, icon_height;
1939 int canvas_width;
1940 int canvas_height;
1941 int height_for_bound_check;
1942 EelIRect icon_position;
1943 EelDRect pixbuf_rect;
1944 gboolean collision;
1945 CtkAllocation allocation;
1946
1947 /* Get container dimensions */
1948 ctk_widget_get_allocation (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
, &allocation);
1949 canvas_width = CANVAS_WIDTH(container, allocation)((allocation.width - container->details->left_margin - container
->details->right_margin) / ((((EelCanvas*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), ((eel_canvas_get_type ())))
)))->pixels_per_unit)
;
1950 canvas_height = CANVAS_HEIGHT(container, allocation)((allocation.height - container->details->top_margin - container
->details->bottom_margin) / ((((EelCanvas*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), ((eel_canvas_get_type ())))
)))->pixels_per_unit)
;
1951
1952 icon_get_bounding_box (icon,
1953 &icon_position.x0, &icon_position.y0,
1954 &icon_position.x1, &icon_position.y1,
1955 BOUNDS_USAGE_FOR_LAYOUT);
1956 icon_width = icon_position.x1 - icon_position.x0;
1957 icon_height = icon_position.y1 - icon_position.y0;
1958
1959 icon_get_bounding_box (icon,
1960 NULL((void*)0), &icon_position.y0,
1961 NULL((void*)0), &icon_position.y1,
1962 BOUNDS_USAGE_FOR_ENTIRE_ITEM);
1963 height_for_bound_check = icon_position.y1 - icon_position.y0;
1964
1965 pixbuf_rect = baul_icon_canvas_item_get_icon_rectangle (icon->item);
1966
1967 /* Start the icon on a grid location */
1968 snap_position (container, icon, &start_x, &start_y);
1969
1970 icon_position.x0 = start_x;
1971 icon_position.y0 = start_y;
1972 icon_position.x1 = icon_position.x0 + icon_width;
1973 icon_position.y1 = icon_position.y0 + icon_height;
1974
1975 do
1976 {
1977 EelIRect grid_position;
1978 gboolean need_new_column;
1979
1980 collision = FALSE(0);
1981
1982 canvas_position_to_grid_position (grid,
1983 icon_position,
1984 &grid_position);
1985
1986 need_new_column = icon_position.y0 + height_for_bound_check + DESKTOP_PAD_VERTICAL10 > canvas_height;
1987
1988 if (need_new_column ||
1989 !placement_grid_position_is_free (grid, grid_position))
1990 {
1991 icon_position.y0 += SNAP_SIZE_Y20;
1992 icon_position.y1 = icon_position.y0 + icon_height;
1993
1994 if (need_new_column)
1995 {
1996 /* Move to the next column */
1997 icon_position.y0 = DESKTOP_PAD_VERTICAL10 + SNAP_SIZE_Y20 - (pixbuf_rect.y1 - pixbuf_rect.y0);
1998 while (icon_position.y0 < DESKTOP_PAD_VERTICAL10)
1999 {
2000 icon_position.y0 += SNAP_SIZE_Y20;
2001 }
2002 icon_position.y1 = icon_position.y0 + icon_height;
2003
2004 icon_position.x0 += SNAP_SIZE_X78;
2005 icon_position.x1 = icon_position.x0 + icon_width;
2006 }
2007
2008 collision = TRUE(!(0));
2009 }
2010 }
2011 while (collision && (icon_position.x1 < canvas_width));
2012
2013 *x = icon_position.x0;
2014 *y = icon_position.y0;
2015}
2016
2017static void
2018align_icons (BaulIconContainer *container)
2019{
2020 GList *unplaced_icons;
2021 GList *l;
2022 PlacementGrid *grid;
2023
2024 unplaced_icons = g_list_copy (container->details->icons);
2025
2026 unplaced_icons = g_list_sort (unplaced_icons,
2027 compare_icons_by_position);
2028
2029 if (baul_icon_container_is_layout_rtl (container))
2030 {
2031 unplaced_icons = g_list_reverse (unplaced_icons);
2032 }
2033
2034 grid = placement_grid_new (container, TRUE(!(0)));
2035
2036 if (!grid)
2037 {
2038 g_list_free (unplaced_icons);
2039 return;
2040 }
2041
2042 for (l = unplaced_icons; l != NULL((void*)0); l = l->next)
2043 {
2044 BaulIcon *icon;
2045 int x, y;
2046
2047 icon = l->data;
2048 x = icon->saved_ltr_x;
2049 y = icon->y;
2050 find_empty_location (container, grid,
2051 icon, x, y, &x, &y);
2052
2053 icon_set_position (icon, x, y);
2054 icon->saved_ltr_x = icon->x;
2055 placement_grid_mark_icon (grid, icon);
2056 }
2057
2058 g_list_free (unplaced_icons);
2059
2060 placement_grid_free (grid);
2061
2062 if (baul_icon_container_is_layout_rtl (container))
2063 {
2064 baul_icon_container_set_rtl_positions (container);
2065 }
2066}
2067
2068static double
2069get_mirror_x_position (BaulIconContainer *container, BaulIcon *icon, double x)
2070{
2071 EelDRect icon_bounds;
2072 CtkAllocation allocation;
2073
2074 ctk_widget_get_allocation (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
, &allocation);
2075 icon_bounds = baul_icon_canvas_item_get_icon_rectangle (icon->item);
2076
2077 return CANVAS_WIDTH(container, allocation)((allocation.width - container->details->left_margin - container
->details->right_margin) / ((((EelCanvas*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), ((eel_canvas_get_type ())))
)))->pixels_per_unit)
- x - (icon_bounds.x1 - icon_bounds.x0);
2078}
2079
2080static void
2081baul_icon_container_set_rtl_positions (BaulIconContainer *container)
2082{
2083 GList *l;
2084 BaulIcon *icon = NULL((void*)0);
2085
2086 if (!container->details->icons)
2087 {
2088 return;
2089 }
2090
2091 for (l = container->details->icons; l != NULL((void*)0); l = l->next)
2092 {
2093 double x;
2094
2095 icon = l->data;
2096 x = get_mirror_x_position (container, icon, icon->saved_ltr_x);
2097 icon_set_position (icon, x, icon->y);
2098 }
2099}
2100
2101static void
2102lay_down_icons_vertical_desktop (BaulIconContainer *container, GList *icons)
2103{
2104 GList *p, *placed_icons, *unplaced_icons;
2105 int total, new_length, placed;
2106 BaulIcon *icon;
2107 int height;
2108 int x, y, x1, x2, y1, y2;
2109 EelDRect icon_rect;
2110 CtkAllocation allocation;
2111
2112 /* Get container dimensions */
2113 ctk_widget_get_allocation (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
, &allocation);
2114 height = CANVAS_HEIGHT(container, allocation)((allocation.height - container->details->top_margin - container
->details->bottom_margin) / ((((EelCanvas*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), ((eel_canvas_get_type ())))
)))->pixels_per_unit)
;
2115
2116 /* Determine which icons have and have not been placed */
2117 placed_icons = NULL((void*)0);
2118 unplaced_icons = NULL((void*)0);
2119
2120 total = g_list_length (container->details->icons);
2121 new_length = g_list_length (icons);
2122 placed = total - new_length;
2123 if (placed > 0)
2124 {
2125 PlacementGrid *grid;
2126 /* Add only placed icons in list */
2127 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
2128 {
2129 icon = p->data;
2130 if (icon_is_positioned (icon))
2131 {
2132 icon_set_position(icon, icon->saved_ltr_x, icon->y);
2133 placed_icons = g_list_prepend (placed_icons, icon);
2134 }
2135 else
2136 {
2137 icon->x = 0;
2138 icon->y = 0;
2139 unplaced_icons = g_list_prepend (unplaced_icons, icon);
2140 }
2141 }
2142 placed_icons = g_list_reverse (placed_icons);
2143 unplaced_icons = g_list_reverse (unplaced_icons);
2144
2145 grid = placement_grid_new (container, FALSE(0));
2146
2147 if (grid)
2148 {
2149 for (p = placed_icons; p != NULL((void*)0); p = p->next)
2150 {
2151 placement_grid_mark_icon
2152 (grid, (BaulIcon*)p->data);
2153 }
2154
2155 /* Place unplaced icons in the best locations */
2156 for (p = unplaced_icons; p != NULL((void*)0); p = p->next)
2157 {
2158 icon = p->data;
2159
2160 icon_rect = baul_icon_canvas_item_get_icon_rectangle (icon->item);
2161
2162 /* Start the icon in the first column */
2163 x = DESKTOP_PAD_HORIZONTAL10 + (SNAP_SIZE_X78 / 2) - ((icon_rect.x1 - icon_rect.x0) / 2);
2164 y = DESKTOP_PAD_VERTICAL10 + SNAP_SIZE_Y20 - (icon_rect.y1 - icon_rect.y0);
2165
2166 find_empty_location (container,
2167 grid,
2168 icon,
2169 x, y,
2170 &x, &y);
2171
2172 icon_set_position (icon, x, y);
2173 icon->saved_ltr_x = x;
2174 placement_grid_mark_icon (grid, icon);
2175 }
2176
2177 placement_grid_free (grid);
2178 }
2179
2180 g_list_free (placed_icons);
2181 g_list_free (unplaced_icons);
2182 }
2183 else
2184 {
2185 /* There are no placed icons. Just lay them down using our rules */
2186 x = DESKTOP_PAD_HORIZONTAL10;
2187
2188 while (icons != NULL((void*)0))
2189 {
2190 int max_width, column_width, icon_height;
2191 int center_x;
2192 int baseline;
2193 int icon_height_for_bound_check;
2194 gboolean should_snap;
2195
2196 should_snap = !(container->details->tighter_layout && !container->details->keep_aligned);
2197
2198 y = DESKTOP_PAD_VERTICAL10;
2199
2200 max_width = 0;
2201
2202 /* Calculate max width for column */
2203 for (p = icons; p != NULL((void*)0); p = p->next)
2204 {
2205 int icon_width;
2206
2207 icon = p->data;
2208
2209 icon_get_bounding_box (icon, &x1, &y1, &x2, &y2,
2210 BOUNDS_USAGE_FOR_LAYOUT);
2211 icon_width = x2 - x1;
2212 icon_height = y2 - y1;
2213
2214 icon_get_bounding_box (icon, NULL((void*)0), &y1, NULL((void*)0), &y2,
2215 BOUNDS_USAGE_FOR_ENTIRE_ITEM);
2216 icon_height_for_bound_check = y2 - y1;
2217
2218 if (should_snap)
2219 {
2220 /* Snap the baseline to a grid position */
2221 icon_rect = baul_icon_canvas_item_get_icon_rectangle (icon->item);
2222 baseline = y + (icon_rect.y1 - icon_rect.y0);
2223 baseline = SNAP_CEIL_VERTICAL (baseline)((ceil ((double)((baseline) - 10) / 20) * 20) + 10);
2224 y = baseline - (icon_rect.y1 - icon_rect.y0);
2225 }
2226
2227 /* Check and see if we need to move to a new column */
2228 if (y != DESKTOP_PAD_VERTICAL10 && y + icon_height_for_bound_check > height)
2229 {
2230 break;
2231 }
2232
2233 if (max_width < icon_width)
2234 {
2235 max_width = icon_width;
2236 }
2237
2238 y += icon_height + DESKTOP_PAD_VERTICAL10;
2239 }
2240
2241 y = DESKTOP_PAD_VERTICAL10;
2242
2243 center_x = x + max_width / 2;
2244 column_width = max_width;
2245 if (should_snap)
2246 {
2247 /* Find the grid column to center on */
2248 center_x = SNAP_CEIL_HORIZONTAL (center_x)((ceil ((double)((center_x) - 10) / 78) * 78) + 10);
2249 column_width = (center_x - x) + (max_width / 2);
2250 }
2251
2252 /* Lay out column */
2253 for (p = icons; p != NULL((void*)0); p = p->next)
2254 {
2255 icon = p->data;
2256 icon_get_bounding_box (icon, &x1, &y1, &x2, &y2,
2257 BOUNDS_USAGE_FOR_LAYOUT);
2258 icon_height = y2 - y1;
2259
2260 icon_get_bounding_box (icon, NULL((void*)0), &y1, NULL((void*)0), &y2,
2261 BOUNDS_USAGE_FOR_ENTIRE_ITEM);
2262 icon_height_for_bound_check = y2 - y1;
2263
2264 icon_rect = baul_icon_canvas_item_get_icon_rectangle (icon->item);
2265
2266 if (should_snap)
2267 {
2268 baseline = y + (icon_rect.y1 - icon_rect.y0);
2269 baseline = SNAP_CEIL_VERTICAL (baseline)((ceil ((double)((baseline) - 10) / 20) * 20) + 10);
2270 y = baseline - (icon_rect.y1 - icon_rect.y0);
2271 }
2272
2273 /* Check and see if we need to move to a new column */
2274 if (y != DESKTOP_PAD_VERTICAL10 && y > height - icon_height_for_bound_check &&
2275 /* Make sure we lay out at least one icon per column, to make progress */
2276 p != icons)
2277 {
2278 x += column_width + DESKTOP_PAD_HORIZONTAL10;
2279 break;
2280 }
2281
2282 icon_set_position (icon,
2283 center_x - (icon_rect.x1 - icon_rect.x0) / 2,
2284 y);
2285
2286 icon->saved_ltr_x = icon->x;
2287 y += icon_height + DESKTOP_PAD_VERTICAL10;
2288 }
2289 icons = p;
2290 }
2291 }
2292
2293 /* These modes are special. We freeze all of our positions
2294 * after we do the layout.
2295 */
2296 /* FIXME bugzilla.gnome.org 42478:
2297 * This should not be tied to the direction of layout.
2298 * It should be a separate switch.
2299 */
2300 baul_icon_container_freeze_icon_positions (container);
2301}
2302
2303
2304static void
2305lay_down_icons (BaulIconContainer *container, GList *icons, double start_y)
2306{
2307 switch (container->details->layout_mode)
2308 {
2309 case BAUL_ICON_LAYOUT_L_R_T_B:
2310 case BAUL_ICON_LAYOUT_R_L_T_B:
2311 lay_down_icons_horizontal (container, icons, start_y);
2312 break;
2313
2314 case BAUL_ICON_LAYOUT_T_B_L_R:
2315 case BAUL_ICON_LAYOUT_T_B_R_L:
2316 if (baul_icon_container_get_is_desktop (container))
2317 {
2318 lay_down_icons_vertical_desktop (container, icons);
2319 }
2320 else
2321 {
2322 lay_down_icons_vertical (container, icons, start_y);
2323 }
2324 break;
2325
2326 default:
2327 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 2327, ((const char*) (__func__)), ((void*)0)); } while (0)
;
2328 }
2329}
2330
2331static void
2332redo_layout_internal (BaulIconContainer *container)
2333{
2334 finish_adding_new_icons (container);
2335
2336 /* Don't do any re-laying-out during stretching. Later we
2337 * might add smart logic that does this and leaves room for
2338 * the stretched icon, but if we do it we want it to be fast
2339 * and only re-lay-out when it's really needed.
2340 */
2341 if (container->details->auto_layout
2342 && container->details->drag_state != DRAG_STATE_STRETCH)
2343 {
2344 resort (container);
2345 lay_down_icons (container, container->details->icons, 0);
2346 }
2347
2348 if (baul_icon_container_is_layout_rtl (container))
2349 {
2350 baul_icon_container_set_rtl_positions (container);
2351 }
2352
2353 baul_icon_container_update_scroll_region (container);
2354
2355 process_pending_icon_to_reveal (container);
2356 process_pending_icon_to_rename (container);
2357 baul_icon_container_update_visible_icons (container);
2358}
2359
2360static gboolean
2361redo_layout_callback (gpointer callback_data)
2362{
2363 BaulIconContainer *container;
2364
2365 container = BAUL_ICON_CONTAINER (callback_data)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((callback_data)), (baul_icon_container_get_type
())))))
;
2366 redo_layout_internal (container);
2367 container->details->idle_id = 0;
2368
2369 return FALSE(0);
2370}
2371
2372static void
2373unschedule_redo_layout (BaulIconContainer *container)
2374{
2375 if (container->details->idle_id != 0)
2376 {
2377 g_source_remove (container->details->idle_id);
2378 container->details->idle_id = 0;
2379 }
2380}
2381
2382static void
2383schedule_redo_layout (BaulIconContainer *container)
2384{
2385 if (container->details->idle_id == 0
2386 && container->details->has_been_allocated)
2387 {
2388 container->details->idle_id = g_idle_add
2389 (redo_layout_callback, container);
2390 }
2391}
2392
2393static void
2394redo_layout (BaulIconContainer *container)
2395{
2396 unschedule_redo_layout (container);
2397 redo_layout_internal (container);
2398}
2399
2400static void
2401reload_icon_positions (BaulIconContainer *container)
2402{
2403 GList *p, *no_position_icons;
2404 gboolean have_stored_position;
2405 BaulIconPosition position;
2406 EelDRect bounds;
2407 double bottom;
2408 EelCanvasItem *item;
2409 BaulIcon *icon = NULL((void*)0);
2410
2411 g_assert (!container->details->auto_layout)do { if (!container->details->auto_layout) ; else g_assertion_message_expr
(((gchar*) 0), "baul-icon-container.c", 2411, ((const char*)
(__func__)), "!container->details->auto_layout"); } while
(0)
;
2412
2413 resort (container);
2414
2415 no_position_icons = NULL((void*)0);
2416
2417 /* Place all the icons with positions. */
2418 bottom = 0;
2419 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
2420 {
2421 icon = p->data;
2422
2423 have_stored_position = FALSE(0);
2424 g_signal_emit (container,
2425 signals[GET_STORED_ICON_POSITION], 0,
2426 icon->data,
2427 &position,
2428 &have_stored_position);
2429 if (have_stored_position)
2430 {
2431 icon_set_position (icon, position.x, position.y);
2432 item = EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
;
2433 baul_icon_canvas_item_get_bounds_for_layout (icon->item,
2434 &bounds.x0,
2435 &bounds.y0,
2436 &bounds.x1,
2437 &bounds.y1);
2438 eel_canvas_item_i2w (item->parent,
2439 &bounds.x0,
2440 &bounds.y0);
2441 eel_canvas_item_i2w (item->parent,
2442 &bounds.x1,
2443 &bounds.y1);
2444 if (bounds.y1 > bottom)
2445 {
2446 bottom = bounds.y1;
2447 }
2448 }
2449 else
2450 {
2451 no_position_icons = g_list_prepend (no_position_icons, icon);
2452 }
2453 }
2454 no_position_icons = g_list_reverse (no_position_icons);
2455
2456 /* Place all the other icons. */
2457 lay_down_icons (container, no_position_icons, bottom + ICON_PAD_BOTTOM4);
2458 g_list_free (no_position_icons);
2459}
2460
2461/* Container-level icon handling functions. */
2462
2463static gboolean
2464button_event_modifies_selection (CdkEventButton *event)
2465{
2466 return (event->state & (CDK_CONTROL_MASK | CDK_SHIFT_MASK)) != 0;
2467}
2468
2469/* invalidate the cached label sizes for all the icons */
2470static void
2471invalidate_label_sizes (BaulIconContainer *container)
2472{
2473 GList *p;
2474 BaulIcon *icon = NULL((void*)0);
2475
2476 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
2477 {
2478 icon = p->data;
2479
2480 baul_icon_canvas_item_invalidate_label_size (icon->item);
2481 }
2482}
2483
2484/* invalidate the entire labels (i.e. their attributes) for all the icons */
2485static void
2486invalidate_labels (BaulIconContainer *container)
2487{
2488 GList *p;
2489 BaulIcon *icon = NULL((void*)0);
2490
2491 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
2492 {
2493 icon = p->data;
2494
2495 baul_icon_canvas_item_invalidate_label (icon->item);
2496 }
2497}
2498
2499static gboolean
2500select_range (BaulIconContainer *container,
2501 BaulIcon *icon1,
2502 BaulIcon *icon2,
2503 gboolean unselect_outside_range)
2504{
2505 gboolean selection_changed;
2506 GList *p;
2507 BaulIcon *icon = NULL((void*)0);
2508 BaulIcon *unmatched_icon;
2509 gboolean select;
2510
2511 selection_changed = FALSE(0);
2512
2513 unmatched_icon = NULL((void*)0);
2514 select = FALSE(0);
2515 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
2516 {
2517 icon = p->data;
2518
2519 if (unmatched_icon == NULL((void*)0))
2520 {
2521 if (icon == icon1)
2522 {
2523 unmatched_icon = icon2;
2524 select = TRUE(!(0));
2525 }
2526 else if (icon == icon2)
2527 {
2528 unmatched_icon = icon1;
2529 select = TRUE(!(0));
2530 }
2531 }
2532
2533 if (select || unselect_outside_range)
2534 {
2535 selection_changed |= icon_set_selected
2536 (container, icon, select);
2537 }
2538
2539 if (unmatched_icon != NULL((void*)0) && icon == unmatched_icon)
2540 {
2541 select = FALSE(0);
2542 }
2543
2544 }
2545
2546 if (selection_changed && icon2 != NULL((void*)0))
2547 {
2548 emit_atk_focus_state_change (icon2, TRUE(!(0)));
2549 }
2550 return selection_changed;
2551}
2552
2553
2554static gboolean
2555select_one_unselect_others (BaulIconContainer *container,
2556 BaulIcon *icon_to_select)
2557{
2558 gboolean selection_changed;
2559 GList *p;
2560 BaulIcon *icon = NULL((void*)0);
2561
2562 selection_changed = FALSE(0);
2563
2564 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
2565 {
2566 icon = p->data;
2567
2568 selection_changed |= icon_set_selected
2569 (container, icon, icon == icon_to_select);
2570 }
2571
2572 if (selection_changed && icon_to_select != NULL((void*)0))
2573 {
2574 emit_atk_focus_state_change (icon_to_select, TRUE(!(0)));
2575 reveal_icon (container, icon_to_select);
2576 }
2577 return selection_changed;
2578}
2579
2580static gboolean
2581unselect_all (BaulIconContainer *container)
2582{
2583 return select_one_unselect_others (container, NULL((void*)0));
2584}
2585
2586void
2587baul_icon_container_move_icon (BaulIconContainer *container,
2588 BaulIcon *icon,
2589 int x, int y,
2590 double scale,
2591 gboolean raise,
2592 gboolean snap,
2593 gboolean update_position)
2594{
2595 BaulIconContainerDetails *details;
2596 gboolean emit_signal;
2597 BaulIconPosition position;
2598
2599 details = container->details;
2600
2601 emit_signal = FALSE(0);
2602
2603 if (icon == get_icon_being_renamed (container))
2604 {
2605 end_renaming_mode (container, TRUE(!(0)));
2606 }
2607
2608 if (scale != icon->scale)
2609 {
2610 icon->scale = scale;
2611 baul_icon_container_update_icon (container, icon);
2612 if (update_position)
2613 {
2614 redo_layout (container);
2615 emit_signal = TRUE(!(0));
2616 }
2617 }
2618
2619 if (!details->auto_layout)
2620 {
2621 if (details->keep_aligned && snap)
2622 {
2623 snap_position (container, icon, &x, &y);
2624 }
2625
2626 if (x != icon->x || y != icon->y)
2627 {
2628 icon_set_position (icon, x, y);
2629 emit_signal = update_position;
2630 }
2631
2632 icon->saved_ltr_x = baul_icon_container_is_layout_rtl (container) ? get_mirror_x_position (container, icon, icon->x) : icon->x;
2633 }
2634
2635 if (emit_signal)
2636 {
2637 position.x = icon->saved_ltr_x;
2638 position.y = icon->y;
2639 position.scale = scale;
2640 g_signal_emit (container,
2641 signals[ICON_POSITION_CHANGED], 0,
2642 icon->data, &position);
2643 }
2644
2645 if (raise)
2646 {
2647 icon_raise (icon);
2648 }
2649
2650 /* FIXME bugzilla.gnome.org 42474:
2651 * Handling of the scroll region is inconsistent here. In
2652 * the scale-changing case, redo_layout is called, which updates the
2653 * scroll region appropriately. In other cases, it's up to the
2654 * caller to make sure the scroll region is updated. This could
2655 * lead to hard-to-track-down bugs.
2656 */
2657}
2658
2659/* Implementation of rubberband selection. */
2660static void
2661rubberband_select (BaulIconContainer *container,
2662 const EelDRect *previous_rect G_GNUC_UNUSED__attribute__ ((__unused__)),
2663 const EelDRect *current_rect)
2664{
2665 GList *p;
2666 gboolean selection_changed, is_in, canvas_rect_calculated;
2667 EelIRect canvas_rect;
2668 EelCanvas *canvas;
2669 BaulIcon *icon = NULL((void*)0);
2670
2671 selection_changed = FALSE(0);
2672 canvas_rect_calculated = FALSE(0);
2673
2674 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
2675 {
2676 icon = p->data;
2677
2678 if (!canvas_rect_calculated)
2679 {
2680 /* Only do this calculation once, since all the canvas items
2681 * we are interating are in the same coordinate space
2682 */
2683 canvas = EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
->canvas;
2684 eel_canvas_w2c (canvas,
2685 current_rect->x0,
2686 current_rect->y0,
2687 &canvas_rect.x0,
2688 &canvas_rect.y0);
2689 eel_canvas_w2c (canvas,
2690 current_rect->x1,
2691 current_rect->y1,
2692 &canvas_rect.x1,
2693 &canvas_rect.y1);
2694 canvas_rect_calculated = TRUE(!(0));
2695 }
2696
2697 is_in = baul_icon_canvas_item_hit_test_rectangle (icon->item, canvas_rect);
2698
2699 selection_changed |= icon_set_selected
2700 (container, icon,
2701 is_in ^ icon->was_selected_before_rubberband);
2702 }
2703
2704 if (selection_changed)
2705 {
2706 g_signal_emit (container,
2707 signals[SELECTION_CHANGED], 0);
2708 }
2709}
2710
2711static int
2712rubberband_timeout_callback (gpointer data)
2713{
2714 BaulIconContainer *container;
2715 CtkWidget *widget;
2716 BaulIconRubberbandInfo *band_info;
2717 int x, y;
2718 double x1, y1, x2, y2;
2719 double world_x, world_y;
2720 int x_scroll, y_scroll;
2721 int adj_x, adj_y;
2722 CdkDisplay *display;
2723 CdkSeat *seat;
2724 gboolean adj_changed;
2725 CtkAllocation allocation;
2726
2727 EelDRect selection_rect;
2728
2729 widget = CTK_WIDGET (data)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data)), ((ctk_widget_get_type ()))))))
;
2730 container = BAUL_ICON_CONTAINER (data)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((data)), (baul_icon_container_get_type())))
))
;
2731 band_info = &container->details->rubberband_info;
2732
2733 g_assert (band_info->timer_id != 0)do { if (band_info->timer_id != 0) ; else g_assertion_message_expr
(((gchar*) 0), "baul-icon-container.c", 2733, ((const char*)
(__func__)), "band_info->timer_id != 0"); } while (0)
;
2734 g_assert (EEL_IS_CANVAS_RECT (band_info->selection_rectangle) ||do { if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((band_info->selection_rectangle)); GType __t = ((eel_canvas_rect_get_type
())); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))) || (((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((band_info->selection_rectangle)); GType __t = ((eel_canvas_rect_get_type
())); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 2735, ((const char*) (__func__)), "EEL_IS_CANVAS_RECT (band_info->selection_rectangle) || EEL_IS_CANVAS_RECT (band_info->selection_rectangle)"
); } while (0)
2735 EEL_IS_CANVAS_RECT (band_info->selection_rectangle))do { if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((band_info->selection_rectangle)); GType __t = ((eel_canvas_rect_get_type
())); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))) || (((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((band_info->selection_rectangle)); GType __t = ((eel_canvas_rect_get_type
())); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 2735, ((const char*) (__func__)), "EEL_IS_CANVAS_RECT (band_info->selection_rectangle) || EEL_IS_CANVAS_RECT (band_info->selection_rectangle)"
); } while (0)
;
2736
2737 adj_changed = FALSE(0);
2738 ctk_widget_get_allocation (widget, &allocation);
2739
2740 adj_x = ctk_adjustment_get_value (ctk_scrollable_get_hadjustment (CTK_SCROLLABLE (container)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_scrollable_get_type ()))))))
));
2741 if (adj_x != band_info->last_adj_x)
2742 {
2743 band_info->last_adj_x = adj_x;
2744 adj_changed = TRUE(!(0));
2745 }
2746
2747 adj_y = ctk_adjustment_get_value (ctk_scrollable_get_vadjustment (CTK_SCROLLABLE (container)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_scrollable_get_type ()))))))
));
2748 if (adj_y != band_info->last_adj_y)
2749 {
2750 band_info->last_adj_y = adj_y;
2751 adj_changed = TRUE(!(0));
2752 }
2753 display = ctk_widget_get_display (widget);
2754 seat = cdk_display_get_default_seat (display);
2755
2756 cdk_window_get_device_position (ctk_widget_get_window (widget),
2757 cdk_seat_get_pointer (seat),
2758 &x, &y, NULL((void*)0));
2759
2760 if (x < 0)
2761 {
2762 x_scroll = x;
2763 x = 0;
2764 }
2765 else if (x >= allocation.width)
2766 {
2767 x_scroll = x - allocation.width + 1;
2768 x = allocation.width - 1;
2769 }
2770 else
2771 {
2772 x_scroll = 0;
2773 }
2774
2775 if (y < 0)
2776 {
2777 y_scroll = y;
2778 y = 0;
2779 }
2780 else if (y >= allocation.height)
2781 {
2782 y_scroll = y - allocation.height + 1;
2783 y = allocation.height - 1;
2784 }
2785 else
2786 {
2787 y_scroll = 0;
2788 }
2789
2790 if (y_scroll == 0 && x_scroll == 0
2791 && (int) band_info->prev_x == x && (int) band_info->prev_y == y && !adj_changed)
2792 {
2793 return TRUE(!(0));
2794 }
2795
2796 baul_icon_container_scroll (container, x_scroll, y_scroll);
2797
2798 /* Remember to convert from widget to scrolled window coords */
2799 eel_canvas_window_to_world (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
,
2800 x + ctk_adjustment_get_value (ctk_scrollable_get_hadjustment (CTK_SCROLLABLE (container)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_scrollable_get_type ()))))))
)),
2801 y + ctk_adjustment_get_value (ctk_scrollable_get_vadjustment (CTK_SCROLLABLE (container)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_scrollable_get_type ()))))))
)),
2802 &world_x, &world_y);
2803
2804 if (world_x < band_info->start_x)
2805 {
2806 x1 = world_x;
2807 x2 = band_info->start_x;
2808 }
2809 else
2810 {
2811 x1 = band_info->start_x;
2812 x2 = world_x;
2813 }
2814
2815 if (world_y < band_info->start_y)
2816 {
2817 y1 = world_y;
2818 y2 = band_info->start_y;
2819 }
2820 else
2821 {
2822 y1 = band_info->start_y;
2823 y2 = world_y;
2824 }
2825
2826 /* Don't let the area of the selection rectangle be empty.
2827 * Aside from the fact that it would be funny when the rectangle disappears,
2828 * this also works around a crash in libart that happens sometimes when a
2829 * zero height rectangle is passed.
2830 */
2831 x2 = MAX (x1 + 1, x2)(((x1 + 1) > (x2)) ? (x1 + 1) : (x2));
2832 y2 = MAX (y1 + 1, y2)(((y1 + 1) > (y2)) ? (y1 + 1) : (y2));
2833
2834 eel_canvas_item_set
2835 (band_info->selection_rectangle,
2836 "x1", x1, "y1", y1,
2837 "x2", x2, "y2", y2,
2838 NULL((void*)0));
2839
2840 selection_rect.x0 = x1;
2841 selection_rect.y0 = y1;
2842 selection_rect.x1 = x2;
2843 selection_rect.y1 = y2;
2844
2845 rubberband_select (container,
2846 &band_info->prev_rect,
2847 &selection_rect);
2848
2849 band_info->prev_x = x;
2850 band_info->prev_y = y;
2851
2852 band_info->prev_rect = selection_rect;
2853
2854 return TRUE(!(0));
2855}
2856
2857/*borrowed from Nemo, makes Baul rubberbanding follow same selectors as Nemo and presumably Nautilus */
2858static void
2859start_rubberbanding (BaulIconContainer *container,
2860 CdkEventButton *event)
2861{
2862 AtkObject *accessible;
2863 BaulIconContainerDetails *details;
2864 BaulIconRubberbandInfo *band_info;
2865 CdkRGBA bg_color, border_color;
2866 CdkRGBA *c;
2867 GList *p;
2868 BaulIcon *icon;
2869 CtkStyleContext *context;
2870
2871 details = container->details;
2872 band_info = &details->rubberband_info;
2873
2874 g_signal_emit (container,
2875 signals[BAND_SELECT_STARTED], 0);
2876
2877 for (p = details->icons; p != NULL((void*)0); p = p->next) {
2878 icon = p->data;
2879 icon->was_selected_before_rubberband = icon->is_selected;
2880 }
2881
2882 eel_canvas_window_to_world
2883 (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
, event->x, event->y,
2884 &band_info->start_x, &band_info->start_y);
2885
2886 context = ctk_widget_get_style_context (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
);
2887 ctk_style_context_save (context);
2888 ctk_style_context_add_class (context, CTK_STYLE_CLASS_RUBBERBAND"rubberband");
2889
2890 ctk_style_context_get (context, CTK_STATE_FLAG_NORMAL,
2891 CTK_STYLE_PROPERTY_BACKGROUND_COLOR"background-color",
2892 &c, NULL((void*)0));
2893
2894 bg_color = *c;
2895
2896 ctk_style_context_get (context, CTK_STATE_FLAG_NORMAL,
2897 CTK_STYLE_PROPERTY_BORDER_COLOR"border-color",
2898 &c, NULL((void*)0));
2899
2900 border_color = *c;
2901 cdk_rgba_free (c);
2902
2903 ctk_style_context_restore (context);
2904
2905 band_info->selection_rectangle = eel_canvas_item_new
2906 (eel_canvas_root
2907 (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
),
2908 EEL_TYPE_CANVAS_RECT(eel_canvas_rect_get_type ()),
2909 "x1", band_info->start_x,
2910 "y1", band_info->start_y,
2911 "x2", band_info->start_x,
2912 "y2", band_info->start_y,
2913 "fill_color_rgba", &bg_color,
2914 "outline_color_rgba", &border_color,
2915 "width_pixels", 1,
2916 NULL((void*)0));
2917
2918 accessible = atk_gobject_accessible_for_object
2919 (G_OBJECT (band_info->selection_rectangle)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((band_info->selection_rectangle)), (((GType) ((20) <<
(2))))))))
);
2920 atk_object_set_name (accessible, "selection");
2921 atk_object_set_description (accessible, _("The selection rectangle")gettext ("The selection rectangle"));
2922
2923 band_info->prev_x = event->x - ctk_adjustment_get_value (ctk_scrollable_get_hadjustment (CTK_SCROLLABLE (container)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_scrollable_get_type ()))))))
));
2924 band_info->prev_y = event->y - ctk_adjustment_get_value (ctk_scrollable_get_vadjustment (CTK_SCROLLABLE (container)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_scrollable_get_type ()))))))
));
2925
2926 band_info->active = TRUE(!(0));
2927
2928 if (band_info->timer_id == 0) {
2929 band_info->timer_id = g_timeout_add
2930 (RUBBERBAND_TIMEOUT_INTERVAL10,
2931 rubberband_timeout_callback,
2932 container);
2933 }
2934
2935 eel_canvas_item_grab (band_info->selection_rectangle,
2936 (CDK_POINTER_MOTION_MASK
2937 | CDK_BUTTON_RELEASE_MASK
2938 | CDK_SCROLL_MASK),
2939 NULL((void*)0),
2940 (CdkEvent *)event);
2941}
2942
2943static void
2944stop_rubberbanding (BaulIconContainer *container)
2945{
2946 BaulIconRubberbandInfo *band_info;
2947 GList *icons;
2948
2949 band_info = &container->details->rubberband_info;
2950
2951 g_assert (band_info->timer_id != 0)do { if (band_info->timer_id != 0) ; else g_assertion_message_expr
(((gchar*) 0), "baul-icon-container.c", 2951, ((const char*)
(__func__)), "band_info->timer_id != 0"); } while (0)
;
2952 g_source_remove (band_info->timer_id);
2953 band_info->timer_id = 0;
2954
2955 band_info->active = FALSE(0);
2956
2957 /* Destroy this canvas item; the parent will unref it. */
2958 eel_canvas_item_ungrab (band_info->selection_rectangle);
2959 eel_canvas_item_destroy (band_info->selection_rectangle);
2960 band_info->selection_rectangle = NULL((void*)0);
2961
2962 /* if only one item has been selected, use it as range
2963 * selection base (cf. handle_icon_button_press) */
2964 icons = baul_icon_container_get_selected_icons (container);
2965 if (g_list_length (icons) == 1)
2966 {
2967 container->details->range_selection_base_icon = icons->data;
2968 }
2969 g_list_free (icons);
2970
2971 g_signal_emit (container,
2972 signals[BAND_SELECT_ENDED], 0);
2973}
2974
2975/* Keyboard navigation. */
2976
2977typedef gboolean (* IsBetterIconFunction) (BaulIconContainer *container,
2978 BaulIcon *start_icon,
2979 BaulIcon *best_so_far,
2980 BaulIcon *candidate,
2981 void *data);
2982
2983static BaulIcon *
2984find_best_icon (BaulIconContainer *container,
2985 BaulIcon *start_icon,
2986 IsBetterIconFunction function,
2987 void *data)
2988{
2989 GList *p;
2990 BaulIcon *best, *candidate;
2991
2992 best = NULL((void*)0);
2993 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
2994 {
2995 candidate = p->data;
2996
2997 if (candidate != start_icon)
2998 {
2999 if ((* function) (container, start_icon, best, candidate, data))
3000 {
3001 best = candidate;
3002 }
3003 }
3004 }
3005 return best;
3006}
3007
3008static BaulIcon *
3009find_best_selected_icon (BaulIconContainer *container,
3010 BaulIcon *start_icon,
3011 IsBetterIconFunction function,
3012 void *data)
3013{
3014 GList *p;
3015 BaulIcon *best, *candidate;
3016
3017 best = NULL((void*)0);
3018 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
3019 {
3020 candidate = p->data;
3021
3022 if (candidate != start_icon && candidate->is_selected)
3023 {
3024 if ((* function) (container, start_icon, best, candidate, data))
3025 {
3026 best = candidate;
3027 }
3028 }
3029 }
3030 return best;
3031}
3032
3033static int
3034compare_icons_by_uri (BaulIconContainer *container,
3035 BaulIcon *icon_a,
3036 BaulIcon *icon_b)
3037{
3038 char *uri_a, *uri_b;
3039 int result;
3040
3041 g_assert (BAUL_IS_ICON_CONTAINER (container))do { if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 3041, ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); } while (0)
;
3042 g_assert (icon_a != NULL)do { if (icon_a != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-icon-container.c", 3042, ((const char*)
(__func__)), "icon_a != NULL"); } while (0)
;
3043 g_assert (icon_b != NULL)do { if (icon_b != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-icon-container.c", 3043, ((const char*)
(__func__)), "icon_b != NULL"); } while (0)
;
3044 g_assert (icon_a != icon_b)do { if (icon_a != icon_b) ; else g_assertion_message_expr ((
(gchar*) 0), "baul-icon-container.c", 3044, ((const char*) (__func__
)), "icon_a != icon_b"); } while (0)
;
3045
3046 uri_a = baul_icon_container_get_icon_uri (container, icon_a);
3047 uri_b = baul_icon_container_get_icon_uri (container, icon_b);
3048 result = strcmp (uri_a, uri_b);
3049 g_assert (result != 0)do { if (result != 0) ; else g_assertion_message_expr (((gchar
*) 0), "baul-icon-container.c", 3049, ((const char*) (__func__
)), "result != 0"); } while (0)
;
3050 g_free (uri_a);
3051 g_free (uri_b);
3052
3053 return result;
3054}
3055
3056static int
3057get_cmp_point_x (BaulIconContainer *container,
3058 EelDRect icon_rect)
3059{
3060 if (container->details->label_position == BAUL_ICON_LABEL_POSITION_BESIDE)
3061 {
3062 if (ctk_widget_get_direction (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
) == CTK_TEXT_DIR_RTL)
3063 {
3064 return icon_rect.x0;
3065 }
3066 else
3067 {
3068 return icon_rect.x1;
3069 }
3070 }
3071 else
3072 {
3073 return (icon_rect.x0 + icon_rect.x1) / 2;
3074 }
3075}
3076
3077static int
3078get_cmp_point_y (BaulIconContainer *container,
3079 EelDRect icon_rect)
3080{
3081 if (container->details->label_position == BAUL_ICON_LABEL_POSITION_BESIDE)
3082 {
3083 return (icon_rect.y0 + icon_rect.y1)/2;
3084 }
3085 else
3086 {
3087 return icon_rect.y1;
3088 }
3089}
3090
3091
3092static int
3093compare_icons_horizontal (BaulIconContainer *container,
3094 BaulIcon *icon_a,
3095 BaulIcon *icon_b)
3096{
3097 EelDRect world_rect;
3098 int ax, bx;
3099
3100 world_rect = baul_icon_canvas_item_get_icon_rectangle (icon_a->item);
3101 eel_canvas_w2c
3102 (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
,
3103 get_cmp_point_x (container, world_rect),
3104 get_cmp_point_y (container, world_rect),
3105 &ax,
3106 NULL((void*)0));
3107 world_rect = baul_icon_canvas_item_get_icon_rectangle (icon_b->item);
3108 eel_canvas_w2c
3109 (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
,
3110 get_cmp_point_x (container, world_rect),
3111 get_cmp_point_y (container, world_rect),
3112 &bx,
3113 NULL((void*)0));
3114
3115 if (ax < bx)
3116 {
3117 return -1;
3118 }
3119 if (ax > bx)
3120 {
3121 return +1;
3122 }
3123 return 0;
3124}
3125
3126static int
3127compare_icons_vertical (BaulIconContainer *container,
3128 BaulIcon *icon_a,
3129 BaulIcon *icon_b)
3130{
3131 EelDRect world_rect;
3132 int ay, by;
3133
3134 world_rect = baul_icon_canvas_item_get_icon_rectangle (icon_a->item);
3135 eel_canvas_w2c
3136 (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
,
3137 get_cmp_point_x (container, world_rect),
3138 get_cmp_point_y (container, world_rect),
3139 NULL((void*)0),
3140 &ay);
3141 world_rect = baul_icon_canvas_item_get_icon_rectangle (icon_b->item);
3142 eel_canvas_w2c
3143 (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
,
3144 get_cmp_point_x (container, world_rect),
3145 get_cmp_point_y (container, world_rect),
3146 NULL((void*)0),
3147 &by);
3148
3149 if (ay < by)
3150 {
3151 return -1;
3152 }
3153 if (ay > by)
3154 {
3155 return +1;
3156 }
3157 return 0;
3158}
3159
3160static int
3161compare_icons_horizontal_first (BaulIconContainer *container,
3162 BaulIcon *icon_a,
3163 BaulIcon *icon_b)
3164{
3165 EelDRect world_rect;
3166 int ax, ay, bx, by;
3167
3168 world_rect = baul_icon_canvas_item_get_icon_rectangle (icon_a->item);
3169 eel_canvas_w2c
3170 (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
,
3171 get_cmp_point_x (container, world_rect),
3172 get_cmp_point_y (container, world_rect),
3173 &ax,
3174 &ay);
3175 world_rect = baul_icon_canvas_item_get_icon_rectangle (icon_b->item);
3176 eel_canvas_w2c
3177 (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
,
3178 get_cmp_point_x (container, world_rect),
3179 get_cmp_point_y (container, world_rect),
3180 &bx,
3181 &by);
3182
3183 if (ax < bx)
3184 {
3185 return -1;
3186 }
3187 if (ax > bx)
3188 {
3189 return +1;
3190 }
3191 if (ay < by)
3192 {
3193 return -1;
3194 }
3195 if (ay > by)
3196 {
3197 return +1;
3198 }
3199 return compare_icons_by_uri (container, icon_a, icon_b);
3200}
3201
3202static int
3203compare_icons_vertical_first (BaulIconContainer *container,
3204 BaulIcon *icon_a,
3205 BaulIcon *icon_b)
3206{
3207 EelDRect world_rect;
3208 int ax, ay, bx, by;
3209
3210 world_rect = baul_icon_canvas_item_get_icon_rectangle (icon_a->item);
3211 eel_canvas_w2c
3212 (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
,
3213 get_cmp_point_x (container, world_rect),
3214 get_cmp_point_y (container, world_rect),
3215 &ax,
3216 &ay);
3217 world_rect = baul_icon_canvas_item_get_icon_rectangle (icon_b->item);
3218 eel_canvas_w2c
3219 (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
,
3220 get_cmp_point_x (container, world_rect),
3221 get_cmp_point_y (container, world_rect),
3222 &bx,
3223 &by);
3224
3225 if (ay < by)
3226 {
3227 return -1;
3228 }
3229 if (ay > by)
3230 {
3231 return +1;
3232 }
3233 if (ax < bx)
3234 {
3235 return -1;
3236 }
3237 if (ax > bx)
3238 {
3239 return +1;
3240 }
3241 return compare_icons_by_uri (container, icon_a, icon_b);
3242}
3243
3244static gboolean
3245leftmost_in_top_row (BaulIconContainer *container,
3246 BaulIcon *start_icon G_GNUC_UNUSED__attribute__ ((__unused__)),
3247 BaulIcon *best_so_far,
3248 BaulIcon *candidate,
3249 void *data G_GNUC_UNUSED__attribute__ ((__unused__)))
3250{
3251 if (best_so_far == NULL((void*)0))
3252 {
3253 return TRUE(!(0));
3254 }
3255 return compare_icons_vertical_first (container, best_so_far, candidate) > 0;
3256}
3257
3258static gboolean
3259rightmost_in_top_row (BaulIconContainer *container,
3260 BaulIcon *start_icon G_GNUC_UNUSED__attribute__ ((__unused__)),
3261 BaulIcon *best_so_far,
3262 BaulIcon *candidate,
3263 void *data G_GNUC_UNUSED__attribute__ ((__unused__)))
3264{
3265 if (best_so_far == NULL((void*)0))
3266 {
3267 return TRUE(!(0));
3268 }
3269 return compare_icons_vertical (container, best_so_far, candidate) > 0;
3270 return compare_icons_horizontal (container, best_so_far, candidate) < 0;
3271}
3272
3273static gboolean
3274rightmost_in_bottom_row (BaulIconContainer *container,
3275 BaulIcon *start_icon G_GNUC_UNUSED__attribute__ ((__unused__)),
3276 BaulIcon *best_so_far,
3277 BaulIcon *candidate,
3278 void *data G_GNUC_UNUSED__attribute__ ((__unused__)))
3279{
3280 if (best_so_far == NULL((void*)0))
3281 {
3282 return TRUE(!(0));
3283 }
3284 return compare_icons_vertical_first (container, best_so_far, candidate) < 0;
3285}
3286
3287static int
3288compare_with_start_row (BaulIconContainer *container,
3289 BaulIcon *icon)
3290{
3291 EelCanvasItem *item;
3292
3293 item = EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
;
3294
3295 if (container->details->arrow_key_start_y < item->y1)
3296 {
3297 return -1;
3298 }
3299 if (container->details->arrow_key_start_y > item->y2)
3300 {
3301 return +1;
3302 }
3303 return 0;
3304}
3305
3306static int
3307compare_with_start_column (BaulIconContainer *container,
3308 BaulIcon *icon)
3309{
3310 EelCanvasItem *item;
3311
3312 item = EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
;
3313
3314 if (container->details->arrow_key_start_x < item->x1)
3315 {
3316 return -1;
3317 }
3318 if (container->details->arrow_key_start_x > item->x2)
3319 {
3320 return +1;
3321 }
3322 return 0;
3323}
3324
3325static gboolean
3326same_row_right_side_leftmost (BaulIconContainer *container,
3327 BaulIcon *start_icon,
3328 BaulIcon *best_so_far,
3329 BaulIcon *candidate,
3330 void *data G_GNUC_UNUSED__attribute__ ((__unused__)))
3331{
3332 /* Candidates not on the start row do not qualify. */
3333 if (compare_with_start_row (container, candidate) != 0)
3334 {
3335 return FALSE(0);
3336 }
3337
3338 /* Candidates that are farther right lose out. */
3339 if (best_so_far != NULL((void*)0))
3340 {
3341 if (compare_icons_horizontal_first (container,
3342 best_so_far,
3343 candidate) < 0)
3344 {
3345 return FALSE(0);
3346 }
3347 }
3348
3349 /* Candidate to the left of the start do not qualify. */
3350 if (compare_icons_horizontal_first (container,
3351 candidate,
3352 start_icon) <= 0)
3353 {
3354 return FALSE(0);
3355 }
3356
3357 return TRUE(!(0));
3358}
3359
3360static gboolean
3361same_row_left_side_rightmost (BaulIconContainer *container,
3362 BaulIcon *start_icon,
3363 BaulIcon *best_so_far,
3364 BaulIcon *candidate,
3365 void *data G_GNUC_UNUSED__attribute__ ((__unused__)))
3366{
3367 /* Candidates not on the start row do not qualify. */
3368 if (compare_with_start_row (container, candidate) != 0)
3369 {
3370 return FALSE(0);
3371 }
3372
3373 /* Candidates that are farther left lose out. */
3374 if (best_so_far != NULL((void*)0))
3375 {
3376 if (compare_icons_horizontal_first (container,
3377 best_so_far,
3378 candidate) > 0)
3379 {
3380 return FALSE(0);
3381 }
3382 }
3383
3384 /* Candidate to the right of the start do not qualify. */
3385 if (compare_icons_horizontal_first (container,
3386 candidate,
3387 start_icon) >= 0)
3388 {
3389 return FALSE(0);
3390 }
3391
3392 return TRUE(!(0));
3393}
3394
3395static gboolean
3396next_row_leftmost (BaulIconContainer *container,
3397 BaulIcon *start_icon G_GNUC_UNUSED__attribute__ ((__unused__)),
3398 BaulIcon *best_so_far,
3399 BaulIcon *candidate,
3400 void *data G_GNUC_UNUSED__attribute__ ((__unused__)))
3401{
3402 /* sort out icons that are not below the current row */
3403 if (compare_with_start_row (container, candidate) >= 0)
3404 {
3405 return FALSE(0);
3406 }
3407
3408 if (best_so_far != NULL((void*)0))
3409 {
3410 if (compare_icons_vertical_first (container,
3411 best_so_far,
3412 candidate) > 0)
3413 {
3414 /* candidate is above best choice, but below the current row */
3415 return TRUE(!(0));
3416 }
3417
3418 if (compare_icons_horizontal_first (container,
3419 best_so_far,
3420 candidate) > 0)
3421 {
3422 return TRUE(!(0));
3423 }
3424 }
3425
3426 return best_so_far == NULL((void*)0);
3427}
3428
3429static gboolean
3430next_row_rightmost (BaulIconContainer *container,
3431 BaulIcon *start_icon G_GNUC_UNUSED__attribute__ ((__unused__)),
3432 BaulIcon *best_so_far,
3433 BaulIcon *candidate,
3434 void *data G_GNUC_UNUSED__attribute__ ((__unused__)))
3435{
3436 /* sort out icons that are not below the current row */
3437 if (compare_with_start_row (container, candidate) >= 0)
3438 {
3439 return FALSE(0);
3440 }
3441
3442 if (best_so_far != NULL((void*)0))
3443 {
3444 if (compare_icons_vertical_first (container,
3445 best_so_far,
3446 candidate) > 0)
3447 {
3448 /* candidate is above best choice, but below the current row */
3449 return TRUE(!(0));
3450 }
3451
3452 if (compare_icons_horizontal_first (container,
3453 best_so_far,
3454 candidate) < 0)
3455 {
3456 return TRUE(!(0));
3457 }
3458 }
3459
3460 return best_so_far == NULL((void*)0);
3461}
3462
3463static gboolean
3464next_column_bottommost (BaulIconContainer *container,
3465 BaulIcon *start_icon G_GNUC_UNUSED__attribute__ ((__unused__)),
3466 BaulIcon *best_so_far,
3467 BaulIcon *candidate,
3468 void *data G_GNUC_UNUSED__attribute__ ((__unused__)))
3469{
3470 /* sort out icons that are not on the right of the current column */
3471 if (compare_with_start_column (container, candidate) >= 0)
3472 {
3473 return FALSE(0);
3474 }
3475
3476 if (best_so_far != NULL((void*)0))
3477 {
3478 if (compare_icons_horizontal_first (container,
3479 best_so_far,
3480 candidate) > 0)
3481 {
3482 /* candidate is above best choice, but below the current row */
3483 return TRUE(!(0));
3484 }
3485
3486 if (compare_icons_vertical_first (container,
3487 best_so_far,
3488 candidate) < 0)
3489 {
3490 return TRUE(!(0));
3491 }
3492 }
3493
3494 return best_so_far == NULL((void*)0);
3495}
3496
3497static gboolean
3498previous_row_rightmost (BaulIconContainer *container,
3499 BaulIcon *start_icon G_GNUC_UNUSED__attribute__ ((__unused__)),
3500 BaulIcon *best_so_far,
3501 BaulIcon *candidate,
3502 void *data G_GNUC_UNUSED__attribute__ ((__unused__)))
3503{
3504 /* sort out icons that are not above the current row */
3505 if (compare_with_start_row (container, candidate) <= 0)
3506 {
3507 return FALSE(0);
3508 }
3509
3510 if (best_so_far != NULL((void*)0))
3511 {
3512 if (compare_icons_vertical_first (container,
3513 best_so_far,
3514 candidate) < 0)
3515 {
3516 /* candidate is below the best choice, but above the current row */
3517 return TRUE(!(0));
3518 }
3519
3520 if (compare_icons_horizontal_first (container,
3521 best_so_far,
3522 candidate) < 0)
3523 {
3524 return TRUE(!(0));
3525 }
3526 }
3527
3528 return best_so_far == NULL((void*)0);
3529}
3530
3531static gboolean
3532same_column_above_lowest (BaulIconContainer *container,
3533 BaulIcon *start_icon,
3534 BaulIcon *best_so_far,
3535 BaulIcon *candidate,
3536 void *data G_GNUC_UNUSED__attribute__ ((__unused__)))
3537{
3538 /* Candidates not on the start column do not qualify. */
3539 if (compare_with_start_column (container, candidate) != 0)
3540 {
3541 return FALSE(0);
3542 }
3543
3544 /* Candidates that are higher lose out. */
3545 if (best_so_far != NULL((void*)0))
3546 {
3547 if (compare_icons_vertical_first (container,
3548 best_so_far,
3549 candidate) > 0)
3550 {
3551 return FALSE(0);
3552 }
3553 }
3554
3555 /* Candidates below the start do not qualify. */
3556 if (compare_icons_vertical_first (container,
3557 candidate,
3558 start_icon) >= 0)
3559 {
3560 return FALSE(0);
3561 }
3562
3563 return TRUE(!(0));
3564}
3565
3566static gboolean
3567same_column_below_highest (BaulIconContainer *container,
3568 BaulIcon *start_icon,
3569 BaulIcon *best_so_far,
3570 BaulIcon *candidate,
3571 void *data G_GNUC_UNUSED__attribute__ ((__unused__)))
3572{
3573 /* Candidates not on the start column do not qualify. */
3574 if (compare_with_start_column (container, candidate) != 0)
3575 {
3576 return FALSE(0);
3577 }
3578
3579 /* Candidates that are lower lose out. */
3580 if (best_so_far != NULL((void*)0))
3581 {
3582 if (compare_icons_vertical_first (container,
3583 best_so_far,
3584 candidate) < 0)
3585 {
3586 return FALSE(0);
3587 }
3588 }
3589
3590 /* Candidates above the start do not qualify. */
3591 if (compare_icons_vertical_first (container,
3592 candidate,
3593 start_icon) <= 0)
3594 {
3595 return FALSE(0);
3596 }
3597
3598 return TRUE(!(0));
3599}
3600
3601static gboolean
3602previous_column_highest (BaulIconContainer *container,
3603 BaulIcon *start_icon G_GNUC_UNUSED__attribute__ ((__unused__)),
3604 BaulIcon *best_so_far,
3605 BaulIcon *candidate,
3606 void *data G_GNUC_UNUSED__attribute__ ((__unused__)))
3607{
3608 /* sort out icons that are not before the current column */
3609 if (compare_with_start_column (container, candidate) <= 0)
3610 {
3611 return FALSE(0);
3612 }
3613
3614 if (best_so_far != NULL((void*)0))
3615 {
3616 if (compare_icons_horizontal (container,
3617 best_so_far,
3618 candidate) < 0)
3619 {
3620 /* candidate is right of the best choice, but left of the current column */
3621 return TRUE(!(0));
3622 }
3623
3624 if (compare_icons_vertical (container,
3625 best_so_far,
3626 candidate) > 0)
3627 {
3628 return TRUE(!(0));
3629 }
3630 }
3631
3632 return best_so_far == NULL((void*)0);
3633}
3634
3635
3636static gboolean
3637next_column_highest (BaulIconContainer *container,
3638 BaulIcon *start_icon G_GNUC_UNUSED__attribute__ ((__unused__)),
3639 BaulIcon *best_so_far,
3640 BaulIcon *candidate,
3641 void *data G_GNUC_UNUSED__attribute__ ((__unused__)))
3642{
3643 /* sort out icons that are not after the current column */
3644 if (compare_with_start_column (container, candidate) >= 0)
3645 {
3646 return FALSE(0);
3647 }
3648
3649 if (best_so_far != NULL((void*)0))
3650 {
3651 if (compare_icons_horizontal_first (container,
3652 best_so_far,
3653 candidate) > 0)
3654 {
3655 /* candidate is left of the best choice, but right of the current column */
3656 return TRUE(!(0));
3657 }
3658
3659 if (compare_icons_vertical_first (container,
3660 best_so_far,
3661 candidate) > 0)
3662 {
3663 return TRUE(!(0));
3664 }
3665 }
3666
3667 return best_so_far == NULL((void*)0);
3668}
3669
3670static gboolean
3671previous_column_lowest (BaulIconContainer *container,
3672 BaulIcon *start_icon G_GNUC_UNUSED__attribute__ ((__unused__)),
3673 BaulIcon *best_so_far,
3674 BaulIcon *candidate,
3675 void *data G_GNUC_UNUSED__attribute__ ((__unused__)))
3676{
3677 /* sort out icons that are not before the current column */
3678 if (compare_with_start_column (container, candidate) <= 0)
3679 {
3680 return FALSE(0);
3681 }
3682
3683 if (best_so_far != NULL((void*)0))
3684 {
3685 if (compare_icons_horizontal_first (container,
3686 best_so_far,
3687 candidate) < 0)
3688 {
3689 /* candidate is right of the best choice, but left of the current column */
3690 return TRUE(!(0));
3691 }
3692
3693 if (compare_icons_vertical_first (container,
3694 best_so_far,
3695 candidate) < 0)
3696 {
3697 return TRUE(!(0));
3698 }
3699 }
3700
3701 return best_so_far == NULL((void*)0);
3702}
3703
3704static gboolean
3705last_column_lowest (BaulIconContainer *container,
3706 BaulIcon *start_icon G_GNUC_UNUSED__attribute__ ((__unused__)),
3707 BaulIcon *best_so_far,
3708 BaulIcon *candidate,
3709 void *data G_GNUC_UNUSED__attribute__ ((__unused__)))
3710{
3711 if (best_so_far == NULL((void*)0))
3712 {
3713 return TRUE(!(0));
3714 }
3715 return compare_icons_horizontal_first (container, best_so_far, candidate) < 0;
3716}
3717
3718static gboolean
3719closest_in_90_degrees (BaulIconContainer *container,
3720 BaulIcon *start_icon G_GNUC_UNUSED__attribute__ ((__unused__)),
3721 BaulIcon *best_so_far,
3722 BaulIcon *candidate,
3723 void *data)
3724{
3725 EelDRect world_rect;
3726 int x, y;
3727 int dx, dy;
3728 int dist;
3729 int *best_dist;
3730
3731
3732 world_rect = baul_icon_canvas_item_get_icon_rectangle (candidate->item);
3733 eel_canvas_w2c
3734 (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
,
3735 get_cmp_point_x (container, world_rect),
3736 get_cmp_point_y (container, world_rect),
3737 &x,
3738 &y);
3739
3740 dx = x - container->details->arrow_key_start_x;
3741 dy = y - container->details->arrow_key_start_y;
3742
3743 switch (container->details->arrow_key_direction)
3744 {
3745 case CTK_DIR_UP:
3746 if (dy > 0 ||
3747 ABS(dx)(((dx) < 0) ? -(dx) : (dx)) > ABS(dy)(((dy) < 0) ? -(dy) : (dy)))
3748 {
3749 return FALSE(0);
3750 }
3751 break;
3752 case CTK_DIR_DOWN:
3753 if (dy < 0 ||
3754 ABS(dx)(((dx) < 0) ? -(dx) : (dx)) > ABS(dy)(((dy) < 0) ? -(dy) : (dy)))
3755 {
3756 return FALSE(0);
3757 }
3758 break;
3759 case CTK_DIR_LEFT:
3760 if (dx > 0 ||
3761 ABS(dy)(((dy) < 0) ? -(dy) : (dy)) > ABS(dx)(((dx) < 0) ? -(dx) : (dx)))
3762 {
3763 return FALSE(0);
3764 }
3765 break;
3766 case CTK_DIR_RIGHT:
3767 if (dx < 0 ||
3768 ABS(dy)(((dy) < 0) ? -(dy) : (dy)) > ABS(dx)(((dx) < 0) ? -(dx) : (dx)))
3769 {
3770 return FALSE(0);
3771 }
3772 break;
3773 default:
3774 g_assert_not_reached()do { g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 3774, ((const char*) (__func__)), ((void*)0)); } while (0)
;
3775 }
3776
3777 dist = dx*dx + dy*dy;
3778 best_dist = data;
3779
3780 if (best_so_far == NULL((void*)0))
3781 {
3782 *best_dist = dist;
3783 return TRUE(!(0));
3784 }
3785
3786 if (dist < *best_dist)
3787 {
3788 *best_dist = dist;
3789 return TRUE(!(0));
3790 }
3791
3792 return FALSE(0);
3793}
3794
3795static EelDRect
3796get_rubberband (BaulIcon *icon1,
3797 BaulIcon *icon2)
3798{
3799 EelDRect rect1;
3800 EelDRect rect2;
3801 EelDRect ret;
3802
3803 eel_canvas_item_get_bounds (EEL_CANVAS_ITEM (icon1->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon1->item)), ((eel_canvas_item_get_type ()))))))
,
3804 &rect1.x0, &rect1.y0,
3805 &rect1.x1, &rect1.y1);
3806 eel_canvas_item_get_bounds (EEL_CANVAS_ITEM (icon2->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon2->item)), ((eel_canvas_item_get_type ()))))))
,
3807 &rect2.x0, &rect2.y0,
3808 &rect2.x1, &rect2.y1);
3809
3810 eel_drect_union (&ret, &rect1, &rect2);
3811
3812 return ret;
3813}
3814
3815static void
3816keyboard_move_to (BaulIconContainer *container,
3817 BaulIcon *icon,
3818 BaulIcon *from,
3819 CdkEventKey *event)
3820{
3821 if (icon == NULL((void*)0))
3822 {
3823 return;
3824 }
3825
3826 if (event != NULL((void*)0) &&
3827 (event->state & CDK_CONTROL_MASK) != 0 &&
3828 (event->state & CDK_SHIFT_MASK) == 0)
3829 {
3830 /* Move the keyboard focus. Use Control modifier
3831 * rather than Alt to avoid Sawfish conflict.
3832 */
3833 set_keyboard_focus (container, icon);
3834 container->details->keyboard_rubberband_start = NULL((void*)0);
3835 }
3836 else if (event != NULL((void*)0) &&
3837 ((event->state & CDK_CONTROL_MASK) != 0 ||
3838 !container->details->auto_layout) &&
3839 (event->state & CDK_SHIFT_MASK) != 0)
3840 {
3841 /* Do rubberband selection */
3842 EelDRect rect;
3843
3844 if (from && !container->details->keyboard_rubberband_start)
3845 {
3846 set_keyboard_rubberband_start (container, from);
3847 }
3848
3849 set_keyboard_focus (container, icon);
3850
3851 if (icon && container->details->keyboard_rubberband_start)
3852 {
3853 rect = get_rubberband (container->details->keyboard_rubberband_start,
3854 icon);
3855 rubberband_select (container, NULL((void*)0), &rect);
3856 }
3857 }
3858 else if (event != NULL((void*)0) &&
3859 (event->state & CDK_CONTROL_MASK) == 0 &&
3860 (event->state & CDK_SHIFT_MASK) != 0)
3861 {
3862 /* Select range */
3863 BaulIcon *start_icon;
3864
3865 start_icon = container->details->range_selection_base_icon;
3866 if (start_icon == NULL((void*)0) || !start_icon->is_selected)
3867 {
3868 start_icon = icon;
3869 container->details->range_selection_base_icon = icon;
3870 }
3871
3872 set_keyboard_focus (container, icon);
3873
3874 if (select_range (container, start_icon, icon, TRUE(!(0))))
3875 {
3876 g_signal_emit (container,
3877 signals[SELECTION_CHANGED], 0);
3878 }
3879 }
3880 else
3881 {
3882 /* Select icons and get rid of the special keyboard focus. */
3883 clear_keyboard_focus (container);
3884 clear_keyboard_rubberband_start (container);
3885
3886 container->details->range_selection_base_icon = icon;
3887 if (select_one_unselect_others (container, icon))
3888 {
3889 g_signal_emit (container,
3890 signals[SELECTION_CHANGED], 0);
3891 }
3892 }
3893 schedule_keyboard_icon_reveal (container, icon);
3894}
3895
3896static void
3897keyboard_home (BaulIconContainer *container,
3898 CdkEventKey *event)
3899{
3900 BaulIcon *from;
3901 BaulIcon *to;
3902
3903 /* Home selects the first icon.
3904 * Control-Home sets the keyboard focus to the first icon.
3905 */
3906
3907 from = find_best_selected_icon (container, NULL((void*)0),
3908 rightmost_in_bottom_row,
3909 NULL((void*)0));
3910 to = find_best_icon (container, NULL((void*)0), leftmost_in_top_row, NULL((void*)0));
3911
3912 keyboard_move_to (container, to, from, event);
3913}
3914
3915static void
3916keyboard_end (BaulIconContainer *container,
3917 CdkEventKey *event)
3918{
3919 BaulIcon *to;
3920 BaulIcon *from;
3921
3922 /* End selects the last icon.
3923 * Control-End sets the keyboard focus to the last icon.
3924 */
3925 from = find_best_selected_icon (container, NULL((void*)0),
3926 leftmost_in_top_row,
3927 NULL((void*)0));
3928 to = find_best_icon (container, NULL((void*)0),
3929 baul_icon_container_is_layout_vertical (container) ?
3930 last_column_lowest :
3931 rightmost_in_bottom_row,
3932 NULL((void*)0));
3933
3934 keyboard_move_to (container, to, from, event);
3935}
3936
3937static void
3938record_arrow_key_start (BaulIconContainer *container,
3939 BaulIcon *icon,
3940 CtkDirectionType direction)
3941{
3942 EelDRect world_rect;
3943
3944 world_rect = baul_icon_canvas_item_get_icon_rectangle (icon->item);
3945 eel_canvas_w2c
3946 (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
,
3947 get_cmp_point_x (container, world_rect),
3948 get_cmp_point_y (container, world_rect),
3949 &container->details->arrow_key_start_x,
3950 &container->details->arrow_key_start_y);
3951 container->details->arrow_key_direction = direction;
3952}
3953
3954static void
3955keyboard_arrow_key (BaulIconContainer *container,
3956 CdkEventKey *event,
3957 CtkDirectionType direction,
3958 IsBetterIconFunction better_start,
3959 IsBetterIconFunction empty_start,
3960 IsBetterIconFunction better_destination,
3961 IsBetterIconFunction better_destination_fallback,
3962 IsBetterIconFunction better_destination_fallback_fallback,
3963 IsBetterIconFunction better_destination_manual)
3964{
3965 BaulIcon *from;
3966 BaulIcon *to;
3967 int data;
3968
3969 /* Chose the icon to start with.
3970 * If we have a keyboard focus, start with it.
3971 * Otherwise, use the single selected icon.
3972 * If there's multiple selection, use the icon farthest toward the end.
3973 */
3974
3975 from = container->details->keyboard_focus;
3976
3977 if (from == NULL((void*)0))
3978 {
3979 if (has_multiple_selection (container))
3980 {
3981 if (all_selected (container))
3982 {
3983 from = find_best_selected_icon
3984 (container, NULL((void*)0),
3985 empty_start, NULL((void*)0));
3986 }
3987 else
3988 {
3989 from = find_best_selected_icon
3990 (container, NULL((void*)0),
3991 better_start, NULL((void*)0));
3992 }
3993 }
3994 else
3995 {
3996 from = get_first_selected_icon (container);
3997 }
3998 }
3999
4000 /* If there's no icon, select the icon farthest toward the end.
4001 * If there is an icon, select the next icon based on the arrow direction.
4002 */
4003 if (from == NULL((void*)0))
4004 {
4005 to = from = find_best_icon
4006 (container, NULL((void*)0),
4007 empty_start, NULL((void*)0));
4008 }
4009 else
4010 {
4011 record_arrow_key_start (container, from, direction);
4012
4013 to = find_best_icon
4014 (container, from,
4015 container->details->auto_layout ? better_destination : better_destination_manual,
4016 &data);
4017
4018 /* Wrap around to next/previous row/column */
4019 if (to == NULL((void*)0) &&
4020 better_destination_fallback != NULL((void*)0)) {
4021 to = find_best_icon
4022 (container, from,
4023 better_destination_fallback,
4024 &data);
4025 }
4026
4027 /* With a layout like
4028 * 1 2 3
4029 * 4
4030 * (horizontal layout)
4031 *
4032 * or
4033 *
4034 * 1 4
4035 * 2
4036 * 3
4037 * (vertical layout)
4038 *
4039 * * pressing down for any of 1,2,3 (horizontal layout)
4040 * * pressing right for any of 1,2,3 (vertical layout)
4041 *
4042 * Should select 4.
4043 */
4044 if (to == NULL((void*)0) &&
4045 container->details->auto_layout &&
4046 better_destination_fallback_fallback != NULL((void*)0))
4047 {
4048 to = find_best_icon
4049 (container, from,
4050 better_destination_fallback_fallback,
4051 &data);
4052 }
4053
4054 if (to == NULL((void*)0))
4055 {
4056 to = from;
4057 }
4058
4059 }
4060
4061 keyboard_move_to (container, to, from, event);
4062}
4063
4064static gboolean
4065is_rectangle_selection_event (CdkEventKey *event)
4066{
4067 return (event->state & CDK_CONTROL_MASK) != 0 &&
4068 (event->state & CDK_SHIFT_MASK) != 0;
4069}
4070
4071static void
4072keyboard_right (BaulIconContainer *container,
4073 CdkEventKey *event)
4074{
4075 IsBetterIconFunction fallback;
4076 IsBetterIconFunction next_column_fallback;
4077
4078 fallback = NULL((void*)0);
4079 if (container->details->auto_layout &&
4080 !baul_icon_container_is_layout_vertical (container) &&
4081 !is_rectangle_selection_event (event))
4082 {
4083 fallback = next_row_leftmost;
4084 }
4085
4086 next_column_fallback = NULL((void*)0);
4087 if (baul_icon_container_is_layout_vertical (container) &&
4088 ctk_widget_get_direction (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
) != CTK_TEXT_DIR_RTL)
4089 {
4090 next_column_fallback = next_column_bottommost;
4091 }
4092
4093 /* Right selects the next icon in the same row.
4094 * Control-Right sets the keyboard focus to the next icon in the same row.
4095 */
4096 keyboard_arrow_key (container,
4097 event,
4098 CTK_DIR_RIGHT,
4099 rightmost_in_bottom_row,
4100 baul_icon_container_is_layout_rtl (container) ?
4101 rightmost_in_top_row : leftmost_in_top_row,
4102 same_row_right_side_leftmost,
4103 fallback,
4104 next_column_fallback,
4105 closest_in_90_degrees);
4106}
4107
4108static void
4109keyboard_left (BaulIconContainer *container,
4110 CdkEventKey *event)
4111{
4112 IsBetterIconFunction fallback;
4113 IsBetterIconFunction previous_column_fallback;
4114
4115 fallback = NULL((void*)0);
4116 if (container->details->auto_layout &&
4117 !baul_icon_container_is_layout_vertical (container) &&
4118 !is_rectangle_selection_event (event))
4119 {
4120 fallback = previous_row_rightmost;
4121 }
4122
4123 previous_column_fallback = NULL((void*)0);
4124 if (baul_icon_container_is_layout_vertical (container) &&
4125 ctk_widget_get_direction (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
) == CTK_TEXT_DIR_RTL)
4126 {
4127 previous_column_fallback = previous_column_lowest;
4128 }
4129
4130 /* Left selects the next icon in the same row.
4131 * Control-Left sets the keyboard focus to the next icon in the same row.
4132 */
4133 keyboard_arrow_key (container,
4134 event,
4135 CTK_DIR_LEFT,
4136 rightmost_in_bottom_row,
4137 baul_icon_container_is_layout_rtl (container) ?
4138 rightmost_in_top_row : leftmost_in_top_row,
4139 same_row_left_side_rightmost,
4140 fallback,
4141 previous_column_fallback,
4142 closest_in_90_degrees);
4143}
4144
4145static void
4146keyboard_down (BaulIconContainer *container,
4147 CdkEventKey *event)
4148{
4149 IsBetterIconFunction fallback;
4150 IsBetterIconFunction next_row_fallback;
4151
4152 fallback = NULL((void*)0);
4153 if (container->details->auto_layout &&
4154 baul_icon_container_is_layout_vertical (container) &&
4155 !is_rectangle_selection_event (event))
4156 {
4157 if (ctk_widget_get_direction (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
) == CTK_TEXT_DIR_RTL)
4158 {
4159 fallback = previous_column_highest;
4160 }
4161 else
4162 {
4163 fallback = next_column_highest;
4164 }
4165 }
4166
4167 next_row_fallback = NULL((void*)0);
4168 if (!baul_icon_container_is_layout_vertical (container))
4169 {
4170 if (ctk_widget_get_direction (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
) == CTK_TEXT_DIR_RTL)
4171 {
4172 next_row_fallback = next_row_leftmost;
4173 }
4174 else
4175 {
4176 next_row_fallback = next_row_rightmost;
4177 }
4178 }
4179
4180 /* Down selects the next icon in the same column.
4181 * Control-Down sets the keyboard focus to the next icon in the same column.
4182 */
4183 keyboard_arrow_key (container,
4184 event,
4185 CTK_DIR_DOWN,
4186 rightmost_in_bottom_row,
4187 baul_icon_container_is_layout_rtl (container) ?
4188 rightmost_in_top_row : leftmost_in_top_row,
4189 same_column_below_highest,
4190 fallback,
4191 next_row_fallback,
4192 closest_in_90_degrees);
4193}
4194
4195static void
4196keyboard_up (BaulIconContainer *container,
4197 CdkEventKey *event)
4198{
4199 IsBetterIconFunction fallback;
4200
4201 fallback = NULL((void*)0);
4202 if (container->details->auto_layout &&
4203 baul_icon_container_is_layout_vertical (container) &&
4204 !is_rectangle_selection_event (event))
4205 {
4206 if (ctk_widget_get_direction (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
) == CTK_TEXT_DIR_RTL)
4207 {
4208 fallback = next_column_bottommost;
4209 }
4210 else
4211 {
4212 fallback = previous_column_lowest;
4213 }
4214 }
4215
4216 /* Up selects the next icon in the same column.
4217 * Control-Up sets the keyboard focus to the next icon in the same column.
4218 */
4219 keyboard_arrow_key (container,
4220 event,
4221 CTK_DIR_UP,
4222 rightmost_in_bottom_row,
4223 baul_icon_container_is_layout_rtl (container) ?
4224 rightmost_in_top_row : leftmost_in_top_row,
4225 same_column_above_lowest,
4226 fallback,
4227 NULL((void*)0),
4228 closest_in_90_degrees);
4229}
4230
4231static void
4232keyboard_space (BaulIconContainer *container,
4233 CdkEventKey *event)
4234{
4235 BaulIcon *icon;
4236
4237 if (!has_selection (container) &&
4238 container->details->keyboard_focus != NULL((void*)0))
4239 {
4240 keyboard_move_to (container,
4241 container->details->keyboard_focus,
4242 NULL((void*)0), NULL((void*)0));
4243 }
4244 else if ((event->state & CDK_CONTROL_MASK) != 0 &&
4245 (event->state & CDK_SHIFT_MASK) == 0)
4246 {
4247 /* Control-space toggles the selection state of the current icon. */
4248 if (container->details->keyboard_focus != NULL((void*)0))
4249 {
4250 icon_toggle_selected (container, container->details->keyboard_focus);
4251 g_signal_emit (container, signals[SELECTION_CHANGED], 0);
4252 if (container->details->keyboard_focus->is_selected)
4253 {
4254 container->details->range_selection_base_icon = container->details->keyboard_focus;
4255 }
4256 }
4257 else
4258 {
4259 icon = find_best_selected_icon (container,
4260 NULL((void*)0),
4261 leftmost_in_top_row,
4262 NULL((void*)0));
4263 if (icon == NULL((void*)0))
4264 {
4265 icon = find_best_icon (container,
4266 NULL((void*)0),
4267 leftmost_in_top_row,
4268 NULL((void*)0));
4269 }
4270 if (icon != NULL((void*)0))
4271 {
4272 set_keyboard_focus (container, icon);
4273 }
4274 }
4275 }
4276 else if ((event->state & CDK_SHIFT_MASK) != 0)
4277 {
4278 activate_selected_items_alternate (container, NULL((void*)0));
4279 }
4280 else
4281 {
4282 activate_selected_items (container);
4283 }
4284}
4285
4286/* look for the first icon that matches the longest part of a given
4287 * search pattern
4288 */
4289typedef struct
4290{
4291 gunichar *name;
4292 int last_match_length;
4293} BestNameMatch;
4294
4295#ifndef TAB_NAVIGATION_DISABLED
4296static void
4297select_previous_or_next_icon (BaulIconContainer *container,
4298 gboolean next,
4299 CdkEventKey *event)
4300{
4301 BaulIcon *icon;
4302 const GList *item;
4303
4304 item = NULL((void*)0);
4305 /* Chose the icon to start with.
4306 * If we have a keyboard focus, start with it.
4307 * Otherwise, use the single selected icon.
4308 */
4309 icon = container->details->keyboard_focus;
4310 if (icon == NULL((void*)0))
4311 {
4312 icon = get_first_selected_icon (container);
4313 }
4314
4315 if (icon != NULL((void*)0))
4316 {
4317 /* must have at least @icon in the list */
4318 g_assert (container->details->icons != NULL)do { if (container->details->icons != ((void*)0)) ; else
g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 4318, ((const char*) (__func__)), "container->details->icons != NULL"
); } while (0)
;
4319 item = g_list_find (container->details->icons, icon);
4320 g_assert (item != NULL)do { if (item != ((void*)0)) ; else g_assertion_message_expr (
((gchar*) 0), "baul-icon-container.c", 4320, ((const char*) (
__func__)), "item != NULL"); } while (0)
;
4321
4322 item = next ? item->next : item->prev;
4323 if (item == NULL((void*)0))
4324 {
4325 item = next ? g_list_first (container->details->icons) : g_list_last (container->details->icons);
4326 }
4327
4328 }
4329 else if (container->details->icons != NULL((void*)0))
4330 {
4331 /* no selection yet, pick the first or last item to select */
4332 item = next ? g_list_first (container->details->icons) : g_list_last (container->details->icons);
4333 }
4334
4335 icon = (item != NULL((void*)0)) ? item->data : NULL((void*)0);
4336
4337 if (icon != NULL((void*)0))
4338 {
4339 keyboard_move_to (container, icon, NULL((void*)0), event);
4340 }
4341}
4342#endif
4343
4344static void
4345destroy (CtkWidget *object)
4346{
4347 BaulIconContainer *container;
4348
4349 container = BAUL_ICON_CONTAINER (object)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((object)), (baul_icon_container_get_type())
))))
;
4350
4351 baul_icon_container_clear (container);
4352
4353 if (container->details->rubberband_info.timer_id != 0)
4354 {
4355 g_source_remove (container->details->rubberband_info.timer_id);
4356 container->details->rubberband_info.timer_id = 0;
4357 }
4358
4359 if (container->details->idle_id != 0)
4360 {
4361 g_source_remove (container->details->idle_id);
4362 container->details->idle_id = 0;
4363 }
4364
4365 if (container->details->stretch_idle_id != 0)
4366 {
4367 g_source_remove (container->details->stretch_idle_id);
4368 container->details->stretch_idle_id = 0;
4369 }
4370
4371 if (container->details->align_idle_id != 0)
4372 {
4373 g_source_remove (container->details->align_idle_id);
4374 container->details->align_idle_id = 0;
4375 }
4376
4377 if (container->details->selection_changed_id != 0)
4378 {
4379 g_source_remove (container->details->selection_changed_id);
4380 container->details->selection_changed_id = 0;
4381 }
4382
4383 if (container->details->size_allocation_count_id != 0)
4384 {
4385 g_source_remove (container->details->size_allocation_count_id);
4386 container->details->size_allocation_count_id = 0;
4387 }
4388
4389 /* destroy interactive search dialog */
4390 if (container->details->search_window)
4391 {
4392 ctk_widget_destroy (container->details->search_window);
4393 container->details->search_window = NULL((void*)0);
4394 container->details->search_entry = NULL((void*)0);
4395 if (container->details->typeselect_flush_timeout)
4396 {
4397 g_source_remove (container->details->typeselect_flush_timeout);
4398 container->details->typeselect_flush_timeout = 0;
4399 }
4400 }
4401
4402 CTK_WIDGET_CLASS (baul_icon_container_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((baul_icon_container_parent_class)), ((ctk_widget_get_type
()))))))
->destroy (object);
4403}
4404
4405static void
4406finalize (GObject *object)
4407{
4408 BaulIconContainerDetails *details;
4409
4410 details = BAUL_ICON_CONTAINER (object)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((object)), (baul_icon_container_get_type())
))))
->details;
4411
4412 g_signal_handlers_disconnect_by_func (baul_icon_view_preferences,g_signal_handlers_disconnect_matched ((baul_icon_view_preferences
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (text_ellipsis_limit_changed_container_callback
), (object))
4413 text_ellipsis_limit_changed_container_callback,g_signal_handlers_disconnect_matched ((baul_icon_view_preferences
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (text_ellipsis_limit_changed_container_callback
), (object))
4414 object)g_signal_handlers_disconnect_matched ((baul_icon_view_preferences
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (text_ellipsis_limit_changed_container_callback
), (object))
;
4415 g_signal_handlers_disconnect_by_func (baul_desktop_preferences,g_signal_handlers_disconnect_matched ((baul_desktop_preferences
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (text_ellipsis_limit_changed_container_callback
), (object))
4416 text_ellipsis_limit_changed_container_callback,g_signal_handlers_disconnect_matched ((baul_desktop_preferences
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (text_ellipsis_limit_changed_container_callback
), (object))
4417 object)g_signal_handlers_disconnect_matched ((baul_desktop_preferences
), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA
), 0, 0, ((void*)0), (text_ellipsis_limit_changed_container_callback
), (object))
;
4418
4419 g_hash_table_destroy (details->icon_set);
4420 details->icon_set = NULL((void*)0);
4421
4422 g_free (details->font);
4423
4424 if (details->a11y_item_action_queue != NULL((void*)0))
4425 {
4426 while (!g_queue_is_empty (details->a11y_item_action_queue))
4427 {
4428 g_free (g_queue_pop_head (details->a11y_item_action_queue));
4429 }
4430 g_queue_free (details->a11y_item_action_queue);
4431 }
4432 if (details->a11y_item_action_idle_handler != 0)
4433 {
4434 g_source_remove (details->a11y_item_action_idle_handler);
4435 }
4436
4437 g_free (details);
4438
4439 G_OBJECT_CLASS (baul_icon_container_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((baul_icon_container_parent_class)), (((GType) ((20) <<
(2))))))))
->finalize (object);
4440}
4441
4442/* CtkWidget methods. */
4443
4444static gboolean
4445clear_size_allocation_count (gpointer data)
4446{
4447 BaulIconContainer *container;
4448
4449 container = BAUL_ICON_CONTAINER (data)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((data)), (baul_icon_container_get_type())))
))
;
4450
4451 container->details->size_allocation_count_id = 0;
4452 container->details->size_allocation_count = 0;
4453
4454 return FALSE(0);
4455}
4456
4457static void
4458size_allocate (CtkWidget *widget,
4459 CtkAllocation *allocation)
4460{
4461 BaulIconContainer *container;
4462 gboolean need_layout_redone;
4463 CtkAllocation wid_allocation;
4464
4465 container = BAUL_ICON_CONTAINER (widget)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((widget)), (baul_icon_container_get_type())
))))
;
4466
4467 need_layout_redone = !container->details->has_been_allocated;
4468 ctk_widget_get_allocation (widget, &wid_allocation);
4469
4470 if (allocation->width != wid_allocation.width)
4471 {
4472 need_layout_redone = TRUE(!(0));
4473 }
4474
4475 if (allocation->height != wid_allocation.height)
4476 {
4477 need_layout_redone = TRUE(!(0));
4478 }
4479
4480 /* Under some conditions we can end up in a loop when size allocating.
4481 * This happens when the icons don't fit without a scrollbar, but fits
4482 * when a scrollbar is added (bug #129963 for details).
4483 * We keep track of this looping by increasing a counter in size_allocate
4484 * and clearing it in a high-prio idle (the only way to detect the loop is
4485 * done).
4486 * When we've done at more than two iterations (with/without scrollbar)
4487 * we terminate this looping by not redoing the layout when the width
4488 * is wider than the current one (i.e when removing the scrollbar).
4489 */
4490 if (container->details->size_allocation_count_id == 0)
4491 {
4492 container->details->size_allocation_count_id =
4493 g_idle_add_full (G_PRIORITY_HIGH-100,
4494 clear_size_allocation_count,
4495 container, NULL((void*)0));
4496 }
4497 container->details->size_allocation_count++;
4498 if (container->details->size_allocation_count > 2 &&
4499 allocation->width >= wid_allocation.width)
4500 {
4501 need_layout_redone = FALSE(0);
4502 }
4503
4504 CTK_WIDGET_CLASS (baul_icon_container_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((baul_icon_container_parent_class)), ((ctk_widget_get_type
()))))))
->size_allocate (widget, allocation);
4505
4506 container->details->has_been_allocated = TRUE(!(0));
4507
4508 if (need_layout_redone)
4509 {
4510 redo_layout (container);
4511 }
4512}
4513
4514static CtkSizeRequestMode
4515get_request_mode (CtkWidget *widget G_GNUC_UNUSED__attribute__ ((__unused__)))
4516{
4517 /* Don't trade size at all, since we get whatever we get anyway. */
4518 return CTK_SIZE_REQUEST_CONSTANT_SIZE;
4519}
4520
4521 /* We need to implement these since the CtkScrolledWindow uses them
4522 to guess whether to show scrollbars or not, and if we don't report
4523 anything it'll tend to get it wrong causing double calls
4524 to size_allocate (at different sizes) during its size allocation. */
4525static void
4526get_prefered_width (CtkWidget *widget,
4527 gint *minimum_size,
4528 gint *natural_size)
4529{
4530 EelCanvasGroup *root;
4531 double x1, x2;
4532 int cx1, cx2;
4533 int width;
4534
4535 root = eel_canvas_root (EEL_CANVAS (widget)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((eel_canvas_get_type ()))))))
);
4536 eel_canvas_item_get_bounds (EEL_CANVAS_ITEM (root)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((root)), ((eel_canvas_item_get_type ()))))))
,
4537 &x1, NULL((void*)0), &x2, NULL((void*)0));
4538 eel_canvas_w2c (EEL_CANVAS (widget)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((eel_canvas_get_type ()))))))
, x1, 0, &cx1, NULL((void*)0));
4539 eel_canvas_w2c (EEL_CANVAS (widget)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((eel_canvas_get_type ()))))))
, x2, 0, &cx2, NULL((void*)0));
4540
4541 width = cx2 - cx1;
4542 if (natural_size) {
4543 *natural_size = width;
4544 }
4545 if (minimum_size) {
4546 *minimum_size = width;
4547 }
4548}
4549
4550static void
4551get_prefered_height (CtkWidget *widget,
4552 gint *minimum_size,
4553 gint *natural_size)
4554{
4555 EelCanvasGroup *root;
4556 double y1, y2;
4557 int cy1, cy2;
4558 int height;
4559
4560 root = eel_canvas_root (EEL_CANVAS (widget)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((eel_canvas_get_type ()))))))
);
4561 eel_canvas_item_get_bounds (EEL_CANVAS_ITEM (root)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((root)), ((eel_canvas_item_get_type ()))))))
,
4562 NULL((void*)0), &y1, NULL((void*)0), &y2);
4563 eel_canvas_w2c (EEL_CANVAS (widget)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((eel_canvas_get_type ()))))))
, 0, y1, NULL((void*)0), &cy1);
4564 eel_canvas_w2c (EEL_CANVAS (widget)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((eel_canvas_get_type ()))))))
, 0, y2, NULL((void*)0), &cy2);
4565
4566 height = cy2 - cy1;
4567 if (natural_size) {
4568 *natural_size = height;
4569 }
4570 if (minimum_size) {
4571 *minimum_size = height;
4572 }
4573}
4574
4575static gboolean
4576draw (CtkWidget *widget, cairo_t *cr)
4577{
4578 if (!BAUL_ICON_CONTAINER (widget)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((widget)), (baul_icon_container_get_type())
))))
->details->is_desktop)
4579 {
4580 eel_background_draw (widget, cr);
4581 }
4582
4583 return CTK_WIDGET_CLASS (baul_icon_container_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((baul_icon_container_parent_class)), ((ctk_widget_get_type
()))))))
->draw (widget,
4584 cr);
4585}
4586
4587static void
4588realize (CtkWidget *widget)
4589{
4590 CtkAdjustment *vadj, *hadj;
4591 BaulIconContainer *container;
4592
4593 CTK_WIDGET_CLASS (baul_icon_container_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((baul_icon_container_parent_class)), ((ctk_widget_get_type
()))))))
->realize (widget);
4594
4595 container = BAUL_ICON_CONTAINER (widget)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((widget)), (baul_icon_container_get_type())
))))
;
4596
4597 /* Set up DnD. */
4598 baul_icon_dnd_init (container);
4599
4600 hadj = ctk_scrollable_get_hadjustment (CTK_SCROLLABLE (widget)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_scrollable_get_type ()))))))
);
4601 g_signal_connect (hadj, "value_changed",g_signal_connect_data ((hadj), ("value_changed"), (((GCallback
) (handle_hadjustment_changed))), (widget), ((void*)0), (GConnectFlags
) 0)
4602 G_CALLBACK (handle_hadjustment_changed), widget)g_signal_connect_data ((hadj), ("value_changed"), (((GCallback
) (handle_hadjustment_changed))), (widget), ((void*)0), (GConnectFlags
) 0)
;
4603
4604 vadj = ctk_scrollable_get_vadjustment (CTK_SCROLLABLE (widget)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_scrollable_get_type ()))))))
);
4605 g_signal_connect (vadj, "value_changed",g_signal_connect_data ((vadj), ("value_changed"), (((GCallback
) (handle_vadjustment_changed))), (widget), ((void*)0), (GConnectFlags
) 0)
4606 G_CALLBACK (handle_vadjustment_changed), widget)g_signal_connect_data ((vadj), ("value_changed"), (((GCallback
) (handle_vadjustment_changed))), (widget), ((void*)0), (GConnectFlags
) 0)
;
4607
4608}
4609
4610static void
4611unrealize (CtkWidget *widget)
4612{
4613 BaulIconContainer *container;
4614
4615 container = BAUL_ICON_CONTAINER (widget)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((widget)), (baul_icon_container_get_type())
))))
;
4616
4617 baul_icon_dnd_fini (container);
4618
4619 if (container->details->typeselect_flush_timeout)
4620 {
4621 g_source_remove (container->details->typeselect_flush_timeout);
4622 container->details->typeselect_flush_timeout = 0;
4623 }
4624
4625 CTK_WIDGET_CLASS (baul_icon_container_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((baul_icon_container_parent_class)), ((ctk_widget_get_type
()))))))
->unrealize (widget);
4626}
4627
4628static void
4629style_updated (CtkWidget *widget)
4630{
4631 BaulIconContainer *container;
4632
4633 container = BAUL_ICON_CONTAINER (widget)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((widget)), (baul_icon_container_get_type())
))))
;
4634 container->details->use_drop_shadows = container->details->drop_shadows_requested;
4635
4636 /* Don't chain up to parent, if this is a desktop container,
4637 * because that resets the background of the window.
4638 */
4639 if (!baul_icon_container_get_is_desktop (container)) {
4640 CTK_WIDGET_CLASS (baul_icon_container_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((baul_icon_container_parent_class)), ((ctk_widget_get_type
()))))))
->style_updated (widget);
4641 }
4642
4643 if (ctk_widget_get_realized (widget))
4644 {
4645 invalidate_labels (container);
4646 baul_icon_container_request_update_all (container);
4647 }
4648}
4649
4650static gboolean
4651button_press_event (CtkWidget *widget,
4652 CdkEventButton *event)
4653{
4654 BaulIconContainer *container;
4655 gboolean selection_changed;
4656 gboolean return_value;
4657 gboolean clicked_on_icon;
4658
4659 container = BAUL_ICON_CONTAINER (widget)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((widget)), (baul_icon_container_get_type())
))))
;
4660 container->details->button_down_time = event->time;
4661
4662 /* Forget about the old keyboard selection now that we've started mousing. */
4663 clear_keyboard_focus (container);
4664 clear_keyboard_rubberband_start (container);
4665
4666 if (event->type == CDK_2BUTTON_PRESS || event->type == CDK_3BUTTON_PRESS)
4667 {
4668 /* We use our own double-click detection. */
4669 return TRUE(!(0));
4670 }
4671
4672 /* Invoke the canvas event handler and see if an item picks up the event. */
4673 clicked_on_icon = CTK_WIDGET_CLASS (baul_icon_container_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((baul_icon_container_parent_class)), ((ctk_widget_get_type
()))))))
->button_press_event (widget, event);
4674
4675 /* Move focus to icon container, unless we're still renaming (to avoid exiting
4676 * renaming mode)
4677 */
4678 if (!ctk_widget_has_focus (widget) && !(is_renaming (container) || is_renaming_pending (container)))
4679 {
4680 ctk_widget_grab_focus (widget);
4681 }
4682
4683 if (clicked_on_icon)
4684 {
4685 return TRUE(!(0));
4686 }
4687
4688 if (event->button == DRAG_BUTTON1 &&
4689 event->type == CDK_BUTTON_PRESS)
4690 {
4691 /* Clear the last click icon for double click */
4692 container->details->double_click_icon[1] = container->details->double_click_icon[0];
4693 container->details->double_click_icon[0] = NULL((void*)0);
4694 }
4695
4696 /* Button 1 does rubber banding. */
4697 if (event->button == RUBBERBAND_BUTTON1)
4698 {
4699 if (! button_event_modifies_selection (event))
4700 {
4701 selection_changed = unselect_all (container);
4702 if (selection_changed)
4703 {
4704 g_signal_emit (container,
4705 signals[SELECTION_CHANGED], 0);
4706 }
4707 }
4708
4709 start_rubberbanding (container, event);
4710 return TRUE(!(0));
4711 }
4712
4713 /* Prevent multi-button weirdness such as bug 6181 */
4714 if (container->details->rubberband_info.active)
4715 {
4716 return TRUE(!(0));
4717 }
4718
4719 /* Button 2 may be passed to the window manager. */
4720 if (event->button == MIDDLE_BUTTON2)
4721 {
4722 selection_changed = unselect_all (container);
4723 if (selection_changed)
4724 {
4725 g_signal_emit (container, signals[SELECTION_CHANGED], 0);
4726 }
4727 g_signal_emit (widget, signals[MIDDLE_CLICK], 0, event);
4728 return TRUE(!(0));
4729 }
4730
4731 /* Button 3 does a contextual menu. */
4732 if (event->button == CONTEXTUAL_MENU_BUTTON3)
4733 {
4734 end_renaming_mode (container, TRUE(!(0)));
4735 selection_changed = unselect_all (container);
4736 if (selection_changed)
4737 {
4738 g_signal_emit (container, signals[SELECTION_CHANGED], 0);
4739 }
4740 g_signal_emit (widget, signals[CONTEXT_CLICK_BACKGROUND], 0, event);
4741 return TRUE(!(0));
4742 }
4743
4744 /* Otherwise, we emit a button_press message. */
4745 g_signal_emit (widget,
4746 signals[BUTTON_PRESS], 0, event,
4747 &return_value);
4748 return return_value;
4749}
4750
4751static void
4752baul_icon_container_did_not_drag (BaulIconContainer *container,
4753 CdkEventButton *event)
4754{
4755 BaulIconContainerDetails *details;
4756 gboolean selection_changed;
4757 static gint64 last_click_time = 0;
4758 static gint click_count = 0;
4759 gint double_click_time;
4760 gint64 current_time;
4761
4762 details = container->details;
4763
4764 if (details->icon_selected_on_button_down &&
4765 ((event->state & CDK_CONTROL_MASK) != 0 ||
4766 (event->state & CDK_SHIFT_MASK) == 0))
4767 {
4768 if (button_event_modifies_selection (event))
4769 {
4770 details->range_selection_base_icon = NULL((void*)0);
4771 icon_toggle_selected (container, details->drag_icon);
4772 g_signal_emit (container,
4773 signals[SELECTION_CHANGED], 0);
4774 }
4775 else
4776 {
4777 details->range_selection_base_icon = details->drag_icon;
4778 selection_changed = select_one_unselect_others
4779 (container, details->drag_icon);
4780
4781 if (selection_changed)
4782 {
4783 g_signal_emit (container,
4784 signals[SELECTION_CHANGED], 0);
4785 }
4786 }
4787 }
4788
4789 if (details->drag_icon != NULL((void*)0) &&
4790 (details->single_click_mode ||
4791 event->button == MIDDLE_BUTTON2))
4792 {
4793 /* Determine click count */
4794 g_object_get (G_OBJECT (ctk_widget_get_settings (CTK_WIDGET (container)))((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_widget_get_settings (((((CtkWidget*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), ((ctk_widget_get_type ())))
)))))), (((GType) ((20) << (2))))))))
,
4795 "ctk-double-click-time", &double_click_time,
4796 NULL((void*)0));
4797 current_time = g_get_monotonic_time ();
4798 if (current_time - last_click_time < double_click_time * 1000)
4799 {
4800 click_count++;
4801 }
4802 else
4803 {
4804 click_count = 0;
4805 }
4806
4807 /* Stash time for next compare */
4808 last_click_time = current_time;
4809
4810 /* If single-click mode, activate the selected icons, unless modifying
4811 * the selection or pressing for a very long time, or double clicking.
4812 */
4813
4814
4815 if (click_count == 0 &&
4816 event->time - details->button_down_time < MAX_CLICK_TIME1500 &&
4817 ! button_event_modifies_selection (event))
4818 {
4819
4820 /* It's a tricky UI issue whether this should activate
4821 * just the clicked item (as if it were a link), or all
4822 * the selected items (as if you were issuing an "activate
4823 * selection" command). For now, we're trying the activate
4824 * entire selection version to see how it feels. Note that
4825 * BaulList goes the other way because its "links" seem
4826 * much more link-like.
4827 */
4828 if (event->button == MIDDLE_BUTTON2)
4829 {
4830 activate_selected_items_alternate (container, NULL((void*)0));
4831 }
4832 else
4833 {
4834 activate_selected_items (container);
4835 }
4836 }
4837 }
4838}
4839
4840static gboolean
4841clicked_within_double_click_interval (BaulIconContainer *container)
4842{
4843 static gint64 last_click_time = 0;
4844 static gint click_count = 0;
4845 gint double_click_time;
4846 gint64 current_time;
4847
4848 /* Determine click count */
4849 g_object_get (G_OBJECT (ctk_widget_get_settings (CTK_WIDGET (container)))((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_widget_get_settings (((((CtkWidget*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), ((ctk_widget_get_type ())))
)))))), (((GType) ((20) << (2))))))))
,
4850 "ctk-double-click-time", &double_click_time,
4851 NULL((void*)0));
4852 current_time = g_get_monotonic_time ();
4853 if (current_time - last_click_time < double_click_time * 1000)
4854 {
4855 click_count++;
4856 }
4857 else
4858 {
4859 click_count = 0;
4860 }
4861
4862 /* Stash time for next compare */
4863 last_click_time = current_time;
4864
4865 /* Only allow double click */
4866 if (click_count == 1) {
4867 click_count = 0;
4868 return TRUE(!(0));
4869 } else {
4870 return FALSE(0);
4871 }
4872}
4873
4874static void
4875clear_drag_state (BaulIconContainer *container)
4876{
4877 container->details->drag_icon = NULL((void*)0);
4878 container->details->drag_state = DRAG_STATE_INITIAL;
4879}
4880
4881static gboolean
4882start_stretching (BaulIconContainer *container,
4883 CdkEvent *event)
4884{
4885 BaulIconContainerDetails *details;
4886 BaulIcon *icon;
4887 EelDPoint world_point;
4888 CtkWidget *toplevel;
4889 CdkDisplay *display;
4890 CtkCornerType corner;
4891 CdkCursor *cursor;
4892
4893 details = container->details;
4894 icon = details->stretch_icon;
4895 display = ctk_widget_get_display (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
);
4896
4897 /* Check if we hit the stretch handles. */
4898 world_point.x = details->drag_x;
4899 world_point.y = details->drag_y;
4900 if (!baul_icon_canvas_item_hit_test_stretch_handles (icon->item, world_point, &corner))
4901 {
4902 return FALSE(0);
4903 }
4904
4905 switch (corner)
4906 {
4907 case CTK_CORNER_TOP_LEFT:
4908 cursor = cdk_cursor_new_for_display (display, CDK_TOP_LEFT_CORNER);
4909 break;
4910 case CTK_CORNER_BOTTOM_LEFT:
4911 cursor = cdk_cursor_new_for_display (display, CDK_BOTTOM_LEFT_CORNER);
4912 break;
4913 case CTK_CORNER_TOP_RIGHT:
4914 cursor = cdk_cursor_new_for_display (display, CDK_TOP_RIGHT_CORNER);
4915 break;
4916 case CTK_CORNER_BOTTOM_RIGHT:
4917 cursor = cdk_cursor_new_for_display (display, CDK_BOTTOM_RIGHT_CORNER);
4918 break;
4919 default:
4920 cursor = NULL((void*)0);
4921 break;
4922 }
4923 /* Set up the dragging. */
4924 details->drag_state = DRAG_STATE_STRETCH;
4925 eel_canvas_w2c (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
,
4926 details->drag_x,
4927 details->drag_y,
4928 &details->stretch_start.pointer_x,
4929 &details->stretch_start.pointer_y);
4930 eel_canvas_w2c (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
,
4931 icon->x, icon->y,
4932 &details->stretch_start.icon_x,
4933 &details->stretch_start.icon_y);
4934 icon_get_size (container, icon,
4935 &details->stretch_start.icon_size);
4936
4937 eel_canvas_item_grab (EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
,
4938 (CDK_POINTER_MOTION_MASK
4939 | CDK_BUTTON_RELEASE_MASK),
4940 cursor,
4941 event);
4942
4943 if (cursor)
4944 g_object_unref (cursor);
4945
4946 /* Ensure the window itself is focused.. */
4947 toplevel = ctk_widget_get_toplevel (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
);
4948 if (toplevel != NULL((void*)0) && ctk_widget_get_realized (toplevel))
4949 {
4950 cdk_window_focus (ctk_widget_get_window (toplevel), CDK_CURRENT_TIME0L);
4951 }
4952
4953 return TRUE(!(0));
4954}
4955
4956static gboolean
4957update_stretch_at_idle (BaulIconContainer *container)
4958{
4959 BaulIconContainerDetails *details;
4960 BaulIcon *icon;
4961 double world_x, world_y;
4962 StretchState stretch_state;
4963
4964 details = container->details;
4965 icon = details->stretch_icon;
4966
4967 if (icon == NULL((void*)0))
4968 {
4969 container->details->stretch_idle_id = 0;
4970 return FALSE(0);
4971 }
4972
4973 eel_canvas_w2c (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
,
4974 details->world_x, details->world_y,
4975 &stretch_state.pointer_x, &stretch_state.pointer_y);
4976
4977 compute_stretch (&details->stretch_start,
4978 &stretch_state);
4979
4980 eel_canvas_c2w (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
,
4981 stretch_state.icon_x, stretch_state.icon_y,
4982 &world_x, &world_y);
4983
4984 icon_set_position (icon, world_x, world_y);
4985 icon_set_size (container, icon, stretch_state.icon_size, FALSE(0), FALSE(0));
4986
4987 container->details->stretch_idle_id = 0;
4988
4989 return FALSE(0);
4990}
4991
4992static void
4993continue_stretching (BaulIconContainer *container,
4994 double world_x, double world_y)
4995{
4996
4997 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
4998
4999 container->details->world_x = world_x;
5000 container->details->world_y = world_y;
5001
5002 if (container->details->stretch_idle_id == 0)
5003 {
5004 container->details->stretch_idle_id = g_idle_add ((GSourceFunc) update_stretch_at_idle, container);
5005 }
5006}
5007
5008static gboolean
5009keyboard_stretching (BaulIconContainer *container,
5010 CdkEventKey *event)
5011{
5012 BaulIcon *icon;
5013 guint size;
5014
5015 icon = container->details->stretch_icon;
5016
5017 if (icon == NULL((void*)0) || !icon->is_selected)
5018 {
5019 return FALSE(0);
5020 }
5021
5022 icon_get_size (container, icon, &size);
5023
5024 switch (event->keyval)
5025 {
5026 case CDK_KEY_equal0x03d:
5027 case CDK_KEY_plus0x02b:
5028 case CDK_KEY_KP_Add0xffab:
5029 icon_set_size (container, icon, size + 5, FALSE(0), FALSE(0));
5030 break;
5031 case CDK_KEY_minus0x02d:
5032 case CDK_KEY_KP_Subtract0xffad:
5033 icon_set_size (container, icon, size - 5, FALSE(0), FALSE(0));
5034 break;
5035 case CDK_KEY_00x030:
5036 case CDK_KEY_KP_00xffb0:
5037 baul_icon_container_move_icon (container, icon,
5038 icon->x, icon->y,
5039 1.0,
5040 FALSE(0), TRUE(!(0)), TRUE(!(0)));
5041 break;
5042 }
5043
5044 return TRUE(!(0));
5045}
5046
5047static void
5048ungrab_stretch_icon (BaulIconContainer *container)
5049{
5050 eel_canvas_item_ungrab (EEL_CANVAS_ITEM (container->details->stretch_icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container->details->stretch_icon->item)), ((eel_canvas_item_get_type
()))))))
);
5051}
5052
5053static void
5054end_stretching (BaulIconContainer *container,
5055 double world_x, double world_y)
5056{
5057 BaulIconPosition position;
5058 BaulIcon *icon;
5059
5060 continue_stretching (container, world_x, world_y);
5061 ungrab_stretch_icon (container);
5062
5063 /* now that we're done stretching, update the icon's position */
5064
5065 icon = container->details->drag_icon;
5066 if (baul_icon_container_is_layout_rtl (container))
5067 {
5068 position.x = icon->saved_ltr_x = get_mirror_x_position (container, icon, icon->x);
5069 }
5070 else
5071 {
5072 position.x = icon->x;
5073 }
5074 position.y = icon->y;
5075 position.scale = icon->scale;
5076 g_signal_emit (container,
5077 signals[ICON_POSITION_CHANGED], 0,
5078 icon->data, &position);
5079
5080 clear_drag_state (container);
5081 redo_layout (container);
5082}
5083
5084static gboolean
5085undo_stretching (BaulIconContainer *container)
5086{
5087 BaulIcon *stretched_icon;
5088
5089 stretched_icon = container->details->stretch_icon;
5090
5091 if (stretched_icon == NULL((void*)0))
5092 {
5093 return FALSE(0);
5094 }
5095
5096 if (container->details->drag_state == DRAG_STATE_STRETCH)
5097 {
5098 ungrab_stretch_icon (container);
5099 clear_drag_state (container);
5100 }
5101 baul_icon_canvas_item_set_show_stretch_handles
5102 (stretched_icon->item, FALSE(0));
5103
5104 icon_set_position (stretched_icon,
5105 container->details->stretch_initial_x,
5106 container->details->stretch_initial_y);
5107 icon_set_size (container,
5108 stretched_icon,
5109 container->details->stretch_initial_size,
5110 TRUE(!(0)),
5111 TRUE(!(0)));
5112
5113 container->details->stretch_icon = NULL((void*)0);
5114 emit_stretch_ended (container, stretched_icon);
5115 redo_layout (container);
5116
5117 return TRUE(!(0));
5118}
5119
5120static gboolean
5121button_release_event (CtkWidget *widget,
5122 CdkEventButton *event)
5123{
5124 BaulIconContainer *container;
5125 BaulIconContainerDetails *details;
5126 double world_x, world_y;
5127
5128 container = BAUL_ICON_CONTAINER (widget)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((widget)), (baul_icon_container_get_type())
))))
;
5129 details = container->details;
5130
5131 if (event->button == RUBBERBAND_BUTTON1 && details->rubberband_info.active)
5132 {
5133 stop_rubberbanding (container);
5134 return TRUE(!(0));
5135 }
5136
5137 if (event->button == details->drag_button)
5138 {
5139 details->drag_button = 0;
5140
5141 switch (details->drag_state)
5142 {
5143 case DRAG_STATE_MOVE_OR_COPY:
5144 if (!details->drag_started)
5145 {
5146 baul_icon_container_did_not_drag (container, event);
5147 }
5148 else
5149 {
5150 baul_icon_dnd_end_drag (container);
5151 baul_debug_log (FALSE(0), BAUL_DEBUG_LOG_DOMAIN_USER"USER",
5152 "end drag from icon container");
5153 }
5154 break;
5155 case DRAG_STATE_STRETCH:
5156 eel_canvas_window_to_world
5157 (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
, event->x, event->y, &world_x, &world_y);
5158 end_stretching (container, world_x, world_y);
5159 break;
5160 default:
5161 break;
5162 }
5163
5164 clear_drag_state (container);
5165 return TRUE(!(0));
5166 }
5167
5168 return CTK_WIDGET_CLASS (baul_icon_container_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((baul_icon_container_parent_class)), ((ctk_widget_get_type
()))))))
->button_release_event (widget, event);
5169}
5170
5171static int
5172motion_notify_event (CtkWidget *widget,
5173 CdkEventMotion *event)
5174{
5175 BaulIconContainer *container;
5176 BaulIconContainerDetails *details;
5177 double world_x, world_y;
5178 int canvas_x, canvas_y;
5179 CdkDragAction actions;
5180
5181 container = BAUL_ICON_CONTAINER (widget)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((widget)), (baul_icon_container_get_type())
))))
;
5182 details = container->details;
5183
5184 if (details->drag_button != 0)
5185 {
5186 switch (details->drag_state)
5187 {
5188 case DRAG_STATE_MOVE_OR_COPY:
5189 if (details->drag_started)
5190 {
5191 break;
5192 }
5193
5194 eel_canvas_window_to_world
5195 (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
, event->x, event->y, &world_x, &world_y);
5196
5197 if (ctk_drag_check_threshold (widget,
5198 details->drag_x,
5199 details->drag_y,
5200 world_x,
5201 world_y))
5202 {
5203 details->drag_started = TRUE(!(0));
5204 details->drag_state = DRAG_STATE_MOVE_OR_COPY;
5205
5206 end_renaming_mode (container, TRUE(!(0)));
5207
5208 eel_canvas_w2c (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
,
5209 details->drag_x,
5210 details->drag_y,
5211 &canvas_x,
5212 &canvas_y);
5213
5214 actions = CDK_ACTION_COPY
5215 | CDK_ACTION_LINK
5216 | CDK_ACTION_ASK;
5217
5218 if (container->details->drag_allow_moves)
5219 {
5220 actions |= CDK_ACTION_MOVE;
5221 }
5222
5223 baul_icon_dnd_begin_drag (container,
5224 actions,
5225 details->drag_button,
5226 event,
5227 canvas_x,
5228 canvas_y);
5229 baul_debug_log (FALSE(0), BAUL_DEBUG_LOG_DOMAIN_USER"USER",
5230 "begin drag from icon container");
5231 }
5232 break;
5233 case DRAG_STATE_STRETCH:
5234 eel_canvas_window_to_world
5235 (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
, event->x, event->y, &world_x, &world_y);
5236 continue_stretching (container, world_x, world_y);
5237 break;
5238 default:
5239 break;
5240 }
5241 }
5242
5243 return CTK_WIDGET_CLASS (baul_icon_container_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((baul_icon_container_parent_class)), ((ctk_widget_get_type
()))))))
->motion_notify_event (widget, event);
5244}
5245
5246static void
5247baul_icon_container_search_position_func (BaulIconContainer *container,
5248 CtkWidget *search_dialog)
5249{
5250 gint x, y;
5251 gint cont_x, cont_y;
5252 gint cont_width, cont_height;
5253 gint scale;
5254 CdkWindow *cont_window;
5255 CdkScreen *screen;
5256 CtkRequisition requisition;
5257 CdkMonitor *monitor_num;
5258 CdkRectangle monitor;
5259
5260
5261 cont_window = ctk_widget_get_window (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
);
5262 scale = ctk_widget_get_scale_factor (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
);
5263 screen = cdk_window_get_screen (cont_window);
5264
5265 monitor_num = cdk_display_get_monitor_at_window (cdk_screen_get_display (screen),
5266 cont_window);
5267 cdk_monitor_get_geometry (monitor_num, &monitor);
5268
5269 ctk_widget_realize (search_dialog);
5270
5271 cdk_window_get_origin (cont_window, &cont_x, &cont_y);
5272
5273 cont_width = cdk_window_get_width (cont_window);
5274 cont_height = cdk_window_get_height (cont_window);
5275
5276 ctk_widget_get_preferred_size (search_dialog, &requisition, NULL((void*)0));
5277
5278 if (cont_x + cont_width - requisition.width > WidthOfScreen (cdk_x11_screen_get_xscreen (screen))((cdk_x11_screen_get_xscreen (screen))->width) / scale)
5279 {
5280 x = WidthOfScreen (cdk_x11_screen_get_xscreen (screen))((cdk_x11_screen_get_xscreen (screen))->width) / scale - requisition.width;
5281 }
5282 else if (cont_x + cont_width - requisition.width < 0)
5283 {
5284 x = 0;
5285 }
5286 else
5287 {
5288 x = cont_x + cont_width - requisition.width;
5289 }
5290
5291 if (cont_y + cont_height > HeightOfScreen (cdk_x11_screen_get_xscreen (screen))((cdk_x11_screen_get_xscreen (screen))->height))
5292 {
5293 y = HeightOfScreen (cdk_x11_screen_get_xscreen (screen))((cdk_x11_screen_get_xscreen (screen))->height) - requisition.height;
5294 }
5295 else if (cont_y + cont_height < 0) /* isn't really possible ... */
5296 {
5297 y = 0;
5298 }
5299 else
5300 {
5301 y = cont_y + cont_height;
5302 }
5303
5304 ctk_window_move (CTK_WINDOW (search_dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((search_dialog)), ((ctk_window_get_type ()))))))
, x, y);
5305}
5306
5307static gboolean
5308baul_icon_container_real_search_enable_popdown (gpointer data)
5309{
5310 BaulIconContainer *container = (BaulIconContainer *)data;
5311
5312 container->details->disable_popdown = FALSE(0);
5313
5314 g_object_unref (container);
5315
5316 return FALSE(0);
5317}
5318
5319static void
5320baul_icon_container_search_enable_popdown (CtkWidget *widget G_GNUC_UNUSED__attribute__ ((__unused__)),
5321 gpointer data)
5322{
5323 BaulIconContainer *container = (BaulIconContainer *) data;
5324
5325 g_object_ref (container)((__typeof__ (container)) (g_object_ref) (container));
5326 g_timeout_add (200, baul_icon_container_real_search_enable_popdown, data);
5327}
5328
5329static void
5330baul_icon_container_search_disable_popdown (CtkEntry *entry G_GNUC_UNUSED__attribute__ ((__unused__)),
5331 CtkMenu *menu,
5332 gpointer data)
5333{
5334 BaulIconContainer *container = (BaulIconContainer *) data;
5335
5336 container->details->disable_popdown = TRUE(!(0));
5337 g_signal_connect (menu, "hide",g_signal_connect_data ((menu), ("hide"), (((GCallback) (baul_icon_container_search_enable_popdown
))), (data), ((void*)0), (GConnectFlags) 0)
5338 G_CALLBACK (baul_icon_container_search_enable_popdown),g_signal_connect_data ((menu), ("hide"), (((GCallback) (baul_icon_container_search_enable_popdown
))), (data), ((void*)0), (GConnectFlags) 0)
5339 data)g_signal_connect_data ((menu), ("hide"), (((GCallback) (baul_icon_container_search_enable_popdown
))), (data), ((void*)0), (GConnectFlags) 0)
;
5340}
5341
5342/* Cut and paste from ctkwindow.c */
5343static void
5344send_focus_change (CtkWidget *widget, gboolean in)
5345{
5346 CdkEvent *fevent;
5347
5348 fevent = cdk_event_new (CDK_FOCUS_CHANGE);
5349
5350 g_object_ref (widget)((__typeof__ (widget)) (g_object_ref) (widget));
5351 ((CdkEventFocus *) fevent)->in = in;
5352
5353 ctk_widget_send_focus_change (widget, fevent);
5354
5355 fevent->focus_change.type = CDK_FOCUS_CHANGE;
5356 fevent->focus_change.window = g_object_ref (ctk_widget_get_window (widget))((__typeof__ (ctk_widget_get_window (widget))) (g_object_ref)
(ctk_widget_get_window (widget)))
;
5357 fevent->focus_change.in = in;
5358
5359 ctk_widget_event (widget, fevent);
5360
5361 g_object_notify (G_OBJECT (widget)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), (((GType) ((20) << (2))))))))
, "has-focus");
5362
5363 g_object_unref (widget);
5364 cdk_event_free (fevent);
5365}
5366
5367static void
5368baul_icon_container_search_dialog_hide (CtkWidget *search_dialog,
5369 BaulIconContainer *container)
5370{
5371 if (container->details->disable_popdown)
5372 {
5373 return;
5374 }
5375
5376 if (container->details->search_entry_changed_id)
5377 {
5378 g_signal_handler_disconnect (container->details->search_entry,
5379 container->details->search_entry_changed_id);
5380 container->details->search_entry_changed_id = 0;
5381 }
5382 if (container->details->typeselect_flush_timeout)
5383 {
5384 g_source_remove (container->details->typeselect_flush_timeout);
5385 container->details->typeselect_flush_timeout = 0;
5386 }
5387
5388 /* send focus-in event */
5389 send_focus_change (CTK_WIDGET (container->details->search_entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container->details->search_entry)), ((ctk_widget_get_type
()))))))
, FALSE(0));
5390 ctk_widget_hide (search_dialog);
5391 ctk_entry_set_text (CTK_ENTRY (container->details->search_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container->details->search_entry)), ((ctk_entry_get_type
()))))))
, "");
5392}
5393
5394static gboolean
5395baul_icon_container_search_entry_flush_timeout (BaulIconContainer *container)
5396{
5397 baul_icon_container_search_dialog_hide (container->details->search_window, container);
5398
5399 return TRUE(!(0));
5400}
5401
5402/* Because we're visible but offscreen, we just set a flag in the preedit
5403 * callback.
5404 */
5405static void
5406baul_icon_container_search_preedit_changed (CtkEntry *entry G_GNUC_UNUSED__attribute__ ((__unused__)),
5407 gchar *preedit G_GNUC_UNUSED__attribute__ ((__unused__)),
5408 BaulIconContainer *container)
5409{
5410 container->details->imcontext_changed = 1;
5411 if (container->details->typeselect_flush_timeout)
5412 {
5413 g_source_remove (container->details->typeselect_flush_timeout);
5414 container->details->typeselect_flush_timeout =
5415 g_timeout_add_seconds (BAUL_ICON_CONTAINER_SEARCH_DIALOG_TIMEOUT5,
5416 (GSourceFunc) baul_icon_container_search_entry_flush_timeout,
5417 container);
5418 }
5419}
5420
5421static void
5422baul_icon_container_search_activate (CtkEntry *entry G_GNUC_UNUSED__attribute__ ((__unused__)),
5423 BaulIconContainer *container)
5424{
5425 baul_icon_container_search_dialog_hide (container->details->search_window,
5426 container);
5427
5428 activate_selected_items (container);
5429}
5430
5431static gboolean
5432baul_icon_container_search_delete_event (CtkWidget *widget,
5433 CdkEventAny *event G_GNUC_UNUSED__attribute__ ((__unused__)),
5434 BaulIconContainer *container)
5435{
5436 g_assert (CTK_IS_WIDGET (widget))do { if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((widget)); GType __t = ((ctk_widget_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) ; else
g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 5436, ((const char*) (__func__)), "CTK_IS_WIDGET (widget)")
; } while (0)
;
5437
5438 baul_icon_container_search_dialog_hide (widget, container);
5439
5440 return TRUE(!(0));
5441}
5442
5443static gboolean
5444baul_icon_container_search_button_press_event (CtkWidget *widget,
5445 CdkEventButton *event,
5446 BaulIconContainer *container)
5447{
5448 g_assert (CTK_IS_WIDGET (widget))do { if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((widget)); GType __t = ((ctk_widget_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) ; else
g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 5448, ((const char*) (__func__)), "CTK_IS_WIDGET (widget)")
; } while (0)
;
5449
5450 baul_icon_container_search_dialog_hide (widget, container);
5451
5452 if (event->window == ctk_layout_get_bin_window (CTK_LAYOUT (container)((((CtkLayout*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_layout_get_type ()))))))
))
5453 {
5454 button_press_event (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
, event);
5455 }
5456
5457 return TRUE(!(0));
5458}
5459
5460static void
5461baul_icon_container_get_icon_text (BaulIconContainer *container,
5462 BaulIconData *data,
5463 char **editable_text,
5464 char **additional_text,
5465 gboolean include_invisible)
5466{
5467 BaulIconContainerClass *klass;
5468
5469 klass = BAUL_ICON_CONTAINER_GET_CLASS (container)((((BaulIconContainerClass*) (((GTypeInstance*) ((container))
)->g_class))))
;
5470 g_assert (klass->get_icon_text != NULL)do { if (klass->get_icon_text != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-icon-container.c", 5470, ((const char*)
(__func__)), "klass->get_icon_text != NULL"); } while (0)
;
5471
5472 klass->get_icon_text (container, data, editable_text, additional_text, include_invisible);
5473}
5474
5475static gboolean
5476baul_icon_container_search_iter (BaulIconContainer *container,
5477 const char *key, gint n)
5478{
5479 GList *p;
5480 BaulIcon *icon;
5481 char *name;
5482 int count;
5483 char *normalized_key, *case_normalized_key;
5484 char *normalized_name, *case_normalized_name;
5485
5486 g_assert (key != NULL)do { if (key != ((void*)0)) ; else g_assertion_message_expr (
((gchar*) 0), "baul-icon-container.c", 5486, ((const char*) (
__func__)), "key != NULL"); } while (0)
;
5487 g_assert (n >= 1)do { if (n >= 1) ; else g_assertion_message_expr (((gchar*
) 0), "baul-icon-container.c", 5487, ((const char*) (__func__
)), "n >= 1"); } while (0)
;
5488
5489 normalized_key = g_utf8_normalize (key, -1, G_NORMALIZE_ALL);
5490 if (!normalized_key)
5491 {
5492 return FALSE(0);
5493 }
5494 case_normalized_key = g_utf8_casefold (normalized_key, -1);
5495 g_free (normalized_key);
5496 if (!case_normalized_key)
5497 {
5498 return FALSE(0);
5499 }
5500
5501 icon = NULL((void*)0);
5502 name = NULL((void*)0);
5503 count = 0;
5504 for (p = container->details->icons; p != NULL((void*)0) && count != n; p = p->next)
5505 {
5506 icon = p->data;
5507 baul_icon_container_get_icon_text (container, icon->data, &name,
5508 NULL((void*)0), TRUE(!(0)));
5509
5510 /* This can happen if a key event is handled really early while
5511 * loading the icon container, before the items have all been
5512 * updated once.
5513 */
5514 if (!name)
5515 {
5516 continue;
5517 }
5518
5519 normalized_name = g_utf8_normalize (name, -1, G_NORMALIZE_ALL);
5520 if (!normalized_name)
5521 {
5522 continue;
5523 }
5524 case_normalized_name = g_utf8_casefold (normalized_name, -1);
5525 g_free (normalized_name);
5526 if (!case_normalized_name)
5527 {
5528 continue;
5529 }
5530
5531 if (strncmp (case_normalized_key, case_normalized_name,
5532 strlen (case_normalized_key)) == 0)
5533 {
5534 count++;
5535 }
5536
5537 g_free (case_normalized_name);
5538 g_free (name);
5539 name = NULL((void*)0);
5540 }
5541
5542 g_free (case_normalized_key);
5543
5544 if (count == n)
5545 {
5546 if (select_one_unselect_others (container, icon))
5547 {
5548 g_signal_emit (container, signals[SELECTION_CHANGED], 0);
5549 }
5550 schedule_keyboard_icon_reveal (container, icon);
5551
5552 return TRUE(!(0));
5553 }
5554
5555 return FALSE(0);
5556}
5557
5558static void
5559baul_icon_container_search_move (CtkWidget *window G_GNUC_UNUSED__attribute__ ((__unused__)),
5560 BaulIconContainer *container,
5561 gboolean up)
5562{
5563 gboolean ret;
5564 gint len;
5565 const gchar *text;
5566
5567 text = ctk_entry_get_text (CTK_ENTRY (container->details->search_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container->details->search_entry)), ((ctk_entry_get_type
()))))))
);
5568
5569 g_assert (text != NULL)do { if (text != ((void*)0)) ; else g_assertion_message_expr (
((gchar*) 0), "baul-icon-container.c", 5569, ((const char*) (
__func__)), "text != NULL"); } while (0)
;
5570
5571 if (container->details->selected_iter == 0)
5572 {
5573 return;
5574 }
5575
5576 if (up && container->details->selected_iter == 1)
5577 {
5578 return;
5579 }
5580
5581 len = strlen (text);
5582
5583 if (len < 1)
5584 {
5585 return;
5586 }
5587
5588 /* search */
5589 unselect_all (container);
5590
5591 ret = baul_icon_container_search_iter (container, text,
5592 up?((container->details->selected_iter) - 1):((container->details->selected_iter + 1)));
5593
5594 if (ret)
5595 {
5596 /* found */
5597 container->details->selected_iter += up?(-1):(1);
5598 }
5599 else
5600 {
5601 /* return to old iter */
5602 baul_icon_container_search_iter (container, text,
5603 container->details->selected_iter);
5604 }
5605}
5606
5607static gboolean
5608baul_icon_container_search_scroll_event (CtkWidget *widget,
5609 CdkEventScroll *event,
5610 BaulIconContainer *container)
5611{
5612 gboolean retval = FALSE(0);
5613
5614 if (event->direction == CDK_SCROLL_UP)
5615 {
5616 baul_icon_container_search_move (widget, container, TRUE(!(0)));
5617 retval = TRUE(!(0));
5618 }
5619 else if (event->direction == CDK_SCROLL_DOWN)
5620 {
5621 baul_icon_container_search_move (widget, container, FALSE(0));
5622 retval = TRUE(!(0));
5623 }
5624
5625 /* renew the flush timeout */
5626 if (retval && container->details->typeselect_flush_timeout)
5627 {
5628 g_source_remove (container->details->typeselect_flush_timeout);
5629 container->details->typeselect_flush_timeout =
5630 g_timeout_add_seconds (BAUL_ICON_CONTAINER_SEARCH_DIALOG_TIMEOUT5,
5631 (GSourceFunc) baul_icon_container_search_entry_flush_timeout,
5632 container);
5633 }
5634
5635 return retval;
5636}
5637
5638static gboolean
5639baul_icon_container_search_key_press_event (CtkWidget *widget,
5640 CdkEventKey *event,
5641 BaulIconContainer *container)
5642{
5643 gboolean retval = FALSE(0);
5644
5645 g_assert (CTK_IS_WIDGET (widget))do { if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((widget)); GType __t = ((ctk_widget_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) ; else
g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 5645, ((const char*) (__func__)), "CTK_IS_WIDGET (widget)")
; } while (0)
;
5646 g_assert (BAUL_IS_ICON_CONTAINER (container))do { if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 5646, ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); } while (0)
;
5647
5648 /* close window and cancel the search */
5649 if (event->keyval == CDK_KEY_Escape0xff1b || event->keyval == CDK_KEY_Tab0xff09)
5650 {
5651 baul_icon_container_search_dialog_hide (widget, container);
5652 return TRUE(!(0));
5653 }
5654
5655 /* close window and activate alternate */
5656 if (event->keyval == CDK_KEY_Return0xff0d && event->state & CDK_SHIFT_MASK)
5657 {
5658 baul_icon_container_search_dialog_hide (widget,
5659 container);
5660
5661 activate_selected_items_alternate (container, NULL((void*)0));
5662 return TRUE(!(0));
5663 }
5664
5665 /* select previous matching iter */
5666 if (event->keyval == CDK_KEY_Up0xff52 || event->keyval == CDK_KEY_KP_Up0xff97)
5667 {
5668 baul_icon_container_search_move (widget, container, TRUE(!(0)));
5669 retval = TRUE(!(0));
5670 }
5671
5672 if (((event->state & (CDK_CONTROL_MASK | CDK_SHIFT_MASK)) == (CDK_CONTROL_MASK | CDK_SHIFT_MASK))
5673 && (event->keyval == CDK_KEY_g0x067 || event->keyval == CDK_KEY_G0x047))
5674 {
5675 baul_icon_container_search_move (widget, container, TRUE(!(0)));
5676 retval = TRUE(!(0));
5677 }
5678
5679 /* select next matching iter */
5680 if (event->keyval == CDK_KEY_Down0xff54 || event->keyval == CDK_KEY_KP_Down0xff99)
5681 {
5682 baul_icon_container_search_move (widget, container, FALSE(0));
5683 retval = TRUE(!(0));
5684 }
5685
5686 if (((event->state & (CDK_CONTROL_MASK | CDK_SHIFT_MASK)) == CDK_CONTROL_MASK)
5687 && (event->keyval == CDK_KEY_g0x067 || event->keyval == CDK_KEY_G0x047))
5688 {
5689 baul_icon_container_search_move (widget, container, FALSE(0));
5690 retval = TRUE(!(0));
5691 }
5692
5693 /* renew the flush timeout */
5694 if (retval && container->details->typeselect_flush_timeout)
5695 {
5696 g_source_remove (container->details->typeselect_flush_timeout);
5697 container->details->typeselect_flush_timeout =
5698 g_timeout_add_seconds (BAUL_ICON_CONTAINER_SEARCH_DIALOG_TIMEOUT5,
5699 (GSourceFunc) baul_icon_container_search_entry_flush_timeout,
5700 container);
5701 }
5702
5703 return retval;
5704}
5705
5706static void
5707baul_icon_container_search_init (CtkWidget *entry,
5708 BaulIconContainer *container)
5709{
5710 gint ret;
5711 gint len;
5712 const gchar *text;
5713
5714 g_assert (CTK_IS_ENTRY (entry))do { if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((entry)); GType __t = ((ctk_entry_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))) ; else
g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 5714, ((const char*) (__func__)), "CTK_IS_ENTRY (entry)"); }
while (0)
;
5715 g_assert (BAUL_IS_ICON_CONTAINER (container))do { if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 5715, ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); } while (0)
;
5716
5717 text = ctk_entry_get_text (CTK_ENTRY (entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((entry)), ((ctk_entry_get_type ()))))))
);
5718 len = strlen (text);
5719
5720 /* search */
5721 unselect_all (container);
5722 if (container->details->typeselect_flush_timeout)
5723 {
5724 g_source_remove (container->details->typeselect_flush_timeout);
5725 container->details->typeselect_flush_timeout =
5726 g_timeout_add_seconds (BAUL_ICON_CONTAINER_SEARCH_DIALOG_TIMEOUT5,
5727 (GSourceFunc) baul_icon_container_search_entry_flush_timeout,
5728 container);
5729 }
5730
5731 if (len < 1)
5732 {
5733 return;
5734 }
5735
5736 ret = baul_icon_container_search_iter (container, text, 1);
5737
5738 if (ret)
5739 {
5740 container->details->selected_iter = 1;
5741 }
5742}
5743
5744static void
5745baul_icon_container_ensure_interactive_directory (BaulIconContainer *container)
5746{
5747 CtkWidget *frame, *vbox;
5748
5749 if (container->details->search_window != NULL((void*)0))
5750 {
5751 return;
5752 }
5753
5754 container->details->search_window = ctk_window_new (CTK_WINDOW_POPUP);
5755
5756 ctk_window_set_modal (CTK_WINDOW (container->details->search_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container->details->search_window)), ((ctk_window_get_type
()))))))
, TRUE(!(0)));
5757 ctk_window_set_type_hint (CTK_WINDOW (container->details->search_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container->details->search_window)), ((ctk_window_get_type
()))))))
,
5758 CDK_WINDOW_TYPE_HINT_COMBO);
5759
5760 g_signal_connect (container->details->search_window, "delete_event",g_signal_connect_data ((container->details->search_window
), ("delete_event"), (((GCallback) (baul_icon_container_search_delete_event
))), (container), ((void*)0), (GConnectFlags) 0)
5761 G_CALLBACK (baul_icon_container_search_delete_event),g_signal_connect_data ((container->details->search_window
), ("delete_event"), (((GCallback) (baul_icon_container_search_delete_event
))), (container), ((void*)0), (GConnectFlags) 0)
5762 container)g_signal_connect_data ((container->details->search_window
), ("delete_event"), (((GCallback) (baul_icon_container_search_delete_event
))), (container), ((void*)0), (GConnectFlags) 0)
;
5763 g_signal_connect (container->details->search_window, "key_press_event",g_signal_connect_data ((container->details->search_window
), ("key_press_event"), (((GCallback) (baul_icon_container_search_key_press_event
))), (container), ((void*)0), (GConnectFlags) 0)
5764 G_CALLBACK (baul_icon_container_search_key_press_event),g_signal_connect_data ((container->details->search_window
), ("key_press_event"), (((GCallback) (baul_icon_container_search_key_press_event
))), (container), ((void*)0), (GConnectFlags) 0)
5765 container)g_signal_connect_data ((container->details->search_window
), ("key_press_event"), (((GCallback) (baul_icon_container_search_key_press_event
))), (container), ((void*)0), (GConnectFlags) 0)
;
5766 g_signal_connect (container->details->search_window, "button_press_event",g_signal_connect_data ((container->details->search_window
), ("button_press_event"), (((GCallback) (baul_icon_container_search_button_press_event
))), (container), ((void*)0), (GConnectFlags) 0)
5767 G_CALLBACK (baul_icon_container_search_button_press_event),g_signal_connect_data ((container->details->search_window
), ("button_press_event"), (((GCallback) (baul_icon_container_search_button_press_event
))), (container), ((void*)0), (GConnectFlags) 0)
5768 container)g_signal_connect_data ((container->details->search_window
), ("button_press_event"), (((GCallback) (baul_icon_container_search_button_press_event
))), (container), ((void*)0), (GConnectFlags) 0)
;
5769 g_signal_connect (container->details->search_window, "scroll_event",g_signal_connect_data ((container->details->search_window
), ("scroll_event"), (((GCallback) (baul_icon_container_search_scroll_event
))), (container), ((void*)0), (GConnectFlags) 0)
5770 G_CALLBACK (baul_icon_container_search_scroll_event),g_signal_connect_data ((container->details->search_window
), ("scroll_event"), (((GCallback) (baul_icon_container_search_scroll_event
))), (container), ((void*)0), (GConnectFlags) 0)
5771 container)g_signal_connect_data ((container->details->search_window
), ("scroll_event"), (((GCallback) (baul_icon_container_search_scroll_event
))), (container), ((void*)0), (GConnectFlags) 0)
;
5772
5773 frame = ctk_frame_new (NULL((void*)0));
5774 ctk_frame_set_shadow_type (CTK_FRAME (frame)((((CtkFrame*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((frame)), ((ctk_frame_get_type ()))))))
, CTK_SHADOW_ETCHED_IN);
5775 ctk_widget_show (frame);
5776 ctk_container_add (CTK_CONTAINER (container->details->search_window)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container->details->search_window)), ((ctk_container_get_type
()))))))
, frame);
5777
5778 vbox = ctk_box_new (CTK_ORIENTATION_VERTICAL, 0);
5779 ctk_widget_show (vbox);
5780 ctk_container_add (CTK_CONTAINER (frame)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((frame)), ((ctk_container_get_type ()))))))
, vbox);
5781 ctk_container_set_border_width (CTK_CONTAINER (vbox)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((vbox)), ((ctk_container_get_type ()))))))
, 3);
5782
5783 /* add entry */
5784 container->details->search_entry = ctk_entry_new ();
5785 ctk_widget_show (container->details->search_entry);
5786 g_signal_connect (container->details->search_entry, "populate_popup",g_signal_connect_data ((container->details->search_entry
), ("populate_popup"), (((GCallback) (baul_icon_container_search_disable_popdown
))), (container), ((void*)0), (GConnectFlags) 0)
5787 G_CALLBACK (baul_icon_container_search_disable_popdown),g_signal_connect_data ((container->details->search_entry
), ("populate_popup"), (((GCallback) (baul_icon_container_search_disable_popdown
))), (container), ((void*)0), (GConnectFlags) 0)
5788 container)g_signal_connect_data ((container->details->search_entry
), ("populate_popup"), (((GCallback) (baul_icon_container_search_disable_popdown
))), (container), ((void*)0), (GConnectFlags) 0)
;
5789 g_signal_connect (container->details->search_entry, "activate",g_signal_connect_data ((container->details->search_entry
), ("activate"), (((GCallback) (baul_icon_container_search_activate
))), (container), ((void*)0), (GConnectFlags) 0)
5790 G_CALLBACK (baul_icon_container_search_activate),g_signal_connect_data ((container->details->search_entry
), ("activate"), (((GCallback) (baul_icon_container_search_activate
))), (container), ((void*)0), (GConnectFlags) 0)
5791 container)g_signal_connect_data ((container->details->search_entry
), ("activate"), (((GCallback) (baul_icon_container_search_activate
))), (container), ((void*)0), (GConnectFlags) 0)
;
5792 g_signal_connect (container->details->search_entry,g_signal_connect_data ((container->details->search_entry
), ("preedit-changed"), (((GCallback) (baul_icon_container_search_preedit_changed
))), (container), ((void*)0), (GConnectFlags) 0)
5793 "preedit-changed",g_signal_connect_data ((container->details->search_entry
), ("preedit-changed"), (((GCallback) (baul_icon_container_search_preedit_changed
))), (container), ((void*)0), (GConnectFlags) 0)
5794 G_CALLBACK (baul_icon_container_search_preedit_changed),g_signal_connect_data ((container->details->search_entry
), ("preedit-changed"), (((GCallback) (baul_icon_container_search_preedit_changed
))), (container), ((void*)0), (GConnectFlags) 0)
5795 container)g_signal_connect_data ((container->details->search_entry
), ("preedit-changed"), (((GCallback) (baul_icon_container_search_preedit_changed
))), (container), ((void*)0), (GConnectFlags) 0)
;
5796 ctk_container_add (CTK_CONTAINER (vbox)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((vbox)), ((ctk_container_get_type ()))))))
, container->details->search_entry);
5797
5798 ctk_widget_realize (container->details->search_entry);
5799}
5800
5801/* Pops up the interactive search entry. If keybinding is TRUE then the user
5802 * started this by typing the start_interactive_search keybinding. Otherwise, it came from
5803 */
5804static gboolean
5805baul_icon_container_real_start_interactive_search (BaulIconContainer *container,
5806 gboolean keybinding)
5807{
5808 /* We only start interactive search if we have focus. If one of our
5809 * children have focus, we don't want to start the search.
5810 */
5811 CtkWidgetClass *entry_parent_class;
5812
5813 if (container->details->search_window != NULL((void*)0) &&
5814 ctk_widget_get_visible (container->details->search_window))
5815 {
5816 return TRUE(!(0));
5817 }
5818
5819 if (!ctk_widget_has_focus (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
))
5820 {
5821 return FALSE(0);
5822 }
5823
5824 baul_icon_container_ensure_interactive_directory (container);
5825
5826 if (keybinding)
5827 {
5828 ctk_entry_set_text (CTK_ENTRY (container->details->search_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container->details->search_entry)), ((ctk_entry_get_type
()))))))
, "");
5829 }
5830
5831 /* done, show it */
5832 baul_icon_container_search_position_func (container, container->details->search_window);
5833 ctk_widget_show (container->details->search_window);
5834 if (container->details->search_entry_changed_id == 0)
5835 {
5836 container->details->search_entry_changed_id =
5837 g_signal_connect (container->details->search_entry, "changed",g_signal_connect_data ((container->details->search_entry
), ("changed"), (((GCallback) (baul_icon_container_search_init
))), (container), ((void*)0), (GConnectFlags) 0)
5838 G_CALLBACK (baul_icon_container_search_init),g_signal_connect_data ((container->details->search_entry
), ("changed"), (((GCallback) (baul_icon_container_search_init
))), (container), ((void*)0), (GConnectFlags) 0)
5839 container)g_signal_connect_data ((container->details->search_entry
), ("changed"), (((GCallback) (baul_icon_container_search_init
))), (container), ((void*)0), (GConnectFlags) 0)
;
5840 }
5841
5842 container->details->typeselect_flush_timeout =
5843 g_timeout_add_seconds (BAUL_ICON_CONTAINER_SEARCH_DIALOG_TIMEOUT5,
5844 (GSourceFunc) baul_icon_container_search_entry_flush_timeout,
5845 container);
5846
5847 /* Grab focus will select all the text. We don't want that to happen, so we
5848 * call the parent instance and bypass the selection change. This is probably
5849 * really non-kosher. */
5850 entry_parent_class = g_type_class_peek_parent (CTK_ENTRY_GET_CLASS (container->details->search_entry)((((CtkEntryClass*) (((GTypeInstance*) ((container->details
->search_entry)))->g_class))))
);
5851 (entry_parent_class->grab_focus) (container->details->search_entry);
5852
5853 /* send focus-in event */
5854 send_focus_change (container->details->search_entry, TRUE(!(0)));
5855
5856 /* search first matching iter */
5857 baul_icon_container_search_init (container->details->search_entry, container);
5858
5859 return TRUE(!(0));
5860}
5861
5862static gboolean
5863baul_icon_container_start_interactive_search (BaulIconContainer *container)
5864{
5865 return baul_icon_container_real_start_interactive_search (container, TRUE(!(0)));
5866}
5867
5868static gboolean
5869handle_popups (BaulIconContainer *container,
5870 CdkEventKey *event G_GNUC_UNUSED__attribute__ ((__unused__)),
5871 const char *signal)
5872{
5873 CdkEventButton button_event = { 0 };
5874
5875 g_signal_emit_by_name (container, signal, &button_event);
5876
5877 return TRUE(!(0));
5878}
5879
5880static int
5881key_press_event (CtkWidget *widget,
5882 CdkEventKey *event)
5883{
5884 BaulIconContainer *container;
5885 gboolean handled;
5886
5887 container = BAUL_ICON_CONTAINER (widget)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((widget)), (baul_icon_container_get_type())
))))
;
5888 handled = FALSE(0);
5889
5890 if (is_renaming (container) || is_renaming_pending (container))
5891 {
5892 switch (event->keyval)
5893 {
5894 case CDK_KEY_Return0xff0d:
5895 case CDK_KEY_KP_Enter0xff8d:
5896 end_renaming_mode (container, TRUE(!(0)));
5897 handled = TRUE(!(0));
5898 break;
5899 case CDK_KEY_Escape0xff1b:
5900 end_renaming_mode (container, FALSE(0));
5901 handled = TRUE(!(0));
5902 break;
5903 default:
5904 break;
5905 }
5906 }
5907 else
5908 {
5909 switch (event->keyval)
5910 {
5911 case CDK_KEY_Home0xff50:
5912 case CDK_KEY_KP_Home0xff95:
5913 keyboard_home (container, event);
5914 handled = TRUE(!(0));
5915 break;
5916 case CDK_KEY_End0xff57:
5917 case CDK_KEY_KP_End0xff9c:
5918 keyboard_end (container, event);
5919 handled = TRUE(!(0));
5920 break;
5921 case CDK_KEY_Left0xff51:
5922 case CDK_KEY_KP_Left0xff96:
5923 /* Don't eat Alt-Left, as that is used for history browsing */
5924 if ((event->state & CDK_MOD1_MASK) == 0)
5925 {
5926 keyboard_left (container, event);
5927 handled = TRUE(!(0));
5928 }
5929 break;
5930 case CDK_KEY_Up0xff52:
5931 case CDK_KEY_KP_Up0xff97:
5932 /* Don't eat Alt-Up, as that is used for alt-shift-Up */
5933 if ((event->state & CDK_MOD1_MASK) == 0)
5934 {
5935 keyboard_up (container, event);
5936 handled = TRUE(!(0));
5937 }
5938 break;
5939 case CDK_KEY_Right0xff53:
5940 case CDK_KEY_KP_Right0xff98:
5941 /* Don't eat Alt-Right, as that is used for history browsing */
5942 if ((event->state & CDK_MOD1_MASK) == 0)
5943 {
5944 keyboard_right (container, event);
5945 handled = TRUE(!(0));
5946 }
5947 break;
5948 case CDK_KEY_Down0xff54:
5949 case CDK_KEY_KP_Down0xff99:
5950 /* Don't eat Alt-Down, as that is used for Open */
5951 if ((event->state & CDK_MOD1_MASK) == 0)
5952 {
5953 keyboard_down (container, event);
5954 handled = TRUE(!(0));
5955 }
5956 break;
5957 case CDK_KEY_space0x020:
5958 keyboard_space (container, event);
5959 handled = TRUE(!(0));
5960 break;
5961#ifndef TAB_NAVIGATION_DISABLED
5962 case CDK_KEY_Tab0xff09:
5963 case CDK_KEY_ISO_Left_Tab0xfe20:
5964 select_previous_or_next_icon (container,
5965 (event->state & CDK_SHIFT_MASK) == 0, event);
5966 handled = TRUE(!(0));
5967 break;
5968#endif
5969 case CDK_KEY_Return0xff0d:
5970 case CDK_KEY_KP_Enter0xff8d:
5971 if ((event->state & CDK_SHIFT_MASK) != 0)
5972 {
5973 activate_selected_items_alternate (container, NULL((void*)0));
5974 }
5975 else
5976 {
5977 activate_selected_items (container);
5978 }
5979
5980 handled = TRUE(!(0));
5981 break;
5982 case CDK_KEY_Escape0xff1b:
5983 handled = undo_stretching (container);
5984 break;
5985 case CDK_KEY_plus0x02b:
5986 case CDK_KEY_minus0x02d:
5987 case CDK_KEY_equal0x03d:
5988 case CDK_KEY_KP_Add0xffab:
5989 case CDK_KEY_KP_Subtract0xffad:
5990 case CDK_KEY_00x030:
5991 case CDK_KEY_KP_00xffb0:
5992 if (event->state & CDK_CONTROL_MASK)
5993 {
5994 handled = keyboard_stretching (container, event);
5995 }
5996 break;
5997 case CDK_KEY_F100xffc7:
5998 /* handle Ctrl+F10 because we want to display the
5999 * background popup even if something is selected.
6000 * The other cases are handled by popup_menu().
6001 */
6002 if (event->state & CDK_CONTROL_MASK)
6003 {
6004 handled = handle_popups (container, event,
6005 "context_click_background");
6006 }
6007 break;
6008 case CDK_KEY_v0x076:
6009 /* Eat Control + v to not enable type ahead */
6010 if ((event->state & CDK_CONTROL_MASK) != 0)
6011 {
6012 handled = TRUE(!(0));
6013 }
6014 break;
6015 default:
6016 break;
6017 }
6018 }
6019
6020 if (!handled)
6021 {
6022 handled = CTK_WIDGET_CLASS (baul_icon_container_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((baul_icon_container_parent_class)), ((ctk_widget_get_type
()))))))
->key_press_event (widget, event);
6023 }
6024
6025 /* We pass the event to the search_entry. If its text changes, then we
6026 * start the typeahead find capabilities.
6027 * Copied from BaulIconContainer */
6028 if (!handled &&
6029 event->keyval != CDK_KEY_slash0x02f /* don't steal slash key event, used for "go to" */ &&
6030 event->keyval != CDK_KEY_BackSpace0xff08 &&
6031 event->keyval != CDK_KEY_Delete0xffff)
6032 {
6033 CdkEvent *new_event;
6034 CdkWindow *window;
6035 char *old_text;
6036 const char *new_text;
6037 gboolean retval;
6038 CdkScreen *screen;
6039 gboolean text_modified;
6040 gulong popup_menu_id;
6041 gint scale;
6042
6043 baul_icon_container_ensure_interactive_directory (container);
6044
6045 /* Make a copy of the current text */
6046 old_text = g_strdup (ctk_entry_get_text (CTK_ENTRY (container->details->search_entry)))g_strdup_inline (ctk_entry_get_text (((((CtkEntry*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container->details->search_entry))
, ((ctk_entry_get_type ()))))))))
;
6047 new_event = cdk_event_copy ((CdkEvent *) event);
6048 window = ((CdkEventKey *) new_event)->window;
6049 ((CdkEventKey *) new_event)->window = ctk_widget_get_window (container->details->search_entry);
6050 ctk_widget_realize (container->details->search_window);
6051
6052 popup_menu_id = g_signal_connect (container->details->search_entry,g_signal_connect_data ((container->details->search_entry
), ("popup_menu"), (((GCallback) (ctk_true))), (((void*)0)), (
(void*)0), (GConnectFlags) 0)
6053 "popup_menu", G_CALLBACK (ctk_true), NULL)g_signal_connect_data ((container->details->search_entry
), ("popup_menu"), (((GCallback) (ctk_true))), (((void*)0)), (
(void*)0), (GConnectFlags) 0)
;
6054
6055 /* Move the entry off screen */
6056 screen = ctk_widget_get_screen (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
);
6057 scale = ctk_widget_get_scale_factor (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
);
6058 ctk_window_move (CTK_WINDOW (container->details->search_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container->details->search_window)), ((ctk_window_get_type
()))))))
,
6059 WidthOfScreen (cdk_x11_screen_get_xscreen (screen))((cdk_x11_screen_get_xscreen (screen))->width) / scale + 1,
6060 HeightOfScreen (cdk_x11_screen_get_xscreen (screen))((cdk_x11_screen_get_xscreen (screen))->height) / scale + 1);
6061 ctk_widget_show (container->details->search_window);
6062
6063 /* Send the event to the window. If the preedit_changed signal is emitted
6064 * during this event, we will set priv->imcontext_changed */
6065 container->details->imcontext_changed = FALSE(0);
6066 retval = ctk_widget_event (container->details->search_entry, new_event);
6067 ctk_widget_hide (container->details->search_window);
6068
6069 g_signal_handler_disconnect (container->details->search_entry,
6070 popup_menu_id);
6071
6072 /* We check to make sure that the entry tried to handle the text, and that
6073 * the text has changed. */
6074 new_text = ctk_entry_get_text (CTK_ENTRY (container->details->search_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container->details->search_entry)), ((ctk_entry_get_type
()))))))
);
6075 text_modified = strcmp (old_text, new_text) != 0;
6076 g_free (old_text);
6077 if (container->details->imcontext_changed || /* we're in a preedit */
6078 (retval && text_modified)) /* ...or the text was modified */
6079 {
6080 if (baul_icon_container_real_start_interactive_search (container, FALSE(0)))
6081 {
6082 ctk_widget_grab_focus (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
);
6083 return TRUE(!(0));
6084 }
6085 else
6086 {
6087 ctk_entry_set_text (CTK_ENTRY (container->details->search_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container->details->search_entry)), ((ctk_entry_get_type
()))))))
, "");
6088 return FALSE(0);
6089 }
6090 }
6091
6092 ((CdkEventKey *) new_event)->window = window;
6093 cdk_event_free (new_event);
6094 }
6095
6096 return handled;
6097}
6098
6099static gboolean
6100popup_menu (CtkWidget *widget)
6101{
6102 BaulIconContainer *container;
6103
6104 container = BAUL_ICON_CONTAINER (widget)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((widget)), (baul_icon_container_get_type())
))))
;
6105
6106 if (has_selection (container))
6107 {
6108 handle_popups (container, NULL((void*)0),
6109 "context_click_selection");
6110 }
6111 else
6112 {
6113 handle_popups (container, NULL((void*)0),
6114 "context_click_background");
6115 }
6116
6117 return TRUE(!(0));
6118}
6119
6120static void
6121draw_canvas_background (EelCanvas *canvas G_GNUC_UNUSED__attribute__ ((__unused__)),
6122 cairo_t *cr G_GNUC_UNUSED__attribute__ ((__unused__)))
6123{
6124 /* Don't chain up to the parent to avoid clearing and redrawing */
6125}
6126
6127static void
6128grab_notify_cb (CtkWidget *widget,
6129 gboolean was_grabbed)
6130{
6131 BaulIconContainer *container;
6132
6133 container = BAUL_ICON_CONTAINER (widget)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((widget)), (baul_icon_container_get_type())
))))
;
6134
6135 if (container->details->rubberband_info.active &&
6136 !was_grabbed)
6137 {
6138 /* we got a (un)grab-notify during rubberband.
6139 * This happens when a new modal dialog shows
6140 * up (e.g. authentication or an error). Stop
6141 * the rubberbanding so that we can handle the
6142 * dialog. */
6143 stop_rubberbanding (container);
6144 }
6145}
6146
6147static void
6148text_ellipsis_limit_changed_container_callback (gpointer callback_data)
6149{
6150 BaulIconContainer *container;
6151
6152 container = BAUL_ICON_CONTAINER (callback_data)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((callback_data)), (baul_icon_container_get_type
())))))
;
6153 invalidate_label_sizes (container);
6154 schedule_redo_layout (container);
6155}
6156
6157static GObject*
6158baul_icon_container_constructor (GType type,
6159 guint n_construct_params,
6160 GObjectConstructParam *construct_params)
6161{
6162 BaulIconContainer *container;
6163 GObject *object;
6164
6165 object = G_OBJECT_CLASS (baul_icon_container_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((baul_icon_container_parent_class)), (((GType) ((20) <<
(2))))))))
->constructor
6166 (type,
6167 n_construct_params,
6168 construct_params);
6169
6170 container = BAUL_ICON_CONTAINER (object)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((object)), (baul_icon_container_get_type())
))))
;
6171 if (baul_icon_container_get_is_desktop (container))
6172 {
6173 g_signal_connect_swapped (baul_desktop_preferences,g_signal_connect_data ((baul_desktop_preferences), ("changed::"
"text-ellipsis-limit"), (((GCallback) (text_ellipsis_limit_changed_container_callback
))), (container), ((void*)0), G_CONNECT_SWAPPED)
6174 "changed::" BAUL_PREFERENCES_DESKTOP_TEXT_ELLIPSIS_LIMIT,g_signal_connect_data ((baul_desktop_preferences), ("changed::"
"text-ellipsis-limit"), (((GCallback) (text_ellipsis_limit_changed_container_callback
))), (container), ((void*)0), G_CONNECT_SWAPPED)
6175 G_CALLBACK (text_ellipsis_limit_changed_container_callback),g_signal_connect_data ((baul_desktop_preferences), ("changed::"
"text-ellipsis-limit"), (((GCallback) (text_ellipsis_limit_changed_container_callback
))), (container), ((void*)0), G_CONNECT_SWAPPED)
6176 container)g_signal_connect_data ((baul_desktop_preferences), ("changed::"
"text-ellipsis-limit"), (((GCallback) (text_ellipsis_limit_changed_container_callback
))), (container), ((void*)0), G_CONNECT_SWAPPED)
;
6177 }
6178 else
6179 {
6180 g_signal_connect_swapped (baul_icon_view_preferences,g_signal_connect_data ((baul_icon_view_preferences), ("changed::"
"text-ellipsis-limit"), (((GCallback) (text_ellipsis_limit_changed_container_callback
))), (container), ((void*)0), G_CONNECT_SWAPPED)
6181 "changed::" BAUL_PREFERENCES_ICON_VIEW_TEXT_ELLIPSIS_LIMIT,g_signal_connect_data ((baul_icon_view_preferences), ("changed::"
"text-ellipsis-limit"), (((GCallback) (text_ellipsis_limit_changed_container_callback
))), (container), ((void*)0), G_CONNECT_SWAPPED)
6182 G_CALLBACK (text_ellipsis_limit_changed_container_callback),g_signal_connect_data ((baul_icon_view_preferences), ("changed::"
"text-ellipsis-limit"), (((GCallback) (text_ellipsis_limit_changed_container_callback
))), (container), ((void*)0), G_CONNECT_SWAPPED)
6183 container)g_signal_connect_data ((baul_icon_view_preferences), ("changed::"
"text-ellipsis-limit"), (((GCallback) (text_ellipsis_limit_changed_container_callback
))), (container), ((void*)0), G_CONNECT_SWAPPED)
;
6184 }
6185
6186 return object;
6187}
6188
6189/* Initialization. */
6190
6191static void
6192baul_icon_container_class_init (BaulIconContainerClass *class)
6193{
6194 CtkWidgetClass *widget_class;
6195 EelCanvasClass *canvas_class;
6196 CtkBindingSet *binding_set;
6197
6198 G_OBJECT_CLASS (class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((class)), (((GType) ((20) << (2))))))))
->constructor = baul_icon_container_constructor;
6199 G_OBJECT_CLASS (class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((class)), (((GType) ((20) << (2))))))))
->finalize = finalize;
6200
6201 CTK_WIDGET_CLASS (class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((class)), ((ctk_widget_get_type ()))))))
->destroy = destroy;
6202
6203 /* Signals. */
6204
6205 signals[SELECTION_CHANGED]
6206 = g_signal_new ("selection_changed",
6207 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6208 G_SIGNAL_RUN_LAST,
6209 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, selection_changed
))
6210 selection_changed)((glong) __builtin_offsetof(BaulIconContainerClass, selection_changed
))
,
6211 NULL((void*)0), NULL((void*)0),
6212 g_cclosure_marshal_VOID__VOID,
6213 G_TYPE_NONE((GType) ((1) << (2))), 0);
6214 signals[BUTTON_PRESS]
6215 = g_signal_new ("button_press",
6216 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6217 G_SIGNAL_RUN_LAST,
6218 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, button_press
))
6219 button_press)((glong) __builtin_offsetof(BaulIconContainerClass, button_press
))
,
6220 NULL((void*)0), NULL((void*)0),
6221 baul_marshal_BOOLEAN__POINTER,
6222 G_TYPE_BOOLEAN((GType) ((5) << (2))), 1,
6223 CDK_TYPE_EVENT(cdk_event_get_type ()));
6224 signals[ACTIVATE]
6225 = g_signal_new ("activate",
6226 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6227 G_SIGNAL_RUN_LAST,
6228 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, activate)
)
6229 activate)((glong) __builtin_offsetof(BaulIconContainerClass, activate)
)
,
6230 NULL((void*)0), NULL((void*)0),
6231 g_cclosure_marshal_VOID__POINTER,
6232 G_TYPE_NONE((GType) ((1) << (2))), 1,
6233 G_TYPE_POINTER((GType) ((17) << (2))));
6234 signals[ACTIVATE_ALTERNATE]
6235 = g_signal_new ("activate_alternate",
6236 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6237 G_SIGNAL_RUN_LAST,
6238 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, activate_alternate
))
6239 activate_alternate)((glong) __builtin_offsetof(BaulIconContainerClass, activate_alternate
))
,
6240 NULL((void*)0), NULL((void*)0),
6241 g_cclosure_marshal_VOID__POINTER,
6242 G_TYPE_NONE((GType) ((1) << (2))), 1,
6243 G_TYPE_POINTER((GType) ((17) << (2))));
6244 signals[CONTEXT_CLICK_SELECTION]
6245 = g_signal_new ("context_click_selection",
6246 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6247 G_SIGNAL_RUN_LAST,
6248 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, context_click_selection
))
6249 context_click_selection)((glong) __builtin_offsetof(BaulIconContainerClass, context_click_selection
))
,
6250 NULL((void*)0), NULL((void*)0),
6251 g_cclosure_marshal_VOID__POINTER,
6252 G_TYPE_NONE((GType) ((1) << (2))), 1,
6253 G_TYPE_POINTER((GType) ((17) << (2))));
6254 signals[CONTEXT_CLICK_BACKGROUND]
6255 = g_signal_new ("context_click_background",
6256 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6257 G_SIGNAL_RUN_LAST,
6258 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, context_click_background
))
6259 context_click_background)((glong) __builtin_offsetof(BaulIconContainerClass, context_click_background
))
,
6260 NULL((void*)0), NULL((void*)0),
6261 g_cclosure_marshal_VOID__POINTER,
6262 G_TYPE_NONE((GType) ((1) << (2))), 1,
6263 G_TYPE_POINTER((GType) ((17) << (2))));
6264 signals[MIDDLE_CLICK]
6265 = g_signal_new ("middle_click",
6266 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6267 G_SIGNAL_RUN_LAST,
6268 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, middle_click
))
6269 middle_click)((glong) __builtin_offsetof(BaulIconContainerClass, middle_click
))
,
6270 NULL((void*)0), NULL((void*)0),
6271 g_cclosure_marshal_VOID__POINTER,
6272 G_TYPE_NONE((GType) ((1) << (2))), 1,
6273 G_TYPE_POINTER((GType) ((17) << (2))));
6274 signals[ICON_POSITION_CHANGED]
6275 = g_signal_new ("icon_position_changed",
6276 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6277 G_SIGNAL_RUN_LAST,
6278 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, icon_position_changed
))
6279 icon_position_changed)((glong) __builtin_offsetof(BaulIconContainerClass, icon_position_changed
))
,
6280 NULL((void*)0), NULL((void*)0),
6281 baul_marshal_VOID__POINTER_POINTER,
6282 G_TYPE_NONE((GType) ((1) << (2))), 2,
6283 G_TYPE_POINTER((GType) ((17) << (2))),
6284 G_TYPE_POINTER((GType) ((17) << (2))));
6285 signals[ICON_TEXT_CHANGED]
6286 = g_signal_new ("icon_text_changed",
6287 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6288 G_SIGNAL_RUN_LAST,
6289 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, icon_text_changed
))
6290 icon_text_changed)((glong) __builtin_offsetof(BaulIconContainerClass, icon_text_changed
))
,
6291 NULL((void*)0), NULL((void*)0),
6292 baul_marshal_VOID__POINTER_STRING,
6293 G_TYPE_NONE((GType) ((1) << (2))), 2,
6294 G_TYPE_POINTER((GType) ((17) << (2))),
6295 G_TYPE_STRING((GType) ((16) << (2))));
6296 signals[ICON_STRETCH_STARTED]
6297 = g_signal_new ("icon_stretch_started",
6298 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6299 G_SIGNAL_RUN_LAST,
6300 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, icon_stretch_started
))
6301 icon_stretch_started)((glong) __builtin_offsetof(BaulIconContainerClass, icon_stretch_started
))
,
6302 NULL((void*)0), NULL((void*)0),
6303 g_cclosure_marshal_VOID__POINTER,
6304 G_TYPE_NONE((GType) ((1) << (2))), 1,
6305 G_TYPE_POINTER((GType) ((17) << (2))));
6306 signals[ICON_STRETCH_ENDED]
6307 = g_signal_new ("icon_stretch_ended",
6308 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6309 G_SIGNAL_RUN_LAST,
6310 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, icon_stretch_ended
))
6311 icon_stretch_ended)((glong) __builtin_offsetof(BaulIconContainerClass, icon_stretch_ended
))
,
6312 NULL((void*)0), NULL((void*)0),
6313 g_cclosure_marshal_VOID__POINTER,
6314 G_TYPE_NONE((GType) ((1) << (2))), 1,
6315 G_TYPE_POINTER((GType) ((17) << (2))));
6316 signals[RENAMING_ICON]
6317 = g_signal_new ("renaming_icon",
6318 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6319 G_SIGNAL_RUN_LAST,
6320 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, renaming_icon
))
6321 renaming_icon)((glong) __builtin_offsetof(BaulIconContainerClass, renaming_icon
))
,
6322 NULL((void*)0), NULL((void*)0),
6323 g_cclosure_marshal_VOID__POINTER,
6324 G_TYPE_NONE((GType) ((1) << (2))), 1,
6325 G_TYPE_POINTER((GType) ((17) << (2))));
6326 signals[GET_ICON_URI]
6327 = g_signal_new ("get_icon_uri",
6328 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6329 G_SIGNAL_RUN_LAST,
6330 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, get_icon_uri
))
6331 get_icon_uri)((glong) __builtin_offsetof(BaulIconContainerClass, get_icon_uri
))
,
6332 NULL((void*)0), NULL((void*)0),
6333 baul_marshal_STRING__POINTER,
6334 G_TYPE_STRING((GType) ((16) << (2))), 1,
6335 G_TYPE_POINTER((GType) ((17) << (2))));
6336 signals[GET_ICON_DROP_TARGET_URI]
6337 = g_signal_new ("get_icon_drop_target_uri",
6338 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6339 G_SIGNAL_RUN_LAST,
6340 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, get_icon_drop_target_uri
))
6341 get_icon_drop_target_uri)((glong) __builtin_offsetof(BaulIconContainerClass, get_icon_drop_target_uri
))
,
6342 NULL((void*)0), NULL((void*)0),
6343 baul_marshal_STRING__POINTER,
6344 G_TYPE_STRING((GType) ((16) << (2))), 1,
6345 G_TYPE_POINTER((GType) ((17) << (2))));
6346 signals[MOVE_COPY_ITEMS]
6347 = g_signal_new ("move_copy_items",
6348 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6349 G_SIGNAL_RUN_LAST,
6350 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, move_copy_items
))
6351 move_copy_items)((glong) __builtin_offsetof(BaulIconContainerClass, move_copy_items
))
,
6352 NULL((void*)0), NULL((void*)0),
6353 baul_marshal_VOID__POINTER_POINTER_POINTER_ENUM_INT_INT,
6354 G_TYPE_NONE((GType) ((1) << (2))), 6,
6355 G_TYPE_POINTER((GType) ((17) << (2))),
6356 G_TYPE_POINTER((GType) ((17) << (2))),
6357 G_TYPE_POINTER((GType) ((17) << (2))),
6358 CDK_TYPE_DRAG_ACTION(cdk_drag_action_get_type ()),
6359 G_TYPE_INT((GType) ((6) << (2))),
6360 G_TYPE_INT((GType) ((6) << (2))));
6361 signals[HANDLE_NETSCAPE_URL]
6362 = g_signal_new ("handle_netscape_url",
6363 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6364 G_SIGNAL_RUN_LAST,
6365 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, handle_netscape_url
))
6366 handle_netscape_url)((glong) __builtin_offsetof(BaulIconContainerClass, handle_netscape_url
))
,
6367 NULL((void*)0), NULL((void*)0),
6368 baul_marshal_VOID__STRING_STRING_ENUM_INT_INT,
6369 G_TYPE_NONE((GType) ((1) << (2))), 5,
6370 G_TYPE_STRING((GType) ((16) << (2))),
6371 G_TYPE_STRING((GType) ((16) << (2))),
6372 CDK_TYPE_DRAG_ACTION(cdk_drag_action_get_type ()),
6373 G_TYPE_INT((GType) ((6) << (2))),
6374 G_TYPE_INT((GType) ((6) << (2))));
6375 signals[HANDLE_URI_LIST]
6376 = g_signal_new ("handle_uri_list",
6377 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6378 G_SIGNAL_RUN_LAST,
6379 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, handle_uri_list
))
6380 handle_uri_list)((glong) __builtin_offsetof(BaulIconContainerClass, handle_uri_list
))
,
6381 NULL((void*)0), NULL((void*)0),
6382 baul_marshal_VOID__STRING_STRING_ENUM_INT_INT,
6383 G_TYPE_NONE((GType) ((1) << (2))), 5,
6384 G_TYPE_STRING((GType) ((16) << (2))),
6385 G_TYPE_STRING((GType) ((16) << (2))),
6386 CDK_TYPE_DRAG_ACTION(cdk_drag_action_get_type ()),
6387 G_TYPE_INT((GType) ((6) << (2))),
6388 G_TYPE_INT((GType) ((6) << (2))));
6389 signals[HANDLE_TEXT]
6390 = g_signal_new ("handle_text",
6391 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6392 G_SIGNAL_RUN_LAST,
6393 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, handle_text
))
6394 handle_text)((glong) __builtin_offsetof(BaulIconContainerClass, handle_text
))
,
6395 NULL((void*)0), NULL((void*)0),
6396 baul_marshal_VOID__STRING_STRING_ENUM_INT_INT,
6397 G_TYPE_NONE((GType) ((1) << (2))), 5,
6398 G_TYPE_STRING((GType) ((16) << (2))),
6399 G_TYPE_STRING((GType) ((16) << (2))),
6400 CDK_TYPE_DRAG_ACTION(cdk_drag_action_get_type ()),
6401 G_TYPE_INT((GType) ((6) << (2))),
6402 G_TYPE_INT((GType) ((6) << (2))));
6403 signals[HANDLE_RAW]
6404 = g_signal_new ("handle_raw",
6405 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6406 G_SIGNAL_RUN_LAST,
6407 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, handle_raw
))
6408 handle_raw)((glong) __builtin_offsetof(BaulIconContainerClass, handle_raw
))
,
6409 NULL((void*)0), NULL((void*)0),
6410 baul_marshal_VOID__POINTER_INT_STRING_STRING_ENUM_INT_INT,
6411 G_TYPE_NONE((GType) ((1) << (2))), 7,
6412 G_TYPE_POINTER((GType) ((17) << (2))),
6413 G_TYPE_INT((GType) ((6) << (2))),
6414 G_TYPE_STRING((GType) ((16) << (2))),
6415 G_TYPE_STRING((GType) ((16) << (2))),
6416 CDK_TYPE_DRAG_ACTION(cdk_drag_action_get_type ()),
6417 G_TYPE_INT((GType) ((6) << (2))),
6418 G_TYPE_INT((GType) ((6) << (2))));
6419 signals[GET_CONTAINER_URI]
6420 = g_signal_new ("get_container_uri",
6421 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6422 G_SIGNAL_RUN_LAST,
6423 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, get_container_uri
))
6424 get_container_uri)((glong) __builtin_offsetof(BaulIconContainerClass, get_container_uri
))
,
6425 NULL((void*)0), NULL((void*)0),
6426 baul_marshal_STRING__VOID,
6427 G_TYPE_STRING((GType) ((16) << (2))), 0);
6428 signals[CAN_ACCEPT_ITEM]
6429 = g_signal_new ("can_accept_item",
6430 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6431 G_SIGNAL_RUN_LAST,
6432 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, can_accept_item
))
6433 can_accept_item)((glong) __builtin_offsetof(BaulIconContainerClass, can_accept_item
))
,
6434 NULL((void*)0), NULL((void*)0),
6435 baul_marshal_INT__POINTER_STRING,
6436 G_TYPE_INT((GType) ((6) << (2))), 2,
6437 G_TYPE_POINTER((GType) ((17) << (2))),
6438 G_TYPE_STRING((GType) ((16) << (2))));
6439 signals[GET_STORED_ICON_POSITION]
6440 = g_signal_new ("get_stored_icon_position",
6441 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6442 G_SIGNAL_RUN_LAST,
6443 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, get_stored_icon_position
))
6444 get_stored_icon_position)((glong) __builtin_offsetof(BaulIconContainerClass, get_stored_icon_position
))
,
6445 NULL((void*)0), NULL((void*)0),
6446 baul_marshal_BOOLEAN__POINTER_POINTER,
6447 G_TYPE_BOOLEAN((GType) ((5) << (2))), 2,
6448 G_TYPE_POINTER((GType) ((17) << (2))),
6449 G_TYPE_POINTER((GType) ((17) << (2))));
6450 signals[GET_STORED_LAYOUT_TIMESTAMP]
6451 = g_signal_new ("get_stored_layout_timestamp",
6452 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6453 G_SIGNAL_RUN_LAST,
6454 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, get_stored_layout_timestamp
))
6455 get_stored_layout_timestamp)((glong) __builtin_offsetof(BaulIconContainerClass, get_stored_layout_timestamp
))
,
6456 NULL((void*)0), NULL((void*)0),
6457 baul_marshal_BOOLEAN__POINTER_POINTER,
6458 G_TYPE_BOOLEAN((GType) ((5) << (2))), 2,
6459 G_TYPE_POINTER((GType) ((17) << (2))),
6460 G_TYPE_POINTER((GType) ((17) << (2))));
6461 signals[STORE_LAYOUT_TIMESTAMP]
6462 = g_signal_new ("store_layout_timestamp",
6463 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6464 G_SIGNAL_RUN_LAST,
6465 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, store_layout_timestamp
))
6466 store_layout_timestamp)((glong) __builtin_offsetof(BaulIconContainerClass, store_layout_timestamp
))
,
6467 NULL((void*)0), NULL((void*)0),
6468 baul_marshal_BOOLEAN__POINTER_POINTER,
6469 G_TYPE_BOOLEAN((GType) ((5) << (2))), 2,
6470 G_TYPE_POINTER((GType) ((17) << (2))),
6471 G_TYPE_POINTER((GType) ((17) << (2))));
6472 signals[LAYOUT_CHANGED]
6473 = g_signal_new ("layout_changed",
6474 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6475 G_SIGNAL_RUN_LAST,
6476 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, layout_changed
))
6477 layout_changed)((glong) __builtin_offsetof(BaulIconContainerClass, layout_changed
))
,
6478 NULL((void*)0), NULL((void*)0),
6479 g_cclosure_marshal_VOID__VOID,
6480 G_TYPE_NONE((GType) ((1) << (2))), 0);
6481 signals[PREVIEW]
6482 = g_signal_new ("preview",
6483 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6484 G_SIGNAL_RUN_LAST,
6485 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, preview))
6486 preview)((glong) __builtin_offsetof(BaulIconContainerClass, preview)),
6487 NULL((void*)0), NULL((void*)0),
6488 baul_marshal_INT__POINTER_BOOLEAN,
6489 G_TYPE_INT((GType) ((6) << (2))), 2,
6490 G_TYPE_POINTER((GType) ((17) << (2))),
6491 G_TYPE_BOOLEAN((GType) ((5) << (2))));
6492 signals[BAND_SELECT_STARTED]
6493 = g_signal_new ("band_select_started",
6494 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6495 G_SIGNAL_RUN_LAST,
6496 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, band_select_started
))
6497 band_select_started)((glong) __builtin_offsetof(BaulIconContainerClass, band_select_started
))
,
6498 NULL((void*)0), NULL((void*)0),
6499 g_cclosure_marshal_VOID__VOID,
6500 G_TYPE_NONE((GType) ((1) << (2))), 0);
6501 signals[BAND_SELECT_ENDED]
6502 = g_signal_new ("band_select_ended",
6503 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6504 G_SIGNAL_RUN_LAST,
6505 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, band_select_ended
))
6506 band_select_ended)((glong) __builtin_offsetof(BaulIconContainerClass, band_select_ended
))
,
6507 NULL((void*)0), NULL((void*)0),
6508 g_cclosure_marshal_VOID__VOID,
6509 G_TYPE_NONE((GType) ((1) << (2))), 0);
6510 signals[ICON_ADDED]
6511 = g_signal_new ("icon_added",
6512 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6513 G_SIGNAL_RUN_LAST,
6514 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, icon_added
))
6515 icon_added)((glong) __builtin_offsetof(BaulIconContainerClass, icon_added
))
,
6516 NULL((void*)0), NULL((void*)0),
6517 g_cclosure_marshal_VOID__POINTER,
6518 G_TYPE_NONE((GType) ((1) << (2))), 1, G_TYPE_POINTER((GType) ((17) << (2))));
6519 signals[ICON_REMOVED]
6520 = g_signal_new ("icon_removed",
6521 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6522 G_SIGNAL_RUN_LAST,
6523 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, icon_removed
))
6524 icon_removed)((glong) __builtin_offsetof(BaulIconContainerClass, icon_removed
))
,
6525 NULL((void*)0), NULL((void*)0),
6526 g_cclosure_marshal_VOID__POINTER,
6527 G_TYPE_NONE((GType) ((1) << (2))), 1, G_TYPE_POINTER((GType) ((17) << (2))));
6528
6529 signals[CLEARED]
6530 = g_signal_new ("cleared",
6531 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6532 G_SIGNAL_RUN_LAST,
6533 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, cleared))
6534 cleared)((glong) __builtin_offsetof(BaulIconContainerClass, cleared)),
6535 NULL((void*)0), NULL((void*)0),
6536 g_cclosure_marshal_VOID__VOID,
6537 G_TYPE_NONE((GType) ((1) << (2))), 0);
6538
6539 signals[START_INTERACTIVE_SEARCH]
6540 = g_signal_new ("start_interactive_search",
6541 G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type),
6542 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
6543 G_STRUCT_OFFSET (BaulIconContainerClass,((glong) __builtin_offsetof(BaulIconContainerClass, start_interactive_search
))
6544 start_interactive_search)((glong) __builtin_offsetof(BaulIconContainerClass, start_interactive_search
))
,
6545 NULL((void*)0), NULL((void*)0),
6546 baul_marshal_BOOLEAN__VOID,
6547 G_TYPE_BOOLEAN((GType) ((5) << (2))), 0);
6548
6549 /* CtkWidget class. */
6550
6551 widget_class = CTK_WIDGET_CLASS (class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((class)), ((ctk_widget_get_type ()))))))
;
6552 widget_class->size_allocate = size_allocate;
6553 widget_class->get_request_mode = get_request_mode;
6554 widget_class->get_preferred_width = get_prefered_width;
6555 widget_class->get_preferred_height = get_prefered_height;
6556 widget_class->draw = draw;
6557 widget_class->realize = realize;
6558 widget_class->unrealize = unrealize;
6559 widget_class->button_press_event = button_press_event;
6560 widget_class->button_release_event = button_release_event;
6561 widget_class->motion_notify_event = motion_notify_event;
6562 widget_class->key_press_event = key_press_event;
6563 widget_class->popup_menu = popup_menu;
6564 widget_class->style_updated = style_updated;
6565 widget_class->grab_notify = grab_notify_cb;
6566
6567 ctk_widget_class_set_accessible_type (widget_class, baul_icon_container_accessible_get_type ());
6568
6569 canvas_class = EEL_CANVAS_CLASS (class)((((EelCanvasClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((class)), ((eel_canvas_get_type ()))))))
;
6570 canvas_class->draw_background = draw_canvas_background;
6571 class->start_interactive_search = baul_icon_container_start_interactive_search;
6572
6573 ctk_widget_class_install_style_property (widget_class,
6574 g_param_spec_boxed ("selection_box_rgba",
6575 "Selection Box RGBA",
6576 "Color of the selection box",
6577 CDK_TYPE_RGBA(cdk_rgba_get_type ()),
6578 G_PARAM_READABLE));
6579 ctk_widget_class_install_style_property (widget_class,
6580 g_param_spec_boxed ("light_info_rgba",
6581 "Light Info RGBA",
6582 "Color used for information text against a dark background",
6583 CDK_TYPE_RGBA(cdk_rgba_get_type ()),
6584 G_PARAM_READABLE));
6585 ctk_widget_class_install_style_property (widget_class,
6586 g_param_spec_boxed ("dark_info_rgba",
6587 "Dark Info RGBA",
6588 "Color used for information text against a light background",
6589 CDK_TYPE_RGBA(cdk_rgba_get_type ()),
6590 G_PARAM_READABLE));
6591 ctk_widget_class_install_style_property (widget_class,
6592 g_param_spec_boolean ("activate_prelight_icon_label",
6593 "Activate Prelight Icon Label",
6594 "Whether icon labels should make use of its prelight color in prelight state",
6595 FALSE(0),
6596 G_PARAM_READABLE));
6597
6598
6599 binding_set = ctk_binding_set_by_class (class);
6600
6601 ctk_binding_entry_add_signal (binding_set, CDK_KEY_f0x066, CDK_CONTROL_MASK, "start_interactive_search", 0);
6602 ctk_binding_entry_add_signal (binding_set, CDK_KEY_F0x046, CDK_CONTROL_MASK, "start_interactive_search", 0);
6603}
6604
6605static void
6606update_selected (BaulIconContainer *container)
6607{
6608 GList *node;
6609 BaulIcon *icon = NULL((void*)0);
6610
6611 for (node = container->details->icons; node != NULL((void*)0); node = node->next)
6612 {
6613 icon = node->data;
6614 if (icon->is_selected)
6615 {
6616 eel_canvas_item_request_update (EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
);
6617 }
6618 }
6619}
6620
6621static gboolean
6622handle_focus_in_event (CtkWidget *widget,
6623 CdkEventFocus *event G_GNUC_UNUSED__attribute__ ((__unused__)),
6624 gpointer user_data G_GNUC_UNUSED__attribute__ ((__unused__)))
6625{
6626 update_selected (BAUL_ICON_CONTAINER (widget)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((widget)), (baul_icon_container_get_type())
))))
);
6627
6628 return FALSE(0);
6629}
6630
6631static gboolean
6632handle_focus_out_event (CtkWidget *widget,
6633 CdkEventFocus *event G_GNUC_UNUSED__attribute__ ((__unused__)),
6634 gpointer user_data G_GNUC_UNUSED__attribute__ ((__unused__)))
6635{
6636 /* End renaming and commit change. */
6637 end_renaming_mode (BAUL_ICON_CONTAINER (widget)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((widget)), (baul_icon_container_get_type())
))))
, TRUE(!(0)));
6638 update_selected (BAUL_ICON_CONTAINER (widget)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((widget)), (baul_icon_container_get_type())
))))
);
6639
6640 return FALSE(0);
6641}
6642
6643static void
6644handle_scale_factor_changed (GObject *object,
6645 GParamSpec *pspec G_GNUC_UNUSED__attribute__ ((__unused__)),
6646 gpointer user_data G_GNUC_UNUSED__attribute__ ((__unused__)))
6647{
6648 invalidate_labels (BAUL_ICON_CONTAINER (object)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((object)), (baul_icon_container_get_type())
))))
);
6649 baul_icon_container_request_update_all (BAUL_ICON_CONTAINER (object)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((object)), (baul_icon_container_get_type())
))))
);
6650}
6651
6652
6653static int text_ellipsis_limits[BAUL_ZOOM_LEVEL_N_ENTRIES(BAUL_ZOOM_LEVEL_LARGEST + 1)];
6654static int desktop_text_ellipsis_limit;
6655
6656static gboolean
6657get_text_ellipsis_limit_for_zoom (char **strs,
6658 const char *zoom_level,
6659 int *limit)
6660{
6661 char *str;
6662 gboolean success;
6663
6664 success = FALSE(0);
6665
6666 /* default */
6667 *limit = 3;
6668
6669 if (zoom_level != NULL((void*)0))
6670 {
6671 str = g_strdup_printf ("%s:%%d", zoom_level);
6672 }
6673 else
6674 {
6675 str = g_strdup ("%d")g_strdup_inline ("%d");
6676 }
6677
6678 if (strs != NULL((void*)0))
6679 {
6680 char **p;
6681
6682 for (p = strs; *p != NULL((void*)0); p++)
6683 {
6684 if (sscanf (*p, str, limit))
6685 {
6686 success = TRUE(!(0));
6687 }
6688 }
6689 }
6690
6691 g_free (str);
6692
6693 return success;
6694}
6695
6696static const char * zoom_level_names[] = {
6697 "smallest",
6698 "smaller",
6699 "small",
6700 "standard",
6701 "large",
6702 "larger",
6703 "largest"
6704};
6705
6706static void
6707text_ellipsis_limit_changed_callback (gpointer callback_data G_GNUC_UNUSED__attribute__ ((__unused__)))
6708{
6709 char **pref;
6710 unsigned int i;
6711 int one_limit;
6712
6713 pref = g_settings_get_strv (baul_icon_view_preferences, BAUL_PREFERENCES_ICON_VIEW_TEXT_ELLIPSIS_LIMIT"text-ellipsis-limit");
6714
6715 /* set default */
6716 get_text_ellipsis_limit_for_zoom (pref, NULL((void*)0), &one_limit);
6717 for (i = 0; i < BAUL_ZOOM_LEVEL_N_ENTRIES(BAUL_ZOOM_LEVEL_LARGEST + 1); i++)
6718 {
6719 text_ellipsis_limits[i] = one_limit;
6720 }
6721
6722 /* override for each zoom level */
6723 for (i = 0; i < G_N_ELEMENTS(zoom_level_names)(sizeof (zoom_level_names) / sizeof ((zoom_level_names)[0])); i++) {
6724 if (get_text_ellipsis_limit_for_zoom (pref,
6725 zoom_level_names[i],
6726 &one_limit)) {
6727 text_ellipsis_limits[i] = one_limit;
6728 }
6729 }
6730
6731 g_strfreev (pref);
6732}
6733
6734static void
6735desktop_text_ellipsis_limit_changed_callback (gpointer callback_data G_GNUC_UNUSED__attribute__ ((__unused__)))
6736{
6737 int pref;
6738
6739 pref = g_settings_get_int (baul_desktop_preferences, BAUL_PREFERENCES_DESKTOP_TEXT_ELLIPSIS_LIMIT"text-ellipsis-limit");
6740 desktop_text_ellipsis_limit = pref;
6741}
6742
6743static void
6744baul_icon_container_init (BaulIconContainer *container)
6745{
6746 BaulIconContainerDetails *details;
6747 EelBackground *background;
6748 static gboolean setup_prefs = FALSE(0);
6749
6750 details = g_new0 (BaulIconContainerDetails, 1)((BaulIconContainerDetails *) g_malloc0_n ((1), sizeof (BaulIconContainerDetails
)))
;
6751
6752 details->icon_set = g_hash_table_new (g_direct_hash, g_direct_equal);
6753 details->layout_timestamp = UNDEFINED_TIME((time_t) (-1));
6754
6755 details->zoom_level = BAUL_ZOOM_LEVEL_STANDARD;
6756
6757 details->font_size_table[BAUL_ZOOM_LEVEL_SMALLEST] = -2 * PANGO_SCALE1024;
6758 details->font_size_table[BAUL_ZOOM_LEVEL_SMALLER] = -2 * PANGO_SCALE1024;
6759 details->font_size_table[BAUL_ZOOM_LEVEL_SMALL] = -0 * PANGO_SCALE1024;
6760 details->font_size_table[BAUL_ZOOM_LEVEL_STANDARD] = 0 * PANGO_SCALE1024;
6761 details->font_size_table[BAUL_ZOOM_LEVEL_LARGE] = 0 * PANGO_SCALE1024;
6762 details->font_size_table[BAUL_ZOOM_LEVEL_LARGER] = 0 * PANGO_SCALE1024;
6763 details->font_size_table[BAUL_ZOOM_LEVEL_LARGEST] = 0 * PANGO_SCALE1024;
6764
6765 container->details = details;
6766
6767 /* when the background changes, we must set up the label text color */
6768 background = eel_get_widget_background (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
);
6769
6770 g_signal_connect (container, "focus-in-event",g_signal_connect_data ((container), ("focus-in-event"), (((GCallback
) (handle_focus_in_event))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
6771 G_CALLBACK (handle_focus_in_event), NULL)g_signal_connect_data ((container), ("focus-in-event"), (((GCallback
) (handle_focus_in_event))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
;
6772 g_signal_connect (container, "focus-out-event",g_signal_connect_data ((container), ("focus-out-event"), (((GCallback
) (handle_focus_out_event))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
6773 G_CALLBACK (handle_focus_out_event), NULL)g_signal_connect_data ((container), ("focus-out-event"), (((GCallback
) (handle_focus_out_event))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
;
6774
6775 g_signal_connect (container, "notify::scale-factor",g_signal_connect_data ((container), ("notify::scale-factor"),
(((GCallback) (handle_scale_factor_changed))), (((void*)0)),
((void*)0), (GConnectFlags) 0)
6776 G_CALLBACK (handle_scale_factor_changed), NULL)g_signal_connect_data ((container), ("notify::scale-factor"),
(((GCallback) (handle_scale_factor_changed))), (((void*)0)),
((void*)0), (GConnectFlags) 0)
;
6777
6778 eel_background_set_use_base (background, TRUE(!(0)));
6779
6780 if (!setup_prefs)
6781 {
6782 g_signal_connect_swapped (baul_icon_view_preferences,g_signal_connect_data ((baul_icon_view_preferences), ("changed::"
"text-ellipsis-limit"), (((GCallback) (text_ellipsis_limit_changed_callback
))), (((void*)0)), ((void*)0), G_CONNECT_SWAPPED)
6783 "changed::" BAUL_PREFERENCES_ICON_VIEW_TEXT_ELLIPSIS_LIMIT,g_signal_connect_data ((baul_icon_view_preferences), ("changed::"
"text-ellipsis-limit"), (((GCallback) (text_ellipsis_limit_changed_callback
))), (((void*)0)), ((void*)0), G_CONNECT_SWAPPED)
6784 G_CALLBACK (text_ellipsis_limit_changed_callback),g_signal_connect_data ((baul_icon_view_preferences), ("changed::"
"text-ellipsis-limit"), (((GCallback) (text_ellipsis_limit_changed_callback
))), (((void*)0)), ((void*)0), G_CONNECT_SWAPPED)
6785 NULL)g_signal_connect_data ((baul_icon_view_preferences), ("changed::"
"text-ellipsis-limit"), (((GCallback) (text_ellipsis_limit_changed_callback
))), (((void*)0)), ((void*)0), G_CONNECT_SWAPPED)
;
6786 text_ellipsis_limit_changed_callback (NULL((void*)0));
6787
6788 g_signal_connect_swapped (baul_icon_view_preferences,g_signal_connect_data ((baul_icon_view_preferences), ("changed::"
"text-ellipsis-limit"), (((GCallback) (desktop_text_ellipsis_limit_changed_callback
))), (((void*)0)), ((void*)0), G_CONNECT_SWAPPED)
6789 "changed::" BAUL_PREFERENCES_DESKTOP_TEXT_ELLIPSIS_LIMIT,g_signal_connect_data ((baul_icon_view_preferences), ("changed::"
"text-ellipsis-limit"), (((GCallback) (desktop_text_ellipsis_limit_changed_callback
))), (((void*)0)), ((void*)0), G_CONNECT_SWAPPED)
6790 G_CALLBACK (desktop_text_ellipsis_limit_changed_callback),g_signal_connect_data ((baul_icon_view_preferences), ("changed::"
"text-ellipsis-limit"), (((GCallback) (desktop_text_ellipsis_limit_changed_callback
))), (((void*)0)), ((void*)0), G_CONNECT_SWAPPED)
6791 NULL)g_signal_connect_data ((baul_icon_view_preferences), ("changed::"
"text-ellipsis-limit"), (((GCallback) (desktop_text_ellipsis_limit_changed_callback
))), (((void*)0)), ((void*)0), G_CONNECT_SWAPPED)
;
6792 desktop_text_ellipsis_limit_changed_callback (NULL((void*)0));
6793
6794 setup_prefs = TRUE(!(0));
6795 }
6796}
6797
6798typedef struct
6799{
6800 BaulIconContainer *container;
6801 CdkEventButton *event;
6802} ContextMenuParameters;
6803
6804static gboolean
6805handle_icon_double_click (BaulIconContainer *container,
6806 BaulIcon *icon,
6807 CdkEventButton *event)
6808{
6809 BaulIconContainerDetails *details;
6810
6811 if (event->button != DRAG_BUTTON1)
6812 {
6813 return FALSE(0);
6814 }
6815
6816 details = container->details;
6817
6818 if (!details->single_click_mode &&
6819 clicked_within_double_click_interval (container) &&
6820 details->double_click_icon[0] == details->double_click_icon[1] &&
6821 details->double_click_button[0] == details->double_click_button[1])
6822 {
6823 if (!button_event_modifies_selection (event))
6824 {
6825 activate_selected_items (container);
6826 return TRUE(!(0));
6827 }
6828 else if ((event->state & CDK_CONTROL_MASK) == 0 &&
6829 (event->state & CDK_SHIFT_MASK) != 0)
6830 {
6831 activate_selected_items_alternate (container, icon);
6832 return TRUE(!(0));
6833 }
6834 }
6835
6836 return FALSE(0);
6837}
6838
6839/* BaulIcon event handling. */
6840
6841/* Conceptually, pressing button 1 together with CTRL or SHIFT toggles
6842 * selection of a single icon without affecting the other icons;
6843 * without CTRL or SHIFT, it selects a single icon and un-selects all
6844 * the other icons. But in this latter case, the de-selection should
6845 * only happen when the button is released if the icon is already
6846 * selected, because the user might select multiple icons and drag all
6847 * of them by doing a simple click-drag.
6848*/
6849
6850static gboolean
6851handle_icon_button_press (BaulIconContainer *container,
6852 BaulIcon *icon,
6853 CdkEventButton *event)
6854{
6855 BaulIconContainerDetails *details;
6856
6857 details = container->details;
6858
6859 if (event->type == CDK_2BUTTON_PRESS || event->type == CDK_3BUTTON_PRESS)
6860 {
6861 return TRUE(!(0));
6862 }
6863
6864 if (event->button != DRAG_BUTTON1
6865 && event->button != CONTEXTUAL_MENU_BUTTON3
6866 && event->button != DRAG_MENU_BUTTON2)
6867 {
6868 return TRUE(!(0));
6869 }
6870
6871 if ((event->button == DRAG_BUTTON1) &&
6872 event->type == CDK_BUTTON_PRESS)
6873 {
6874 /* The next double click has to be on this icon */
6875 details->double_click_icon[1] = details->double_click_icon[0];
6876 details->double_click_icon[0] = icon;
6877
6878 details->double_click_button[1] = details->double_click_button[0];
6879 details->double_click_button[0] = event->button;
6880 }
6881
6882 if (handle_icon_double_click (container, icon, event))
6883 {
6884 /* Double clicking does not trigger a D&D action. */
6885 details->drag_button = 0;
6886 details->drag_icon = NULL((void*)0);
6887 return TRUE(!(0));
6888 }
6889
6890 if (event->button == DRAG_BUTTON1
6891 || event->button == DRAG_MENU_BUTTON2)
6892 {
6893 details->drag_button = event->button;
6894 details->drag_icon = icon;
6895 details->drag_x = event->x;
6896 details->drag_y = event->y;
6897 details->drag_state = DRAG_STATE_MOVE_OR_COPY;
6898 details->drag_started = FALSE(0);
6899
6900 /* Check to see if this is a click on the stretch handles.
6901 * If so, it won't modify the selection.
6902 */
6903 if (icon == container->details->stretch_icon)
6904 {
6905 if (start_stretching (container, (CdkEvent *)event))
6906 {
6907 return TRUE(!(0));
6908 }
6909 }
6910 }
6911
6912 /* Modify the selection as appropriate. Selection is modified
6913 * the same way for contextual menu as it would be without.
6914 */
6915 details->icon_selected_on_button_down = icon->is_selected;
6916
6917 if ((event->button == DRAG_BUTTON1 || event->button == MIDDLE_BUTTON2) &&
6918 (event->state & CDK_SHIFT_MASK) != 0)
6919 {
6920 BaulIcon *start_icon;
6921
6922 start_icon = details->range_selection_base_icon;
6923 if (start_icon == NULL((void*)0) || !start_icon->is_selected)
6924 {
6925 start_icon = icon;
6926 details->range_selection_base_icon = icon;
6927 }
6928 if (select_range (container, start_icon, icon,
6929 (event->state & CDK_CONTROL_MASK) == 0))
6930 {
6931 g_signal_emit (container,
6932 signals[SELECTION_CHANGED], 0);
6933 }
6934 }
6935 else if (!details->icon_selected_on_button_down)
6936 {
6937 details->range_selection_base_icon = icon;
6938 if (button_event_modifies_selection (event))
6939 {
6940 icon_toggle_selected (container, icon);
6941 g_signal_emit (container,
6942 signals[SELECTION_CHANGED], 0);
6943 }
6944 else
6945 {
6946 select_one_unselect_others (container, icon);
6947 g_signal_emit (container,
6948 signals[SELECTION_CHANGED], 0);
6949 }
6950 }
6951
6952 if (event->button == CONTEXTUAL_MENU_BUTTON3)
6953 {
6954 g_signal_emit (container,
6955 signals[CONTEXT_CLICK_SELECTION], 0,
6956 event);
6957 }
6958
6959
6960 return TRUE(!(0));
6961}
6962
6963static int
6964item_event_callback (EelCanvasItem *item,
6965 CdkEvent *event,
6966 gpointer data)
6967{
6968 BaulIconContainer *container;
6969 BaulIcon *icon;
6970
6971 container = BAUL_ICON_CONTAINER (data)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((data)), (baul_icon_container_get_type())))
))
;
6972
6973 icon = BAUL_ICON_CANVAS_ITEM (item)((((BaulIconCanvasItem*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((item)), (baul_icon_canvas_item_get_type())
))))
->user_data;
6974 g_assert (icon != NULL)do { if (icon != ((void*)0)) ; else g_assertion_message_expr (
((gchar*) 0), "baul-icon-container.c", 6974, ((const char*) (
__func__)), "icon != NULL"); } while (0)
;
6975
6976 switch (event->type)
6977 {
6978 case CDK_BUTTON_PRESS:
6979 if (handle_icon_button_press (container, icon, &event->button))
6980 {
6981 /* Stop the event from being passed along further. Returning
6982 * TRUE ain't enough.
6983 */
6984 return TRUE(!(0));
6985 }
6986 return FALSE(0);
6987 default:
6988 return FALSE(0);
6989 }
6990}
6991
6992CtkWidget *
6993baul_icon_container_new (void)
6994{
6995 return ctk_widget_new (BAUL_TYPE_ICON_CONTAINERbaul_icon_container_get_type(), NULL((void*)0));
6996}
6997
6998/* Clear all of the icons in the container. */
6999void
7000baul_icon_container_clear (BaulIconContainer *container)
7001{
7002 BaulIconContainerDetails *details;
7003 GList *p;
7004
7005 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
7006
7007 details = container->details;
7008 details->layout_timestamp = UNDEFINED_TIME((time_t) (-1));
7009 details->store_layout_timestamps_when_finishing_new_icons = FALSE(0);
7010
7011 if (details->icons == NULL((void*)0))
7012 {
7013 return;
7014 }
7015
7016 end_renaming_mode (container, TRUE(!(0)));
7017
7018 clear_keyboard_focus (container);
7019 clear_keyboard_rubberband_start (container);
7020 unschedule_keyboard_icon_reveal (container);
7021 set_pending_icon_to_reveal (container, NULL((void*)0));
7022 details->stretch_icon = NULL((void*)0);
7023 details->drop_target = NULL((void*)0);
7024
7025 for (p = details->icons; p != NULL((void*)0); p = p->next)
7026 {
7027 icon_free (p->data);
7028 }
7029 g_list_free (details->icons);
7030 details->icons = NULL((void*)0);
7031 g_list_free (details->new_icons);
7032 details->new_icons = NULL((void*)0);
7033
7034 g_hash_table_destroy (details->icon_set);
7035 details->icon_set = g_hash_table_new (g_direct_hash, g_direct_equal);
7036
7037 baul_icon_container_update_scroll_region (container);
7038}
7039
7040gboolean
7041baul_icon_container_is_empty (BaulIconContainer *container)
7042{
7043 return container->details->icons == NULL((void*)0);
7044}
7045
7046BaulIconData *
7047baul_icon_container_get_first_visible_icon (BaulIconContainer *container)
7048{
7049 GList *l;
7050 BaulIcon *icon, *best_icon;
7051 double x, y;
7052 double x1, y1, x2, y2;
7053 double *pos, best_pos;
7054 double hadj_v, vadj_v, h_page_size;
7055 gboolean better_icon;
7056 gboolean compare_lt;
7057
7058 hadj_v = ctk_adjustment_get_value (ctk_scrollable_get_hadjustment (CTK_SCROLLABLE (container)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_scrollable_get_type ()))))))
));
7059 vadj_v = ctk_adjustment_get_value (ctk_scrollable_get_vadjustment (CTK_SCROLLABLE (container)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_scrollable_get_type ()))))))
));
7060 h_page_size = ctk_adjustment_get_page_size (ctk_scrollable_get_hadjustment (CTK_SCROLLABLE (container)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_scrollable_get_type ()))))))
));
7061
7062 if (baul_icon_container_is_layout_rtl (container))
7063 {
7064 x = hadj_v + h_page_size - ICON_PAD_LEFT4 - 1;
7065 y = vadj_v;
7066 }
7067 else
7068 {
7069 x = hadj_v;
7070 y = vadj_v;
7071 }
7072
7073 eel_canvas_c2w (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
,
7074 x, y,
7075 &x, &y);
7076
7077 l = container->details->icons;
7078 best_icon = NULL((void*)0);
7079 best_pos = 0;
7080 while (l != NULL((void*)0))
7081 {
7082 icon = l->data;
7083
7084 if (icon_is_positioned (icon))
7085 {
7086 eel_canvas_item_get_bounds (EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
,
7087 &x1, &y1, &x2, &y2);
7088
7089 compare_lt = FALSE(0);
7090 if (baul_icon_container_is_layout_vertical (container))
7091 {
7092 pos = &x1;
7093 if (baul_icon_container_is_layout_rtl (container))
7094 {
7095 compare_lt = TRUE(!(0));
7096 better_icon = x1 < x + ICON_PAD_LEFT4;
7097 }
7098 else
7099 {
7100 better_icon = x2 > x + ICON_PAD_LEFT4;
7101 }
7102 }
7103 else
7104 {
7105 pos = &y1;
7106 better_icon = y2 > y + ICON_PAD_TOP4;
7107 }
7108 if (better_icon)
7109 {
7110 if (best_icon == NULL((void*)0))
7111 {
7112 better_icon = TRUE(!(0));
7113 }
7114 else if (compare_lt)
7115 {
7116 better_icon = best_pos < *pos;
7117 }
7118 else
7119 {
7120 better_icon = best_pos > *pos;
7121 }
7122
7123 if (better_icon)
7124 {
7125 best_icon = icon;
7126 best_pos = *pos;
7127 }
7128 }
7129 }
7130
7131 l = l->next;
7132 }
7133
7134 return best_icon ? best_icon->data : NULL((void*)0);
7135}
7136
7137/* puts the icon at the top of the screen */
7138void
7139baul_icon_container_scroll_to_icon (BaulIconContainer *container,
7140 BaulIconData *data)
7141{
7142 GList *l;
7143 CtkAdjustment *hadj, *vadj;
7144 EelIRect bounds;
7145 CtkAllocation allocation;
7146 BaulIcon *icon = NULL((void*)0);
7147
7148 hadj = ctk_scrollable_get_hadjustment (CTK_SCROLLABLE (container)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_scrollable_get_type ()))))))
);
7149 vadj = ctk_scrollable_get_vadjustment (CTK_SCROLLABLE (container)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_scrollable_get_type ()))))))
);
7150 ctk_widget_get_allocation (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
, &allocation);
7151
7152 /* We need to force a relayout now if there are updates queued
7153 * since we need the final positions */
7154 baul_icon_container_layout_now (container);
7155
7156 l = container->details->icons;
7157 while (l != NULL((void*)0)) {
7158 icon = l->data;
7159
7160 if (icon->data == data &&
7161 icon_is_positioned (icon)) {
7162
7163 if (baul_icon_container_is_auto_layout (container)) {
7164 /* ensure that we reveal the entire row/column */
7165 icon_get_row_and_column_bounds (container, icon, &bounds, TRUE(!(0)));
7166 } else {
7167 item_get_canvas_bounds (EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
, &bounds, TRUE(!(0)));
7168 }
7169
7170 if (baul_icon_container_is_layout_vertical (container)) {
7171 if (baul_icon_container_is_layout_rtl (container)) {
7172 ctk_adjustment_set_value (hadj, bounds.x1 - allocation.width);
7173 } else {
7174 ctk_adjustment_set_value (hadj, bounds.x0);
7175 }
7176 } else {
7177 ctk_adjustment_set_value (vadj, bounds.y0);
7178 }
7179 }
7180
7181 l = l->next;
7182 }
7183}
7184
7185/* Call a function for all the icons. */
7186typedef struct
7187{
7188 BaulIconCallback callback;
7189 gpointer callback_data;
7190} CallbackAndData;
7191
7192static void
7193call_icon_callback (gpointer data, gpointer callback_data)
7194{
7195 BaulIcon *icon;
7196 CallbackAndData *callback_and_data;
7197
7198 icon = data;
7199 callback_and_data = callback_data;
7200 (* callback_and_data->callback) (icon->data, callback_and_data->callback_data);
7201}
7202
7203void
7204baul_icon_container_for_each (BaulIconContainer *container,
7205 BaulIconCallback callback,
7206 gpointer callback_data)
7207{
7208 CallbackAndData callback_and_data;
7209
7210 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
7211
7212 callback_and_data.callback = callback;
7213 callback_and_data.callback_data = callback_data;
7214
7215 g_list_foreach (container->details->icons,
7216 call_icon_callback, &callback_and_data);
7217}
7218
7219static int
7220selection_changed_at_idle_callback (gpointer data)
7221{
7222 BaulIconContainer *container;
7223
7224 container = BAUL_ICON_CONTAINER (data)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((data)), (baul_icon_container_get_type())))
))
;
7225
7226 g_signal_emit (container,
7227 signals[SELECTION_CHANGED], 0);
7228
7229 container->details->selection_changed_id = 0;
7230 return FALSE(0);
7231}
7232
7233/* utility routine to remove a single icon from the container */
7234
7235static void
7236icon_destroy (BaulIconContainer *container,
7237 BaulIcon *icon)
7238{
7239 BaulIconContainerDetails *details;
7240 gboolean was_selected;
7241 BaulIcon *icon_to_focus;
7242 GList *item;
7243
7244 details = container->details;
7245
7246 item = g_list_find (details->icons, icon);
7247 item = item->next ? item->next : item->prev;
7248 icon_to_focus = (item != NULL((void*)0)) ? item->data : NULL((void*)0);
7249
7250 details->icons = g_list_remove (details->icons, icon);
7251 details->new_icons = g_list_remove (details->new_icons, icon);
7252 g_hash_table_remove (details->icon_set, icon->data);
7253
7254 was_selected = icon->is_selected;
7255
7256 if (details->keyboard_focus == icon ||
7257 details->keyboard_focus == NULL((void*)0))
7258 {
7259 if (icon_to_focus != NULL((void*)0))
7260 {
7261 set_keyboard_focus (container, icon_to_focus);
7262 }
7263 else
7264 {
7265 clear_keyboard_focus (container);
7266 }
7267 }
7268
7269 if (details->keyboard_rubberband_start == icon)
7270 {
7271 clear_keyboard_rubberband_start (container);
7272 }
7273
7274 if (details->keyboard_icon_to_reveal == icon)
7275 {
7276 unschedule_keyboard_icon_reveal (container);
7277 }
7278 if (details->drag_icon == icon)
7279 {
7280 clear_drag_state (container);
7281 }
7282 if (details->drop_target == icon)
7283 {
7284 details->drop_target = NULL((void*)0);
7285 }
7286 if (details->range_selection_base_icon == icon)
7287 {
7288 details->range_selection_base_icon = NULL((void*)0);
7289 }
7290 if (details->pending_icon_to_reveal == icon)
7291 {
7292 set_pending_icon_to_reveal (container, NULL((void*)0));
7293 }
7294 if (details->stretch_icon == icon)
7295 {
7296 details->stretch_icon = NULL((void*)0);
7297 }
7298
7299 icon_free (icon);
7300
7301 if (was_selected)
7302 {
7303 /* Coalesce multiple removals causing multiple selection_changed events */
7304 details->selection_changed_id = g_idle_add (selection_changed_at_idle_callback, container);
7305 }
7306}
7307
7308/* activate any selected items in the container */
7309static void
7310activate_selected_items (BaulIconContainer *container)
7311{
7312 GList *selection;
7313
7314 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
7315
7316 selection = baul_icon_container_get_selection (container);
7317 if (selection != NULL((void*)0))
7318 {
7319 g_signal_emit (container,
7320 signals[ACTIVATE], 0,
7321 selection);
7322 }
7323 g_list_free (selection);
7324}
7325
7326static void
7327activate_selected_items_alternate (BaulIconContainer *container,
7328 BaulIcon *icon)
7329{
7330 GList *selection;
7331
7332 g_assert (BAUL_IS_ICON_CONTAINER (container))do { if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 7332, ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); } while (0)
;
7333
7334 if (icon != NULL((void*)0))
7335 {
7336 selection = g_list_prepend (NULL((void*)0), icon->data);
7337 }
7338 else
7339 {
7340 selection = baul_icon_container_get_selection (container);
7341 }
7342 if (selection != NULL((void*)0))
7343 {
7344 g_signal_emit (container,
7345 signals[ACTIVATE_ALTERNATE], 0,
7346 selection);
7347 }
7348 g_list_free (selection);
7349}
7350
7351static BaulIcon *
7352get_icon_being_renamed (BaulIconContainer *container)
7353{
7354 BaulIcon *rename_icon;
7355
7356 if (!is_renaming (container))
7357 {
7358 return NULL((void*)0);
7359 }
7360
7361 g_assert (!has_multiple_selection (container))do { if (!has_multiple_selection (container)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-icon-container.c", 7361, ((const char*)
(__func__)), "!has_multiple_selection (container)"); } while
(0)
;
7362
7363 rename_icon = get_first_selected_icon (container);
7364 g_assert (rename_icon != NULL)do { if (rename_icon != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-icon-container.c", 7364, ((const char*)
(__func__)), "rename_icon != NULL"); } while (0)
;
7365
7366 return rename_icon;
7367}
7368
7369static BaulIconInfo *
7370baul_icon_container_get_icon_images (BaulIconContainer *container,
7371 BaulIconData *data,
7372 int size,
7373 GList **emblem_pixbufs,
7374 char **embedded_text,
7375 gboolean for_drag_accept,
7376 gboolean need_large_embeddded_text,
7377 gboolean *embedded_text_needs_loading,
7378 gboolean *has_open_window)
7379{
7380 BaulIconContainerClass *klass;
7381
7382 klass = BAUL_ICON_CONTAINER_GET_CLASS (container)((((BaulIconContainerClass*) (((GTypeInstance*) ((container))
)->g_class))))
;
7383 g_assert (klass->get_icon_images != NULL)do { if (klass->get_icon_images != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-icon-container.c", 7383, ((const char*)
(__func__)), "klass->get_icon_images != NULL"); } while (
0)
;
7384
7385 return klass->get_icon_images (container, data, size, emblem_pixbufs, embedded_text, for_drag_accept, need_large_embeddded_text, embedded_text_needs_loading, has_open_window);
7386}
7387
7388static void
7389baul_icon_container_freeze_updates (BaulIconContainer *container)
7390{
7391 BaulIconContainerClass *klass;
7392
7393 klass = BAUL_ICON_CONTAINER_GET_CLASS (container)((((BaulIconContainerClass*) (((GTypeInstance*) ((container))
)->g_class))))
;
7394 g_assert (klass->freeze_updates != NULL)do { if (klass->freeze_updates != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-icon-container.c", 7394, ((const char*)
(__func__)), "klass->freeze_updates != NULL"); } while (0
)
;
7395
7396 klass->freeze_updates (container);
7397}
7398
7399static void
7400baul_icon_container_unfreeze_updates (BaulIconContainer *container)
7401{
7402 BaulIconContainerClass *klass;
7403
7404 klass = BAUL_ICON_CONTAINER_GET_CLASS (container)((((BaulIconContainerClass*) (((GTypeInstance*) ((container))
)->g_class))))
;
7405 g_assert (klass->unfreeze_updates != NULL)do { if (klass->unfreeze_updates != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-icon-container.c", 7405, ((const char*)
(__func__)), "klass->unfreeze_updates != NULL"); } while (
0)
;
7406
7407 klass->unfreeze_updates (container);
7408}
7409
7410static void
7411baul_icon_container_prioritize_thumbnailing (BaulIconContainer *container,
7412 BaulIcon *icon)
7413{
7414 BaulIconContainerClass *klass;
7415
7416 klass = BAUL_ICON_CONTAINER_GET_CLASS (container)((((BaulIconContainerClass*) (((GTypeInstance*) ((container))
)->g_class))))
;
7417 g_assert (klass->prioritize_thumbnailing != NULL)do { if (klass->prioritize_thumbnailing != ((void*)0)) ; else
g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 7417, ((const char*) (__func__)), "klass->prioritize_thumbnailing != NULL"
); } while (0)
;
7418
7419 klass->prioritize_thumbnailing (container, icon->data);
7420}
7421
7422static void
7423baul_icon_container_update_visible_icons (BaulIconContainer *container)
7424{
7425 CtkAdjustment *vadj, *hadj;
7426 double min_y, max_y;
7427 double min_x, max_x;
7428 double x0, y0, x1, y1;
7429 GList *node;
7430 gboolean visible;
7431 CtkAllocation allocation;
7432 BaulIcon *icon = NULL((void*)0);
7433
7434 hadj = ctk_scrollable_get_hadjustment (CTK_SCROLLABLE (container)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_scrollable_get_type ()))))))
);
7435 vadj = ctk_scrollable_get_vadjustment (CTK_SCROLLABLE (container)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_scrollable_get_type ()))))))
);
7436 ctk_widget_get_allocation (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
, &allocation);
7437
7438 min_x = ctk_adjustment_get_value (hadj);
7439 max_x = min_x + allocation.width;
7440
7441 min_y = ctk_adjustment_get_value (vadj);
7442 max_y = min_y + allocation.height;
7443
7444 eel_canvas_c2w (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
,
7445 min_x, min_y, &min_x, &min_y);
7446 eel_canvas_c2w (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
,
7447 max_x, max_y, &max_x, &max_y);
7448
7449 /* Do the iteration in reverse to get the render-order from top to
7450 * bottom for the prioritized thumbnails.
7451 */
7452 for (node = g_list_last (container->details->icons); node != NULL((void*)0); node = node->prev)
7453 {
7454 icon = node->data;
7455
7456 if (icon_is_positioned (icon))
7457 {
7458 eel_canvas_item_get_bounds (EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
,
7459 &x0,
7460 &y0,
7461 &x1,
7462 &y1);
7463 eel_canvas_item_i2w (EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
->parent,
7464 &x0,
7465 &y0);
7466 eel_canvas_item_i2w (EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
->parent,
7467 &x1,
7468 &y1);
7469
7470 if (baul_icon_container_is_layout_vertical (container))
7471 {
7472 visible = x1 >= min_x && x0 <= max_x;
7473 }
7474 else
7475 {
7476 visible = y1 >= min_y && y0 <= max_y;
7477 }
7478
7479 if (visible)
7480 {
7481 baul_icon_canvas_item_set_is_visible (icon->item, TRUE(!(0)));
7482 baul_icon_container_prioritize_thumbnailing (container,
7483 icon);
7484 }
7485 else
7486 {
7487 baul_icon_canvas_item_set_is_visible (icon->item, FALSE(0));
7488 }
7489 }
7490 }
7491}
7492
7493static void
7494handle_vadjustment_changed (CtkAdjustment *adjustment G_GNUC_UNUSED__attribute__ ((__unused__)),
7495 BaulIconContainer *container)
7496{
7497 if (!baul_icon_container_is_layout_vertical (container))
7498 {
7499 baul_icon_container_update_visible_icons (container);
7500 }
7501}
7502
7503static void
7504handle_hadjustment_changed (CtkAdjustment *adjustment G_GNUC_UNUSED__attribute__ ((__unused__)),
7505 BaulIconContainer *container)
7506{
7507 if (baul_icon_container_is_layout_vertical (container))
7508 {
7509 baul_icon_container_update_visible_icons (container);
7510 }
7511}
7512
7513
7514void
7515baul_icon_container_update_icon (BaulIconContainer *container,
7516 BaulIcon *icon)
7517{
7518 BaulIconContainerDetails *details;
7519 guint icon_size;
7520 guint min_image_size, max_image_size;
7521 BaulIconInfo *icon_info;
7522 CdkPoint *attach_points;
7523 int n_attach_points;
7524 GdkPixbuf *pixbuf;
7525 GList *emblem_pixbufs;
7526 char *editable_text, *additional_text;
7527 char *embedded_text;
7528 CdkRectangle embedded_text_rect;
7529 gboolean large_embedded_text;
7530 gboolean embedded_text_needs_loading;
7531 gboolean has_open_window;
7532
7533 if (icon == NULL((void*)0))
7534 {
7535 return;
7536 }
7537
7538 details = container->details;
7539
7540 /* compute the maximum size based on the scale factor */
7541 min_image_size = MINIMUM_IMAGE_SIZE24 * EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
->pixels_per_unit;
7542 max_image_size = MAX (MAXIMUM_IMAGE_SIZE * EEL_CANVAS (container)->pixels_per_unit, BAUL_ICON_MAXIMUM_SIZE)(((96 * ((((EelCanvas*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((container)), ((eel_canvas_get_type ())))))
)->pixels_per_unit) > (320)) ? (96 * ((((EelCanvas*) (void
*) g_type_check_instance_cast ((GTypeInstance*) ((container)
), ((eel_canvas_get_type ()))))))->pixels_per_unit) : (320
))
;
7543
7544 /* Get the appropriate images for the file. */
7545 if (container->details->forced_icon_size > 0)
7546 {
7547 icon_size = container->details->forced_icon_size;
7548 }
7549 else
7550 {
7551 icon_get_size (container, icon, &icon_size);
7552 }
7553
7554
7555 icon_size = MAX (icon_size, min_image_size)(((icon_size) > (min_image_size)) ? (icon_size) : (min_image_size
))
;
7556 icon_size = MIN (icon_size, max_image_size)(((icon_size) < (max_image_size)) ? (icon_size) : (max_image_size
))
;
7557
7558 /* Get the icons. */
7559 emblem_pixbufs = NULL((void*)0);
7560 embedded_text = NULL((void*)0);
7561 large_embedded_text = icon_size > ICON_SIZE_FOR_LARGE_EMBEDDED_TEXT55;
7562 icon_info = baul_icon_container_get_icon_images (container, icon->data, icon_size,
7563 &emblem_pixbufs,
7564 &embedded_text,
7565 icon == details->drop_target,
7566 large_embedded_text, &embedded_text_needs_loading,
7567 &has_open_window);
7568
7569
7570 if (container->details->forced_icon_size > 0)
7571 pixbuf = baul_icon_info_get_pixbuf_at_size (icon_info, icon_size);
7572 else
7573 pixbuf = baul_icon_info_get_pixbuf (icon_info);
7574 baul_icon_info_get_attach_points (icon_info, &attach_points, &n_attach_points);
7575
7576 baul_icon_container_get_icon_text (container,
7577 icon->data,
7578 &editable_text,
7579 &additional_text,
7580 FALSE(0));
7581
7582 /* If name of icon being renamed was changed from elsewhere, end renaming mode.
7583 * Alternatively, we could replace the characters in the editable text widget
7584 * with the new name, but that could cause timing problems if the user just
7585 * happened to be typing at that moment.
7586 */
7587 if (icon == get_icon_being_renamed (container) &&
7588 g_strcmp0 (editable_text,
7589 baul_icon_canvas_item_get_editable_text (icon->item)) != 0)
7590 {
7591 end_renaming_mode (container, FALSE(0));
7592 }
7593
7594 eel_canvas_item_set (EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
,
7595 "editable_text", editable_text,
7596 "additional_text", additional_text,
7597 "highlighted_for_drop", icon == details->drop_target,
7598 NULL((void*)0));
7599
7600 baul_icon_canvas_item_set_image (icon->item, pixbuf);
7601 baul_icon_canvas_item_set_attach_points (icon->item, attach_points, n_attach_points);
7602 baul_icon_canvas_item_set_emblems (icon->item, emblem_pixbufs);
7603 baul_icon_canvas_item_set_embedded_text_rect (icon->item, &embedded_text_rect);
7604 baul_icon_canvas_item_set_embedded_text (icon->item, embedded_text);
7605
7606 /* Let the pixbufs go. */
7607 g_object_unref (pixbuf);
7608 g_list_free_full (emblem_pixbufs, g_object_unref);
7609
7610 g_free (editable_text);
7611 g_free (additional_text);
7612
7613 g_object_unref (icon_info);
7614}
7615
7616static gboolean
7617assign_icon_position (BaulIconContainer *container,
7618 BaulIcon *icon)
7619{
7620 gboolean have_stored_position;
7621 BaulIconPosition position;
7622
7623 /* Get the stored position. */
7624 have_stored_position = FALSE(0);
7625 position.scale = 1.0;
7626 g_signal_emit (container,
7627 signals[GET_STORED_ICON_POSITION], 0,
7628 icon->data,
7629 &position,
7630 &have_stored_position);
7631 icon->scale = position.scale;
7632 if (!container->details->auto_layout)
7633 {
7634 if (have_stored_position)
7635 {
7636 icon_set_position (icon, position.x, position.y);
7637 icon->saved_ltr_x = icon->x;
7638 }
7639 else
7640 {
7641 return FALSE(0);
7642 }
7643 }
7644 return TRUE(!(0));
7645}
7646
7647static void
7648finish_adding_icon (BaulIconContainer *container,
7649 BaulIcon *icon)
7650{
7651 baul_icon_container_update_icon (container, icon);
7652 eel_canvas_item_show (EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
);
7653
7654 g_signal_connect_object (icon->item, "event",
7655 G_CALLBACK (item_event_callback)((GCallback) (item_event_callback)), container, 0);
7656
7657 g_signal_emit (container, signals[ICON_ADDED], 0, icon->data);
7658}
7659
7660static void
7661finish_adding_new_icons (BaulIconContainer *container)
7662{
7663 GList *p, *new_icons, *no_position_icons, *semi_position_icons;
7664 BaulIcon *icon;
7665 double bottom;
7666
7667 new_icons = container->details->new_icons;
7668 container->details->new_icons = NULL((void*)0);
7669 container->details->is_populating_container =
7670 g_list_length(new_icons) == g_hash_table_size(container->details->icon_set);
7671
7672 /* Position most icons (not unpositioned manual-layout icons). */
7673 new_icons = g_list_reverse (new_icons);
7674 no_position_icons = semi_position_icons = NULL((void*)0);
7675 for (p = new_icons; p != NULL((void*)0); p = p->next)
7676 {
7677 icon = p->data;
7678 if (icon->has_lazy_position)
7679 {
7680 assign_icon_position (container, icon);
7681 semi_position_icons = g_list_prepend (semi_position_icons, icon);
7682 }
7683 else if (!assign_icon_position (container, icon))
7684 {
7685 no_position_icons = g_list_prepend (no_position_icons, icon);
7686 }
7687
7688 finish_adding_icon (container, icon);
7689 }
7690 g_list_free (new_icons);
7691
7692 if (semi_position_icons != NULL((void*)0))
7693 {
7694 PlacementGrid *grid;
7695 time_t now;
7696 gboolean dummy;
7697
7698 g_assert (!container->details->auto_layout)do { if (!container->details->auto_layout) ; else g_assertion_message_expr
(((gchar*) 0), "baul-icon-container.c", 7698, ((const char*)
(__func__)), "!container->details->auto_layout"); } while
(0)
;
7699
7700 semi_position_icons = g_list_reverse (semi_position_icons);
7701
7702 /* This is currently only used on the desktop.
7703 * Thus, we pass FALSE for tight, like lay_down_icons_tblr */
7704 grid = placement_grid_new (container, FALSE(0));
7705
7706 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
7707 {
7708 icon = p->data;
7709
7710 if (icon_is_positioned (icon) && !icon->has_lazy_position)
7711 {
7712 placement_grid_mark_icon (grid, icon);
7713 }
7714 }
7715
7716 now = time (NULL((void*)0));
7717
7718 for (p = semi_position_icons; p != NULL((void*)0); p = p->next)
7719 {
7720 BaulIcon *icon;
7721 BaulIconPosition position;
7722 int x, y;
7723
7724 icon = p->data;
7725 x = icon->x;
7726 y = icon->y;
7727
7728 find_empty_location (container, grid,
7729 icon, x, y, &x, &y);
7730
7731 icon_set_position (icon, x, y);
7732
7733 position.x = icon->x;
7734 position.y = icon->y;
7735 position.scale = icon->scale;
7736 placement_grid_mark_icon (grid, icon);
7737 g_signal_emit (container, signals[ICON_POSITION_CHANGED], 0,
7738 icon->data, &position);
7739 g_signal_emit (container, signals[STORE_LAYOUT_TIMESTAMP], 0,
7740 icon->data, &now, &dummy);
7741
7742 /* ensure that next time we run this code, the formerly semi-positioned
7743 * icons are treated as being positioned. */
7744 icon->has_lazy_position = FALSE(0);
7745 }
7746
7747 placement_grid_free (grid);
7748
7749 g_list_free (semi_position_icons);
7750 }
7751
7752 /* Position the unpositioned manual layout icons. */
7753 if (no_position_icons != NULL((void*)0))
7754 {
7755 g_assert (!container->details->auto_layout)do { if (!container->details->auto_layout) ; else g_assertion_message_expr
(((gchar*) 0), "baul-icon-container.c", 7755, ((const char*)
(__func__)), "!container->details->auto_layout"); } while
(0)
;
7756
7757 sort_icons (container, &no_position_icons);
7758 if (baul_icon_container_get_is_desktop (container))
7759 {
7760 lay_down_icons (container, no_position_icons, CONTAINER_PAD_TOP4);
7761 }
7762 else
7763 {
7764 get_all_icon_bounds (container, NULL((void*)0), NULL((void*)0), NULL((void*)0), &bottom, BOUNDS_USAGE_FOR_LAYOUT);
7765 lay_down_icons (container, no_position_icons, bottom + ICON_PAD_BOTTOM4);
7766 }
7767 g_list_free (no_position_icons);
7768 }
7769
7770 if (container->details->store_layout_timestamps_when_finishing_new_icons)
7771 {
7772 store_layout_timestamps_now (container);
7773 container->details->store_layout_timestamps_when_finishing_new_icons = FALSE(0);
7774 }
7775}
7776
7777static gboolean
7778is_old_or_unknown_icon_data (BaulIconContainer *container,
7779 BaulIconData *data)
7780{
7781 time_t timestamp;
7782 gboolean success;
7783
7784 if (container->details->layout_timestamp == UNDEFINED_TIME((time_t) (-1)))
7785 {
7786 /* don't know */
7787 return FALSE(0);
7788 }
7789
7790 g_signal_emit (container,
7791 signals[GET_STORED_LAYOUT_TIMESTAMP], 0,
7792 data, &timestamp, &success);
7793 return (!success || timestamp < container->details->layout_timestamp);
7794}
7795
7796/**
7797 * baul_icon_container_add:
7798 * @container: A BaulIconContainer
7799 * @data: Icon data.
7800 *
7801 * Add icon to represent @data to container.
7802 * Returns FALSE if there was already such an icon.
7803 **/
7804gboolean
7805baul_icon_container_add (BaulIconContainer *container,
7806 BaulIconData *data)
7807{
7808 BaulIconContainerDetails *details;
7809 BaulIcon *icon;
7810 EelCanvasItem *band, *item;
7811
7812 g_return_val_if_fail (BAUL_IS_ICON_CONTAINER (container), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return ((0)); } } while (0)
;
7813 g_return_val_if_fail (data != NULL, FALSE)do { if ((data != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "data != NULL"); return
((0)); } } while (0)
;
7814
7815 details = container->details;
7816
7817 if (g_hash_table_lookup (details->icon_set, data) != NULL((void*)0))
7818 {
7819 return FALSE(0);
7820 }
7821
7822 /* Create the new icon, including the canvas item. */
7823 icon = g_new0 (BaulIcon, 1)((BaulIcon *) g_malloc0_n ((1), sizeof (BaulIcon)));
7824 icon->data = data;
7825 icon->x = ICON_UNPOSITIONED_VALUE-1;
7826 icon->y = ICON_UNPOSITIONED_VALUE-1;
7827
7828 /* Whether the saved icon position should only be used
7829 * if the previous icon position is free. If the position
7830 * is occupied, another position near the last one will
7831 */
7832 icon->has_lazy_position = is_old_or_unknown_icon_data (container, data);
7833 icon->scale = 1.0;
7834 icon->item = BAUL_ICON_CANVAS_ITEM((((BaulIconCanvasItem*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((eel_canvas_item_new (((((EelCanvasGroup*) (
void *) g_type_check_instance_cast ((GTypeInstance*) ((((((EelCanvas
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((container
)), ((eel_canvas_get_type ()))))))->root)), ((eel_canvas_group_get_type
())))))), baul_icon_canvas_item_get_type (), "visible", (0),
((void*)0)))), (baul_icon_canvas_item_get_type())))))
7835 (eel_canvas_item_new (EEL_CANVAS_GROUP (EEL_CANVAS (container)->root),((((BaulIconCanvasItem*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((eel_canvas_item_new (((((EelCanvasGroup*) (
void *) g_type_check_instance_cast ((GTypeInstance*) ((((((EelCanvas
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((container
)), ((eel_canvas_get_type ()))))))->root)), ((eel_canvas_group_get_type
())))))), baul_icon_canvas_item_get_type (), "visible", (0),
((void*)0)))), (baul_icon_canvas_item_get_type())))))
7836 baul_icon_canvas_item_get_type (),((((BaulIconCanvasItem*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((eel_canvas_item_new (((((EelCanvasGroup*) (
void *) g_type_check_instance_cast ((GTypeInstance*) ((((((EelCanvas
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((container
)), ((eel_canvas_get_type ()))))))->root)), ((eel_canvas_group_get_type
())))))), baul_icon_canvas_item_get_type (), "visible", (0),
((void*)0)))), (baul_icon_canvas_item_get_type())))))
7837 "visible", FALSE,((((BaulIconCanvasItem*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((eel_canvas_item_new (((((EelCanvasGroup*) (
void *) g_type_check_instance_cast ((GTypeInstance*) ((((((EelCanvas
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((container
)), ((eel_canvas_get_type ()))))))->root)), ((eel_canvas_group_get_type
())))))), baul_icon_canvas_item_get_type (), "visible", (0),
((void*)0)))), (baul_icon_canvas_item_get_type())))))
7838 NULL))((((BaulIconCanvasItem*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((eel_canvas_item_new (((((EelCanvasGroup*) (
void *) g_type_check_instance_cast ((GTypeInstance*) ((((((EelCanvas
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((container
)), ((eel_canvas_get_type ()))))))->root)), ((eel_canvas_group_get_type
())))))), baul_icon_canvas_item_get_type (), "visible", (0),
((void*)0)))), (baul_icon_canvas_item_get_type())))))
;
7839 icon->item->user_data = icon;
7840
7841 /* Make sure the icon is under the selection_rectangle */
7842 item = EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
;
7843 band = BAUL_ICON_CONTAINER (item->canvas)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((item->canvas)), (baul_icon_container_get_type
())))))
->details->rubberband_info.selection_rectangle;
7844 if (band)
7845 {
7846 eel_canvas_item_send_behind (item, band);
7847 }
7848
7849 /* Put it on both lists. */
7850 details->icons = g_list_prepend (details->icons, icon);
7851 details->new_icons = g_list_prepend (details->new_icons, icon);
7852
7853 g_hash_table_insert (details->icon_set, data, icon);
7854
7855 /* Run an idle function to add the icons. */
7856 schedule_redo_layout (container);
7857
7858 return TRUE(!(0));
7859}
7860
7861void
7862baul_icon_container_layout_now (BaulIconContainer *container)
7863{
7864 if (container->details->idle_id != 0)
7865 {
7866 unschedule_redo_layout (container);
7867 redo_layout_internal (container);
7868 }
7869
7870 /* Also need to make sure we're properly resized, for instance
7871 * newly added files may trigger a change in the size allocation and
7872 * thus toggle scrollbars on */
7873 ctk_container_check_resize (CTK_CONTAINER (ctk_widget_get_parent (CTK_WIDGET (container)))((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_widget_get_parent (((((CtkWidget*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), ((ctk_widget_get_type ())))
)))))), ((ctk_container_get_type ()))))))
);
7874}
7875
7876/**
7877 * baul_icon_container_remove:
7878 * @container: A BaulIconContainer.
7879 * @data: Icon data.
7880 *
7881 * Remove the icon with this data.
7882 **/
7883gboolean
7884baul_icon_container_remove (BaulIconContainer *container,
7885 BaulIconData *data)
7886{
7887 BaulIcon *icon;
7888
7889 g_return_val_if_fail (BAUL_IS_ICON_CONTAINER (container), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return ((0)); } } while (0)
;
7890 g_return_val_if_fail (data != NULL, FALSE)do { if ((data != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "data != NULL"); return
((0)); } } while (0)
;
7891
7892 end_renaming_mode (container, FALSE(0));
7893
7894 icon = g_hash_table_lookup (container->details->icon_set, data);
7895
7896 if (icon == NULL((void*)0))
7897 {
7898 return FALSE(0);
7899 }
7900
7901 g_signal_emit (container, signals[ICON_REMOVED], 0, icon);
7902
7903 icon_destroy (container, icon);
7904 schedule_redo_layout (container);
7905
7906 return TRUE(!(0));
7907}
7908
7909/**
7910 * baul_icon_container_request_update:
7911 * @container: A BaulIconContainer.
7912 * @data: Icon data.
7913 *
7914 * Update the icon with this data.
7915 **/
7916void
7917baul_icon_container_request_update (BaulIconContainer *container,
7918 BaulIconData *data)
7919{
7920 BaulIcon *icon;
7921
7922 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
7923 g_return_if_fail (data != NULL)do { if ((data != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "data != NULL"); return
; } } while (0)
;
7924
7925 icon = g_hash_table_lookup (container->details->icon_set, data);
7926
7927 if (icon != NULL((void*)0))
7928 {
7929 baul_icon_container_update_icon (container, icon);
7930 schedule_redo_layout (container);
7931 }
7932}
7933
7934/* zooming */
7935
7936BaulZoomLevel
7937baul_icon_container_get_zoom_level (BaulIconContainer *container)
7938{
7939 return container->details->zoom_level;
7940}
7941
7942void
7943baul_icon_container_set_zoom_level (BaulIconContainer *container, int new_level)
7944{
7945 BaulIconContainerDetails *details;
7946 int pinned_level;
7947 double pixels_per_unit;
7948
7949 details = container->details;
7950
7951 end_renaming_mode (container, TRUE(!(0)));
7952
7953 pinned_level = new_level;
7954 if (pinned_level < BAUL_ZOOM_LEVEL_SMALLEST)
7955 {
7956 pinned_level = BAUL_ZOOM_LEVEL_SMALLEST;
7957 }
7958 else if (pinned_level > BAUL_ZOOM_LEVEL_LARGEST)
7959 {
7960 pinned_level = BAUL_ZOOM_LEVEL_LARGEST;
7961 }
7962
7963 if (pinned_level == details->zoom_level)
7964 {
7965 return;
7966 }
7967
7968 details->zoom_level = pinned_level;
7969
7970 pixels_per_unit = (double) baul_get_icon_size_for_zoom_level (pinned_level)
7971 / BAUL_ICON_SIZE_STANDARD48;
7972 eel_canvas_set_pixels_per_unit (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
, pixels_per_unit);
7973
7974 invalidate_labels (container);
7975 baul_icon_container_request_update_all (container);
7976}
7977
7978/**
7979 * baul_icon_container_request_update_all:
7980 * For each icon, synchronizes the displayed information (image, text) with the
7981 * information from the model.
7982 *
7983 * @container: An icon container.
7984 **/
7985void
7986baul_icon_container_request_update_all (BaulIconContainer *container)
7987{
7988 GList *node;
7989 BaulIcon *icon = NULL((void*)0);
7990
7991 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
7992
7993 container->details->is_loading = TRUE(!(0));
7994 for (node = container->details->icons; node != NULL((void*)0); node = node->next)
7995 {
7996 icon = node->data;
7997 baul_icon_container_update_icon (container, icon);
7998 }
7999
8000 redo_layout (container);
8001 container->details->is_loading = FALSE(0);
8002}
8003
8004/**
8005 * baul_icon_container_reveal:
8006 * Change scroll position as necessary to reveal the specified item.
8007 */
8008void
8009baul_icon_container_reveal (BaulIconContainer *container, BaulIconData *data)
8010{
8011 BaulIcon *icon;
8012
8013 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
8014 g_return_if_fail (data != NULL)do { if ((data != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "data != NULL"); return
; } } while (0)
;
8015
8016 icon = g_hash_table_lookup (container->details->icon_set, data);
8017
8018 if (icon != NULL((void*)0))
8019 {
8020 reveal_icon (container, icon);
8021 }
8022}
8023
8024/**
8025 * baul_icon_container_get_selection:
8026 * @container: An icon container.
8027 *
8028 * Get a list of the icons currently selected in @container.
8029 *
8030 * Return value: A GList of the programmer-specified data associated to each
8031 * selected icon, or NULL if no icon is selected. The caller is expected to
8032 * free the list when it is not needed anymore.
8033 **/
8034GList *
8035baul_icon_container_get_selection (BaulIconContainer *container)
8036{
8037 GList *list, *p;
8038
8039 g_return_val_if_fail (BAUL_IS_ICON_CONTAINER (container), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return (((void*)0)); } } while (0)
;
8040
8041 list = NULL((void*)0);
8042 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
8043 {
8044 BaulIcon *icon;
8045
8046 icon = p->data;
8047 if (icon->is_selected)
8048 {
8049 list = g_list_prepend (list, icon->data);
8050 }
8051 }
8052
8053 return g_list_reverse (list);
8054}
8055
8056static GList *
8057baul_icon_container_get_selected_icons (BaulIconContainer *container)
8058{
8059 GList *list, *p;
8060
8061 g_return_val_if_fail (BAUL_IS_ICON_CONTAINER (container), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return (((void*)0)); } } while (0)
;
8062
8063 list = NULL((void*)0);
8064 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
8065 {
8066 BaulIcon *icon;
8067
8068 icon = p->data;
8069 if (icon->is_selected)
8070 {
8071 list = g_list_prepend (list, icon);
8072 }
8073 }
8074
8075 return g_list_reverse (list);
8076}
8077
8078/**
8079 * baul_icon_container_invert_selection:
8080 * @container: An icon container.
8081 *
8082 * Inverts the selection in @container.
8083 *
8084 **/
8085void
8086baul_icon_container_invert_selection (BaulIconContainer *container)
8087{
8088 GList *p;
8089
8090 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
8091
8092 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
8093 {
8094 BaulIcon *icon;
8095
8096 icon = p->data;
8097 icon_toggle_selected (container, icon);
8098 }
8099
8100 g_signal_emit (container, signals[SELECTION_CHANGED], 0);
8101}
8102
8103
8104/* Returns an array of CdkPoints of locations of the icons. */
8105static GArray *
8106baul_icon_container_get_icon_locations (BaulIconContainer *container G_GNUC_UNUSED__attribute__ ((__unused__)),
8107 GList *icons)
8108{
8109 GArray *result;
8110 GList *node;
8111 int index;
8112
8113 result = g_array_new (FALSE(0), TRUE(!(0)), sizeof (CdkPoint));
8114 result = g_array_set_size (result, g_list_length (icons));
8115
8116 for (index = 0, node = icons; node != NULL((void*)0); index++, node = node->next)
8117 {
8118 g_array_index (result, CdkPoint, index)(((CdkPoint*) (void *) (result)->data) [(index)]).x =
8119 ((BaulIcon *)node->data)->x;
8120 g_array_index (result, CdkPoint, index)(((CdkPoint*) (void *) (result)->data) [(index)]).y =
8121 ((BaulIcon *)node->data)->y;
8122 }
8123
8124 return result;
8125}
8126
8127/**
8128 * baul_icon_container_get_selected_icon_locations:
8129 * @container: An icon container widget.
8130 *
8131 * Returns an array of CdkPoints of locations of the selected icons.
8132 **/
8133GArray *
8134baul_icon_container_get_selected_icon_locations (BaulIconContainer *container)
8135{
8136 GArray *result;
8137 GList *icons;
8138
8139 g_return_val_if_fail (BAUL_IS_ICON_CONTAINER (container), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return (((void*)0)); } } while (0)
;
8140
8141 icons = baul_icon_container_get_selected_icons (container);
8142 result = baul_icon_container_get_icon_locations (container, icons);
8143 g_list_free (icons);
8144
8145 return result;
8146}
8147
8148/**
8149 * baul_icon_container_select_all:
8150 * @container: An icon container widget.
8151 *
8152 * Select all the icons in @container at once.
8153 **/
8154void
8155baul_icon_container_select_all (BaulIconContainer *container)
8156{
8157 gboolean selection_changed;
8158 GList *p;
8159 BaulIcon *icon = NULL((void*)0);
8160
8161 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
8162
8163 selection_changed = FALSE(0);
8164
8165 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
8166 {
8167 icon = p->data;
8168
8169 selection_changed |= icon_set_selected (container, icon, TRUE(!(0)));
8170 }
8171
8172 if (selection_changed)
8173 {
8174 g_signal_emit (container,
8175 signals[SELECTION_CHANGED], 0);
8176 }
8177}
8178
8179/**
8180 * baul_icon_container_set_selection:
8181 * @container: An icon container widget.
8182 * @selection: A list of BaulIconData *.
8183 *
8184 * Set the selection to exactly the icons in @container which have
8185 * programmer data matching one of the items in @selection.
8186 **/
8187void
8188baul_icon_container_set_selection (BaulIconContainer *container,
8189 GList *selection)
8190{
8191 gboolean selection_changed;
8192 GHashTable *hash;
8193 GList *p;
8194 BaulIcon *icon = NULL((void*)0);
8195
8196 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
8197
8198 selection_changed = FALSE(0);
8199
8200 hash = g_hash_table_new (NULL((void*)0), NULL((void*)0));
8201 for (p = selection; p != NULL((void*)0); p = p->next)
8202 {
8203 g_hash_table_insert (hash, p->data, p->data);
8204 }
8205 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
8206 {
8207 icon = p->data;
8208
8209 selection_changed |= icon_set_selected
8210 (container, icon,
8211 g_hash_table_lookup (hash, icon->data) != NULL((void*)0));
8212 }
8213 g_hash_table_destroy (hash);
8214
8215 if (selection_changed)
8216 {
8217 g_signal_emit (container,
8218 signals[SELECTION_CHANGED], 0);
8219 }
8220}
8221
8222/**
8223 * baul_icon_container_select_list_unselect_others.
8224 * @container: An icon container widget.
8225 * @selection: A list of BaulIcon *.
8226 *
8227 * Set the selection to exactly the icons in @selection.
8228 **/
8229void
8230baul_icon_container_select_list_unselect_others (BaulIconContainer *container,
8231 GList *selection)
8232{
8233 gboolean selection_changed;
8234 GHashTable *hash;
8235 GList *p;
8236 BaulIcon *icon = NULL((void*)0);
8237
8238 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
8239
8240 selection_changed = FALSE(0);
8241
8242 hash = g_hash_table_new (NULL((void*)0), NULL((void*)0));
8243 for (p = selection; p != NULL((void*)0); p = p->next)
8244 {
8245 g_hash_table_insert (hash, p->data, p->data);
8246 }
8247 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
8248 {
8249 icon = p->data;
8250
8251 selection_changed |= icon_set_selected
8252 (container, icon,
8253 g_hash_table_lookup (hash, icon) != NULL((void*)0));
8254 }
8255 g_hash_table_destroy (hash);
8256
8257 if (selection_changed)
8258 {
8259 g_signal_emit (container,
8260 signals[SELECTION_CHANGED], 0);
8261 }
8262}
8263
8264/**
8265 * baul_icon_container_unselect_all:
8266 * @container: An icon container widget.
8267 *
8268 * Deselect all the icons in @container.
8269 **/
8270void
8271baul_icon_container_unselect_all (BaulIconContainer *container)
8272{
8273 if (unselect_all (container))
8274 {
8275 g_signal_emit (container,
8276 signals[SELECTION_CHANGED], 0);
8277 }
8278}
8279
8280/**
8281 * baul_icon_container_get_icon_by_uri:
8282 * @container: An icon container widget.
8283 * @uri: The uri of an icon to find.
8284 *
8285 * Locate an icon, given the URI. The URI must match exactly.
8286 * Later we may have to have some way of figuring out if the
8287 * URI specifies the same object that does not require an exact match.
8288 **/
8289BaulIcon *
8290baul_icon_container_get_icon_by_uri (BaulIconContainer *container,
8291 const char *uri)
8292{
8293 BaulIconContainerDetails *details;
8294 GList *p;
8295
8296 /* Eventually, we must avoid searching the entire icon list,
8297 but it's OK for now.
8298 A hash table mapping uri to icon is one possibility.
8299 */
8300
8301 details = container->details;
8302
8303 for (p = details->icons; p != NULL((void*)0); p = p->next)
8304 {
8305 BaulIcon *icon;
8306 char *icon_uri;
8307 gboolean is_match;
8308
8309 icon = p->data;
8310
8311 icon_uri = baul_icon_container_get_icon_uri
8312 (container, icon);
8313 is_match = strcmp (uri, icon_uri) == 0;
8314 g_free (icon_uri);
8315
8316 if (is_match)
8317 {
8318 return icon;
8319 }
8320 }
8321
8322 return NULL((void*)0);
8323}
8324
8325static BaulIcon *
8326get_nth_selected_icon (BaulIconContainer *container, int index)
8327{
8328 GList *p;
8329 int selection_count;
8330 BaulIcon *icon = NULL((void*)0);
8331
8332 g_assert (index > 0)do { if (index > 0) ; else g_assertion_message_expr (((gchar
*) 0), "baul-icon-container.c", 8332, ((const char*) (__func__
)), "index > 0"); } while (0)
;
8333
8334 /* Find the nth selected icon. */
8335 selection_count = 0;
8336 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
8337 {
8338 icon = p->data;
8339 if (icon->is_selected)
8340 {
8341 if (++selection_count == index)
8342 {
8343 return icon;
8344 }
8345 }
8346 }
8347 return NULL((void*)0);
8348}
8349
8350static BaulIcon *
8351get_first_selected_icon (BaulIconContainer *container)
8352{
8353 return get_nth_selected_icon (container, 1);
8354}
8355
8356static gboolean
8357has_multiple_selection (BaulIconContainer *container)
8358{
8359 return get_nth_selected_icon (container, 2) != NULL((void*)0);
8360}
8361
8362static gboolean
8363all_selected (BaulIconContainer *container)
8364{
8365 GList *p;
8366 BaulIcon *icon = NULL((void*)0);
8367
8368 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
8369 {
8370 icon = p->data;
8371 if (!icon->is_selected)
8372 {
8373 return FALSE(0);
8374 }
8375 }
8376 return TRUE(!(0));
8377}
8378
8379static gboolean
8380has_selection (BaulIconContainer *container)
8381{
8382 return get_nth_selected_icon (container, 1) != NULL((void*)0);
8383}
8384
8385/**
8386 * baul_icon_container_show_stretch_handles:
8387 * @container: An icon container widget.
8388 *
8389 * Makes stretch handles visible on the first selected icon.
8390 **/
8391void
8392baul_icon_container_show_stretch_handles (BaulIconContainer *container)
8393{
8394 BaulIconContainerDetails *details;
8395 BaulIcon *icon;
8396 guint initial_size;
8397
8398 icon = get_first_selected_icon (container);
8399 if (icon == NULL((void*)0))
8400 {
8401 return;
8402 }
8403
8404 /* Check if it already has stretch handles. */
8405 details = container->details;
8406 if (details->stretch_icon == icon)
8407 {
8408 return;
8409 }
8410
8411 /* Get rid of the existing stretch handles and put them on the new icon. */
8412 if (details->stretch_icon != NULL((void*)0))
8413 {
8414 baul_icon_canvas_item_set_show_stretch_handles
8415 (details->stretch_icon->item, FALSE(0));
8416 ungrab_stretch_icon (container);
8417 emit_stretch_ended (container, details->stretch_icon);
8418 }
8419 baul_icon_canvas_item_set_show_stretch_handles (icon->item, TRUE(!(0)));
8420 details->stretch_icon = icon;
8421
8422 icon_get_size (container, icon, &initial_size);
8423
8424 /* only need to keep size in one dimension, since they are constrained to be the same */
8425 container->details->stretch_initial_x = icon->x;
8426 container->details->stretch_initial_y = icon->y;
8427 container->details->stretch_initial_size = initial_size;
8428
8429 emit_stretch_started (container, icon);
8430}
8431
8432/**
8433 * baul_icon_container_has_stretch_handles
8434 * @container: An icon container widget.
8435 *
8436 * Returns true if the first selected item has stretch handles.
8437 **/
8438gboolean
8439baul_icon_container_has_stretch_handles (BaulIconContainer *container)
8440{
8441 BaulIcon *icon;
8442
8443 icon = get_first_selected_icon (container);
8444 if (icon == NULL((void*)0))
8445 {
8446 return FALSE(0);
8447 }
8448
8449 return icon == container->details->stretch_icon;
8450}
8451
8452/**
8453 * baul_icon_container_is_stretched
8454 * @container: An icon container widget.
8455 *
8456 * Returns true if the any selected item is stretched to a size other than 1.0.
8457 **/
8458gboolean
8459baul_icon_container_is_stretched (BaulIconContainer *container)
8460{
8461 GList *p;
8462 BaulIcon *icon = NULL((void*)0);
8463
8464 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
8465 {
8466 icon = p->data;
8467 if (icon->is_selected && icon->scale != 1.0)
8468 {
8469 return TRUE(!(0));
8470 }
8471 }
8472 return FALSE(0);
8473}
8474
8475/**
8476 * baul_icon_container_unstretch
8477 * @container: An icon container widget.
8478 *
8479 * Gets rid of any icon stretching.
8480 **/
8481void
8482baul_icon_container_unstretch (BaulIconContainer *container)
8483{
8484 GList *p;
8485 BaulIcon *icon = NULL((void*)0);
8486
8487 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
8488 {
8489 icon = p->data;
8490 if (icon->is_selected)
8491 {
8492 baul_icon_container_move_icon (container, icon,
8493 icon->x, icon->y,
8494 1.0,
8495 FALSE(0), TRUE(!(0)), TRUE(!(0)));
8496 }
8497 }
8498}
8499
8500static void
8501compute_stretch (StretchState *start,
8502 StretchState *current)
8503{
8504 gboolean right, bottom;
8505 int x_stretch, y_stretch;
8506
8507 /* FIXME bugzilla.gnome.org 45390: This doesn't correspond to
8508 * the way the handles are drawn.
8509 */
8510 /* Figure out which handle we are dragging. */
8511 right = start->pointer_x > start->icon_x + (int) start->icon_size / 2;
8512 bottom = start->pointer_y > start->icon_y + (int) start->icon_size / 2;
8513
8514 /* Figure out how big we should stretch. */
8515 x_stretch = start->pointer_x - current->pointer_x;
8516 y_stretch = start->pointer_y - current->pointer_y;
8517 if (right)
8518 {
8519 x_stretch = - x_stretch;
8520 }
8521 if (bottom)
8522 {
8523 y_stretch = - y_stretch;
8524 }
8525 current->icon_size = MAX ((int) start->icon_size + MIN (x_stretch, y_stretch),((((int) start->icon_size + (((x_stretch) < (y_stretch)
) ? (x_stretch) : (y_stretch))) > ((int) 16)) ? ((int) start
->icon_size + (((x_stretch) < (y_stretch)) ? (x_stretch
) : (y_stretch))) : ((int) 16))
8526 (int) BAUL_ICON_SIZE_SMALLEST)((((int) start->icon_size + (((x_stretch) < (y_stretch)
) ? (x_stretch) : (y_stretch))) > ((int) 16)) ? ((int) start
->icon_size + (((x_stretch) < (y_stretch)) ? (x_stretch
) : (y_stretch))) : ((int) 16))
;
8527
8528 /* Figure out where the corner of the icon should be. */
8529 current->icon_x = start->icon_x;
8530 if (!right)
8531 {
8532 current->icon_x += start->icon_size - current->icon_size;
8533 }
8534 current->icon_y = start->icon_y;
8535 if (!bottom)
8536 {
8537 current->icon_y += start->icon_size - current->icon_size;
8538 }
8539}
8540
8541char *
8542baul_icon_container_get_icon_uri (BaulIconContainer *container,
8543 BaulIcon *icon)
8544{
8545 char *uri;
8546
8547 uri = NULL((void*)0);
8548 g_signal_emit (container,
8549 signals[GET_ICON_URI], 0,
8550 icon->data,
8551 &uri);
8552 return uri;
8553}
8554
8555char *
8556baul_icon_container_get_icon_drop_target_uri (BaulIconContainer *container,
8557 BaulIcon *icon)
8558{
8559 char *uri;
8560
8561 uri = NULL((void*)0);
8562 g_signal_emit (container,
8563 signals[GET_ICON_DROP_TARGET_URI], 0,
8564 icon->data,
8565 &uri);
8566 return uri;
8567}
8568
8569/* Call to reset the scroll region only if the container is not empty,
8570 * to avoid having the flag linger until the next file is added.
8571 */
8572static void
8573reset_scroll_region_if_not_empty (BaulIconContainer *container)
8574{
8575 if (!baul_icon_container_is_empty (container))
8576 {
8577 baul_icon_container_reset_scroll_region (container);
8578 }
8579}
8580
8581/* Switch from automatic layout to manual or vice versa.
8582 * If we switch to manual layout, we restore the icon positions from the
8583 * last manual layout.
8584 */
8585void
8586baul_icon_container_set_auto_layout (BaulIconContainer *container,
8587 gboolean auto_layout)
8588{
8589 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
8590 g_return_if_fail (auto_layout == FALSE || auto_layout == TRUE)do { if ((auto_layout == (0) || auto_layout == (!(0)))) { } else
{ g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "auto_layout == FALSE || auto_layout == TRUE"); return; }
} while (0)
;
8591
8592 if (container->details->auto_layout == auto_layout)
8593 {
8594 return;
8595 }
8596
8597 reset_scroll_region_if_not_empty (container);
8598 container->details->auto_layout = auto_layout;
8599
8600 if (!auto_layout)
8601 {
8602 reload_icon_positions (container);
8603 baul_icon_container_freeze_icon_positions (container);
8604 }
8605
8606 redo_layout (container);
8607
8608 g_signal_emit (container, signals[LAYOUT_CHANGED], 0);
8609}
8610
8611
8612/* Toggle the tighter layout boolean. */
8613void
8614baul_icon_container_set_tighter_layout (BaulIconContainer *container,
8615 gboolean tighter_layout)
8616{
8617 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
8618 g_return_if_fail (tighter_layout == FALSE || tighter_layout == TRUE)do { if ((tighter_layout == (0) || tighter_layout == (!(0))))
{ } else { g_return_if_fail_warning (((gchar*) 0), ((const char
*) (__func__)), "tighter_layout == FALSE || tighter_layout == TRUE"
); return; } } while (0)
;
8619
8620 if (container->details->tighter_layout == tighter_layout)
8621 {
8622 return;
8623 }
8624
8625 container->details->tighter_layout = tighter_layout;
8626
8627 if (container->details->auto_layout)
8628 {
8629 invalidate_label_sizes (container);
8630 redo_layout (container);
8631
8632 g_signal_emit (container, signals[LAYOUT_CHANGED], 0);
8633 }
8634 else
8635 {
8636 /* in manual layout, label sizes still change, even though
8637 * the icons don't move.
8638 */
8639 invalidate_label_sizes (container);
8640 baul_icon_container_request_update_all (container);
8641 }
8642}
8643
8644gboolean
8645baul_icon_container_is_keep_aligned (BaulIconContainer *container)
8646{
8647 return container->details->keep_aligned;
8648}
8649
8650static gboolean
8651align_icons_callback (gpointer callback_data)
8652{
8653 BaulIconContainer *container;
8654
8655 container = BAUL_ICON_CONTAINER (callback_data)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((callback_data)), (baul_icon_container_get_type
())))))
;
8656 align_icons (container);
8657 container->details->align_idle_id = 0;
8658
8659 return FALSE(0);
8660}
8661
8662static void
8663unschedule_align_icons (BaulIconContainer *container)
8664{
8665 if (container->details->align_idle_id != 0)
8666 {
8667 g_source_remove (container->details->align_idle_id);
8668 container->details->align_idle_id = 0;
8669 }
8670}
8671
8672static void
8673schedule_align_icons (BaulIconContainer *container)
8674{
8675 if (container->details->align_idle_id == 0
8676 && container->details->has_been_allocated)
8677 {
8678 container->details->align_idle_id = g_idle_add
8679 (align_icons_callback, container);
8680 }
8681}
8682
8683void
8684baul_icon_container_set_keep_aligned (BaulIconContainer *container,
8685 gboolean keep_aligned)
8686{
8687 if (container->details->keep_aligned != keep_aligned)
8688 {
8689 container->details->keep_aligned = keep_aligned;
8690
8691 if (keep_aligned && !container->details->auto_layout)
8692 {
8693 schedule_align_icons (container);
8694 }
8695 else
8696 {
8697 unschedule_align_icons (container);
8698 }
8699 }
8700}
8701
8702void
8703baul_icon_container_set_layout_mode (BaulIconContainer *container,
8704 BaulIconLayoutMode mode)
8705{
8706 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
8707
8708 container->details->layout_mode = mode;
8709 invalidate_labels (container);
8710
8711 redo_layout (container);
8712
8713 g_signal_emit (container, signals[LAYOUT_CHANGED], 0);
8714}
8715
8716void
8717baul_icon_container_set_label_position (BaulIconContainer *container,
8718 BaulIconLabelPosition position)
8719{
8720 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
8721
8722 if (container->details->label_position != position)
8723 {
8724 container->details->label_position = position;
8725
8726 invalidate_labels (container);
8727 baul_icon_container_request_update_all (container);
8728
8729 schedule_redo_layout (container);
8730 }
8731}
8732
8733/* Switch from automatic to manual layout, freezing all the icons in their
8734 * current positions instead of restoring icon positions from the last manual
8735 * layout as set_auto_layout does.
8736 */
8737void
8738baul_icon_container_freeze_icon_positions (BaulIconContainer *container)
8739{
8740 gboolean changed;
8741 GList *p;
8742 BaulIcon *icon;
8743 BaulIconPosition position;
8744
8745 changed = container->details->auto_layout;
8746 container->details->auto_layout = FALSE(0);
8747
8748 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
8749 {
8750 icon = p->data;
8751
8752 position.x = icon->saved_ltr_x;
8753 position.y = icon->y;
8754 position.scale = icon->scale;
8755 g_signal_emit (container, signals[ICON_POSITION_CHANGED], 0,
8756 icon->data, &position);
8757 }
8758
8759 if (changed)
8760 {
8761 g_signal_emit (container, signals[LAYOUT_CHANGED], 0);
8762 }
8763}
8764
8765/* Re-sort, switching to automatic layout if it was in manual layout. */
8766void
8767baul_icon_container_sort (BaulIconContainer *container)
8768{
8769 gboolean changed;
8770
8771 changed = !container->details->auto_layout;
8772 container->details->auto_layout = TRUE(!(0));
8773
8774 reset_scroll_region_if_not_empty (container);
8775 redo_layout (container);
8776
8777 if (changed)
8778 {
8779 g_signal_emit (container, signals[LAYOUT_CHANGED], 0);
8780 }
8781}
8782
8783gboolean
8784baul_icon_container_is_auto_layout (BaulIconContainer *container)
8785{
8786 g_return_val_if_fail (BAUL_IS_ICON_CONTAINER (container), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return ((0)); } } while (0)
;
8787
8788 return container->details->auto_layout;
8789}
8790
8791gboolean
8792baul_icon_container_is_tighter_layout (BaulIconContainer *container)
8793{
8794 g_return_val_if_fail (BAUL_IS_ICON_CONTAINER (container), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return ((0)); } } while (0)
;
8795
8796 return container->details->tighter_layout;
8797}
8798
8799static void
8800pending_icon_to_rename_destroy_callback (BaulIconCanvasItem *item, BaulIconContainer *container)
8801{
8802 g_assert (container->details->pending_icon_to_rename != NULL)do { if (container->details->pending_icon_to_rename != (
(void*)0)) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 8802, ((const char*) (__func__)), "container->details->pending_icon_to_rename != NULL"
); } while (0)
;
8803 g_assert (container->details->pending_icon_to_rename->item == item)do { if (container->details->pending_icon_to_rename->
item == item) ; else g_assertion_message_expr (((gchar*) 0), "baul-icon-container.c"
, 8803, ((const char*) (__func__)), "container->details->pending_icon_to_rename->item == item"
); } while (0)
;
8804 container->details->pending_icon_to_rename = NULL((void*)0);
8805}
8806
8807static BaulIcon*
8808get_pending_icon_to_rename (BaulIconContainer *container)
8809{
8810 return container->details->pending_icon_to_rename;
8811}
8812
8813static void
8814set_pending_icon_to_rename (BaulIconContainer *container, BaulIcon *icon)
8815{
8816 BaulIcon *old_icon;
8817
8818 old_icon = container->details->pending_icon_to_rename;
8819
8820 if (icon == old_icon)
8821 {
8822 return;
8823 }
8824
8825 if (old_icon != NULL((void*)0))
8826 {
8827 g_signal_handlers_disconnect_by_funcg_signal_handlers_disconnect_matched ((old_icon->item), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (((GCallback) (pending_icon_to_rename_destroy_callback)))
, (container))
8828 (old_icon->item,g_signal_handlers_disconnect_matched ((old_icon->item), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (((GCallback) (pending_icon_to_rename_destroy_callback)))
, (container))
8829 G_CALLBACK (pending_icon_to_rename_destroy_callback),g_signal_handlers_disconnect_matched ((old_icon->item), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (((GCallback) (pending_icon_to_rename_destroy_callback)))
, (container))
8830 container)g_signal_handlers_disconnect_matched ((old_icon->item), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (((GCallback) (pending_icon_to_rename_destroy_callback)))
, (container))
;
8831 }
8832
8833 if (icon != NULL((void*)0))
8834 {
8835 g_signal_connect (icon->item, "destroy",g_signal_connect_data ((icon->item), ("destroy"), (((GCallback
) (pending_icon_to_rename_destroy_callback))), (container), (
(void*)0), (GConnectFlags) 0)
8836 G_CALLBACK (pending_icon_to_rename_destroy_callback), container)g_signal_connect_data ((icon->item), ("destroy"), (((GCallback
) (pending_icon_to_rename_destroy_callback))), (container), (
(void*)0), (GConnectFlags) 0)
;
8837 }
8838
8839 container->details->pending_icon_to_rename = icon;
8840}
8841
8842static void
8843process_pending_icon_to_rename (BaulIconContainer *container)
8844{
8845 BaulIcon *pending_icon_to_rename;
8846
8847 pending_icon_to_rename = get_pending_icon_to_rename (container);
8848
8849 if (pending_icon_to_rename != NULL((void*)0))
8850 {
8851 if (pending_icon_to_rename->is_selected && !has_multiple_selection (container))
8852 {
8853 baul_icon_container_start_renaming_selected_item (container, FALSE(0));
8854 }
8855 else
8856 {
8857 set_pending_icon_to_rename (container, NULL((void*)0));
8858 }
8859 }
8860}
8861
8862static gboolean
8863is_renaming_pending (BaulIconContainer *container)
8864{
8865 return get_pending_icon_to_rename (container) != NULL((void*)0);
8866}
8867
8868static gboolean
8869is_renaming (BaulIconContainer *container)
8870{
8871 return container->details->renaming;
8872}
8873
8874/**
8875 * baul_icon_container_start_renaming_selected_item
8876 * @container: An icon container widget.
8877 * @select_all: Whether the whole file should initially be selected, or
8878 * only its basename (i.e. everything except its extension).
8879 *
8880 * Displays the edit name widget on the first selected icon
8881 **/
8882void
8883baul_icon_container_start_renaming_selected_item (BaulIconContainer *container,
8884 gboolean select_all)
8885{
8886 BaulIconContainerDetails *details;
8887 BaulIcon *icon;
8888 EelDRect icon_rect;
8889 EelDRect text_rect;
8890 PangoFontDescription *desc;
8891 const char *editable_text;
8892 int x, y, width;
8893 int start_offset, end_offset;
8894
8895 /* Check if it already in renaming mode, if so - select all */
8896 details = container->details;
8897 if (details->renaming)
8898 {
8899 eel_editable_label_select_region (EEL_EDITABLE_LABEL (details->rename_widget)((((EelEditableLabel*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((details->rename_widget)), (eel_editable_label_get_type
())))))
,
8900 0,
8901 -1);
8902 return;
8903 }
8904
8905 /* Find selected icon */
8906 icon = get_first_selected_icon (container);
8907 if (icon == NULL((void*)0))
8908 {
8909 return;
8910 }
8911
8912 g_assert (!has_multiple_selection (container))do { if (!has_multiple_selection (container)) ; else g_assertion_message_expr
(((gchar*) 0), "baul-icon-container.c", 8912, ((const char*)
(__func__)), "!has_multiple_selection (container)"); } while
(0)
;
8913
8914
8915 if (!icon_is_positioned (icon))
8916 {
8917 set_pending_icon_to_rename (container, icon);
8918 return;
8919 }
8920
8921 set_pending_icon_to_rename (container, NULL((void*)0));
8922
8923 /* Make a copy of the original editable text for a later compare */
8924 editable_text = baul_icon_canvas_item_get_editable_text (icon->item);
8925
8926 /* This could conceivably be NULL if a rename was triggered really early. */
8927 if (editable_text == NULL((void*)0))
8928 {
8929 return;
8930 }
8931
8932 details->original_text = g_strdup (editable_text)g_strdup_inline (editable_text);
8933
8934 /* Freeze updates so files added while renaming don't cause rename to loose focus, bug #318373 */
8935 baul_icon_container_freeze_updates (container);
8936
8937 /* Create text renaming widget, if it hasn't been created already.
8938 * We deal with the broken icon text item widget by keeping it around
8939 * so its contents can still be cut and pasted as part of the clipboard
8940 */
8941 if (details->rename_widget == NULL((void*)0))
8942 {
8943 details->rename_widget = eel_editable_label_new ("Test text");
8944 eel_editable_label_set_line_wrap (EEL_EDITABLE_LABEL (details->rename_widget)((((EelEditableLabel*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((details->rename_widget)), (eel_editable_label_get_type
())))))
, TRUE(!(0)));
8945 eel_editable_label_set_line_wrap_mode (EEL_EDITABLE_LABEL (details->rename_widget)((((EelEditableLabel*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((details->rename_widget)), (eel_editable_label_get_type
())))))
, PANGO_WRAP_WORD_CHAR);
8946 eel_editable_label_set_draw_outline (EEL_EDITABLE_LABEL (details->rename_widget)((((EelEditableLabel*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((details->rename_widget)), (eel_editable_label_get_type
())))))
, TRUE(!(0)));
8947
8948 if (details->label_position != BAUL_ICON_LABEL_POSITION_BESIDE)
8949 {
8950 eel_editable_label_set_justify (EEL_EDITABLE_LABEL (details->rename_widget)((((EelEditableLabel*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((details->rename_widget)), (eel_editable_label_get_type
())))))
, CTK_JUSTIFY_CENTER);
8951 }
8952
8953 ctk_widget_set_margin_start (details->rename_widget, 1);
8954 ctk_widget_set_margin_end (details->rename_widget, 1);
8955 ctk_widget_set_margin_top (details->rename_widget, 1);
8956 ctk_widget_set_margin_bottom (details->rename_widget, 1);
8957 ctk_layout_put (CTK_LAYOUT (container)((((CtkLayout*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_layout_get_type ()))))))
,
8958 details->rename_widget, 0, 0);
8959 }
8960
8961 /* Set the right font */
8962 if (details->font)
8963 {
8964 desc = pango_font_description_from_string (details->font);
8965 }
8966 else
8967 {
8968 PangoContext *context;
8969
8970 context = ctk_widget_get_pango_context (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
);
8971 desc = pango_font_description_copy (pango_context_get_font_description (context));
8972 pango_font_description_set_size (desc,
8973 pango_font_description_get_size (desc) +
8974 container->details->font_size_table [container->details->zoom_level]);
8975 }
8976 eel_editable_label_set_font_description (EEL_EDITABLE_LABEL (details->rename_widget)((((EelEditableLabel*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((details->rename_widget)), (eel_editable_label_get_type
())))))
,
8977 desc);
8978 pango_font_description_free (desc);
8979
8980 icon_rect = baul_icon_canvas_item_get_icon_rectangle (icon->item);
8981 text_rect = baul_icon_canvas_item_get_text_rectangle (icon->item, TRUE(!(0)));
8982
8983 if (baul_icon_container_is_layout_vertical (container) &&
8984 container->details->label_position == BAUL_ICON_LABEL_POSITION_BESIDE)
8985 {
8986 /* for one-line editables, the width changes dynamically */
8987 width = -1;
8988 }
8989 else
8990 {
8991 width = baul_icon_canvas_item_get_max_text_width (icon->item);
8992 }
8993
8994 if (details->label_position == BAUL_ICON_LABEL_POSITION_BESIDE)
8995 {
8996 eel_canvas_w2c (EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
->canvas,
8997 text_rect.x0,
8998 text_rect.y0,
8999 &x, &y);
9000 }
9001 else
9002 {
9003 eel_canvas_w2c (EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
->canvas,
9004 (icon_rect.x0 + icon_rect.x1) / 2,
9005 icon_rect.y1,
9006 &x, &y);
9007 x = x - width / 2 - 1;
9008 }
9009
9010 ctk_layout_move (CTK_LAYOUT (container)((((CtkLayout*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_layout_get_type ()))))))
,
9011 details->rename_widget,
9012 x, y);
9013
9014 ctk_widget_set_size_request (details->rename_widget,
9015 width, -1);
9016 eel_editable_label_set_text (EEL_EDITABLE_LABEL (details->rename_widget)((((EelEditableLabel*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((details->rename_widget)), (eel_editable_label_get_type
())))))
,
9017 editable_text);
9018 if (select_all)
9019 {
9020 start_offset = 0;
9021 end_offset = -1;
9022 }
9023 else
9024 {
9025 eel_filename_get_rename_region (editable_text, &start_offset, &end_offset);
9026 }
9027 ctk_widget_show (details->rename_widget);
9028 ctk_widget_grab_focus (details->rename_widget);
9029
9030 eel_editable_label_select_region (EEL_EDITABLE_LABEL (details->rename_widget)((((EelEditableLabel*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((details->rename_widget)), (eel_editable_label_get_type
())))))
,
9031 start_offset,
9032 end_offset);
9033 g_signal_emit (container,
9034 signals[RENAMING_ICON], 0,
9035 CTK_EDITABLE (details->rename_widget)((((CtkEditable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((details->rename_widget)), ((ctk_editable_get_type ())
)))))
);
9036
9037 baul_icon_container_update_icon (container, icon);
9038
9039 /* We are in renaming mode */
9040 details->renaming = TRUE(!(0));
9041 baul_icon_canvas_item_set_renaming (icon->item, TRUE(!(0)));
9042}
9043
9044static void
9045end_renaming_mode (BaulIconContainer *container, gboolean commit)
9046{
9047 BaulIcon *icon;
9048
9049 set_pending_icon_to_rename (container, NULL((void*)0));
9050
9051 icon = get_icon_being_renamed (container);
9052 if (icon == NULL((void*)0))
9053 {
9054 return;
9055 }
9056
9057 /* We are not in renaming mode */
9058 container->details->renaming = FALSE(0);
9059 baul_icon_canvas_item_set_renaming (icon->item, FALSE(0));
9060
9061 baul_icon_container_unfreeze_updates (container);
9062
9063 if (commit)
9064 {
9065 set_pending_icon_to_reveal (container, icon);
9066 }
9067
9068 ctk_widget_grab_focus (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
);
9069
9070 if (commit)
9071 {
9072 const char *changed_text;
9073
9074 /* Verify that text has been modified before signalling change. */
9075 changed_text = eel_editable_label_get_text (EEL_EDITABLE_LABEL (container->details->rename_widget)((((EelEditableLabel*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((container->details->rename_widget)), (
eel_editable_label_get_type())))))
);
9076 if (strcmp (container->details->original_text, changed_text) != 0)
9077 {
9078 AtkObject *accessible_icon;
9079
9080 g_signal_emit (container,
9081 signals[ICON_TEXT_CHANGED], 0,
9082 icon->data,
9083 changed_text);
9084
9085 accessible_icon = atk_gobject_accessible_for_object (G_OBJECT(icon->item)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), (((GType) ((20) << (2))))))))
);
9086 g_object_notify (G_OBJECT(accessible_icon)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible_icon)), (((GType) ((20) << (2))))))))
, "accessible-name");
9087 }
9088 }
9089
9090 ctk_widget_hide (container->details->rename_widget);
9091
9092 g_free (container->details->original_text);
9093
9094}
9095
9096/* emit preview signal, called by the canvas item */
9097gboolean
9098baul_icon_container_emit_preview_signal (BaulIconContainer *icon_container,
9099 BaulIcon *icon,
9100 gboolean start_flag)
9101{
9102 gboolean result;
9103
9104 g_return_val_if_fail (BAUL_IS_ICON_CONTAINER (icon_container), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((icon_container)); GType __t = (baul_icon_container_get_type
()); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (icon_container)"
); return ((0)); } } while (0)
;
9105 g_return_val_if_fail (icon != NULL, FALSE)do { if ((icon != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "icon != NULL"); return
((0)); } } while (0)
;
9106 g_return_val_if_fail (start_flag == FALSE || start_flag == TRUE, FALSE)do { if ((start_flag == (0) || start_flag == (!(0)))) { } else
{ g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__
)), "start_flag == FALSE || start_flag == TRUE"); return ((0)
); } } while (0)
;
9107
9108 result = FALSE(0);
9109 g_signal_emit (icon_container,
9110 signals[PREVIEW], 0,
9111 icon->data,
9112 start_flag,
9113 &result);
9114
9115 return result;
9116}
9117
9118gboolean
9119baul_icon_container_has_stored_icon_positions (BaulIconContainer *container)
9120{
9121 GList *p;
9122 gboolean have_stored_position;
9123 BaulIconPosition position;
9124 BaulIcon *icon = NULL((void*)0);
9125
9126 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
9127 {
9128 icon = p->data;
9129
9130 have_stored_position = FALSE(0);
9131 g_signal_emit (container,
9132 signals[GET_STORED_ICON_POSITION], 0,
9133 icon->data,
9134 &position,
9135 &have_stored_position);
9136 if (have_stored_position)
9137 {
9138 return TRUE(!(0));
9139 }
9140 }
9141 return FALSE(0);
9142}
9143
9144void
9145baul_icon_container_set_single_click_mode (BaulIconContainer *container,
9146 gboolean single_click_mode)
9147{
9148 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
9149
9150 container->details->single_click_mode = single_click_mode;
9151}
9152
9153/* Return if the icon container is a fixed size */
9154gboolean
9155baul_icon_container_get_is_fixed_size (BaulIconContainer *container)
9156{
9157 g_return_val_if_fail (BAUL_IS_ICON_CONTAINER (container), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return ((0)); } } while (0)
;
9158
9159 return container->details->is_fixed_size;
9160}
9161
9162/* Set the icon container to be a fixed size */
9163void
9164baul_icon_container_set_is_fixed_size (BaulIconContainer *container,
9165 gboolean is_fixed_size)
9166{
9167 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
9168
9169 container->details->is_fixed_size = is_fixed_size;
9170}
9171
9172gboolean
9173baul_icon_container_get_is_desktop (BaulIconContainer *container)
9174{
9175 g_return_val_if_fail (BAUL_IS_ICON_CONTAINER (container), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return ((0)); } } while (0)
;
9176
9177 return container->details->is_desktop;
9178}
9179
9180void
9181baul_icon_container_set_is_desktop (BaulIconContainer *container,
9182 gboolean is_desktop)
9183{
9184 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
9185
9186 container->details->is_desktop = is_desktop;
9187
9188 if (is_desktop) {
9189 CtkStyleContext *context;
9190
9191 context = ctk_widget_get_style_context (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
);
9192 ctk_style_context_add_class (context, "baul-desktop");
9193 }
9194}
9195
9196void
9197baul_icon_container_set_margins (BaulIconContainer *container,
9198 int left_margin,
9199 int right_margin,
9200 int top_margin,
9201 int bottom_margin)
9202{
9203 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
9204
9205 container->details->left_margin = left_margin;
9206 container->details->right_margin = right_margin;
9207 container->details->top_margin = top_margin;
9208 container->details->bottom_margin = bottom_margin;
9209
9210 /* redo layout of icons as the margins have changed */
9211 schedule_redo_layout (container);
9212}
9213
9214void
9215baul_icon_container_set_use_drop_shadows (BaulIconContainer *container,
9216 gboolean use_drop_shadows)
9217{
9218 if (container->details->drop_shadows_requested == use_drop_shadows)
9219 {
9220 return;
9221 }
9222
9223 container->details->drop_shadows_requested = use_drop_shadows;
9224 container->details->use_drop_shadows = use_drop_shadows;
9225
9226 ctk_widget_queue_draw (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
);
9227}
9228
9229/* handle theme changes */
9230
9231void
9232baul_icon_container_set_font (BaulIconContainer *container,
9233 const char *font)
9234{
9235 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
9236
9237 if (g_strcmp0 (container->details->font, font) == 0)
9238 {
9239 return;
9240 }
9241
9242 g_free (container->details->font);
9243 container->details->font = g_strdup (font)g_strdup_inline (font);
9244
9245 invalidate_labels (container);
9246 baul_icon_container_request_update_all (container);
9247 ctk_widget_queue_draw (CTK_WIDGET (container)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((ctk_widget_get_type ()))))))
);
9248}
9249
9250void
9251baul_icon_container_set_font_size_table (BaulIconContainer *container,
9252 const int font_size_table[BAUL_ZOOM_LEVEL_LARGEST + 1])
9253{
9254 int old_font_size;
9255 int i;
9256
9257 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
9258 g_return_if_fail (font_size_table != NULL)do { if ((font_size_table != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "font_size_table != NULL"
); return; } } while (0)
;
9259
9260 old_font_size = container->details->font_size_table[container->details->zoom_level];
9261
9262 for (i = 0; i <= BAUL_ZOOM_LEVEL_LARGEST; i++)
9263 {
9264 if (container->details->font_size_table[i] != font_size_table[i])
9265 {
9266 container->details->font_size_table[i] = font_size_table[i];
9267 }
9268 }
9269
9270 if (old_font_size != container->details->font_size_table[container->details->zoom_level])
9271 {
9272 invalidate_labels (container);
9273 baul_icon_container_request_update_all (container);
9274 }
9275}
9276
9277/**
9278 * baul_icon_container_get_icon_description
9279 * @container: An icon container widget.
9280 * @data: Icon data
9281 *
9282 * Gets the description for the icon. This function may return NULL.
9283 **/
9284char*
9285baul_icon_container_get_icon_description (BaulIconContainer *container,
9286 BaulIconData *data)
9287{
9288 BaulIconContainerClass *klass;
9289
9290 klass = BAUL_ICON_CONTAINER_GET_CLASS (container)((((BaulIconContainerClass*) (((GTypeInstance*) ((container))
)->g_class))))
;
9291
9292 if (klass->get_icon_description)
9293 {
9294 return klass->get_icon_description (container, data);
9295 }
9296 else
9297 {
9298 return NULL((void*)0);
9299 }
9300}
9301
9302gboolean
9303baul_icon_container_get_allow_moves (BaulIconContainer *container)
9304{
9305 g_return_val_if_fail (BAUL_IS_ICON_CONTAINER (container), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return ((0)); } } while (0)
;
9306
9307 return container->details->drag_allow_moves;
9308}
9309
9310void
9311baul_icon_container_set_allow_moves (BaulIconContainer *container,
9312 gboolean allow_moves)
9313{
9314 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
9315
9316 container->details->drag_allow_moves = allow_moves;
9317}
9318
9319void
9320baul_icon_container_set_forced_icon_size (BaulIconContainer *container,
9321 int forced_icon_size)
9322{
9323 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
9324
9325 if (forced_icon_size != container->details->forced_icon_size)
9326 {
9327 container->details->forced_icon_size = forced_icon_size;
9328
9329 invalidate_label_sizes (container);
9330 baul_icon_container_request_update_all (container);
9331 }
9332}
9333
9334void
9335baul_icon_container_set_all_columns_same_width (BaulIconContainer *container,
9336 gboolean all_columns_same_width)
9337{
9338 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
9339
9340 if (all_columns_same_width != container->details->all_columns_same_width)
9341 {
9342 container->details->all_columns_same_width = all_columns_same_width;
9343
9344 invalidate_labels (container);
9345 baul_icon_container_request_update_all (container);
9346 }
9347}
9348
9349/**
9350 * baul_icon_container_set_highlighted_for_clipboard
9351 * @container: An icon container widget.
9352 * @data: Icon Data associated with all icons that should be highlighted.
9353 * Others will be unhighlighted.
9354 **/
9355void
9356baul_icon_container_set_highlighted_for_clipboard (BaulIconContainer *container,
9357 GList *clipboard_icon_data)
9358{
9359 GList *l;
9360 gboolean highlighted_for_clipboard;
9361 BaulIcon *icon = NULL((void*)0);
9362
9363 g_return_if_fail (BAUL_IS_ICON_CONTAINER (container))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return; } } while (0)
;
9364
9365 for (l = container->details->icons; l != NULL((void*)0); l = l->next)
9366 {
9367 icon = l->data;
9368 highlighted_for_clipboard = (g_list_find (clipboard_icon_data, icon->data) != NULL((void*)0));
9369
9370 eel_canvas_item_set (EEL_CANVAS_ITEM (icon->item)((((EelCanvasItem*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), ((eel_canvas_item_get_type ()))))))
,
9371 "highlighted-for-clipboard", highlighted_for_clipboard,
9372 NULL((void*)0));
9373 }
9374
9375}
9376
9377/* BaulIconContainerAccessible */
9378
9379static BaulIconContainerAccessiblePrivate *
9380accessible_get_priv (AtkObject *accessible)
9381{
9382 BaulIconContainerAccessiblePrivate *priv;
9383
9384 priv = g_object_get_qdata (G_OBJECT (accessible)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), (((GType) ((20) << (2))))))))
,
9385 accessible_private_data_quark);
9386
9387 return priv;
9388}
9389
9390/* AtkAction interface */
9391
9392static gboolean
9393baul_icon_container_accessible_do_action (AtkAction *accessible, int i)
9394{
9395 CtkWidget *widget;
9396 BaulIconContainer *container;
9397 GList *selection;
9398
9399 g_return_val_if_fail (i < LAST_ACTION, FALSE)do { if ((i < LAST_ACTION)) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "i < LAST_ACTION"
); return ((0)); } } while (0)
;
9400
9401 widget = ctk_accessible_get_widget (CTK_ACCESSIBLE (accessible)((((CtkAccessible*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((ctk_accessible_get_type ()))))))
);
9402 if (!widget)
9403 {
9404 return FALSE(0);
9405 }
9406
9407 container = BAUL_ICON_CONTAINER (widget)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((widget)), (baul_icon_container_get_type())
))))
;
9408 switch (i)
9409 {
9410 case ACTION_ACTIVATE :
9411 selection = baul_icon_container_get_selection (container);
9412
9413 if (selection)
9414 {
9415 g_signal_emit_by_name (container, "activate", selection);
9416 g_list_free (selection);
9417 }
9418 break;
9419 case ACTION_MENU :
9420 handle_popups (container, NULL((void*)0),"context_click_background");
9421 break;
9422 default :
9423 g_warning ("Invalid action passed to BaulIconContainerAccessible::do_action");
9424 return FALSE(0);
9425 }
9426 return TRUE(!(0));
9427}
9428
9429static int
9430baul_icon_container_accessible_get_n_actions (AtkAction *accessible G_GNUC_UNUSED__attribute__ ((__unused__)))
9431{
9432 return LAST_ACTION;
9433}
9434
9435static const char *
9436baul_icon_container_accessible_action_get_description (AtkAction *accessible,
9437 int i)
9438{
9439 BaulIconContainerAccessiblePrivate *priv;
9440
9441 g_assert (i < LAST_ACTION)do { if (i < LAST_ACTION) ; else g_assertion_message_expr (
((gchar*) 0), "baul-icon-container.c", 9441, ((const char*) (
__func__)), "i < LAST_ACTION"); } while (0)
;
9442
9443 priv = accessible_get_priv (ATK_OBJECT (accessible)((((AtkObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((atk_object_get_type ()))))))
);
9444
9445 if (priv->action_descriptions[i])
9446 {
9447 return priv->action_descriptions[i];
9448 }
9449 else
9450 {
9451 return baul_icon_container_accessible_action_descriptions[i];
9452 }
9453}
9454
9455static const char *
9456baul_icon_container_accessible_action_get_name (AtkAction *accessible G_GNUC_UNUSED__attribute__ ((__unused__)),
9457 int i)
9458{
9459 g_assert (i < LAST_ACTION)do { if (i < LAST_ACTION) ; else g_assertion_message_expr (
((gchar*) 0), "baul-icon-container.c", 9459, ((const char*) (
__func__)), "i < LAST_ACTION"); } while (0)
;
9460
9461 return baul_icon_container_accessible_action_names[i];
9462}
9463
9464static const char *
9465baul_icon_container_accessible_action_get_keybinding (AtkAction *accessible G_GNUC_UNUSED__attribute__ ((__unused__)),
9466 int i)
9467{
9468 g_assert (i < LAST_ACTION)do { if (i < LAST_ACTION) ; else g_assertion_message_expr (
((gchar*) 0), "baul-icon-container.c", 9468, ((const char*) (
__func__)), "i < LAST_ACTION"); } while (0)
;
9469
9470 return NULL((void*)0);
9471}
9472
9473static gboolean
9474baul_icon_container_accessible_action_set_description (AtkAction *accessible,
9475 int i,
9476 const char *description)
9477{
9478 BaulIconContainerAccessiblePrivate *priv;
9479
9480 g_assert (i < LAST_ACTION)do { if (i < LAST_ACTION) ; else g_assertion_message_expr (
((gchar*) 0), "baul-icon-container.c", 9480, ((const char*) (
__func__)), "i < LAST_ACTION"); } while (0)
;
9481
9482 priv = accessible_get_priv (ATK_OBJECT (accessible)((((AtkObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((atk_object_get_type ()))))))
);
9483
9484 if (priv->action_descriptions[i])
9485 {
9486 g_free (priv->action_descriptions[i]);
9487 }
9488 priv->action_descriptions[i] = g_strdup (description)g_strdup_inline (description);
9489
9490 return FALSE(0);
9491}
9492
9493static void
9494baul_icon_container_accessible_action_interface_init (AtkActionIface *iface)
9495{
9496 iface->do_action = baul_icon_container_accessible_do_action;
9497 iface->get_n_actions = baul_icon_container_accessible_get_n_actions;
9498 iface->get_description = baul_icon_container_accessible_action_get_description;
9499 iface->get_name = baul_icon_container_accessible_action_get_name;
9500 iface->get_keybinding = baul_icon_container_accessible_action_get_keybinding;
9501 iface->set_description = baul_icon_container_accessible_action_set_description;
9502}
9503
9504/* AtkSelection interface */
9505
9506static void
9507baul_icon_container_accessible_update_selection (AtkObject *accessible)
9508{
9509 BaulIconContainer *container;
9510 BaulIconContainerAccessiblePrivate *priv;
9511 GList *l;
9512 BaulIcon *icon = NULL((void*)0);
9513
9514 container = BAUL_ICON_CONTAINER (ctk_accessible_get_widget (CTK_ACCESSIBLE (accessible)))((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((ctk_accessible_get_widget (((((CtkAccessible
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((accessible
)), ((ctk_accessible_get_type ()))))))))), (baul_icon_container_get_type
())))))
;
9515
9516 priv = accessible_get_priv (accessible);
9517
9518 if (priv->selection)
9519 {
9520 g_list_free (priv->selection);
9521 priv->selection = NULL((void*)0);
9522 }
9523
9524 for (l = container->details->icons; l != NULL((void*)0); l = l->next)
9525 {
9526 icon = l->data;
9527 if (icon->is_selected)
9528 {
9529 priv->selection = g_list_prepend (priv->selection,
9530 icon);
9531 }
9532 }
9533
9534 priv->selection = g_list_reverse (priv->selection);
9535}
9536
9537static void
9538baul_icon_container_accessible_selection_changed_cb (BaulIconContainer *container G_GNUC_UNUSED__attribute__ ((__unused__)),
9539 gpointer data)
9540{
9541 g_signal_emit_by_name (data, "selection_changed");
9542}
9543
9544static void
9545baul_icon_container_accessible_icon_added_cb (BaulIconContainer *container,
9546 BaulIconData *icon_data,
9547 gpointer data)
9548{
9549 BaulIcon *icon;
9550
9551 // We don't want to emit children_changed signals during any type of load.
9552 if (container->details->is_loading || container->details->is_populating_container)
9553 return;
9554
9555 icon = g_hash_table_lookup (container->details->icon_set, icon_data);
9556 if (icon)
9557 {
9558 AtkObject *atk_parent;
9559 AtkObject *atk_child;
9560 int index;
9561
9562 atk_parent = ATK_OBJECT (data)((((AtkObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data)), ((atk_object_get_type ()))))))
;
9563 atk_child = atk_gobject_accessible_for_object
9564 (G_OBJECT (icon->item)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), (((GType) ((20) << (2))))))))
);
9565 index = g_list_index (container->details->icons, icon);
9566
9567 g_signal_emit_by_name (atk_parent, "children_changed::add",
9568 index, atk_child, NULL((void*)0));
9569 }
9570}
9571
9572static void
9573baul_icon_container_accessible_icon_removed_cb (BaulIconContainer *container,
9574 BaulIconData *icon_data,
9575 gpointer data)
9576{
9577 BaulIcon *icon;
9578
9579 icon = g_hash_table_lookup (container->details->icon_set, icon_data);
9580 if (icon)
9581 {
9582 AtkObject *atk_parent;
9583 AtkObject *atk_child;
9584 int index;
9585
9586 atk_parent = ATK_OBJECT (data)((((AtkObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data)), ((atk_object_get_type ()))))))
;
9587 atk_child = atk_gobject_accessible_for_object
9588 (G_OBJECT (icon->item)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), (((GType) ((20) << (2))))))))
);
9589 index = g_list_index (container->details->icons, icon);
9590
9591 g_signal_emit_by_name (atk_parent, "children_changed::remove",
9592 index, atk_child, NULL((void*)0));
9593 }
9594}
9595
9596static void
9597baul_icon_container_accessible_cleared_cb (BaulIconContainer *container G_GNUC_UNUSED__attribute__ ((__unused__)),
9598 gpointer data)
9599{
9600 g_signal_emit_by_name (data, "children_changed", 0, NULL((void*)0), NULL((void*)0));
9601}
9602
9603
9604static gboolean
9605baul_icon_container_accessible_add_selection (AtkSelection *accessible,
9606 int i)
9607{
9608 CtkWidget *widget;
9609 BaulIconContainer *container;
9610 BaulIcon *icon;
9611
9612 widget = ctk_accessible_get_widget (CTK_ACCESSIBLE (accessible)((((CtkAccessible*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((ctk_accessible_get_type ()))))))
);
9613 if (!widget)
9614 {
9615 return FALSE(0);
9616 }
9617
9618 container = BAUL_ICON_CONTAINER (widget)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((widget)), (baul_icon_container_get_type())
))))
;
9619
9620 icon = g_list_nth_data (container->details->icons, i);
9621 if (icon)
9622 {
9623 GList *selection;
9624
9625 selection = baul_icon_container_get_selection (container);
9626 selection = g_list_prepend (selection,
9627 icon->data);
9628 baul_icon_container_set_selection (container, selection);
9629
9630 g_list_free (selection);
9631 return TRUE(!(0));
9632 }
9633
9634 return FALSE(0);
9635}
9636
9637static gboolean
9638baul_icon_container_accessible_clear_selection (AtkSelection *accessible)
9639{
9640 CtkWidget *widget;
9641 BaulIconContainer *container;
9642
9643 widget = ctk_accessible_get_widget (CTK_ACCESSIBLE (accessible)((((CtkAccessible*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((ctk_accessible_get_type ()))))))
);
9644 if (!widget)
9645 {
9646 return FALSE(0);
9647 }
9648
9649 container = BAUL_ICON_CONTAINER (widget)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((widget)), (baul_icon_container_get_type())
))))
;
9650
9651 baul_icon_container_unselect_all (container);
9652
9653 return TRUE(!(0));
9654}
9655
9656static AtkObject *
9657baul_icon_container_accessible_ref_selection (AtkSelection *accessible,
9658 int i)
9659{
9660 BaulIconContainerAccessiblePrivate *priv;
9661 BaulIcon *icon;
9662
9663 baul_icon_container_accessible_update_selection (ATK_OBJECT (accessible)((((AtkObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((atk_object_get_type ()))))))
);
9664 priv = accessible_get_priv (ATK_OBJECT (accessible)((((AtkObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((atk_object_get_type ()))))))
);
9665
9666 icon = g_list_nth_data (priv->selection, i);
9667 if (icon)
9668 {
9669 AtkObject *atk_object;
9670
9671 atk_object = atk_gobject_accessible_for_object (G_OBJECT (icon->item)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), (((GType) ((20) << (2))))))))
);
9672 if (atk_object)
9673 {
9674 g_object_ref (atk_object)((__typeof__ (atk_object)) (g_object_ref) (atk_object));
9675 }
9676
9677 return atk_object;
9678 }
9679 else
9680 {
9681 return NULL((void*)0);
9682 }
9683}
9684
9685static int
9686baul_icon_container_accessible_get_selection_count (AtkSelection *accessible)
9687{
9688 int count;
9689 BaulIconContainerAccessiblePrivate *priv;
9690
9691 baul_icon_container_accessible_update_selection (ATK_OBJECT (accessible)((((AtkObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((atk_object_get_type ()))))))
);
9692 priv = accessible_get_priv (ATK_OBJECT (accessible)((((AtkObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((atk_object_get_type ()))))))
);
9693
9694 count = g_list_length (priv->selection);
9695
9696 return count;
9697}
9698
9699static gboolean
9700baul_icon_container_accessible_is_child_selected (AtkSelection *accessible,
9701 int i)
9702{
9703 BaulIconContainer *container;
9704 BaulIcon *icon;
9705 CtkWidget *widget;
9706
9707 widget = ctk_accessible_get_widget (CTK_ACCESSIBLE (accessible)((((CtkAccessible*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((ctk_accessible_get_type ()))))))
);
9708 if (!widget)
9709 {
9710 return FALSE(0);
9711 }
9712
9713 container = BAUL_ICON_CONTAINER (widget)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((widget)), (baul_icon_container_get_type())
))))
;
9714
9715 icon = g_list_nth_data (container->details->icons, i);
9716 return icon ? icon->is_selected : FALSE(0);
9717}
9718
9719static gboolean
9720baul_icon_container_accessible_remove_selection (AtkSelection *accessible,
9721 int i)
9722{
9723 BaulIconContainer *container;
9724 BaulIconContainerAccessiblePrivate *priv;
9725 BaulIcon *icon;
9726 CtkWidget *widget;
9727
9728 widget = ctk_accessible_get_widget (CTK_ACCESSIBLE (accessible)((((CtkAccessible*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((ctk_accessible_get_type ()))))))
);
9729 if (!widget)
9730 {
9731 return FALSE(0);
9732 }
9733
9734 baul_icon_container_accessible_update_selection (ATK_OBJECT (accessible)((((AtkObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((atk_object_get_type ()))))))
);
9735 priv = accessible_get_priv (ATK_OBJECT (accessible)((((AtkObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((atk_object_get_type ()))))))
);
9736
9737 container = BAUL_ICON_CONTAINER (widget)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((widget)), (baul_icon_container_get_type())
))))
;
9738
9739 icon = g_list_nth_data (priv->selection, i);
9740 if (icon)
9741 {
9742 GList *selection;
9743
9744 selection = baul_icon_container_get_selection (container);
9745 selection = g_list_remove (selection, icon->data);
9746 baul_icon_container_set_selection (container, selection);
9747
9748 g_list_free (selection);
9749 return TRUE(!(0));
9750 }
9751
9752 return FALSE(0);
9753}
9754
9755static gboolean
9756baul_icon_container_accessible_select_all_selection (AtkSelection *accessible)
9757{
9758 BaulIconContainer *container;
9759 CtkWidget *widget;
9760
9761 widget = ctk_accessible_get_widget (CTK_ACCESSIBLE (accessible)((((CtkAccessible*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((ctk_accessible_get_type ()))))))
);
9762 if (!widget)
9763 {
9764 return FALSE(0);
9765 }
9766
9767 container = BAUL_ICON_CONTAINER (widget)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((widget)), (baul_icon_container_get_type())
))))
;
9768
9769 baul_icon_container_select_all (container);
9770
9771 return TRUE(!(0));
9772}
9773
9774void
9775baul_icon_container_widget_to_file_operation_position (BaulIconContainer *container,
9776 CdkPoint *position)
9777{
9778 double x, y;
9779
9780 g_return_if_fail (position != NULL)do { if ((position != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "position != NULL"
); return; } } while (0)
;
9781
9782 x = position->x;
9783 y = position->y;
9784
9785 eel_canvas_window_to_world (EEL_CANVAS (container)((((EelCanvas*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((container)), ((eel_canvas_get_type ()))))))
, x, y, &x, &y);
9786
9787 position->x = (int) x;
9788 position->y = (int) y;
9789
9790 /* ensure that we end up in the middle of the icon */
9791 position->x -= baul_get_icon_size_for_zoom_level (container->details->zoom_level) / 2;
9792 position->y -= baul_get_icon_size_for_zoom_level (container->details->zoom_level) / 2;
9793}
9794
9795static void
9796baul_icon_container_accessible_selection_interface_init (AtkSelectionIface *iface)
9797{
9798 iface->add_selection = baul_icon_container_accessible_add_selection;
9799 iface->clear_selection = baul_icon_container_accessible_clear_selection;
9800 iface->ref_selection = baul_icon_container_accessible_ref_selection;
9801 iface->get_selection_count = baul_icon_container_accessible_get_selection_count;
9802 iface->is_child_selected = baul_icon_container_accessible_is_child_selected;
9803 iface->remove_selection = baul_icon_container_accessible_remove_selection;
9804 iface->select_all_selection = baul_icon_container_accessible_select_all_selection;
9805}
9806
9807
9808static gint
9809baul_icon_container_accessible_get_n_children (AtkObject *accessible)
9810{
9811 BaulIconContainer *container;
9812 CtkWidget *widget;
9813 gint i;
9814
9815 widget = ctk_accessible_get_widget (CTK_ACCESSIBLE (accessible)((((CtkAccessible*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((ctk_accessible_get_type ()))))))
);
9816 if (!widget)
9817 {
9818 return FALSE(0);
9819 }
9820
9821 container = BAUL_ICON_CONTAINER (widget)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((widget)), (baul_icon_container_get_type())
))))
;
9822
9823 i = g_hash_table_size (container->details->icon_set);
9824 if (container->details->rename_widget)
9825 {
9826 i++;
9827 }
9828 return i;
9829}
9830
9831static AtkObject*
9832baul_icon_container_accessible_ref_child (AtkObject *accessible, int i)
9833{
9834 AtkObject *atk_object;
9835 BaulIconContainer *container;
9836 BaulIcon *icon;
9837 CtkWidget *widget;
9838
9839 widget = ctk_accessible_get_widget (CTK_ACCESSIBLE (accessible)((((CtkAccessible*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((ctk_accessible_get_type ()))))))
);
9840 if (!widget)
9841 {
9842 return NULL((void*)0);
9843 }
9844
9845 container = BAUL_ICON_CONTAINER (widget)((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((widget)), (baul_icon_container_get_type())
))))
;
9846
9847 icon = g_list_nth_data (container->details->icons, i);
9848 if (icon)
9849 {
9850 atk_object = atk_gobject_accessible_for_object (G_OBJECT (icon->item)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon->item)), (((GType) ((20) << (2))))))))
);
9851 g_object_ref (atk_object)((__typeof__ (atk_object)) (g_object_ref) (atk_object));
9852
9853 return atk_object;
9854 }
9855 else
9856 {
9857 if (i == g_list_length (container->details->icons))
9858 {
9859 if (container->details->rename_widget)
9860 {
9861 atk_object = ctk_widget_get_accessible (container->details->rename_widget);
9862 g_object_ref (atk_object)((__typeof__ (atk_object)) (g_object_ref) (atk_object));
9863
9864 return atk_object;
9865 }
9866 }
9867 return NULL((void*)0);
9868 }
9869}
9870
9871static void
9872baul_icon_container_accessible_initialize (AtkObject *accessible,
9873 gpointer data)
9874{
9875 BaulIconContainerAccessiblePrivate *priv;
9876
9877 if (ATK_OBJECT_CLASS (accessible_parent_class)((((AtkObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((accessible_parent_class)), ((atk_object_get_type ())))))
)
->initialize)
9878 {
9879 ATK_OBJECT_CLASS (accessible_parent_class)((((AtkObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((accessible_parent_class)), ((atk_object_get_type ())))))
)
->initialize (accessible, data);
9880 }
9881
9882 priv = g_new0 (BaulIconContainerAccessiblePrivate, 1)((BaulIconContainerAccessiblePrivate *) g_malloc0_n ((1), sizeof
(BaulIconContainerAccessiblePrivate)))
;
9883 g_object_set_qdata (G_OBJECT (accessible)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), (((GType) ((20) << (2))))))))
,
9884 accessible_private_data_quark,
9885 priv);
9886
9887 if (CTK_IS_ACCESSIBLE (accessible)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(accessible)); GType __t = ((ctk_accessible_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
9888 {
9889 BaulIconContainer *container;
9890
9891 baul_icon_container_accessible_update_selection
9892 (ATK_OBJECT (accessible)((((AtkObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((accessible)), ((atk_object_get_type ()))))))
);
9893
9894 container = BAUL_ICON_CONTAINER (ctk_accessible_get_widget (CTK_ACCESSIBLE (accessible)))((((BaulIconContainer*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((ctk_accessible_get_widget (((((CtkAccessible
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((accessible
)), ((ctk_accessible_get_type ()))))))))), (baul_icon_container_get_type
())))))
;
9895 g_signal_connect (G_OBJECT (container), "selection_changed",g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), (((GType) ((20) << (2
))))))))), ("selection_changed"), (((GCallback) (baul_icon_container_accessible_selection_changed_cb
))), (accessible), ((void*)0), (GConnectFlags) 0)
9896 G_CALLBACK (baul_icon_container_accessible_selection_changed_cb),g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), (((GType) ((20) << (2
))))))))), ("selection_changed"), (((GCallback) (baul_icon_container_accessible_selection_changed_cb
))), (accessible), ((void*)0), (GConnectFlags) 0)
9897 accessible)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), (((GType) ((20) << (2
))))))))), ("selection_changed"), (((GCallback) (baul_icon_container_accessible_selection_changed_cb
))), (accessible), ((void*)0), (GConnectFlags) 0)
;
9898 g_signal_connect (G_OBJECT (container), "icon_added",g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), (((GType) ((20) << (2
))))))))), ("icon_added"), (((GCallback) (baul_icon_container_accessible_icon_added_cb
))), (accessible), ((void*)0), (GConnectFlags) 0)
9899 G_CALLBACK (baul_icon_container_accessible_icon_added_cb),g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), (((GType) ((20) << (2
))))))))), ("icon_added"), (((GCallback) (baul_icon_container_accessible_icon_added_cb
))), (accessible), ((void*)0), (GConnectFlags) 0)
9900 accessible)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), (((GType) ((20) << (2
))))))))), ("icon_added"), (((GCallback) (baul_icon_container_accessible_icon_added_cb
))), (accessible), ((void*)0), (GConnectFlags) 0)
;
9901 g_signal_connect (G_OBJECT (container), "icon_removed",g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), (((GType) ((20) << (2
))))))))), ("icon_removed"), (((GCallback) (baul_icon_container_accessible_icon_removed_cb
))), (accessible), ((void*)0), (GConnectFlags) 0)
9902 G_CALLBACK (baul_icon_container_accessible_icon_removed_cb),g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), (((GType) ((20) << (2
))))))))), ("icon_removed"), (((GCallback) (baul_icon_container_accessible_icon_removed_cb
))), (accessible), ((void*)0), (GConnectFlags) 0)
9903 accessible)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), (((GType) ((20) << (2
))))))))), ("icon_removed"), (((GCallback) (baul_icon_container_accessible_icon_removed_cb
))), (accessible), ((void*)0), (GConnectFlags) 0)
;
9904 g_signal_connect (G_OBJECT (container), "cleared",g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), (((GType) ((20) << (2
))))))))), ("cleared"), (((GCallback) (baul_icon_container_accessible_cleared_cb
))), (accessible), ((void*)0), (GConnectFlags) 0)
9905 G_CALLBACK (baul_icon_container_accessible_cleared_cb),g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), (((GType) ((20) << (2
))))))))), ("cleared"), (((GCallback) (baul_icon_container_accessible_cleared_cb
))), (accessible), ((void*)0), (GConnectFlags) 0)
9906 accessible)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((container)), (((GType) ((20) << (2
))))))))), ("cleared"), (((GCallback) (baul_icon_container_accessible_cleared_cb
))), (accessible), ((void*)0), (GConnectFlags) 0)
;
9907 }
9908}
9909
9910static void
9911baul_icon_container_accessible_finalize (GObject *object)
9912{
9913 BaulIconContainerAccessiblePrivate *priv;
9914 int i;
9915
9916 priv = accessible_get_priv (ATK_OBJECT (object)((((AtkObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((atk_object_get_type ()))))))
);
9917 if (priv->selection)
9918 {
9919 g_list_free (priv->selection);
9920 }
9921
9922 for (i = 0; i < LAST_ACTION; i++)
9923 {
9924 if (priv->action_descriptions[i])
9925 {
9926 g_free (priv->action_descriptions[i]);
9927 }
9928 }
9929
9930 g_free (priv);
9931
9932 G_OBJECT_CLASS (accessible_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((accessible_parent_class)), (((GType) ((20) << (2))
))))))
->finalize (object);
9933}
9934
9935G_DEFINE_TYPE_WITH_CODE (BaulIconContainerAccessible,static void baul_icon_container_accessible_init (BaulIconContainerAccessible
*self); static void baul_icon_container_accessible_class_init
(BaulIconContainerAccessibleClass *klass); static GType baul_icon_container_accessible_get_type_once
(void); static gpointer baul_icon_container_accessible_parent_class
= ((void*)0); static gint BaulIconContainerAccessible_private_offset
; static void baul_icon_container_accessible_class_intern_init
(gpointer klass) { baul_icon_container_accessible_parent_class
= g_type_class_peek_parent (klass); if (BaulIconContainerAccessible_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &BaulIconContainerAccessible_private_offset
); baul_icon_container_accessible_class_init ((BaulIconContainerAccessibleClass
*) klass); } __attribute__ ((__unused__)) static inline gpointer
baul_icon_container_accessible_get_instance_private (BaulIconContainerAccessible
*self) { return (((gpointer) ((guint8*) (self) + (glong) (BaulIconContainerAccessible_private_offset
)))); } GType baul_icon_container_accessible_get_type (void) {
static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= baul_icon_container_accessible_get_type_once (); (__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); 0 ? (void
) (*(&static_g_define_type_id) = (g_define_type_id)) : (void
) 0; g_once_init_leave_pointer ((&static_g_define_type_id
), (gpointer) (guintptr) (g_define_type_id)); })) ; } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType baul_icon_container_accessible_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(eel_canvas_accessible_get_type (), g_intern_static_string (
"BaulIconContainerAccessible"), sizeof (BaulIconContainerAccessibleClass
), (GClassInitFunc)(void (*)(void)) baul_icon_container_accessible_class_intern_init
, sizeof (BaulIconContainerAccessible), (GInstanceInitFunc)(void
(*)(void)) baul_icon_container_accessible_init, (GTypeFlags)
0); { {{ const GInterfaceInfo g_implement_interface_info = {
(GInterfaceInitFunc)(void (*)(void)) baul_icon_container_accessible_action_interface_init
, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id
, (atk_action_get_type ()), &g_implement_interface_info);
} { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) baul_icon_container_accessible_selection_interface_init
, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id
, (atk_selection_get_type ()), &g_implement_interface_info
); };} } return g_define_type_id; }
9936 baul_icon_container_accessible,static void baul_icon_container_accessible_init (BaulIconContainerAccessible
*self); static void baul_icon_container_accessible_class_init
(BaulIconContainerAccessibleClass *klass); static GType baul_icon_container_accessible_get_type_once
(void); static gpointer baul_icon_container_accessible_parent_class
= ((void*)0); static gint BaulIconContainerAccessible_private_offset
; static void baul_icon_container_accessible_class_intern_init
(gpointer klass) { baul_icon_container_accessible_parent_class
= g_type_class_peek_parent (klass); if (BaulIconContainerAccessible_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &BaulIconContainerAccessible_private_offset
); baul_icon_container_accessible_class_init ((BaulIconContainerAccessibleClass
*) klass); } __attribute__ ((__unused__)) static inline gpointer
baul_icon_container_accessible_get_instance_private (BaulIconContainerAccessible
*self) { return (((gpointer) ((guint8*) (self) + (glong) (BaulIconContainerAccessible_private_offset
)))); } GType baul_icon_container_accessible_get_type (void) {
static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= baul_icon_container_accessible_get_type_once (); (__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); 0 ? (void
) (*(&static_g_define_type_id) = (g_define_type_id)) : (void
) 0; g_once_init_leave_pointer ((&static_g_define_type_id
), (gpointer) (guintptr) (g_define_type_id)); })) ; } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType baul_icon_container_accessible_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(eel_canvas_accessible_get_type (), g_intern_static_string (
"BaulIconContainerAccessible"), sizeof (BaulIconContainerAccessibleClass
), (GClassInitFunc)(void (*)(void)) baul_icon_container_accessible_class_intern_init
, sizeof (BaulIconContainerAccessible), (GInstanceInitFunc)(void
(*)(void)) baul_icon_container_accessible_init, (GTypeFlags)
0); { {{ const GInterfaceInfo g_implement_interface_info = {
(GInterfaceInitFunc)(void (*)(void)) baul_icon_container_accessible_action_interface_init
, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id
, (atk_action_get_type ()), &g_implement_interface_info);
} { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) baul_icon_container_accessible_selection_interface_init
, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id
, (atk_selection_get_type ()), &g_implement_interface_info
); };} } return g_define_type_id; }
9937 eel_canvas_accessible_get_type (),static void baul_icon_container_accessible_init (BaulIconContainerAccessible
*self); static void baul_icon_container_accessible_class_init
(BaulIconContainerAccessibleClass *klass); static GType baul_icon_container_accessible_get_type_once
(void); static gpointer baul_icon_container_accessible_parent_class
= ((void*)0); static gint BaulIconContainerAccessible_private_offset
; static void baul_icon_container_accessible_class_intern_init
(gpointer klass) { baul_icon_container_accessible_parent_class
= g_type_class_peek_parent (klass); if (BaulIconContainerAccessible_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &BaulIconContainerAccessible_private_offset
); baul_icon_container_accessible_class_init ((BaulIconContainerAccessibleClass
*) klass); } __attribute__ ((__unused__)) static inline gpointer
baul_icon_container_accessible_get_instance_private (BaulIconContainerAccessible
*self) { return (((gpointer) ((guint8*) (self) + (glong) (BaulIconContainerAccessible_private_offset
)))); } GType baul_icon_container_accessible_get_type (void) {
static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= baul_icon_container_accessible_get_type_once (); (__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); 0 ? (void
) (*(&static_g_define_type_id) = (g_define_type_id)) : (void
) 0; g_once_init_leave_pointer ((&static_g_define_type_id
), (gpointer) (guintptr) (g_define_type_id)); })) ; } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType baul_icon_container_accessible_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(eel_canvas_accessible_get_type (), g_intern_static_string (
"BaulIconContainerAccessible"), sizeof (BaulIconContainerAccessibleClass
), (GClassInitFunc)(void (*)(void)) baul_icon_container_accessible_class_intern_init
, sizeof (BaulIconContainerAccessible), (GInstanceInitFunc)(void
(*)(void)) baul_icon_container_accessible_init, (GTypeFlags)
0); { {{ const GInterfaceInfo g_implement_interface_info = {
(GInterfaceInitFunc)(void (*)(void)) baul_icon_container_accessible_action_interface_init
, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id
, (atk_action_get_type ()), &g_implement_interface_info);
} { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) baul_icon_container_accessible_selection_interface_init
, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id
, (atk_selection_get_type ()), &g_implement_interface_info
); };} } return g_define_type_id; }
9938 G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION,static void baul_icon_container_accessible_init (BaulIconContainerAccessible
*self); static void baul_icon_container_accessible_class_init
(BaulIconContainerAccessibleClass *klass); static GType baul_icon_container_accessible_get_type_once
(void); static gpointer baul_icon_container_accessible_parent_class
= ((void*)0); static gint BaulIconContainerAccessible_private_offset
; static void baul_icon_container_accessible_class_intern_init
(gpointer klass) { baul_icon_container_accessible_parent_class
= g_type_class_peek_parent (klass); if (BaulIconContainerAccessible_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &BaulIconContainerAccessible_private_offset
); baul_icon_container_accessible_class_init ((BaulIconContainerAccessibleClass
*) klass); } __attribute__ ((__unused__)) static inline gpointer
baul_icon_container_accessible_get_instance_private (BaulIconContainerAccessible
*self) { return (((gpointer) ((guint8*) (self) + (glong) (BaulIconContainerAccessible_private_offset
)))); } GType baul_icon_container_accessible_get_type (void) {
static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= baul_icon_container_accessible_get_type_once (); (__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); 0 ? (void
) (*(&static_g_define_type_id) = (g_define_type_id)) : (void
) 0; g_once_init_leave_pointer ((&static_g_define_type_id
), (gpointer) (guintptr) (g_define_type_id)); })) ; } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType baul_icon_container_accessible_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(eel_canvas_accessible_get_type (), g_intern_static_string (
"BaulIconContainerAccessible"), sizeof (BaulIconContainerAccessibleClass
), (GClassInitFunc)(void (*)(void)) baul_icon_container_accessible_class_intern_init
, sizeof (BaulIconContainerAccessible), (GInstanceInitFunc)(void
(*)(void)) baul_icon_container_accessible_init, (GTypeFlags)
0); { {{ const GInterfaceInfo g_implement_interface_info = {
(GInterfaceInitFunc)(void (*)(void)) baul_icon_container_accessible_action_interface_init
, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id
, (atk_action_get_type ()), &g_implement_interface_info);
} { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) baul_icon_container_accessible_selection_interface_init
, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id
, (atk_selection_get_type ()), &g_implement_interface_info
); };} } return g_define_type_id; }
9939 baul_icon_container_accessible_action_interface_init)static void baul_icon_container_accessible_init (BaulIconContainerAccessible
*self); static void baul_icon_container_accessible_class_init
(BaulIconContainerAccessibleClass *klass); static GType baul_icon_container_accessible_get_type_once
(void); static gpointer baul_icon_container_accessible_parent_class
= ((void*)0); static gint BaulIconContainerAccessible_private_offset
; static void baul_icon_container_accessible_class_intern_init
(gpointer klass) { baul_icon_container_accessible_parent_class
= g_type_class_peek_parent (klass); if (BaulIconContainerAccessible_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &BaulIconContainerAccessible_private_offset
); baul_icon_container_accessible_class_init ((BaulIconContainerAccessibleClass
*) klass); } __attribute__ ((__unused__)) static inline gpointer
baul_icon_container_accessible_get_instance_private (BaulIconContainerAccessible
*self) { return (((gpointer) ((guint8*) (self) + (glong) (BaulIconContainerAccessible_private_offset
)))); } GType baul_icon_container_accessible_get_type (void) {
static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= baul_icon_container_accessible_get_type_once (); (__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); 0 ? (void
) (*(&static_g_define_type_id) = (g_define_type_id)) : (void
) 0; g_once_init_leave_pointer ((&static_g_define_type_id
), (gpointer) (guintptr) (g_define_type_id)); })) ; } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType baul_icon_container_accessible_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(eel_canvas_accessible_get_type (), g_intern_static_string (
"BaulIconContainerAccessible"), sizeof (BaulIconContainerAccessibleClass
), (GClassInitFunc)(void (*)(void)) baul_icon_container_accessible_class_intern_init
, sizeof (BaulIconContainerAccessible), (GInstanceInitFunc)(void
(*)(void)) baul_icon_container_accessible_init, (GTypeFlags)
0); { {{ const GInterfaceInfo g_implement_interface_info = {
(GInterfaceInitFunc)(void (*)(void)) baul_icon_container_accessible_action_interface_init
, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id
, (atk_action_get_type ()), &g_implement_interface_info);
} { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) baul_icon_container_accessible_selection_interface_init
, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id
, (atk_selection_get_type ()), &g_implement_interface_info
); };} } return g_define_type_id; }
9940 G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION,static void baul_icon_container_accessible_init (BaulIconContainerAccessible
*self); static void baul_icon_container_accessible_class_init
(BaulIconContainerAccessibleClass *klass); static GType baul_icon_container_accessible_get_type_once
(void); static gpointer baul_icon_container_accessible_parent_class
= ((void*)0); static gint BaulIconContainerAccessible_private_offset
; static void baul_icon_container_accessible_class_intern_init
(gpointer klass) { baul_icon_container_accessible_parent_class
= g_type_class_peek_parent (klass); if (BaulIconContainerAccessible_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &BaulIconContainerAccessible_private_offset
); baul_icon_container_accessible_class_init ((BaulIconContainerAccessibleClass
*) klass); } __attribute__ ((__unused__)) static inline gpointer
baul_icon_container_accessible_get_instance_private (BaulIconContainerAccessible
*self) { return (((gpointer) ((guint8*) (self) + (glong) (BaulIconContainerAccessible_private_offset
)))); } GType baul_icon_container_accessible_get_type (void) {
static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= baul_icon_container_accessible_get_type_once (); (__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); 0 ? (void
) (*(&static_g_define_type_id) = (g_define_type_id)) : (void
) 0; g_once_init_leave_pointer ((&static_g_define_type_id
), (gpointer) (guintptr) (g_define_type_id)); })) ; } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType baul_icon_container_accessible_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(eel_canvas_accessible_get_type (), g_intern_static_string (
"BaulIconContainerAccessible"), sizeof (BaulIconContainerAccessibleClass
), (GClassInitFunc)(void (*)(void)) baul_icon_container_accessible_class_intern_init
, sizeof (BaulIconContainerAccessible), (GInstanceInitFunc)(void
(*)(void)) baul_icon_container_accessible_init, (GTypeFlags)
0); { {{ const GInterfaceInfo g_implement_interface_info = {
(GInterfaceInitFunc)(void (*)(void)) baul_icon_container_accessible_action_interface_init
, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id
, (atk_action_get_type ()), &g_implement_interface_info);
} { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) baul_icon_container_accessible_selection_interface_init
, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id
, (atk_selection_get_type ()), &g_implement_interface_info
); };} } return g_define_type_id; }
9941 baul_icon_container_accessible_selection_interface_init))static void baul_icon_container_accessible_init (BaulIconContainerAccessible
*self); static void baul_icon_container_accessible_class_init
(BaulIconContainerAccessibleClass *klass); static GType baul_icon_container_accessible_get_type_once
(void); static gpointer baul_icon_container_accessible_parent_class
= ((void*)0); static gint BaulIconContainerAccessible_private_offset
; static void baul_icon_container_accessible_class_intern_init
(gpointer klass) { baul_icon_container_accessible_parent_class
= g_type_class_peek_parent (klass); if (BaulIconContainerAccessible_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &BaulIconContainerAccessible_private_offset
); baul_icon_container_accessible_class_init ((BaulIconContainerAccessibleClass
*) klass); } __attribute__ ((__unused__)) static inline gpointer
baul_icon_container_accessible_get_instance_private (BaulIconContainerAccessible
*self) { return (((gpointer) ((guint8*) (self) + (glong) (BaulIconContainerAccessible_private_offset
)))); } GType baul_icon_container_accessible_get_type (void) {
static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= baul_icon_container_accessible_get_type_once (); (__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); 0 ? (void
) (*(&static_g_define_type_id) = (g_define_type_id)) : (void
) 0; g_once_init_leave_pointer ((&static_g_define_type_id
), (gpointer) (guintptr) (g_define_type_id)); })) ; } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType baul_icon_container_accessible_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(eel_canvas_accessible_get_type (), g_intern_static_string (
"BaulIconContainerAccessible"), sizeof (BaulIconContainerAccessibleClass
), (GClassInitFunc)(void (*)(void)) baul_icon_container_accessible_class_intern_init
, sizeof (BaulIconContainerAccessible), (GInstanceInitFunc)(void
(*)(void)) baul_icon_container_accessible_init, (GTypeFlags)
0); { {{ const GInterfaceInfo g_implement_interface_info = {
(GInterfaceInitFunc)(void (*)(void)) baul_icon_container_accessible_action_interface_init
, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id
, (atk_action_get_type ()), &g_implement_interface_info);
} { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc
)(void (*)(void)) baul_icon_container_accessible_selection_interface_init
, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id
, (atk_selection_get_type ()), &g_implement_interface_info
); };} } return g_define_type_id; }
;
9942
9943static void
9944baul_icon_container_accessible_init (BaulIconContainerAccessible *accessible G_GNUC_UNUSED__attribute__ ((__unused__)))
9945{
9946}
9947
9948static void
9949baul_icon_container_accessible_class_init (BaulIconContainerAccessibleClass *klass)
9950{
9951 GObjectClass *gobject_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
9952 AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass)((((AtkObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), ((atk_object_get_type ()))))))
;
9953
9954 accessible_parent_class = g_type_class_peek_parent (klass);
9955
9956 gobject_class->finalize = baul_icon_container_accessible_finalize;
9957
9958 atk_class->get_n_children = baul_icon_container_accessible_get_n_children;
9959 atk_class->ref_child = baul_icon_container_accessible_ref_child;
9960 atk_class->initialize = baul_icon_container_accessible_initialize;
9961
9962 accessible_private_data_quark = g_quark_from_static_string ("icon-container-accessible-private-data");
9963}
9964
9965#if ! defined (BAUL_OMIT_SELF_CHECK)
9966
9967static char *
9968check_compute_stretch (int icon_x, int icon_y, int icon_size,
9969 int start_pointer_x, int start_pointer_y,
9970 int end_pointer_x, int end_pointer_y)
9971{
9972 StretchState start, current;
9973
9974 start.icon_x = icon_x;
9975 start.icon_y = icon_y;
9976 start.icon_size = icon_size;
9977 start.pointer_x = start_pointer_x;
9978 start.pointer_y = start_pointer_y;
9979 current.pointer_x = end_pointer_x;
9980 current.pointer_y = end_pointer_y;
9981
9982 compute_stretch (&start, &current);
9983
9984 return g_strdup_printf ("%d,%d:%d",
9985 current.icon_x,
9986 current.icon_y,
9987 current.icon_size);
9988}
9989
9990void
9991baul_self_check_icon_container (void)
9992{
9993 EEL_CHECK_STRING_RESULT (check_compute_stretch (0, 0, 16, 0, 0, 0, 0), "0,0:16")do { eel_before_check ("check_compute_stretch (0, 0, 16, 0, 0, 0, 0)"
, "baul-icon-container.c", 9993); eel_check_string_result (check_compute_stretch
(0, 0, 16, 0, 0, 0, 0), "0,0:16"); } while (0)
;
9994 EEL_CHECK_STRING_RESULT (check_compute_stretch (0, 0, 16, 16, 16, 17, 17), "0,0:17")do { eel_before_check ("check_compute_stretch (0, 0, 16, 16, 16, 17, 17)"
, "baul-icon-container.c", 9994); eel_check_string_result (check_compute_stretch
(0, 0, 16, 16, 16, 17, 17), "0,0:17"); } while (0)
;
9995 EEL_CHECK_STRING_RESULT (check_compute_stretch (0, 0, 16, 16, 16, 17, 16), "0,0:16")do { eel_before_check ("check_compute_stretch (0, 0, 16, 16, 16, 17, 16)"
, "baul-icon-container.c", 9995); eel_check_string_result (check_compute_stretch
(0, 0, 16, 16, 16, 17, 16), "0,0:16"); } while (0)
;
9996 EEL_CHECK_STRING_RESULT (check_compute_stretch (100, 100, 64, 105, 105, 40, 40), "35,35:129")do { eel_before_check ("check_compute_stretch (100, 100, 64, 105, 105, 40, 40)"
, "baul-icon-container.c", 9996); eel_check_string_result (check_compute_stretch
(100, 100, 64, 105, 105, 40, 40), "35,35:129"); } while (0)
;
9997}
9998#endif /* ! BAUL_OMIT_SELF_CHECK */
9999
10000gboolean
10001baul_icon_container_is_layout_rtl (BaulIconContainer *container)
10002{
10003 g_return_val_if_fail (BAUL_IS_ICON_CONTAINER (container), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return (0); } } while (0)
;
10004
10005 return container->details->layout_mode == BAUL_ICON_LAYOUT_T_B_R_L ||
10006 container->details->layout_mode == BAUL_ICON_LAYOUT_R_L_T_B;
10007}
10008
10009gboolean
10010baul_icon_container_is_layout_vertical (BaulIconContainer *container)
10011{
10012 g_return_val_if_fail (BAUL_IS_ICON_CONTAINER (container), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((container)); GType __t = (baul_icon_container_get_type()
); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "BAUL_IS_ICON_CONTAINER (container)"
); return ((0)); } } while (0)
;
10013
10014 return (container->details->layout_mode == BAUL_ICON_LAYOUT_T_B_L_R ||
10015 container->details->layout_mode == BAUL_ICON_LAYOUT_T_B_R_L);
10016}
10017
10018int
10019baul_icon_container_get_max_layout_lines_for_pango (BaulIconContainer *container)
10020{
10021 int limit;
10022
10023 if (baul_icon_container_get_is_desktop (container))
10024 {
10025 limit = desktop_text_ellipsis_limit;
10026 }
10027 else
10028 {
10029 limit = text_ellipsis_limits[container->details->zoom_level];
10030 }
10031
10032 if (limit <= 0)
10033 {
10034 return G_MININT(-2147483647 -1);
10035 }
10036
10037 return -limit;
10038}
10039
10040int
10041baul_icon_container_get_max_layout_lines (BaulIconContainer *container)
10042{
10043 int limit;
10044
10045 if (baul_icon_container_get_is_desktop (container))
10046 {
10047 limit = desktop_text_ellipsis_limit;
10048 }
10049 else
10050 {
10051 limit = text_ellipsis_limits[container->details->zoom_level];
10052 }
10053
10054 if (limit <= 0)
10055 {
10056 return G_MAXINT2147483647;
10057 }
10058
10059 return limit;
10060}
10061
10062void
10063baul_icon_container_begin_loading (BaulIconContainer *container)
10064{
10065 gboolean dummy;
10066
10067 if (baul_icon_container_get_store_layout_timestamps (container))
10068 {
10069 container->details->layout_timestamp = UNDEFINED_TIME((time_t) (-1));
10070 g_signal_emit (container,
10071 signals[GET_STORED_LAYOUT_TIMESTAMP], 0,
10072 NULL((void*)0), &container->details->layout_timestamp, &dummy);
10073 }
10074}
10075
10076static void
10077store_layout_timestamps_now (BaulIconContainer *container)
10078{
10079 GList *p;
10080 gboolean dummy;
10081 BaulIcon *icon = NULL((void*)0);
10082
10083 container->details->layout_timestamp = time (NULL((void*)0));
10084 g_signal_emit (container,
10085 signals[STORE_LAYOUT_TIMESTAMP], 0,
10086 NULL((void*)0), &container->details->layout_timestamp, &dummy);
10087
10088 for (p = container->details->icons; p != NULL((void*)0); p = p->next)
10089 {
10090 icon = p->data;
10091
10092 g_signal_emit (container,
10093 signals[STORE_LAYOUT_TIMESTAMP], 0,
10094 icon->data, &container->details->layout_timestamp, &dummy);
10095 }
10096}
10097
10098void
10099baul_icon_container_end_loading (BaulIconContainer *container,
10100 gboolean all_icons_added)
10101{
10102 if (all_icons_added &&
10103 baul_icon_container_get_store_layout_timestamps (container))
10104 {
10105 if (container->details->new_icons == NULL((void*)0))
10106 {
10107 store_layout_timestamps_now (container);
10108 }
10109 else
10110 {
10111 container->details->store_layout_timestamps_when_finishing_new_icons = TRUE(!(0));
10112 }
10113 }
10114}
10115
10116gboolean
10117baul_icon_container_get_store_layout_timestamps (BaulIconContainer *container)
10118{
10119 return container->details->store_layout_timestamps;
10120}
10121
10122void
10123baul_icon_container_set_store_layout_timestamps (BaulIconContainer *container,
10124 gboolean store_layout_timestamps)
10125{
10126 container->details->store_layout_timestamps = store_layout_timestamps;
10127}