1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /* fm-directory-view.h
3  *
4  * Copyright (C) 1999, 2000  Free Software Foundaton
5  * Copyright (C) 2000, 2001  Eazel, Inc.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public
18  * License along with this program; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  *
22  * Authors: Ettore Perazzoli
23  * 	    Darin Adler <darin@bentspoon.com>
24  * 	    John Sullivan <sullivan@eazel.com>
25  *          Pavel Cisler <pavel@eazel.com>
26  */
27 
28 #ifndef FM_DIRECTORY_VIEW_H
29 #define FM_DIRECTORY_VIEW_H
30 
31 #include <gtk/gtk.h>
32 #include <gio/gio.h>
33 
34 #include <eel/eel-background.h>
35 
36 #include <libcaja-private/caja-directory.h>
37 #include <libcaja-private/caja-file.h>
38 #include <libcaja-private/caja-icon-container.h>
39 #include <libcaja-private/caja-link.h>
40 #include <libcaja-private/caja-view.h>
41 #include <libcaja-private/caja-window-info.h>
42 #include <libcaja-private/caja-window-slot-info.h>
43 
44 typedef struct FMDirectoryView FMDirectoryView;
45 typedef struct FMDirectoryViewClass FMDirectoryViewClass;
46 
47 #define FM_TYPE_DIRECTORY_VIEW fm_directory_view_get_type()
48 #define FM_DIRECTORY_VIEW(obj) \
49   (G_TYPE_CHECK_INSTANCE_CAST ((obj), FM_TYPE_DIRECTORY_VIEW, FMDirectoryView))
50 #define FM_DIRECTORY_VIEW_CLASS(klass) \
51   (G_TYPE_CHECK_CLASS_CAST ((klass), FM_TYPE_DIRECTORY_VIEW, FMDirectoryViewClass))
52 #define FM_IS_DIRECTORY_VIEW(obj) \
53   (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FM_TYPE_DIRECTORY_VIEW))
54 #define FM_IS_DIRECTORY_VIEW_CLASS(klass) \
55   (G_TYPE_CHECK_CLASS_TYPE ((klass), FM_TYPE_DIRECTORY_VIEW))
56 #define FM_DIRECTORY_VIEW_GET_CLASS(obj) \
57   (G_TYPE_INSTANCE_GET_CLASS ((obj), FM_TYPE_DIRECTORY_VIEW, FMDirectoryViewClass))
58 
59 typedef struct FMDirectoryViewDetails FMDirectoryViewDetails;
60 
61 struct FMDirectoryView
62 {
63     GtkScrolledWindow parent;
64     FMDirectoryViewDetails *details;
65 };
66 
67 struct FMDirectoryViewClass
68 {
69     GtkScrolledWindowClass parent_class;
70 
71     /* The 'clear' signal is emitted to empty the view of its contents.
72      * It must be replaced by each subclass.
73      */
74     void 	(* clear) 		 (FMDirectoryView *view);
75 
76     /* The 'begin_file_changes' signal is emitted before a set of files
77      * are added to the view. It can be replaced by a subclass to do any
78      * necessary preparation for a set of new files. The default
79      * implementation does nothing.
80      */
81     void 	(* begin_file_changes) (FMDirectoryView *view);
82 
83     /* The 'add_file' signal is emitted to add one file to the view.
84      * It must be replaced by each subclass.
85      */
86     void    (* add_file) 		 (FMDirectoryView *view,
87                                   CajaFile *file,
88                                   CajaDirectory *directory);
89     void    (* remove_file)		 (FMDirectoryView *view,
90                                   CajaFile *file,
91                                   CajaDirectory *directory);
92 
93     /* The 'file_changed' signal is emitted to signal a change in a file,
94      * including the file being removed.
95      * It must be replaced by each subclass.
96      */
97     void 	(* file_changed)         (FMDirectoryView *view,
98                                       CajaFile *file,
99                                       CajaDirectory *directory);
100 
101     /* The 'end_file_changes' signal is emitted after a set of files
102      * are added to the view. It can be replaced by a subclass to do any
103      * necessary cleanup (typically, cleanup for code in begin_file_changes).
104      * The default implementation does nothing.
105      */
106     void 	(* end_file_changes)    (FMDirectoryView *view);
107 
108     void    (* flush_added_files)	 (FMDirectoryView *view);
109 
110     /* The 'begin_loading' signal is emitted before any of the contents
111      * of a directory are added to the view. It can be replaced by a
112      * subclass to do any necessary preparation to start dealing with a
113      * new directory. The default implementation does nothing.
114      */
115     void 	(* begin_loading) 	 (FMDirectoryView *view);
116 
117     /* The 'end_loading' signal is emitted after all of the contents
118      * of a directory are added to the view. It can be replaced by a
119      * subclass to do any necessary clean-up. The default implementation
120      * does nothing.
121      *
122      * If all_files_seen is true, the handler may assume that
123      * no load error ocurred, and all files of the underlying
124      * directory were loaded.
125      *
126      * Otherwise, end_loading was emitted due to cancellation,
127      * which usually means that not all files are available.
128      */
129     void 	(* end_loading) 	 (FMDirectoryView *view,
130                                   gboolean all_files_seen);
131 
132     /* The 'load_error' signal is emitted when the directory model
133      * reports an error in the process of monitoring the directory's
134      * contents.  The load error indicates that the process of
135      * loading the contents has ended, but the directory is still
136      * being monitored. The default implementation handles common
137      * load failures like ACCESS_DENIED.
138      */
139     void    (* load_error)           (FMDirectoryView *view,
140                                       GError *error);
141 
142     /* Function pointers that don't have corresponding signals */
143 
144     /* reset_to_defaults is a function pointer that subclasses must
145      * override to set sort order, zoom level, etc to match default
146      * values.
147      */
148     void     (* reset_to_defaults)	         (FMDirectoryView *view);
149 
150     /* get_selection is not a signal; it is just a function pointer for
151      * subclasses to replace (override). Subclasses must replace it
152      * with a function that returns a newly-allocated GList of
153      * CajaFile pointers.
154      */
155     GList *	(* get_selection) 	 	(FMDirectoryView *view);
156 
157     /* get_selection_for_file_transfer  is a function pointer for
158      * subclasses to replace (override). Subclasses must replace it
159      * with a function that returns a newly-allocated GList of
160      * CajaFile pointers. The difference from get_selection is
161      * that any files in the selection that also has a parent folder
162      * in the selection is not included.
163      */
164     GList *	(* get_selection_for_file_transfer)(FMDirectoryView *view);
165 
166     /* select_all is a function pointer that subclasses must override to
167      * select all of the items in the view */
168     void     (* select_all)	         	(FMDirectoryView *view);
169 
170     /* set_selection is a function pointer that subclasses must
171      * override to select the specified items (and unselect all
172      * others). The argument is a list of CajaFiles. */
173 
174     void     (* set_selection)	 	(FMDirectoryView *view,
175                                      GList *selection);
176 
177     /* invert_selection is a function pointer that subclasses must
178      * override to invert selection. */
179 
180     void     (* invert_selection)	 	(FMDirectoryView *view);
181 
182     /* Return an array of locations of selected icons in their view. */
183     GArray * (* get_selected_icon_locations) (FMDirectoryView *view);
184 
185     guint    (* get_item_count)             (FMDirectoryView *view);
186 
187     /* bump_zoom_level is a function pointer that subclasses must override
188      * to change the zoom level of an object. */
189     void    (* bump_zoom_level)      	(FMDirectoryView *view,
190                                          int zoom_increment);
191 
192     /* zoom_to_level is a function pointer that subclasses must override
193      * to set the zoom level of an object to the specified level. */
194     void    (* zoom_to_level) 		(FMDirectoryView *view,
195                                      CajaZoomLevel level);
196 
197     CajaZoomLevel (* get_zoom_level)    (FMDirectoryView *view);
198 
199     /* restore_default_zoom_level is a function pointer that subclasses must override
200          * to restore the zoom level of an object to a default setting. */
201     void    (* restore_default_zoom_level) (FMDirectoryView *view);
202 
203     /* can_zoom_in is a function pointer that subclasses must override to
204      * return whether the view is at maximum size (furthest-in zoom level) */
205     gboolean (* can_zoom_in)	 	(FMDirectoryView *view);
206 
207     /* can_zoom_out is a function pointer that subclasses must override to
208      * return whether the view is at minimum size (furthest-out zoom level) */
209     gboolean (* can_zoom_out)	 	(FMDirectoryView *view);
210 
211     /* reveal_selection is a function pointer that subclasses may
212      * override to make sure the selected items are sufficiently
213      * apparent to the user (e.g., scrolled into view). By default,
214      * this does nothing.
215      */
216     void     (* reveal_selection)	 	(FMDirectoryView *view);
217 
218     /* get_background is a function pointer that subclasses must
219      * override to return the EelBackground for this view.
220      */
221     GtkWidget * (* get_background_widget)	(FMDirectoryView *view);
222 
223     /* merge_menus is a function pointer that subclasses can override to
224      * add their own menu items to the window's menu bar.
225      * If overridden, subclasses must call parent class's function.
226      */
227     void    (* merge_menus)         	(FMDirectoryView *view);
228     void    (* unmerge_menus)         	(FMDirectoryView *view);
229 
230     /* update_menus is a function pointer that subclasses can override to
231      * update the sensitivity or wording of menu items in the menu bar.
232      * It is called (at least) whenever the selection changes. If overridden,
233      * subclasses must call parent class's function.
234      */
235     void    (* update_menus)         	(FMDirectoryView *view);
236 
237     /* sort_files is a function pointer that subclasses can override
238      * to provide a sorting order to determine which files should be
239      * presented when only a partial list is provided.
240      */
241     int     (* compare_files)              (FMDirectoryView *view,
242                                             CajaFile    *a,
243                                             CajaFile    *b);
244 
245     /* get_emblem_names_to_exclude is a function pointer that subclasses
246      * may override to specify a set of emblem names that should not
247      * be displayed with each file. By default, all emblems returned by
248      * CajaFile are displayed.
249      */
250     char ** (* get_emblem_names_to_exclude)	(FMDirectoryView *view);
251 
252     /* supports_properties is a function pointer that subclasses may
253      * override to control whether the "Show Properties" menu item
254      * should be enabled for selected items. The default implementation
255      * returns TRUE.
256      */
257     gboolean (* supports_properties)	(FMDirectoryView *view);
258 
259     /* supports_zooming is a function pointer that subclasses may
260      * override to control whether or not the zooming control and
261      * menu items should be enabled. The default implementation
262      * returns TRUE.
263      */
264     gboolean (* supports_zooming)		(FMDirectoryView *view);
265 
266     /* using_manual_layout is a function pointer that subclasses may
267      * override to control whether or not items can be freely positioned
268      * on the user-visible area.
269      * Note that this value is not guaranteed to be constant within the
270      * view's lifecycle. */
271     gboolean (* using_manual_layout)     (FMDirectoryView *view);
272 
273     /* is_read_only is a function pointer that subclasses may
274      * override to control whether or not the user is allowed to
275      * change the contents of the currently viewed directory. The
276      * default implementation checks the permissions of the
277      * directory.
278      */
279     gboolean (* is_read_only)	        (FMDirectoryView *view);
280 
281     /* is_empty is a function pointer that subclasses must
282      * override to report whether the view contains any items.
283      */
284     gboolean (* is_empty)                   (FMDirectoryView *view);
285 
286     /* supports_creating_files is a function pointer that subclasses may
287      * override to control whether or not new items can be created.
288      * be accepted. The default implementation checks whether the
289      * user has write permissions for the viewed directory, and whether
290      * the viewed directory is in the trash.
291      */
292     gboolean (* supports_creating_files)	(FMDirectoryView *view);
293 
294     /* accepts_dragged_files is a function pointer that subclasses may
295      * override to control whether or not files can be dropped in this
296      * location. The default implementation returns TRUE.
297      */
298     gboolean (* accepts_dragged_files)	(FMDirectoryView *view);
299 
300     gboolean (* can_rename_file)            (FMDirectoryView *view,
301             CajaFile *file);
302     /* select_all specifies whether the whole filename should be selected
303      * or only its basename (i.e. everything except the extension)
304      * */
305     void	 (* start_renaming_file)        (FMDirectoryView *view,
306             CajaFile *file,
307             gboolean select_all);
308 
309     gboolean (* file_still_belongs)		(FMDirectoryView *view,
310                                          CajaFile	 *file,
311                                          CajaDirectory *directory);
312 
313     /* convert *point from widget's coordinate system to a coordinate
314      * system used for specifying file operation positions, which is view-specific.
315      *
316      * This is used by the the icon view, which converts the screen position to a zoom
317      * level-independent coordinate system.
318      */
319     void (* widget_to_file_operation_position) (FMDirectoryView *view,
320             GdkPoint        *position);
321 
322     /* Preference change callbacks, overriden by icon and list views.
323      * Icon and list views respond by synchronizing to the new preference
324      * values and forcing an update if appropriate.
325      */
326     void	(* text_attribute_names_changed)   (FMDirectoryView *view);
327     void	(* embedded_text_policy_changed)   (FMDirectoryView *view);
328     void	(* image_display_policy_changed)   (FMDirectoryView *view);
329     void	(* click_policy_changed)	   (FMDirectoryView *view);
330     void	(* sort_directories_first_changed) (FMDirectoryView *view);
331 
332     void	(* emblems_changed)                (FMDirectoryView *view);
333 
334     void    (* set_is_active)                  (FMDirectoryView *view,
335             gboolean         is_active);
336 
337     /* Signals used only for keybindings */
338     gboolean (* trash)                         (FMDirectoryView *view);
339     gboolean (* delete)                        (FMDirectoryView *view);
340 };
341 
342 /* GObject support */
343 GType               fm_directory_view_get_type                         (void);
344 
345 G_DEFINE_AUTOPTR_CLEANUP_FUNC (FMDirectoryView, g_object_unref);
346 
347 /* Functions callable from the user interface and elsewhere. */
348 CajaWindowInfo *fm_directory_view_get_caja_window              (FMDirectoryView  *view);
349 CajaWindowSlotInfo *fm_directory_view_get_caja_window_slot     (FMDirectoryView  *view);
350 char *              fm_directory_view_get_uri                          (FMDirectoryView  *view);
351 char *              fm_directory_view_get_backing_uri                  (FMDirectoryView  *view);
352 gboolean            fm_directory_view_can_accept_item                  (CajaFile     *target_item,
353         const char       *item_uri,
354         FMDirectoryView  *view);
355 void                fm_directory_view_display_selection_info           (FMDirectoryView  *view);
356 GList *             fm_directory_view_get_selection                    (FMDirectoryView  *view);
357 GList *             fm_directory_view_get_selection_for_file_transfer  (FMDirectoryView  *view);
358 void                fm_directory_view_invert_selection                 (FMDirectoryView  *view);
359 void                fm_directory_view_stop                             (FMDirectoryView  *view);
360 guint               fm_directory_view_get_item_count                   (FMDirectoryView  *view);
361 gboolean            fm_directory_view_can_zoom_in                      (FMDirectoryView  *view);
362 gboolean            fm_directory_view_can_zoom_out                     (FMDirectoryView  *view);
363 GtkWidget *         fm_directory_view_get_background_widget            (FMDirectoryView  *view);
364 void                fm_directory_view_bump_zoom_level                  (FMDirectoryView  *view,
365         int               zoom_increment);
366 void                fm_directory_view_zoom_to_level                    (FMDirectoryView  *view,
367         CajaZoomLevel zoom_level);
368 CajaZoomLevel   fm_directory_view_get_zoom_level                   (FMDirectoryView  *view);
369 void                fm_directory_view_restore_default_zoom_level       (FMDirectoryView  *view);
370 void                fm_directory_view_reset_to_defaults                (FMDirectoryView  *view);
371 void                fm_directory_view_select_all                       (FMDirectoryView  *view);
372 void                fm_directory_view_set_selection                    (FMDirectoryView  *view,
373         GList            *selection);
374 GArray *            fm_directory_view_get_selected_icon_locations      (FMDirectoryView  *view);
375 void                fm_directory_view_reveal_selection                 (FMDirectoryView  *view);
376 gboolean            fm_directory_view_is_empty                         (FMDirectoryView  *view);
377 gboolean            fm_directory_view_is_read_only                     (FMDirectoryView  *view);
378 gboolean            fm_directory_view_supports_creating_files          (FMDirectoryView  *view);
379 gboolean            fm_directory_view_accepts_dragged_files            (FMDirectoryView  *view);
380 gboolean            fm_directory_view_supports_properties              (FMDirectoryView  *view);
381 gboolean            fm_directory_view_supports_zooming                 (FMDirectoryView  *view);
382 gboolean            fm_directory_view_using_manual_layout              (FMDirectoryView  *view);
383 void                fm_directory_view_move_copy_items                  (const GList      *item_uris,
384         GArray           *relative_item_points,
385         const char       *target_uri,
386         int               copy_action,
387         int               x,
388         int               y,
389         FMDirectoryView  *view);
390 GdkAtom	            fm_directory_view_get_copied_files_atom            (FMDirectoryView  *view);
391 gboolean            fm_directory_view_get_active                       (FMDirectoryView  *view);
392 
393 /* Wrappers for signal emitters. These are normally called
394  * only by FMDirectoryView itself. They have corresponding signals
395  * that observers might want to connect with.
396  */
397 void                fm_directory_view_clear                            (FMDirectoryView  *view);
398 void                fm_directory_view_begin_loading                    (FMDirectoryView  *view);
399 void                fm_directory_view_end_loading                      (FMDirectoryView  *view,
400         gboolean          all_files_seen);
401 
402 gboolean            fm_directory_view_get_loading                      (FMDirectoryView  *view);
403 
404 /* Hooks for subclasses to call. These are normally called only by
405  * FMDirectoryView and its subclasses
406  */
407 void                fm_directory_view_activate_files                   (FMDirectoryView        *view,
408         GList                  *files,
409         CajaWindowOpenMode  mode,
410         CajaWindowOpenFlags flags,
411         gboolean                confirm_multiple);
412 void                fm_directory_view_activate_file                    (FMDirectoryView        *view,
413         CajaFile           *file,
414         CajaWindowOpenMode  mode,
415         CajaWindowOpenFlags flags);
416 void                fm_directory_view_start_batching_selection_changes (FMDirectoryView  *view);
417 void                fm_directory_view_stop_batching_selection_changes  (FMDirectoryView  *view);
418 void                fm_directory_view_queue_file_change                (FMDirectoryView  *view,
419         CajaFile     *file);
420 void                fm_directory_view_notify_selection_changed         (FMDirectoryView  *view);
421 GtkUIManager *      fm_directory_view_get_ui_manager                   (FMDirectoryView  *view);
422 char **             fm_directory_view_get_emblem_names_to_exclude      (FMDirectoryView  *view);
423 CajaDirectory  *fm_directory_view_get_model                        (FMDirectoryView  *view);
424 GtkWindow	   *fm_directory_view_get_containing_window	       (FMDirectoryView  *view);
425 CajaFile       *fm_directory_view_get_directory_as_file            (FMDirectoryView  *view);
426 EelBackground *     fm_directory_view_get_background                   (FMDirectoryView  *view);
427 gboolean            fm_directory_view_get_allow_moves                  (FMDirectoryView  *view);
428 void                fm_directory_view_pop_up_background_context_menu   (FMDirectoryView  *view,
429         GdkEventButton   *event);
430 void                fm_directory_view_pop_up_selection_context_menu    (FMDirectoryView  *view,
431         GdkEventButton   *event);
432 void                fm_directory_view_pop_up_location_context_menu     (FMDirectoryView  *view,
433         GdkEventButton   *event,
434         const char       *location);
435 void                fm_directory_view_send_selection_change            (FMDirectoryView *view);
436 gboolean            fm_directory_view_should_show_file                 (FMDirectoryView  *view,
437         CajaFile     *file);
438 gboolean	    fm_directory_view_should_sort_directories_first    (FMDirectoryView  *view);
439 void                fm_directory_view_update_menus                     (FMDirectoryView  *view);
440 void                fm_directory_view_new_folder                       (FMDirectoryView  *view);
441 void                fm_directory_view_new_file                         (FMDirectoryView  *view,
442         const char       *parent_uri,
443         CajaFile     *source);
444 void                fm_directory_view_ignore_hidden_file_preferences   (FMDirectoryView  *view);
445 void                fm_directory_view_set_show_foreign                 (FMDirectoryView  *view,
446         gboolean          show_foreign);
447 void                fm_directory_view_init_view_iface                  (CajaViewIface *iface);
448 gboolean            fm_directory_view_handle_scroll_event              (FMDirectoryView  *view,
449         GdkEventScroll   *event);
450 void                fm_directory_view_handle_netscape_url_drop         (FMDirectoryView  *view,
451         const char       *encoded_url,
452         const char       *target_uri,
453         GdkDragAction     action,
454         int               x,
455         int               y);
456 void                fm_directory_view_handle_uri_list_drop             (FMDirectoryView  *view,
457         const char       *item_uris,
458         const char       *target_uri,
459         GdkDragAction     action,
460         int               x,
461         int               y);
462 void                fm_directory_view_handle_text_drop                 (FMDirectoryView  *view,
463         const char       *text,
464         const char       *target_uri,
465         GdkDragAction     action,
466         int               x,
467         int               y);
468 void                fm_directory_view_handle_raw_drop                 (FMDirectoryView  *view,
469         const char       *raw_data,
470         int               length,
471         const char       *target_uri,
472         const char       *direct_save_uri,
473         GdkDragAction     action,
474         int               x,
475         int               y);
476 void                fm_directory_view_freeze_updates                   (FMDirectoryView  *view);
477 void                fm_directory_view_unfreeze_updates                 (FMDirectoryView  *view);
478 void                fm_directory_view_add_subdirectory                (FMDirectoryView  *view,
479         CajaDirectory*directory);
480 void                fm_directory_view_remove_subdirectory             (FMDirectoryView  *view,
481         CajaDirectory*directory);
482 
483 gboolean            fm_directory_view_is_editable                     (FMDirectoryView *view);
484 void		    fm_directory_view_set_initiated_unmount	      (FMDirectoryView *view,
485         gboolean inititated_unmount);
486 
487 /* operations affecting two directory views */
488 void                fm_directory_view_move_copy_items_between_views   (FMDirectoryView *source, FMDirectoryView *target, gboolean copy);
489 
490 #endif /* FM_DIRECTORY_VIEW_H */
491