1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ |
---|
2 | |
---|
3 | /* |
---|
4 | * Nautilus |
---|
5 | * |
---|
6 | * Copyright (C) 1999, 2000 Red Hat, Inc. |
---|
7 | * Copyright (C) 1999, 2000, 2001 Eazel, Inc. |
---|
8 | * |
---|
9 | * Nautilus is free software; you can redistribute it and/or |
---|
10 | * modify it under the terms of the GNU 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 | * Nautilus 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 | * General Public License for more details. |
---|
18 | * |
---|
19 | * You should have received a copy of the GNU General Public License |
---|
20 | * along with this program; if not, write to the Free Software |
---|
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
---|
22 | * |
---|
23 | * Authors: Elliot Lee <sopwith@redhat.com> |
---|
24 | * Darin Adler <darin@bentspoon.com> |
---|
25 | * |
---|
26 | */ |
---|
27 | |
---|
28 | /* nautilus-view-frame.c: Widget and CORBA machinery for hosting a NautilusView */ |
---|
29 | |
---|
30 | #include <config.h> |
---|
31 | #include "nautilus-view-frame.h" |
---|
32 | |
---|
33 | #include "nautilus-application.h" |
---|
34 | #include "nautilus-component-adapter-factory.h" |
---|
35 | #include "nautilus-signaller.h" |
---|
36 | #include "nautilus-view-frame-private.h" |
---|
37 | #include "nautilus-window.h" |
---|
38 | #include <bonobo/bonobo-control-frame.h> |
---|
39 | #include <bonobo/bonobo-event-source.h> |
---|
40 | #include <bonobo/bonobo-exception.h> |
---|
41 | #include <bonobo/bonobo-zoomable-frame.h> |
---|
42 | #include <bonobo/bonobo-zoomable.h> |
---|
43 | #include <eel/eel-gtk-extensions.h> |
---|
44 | #include <eel/eel-gtk-macros.h> |
---|
45 | #include <eel/eel-marshal.h> |
---|
46 | #include <gtk/gtkmain.h> |
---|
47 | #include <gtk/gtksignal.h> |
---|
48 | #include <libnautilus-private/nautilus-bonobo-extensions.h> |
---|
49 | #include <libnautilus-private/nautilus-marshal.h> |
---|
50 | #include <libnautilus-private/nautilus-undo-manager.h> |
---|
51 | #include <libnautilus/nautilus-idle-queue.h> |
---|
52 | #include <libnautilus/nautilus-view.h> |
---|
53 | #include <nautilus-marshal.h> |
---|
54 | #include <string.h> |
---|
55 | |
---|
56 | enum { |
---|
57 | CHANGE_SELECTION, |
---|
58 | CHANGE_STATUS, |
---|
59 | FAILED, |
---|
60 | GET_HISTORY_LIST, |
---|
61 | GO_BACK, |
---|
62 | CLOSE_WINDOW, |
---|
63 | LOAD_COMPLETE, |
---|
64 | LOAD_PROGRESS_CHANGED, |
---|
65 | LOAD_UNDERWAY, |
---|
66 | OPEN_LOCATION_FORCE_NEW_WINDOW, |
---|
67 | OPEN_LOCATION_IN_THIS_WINDOW, |
---|
68 | OPEN_LOCATION_PREFER_EXISTING_WINDOW, |
---|
69 | REPORT_LOCATION_CHANGE, |
---|
70 | REPORT_REDIRECT, |
---|
71 | TITLE_CHANGED, |
---|
72 | VIEW_LOADED, |
---|
73 | ZOOM_LEVEL_CHANGED, |
---|
74 | ZOOM_PARAMETERS_CHANGED, |
---|
75 | LAST_SIGNAL |
---|
76 | }; |
---|
77 | |
---|
78 | typedef enum { |
---|
79 | VIEW_FRAME_EMPTY, |
---|
80 | VIEW_FRAME_NO_LOCATION, |
---|
81 | VIEW_FRAME_WAITING, |
---|
82 | VIEW_FRAME_UNDERWAY, |
---|
83 | VIEW_FRAME_LOADED, |
---|
84 | VIEW_FRAME_FAILED |
---|
85 | } NautilusViewFrameState; |
---|
86 | |
---|
87 | struct NautilusViewFrameDetails { |
---|
88 | NautilusViewFrameState state; |
---|
89 | char *title; |
---|
90 | char *label; |
---|
91 | char *view_iid; |
---|
92 | |
---|
93 | /* The view frame Bonobo objects. */ |
---|
94 | BonoboObject *view_frame; |
---|
95 | BonoboEventSource *event_source; |
---|
96 | BonoboControlFrame *control_frame; |
---|
97 | BonoboZoomableFrame *zoomable_frame; |
---|
98 | |
---|
99 | /* The view CORBA object. */ |
---|
100 | Nautilus_View view; |
---|
101 | |
---|
102 | /* A container to connect our clients to. */ |
---|
103 | BonoboUIContainer *ui_container; |
---|
104 | NautilusUndoManager *undo_manager; |
---|
105 | |
---|
106 | NautilusBonoboActivationHandle *activation_handle; |
---|
107 | |
---|
108 | NautilusIdleQueue *idle_queue; |
---|
109 | |
---|
110 | guint failed_idle_id; |
---|
111 | guint socket_gone_idle_id; |
---|
112 | }; |
---|
113 | |
---|
114 | static void nautilus_view_frame_init (NautilusViewFrame *view); |
---|
115 | static void nautilus_view_frame_class_init (NautilusViewFrameClass *klass); |
---|
116 | static void send_history (NautilusViewFrame *view); |
---|
117 | |
---|
118 | static guint signals[LAST_SIGNAL]; |
---|
119 | |
---|
120 | EEL_CLASS_BOILERPLATE (NautilusViewFrame, |
---|
121 | nautilus_view_frame, |
---|
122 | EEL_TYPE_GENEROUS_BIN) |
---|
123 | |
---|
124 | void |
---|
125 | nautilus_view_frame_queue_incoming_call (PortableServer_Servant servant, |
---|
126 | NautilusViewFrameFunction call, |
---|
127 | gpointer callback_data, |
---|
128 | GDestroyNotify destroy_callback_data) |
---|
129 | { |
---|
130 | NautilusViewFrame *view; |
---|
131 | |
---|
132 | view = nautilus_view_frame_from_servant (servant); |
---|
133 | if (view == NULL) { |
---|
134 | if (destroy_callback_data != NULL) { |
---|
135 | (* destroy_callback_data) (callback_data); |
---|
136 | } |
---|
137 | return; |
---|
138 | } |
---|
139 | |
---|
140 | nautilus_idle_queue_add (view->details->idle_queue, |
---|
141 | (GFunc) call, |
---|
142 | view, |
---|
143 | callback_data, |
---|
144 | destroy_callback_data); |
---|
145 | } |
---|
146 | |
---|
147 | static void |
---|
148 | nautilus_view_frame_init (NautilusViewFrame *view) |
---|
149 | { |
---|
150 | GTK_WIDGET_SET_FLAGS (view, GTK_NO_WINDOW); |
---|
151 | |
---|
152 | view->details = g_new0 (NautilusViewFrameDetails, 1); |
---|
153 | |
---|
154 | view->details->idle_queue = nautilus_idle_queue_new (); |
---|
155 | |
---|
156 | g_signal_connect_object (nautilus_signaller_get_current (), |
---|
157 | "history_list_changed", |
---|
158 | G_CALLBACK (send_history), |
---|
159 | view, G_CONNECT_SWAPPED); |
---|
160 | g_signal_connect_object (nautilus_icon_factory_get (), |
---|
161 | "icons_changed", |
---|
162 | G_CALLBACK (send_history), |
---|
163 | view, G_CONNECT_SWAPPED); |
---|
164 | } |
---|
165 | |
---|
166 | static void |
---|
167 | stop_activation (NautilusViewFrame *view) |
---|
168 | { |
---|
169 | nautilus_bonobo_activate_cancel (view->details->activation_handle); |
---|
170 | view->details->activation_handle = NULL; |
---|
171 | } |
---|
172 | |
---|
173 | static void |
---|
174 | destroy_view (NautilusViewFrame *view) |
---|
175 | { |
---|
176 | BonoboUIEngine *engine; |
---|
177 | |
---|
178 | if (view->details->view == CORBA_OBJECT_NIL) { |
---|
179 | return; |
---|
180 | } |
---|
181 | |
---|
182 | g_free (view->details->view_iid); |
---|
183 | view->details->view_iid = NULL; |
---|
184 | |
---|
185 | CORBA_Object_release (view->details->view, NULL); |
---|
186 | view->details->view = CORBA_OBJECT_NIL; |
---|
187 | |
---|
188 | bonobo_object_unref (view->details->view_frame); |
---|
189 | view->details->view_frame = NULL; |
---|
190 | view->details->control_frame = NULL; |
---|
191 | view->details->zoomable_frame = NULL; |
---|
192 | |
---|
193 | engine = bonobo_ui_container_get_engine (view->details->ui_container); |
---|
194 | if (engine != NULL) { |
---|
195 | bonobo_ui_engine_deregister_dead_components (engine); |
---|
196 | } |
---|
197 | bonobo_object_unref (view->details->ui_container); |
---|
198 | view->details->ui_container = NULL; |
---|
199 | } |
---|
200 | |
---|
201 | static void |
---|
202 | shut_down (NautilusViewFrame *view) |
---|
203 | { |
---|
204 | /* It's good to be in "failed" state while shutting down |
---|
205 | * (makes operations all be quiet no-ops). But we don't want |
---|
206 | * to send out a "failed" signal. |
---|
207 | */ |
---|
208 | view->details->state = VIEW_FRAME_FAILED; |
---|
209 | |
---|
210 | stop_activation (view); |
---|
211 | destroy_view (view); |
---|
212 | |
---|
213 | if (view->details->idle_queue != NULL) { |
---|
214 | nautilus_idle_queue_destroy (view->details->idle_queue); |
---|
215 | view->details->idle_queue = NULL; |
---|
216 | } |
---|
217 | |
---|
218 | if (view->details->failed_idle_id != 0) { |
---|
219 | gtk_idle_remove (view->details->failed_idle_id); |
---|
220 | view->details->failed_idle_id = 0; |
---|
221 | } |
---|
222 | if (view->details->socket_gone_idle_id != 0) { |
---|
223 | gtk_idle_remove (view->details->socket_gone_idle_id); |
---|
224 | view->details->socket_gone_idle_id = 0; |
---|
225 | } |
---|
226 | } |
---|
227 | |
---|
228 | static void |
---|
229 | nautilus_view_frame_unrealize (GtkWidget *widget) |
---|
230 | { |
---|
231 | shut_down (NAUTILUS_VIEW_FRAME (widget)); |
---|
232 | EEL_CALL_PARENT (GTK_WIDGET_CLASS, unrealize, (widget)); |
---|
233 | } |
---|
234 | |
---|
235 | static void |
---|
236 | nautilus_view_frame_destroy (GtkObject *object) |
---|
237 | { |
---|
238 | shut_down (NAUTILUS_VIEW_FRAME (object)); |
---|
239 | EEL_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (object)); |
---|
240 | } |
---|
241 | |
---|
242 | static void |
---|
243 | nautilus_view_frame_finalize (GObject *object) |
---|
244 | { |
---|
245 | NautilusViewFrame *view; |
---|
246 | |
---|
247 | view = NAUTILUS_VIEW_FRAME (object); |
---|
248 | |
---|
249 | shut_down (view); |
---|
250 | |
---|
251 | g_free (view->details->title); |
---|
252 | g_free (view->details->label); |
---|
253 | g_free (view->details); |
---|
254 | |
---|
255 | EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); |
---|
256 | } |
---|
257 | |
---|
258 | static void |
---|
259 | emit_zoom_parameters_changed (NautilusViewFrame *view) |
---|
260 | { |
---|
261 | if (view->details->zoomable_frame != NULL) { |
---|
262 | g_signal_emit (view, signals[ZOOM_PARAMETERS_CHANGED], 0); |
---|
263 | } |
---|
264 | } |
---|
265 | |
---|
266 | /* stimulus: successful activated_component call */ |
---|
267 | static void |
---|
268 | view_frame_activated (NautilusViewFrame *view) |
---|
269 | { |
---|
270 | g_assert (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
271 | |
---|
272 | switch (view->details->state) { |
---|
273 | case VIEW_FRAME_EMPTY: |
---|
274 | view->details->state = VIEW_FRAME_NO_LOCATION; |
---|
275 | g_signal_emit (view, signals[VIEW_LOADED], 0); |
---|
276 | emit_zoom_parameters_changed (view); |
---|
277 | send_history (view); |
---|
278 | return; |
---|
279 | case VIEW_FRAME_NO_LOCATION: |
---|
280 | case VIEW_FRAME_UNDERWAY: |
---|
281 | case VIEW_FRAME_LOADED: |
---|
282 | case VIEW_FRAME_WAITING: |
---|
283 | case VIEW_FRAME_FAILED: |
---|
284 | g_assert_not_reached (); |
---|
285 | return; |
---|
286 | } |
---|
287 | |
---|
288 | g_assert_not_reached (); |
---|
289 | } |
---|
290 | |
---|
291 | /* this corresponds to the load_location call stimulus */ |
---|
292 | static void |
---|
293 | view_frame_wait (NautilusViewFrame *view) |
---|
294 | { |
---|
295 | g_assert (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
296 | |
---|
297 | switch (view->details->state) { |
---|
298 | case VIEW_FRAME_EMPTY: |
---|
299 | g_warning ("tried to load location in an empty view frame"); |
---|
300 | break; |
---|
301 | case VIEW_FRAME_NO_LOCATION: |
---|
302 | case VIEW_FRAME_UNDERWAY: |
---|
303 | case VIEW_FRAME_LOADED: |
---|
304 | view->details->state = VIEW_FRAME_WAITING; |
---|
305 | return; |
---|
306 | case VIEW_FRAME_WAITING: |
---|
307 | return; |
---|
308 | case VIEW_FRAME_FAILED: |
---|
309 | g_assert_not_reached (); |
---|
310 | return; |
---|
311 | } |
---|
312 | |
---|
313 | g_assert_not_reached (); |
---|
314 | } |
---|
315 | |
---|
316 | /* this corresponds to the load_underway and load_progress stimulus */ |
---|
317 | static void |
---|
318 | view_frame_underway (NautilusViewFrame *view) |
---|
319 | { |
---|
320 | g_assert (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
321 | |
---|
322 | switch (view->details->state) { |
---|
323 | case VIEW_FRAME_EMPTY: |
---|
324 | g_assert_not_reached (); |
---|
325 | return; |
---|
326 | case VIEW_FRAME_NO_LOCATION: |
---|
327 | g_warning ("got signal from a view frame with no location"); |
---|
328 | return; |
---|
329 | case VIEW_FRAME_WAITING: |
---|
330 | case VIEW_FRAME_LOADED: |
---|
331 | view->details->state = VIEW_FRAME_UNDERWAY; |
---|
332 | g_signal_emit (view, signals[LOAD_UNDERWAY], 0); |
---|
333 | return; |
---|
334 | case VIEW_FRAME_UNDERWAY: |
---|
335 | case VIEW_FRAME_FAILED: |
---|
336 | return; |
---|
337 | } |
---|
338 | |
---|
339 | g_assert_not_reached (); |
---|
340 | } |
---|
341 | |
---|
342 | /* stimulus |
---|
343 | - open_location call from component |
---|
344 | - open_location_in_new_window |
---|
345 | - report_selection_change |
---|
346 | - report_status |
---|
347 | - set_title |
---|
348 | */ |
---|
349 | static void |
---|
350 | view_frame_wait_is_over (NautilusViewFrame *view) |
---|
351 | { |
---|
352 | g_assert (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
353 | |
---|
354 | switch (view->details->state) { |
---|
355 | case VIEW_FRAME_EMPTY: |
---|
356 | case VIEW_FRAME_FAILED: |
---|
357 | g_assert_not_reached (); |
---|
358 | return; |
---|
359 | case VIEW_FRAME_NO_LOCATION: |
---|
360 | g_warning ("got signal from a view frame with no location"); |
---|
361 | return; |
---|
362 | case VIEW_FRAME_WAITING: |
---|
363 | view_frame_underway (view); |
---|
364 | return; |
---|
365 | case VIEW_FRAME_UNDERWAY: |
---|
366 | case VIEW_FRAME_LOADED: |
---|
367 | return; |
---|
368 | } |
---|
369 | |
---|
370 | g_assert_not_reached (); |
---|
371 | } |
---|
372 | |
---|
373 | /* stimulus: report_load_complete */ |
---|
374 | static void |
---|
375 | view_frame_loaded (NautilusViewFrame *view) |
---|
376 | { |
---|
377 | g_assert (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
378 | |
---|
379 | switch (view->details->state) { |
---|
380 | case VIEW_FRAME_EMPTY: |
---|
381 | g_assert_not_reached (); |
---|
382 | return; |
---|
383 | case VIEW_FRAME_NO_LOCATION: |
---|
384 | g_warning ("got signal from a view frame with no location"); |
---|
385 | return; |
---|
386 | case VIEW_FRAME_WAITING: |
---|
387 | view_frame_underway (view); |
---|
388 | /* fall through */ |
---|
389 | case VIEW_FRAME_UNDERWAY: |
---|
390 | view->details->state = VIEW_FRAME_LOADED; |
---|
391 | g_signal_emit (view, signals[LOAD_COMPLETE], 0); |
---|
392 | return; |
---|
393 | case VIEW_FRAME_LOADED: |
---|
394 | case VIEW_FRAME_FAILED: |
---|
395 | return; |
---|
396 | } |
---|
397 | |
---|
398 | g_assert_not_reached (); |
---|
399 | } |
---|
400 | |
---|
401 | /* stimulus: report_load_failed */ |
---|
402 | static void |
---|
403 | view_frame_failed (NautilusViewFrame *view) |
---|
404 | { |
---|
405 | g_assert (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
406 | |
---|
407 | switch (view->details->state) { |
---|
408 | case VIEW_FRAME_EMPTY: |
---|
409 | case VIEW_FRAME_LOADED: |
---|
410 | case VIEW_FRAME_NO_LOCATION: |
---|
411 | case VIEW_FRAME_UNDERWAY: |
---|
412 | case VIEW_FRAME_WAITING: |
---|
413 | view->details->state = VIEW_FRAME_FAILED; |
---|
414 | stop_activation (view); |
---|
415 | destroy_view (view); |
---|
416 | g_signal_emit (view, signals[FAILED], 0); |
---|
417 | return; |
---|
418 | case VIEW_FRAME_FAILED: |
---|
419 | return; |
---|
420 | } |
---|
421 | |
---|
422 | g_assert_not_reached (); |
---|
423 | } |
---|
424 | |
---|
425 | NautilusViewFrame * |
---|
426 | nautilus_view_frame_new (BonoboUIContainer *ui_container, |
---|
427 | NautilusUndoManager *undo_manager) |
---|
428 | { |
---|
429 | NautilusViewFrame *view_frame; |
---|
430 | |
---|
431 | view_frame = NAUTILUS_VIEW_FRAME (gtk_widget_new (nautilus_view_frame_get_type (), NULL)); |
---|
432 | |
---|
433 | bonobo_object_ref (ui_container); |
---|
434 | view_frame->details->ui_container = ui_container; |
---|
435 | view_frame->details->undo_manager = undo_manager; |
---|
436 | |
---|
437 | return view_frame; |
---|
438 | } |
---|
439 | |
---|
440 | static void |
---|
441 | emit_zoom_parameters_changed_callback (gpointer data, |
---|
442 | gpointer callback_data) |
---|
443 | { |
---|
444 | emit_zoom_parameters_changed (NAUTILUS_VIEW_FRAME (data)); |
---|
445 | } |
---|
446 | |
---|
447 | static void |
---|
448 | zoom_parameters_changed_callback (BonoboZoomableFrame *zframe, |
---|
449 | NautilusViewFrame *view) |
---|
450 | { |
---|
451 | g_assert (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
452 | |
---|
453 | nautilus_idle_queue_add (view->details->idle_queue, |
---|
454 | emit_zoom_parameters_changed_callback, |
---|
455 | view, |
---|
456 | NULL, |
---|
457 | NULL); |
---|
458 | } |
---|
459 | |
---|
460 | static void |
---|
461 | emit_zoom_level_changed_callback (gpointer data, |
---|
462 | gpointer callback_data) |
---|
463 | { |
---|
464 | g_signal_emit (data, |
---|
465 | signals[ZOOM_LEVEL_CHANGED], 0, |
---|
466 | * (float *) callback_data); |
---|
467 | } |
---|
468 | |
---|
469 | static void |
---|
470 | zoom_level_changed_callback (BonoboZoomableFrame *zframe, |
---|
471 | float zoom_level, |
---|
472 | NautilusViewFrame *view) |
---|
473 | { |
---|
474 | float *copy; |
---|
475 | |
---|
476 | g_assert (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
477 | |
---|
478 | copy = g_new (float, 1); |
---|
479 | *copy = zoom_level; |
---|
480 | nautilus_idle_queue_add (view->details->idle_queue, |
---|
481 | emit_zoom_level_changed_callback, |
---|
482 | view, |
---|
483 | copy, |
---|
484 | g_free); |
---|
485 | } |
---|
486 | |
---|
487 | enum { |
---|
488 | BONOBO_PROPERTY_TITLE, |
---|
489 | BONOBO_PROPERTY_HISTORY, |
---|
490 | BONOBO_PROPERTY_SELECTION |
---|
491 | }; |
---|
492 | |
---|
493 | static Nautilus_History * |
---|
494 | get_history_list (NautilusViewFrame *view) |
---|
495 | { |
---|
496 | Nautilus_History *history_list; |
---|
497 | |
---|
498 | history_list = NULL; |
---|
499 | g_signal_emit (view, |
---|
500 | signals[GET_HISTORY_LIST], 0, |
---|
501 | &history_list); |
---|
502 | return history_list; |
---|
503 | } |
---|
504 | |
---|
505 | static void |
---|
506 | nautilus_view_frame_get_prop (BonoboPropertyBag *bag, |
---|
507 | BonoboArg *arg, |
---|
508 | guint arg_id, |
---|
509 | CORBA_Environment *ev, |
---|
510 | gpointer user_data) |
---|
511 | { |
---|
512 | NautilusViewFrame *view = user_data; |
---|
513 | |
---|
514 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (user_data)); |
---|
515 | |
---|
516 | switch (arg_id) { |
---|
517 | case BONOBO_PROPERTY_TITLE: |
---|
518 | BONOBO_ARG_SET_STRING (arg, view->details->title); |
---|
519 | break; |
---|
520 | |
---|
521 | case BONOBO_PROPERTY_HISTORY: |
---|
522 | CORBA_free (arg->_value); |
---|
523 | arg->_value = get_history_list (view); |
---|
524 | break; |
---|
525 | |
---|
526 | case BONOBO_PROPERTY_SELECTION: |
---|
527 | g_warning ("NautilusViewFrame: selection fetch not yet implemented"); |
---|
528 | break; |
---|
529 | |
---|
530 | default: |
---|
531 | g_warning ("NautilusViewFrame: Unknown property idx %d", arg_id); |
---|
532 | break; |
---|
533 | } |
---|
534 | } |
---|
535 | |
---|
536 | static BonoboPropertyBag * |
---|
537 | create_ambient_properties (NautilusViewFrame *view) |
---|
538 | { |
---|
539 | BonoboPropertyBag *bag; |
---|
540 | |
---|
541 | bag = bonobo_property_bag_new (nautilus_view_frame_get_prop, NULL, view); |
---|
542 | |
---|
543 | bonobo_property_bag_add |
---|
544 | (bag, |
---|
545 | "title", |
---|
546 | BONOBO_PROPERTY_TITLE, |
---|
547 | TC_CORBA_string, |
---|
548 | NULL, |
---|
549 | _("a title"), |
---|
550 | BONOBO_PROPERTY_READABLE); |
---|
551 | |
---|
552 | bonobo_property_bag_add |
---|
553 | (bag, |
---|
554 | "history", |
---|
555 | BONOBO_PROPERTY_HISTORY, |
---|
556 | TC_Nautilus_History, |
---|
557 | NULL, |
---|
558 | _("the browse history"), |
---|
559 | BONOBO_PROPERTY_READABLE); |
---|
560 | |
---|
561 | bonobo_property_bag_add |
---|
562 | (bag, |
---|
563 | "selection", |
---|
564 | BONOBO_PROPERTY_SELECTION, |
---|
565 | TC_Nautilus_URIList, |
---|
566 | NULL, |
---|
567 | _("the current selection"), |
---|
568 | BONOBO_PROPERTY_READABLE); |
---|
569 | |
---|
570 | view->details->event_source = bag->es; |
---|
571 | |
---|
572 | return bag; |
---|
573 | } |
---|
574 | |
---|
575 | static void |
---|
576 | create_corba_objects (NautilusViewFrame *view) |
---|
577 | { |
---|
578 | CORBA_Environment ev; |
---|
579 | Bonobo_Control control; |
---|
580 | Bonobo_Zoomable zoomable; |
---|
581 | BonoboPropertyBag *bag; |
---|
582 | |
---|
583 | CORBA_exception_init (&ev); |
---|
584 | |
---|
585 | /* Create a view frame. */ |
---|
586 | view->details->view_frame = nautilus_view_frame_create_corba_part (view); |
---|
587 | |
---|
588 | /* Create a control frame. */ |
---|
589 | control = Bonobo_Unknown_queryInterface |
---|
590 | (view->details->view, "IDL:Bonobo/Control:1.0", &ev); |
---|
591 | g_assert (! BONOBO_EX (&ev)); |
---|
592 | |
---|
593 | view->details->control_frame = bonobo_control_frame_new |
---|
594 | (BONOBO_OBJREF (view->details->ui_container)); |
---|
595 | |
---|
596 | bag = create_ambient_properties (view); |
---|
597 | bonobo_control_frame_set_propbag (view->details->control_frame, bag); |
---|
598 | bonobo_object_unref (bag); |
---|
599 | |
---|
600 | bonobo_control_frame_bind_to_control (view->details->control_frame, control, NULL); |
---|
601 | |
---|
602 | bonobo_object_release_unref (control, NULL); |
---|
603 | |
---|
604 | /* Create a zoomable frame. */ |
---|
605 | zoomable = Bonobo_Unknown_queryInterface |
---|
606 | (view->details->view, "IDL:Bonobo/Zoomable:1.0", &ev); |
---|
607 | if (!BONOBO_EX (&ev) |
---|
608 | && !CORBA_Object_is_nil (zoomable, &ev) |
---|
609 | && !BONOBO_EX (&ev)) { |
---|
610 | view->details->zoomable_frame = bonobo_zoomable_frame_new (); |
---|
611 | bonobo_zoomable_frame_bind_to_zoomable |
---|
612 | (view->details->zoomable_frame, zoomable, NULL); |
---|
613 | bonobo_object_release_unref (zoomable, NULL); |
---|
614 | } |
---|
615 | |
---|
616 | CORBA_exception_free (&ev); |
---|
617 | |
---|
618 | /* Aggregate all the interfaces into one object. */ |
---|
619 | bonobo_object_add_interface (BONOBO_OBJECT (view->details->view_frame), |
---|
620 | BONOBO_OBJECT (view->details->control_frame)); |
---|
621 | if (view->details->zoomable_frame != NULL) { |
---|
622 | bonobo_object_add_interface (BONOBO_OBJECT (view->details->view_frame), |
---|
623 | BONOBO_OBJECT (view->details->zoomable_frame)); |
---|
624 | } |
---|
625 | nautilus_undo_manager_add_interface (view->details->undo_manager, |
---|
626 | BONOBO_OBJECT (view->details->view_frame)); |
---|
627 | } |
---|
628 | |
---|
629 | |
---|
630 | static gboolean |
---|
631 | view_frame_failed_callback (gpointer callback_data) |
---|
632 | { |
---|
633 | NautilusViewFrame *view; |
---|
634 | |
---|
635 | view = NAUTILUS_VIEW_FRAME (callback_data); |
---|
636 | view->details->failed_idle_id = 0; |
---|
637 | view_frame_failed (view); |
---|
638 | return FALSE; |
---|
639 | } |
---|
640 | |
---|
641 | static void |
---|
642 | queue_view_frame_failed (NautilusViewFrame *view) |
---|
643 | { |
---|
644 | g_assert (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
645 | |
---|
646 | if (view->details->failed_idle_id == 0) { |
---|
647 | view->details->failed_idle_id = |
---|
648 | gtk_idle_add (view_frame_failed_callback, view); |
---|
649 | } |
---|
650 | } |
---|
651 | |
---|
652 | static gboolean |
---|
653 | check_socket_gone_idle_callback (gpointer callback_data) |
---|
654 | { |
---|
655 | NautilusViewFrame *frame; |
---|
656 | GtkWidget *widget; |
---|
657 | GList *children; |
---|
658 | |
---|
659 | frame = NAUTILUS_VIEW_FRAME (callback_data); |
---|
660 | |
---|
661 | frame->details->socket_gone_idle_id = 0; |
---|
662 | |
---|
663 | widget = bonobo_control_frame_get_widget (frame->details->control_frame); |
---|
664 | |
---|
665 | /* This relies on details of the BonoboControlFrame |
---|
666 | * implementation, specifically that's there's one level of |
---|
667 | * hierarchy between the widget returned by get_widget and the |
---|
668 | * actual plug. |
---|
669 | */ |
---|
670 | children = gtk_container_get_children (GTK_CONTAINER (widget)); |
---|
671 | g_list_free (children); |
---|
672 | |
---|
673 | /* If there's nothing inside the widget at all, that means |
---|
674 | * that the socket went away because the remote plug went away. |
---|
675 | */ |
---|
676 | if (children == NULL) { |
---|
677 | view_frame_failed (frame); |
---|
678 | } |
---|
679 | |
---|
680 | return FALSE; |
---|
681 | } |
---|
682 | |
---|
683 | static void |
---|
684 | check_socket_gone_callback (GtkContainer *container, |
---|
685 | GtkWidget *widget, |
---|
686 | gpointer callback_data) |
---|
687 | { |
---|
688 | NautilusViewFrame *frame; |
---|
689 | |
---|
690 | frame = NAUTILUS_VIEW_FRAME (callback_data); |
---|
691 | |
---|
692 | /* There are two times the socket will be destroyed in Bonobo. |
---|
693 | * One is when a local control decides to not use the socket. |
---|
694 | * The other is when the remote plug goes away. The way to |
---|
695 | * tell these apart is to wait until idle time. At idle time, |
---|
696 | * if there's nothing in the container, then that means the |
---|
697 | * real socket went away. If it was just the local control |
---|
698 | * deciding not to use the socket, there will be another |
---|
699 | * widget in there. |
---|
700 | */ |
---|
701 | if (frame->details->socket_gone_idle_id == 0) { |
---|
702 | frame->details->socket_gone_idle_id = gtk_idle_add |
---|
703 | (check_socket_gone_idle_callback, callback_data); |
---|
704 | } |
---|
705 | } |
---|
706 | |
---|
707 | static void |
---|
708 | attach_view (NautilusViewFrame *view, |
---|
709 | Bonobo_Unknown component) |
---|
710 | { |
---|
711 | CORBA_Environment ev; |
---|
712 | GtkWidget *widget; |
---|
713 | |
---|
714 | /* Either create an adapter or query for the Nautilus:View |
---|
715 | * interface. Either way, we don't need to keep the original |
---|
716 | * reference around once that happens. |
---|
717 | */ |
---|
718 | view->details->view = nautilus_component_adapter_factory_create_adapter |
---|
719 | (nautilus_component_adapter_factory_get (), component); |
---|
720 | |
---|
721 | /* Handle case where we don't know how to host this component. */ |
---|
722 | if (view->details->view == CORBA_OBJECT_NIL) { |
---|
723 | view_frame_failed (view); |
---|
724 | return; |
---|
725 | } |
---|
726 | |
---|
727 | create_corba_objects (view); |
---|
728 | |
---|
729 | CORBA_exception_init (&ev); |
---|
730 | Bonobo_Unknown_unref (view->details->view, &ev); |
---|
731 | CORBA_exception_free (&ev); |
---|
732 | |
---|
733 | widget = bonobo_control_frame_get_widget (view->details->control_frame); |
---|
734 | |
---|
735 | g_signal_connect_object (view->details->view_frame, "destroy", |
---|
736 | G_CALLBACK (view_frame_failed), view, G_CONNECT_SWAPPED); |
---|
737 | g_signal_connect_object (view->details->view_frame, "system_exception", |
---|
738 | G_CALLBACK (queue_view_frame_failed), view, G_CONNECT_SWAPPED); |
---|
739 | g_signal_connect_object (view->details->control_frame, "system_exception", |
---|
740 | G_CALLBACK (queue_view_frame_failed), view, G_CONNECT_SWAPPED); |
---|
741 | g_signal_connect_object (widget, "remove", |
---|
742 | G_CALLBACK (check_socket_gone_callback), view, 0); |
---|
743 | |
---|
744 | if (view->details->zoomable_frame != NULL) { |
---|
745 | g_signal_connect_object (view->details->zoomable_frame, "system_exception", |
---|
746 | G_CALLBACK (queue_view_frame_failed), view, G_CONNECT_SWAPPED); |
---|
747 | g_signal_connect_object (view->details->zoomable_frame, "zoom_parameters_changed", |
---|
748 | G_CALLBACK (zoom_parameters_changed_callback), view, 0); |
---|
749 | g_signal_connect_object (view->details->zoomable_frame, "zoom_level_changed", |
---|
750 | G_CALLBACK (zoom_level_changed_callback), view, 0); |
---|
751 | } |
---|
752 | |
---|
753 | gtk_widget_show (widget); |
---|
754 | gtk_container_add (GTK_CONTAINER (view), widget); |
---|
755 | |
---|
756 | view_frame_activated (view); |
---|
757 | } |
---|
758 | |
---|
759 | static void |
---|
760 | activation_callback (NautilusBonoboActivationHandle *handle, |
---|
761 | Bonobo_Unknown activated_object, |
---|
762 | gpointer callback_data) |
---|
763 | { |
---|
764 | NautilusViewFrame *view; |
---|
765 | |
---|
766 | view = NAUTILUS_VIEW_FRAME (callback_data); |
---|
767 | g_assert (view->details->activation_handle == handle); |
---|
768 | |
---|
769 | view->details->activation_handle = NULL; |
---|
770 | |
---|
771 | if (activated_object == CORBA_OBJECT_NIL) { |
---|
772 | view_frame_failed (view); |
---|
773 | } else { |
---|
774 | attach_view (view, activated_object); |
---|
775 | } |
---|
776 | } |
---|
777 | |
---|
778 | void |
---|
779 | nautilus_view_frame_load_view (NautilusViewFrame *view, |
---|
780 | const char *view_iid) |
---|
781 | { |
---|
782 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
783 | g_return_if_fail (view_iid != NULL); |
---|
784 | |
---|
785 | if (view->details->state == VIEW_FRAME_FAILED) { |
---|
786 | return; |
---|
787 | } |
---|
788 | |
---|
789 | g_return_if_fail (view->details->state == VIEW_FRAME_EMPTY); |
---|
790 | g_assert (view->details->view_iid == NULL); |
---|
791 | g_assert (view->details->activation_handle == NULL); |
---|
792 | |
---|
793 | view->details->view_iid = g_strdup (view_iid); |
---|
794 | view->details->activation_handle = nautilus_bonobo_activate_from_id |
---|
795 | (view_iid, activation_callback, view); |
---|
796 | } |
---|
797 | |
---|
798 | void |
---|
799 | nautilus_view_frame_load_location (NautilusViewFrame *view, |
---|
800 | const char *location) |
---|
801 | { |
---|
802 | CORBA_Environment ev; |
---|
803 | |
---|
804 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
805 | |
---|
806 | if (view->details->state == VIEW_FRAME_FAILED) { |
---|
807 | return; |
---|
808 | } |
---|
809 | |
---|
810 | g_free (view->details->title); |
---|
811 | view->details->title = NULL; |
---|
812 | g_signal_emit (view, signals[TITLE_CHANGED], 0); |
---|
813 | |
---|
814 | view_frame_wait (view); |
---|
815 | |
---|
816 | CORBA_exception_init (&ev); |
---|
817 | Nautilus_View_load_location (view->details->view, location, &ev); |
---|
818 | if (BONOBO_EX (&ev)) { |
---|
819 | view_frame_failed (view); |
---|
820 | } |
---|
821 | CORBA_exception_free (&ev); |
---|
822 | } |
---|
823 | |
---|
824 | void |
---|
825 | nautilus_view_frame_stop (NautilusViewFrame *view) |
---|
826 | { |
---|
827 | CORBA_Environment ev; |
---|
828 | |
---|
829 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
830 | |
---|
831 | if (view->details->state == VIEW_FRAME_FAILED) { |
---|
832 | return; |
---|
833 | } |
---|
834 | |
---|
835 | stop_activation (view); |
---|
836 | |
---|
837 | if (view->details->view != CORBA_OBJECT_NIL) { |
---|
838 | CORBA_exception_init (&ev); |
---|
839 | Nautilus_View_stop_loading (view->details->view, &ev); |
---|
840 | if (BONOBO_EX (&ev)) { |
---|
841 | view_frame_failed (view); |
---|
842 | } |
---|
843 | CORBA_exception_free (&ev); |
---|
844 | } |
---|
845 | } |
---|
846 | |
---|
847 | void |
---|
848 | nautilus_view_frame_selection_changed (NautilusViewFrame *view, |
---|
849 | GList *selection) |
---|
850 | { |
---|
851 | BonoboArg *arg; |
---|
852 | CORBA_Environment ev; |
---|
853 | Nautilus_URIList *uri_list; |
---|
854 | |
---|
855 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
856 | |
---|
857 | if (view->details->view == CORBA_OBJECT_NIL) { |
---|
858 | return; |
---|
859 | } |
---|
860 | |
---|
861 | if (!bonobo_event_source_has_listener |
---|
862 | (view->details->event_source, |
---|
863 | "Bonobo/Property:change:selection")) { |
---|
864 | return; |
---|
865 | } |
---|
866 | |
---|
867 | uri_list = nautilus_uri_list_from_g_list (selection); |
---|
868 | |
---|
869 | CORBA_exception_init (&ev); |
---|
870 | |
---|
871 | arg = bonobo_arg_new_from (TC_Nautilus_URIList, uri_list); |
---|
872 | CORBA_free (uri_list); |
---|
873 | |
---|
874 | bonobo_event_source_notify_listeners |
---|
875 | (view->details->event_source, |
---|
876 | "Bonobo/Property:change:selection", arg, &ev); |
---|
877 | |
---|
878 | CORBA_free (arg); |
---|
879 | |
---|
880 | if (BONOBO_EX (&ev)) { |
---|
881 | view_frame_failed (view); |
---|
882 | } |
---|
883 | |
---|
884 | CORBA_exception_free (&ev); |
---|
885 | } |
---|
886 | |
---|
887 | void |
---|
888 | nautilus_view_frame_title_changed (NautilusViewFrame *view, |
---|
889 | const char *title) |
---|
890 | { |
---|
891 | BonoboArg arg; |
---|
892 | CORBA_Environment ev; |
---|
893 | |
---|
894 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
895 | |
---|
896 | if (view->details->view == CORBA_OBJECT_NIL) { |
---|
897 | return; |
---|
898 | } |
---|
899 | |
---|
900 | CORBA_exception_init (&ev); |
---|
901 | |
---|
902 | arg._type = TC_CORBA_string; |
---|
903 | arg._value = &title; |
---|
904 | |
---|
905 | bonobo_event_source_notify_listeners |
---|
906 | (view->details->event_source, |
---|
907 | "Bonobo/Property:change:title", &arg, &ev); |
---|
908 | |
---|
909 | if (BONOBO_EX (&ev)) { |
---|
910 | view_frame_failed (view); |
---|
911 | } |
---|
912 | |
---|
913 | CORBA_exception_free (&ev); |
---|
914 | } |
---|
915 | |
---|
916 | gboolean |
---|
917 | nautilus_view_frame_get_is_zoomable (NautilusViewFrame *view) |
---|
918 | { |
---|
919 | g_return_val_if_fail (NAUTILUS_IS_VIEW_FRAME (view), FALSE); |
---|
920 | |
---|
921 | return view->details->zoomable_frame != NULL; |
---|
922 | } |
---|
923 | |
---|
924 | float |
---|
925 | nautilus_view_frame_get_zoom_level (NautilusViewFrame *view) |
---|
926 | { |
---|
927 | g_return_val_if_fail (NAUTILUS_IS_VIEW_FRAME (view), 0.0); |
---|
928 | |
---|
929 | if (view->details->zoomable_frame == NULL) { |
---|
930 | return 0.0; |
---|
931 | } |
---|
932 | |
---|
933 | return bonobo_zoomable_frame_get_zoom_level (view->details->zoomable_frame); |
---|
934 | } |
---|
935 | |
---|
936 | void |
---|
937 | nautilus_view_frame_set_zoom_level (NautilusViewFrame *view, |
---|
938 | float zoom_level) |
---|
939 | { |
---|
940 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
941 | |
---|
942 | if (view->details->zoomable_frame == NULL) { |
---|
943 | return; |
---|
944 | } |
---|
945 | |
---|
946 | bonobo_zoomable_frame_set_zoom_level (view->details->zoomable_frame, zoom_level); |
---|
947 | } |
---|
948 | |
---|
949 | float |
---|
950 | nautilus_view_frame_get_min_zoom_level (NautilusViewFrame *view) |
---|
951 | { |
---|
952 | g_return_val_if_fail (NAUTILUS_IS_VIEW_FRAME (view), 0.0); |
---|
953 | |
---|
954 | if (view->details->zoomable_frame == NULL) { |
---|
955 | return 0.0; |
---|
956 | } |
---|
957 | |
---|
958 | return bonobo_zoomable_frame_get_min_zoom_level (view->details->zoomable_frame); |
---|
959 | } |
---|
960 | |
---|
961 | float |
---|
962 | nautilus_view_frame_get_max_zoom_level (NautilusViewFrame *view) |
---|
963 | { |
---|
964 | g_return_val_if_fail (NAUTILUS_IS_VIEW_FRAME (view), 0.0); |
---|
965 | |
---|
966 | if (view->details->zoomable_frame == NULL) { |
---|
967 | return 0.0; |
---|
968 | } |
---|
969 | |
---|
970 | return bonobo_zoomable_frame_get_max_zoom_level (view->details->zoomable_frame); |
---|
971 | } |
---|
972 | |
---|
973 | gboolean |
---|
974 | nautilus_view_frame_get_has_min_zoom_level (NautilusViewFrame *view) |
---|
975 | { |
---|
976 | g_return_val_if_fail (NAUTILUS_IS_VIEW_FRAME (view), FALSE); |
---|
977 | |
---|
978 | if (view->details->zoomable_frame == NULL) { |
---|
979 | return FALSE; |
---|
980 | } |
---|
981 | |
---|
982 | return bonobo_zoomable_frame_has_min_zoom_level (view->details->zoomable_frame); |
---|
983 | } |
---|
984 | |
---|
985 | gboolean |
---|
986 | nautilus_view_frame_get_has_max_zoom_level (NautilusViewFrame *view) |
---|
987 | { |
---|
988 | g_return_val_if_fail (NAUTILUS_IS_VIEW_FRAME (view), FALSE); |
---|
989 | |
---|
990 | if (view->details->zoomable_frame == NULL) { |
---|
991 | return FALSE; |
---|
992 | } |
---|
993 | |
---|
994 | return bonobo_zoomable_frame_has_max_zoom_level (view->details->zoomable_frame); |
---|
995 | } |
---|
996 | |
---|
997 | gboolean |
---|
998 | nautilus_view_frame_get_is_continuous (NautilusViewFrame *view) |
---|
999 | { |
---|
1000 | g_return_val_if_fail (NAUTILUS_IS_VIEW_FRAME (view), FALSE); |
---|
1001 | |
---|
1002 | if (view->details->zoomable_frame == NULL) { |
---|
1003 | return FALSE; |
---|
1004 | } |
---|
1005 | |
---|
1006 | return bonobo_zoomable_frame_is_continuous (view->details->zoomable_frame); |
---|
1007 | } |
---|
1008 | |
---|
1009 | GList * |
---|
1010 | nautilus_view_frame_get_preferred_zoom_levels (NautilusViewFrame *view) |
---|
1011 | { |
---|
1012 | g_return_val_if_fail (NAUTILUS_IS_VIEW_FRAME (view), NULL); |
---|
1013 | |
---|
1014 | if (view->details->zoomable_frame == NULL) { |
---|
1015 | return NULL; |
---|
1016 | } |
---|
1017 | |
---|
1018 | return bonobo_zoomable_frame_get_preferred_zoom_levels (view->details->zoomable_frame); |
---|
1019 | } |
---|
1020 | |
---|
1021 | void |
---|
1022 | nautilus_view_frame_zoom_in (NautilusViewFrame *view) |
---|
1023 | { |
---|
1024 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
1025 | |
---|
1026 | if (view->details->zoomable_frame == NULL) { |
---|
1027 | return; |
---|
1028 | } |
---|
1029 | |
---|
1030 | bonobo_zoomable_frame_zoom_in (view->details->zoomable_frame); |
---|
1031 | } |
---|
1032 | |
---|
1033 | void |
---|
1034 | nautilus_view_frame_zoom_out (NautilusViewFrame *view) |
---|
1035 | { |
---|
1036 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
1037 | |
---|
1038 | if (view->details->zoomable_frame == NULL) { |
---|
1039 | return; |
---|
1040 | } |
---|
1041 | |
---|
1042 | bonobo_zoomable_frame_zoom_out (view->details->zoomable_frame); |
---|
1043 | } |
---|
1044 | |
---|
1045 | void |
---|
1046 | nautilus_view_frame_zoom_to_fit (NautilusViewFrame *view) |
---|
1047 | { |
---|
1048 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
1049 | |
---|
1050 | if (view->details->zoomable_frame == NULL) { |
---|
1051 | return; |
---|
1052 | } |
---|
1053 | |
---|
1054 | bonobo_zoomable_frame_zoom_to_fit (view->details->zoomable_frame); |
---|
1055 | } |
---|
1056 | |
---|
1057 | const char * |
---|
1058 | nautilus_view_frame_get_view_iid (NautilusViewFrame *view) |
---|
1059 | { |
---|
1060 | g_return_val_if_fail (NAUTILUS_IS_VIEW_FRAME (view), NULL); |
---|
1061 | |
---|
1062 | return view->details->view_iid; |
---|
1063 | } |
---|
1064 | |
---|
1065 | void |
---|
1066 | nautilus_view_frame_open_location_in_this_window (NautilusViewFrame *view, |
---|
1067 | const char *location) |
---|
1068 | { |
---|
1069 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
1070 | |
---|
1071 | if (view->details->state == VIEW_FRAME_FAILED) { |
---|
1072 | return; |
---|
1073 | } |
---|
1074 | |
---|
1075 | view_frame_wait_is_over (view); |
---|
1076 | g_signal_emit (view, signals[OPEN_LOCATION_IN_THIS_WINDOW], 0, location); |
---|
1077 | } |
---|
1078 | |
---|
1079 | void |
---|
1080 | nautilus_view_frame_open_location_prefer_existing_window (NautilusViewFrame *view, |
---|
1081 | const char *location) |
---|
1082 | { |
---|
1083 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
1084 | |
---|
1085 | if (view->details->state == VIEW_FRAME_FAILED) { |
---|
1086 | return; |
---|
1087 | } |
---|
1088 | |
---|
1089 | view_frame_wait_is_over (view); |
---|
1090 | g_signal_emit (view, signals[OPEN_LOCATION_PREFER_EXISTING_WINDOW], 0, location); |
---|
1091 | } |
---|
1092 | |
---|
1093 | void |
---|
1094 | nautilus_view_frame_open_location_force_new_window (NautilusViewFrame *view, |
---|
1095 | const char *location, |
---|
1096 | GList *selection) |
---|
1097 | { |
---|
1098 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
1099 | |
---|
1100 | if (view->details->state == VIEW_FRAME_FAILED) { |
---|
1101 | return; |
---|
1102 | } |
---|
1103 | |
---|
1104 | view_frame_wait_is_over (view); |
---|
1105 | g_signal_emit (view, |
---|
1106 | signals[OPEN_LOCATION_FORCE_NEW_WINDOW], 0, |
---|
1107 | location, selection); |
---|
1108 | } |
---|
1109 | |
---|
1110 | void |
---|
1111 | nautilus_view_frame_report_location_change (NautilusViewFrame *view, |
---|
1112 | const char *location, |
---|
1113 | GList *selection, |
---|
1114 | const char *title) |
---|
1115 | { |
---|
1116 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
1117 | |
---|
1118 | if (view->details->state == VIEW_FRAME_FAILED) { |
---|
1119 | return; |
---|
1120 | } |
---|
1121 | |
---|
1122 | g_free (view->details->title); |
---|
1123 | view->details->title = g_strdup (title); |
---|
1124 | |
---|
1125 | view_frame_wait_is_over (view); |
---|
1126 | g_signal_emit (view, |
---|
1127 | signals[REPORT_LOCATION_CHANGE], 0, |
---|
1128 | location, selection, title); |
---|
1129 | } |
---|
1130 | |
---|
1131 | void |
---|
1132 | nautilus_view_frame_report_redirect (NautilusViewFrame *view, |
---|
1133 | const char *from_location, |
---|
1134 | const char *to_location, |
---|
1135 | GList *selection, |
---|
1136 | const char *title) |
---|
1137 | { |
---|
1138 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
1139 | |
---|
1140 | if (view->details->state == VIEW_FRAME_FAILED) { |
---|
1141 | return; |
---|
1142 | } |
---|
1143 | |
---|
1144 | g_free (view->details->title); |
---|
1145 | view->details->title = g_strdup (title); |
---|
1146 | |
---|
1147 | view_frame_wait_is_over (view); |
---|
1148 | g_signal_emit (view, |
---|
1149 | signals[REPORT_REDIRECT], 0, |
---|
1150 | from_location, to_location, selection, title); |
---|
1151 | } |
---|
1152 | |
---|
1153 | void |
---|
1154 | nautilus_view_frame_report_selection_change (NautilusViewFrame *view, |
---|
1155 | GList *selection) |
---|
1156 | { |
---|
1157 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
1158 | |
---|
1159 | if (view->details->state == VIEW_FRAME_FAILED) { |
---|
1160 | return; |
---|
1161 | } |
---|
1162 | |
---|
1163 | view_frame_wait_is_over (view); |
---|
1164 | g_signal_emit (view, |
---|
1165 | signals[CHANGE_SELECTION], 0, selection); |
---|
1166 | } |
---|
1167 | |
---|
1168 | void |
---|
1169 | nautilus_view_frame_report_status (NautilusViewFrame *view, |
---|
1170 | const char *status) |
---|
1171 | { |
---|
1172 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
1173 | |
---|
1174 | if (view->details->state == VIEW_FRAME_FAILED) { |
---|
1175 | return; |
---|
1176 | } |
---|
1177 | |
---|
1178 | view_frame_wait_is_over (view); |
---|
1179 | g_signal_emit (view, |
---|
1180 | signals[CHANGE_STATUS], 0, status); |
---|
1181 | } |
---|
1182 | |
---|
1183 | void |
---|
1184 | nautilus_view_frame_report_load_underway (NautilusViewFrame *view) |
---|
1185 | { |
---|
1186 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
1187 | |
---|
1188 | view_frame_underway (view); |
---|
1189 | } |
---|
1190 | |
---|
1191 | void |
---|
1192 | nautilus_view_frame_report_load_progress (NautilusViewFrame *view, |
---|
1193 | double fraction_done) |
---|
1194 | { |
---|
1195 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
1196 | |
---|
1197 | if (view->details->state == VIEW_FRAME_FAILED) { |
---|
1198 | return; |
---|
1199 | } |
---|
1200 | |
---|
1201 | view_frame_underway (view); |
---|
1202 | g_signal_emit (view, |
---|
1203 | signals[LOAD_PROGRESS_CHANGED], 0); |
---|
1204 | } |
---|
1205 | |
---|
1206 | void |
---|
1207 | nautilus_view_frame_report_load_complete (NautilusViewFrame *view) |
---|
1208 | { |
---|
1209 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
1210 | |
---|
1211 | view_frame_loaded (view); |
---|
1212 | } |
---|
1213 | |
---|
1214 | void |
---|
1215 | nautilus_view_frame_report_load_failed (NautilusViewFrame *view) |
---|
1216 | { |
---|
1217 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
1218 | |
---|
1219 | view_frame_failed (view); |
---|
1220 | } |
---|
1221 | |
---|
1222 | /* return the Bonobo_Control CORBA object associated with the view frame */ |
---|
1223 | Bonobo_Control |
---|
1224 | nautilus_view_frame_get_control (NautilusViewFrame *view) |
---|
1225 | { |
---|
1226 | if (view->details->control_frame == NULL) { |
---|
1227 | return CORBA_OBJECT_NIL; |
---|
1228 | } |
---|
1229 | return bonobo_control_frame_get_control (view->details->control_frame); |
---|
1230 | } |
---|
1231 | |
---|
1232 | void |
---|
1233 | nautilus_view_frame_go_back (NautilusViewFrame *view) |
---|
1234 | { |
---|
1235 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
1236 | |
---|
1237 | g_signal_emit (view, signals[GO_BACK], 0); |
---|
1238 | } |
---|
1239 | |
---|
1240 | void |
---|
1241 | nautilus_view_frame_close_window (NautilusViewFrame *view) |
---|
1242 | { |
---|
1243 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
1244 | |
---|
1245 | g_signal_emit (view, signals[CLOSE_WINDOW], 0); |
---|
1246 | } |
---|
1247 | |
---|
1248 | void |
---|
1249 | nautilus_view_frame_set_title (NautilusViewFrame *view, |
---|
1250 | const char *title) |
---|
1251 | { |
---|
1252 | gboolean changed; |
---|
1253 | |
---|
1254 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
1255 | g_return_if_fail (title != NULL); |
---|
1256 | |
---|
1257 | if (view->details->state == VIEW_FRAME_FAILED) { |
---|
1258 | return; |
---|
1259 | } |
---|
1260 | |
---|
1261 | /* Only do work if the title actually changed. */ |
---|
1262 | changed = view->details->title == NULL |
---|
1263 | || strcmp (view->details->title, title) != 0; |
---|
1264 | |
---|
1265 | g_free (view->details->title); |
---|
1266 | view->details->title = g_strdup (title); |
---|
1267 | |
---|
1268 | view_frame_wait_is_over (view); |
---|
1269 | if (changed) { |
---|
1270 | g_signal_emit (view, signals[TITLE_CHANGED], 0); |
---|
1271 | } |
---|
1272 | } |
---|
1273 | |
---|
1274 | char * |
---|
1275 | nautilus_view_frame_get_title (NautilusViewFrame *view) |
---|
1276 | { |
---|
1277 | g_return_val_if_fail (NAUTILUS_IS_VIEW_FRAME (view), NULL); |
---|
1278 | |
---|
1279 | return g_strdup (view->details->title); |
---|
1280 | } |
---|
1281 | |
---|
1282 | char * |
---|
1283 | nautilus_view_frame_get_label (NautilusViewFrame *view) |
---|
1284 | { |
---|
1285 | g_return_val_if_fail (NAUTILUS_IS_VIEW_FRAME (view), NULL); |
---|
1286 | |
---|
1287 | return g_strdup (view->details->label); |
---|
1288 | } |
---|
1289 | |
---|
1290 | void |
---|
1291 | nautilus_view_frame_set_label (NautilusViewFrame *view, |
---|
1292 | const char *label) |
---|
1293 | { |
---|
1294 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
1295 | |
---|
1296 | g_free (view->details->label); |
---|
1297 | view->details->label = g_strdup (label); |
---|
1298 | } |
---|
1299 | |
---|
1300 | /* Activate the underlying control frame whenever the view is mapped. |
---|
1301 | * This causes the view to merge its menu items, for example. For |
---|
1302 | * sidebar panels, it might be a little late to merge them at map |
---|
1303 | * time. What's a better time? |
---|
1304 | */ |
---|
1305 | static void |
---|
1306 | nautilus_view_frame_map (GtkWidget *view_as_widget) |
---|
1307 | { |
---|
1308 | NautilusViewFrame *view; |
---|
1309 | |
---|
1310 | view = NAUTILUS_VIEW_FRAME (view_as_widget); |
---|
1311 | |
---|
1312 | EEL_CALL_PARENT (GTK_WIDGET_CLASS, map, (view_as_widget)); |
---|
1313 | |
---|
1314 | if (view->details->control_frame != NULL) { |
---|
1315 | bonobo_control_frame_control_activate (view->details->control_frame); |
---|
1316 | } |
---|
1317 | } |
---|
1318 | |
---|
1319 | static void |
---|
1320 | send_history (NautilusViewFrame *view) |
---|
1321 | { |
---|
1322 | Nautilus_History *history; |
---|
1323 | CORBA_Environment ev; |
---|
1324 | BonoboArg *arg; |
---|
1325 | |
---|
1326 | g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view)); |
---|
1327 | |
---|
1328 | if (view->details->view == CORBA_OBJECT_NIL) { |
---|
1329 | return; |
---|
1330 | } |
---|
1331 | |
---|
1332 | if (!bonobo_event_source_has_listener |
---|
1333 | (view->details->event_source, |
---|
1334 | "Bonobo/Property:change:history")) { |
---|
1335 | return; |
---|
1336 | } |
---|
1337 | |
---|
1338 | history = get_history_list (view); |
---|
1339 | if (history == CORBA_OBJECT_NIL) { |
---|
1340 | return; |
---|
1341 | } |
---|
1342 | |
---|
1343 | CORBA_exception_init (&ev); |
---|
1344 | |
---|
1345 | arg = bonobo_arg_new_from (TC_Nautilus_History, history); |
---|
1346 | |
---|
1347 | CORBA_free (history); |
---|
1348 | |
---|
1349 | bonobo_event_source_notify_listeners |
---|
1350 | (view->details->event_source, |
---|
1351 | "Bonobo/Property:change:history", arg, &ev); |
---|
1352 | |
---|
1353 | CORBA_free (arg); |
---|
1354 | |
---|
1355 | if (BONOBO_EX (&ev)) { |
---|
1356 | view_frame_failed (view); |
---|
1357 | } |
---|
1358 | |
---|
1359 | CORBA_exception_free (&ev); |
---|
1360 | } |
---|
1361 | |
---|
1362 | gboolean |
---|
1363 | nautilus_view_frame_get_is_view_loaded (NautilusViewFrame *view) |
---|
1364 | { |
---|
1365 | g_return_val_if_fail (NAUTILUS_IS_VIEW_FRAME (view), FALSE); |
---|
1366 | |
---|
1367 | switch (view->details->state) { |
---|
1368 | case VIEW_FRAME_EMPTY: |
---|
1369 | case VIEW_FRAME_FAILED: |
---|
1370 | return FALSE; |
---|
1371 | case VIEW_FRAME_NO_LOCATION: |
---|
1372 | case VIEW_FRAME_WAITING: |
---|
1373 | case VIEW_FRAME_UNDERWAY: |
---|
1374 | case VIEW_FRAME_LOADED: |
---|
1375 | return TRUE; |
---|
1376 | } |
---|
1377 | |
---|
1378 | g_assert_not_reached (); |
---|
1379 | return FALSE; |
---|
1380 | } |
---|
1381 | |
---|
1382 | static void |
---|
1383 | nautilus_view_frame_class_init (NautilusViewFrameClass *class) |
---|
1384 | { |
---|
1385 | G_OBJECT_CLASS (class)->finalize = nautilus_view_frame_finalize; |
---|
1386 | GTK_OBJECT_CLASS (class)->destroy = nautilus_view_frame_destroy; |
---|
1387 | GTK_WIDGET_CLASS (class)->unrealize = nautilus_view_frame_unrealize; |
---|
1388 | GTK_WIDGET_CLASS (class)->map = nautilus_view_frame_map; |
---|
1389 | |
---|
1390 | signals[CHANGE_SELECTION] = g_signal_new |
---|
1391 | ("change_selection", |
---|
1392 | G_TYPE_FROM_CLASS (class), |
---|
1393 | G_SIGNAL_RUN_LAST, |
---|
1394 | G_STRUCT_OFFSET (NautilusViewFrameClass, |
---|
1395 | change_selection), |
---|
1396 | NULL, NULL, |
---|
1397 | g_cclosure_marshal_VOID__POINTER, |
---|
1398 | G_TYPE_NONE, 1, G_TYPE_POINTER); |
---|
1399 | signals[CHANGE_STATUS] = g_signal_new |
---|
1400 | ("change_status", |
---|
1401 | G_TYPE_FROM_CLASS (class), |
---|
1402 | G_SIGNAL_RUN_LAST, |
---|
1403 | G_STRUCT_OFFSET (NautilusViewFrameClass, |
---|
1404 | change_status), |
---|
1405 | NULL, NULL, |
---|
1406 | g_cclosure_marshal_VOID__STRING, |
---|
1407 | G_TYPE_NONE, 1, G_TYPE_STRING); |
---|
1408 | signals[FAILED] = g_signal_new |
---|
1409 | ("failed", |
---|
1410 | G_TYPE_FROM_CLASS (class), |
---|
1411 | G_SIGNAL_RUN_LAST, |
---|
1412 | G_STRUCT_OFFSET (NautilusViewFrameClass, |
---|
1413 | failed), |
---|
1414 | NULL, NULL, |
---|
1415 | g_cclosure_marshal_VOID__VOID, |
---|
1416 | G_TYPE_NONE, 0); |
---|
1417 | signals[GET_HISTORY_LIST] = g_signal_new |
---|
1418 | ("get_history_list", |
---|
1419 | G_TYPE_FROM_CLASS (class), |
---|
1420 | G_SIGNAL_RUN_LAST, |
---|
1421 | G_STRUCT_OFFSET (NautilusViewFrameClass, |
---|
1422 | get_history_list), |
---|
1423 | NULL, NULL, |
---|
1424 | nautilus_marshal_POINTER__VOID, |
---|
1425 | G_TYPE_POINTER, 0); |
---|
1426 | signals[GO_BACK] = g_signal_new |
---|
1427 | ("go_back", |
---|
1428 | G_TYPE_FROM_CLASS (class), |
---|
1429 | G_SIGNAL_RUN_LAST, |
---|
1430 | G_STRUCT_OFFSET (NautilusViewFrameClass, |
---|
1431 | go_back), |
---|
1432 | NULL, NULL, |
---|
1433 | g_cclosure_marshal_VOID__VOID, |
---|
1434 | G_TYPE_NONE, 0); |
---|
1435 | signals[CLOSE_WINDOW] = g_signal_new |
---|
1436 | ("close_window", |
---|
1437 | G_TYPE_FROM_CLASS (class), |
---|
1438 | G_SIGNAL_RUN_LAST, |
---|
1439 | G_STRUCT_OFFSET (NautilusViewFrameClass, |
---|
1440 | close_window), |
---|
1441 | NULL, NULL, |
---|
1442 | g_cclosure_marshal_VOID__VOID, |
---|
1443 | G_TYPE_NONE, 0); |
---|
1444 | signals[LOAD_COMPLETE] = g_signal_new |
---|
1445 | ("load_complete", |
---|
1446 | G_TYPE_FROM_CLASS (class), |
---|
1447 | G_SIGNAL_RUN_LAST, |
---|
1448 | G_STRUCT_OFFSET (NautilusViewFrameClass, |
---|
1449 | load_complete), |
---|
1450 | NULL, NULL, |
---|
1451 | g_cclosure_marshal_VOID__VOID, |
---|
1452 | G_TYPE_NONE, 0); |
---|
1453 | signals[LOAD_PROGRESS_CHANGED] = g_signal_new |
---|
1454 | ("load_progress_changed", |
---|
1455 | G_TYPE_FROM_CLASS (class), |
---|
1456 | G_SIGNAL_RUN_LAST, |
---|
1457 | G_STRUCT_OFFSET (NautilusViewFrameClass, |
---|
1458 | load_progress_changed), |
---|
1459 | NULL, NULL, |
---|
1460 | g_cclosure_marshal_VOID__VOID, |
---|
1461 | G_TYPE_NONE, 0); |
---|
1462 | signals[LOAD_UNDERWAY] = g_signal_new |
---|
1463 | ("load_underway", |
---|
1464 | G_TYPE_FROM_CLASS (class), |
---|
1465 | G_SIGNAL_RUN_LAST, |
---|
1466 | G_STRUCT_OFFSET (NautilusViewFrameClass, |
---|
1467 | load_underway), |
---|
1468 | NULL, NULL, |
---|
1469 | g_cclosure_marshal_VOID__VOID, |
---|
1470 | G_TYPE_NONE, 0); |
---|
1471 | signals[OPEN_LOCATION_FORCE_NEW_WINDOW] = g_signal_new |
---|
1472 | ("open_location_force_new_window", |
---|
1473 | G_TYPE_FROM_CLASS (class), |
---|
1474 | G_SIGNAL_RUN_LAST, |
---|
1475 | G_STRUCT_OFFSET (NautilusViewFrameClass, |
---|
1476 | open_location_force_new_window), |
---|
1477 | NULL, NULL, |
---|
1478 | eel_marshal_VOID__STRING_POINTER, |
---|
1479 | G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_POINTER); |
---|
1480 | signals[OPEN_LOCATION_IN_THIS_WINDOW] = g_signal_new |
---|
1481 | ("open_location_in_this_window", |
---|
1482 | G_TYPE_FROM_CLASS (class), |
---|
1483 | G_SIGNAL_RUN_LAST, |
---|
1484 | G_STRUCT_OFFSET (NautilusViewFrameClass, |
---|
1485 | open_location_in_this_window), |
---|
1486 | NULL, NULL, |
---|
1487 | g_cclosure_marshal_VOID__STRING, |
---|
1488 | G_TYPE_NONE, 1, G_TYPE_STRING); |
---|
1489 | signals[OPEN_LOCATION_PREFER_EXISTING_WINDOW] = g_signal_new |
---|
1490 | ("open_location_prefer_existing_window", |
---|
1491 | G_TYPE_FROM_CLASS (class), |
---|
1492 | G_SIGNAL_RUN_LAST, |
---|
1493 | G_STRUCT_OFFSET (NautilusViewFrameClass, |
---|
1494 | open_location_prefer_existing_window), |
---|
1495 | NULL, NULL, |
---|
1496 | g_cclosure_marshal_VOID__STRING, |
---|
1497 | G_TYPE_NONE, 1, G_TYPE_STRING); |
---|
1498 | signals[REPORT_LOCATION_CHANGE] = g_signal_new |
---|
1499 | ("report_location_change", |
---|
1500 | G_TYPE_FROM_CLASS (class), |
---|
1501 | G_SIGNAL_RUN_LAST, |
---|
1502 | G_STRUCT_OFFSET (NautilusViewFrameClass, |
---|
1503 | report_location_change), |
---|
1504 | NULL, NULL, |
---|
1505 | eel_marshal_VOID__STRING_POINTER_STRING, |
---|
1506 | G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING); |
---|
1507 | signals[REPORT_REDIRECT] = g_signal_new |
---|
1508 | ("report_redirect", |
---|
1509 | G_TYPE_FROM_CLASS (class), |
---|
1510 | G_SIGNAL_RUN_LAST, |
---|
1511 | G_STRUCT_OFFSET (NautilusViewFrameClass, |
---|
1512 | report_redirect), |
---|
1513 | NULL, NULL, |
---|
1514 | eel_marshal_VOID__STRING_STRING_POINTER_STRING, |
---|
1515 | G_TYPE_NONE, 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING); |
---|
1516 | signals[TITLE_CHANGED] = g_signal_new |
---|
1517 | ("title_changed", |
---|
1518 | G_TYPE_FROM_CLASS (class), |
---|
1519 | G_SIGNAL_RUN_LAST, |
---|
1520 | G_STRUCT_OFFSET (NautilusViewFrameClass, |
---|
1521 | title_changed), |
---|
1522 | NULL, NULL, |
---|
1523 | g_cclosure_marshal_VOID__VOID, |
---|
1524 | G_TYPE_NONE, 0); |
---|
1525 | signals[VIEW_LOADED] = g_signal_new |
---|
1526 | ("view_loaded", |
---|
1527 | G_TYPE_FROM_CLASS (class), |
---|
1528 | G_SIGNAL_RUN_LAST, |
---|
1529 | G_STRUCT_OFFSET (NautilusViewFrameClass, |
---|
1530 | view_loaded), |
---|
1531 | NULL, NULL, |
---|
1532 | g_cclosure_marshal_VOID__VOID, |
---|
1533 | G_TYPE_NONE, 0); |
---|
1534 | signals[ZOOM_LEVEL_CHANGED] = g_signal_new |
---|
1535 | ("zoom_level_changed", |
---|
1536 | G_TYPE_FROM_CLASS (class), |
---|
1537 | G_SIGNAL_RUN_LAST, |
---|
1538 | G_STRUCT_OFFSET (NautilusViewFrameClass, |
---|
1539 | zoom_level_changed), |
---|
1540 | NULL, NULL, |
---|
1541 | g_cclosure_marshal_VOID__VOID, |
---|
1542 | G_TYPE_NONE, 0); |
---|
1543 | signals[ZOOM_PARAMETERS_CHANGED] = g_signal_new |
---|
1544 | ("zoom_parameters_changed", |
---|
1545 | G_TYPE_FROM_CLASS (class), |
---|
1546 | G_SIGNAL_RUN_LAST, |
---|
1547 | G_STRUCT_OFFSET (NautilusViewFrameClass, |
---|
1548 | zoom_parameters_changed), |
---|
1549 | NULL, NULL, |
---|
1550 | g_cclosure_marshal_VOID__VOID, |
---|
1551 | G_TYPE_NONE, 0); |
---|
1552 | } |
---|