new design for the state machine taking into account the new async states.

2000-10-13  Mathieu Lacage  <mathieu@eazel.com>

	* 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.
This commit is contained in:
Mathieu Lacage 2000-10-13 05:56:11 +00:00 committed by Mathieu Lacage
parent 116c3b58bf
commit feb4a10f48
8 changed files with 569 additions and 48 deletions

View file

@ -1,3 +1,31 @@
2000-10-13 Mathieu Lacage <mathieu@eazel.com>
* 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 <andy@eazel.com>
* src/Makefile.am:

View file

@ -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 |
----------------------------------------|-----|-----|-----|-----|-----|-----|-----|

View file

@ -30,6 +30,8 @@
#include <bonobo/bonobo-ui-util.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <liboaf/oaf-async.h>
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);
}

View file

@ -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 */

View file

@ -30,6 +30,8 @@
#include <bonobo/bonobo-ui-util.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <liboaf/oaf-async.h>
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);
}

View file

@ -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 */

View file

@ -37,6 +37,7 @@
#include <libnautilus-extensions/nautilus-gtk-extensions.h>
#include <libnautilus-extensions/nautilus-gtk-macros.h>
#include <libnautilus-extensions/nautilus-bonobo-extensions.h>
#include <gtk/gtksignal.h>
#include <gtk/gtk.h>
#include <libnautilus-extensions/nautilus-undo-manager.h>
@ -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;
}

View file

@ -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);