r2228: Made 'Automatic' an icon size, rather than a separate option.
[rox-filer.git] / ROX-Filer / src / view_iface.c
blob0077962e151b4b0d0e18d2631faff0fa6e147594
1 /*
2 * $Id$
4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2002, the ROX-Filer team.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
22 /* view_iface.c - operations supported by all views */
24 #include "config.h"
26 #include "global.h"
28 #include "view_iface.h"
29 #include "support.h"
30 #include "filer.h"
31 #include "diritem.h"
33 /* A word about interfaces:
35 * gobject's documentation's explanation of interfaces leaves something[1] to
36 * be desired, so I'd better explain here...
38 * [1] Like, eg, an explanation.
40 * A ViewIfaceClass is a struct which contains a number of function
41 * pointers. Each class that implements the View interface creates its
42 * own ViewIfaceClass with pointers to its implementation. This is stored
43 * with the class.
45 * When you want to call a method (eg, sort()) on a View, you call
46 * view_sort(object) here, which gets the class of object and then looks
47 * for that class's implementation of the View interface, and then calls
48 * the actual function through that.
51 /* ViewIters
53 * A ViewIter is used to index items. They are usually allocated
54 * on the stack and then initialised using view_get_iter().
56 * Normally, an iterator starts of not pointing at any item, but
57 * each call to iter->next(iter) returns the next item, and leaves
58 * the iterator pointing at the returned item. If you like the item,
59 * you can then pass the iterator to view_cursor_to_iter(), etc.
61 * Using flags passed to view_get_iter, you can start the sequence from the
62 * beginning, end, cursor or 'base' (a saved cursor position). You can
63 * go forwards or backwards. You can opt to only get selected items returned.
65 * You can also have one-shot iterators which already point to an item, and
66 * you never call the next method (view_get_cursor, for example). In fact,
67 * these iterators return a sequence of one item, but next() gets called
68 * automatically for you.
70 * You don't need to free iterators, and they become invalid if the
71 * View changes (items added, removed or altered), so don't hang on to
72 * them!
75 /****************************************************************
76 * EXTERNAL INTERFACE *
77 ****************************************************************/
79 GType view_iface_get_type(void)
81 static GType iface_type = 0;
83 if (!iface_type)
85 static const GTypeInfo iface_info =
87 sizeof (ViewIfaceClass),
88 NULL, /* base_init */
89 NULL, /* base_finalize */
92 iface_type = g_type_register_static(G_TYPE_INTERFACE,
93 "ViewIface", &iface_info, 0);
95 /* Actually, all Views should be GTK_TYPE_WIDGETs, to be more
96 * accurate, but including gtk.h takes so long, and noone's
97 * going to get this wrong ;-)
99 g_type_interface_add_prerequisite(iface_type, G_TYPE_OBJECT);
102 return iface_type;
105 /* The sort function has changed -- resort */
106 void view_sort(ViewIface *obj)
108 g_return_if_fail(VIEW_IS_IFACE(obj));
109 VIEW_IFACE_GET_CLASS(obj)->sort(obj);
112 /* The style has changed -- shrink the grid and redraw.
113 * Also update ViewData (and name layout too) if appropriate
114 * flags are set.
116 void view_style_changed(ViewIface *obj, int flags)
118 g_return_if_fail(VIEW_IS_IFACE(obj));
120 VIEW_IFACE_GET_CLASS(obj)->style_changed(obj, flags);
123 /* Wink or move the cursor to this item, if present. Return TRUE on
124 * success (iff leaf was present).
126 gboolean view_autoselect(ViewIface *obj, const gchar *leaf)
128 g_return_val_if_fail(VIEW_IS_IFACE(obj), FALSE);
129 g_return_val_if_fail(leaf != NULL, FALSE);
131 return VIEW_IFACE_GET_CLASS(obj)->autoselect(obj, leaf);
134 /* Scanning has turned up some new items... */
135 void view_add_items(ViewIface *obj, GPtrArray *items)
137 VIEW_IFACE_GET_CLASS(obj)->add_items(obj, items);
140 /* These items are already known, but have changed... */
141 void view_update_items(ViewIface *obj, GPtrArray *items)
143 VIEW_IFACE_GET_CLASS(obj)->update_items(obj, items);
146 /* Call test(item) for each item in the view and delete all those for
147 * which it returns TRUE.
149 void view_delete_if(ViewIface *obj,
150 gboolean (*test)(gpointer item, gpointer data),
151 gpointer data)
153 g_return_if_fail(VIEW_IS_IFACE(obj));
155 VIEW_IFACE_GET_CLASS(obj)->delete_if(obj, test, data);
158 /* Remove all items from the view (used when changing directory) */
159 void view_clear(ViewIface *obj)
161 g_return_if_fail(VIEW_IS_IFACE(obj));
163 VIEW_IFACE_GET_CLASS(obj)->clear(obj);
166 /* Select all items */
167 void view_select_all(ViewIface *obj)
169 g_return_if_fail(VIEW_IS_IFACE(obj));
171 VIEW_IFACE_GET_CLASS(obj)->select_all(obj);
174 /* Unselect all items */
175 void view_clear_selection(ViewIface *obj)
177 g_return_if_fail(VIEW_IS_IFACE(obj));
179 VIEW_IFACE_GET_CLASS(obj)->clear_selection(obj);
182 /* Return the total number of items */
183 int view_count_items(ViewIface *obj)
185 g_return_val_if_fail(VIEW_IS_IFACE(obj), 0);
187 return VIEW_IFACE_GET_CLASS(obj)->count_items(obj);
190 /* Return the number of selected items */
191 int view_count_selected(ViewIface *obj)
193 g_return_val_if_fail(VIEW_IS_IFACE(obj), 0);
195 return VIEW_IFACE_GET_CLASS(obj)->count_selected(obj);
198 void view_show_cursor(ViewIface *obj)
200 g_return_if_fail(VIEW_IS_IFACE(obj));
202 VIEW_IFACE_GET_CLASS(obj)->show_cursor(obj);
205 /* Create an iterator which will return each element selected by 'flags'
206 * from successive calls to iter.next(&iter). NULL indicates the end
207 * of the sequence.
209 * The iterator does not need to be freed. It becomes invalid if the
210 * view is changed in any way.
212 void view_get_iter(ViewIface *obj, ViewIter *iter, IterFlags flags)
214 g_return_if_fail(VIEW_IS_IFACE(obj));
215 g_return_if_fail(iter != NULL);
217 VIEW_IFACE_GET_CLASS(obj)->get_iter(obj, iter, flags);
220 /* Make an 'iter' for the cursor item, if any. Use iter->peek() to get
221 * the DirItem (will be NULL if the cursor isn't on an item).
223 void view_get_cursor(ViewIface *obj, ViewIter *iter)
225 g_return_if_fail(VIEW_IS_IFACE(obj));
226 g_return_if_fail(iter != NULL);
228 VIEW_IFACE_GET_CLASS(obj)->get_iter(obj, iter,
229 VIEW_ITER_FROM_CURSOR | VIEW_ITER_ONE_ONLY);
232 /* Position cursor on the last item returned by iter.next().
233 * If iter is NULL, remove the cursor.
235 void view_cursor_to_iter(ViewIface *obj, ViewIter *iter)
237 g_return_if_fail(VIEW_IS_IFACE(obj));
239 VIEW_IFACE_GET_CLASS(obj)->cursor_to_iter(obj, iter);
242 /* Select the item at this iter */
243 void view_set_selected(ViewIface *obj, ViewIter *iter, gboolean selected)
245 g_return_if_fail(VIEW_IS_IFACE(obj));
247 VIEW_IFACE_GET_CLASS(obj)->set_selected(obj, iter, selected);
250 /* TRUE if this item is selected */
251 gboolean view_get_selected(ViewIface *obj, ViewIter *iter)
253 g_return_val_if_fail(VIEW_IS_IFACE(obj), FALSE);
255 return VIEW_IFACE_GET_CLASS(obj)->get_selected(obj, iter);
258 /* Flash / draw attention to this item */
259 void view_wink_item(ViewIface *obj, ViewIter *iter)
261 g_return_if_fail(VIEW_IS_IFACE(obj));
263 VIEW_IFACE_GET_CLASS(obj)->wink_item(obj, iter);
266 /* Clear the selection, then select this item. Does it atomically to avoid
267 * problems with giving up and quickly reclaiming the primary selection.
269 void view_select_only(ViewIface *obj, ViewIter *iter)
271 g_return_if_fail(VIEW_IS_IFACE(obj));
273 VIEW_IFACE_GET_CLASS(obj)->select_only(obj, iter);
276 void view_select_if(ViewIface *obj,
277 gboolean (*test)(ViewIter *iter, gpointer data),
278 gpointer data)
280 ViewIter iter;
281 gboolean should_select_first;
283 g_return_if_fail(VIEW_IS_IFACE(obj));
285 view_get_iter(obj, &iter, 0);
287 if (!iter.next(&iter))
288 return; /* No items */
290 view_freeze(obj);
292 /* If anything is currently selected then select the first item now
293 * and set it to its correct value at the end (avoids losing the
294 * primary and regaining it quickly). Do the test first in case it
295 * relies on the selected state!
297 should_select_first = test(&iter, data);
298 if (view_count_selected(obj))
299 view_set_selected(obj, &iter, TRUE);
301 while (iter.next(&iter))
302 view_set_selected(obj, &iter, test(&iter, data));
304 view_get_iter(obj, &iter, 0);
305 iter.next(&iter);
306 view_set_selected(obj, &iter, should_select_first);
308 view_thaw(obj);
311 /* Prevent selection_changed events from being emitted */
312 void view_freeze(ViewIface *obj)
314 g_return_if_fail(VIEW_IS_IFACE(obj));
316 VIEW_IFACE_GET_CLASS(obj)->set_frozen(obj, TRUE);
319 /* Undo a view_freeze (and emit the changed signal) */
320 void view_thaw(ViewIface *obj)
322 g_return_if_fail(VIEW_IS_IFACE(obj));
324 VIEW_IFACE_GET_CLASS(obj)->set_frozen(obj, FALSE);
327 /* Resize the filer window to a sensible size.
328 * v_border is the height of the toolbar + the minibuffer (if visible).
329 * space is
330 * If allow_shrink is
332 void view_autosize(ViewIface *obj)
334 g_return_if_fail(VIEW_IS_IFACE(obj));
336 VIEW_IFACE_GET_CLASS(obj)->autosize(obj);
339 /* Return TRUE if the cursor is shown. Note that the cursor may be visible
340 * even if their are no items (so get_cursor().peek() would return NULL).
342 gboolean view_cursor_visible(ViewIface *obj)
344 g_return_val_if_fail(VIEW_IS_IFACE(obj), FALSE);
346 return VIEW_IFACE_GET_CLASS(obj)->cursor_visible(obj);
349 /* The 'base' position is used to record the position of the cursor
350 * when the minibuffer is opened, for interactive searching.
352 void view_set_base(ViewIface *obj, ViewIter *iter)
354 g_return_if_fail(VIEW_IS_IFACE(obj));
356 VIEW_IFACE_GET_CLASS(obj)->set_base(obj, iter);
359 /* Returns an interator which yields just the item under the pointer.
360 * iter.peek() will return NULL if no item was under the pointer.
361 * x, y is relative to the window which generates events for the widget.
363 void view_get_iter_at_point(ViewIface *obj, ViewIter *iter, int x, int y)
365 g_return_if_fail(VIEW_IS_IFACE(obj));
367 VIEW_IFACE_GET_CLASS(obj)->get_iter_at_point(obj, iter, x, y);
370 /* Begin a drag to select a group of icons */
371 void view_start_lasso_box(ViewIface *obj, GdkEventButton *event)
373 g_return_if_fail(VIEW_IS_IFACE(obj));
375 VIEW_IFACE_GET_CLASS(obj)->start_lasso_box(obj, event);
378 /* Add anything useful to the tooltip string. Used to include the name of
379 * items where the name is shown truncated.
381 void view_extend_tip(ViewIface *obj, ViewIter *iter, GString *tip)
383 g_return_if_fail(VIEW_IS_IFACE(obj));
385 VIEW_IFACE_GET_CLASS(obj)->extend_tip(obj, iter, tip);