diff --git a/ChangeLog b/ChangeLog index 4029adec3..6f0e7ad66 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2000-10-13 Mathieu Lacage + + * docs/state-machines.txt: new design for the state + machine taking into account the new async states. + * libnautilus-extensions/nautilus-bonobo-extensions.c: + (nautilus_bonobo_set_icon), (oaf_activation_callback), + (nautilus_bonobo_activate_from_id), + (nautilus_bonobo_activate_stop), + (nautilus_bonobo_activate_free): + add async activation call. + * libnautilus-extensions/nautilus-bonobo-extensions.h: + add prototypes. + * src/nautilus-view-frame.c: + (nautilus_view_frame_initialize_class), (view_frame_activating), + (view_frame_not_activated), (view_frame_activated), + (view_frame_stop_activation), (view_frame_wait), + (view_frame_underway), (view_frame_wait_is_over), + (view_frame_loaded), (view_frame_failed), + (nautilus_view_frame_set_to_component), (activation_callback), + (nautilus_view_frame_load_client_async), + (nautilus_view_frame_load_client), + (nautilus_view_frame_stop_activation), + (nautilus_view_frame_load_location): + implement new state machine. add comments to explain by which stimulus + the state-chaging functions are triggered. + * src/nautilus-view-frame.h: + add prototype for new async activation function of ViewFrames. + 2000-10-12 Andy Hertzfeld * src/Makefile.am: diff --git a/docs/state-machines.txt b/docs/state-machines.txt index f70abec65..a762aa9dc 100644 --- a/docs/state-machines.txt +++ b/docs/state-machines.txt @@ -6,7 +6,9 @@ ViewFrame state machine States are: + E: Empty (the initial state right after construction) +A: Activating (waiting for component to be activated) N: No load_location request (a view component has been loaded, but no load_location request has been sent yet) W: Waiting (waiting for a response after a load request) U: Underway (the component has responded and the load is assumed underway) @@ -28,7 +30,7 @@ Missing: Note: -A "*" means htat this is illegal but non-fatal, so we want to use g_warning. +A "*" means that this is illegal but non-fatal, so we want to use g_warning. State Transition Chart @@ -36,33 +38,40 @@ A "*" means htat this is illegal but non-fatal, so we want to use g_warning. Initial State - | E | N | W | U | L | F | - ----------------------------------------|-----|-----|-----|-----|-----|-----| - successful load_client call | N | X | X | X | X | ?2 | - ----------------------------------------|-----|-----|-----|-----|-----|-----| - unsuccessful load_client call | F | X | X | X | X | ?2 | - ----------------------------------------|-----|-----|-----|-----|-----|-----| - nautilus_view_frame_load_location call | F | W | W | W | W | ?2 | - ----------------------------------------|-----|-----|-----|-----|-----|-----| - open_location call from component | X | N* | U | U | L | X | - ----------------------------------------|-----|-----|-----|-----|-----|-----| - open_location_in_new_window | X | N* | U | U | L | X | - ----------------------------------------|-----|-----|-----|-----|-----|-----| - report_location_change | X | N* | U | U | U | X | -S ----------------------------------------|-----|-----|-----|-----|-----|-----| -t report_selection_change | X | N* | U | U | L | X | -i ----------------------------------------|-----|-----|-----|-----|-----|-----| -m report_status | X | N* | U | U | L | X | -u ----------------------------------------|-----|-----|-----|-----|-----|-----| -l report_load_underway | X | N* | U | U | U | X | -u ----------------------------------------|-----|-----|-----|-----|-----|-----| -s report_load_progress | X | N* | U | U | U | X | - ----------------------------------------|-----|-----|-----|-----|-----|-----| - report_load_complete | X | N* | L | L | L | X | - ----------------------------------------|-----|-----|-----|-----|-----|-----| - report_load_failed | X | N* | F | F | F | X | - ----------------------------------------|-----|-----|-----|-----|-----|-----| - set_title | X | N* | U | U | L | X | - ----------------------------------------|-----|-----|-----|-----|-----|-----| - user hits cancel on timer dialog | X | X | F | X | X | X | - ----------------------------------------|-----|-----|-----|-----|-----|-----| + | E | A | N | W | U | L | F | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + successful load_client call | A | X | X | X | X | X | ?2 | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + unsuccessful load_client call | F | X | X | X | X | X | ?2 | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + successful activated_component call | X | N | X | X | X | X | ?2 | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + unsuccessful activated_component call | X | F | X | X | X | X | ?2 | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + stop activation | E | E | X | X | X | X | ?2 | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + nautilus_view_frame_load_location call | X | F | W | W | W | W | ?2 | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + open_location call from component | X | X | N* | U | U | L | X | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + open_location_in_new_window | X | X | N* | U | U | L | X | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + report_location_change | X | X | N* | U | U | U | X | +S ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| +t report_selection_change | X | X | N* | U | U | L | X | +i ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| +m report_status | X | X | N* | U | U | L | X | +u ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| +l report_load_underway | X | X | N* | U | U | U | X | +u ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| +s report_load_progress | X | X | N* | U | U | U | X | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + report_load_complete | X | X | N* | L | L | L | X | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + report_load_failed | X | X | N* | F | F | F | X | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + set_title | X | X | N* | U | U | L | X | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + user hits cancel on timer dialog | X | X | X | F | X | X | X | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + diff --git a/libnautilus-extensions/nautilus-bonobo-extensions.c b/libnautilus-extensions/nautilus-bonobo-extensions.c index 8be51eb0b..1a83f68f8 100644 --- a/libnautilus-extensions/nautilus-bonobo-extensions.c +++ b/libnautilus-extensions/nautilus-bonobo-extensions.c @@ -30,6 +30,8 @@ #include #include +#include + void nautilus_bonobo_set_accelerator (BonoboUIComponent *ui, const char *path, @@ -259,3 +261,113 @@ nautilus_bonobo_set_icon (BonoboUIComponent *ui, "pixtype", "filename", NULL); } + +struct _NautilusBonoboActivate { + NautilusBonoboActivateCallback activation_callback; + gpointer callback_data; + gboolean stop_activation; +}; + +static void +oaf_activation_callback (CORBA_Object object_reference, + const char *error_reason, + gpointer user_data) +{ + NautilusBonoboActivate *activate_struct; + CORBA_Environment ev; + + activate_struct = (NautilusBonoboActivate *) user_data; + CORBA_exception_init (&ev); + + if (CORBA_Object_is_nil (object_reference, &ev)) { + /* error */ + activate_struct->activation_callback (NULL, + activate_struct->callback_data); + + } else if (!activate_struct->stop_activation) { + + /* report activation to caller */ + activate_struct->activation_callback (object_reference, + activate_struct->callback_data); + + } else if (activate_struct->stop_activation) { + activate_struct->stop_activation = FALSE; + + Bonobo_Unknown_unref (object_reference, &ev); + /* it is no use to check for exception here since we + have no way of reporting it... */ + } + CORBA_exception_free (&ev); +} + + +/** + * nautilus_bonobo_activate_from_id: + * @iid: iid of component to activate. + * @callback: callback to call when activation finished. + * @user_data: data to pass to callback when activation finished. + * + * This function will return NULL if something bad happened during + * activation. Alternatively, it will return a structure you are + * supposed to free yourself when you have received a call in your + * callback. + */ +NautilusBonoboActivate * +nautilus_bonobo_activate_from_id (const char *iid, + NautilusBonoboActivateCallback callback, + gpointer user_data) +{ + NautilusBonoboActivate *activate_structure; + CORBA_Environment ev; + + if (iid == NULL || callback == NULL) { + return NULL; + } + + activate_structure = g_new0 (NautilusBonoboActivate, 1); + + activate_structure->stop_activation = FALSE; + activate_structure->activation_callback = callback; + activate_structure->callback_data = user_data; + + CORBA_exception_init (&ev); + oaf_activate_from_id_async ((const OAF_ActivationID) iid, 0, oaf_activation_callback, + activate_structure , &ev); + + if (ev._major != CORBA_NO_EXCEPTION) { + return NULL; + } + + CORBA_exception_free (&ev); + + return activate_structure; +} + +/** + * nautilus_bonobo_activate_from_id: + * @iid: iid of component to activate. + * @callback: callback to call when activation finished. + * @user_data: data to pass to callback when activation finished. + * + * Stops activation of a component. Your callback will never be called. + * you should free your %NautilusBonoboActivate strucutre through + * nautilus_bonobo_activate_free after this call. + */ + +void +nautilus_bonobo_activate_stop (NautilusBonoboActivate *activate_structure) +{ + activate_structure->stop_activation = TRUE; +} + +/** + * nautilus_bonobo_activate_free: + * @activate_structure: structure to free. + * + * Frees the corresponding structure. + */ +void +nautilus_bonobo_activate_free (NautilusBonoboActivate *activate_structure) +{ + g_free (activate_structure); +} diff --git a/libnautilus-extensions/nautilus-bonobo-extensions.h b/libnautilus-extensions/nautilus-bonobo-extensions.h index 525d2cc7d..9c8ff2114 100644 --- a/libnautilus-extensions/nautilus-bonobo-extensions.h +++ b/libnautilus-extensions/nautilus-bonobo-extensions.h @@ -69,4 +69,15 @@ void nautilus_bonobo_set_icon (BonoboUIComponent *ui, const char *path, const char *icon_relative_path); +typedef struct _NautilusBonoboActivate NautilusBonoboActivate; + +typedef void (*NautilusBonoboActivateCallback) (CORBA_Object object_reference, gpointer data); + +NautilusBonoboActivate *nautilus_bonobo_activate_from_id (const char *iid, + NautilusBonoboActivateCallback callback, + gpointer user_data); +void nautilus_bonobo_activate_stop (NautilusBonoboActivate *activate_structure); +void nautilus_bonobo_activate_free (NautilusBonoboActivate *activate_structure); + + #endif /* NAUTILUS_BONOBO_EXTENSIONS_H */ diff --git a/libnautilus-private/nautilus-bonobo-extensions.c b/libnautilus-private/nautilus-bonobo-extensions.c index 8be51eb0b..1a83f68f8 100644 --- a/libnautilus-private/nautilus-bonobo-extensions.c +++ b/libnautilus-private/nautilus-bonobo-extensions.c @@ -30,6 +30,8 @@ #include #include +#include + void nautilus_bonobo_set_accelerator (BonoboUIComponent *ui, const char *path, @@ -259,3 +261,113 @@ nautilus_bonobo_set_icon (BonoboUIComponent *ui, "pixtype", "filename", NULL); } + +struct _NautilusBonoboActivate { + NautilusBonoboActivateCallback activation_callback; + gpointer callback_data; + gboolean stop_activation; +}; + +static void +oaf_activation_callback (CORBA_Object object_reference, + const char *error_reason, + gpointer user_data) +{ + NautilusBonoboActivate *activate_struct; + CORBA_Environment ev; + + activate_struct = (NautilusBonoboActivate *) user_data; + CORBA_exception_init (&ev); + + if (CORBA_Object_is_nil (object_reference, &ev)) { + /* error */ + activate_struct->activation_callback (NULL, + activate_struct->callback_data); + + } else if (!activate_struct->stop_activation) { + + /* report activation to caller */ + activate_struct->activation_callback (object_reference, + activate_struct->callback_data); + + } else if (activate_struct->stop_activation) { + activate_struct->stop_activation = FALSE; + + Bonobo_Unknown_unref (object_reference, &ev); + /* it is no use to check for exception here since we + have no way of reporting it... */ + } + CORBA_exception_free (&ev); +} + + +/** + * nautilus_bonobo_activate_from_id: + * @iid: iid of component to activate. + * @callback: callback to call when activation finished. + * @user_data: data to pass to callback when activation finished. + * + * This function will return NULL if something bad happened during + * activation. Alternatively, it will return a structure you are + * supposed to free yourself when you have received a call in your + * callback. + */ +NautilusBonoboActivate * +nautilus_bonobo_activate_from_id (const char *iid, + NautilusBonoboActivateCallback callback, + gpointer user_data) +{ + NautilusBonoboActivate *activate_structure; + CORBA_Environment ev; + + if (iid == NULL || callback == NULL) { + return NULL; + } + + activate_structure = g_new0 (NautilusBonoboActivate, 1); + + activate_structure->stop_activation = FALSE; + activate_structure->activation_callback = callback; + activate_structure->callback_data = user_data; + + CORBA_exception_init (&ev); + oaf_activate_from_id_async ((const OAF_ActivationID) iid, 0, oaf_activation_callback, + activate_structure , &ev); + + if (ev._major != CORBA_NO_EXCEPTION) { + return NULL; + } + + CORBA_exception_free (&ev); + + return activate_structure; +} + +/** + * nautilus_bonobo_activate_from_id: + * @iid: iid of component to activate. + * @callback: callback to call when activation finished. + * @user_data: data to pass to callback when activation finished. + * + * Stops activation of a component. Your callback will never be called. + * you should free your %NautilusBonoboActivate strucutre through + * nautilus_bonobo_activate_free after this call. + */ + +void +nautilus_bonobo_activate_stop (NautilusBonoboActivate *activate_structure) +{ + activate_structure->stop_activation = TRUE; +} + +/** + * nautilus_bonobo_activate_free: + * @activate_structure: structure to free. + * + * Frees the corresponding structure. + */ +void +nautilus_bonobo_activate_free (NautilusBonoboActivate *activate_structure) +{ + g_free (activate_structure); +} diff --git a/libnautilus-private/nautilus-bonobo-extensions.h b/libnautilus-private/nautilus-bonobo-extensions.h index 525d2cc7d..9c8ff2114 100644 --- a/libnautilus-private/nautilus-bonobo-extensions.h +++ b/libnautilus-private/nautilus-bonobo-extensions.h @@ -69,4 +69,15 @@ void nautilus_bonobo_set_icon (BonoboUIComponent *ui, const char *path, const char *icon_relative_path); +typedef struct _NautilusBonoboActivate NautilusBonoboActivate; + +typedef void (*NautilusBonoboActivateCallback) (CORBA_Object object_reference, gpointer data); + +NautilusBonoboActivate *nautilus_bonobo_activate_from_id (const char *iid, + NautilusBonoboActivateCallback callback, + gpointer user_data); +void nautilus_bonobo_activate_stop (NautilusBonoboActivate *activate_structure); +void nautilus_bonobo_activate_free (NautilusBonoboActivate *activate_structure); + + #endif /* NAUTILUS_BONOBO_EXTENSIONS_H */ diff --git a/src/nautilus-view-frame.c b/src/nautilus-view-frame.c index 6839fc356..bcb7b86b0 100644 --- a/src/nautilus-view-frame.c +++ b/src/nautilus-view-frame.c @@ -37,6 +37,7 @@ #include #include +#include #include #include #include @@ -54,6 +55,7 @@ enum { REPORT_LOAD_PROGRESS, REPORT_LOAD_COMPLETE, REPORT_LOAD_FAILED, + REPORT_ACTIVATION_COMPLETE, TITLE_CHANGED, ZOOM_LEVEL_CHANGED, CLIENT_GONE, @@ -63,6 +65,7 @@ enum { typedef enum { VIEW_FRAME_EMPTY, + VIEW_FRAME_ACTIVATING, VIEW_FRAME_NO_LOCATION, VIEW_FRAME_WAITING, VIEW_FRAME_UNDERWAY, @@ -79,12 +82,20 @@ struct NautilusViewFrameDetails { BonoboUIContainer *ui_container; guint check_if_view_is_gone_timeout_id; + + char *activation_iid; + NautilusBonoboActivate *activate_structure; }; static void nautilus_view_frame_initialize (NautilusViewFrame *view); static void nautilus_view_frame_destroy (GtkObject *view); static void nautilus_view_frame_initialize_class (NautilusViewFrameClass *klass); +static void view_frame_not_activated (NautilusViewFrame *view); +static void view_frame_activated (NautilusViewFrame *view); +static void view_frame_stop_activation (NautilusViewFrame *view); + + static guint signals[LAST_SIGNAL]; NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusViewFrame, nautilus_view_frame, NAUTILUS_TYPE_GENEROUS_BIN) @@ -161,6 +172,15 @@ nautilus_view_frame_initialize_class (NautilusViewFrameClass *klass) report_load_failed), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); + signals[REPORT_ACTIVATION_COMPLETE] = + gtk_signal_new ("report_activation_complete", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (NautilusViewFrameClass, + report_activation_complete), + gtk_marshal_NONE__POINTER, + GTK_TYPE_NONE, 1, + GTK_TYPE_POINTER); signals[TITLE_CHANGED] = gtk_signal_new ("title_changed", GTK_RUN_LAST, @@ -298,6 +318,110 @@ nautilus_view_frame_new (BonoboUIContainer *ui_container, return view_frame; } +/* stimulus: successful load_client call */ +static void +view_frame_activating (NautilusViewFrame *view) +{ + g_assert (NAUTILUS_IS_VIEW_FRAME (view)); + + switch (view->details->state) { + case VIEW_FRAME_EMPTY: + view->details->state = VIEW_FRAME_ACTIVATING; + return; + break; + case VIEW_FRAME_ACTIVATING: + case VIEW_FRAME_NO_LOCATION: + case VIEW_FRAME_UNDERWAY: + case VIEW_FRAME_LOADED: + case VIEW_FRAME_WAITING: + case VIEW_FRAME_FAILED: + g_assert_not_reached (); + return; + } + + g_assert_not_reached (); +} + + +/* stimulus: unsuccessful activated_component call */ +static void +view_frame_not_activated (NautilusViewFrame *view) +{ + g_assert (NAUTILUS_IS_VIEW_FRAME (view)); + + switch (view->details->state) { + case VIEW_FRAME_ACTIVATING: + view->details->state = VIEW_FRAME_FAILED; + return; + break; + case VIEW_FRAME_EMPTY: + case VIEW_FRAME_NO_LOCATION: + case VIEW_FRAME_UNDERWAY: + case VIEW_FRAME_LOADED: + case VIEW_FRAME_WAITING: + case VIEW_FRAME_FAILED: + g_assert_not_reached (); + return; + break; + } + + g_assert_not_reached (); +} + +/* stimulus: successful activated_component call */ +static void +view_frame_activated (NautilusViewFrame *view) +{ + g_assert (NAUTILUS_IS_VIEW_FRAME (view)); + + switch (view->details->state) { + case VIEW_FRAME_ACTIVATING: + view->details->state = VIEW_FRAME_NO_LOCATION; + return; + break; + case VIEW_FRAME_EMPTY: + case VIEW_FRAME_NO_LOCATION: + case VIEW_FRAME_UNDERWAY: + case VIEW_FRAME_LOADED: + case VIEW_FRAME_WAITING: + case VIEW_FRAME_FAILED: + g_assert_not_reached (); + return; + break; + } + + g_assert_not_reached (); +} + + +/* stimulus: stop activation */ +static void +view_frame_stop_activation (NautilusViewFrame *view) +{ + g_assert (NAUTILUS_IS_VIEW_FRAME (view)); + + switch (view->details->state) { + case VIEW_FRAME_EMPTY: + case VIEW_FRAME_ACTIVATING: + view->details->state = VIEW_FRAME_EMPTY; + return; + break; + case VIEW_FRAME_NO_LOCATION: + case VIEW_FRAME_UNDERWAY: + case VIEW_FRAME_LOADED: + case VIEW_FRAME_WAITING: + case VIEW_FRAME_FAILED: + g_assert_not_reached (); + return; + break; + } + + g_assert_not_reached (); +} + + + +/* this corresponds to the load_location call stimulus */ static void view_frame_wait (NautilusViewFrame *view) { @@ -308,6 +432,9 @@ view_frame_wait (NautilusViewFrame *view) /* Darin: Change to state machine? */ g_warning ("tried to load location in an empty view frame"); break; + case VIEW_FRAME_ACTIVATING: + view->details->state = VIEW_FRAME_FAILED; + break; case VIEW_FRAME_NO_LOCATION: case VIEW_FRAME_UNDERWAY: case VIEW_FRAME_LOADED: @@ -323,6 +450,8 @@ view_frame_wait (NautilusViewFrame *view) g_assert_not_reached (); } + +/* this corresponds to the load_underway and load_progress stimulus */ static void view_frame_underway (NautilusViewFrame *view) { @@ -331,6 +460,7 @@ view_frame_underway (NautilusViewFrame *view) switch (view->details->state) { case VIEW_FRAME_EMPTY: case VIEW_FRAME_FAILED: + case VIEW_FRAME_ACTIVATING: g_assert_not_reached (); return; case VIEW_FRAME_NO_LOCATION: @@ -348,6 +478,13 @@ view_frame_underway (NautilusViewFrame *view) g_assert_not_reached (); } +/* stimulus + - open_location call from component + - open_location_in_new_window + - report_selection_change + - report_status + - set_title +*/ static void view_frame_wait_is_over (NautilusViewFrame *view) { @@ -356,6 +493,7 @@ view_frame_wait_is_over (NautilusViewFrame *view) switch (view->details->state) { case VIEW_FRAME_EMPTY: case VIEW_FRAME_FAILED: + case VIEW_FRAME_ACTIVATING: g_assert_not_reached (); return; case VIEW_FRAME_NO_LOCATION: @@ -372,6 +510,9 @@ view_frame_wait_is_over (NautilusViewFrame *view) g_assert_not_reached (); } + +/* stimulus: report_load_complete */ + static void view_frame_loaded (NautilusViewFrame *view) { @@ -380,6 +521,7 @@ view_frame_loaded (NautilusViewFrame *view) switch (view->details->state) { case VIEW_FRAME_EMPTY: case VIEW_FRAME_FAILED: + case VIEW_FRAME_ACTIVATING: g_assert_not_reached (); return; case VIEW_FRAME_NO_LOCATION: @@ -397,6 +539,8 @@ view_frame_loaded (NautilusViewFrame *view) g_assert_not_reached (); } +/* stimulus: report_load_failed */ + static void view_frame_failed (NautilusViewFrame *view) { @@ -408,6 +552,7 @@ view_frame_failed (NautilusViewFrame *view) g_assert_not_reached (); return; case VIEW_FRAME_NO_LOCATION: + case VIEW_FRAME_ACTIVATING: g_warning ("got signal from a view frame with no location"); return; case VIEW_FRAME_WAITING: @@ -451,31 +596,20 @@ check_if_view_is_gone (gpointer data) return ok; } -gboolean /* returns TRUE if successful */ -nautilus_view_frame_load_client (NautilusViewFrame *view, const char *iid) +static gboolean +nautilus_view_frame_set_to_component (NautilusViewFrame *view, BonoboObjectClient *component) { CORBA_Environment ev; Nautilus_View adapted; - BonoboObjectClient *component; Bonobo_Control control; BonoboControlFrame *control_frame; - - g_return_val_if_fail (NAUTILUS_IS_VIEW_FRAME (view), FALSE); - g_return_val_if_fail (view->details->state == VIEW_FRAME_EMPTY, FALSE); - - if (iid == NULL) { - return FALSE; - } - - component = bonobo_object_activate (iid, 0); - if (component == NULL) { - return FALSE; - } + /* Either create an adapter or query for the Nautilus:View * interface. Either way, we don't need to keep the original * reference around once that happens. */ + adapted = nautilus_component_adapter_factory_create_adapter (nautilus_component_adapter_factory_get (), component); @@ -530,7 +664,7 @@ nautilus_view_frame_load_client (NautilusViewFrame *view, const char *iid) bonobo_object_release_unref (control, NULL); - view->iid = g_strdup (iid); + view->iid = g_strdup (view->details->activation_iid); gtk_signal_connect_while_alive (GTK_OBJECT (view->client_object), "destroy", @@ -555,10 +689,92 @@ nautilus_view_frame_load_client (NautilusViewFrame *view, const char *iid) view->details->check_if_view_is_gone_timeout_id = g_timeout_add (10000, check_if_view_is_gone, view); - view->details->state = VIEW_FRAME_NO_LOCATION; return TRUE; } + +static void +activation_callback (CORBA_Object object_reference, gpointer data) +{ + NautilusViewFrame *view; + BonoboObjectClient *bonobo_object; + + view = (NautilusViewFrame *) data; + + bonobo_object = bonobo_object_client_from_corba (object_reference); + nautilus_view_frame_set_to_component (view, bonobo_object); + + gtk_signal_emit (GTK_OBJECT (view), signals[REPORT_ACTIVATION_COMPLETE], + bonobo_object); + +} + + + +void +nautilus_view_frame_load_client_async (NautilusViewFrame *view, + const char *iid) +{ + NautilusBonoboActivate *activate_structure; + + view_frame_activating (view); + view->details->activation_iid = g_strdup (iid); + activate_structure = nautilus_bonobo_activate_from_id (iid, + activation_callback, + view); + + view->details->activate_structure = activate_structure; +} + + + +/** + * I left this function around because I was lazy to make the sidebar activation + * use the async model in the main state machine... there are 2 reasons for not + * doing so: + * - sidebar components should NOT take long to load. + * - hacking the state machine might take me as long as it took me to get + * the core stuff working so... I am not eager to get into this game. + * + * As a consequence, the folowing function does quite a few calls to + * the state changing functions to simulate async activation... + * + */ +gboolean /* returns TRUE if successful */ +nautilus_view_frame_load_client (NautilusViewFrame *view, const char *iid) +{ + BonoboObjectClient *component; + + g_return_val_if_fail (NAUTILUS_IS_VIEW_FRAME (view), FALSE); + g_return_val_if_fail (view->details->state == VIEW_FRAME_EMPTY, FALSE); + + if (iid == NULL) { + return FALSE; + } + + view_frame_activating (view); + component = bonobo_object_activate (iid, 0); + if (component == NULL) { + view_frame_not_activated (view); + return FALSE; + } + + view->details->activation_iid = g_strdup (iid); + view_frame_activated (view); + + return nautilus_view_frame_set_to_component (view, component); +} + +void +nautilus_view_frame_stop_activation (NautilusViewFrame *view) +{ + nautilus_bonobo_activate_stop (view->details->activate_structure); + view_frame_stop_activation (view); + nautilus_bonobo_activate_free (view->details->activate_structure); + view->details->activate_structure = NULL; +} + + static void set_up_for_new_location (NautilusViewFrame *view) { @@ -578,6 +794,7 @@ nautilus_view_frame_load_location (NautilusViewFrame *view, set_up_for_new_location (view); view_frame_wait (view); + /* ORBit does a bad job with Nautilus_URI, so it's not const char *. */ CORBA_exception_init (&ev); Nautilus_View_load_location (bonobo_object_corba_objref (BONOBO_OBJECT (view->client_object)), @@ -992,3 +1209,12 @@ nautilus_view_frame_get_history_list (NautilusViewFrame *view) &history_list); return history_list; } + + + + + + + + + diff --git a/src/nautilus-view-frame.h b/src/nautilus-view-frame.h index d9d62f47e..2953112bd 100644 --- a/src/nautilus-view-frame.h +++ b/src/nautilus-view-frame.h @@ -89,6 +89,9 @@ typedef struct { void (* zoom_level_changed) (NautilusViewFrame *view, double zoom_level); + void (* report_activation_complete) (NautilusViewFrame *view, + BonoboObjectClient *object); + /* Error handling for when client goes away. */ void (* client_gone) (NautilusViewFrame *view); @@ -97,6 +100,15 @@ typedef struct { (* get_history_list) (NautilusViewFrame *view); } NautilusViewFrameClass; +typedef void (*NautilusActivationCallback) (NautilusViewFrame *view_frame, gpointer data); + +void nautilus_view_frame_load_client_async (NautilusViewFrame *view, + const char *iid); + +void nautilus_view_frame_stop_activation (NautilusViewFrame *view); + + + GtkType nautilus_view_frame_get_type (void); NautilusViewFrame * nautilus_view_frame_new (BonoboUIContainer *ui_container, NautilusUndoManager *undo_manager);