reviewed by: John Sullivan <sullivan@eazel.com>

Some preparation work for doing async. activation. This amounts
	to another pass cleaning up the legendary "state machine" as well
	as some other cleanups in the async. activation code.

	* libnautilus-extensions/nautilus-bonobo-extensions.h:
	* libnautilus-extensions/nautilus-bonobo-extensions.c:
	(oaf_activation_callback), (nautilus_bonobo_activate_from_id),
	(nautilus_bonobo_activate_cancel): Fix interface of activation to
	be cleaner. Also handle case where callback is called right away.

	Add queuing to NautilusView so that all incoming CORBA calls are
	dispatched at idle time. This can fix some otherwise-difficult
	re-entrancy problems. The widget destroy call can still come in at
	any time though. Also this same fix may be needed for the
	NautilusViewFrame side.

	* libnautilus/nautilus-view.h:
	* libnautilus/nautilus-view.c: (execute_queued_calls): Function
	to dequeue and execute calls.
	(dequeue_calls_at_idle): Cover to call it at idle time.
	(discard_queued_calls): Discard calls without executing them, for
	use at destroy time.
	(queue_incoming_call): Simple cover to queue and schedule an
	idle-time dequeue pass.
	(nautilus_g_list_from_uri_list): Need to make a full copy, not
	a shallow copy, now that we are queuing things for a hile.
	(call_load_location), (call_stop_loading),
	(call_selection_changed), (call_title_changed),
	(call_history_changed): Simple functions that get queued.
	(list_deep_free_cover): GDestroyNotify-compatible function for one
	destroy case.
	(history_dup): Function to copy the history list, since that is
	now queued instead of used right away.
	(impl_Nautilus_View_load_location),
	(impl_Nautilus_View_stop_loading),
	(impl_Nautilus_View_selection_changed),
	(impl_Nautilus_View_title_changed),
	(impl_Nautilus_View_history_changed): Change these all to queue
	the incoming call instead of doing work right away.
	(nautilus_view_destroy): Discard the queue.

	* src/nautilus-view-frame-corba.c:
	(impl_Nautilus_ViewFrame_open_location_force_new_window),
	(impl_Nautilus_ViewFrame_report_selection_change): These calls now
	use the deep copy, since the shallow one is no longer available.
	This is good since we probably will be doing queuing here later,
	so we'll need the deep copy.

	* src/nautilus-view-frame.h:
	* src/nautilus-view-frame.c:
	(nautilus_view_frame_initialize_class): Set up a map default signal
	handler to activate the control. This is better than the old way,
	where we had an explicit call to do it.
	(nautilus_view_frame_destroy_client): Remove unused
	CORBA_Environment.
	(view_frame_activated): Remove unneeded ACTIVATING state. Also
	send the client_loaded signal in here, so you can't "forget".
	(view_frame_wait), (view_frame_underway),
	(view_frame_wait_is_over), (view_frame_loaded),
	(view_frame_failed): Remove unneeded ACTIVATING state.
	(check_if_view_is_gone): Simplify logic and make sure to check the
	value of the exception and not just the function result.
	(attach_client): Fix CORBA_Exception that was allocated twice and
	that could also be allocated and not freed in some cases.
	(activation_callback), (nautilus_view_frame_load_client_async):
	Better names, use new API, still not tested.
	(nautilus_view_frame_load_client): Get rid of function result and
	use unified interface for telling about success and failure so that
	sync. and async. interfaces will be the same.
	(nautilus_view_frame_stop): Renamed this single function, which
	will soon stop either activation that's in process or loading
	that's in process with a single call. For now it's just the same
	as the old stop_loading call.
	(nautilus_view_frame_map): New override to activate the control.
	This replaces the old explicit activate call.
	(send_history), (nautilus_view_frame_get_is_underway): Remove
	unneeded ACTIVATING state.

	* src/nautilus-window.h:
	* src/nautilus-window-manage-views.c:
	(location_has_really_changed): Assume that new_content_view is not
	NULL. The old code was trying to be inappropriately "general".
	(disconnect_destroy_unref_view): Remove now-unused function.
	(load_content_view): Don't use a return value any more, since it's
	important to set up new_content_view before any signals happen.
	Get rid of code that handles failure right at the start, since
	we now get all failures through the signal handler.
	(handle_view_failure): Add FIXME comments. Minor refactoring.
	(cancel_location_change): Eliminated now-uneeded views_shown and
	view_bombed_out booleans.
	(load_view_for_new_location): New load_content_view doesn't return
	a value any more.
	(update_state): Changed this to be a loop instead of returning a
	boolean and always being called in a loop. Also simplified logic
	so that views_shown and view_bombed_out aren't needed any more.
	(nautilus_window_end_location_change_callback): Use update_state
	directly instead of calling the old clunky change_state cover.
	(nautilus_window_begin_location_change): Use update_state directly
	instead of calling the old clunky change_state cover.
	(stop_loading): Call the new simple nautilus_view_frame_stop
	instead of nautilus_view_frame_stop_loading.
	(natuilus_window_stop_loading): Use update_state directly instead
	of calling the old clunky change_state cover.
	(nautilus_window_set_content_view): Use update_state directly instead
	of calling the old clunky change_state cover.
	(nautilus_window_set_sidebar_panels): Handle failures with
	callback instead of looking at return value (which no longer
	exists).
	(client_loaded_callback): Add this new callback that's done when
	the view is activated and ready to go.
	(failed_callback): Use update_state directly instead of calling
	the old clunky change_state cover.
	(load_underway_callback): Use update_state directly instead of
	calling the old clunky change_state cover.
	(load_complete_callback): Use update_state directly instead of
	calling the old clunky change_state cover.

	* src/nautilus-window.c:
	(nautilus_window_set_content_view_widget): Get rid of explicit
	activation, no longer needed now that NautilusViewFrame handles it
	directly.

	* test/test-nautilus-async-activation.c: (activation_callback),
	(main): Change to use new async. API.

	* user-guide/gnufdl/.cvsignore: Add to ignore some missing files.
This commit is contained in:
Darin Adler 2001-01-26 18:56:57 +00:00
parent 3d2e30943a
commit 2717a5cdd3
21 changed files with 859 additions and 803 deletions

131
ChangeLog
View file

@ -1,3 +1,134 @@
2001-01-25 Darin Adler <darin@eazel.com>
reviewed by: John Sullivan <sullivan@eazel.com>
Some preparation work for doing async. activation. This amounts
to another pass cleaning up the legendary "state machine" as well
as some other cleanups in the async. activation code.
* libnautilus-extensions/nautilus-bonobo-extensions.h:
* libnautilus-extensions/nautilus-bonobo-extensions.c:
(oaf_activation_callback), (nautilus_bonobo_activate_from_id),
(nautilus_bonobo_activate_cancel): Fix interface of activation to
be cleaner. Also handle case where callback is called right away.
Add queuing to NautilusView so that all incoming CORBA calls are
dispatched at idle time. This can fix some otherwise-difficult
re-entrancy problems. The widget destroy call can still come in at
any time though. Also this same fix may be needed for the
NautilusViewFrame side.
* libnautilus/nautilus-view.h:
* libnautilus/nautilus-view.c: (execute_queued_calls): Function
to dequeue and execute calls.
(dequeue_calls_at_idle): Cover to call it at idle time.
(discard_queued_calls): Discard calls without executing them, for
use at destroy time.
(queue_incoming_call): Simple cover to queue and schedule an
idle-time dequeue pass.
(nautilus_g_list_from_uri_list): Need to make a full copy, not
a shallow copy, now that we are queuing things for a hile.
(call_load_location), (call_stop_loading),
(call_selection_changed), (call_title_changed),
(call_history_changed): Simple functions that get queued.
(list_deep_free_cover): GDestroyNotify-compatible function for one
destroy case.
(history_dup): Function to copy the history list, since that is
now queued instead of used right away.
(impl_Nautilus_View_load_location),
(impl_Nautilus_View_stop_loading),
(impl_Nautilus_View_selection_changed),
(impl_Nautilus_View_title_changed),
(impl_Nautilus_View_history_changed): Change these all to queue
the incoming call instead of doing work right away.
(nautilus_view_destroy): Discard the queue.
* src/nautilus-view-frame-corba.c:
(impl_Nautilus_ViewFrame_open_location_force_new_window),
(impl_Nautilus_ViewFrame_report_selection_change): These calls now
use the deep copy, since the shallow one is no longer available.
This is good since we probably will be doing queuing here later,
so we'll need the deep copy.
* src/nautilus-view-frame.h:
* src/nautilus-view-frame.c:
(nautilus_view_frame_initialize_class): Set up a map default signal
handler to activate the control. This is better than the old way,
where we had an explicit call to do it.
(nautilus_view_frame_destroy_client): Remove unused
CORBA_Environment.
(view_frame_activated): Remove unneeded ACTIVATING state. Also
send the client_loaded signal in here, so you can't "forget".
(view_frame_wait), (view_frame_underway),
(view_frame_wait_is_over), (view_frame_loaded),
(view_frame_failed): Remove unneeded ACTIVATING state.
(check_if_view_is_gone): Simplify logic and make sure to check the
value of the exception and not just the function result.
(attach_client): Fix CORBA_Exception that was allocated twice and
that could also be allocated and not freed in some cases.
(activation_callback), (nautilus_view_frame_load_client_async):
Better names, use new API, still not tested.
(nautilus_view_frame_load_client): Get rid of function result and
use unified interface for telling about success and failure so that
sync. and async. interfaces will be the same.
(nautilus_view_frame_stop): Renamed this single function, which
will soon stop either activation that's in process or loading
that's in process with a single call. For now it's just the same
as the old stop_loading call.
(nautilus_view_frame_map): New override to activate the control.
This replaces the old explicit activate call.
(send_history), (nautilus_view_frame_get_is_underway): Remove
unneeded ACTIVATING state.
* src/nautilus-window.h:
* src/nautilus-window-manage-views.c:
(location_has_really_changed): Assume that new_content_view is not
NULL. The old code was trying to be inappropriately "general".
(disconnect_destroy_unref_view): Remove now-unused function.
(load_content_view): Don't use a return value any more, since it's
important to set up new_content_view before any signals happen.
Get rid of code that handles failure right at the start, since
we now get all failures through the signal handler.
(handle_view_failure): Add FIXME comments. Minor refactoring.
(cancel_location_change): Eliminated now-uneeded views_shown and
view_bombed_out booleans.
(load_view_for_new_location): New load_content_view doesn't return
a value any more.
(update_state): Changed this to be a loop instead of returning a
boolean and always being called in a loop. Also simplified logic
so that views_shown and view_bombed_out aren't needed any more.
(nautilus_window_end_location_change_callback): Use update_state
directly instead of calling the old clunky change_state cover.
(nautilus_window_begin_location_change): Use update_state directly
instead of calling the old clunky change_state cover.
(stop_loading): Call the new simple nautilus_view_frame_stop
instead of nautilus_view_frame_stop_loading.
(natuilus_window_stop_loading): Use update_state directly instead
of calling the old clunky change_state cover.
(nautilus_window_set_content_view): Use update_state directly instead
of calling the old clunky change_state cover.
(nautilus_window_set_sidebar_panels): Handle failures with
callback instead of looking at return value (which no longer
exists).
(client_loaded_callback): Add this new callback that's done when
the view is activated and ready to go.
(failed_callback): Use update_state directly instead of calling
the old clunky change_state cover.
(load_underway_callback): Use update_state directly instead of
calling the old clunky change_state cover.
(load_complete_callback): Use update_state directly instead of
calling the old clunky change_state cover.
* src/nautilus-window.c:
(nautilus_window_set_content_view_widget): Get rid of explicit
activation, no longer needed now that NautilusViewFrame handles it
directly.
* test/test-nautilus-async-activation.c: (activation_callback),
(main): Change to use new async. API.
* user-guide/gnufdl/.cvsignore: Add to ignore some missing files.
2001-01-25 Maciej Stachowiak <mjs@eazel.com>
* src/nautilus-window-manage-views.c

View file

@ -26,13 +26,19 @@
#include <config.h>
#include "nautilus-bonobo-extensions.h"
#include "nautilus-string.h"
#include "nautilus-string.h"
#include <bonobo/bonobo-ui-util.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <liboaf/oaf-async.h>
struct NautilusBonoboActivationHandle {
NautilusBonoboActivationHandle **early_completion_hook;
NautilusBonoboActivationCallback callback;
gpointer callback_data;
gboolean cancel;
};
void
nautilus_bonobo_set_accelerator (BonoboUIComponent *ui,
const char *path,
@ -423,44 +429,33 @@ nautilus_bonobo_set_icon (BonoboUIComponent *ui,
"filename", NULL);
}
struct _NautilusBonoboActivate {
NautilusBonoboActivateCallback activation_callback;
gpointer callback_data;
gboolean stop_activation;
};
static void
oaf_activation_callback (CORBA_Object object_reference,
oaf_activation_callback (Bonobo_Unknown activated_object,
const char *error_reason,
gpointer user_data)
gpointer callback_data)
{
NautilusBonoboActivate *activate_struct;
NautilusBonoboActivationHandle *handle;
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 (CORBA_OBJECT_NIL,
activate_struct->callback_data);
handle = (NautilusBonoboActivationHandle *) 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... */
if (handle->cancel) {
CORBA_exception_init (&ev);
Bonobo_Unknown_unref (activated_object, &ev);
CORBA_exception_free (&ev);
} else {
(* handle->callback) (handle,
activated_object,
handle->callback_data);
}
CORBA_exception_free (&ev);
}
if (handle->early_completion_hook != NULL) {
g_assert (*handle->early_completion_hook == handle);
*handle->early_completion_hook = NULL;
}
g_free (handle);
}
/**
* nautilus_bonobo_activate_from_id:
@ -469,67 +464,53 @@ oaf_activation_callback (CORBA_Object object_reference,
* @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.
* activation.
*/
NautilusBonoboActivate *
nautilus_bonobo_activate_from_id (const char *iid,
NautilusBonoboActivateCallback callback,
gpointer user_data)
NautilusBonoboActivationHandle *
nautilus_bonobo_activate_from_id (const char *iid,
NautilusBonoboActivationCallback callback,
gpointer callback_data)
{
NautilusBonoboActivate *activate_structure;
CORBA_Environment ev;
NautilusBonoboActivationHandle *handle;
if (iid == NULL || callback == NULL) {
return NULL;
g_return_val_if_fail (iid != NULL, NULL);
g_return_val_if_fail (callback != NULL, NULL);
handle = g_new0 (NautilusBonoboActivationHandle, 1);
handle->early_completion_hook = &handle;
handle->callback = callback;
handle->callback_data = callback_data;
oaf_activate_from_id_async ((char *) iid, 0,
oaf_activation_callback,
handle, NULL);
if (handle != NULL) {
handle->early_completion_hook = 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;
return handle;
}
/**
* nautilus_bonobo_activate_from_id:
* nautilus_bonobo_activate_stop:
* @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 not be called
* after this call.
* you should free your %NautilusBonoboActivate structure through
* nautilus_bonobo_activate_free after this call.
*/
void
nautilus_bonobo_activate_stop (NautilusBonoboActivate *activate_structure)
nautilus_bonobo_activate_cancel (NautilusBonoboActivationHandle *handle)
{
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);
if (handle != NULL) {
handle->cancel = TRUE;
if (handle->early_completion_hook != NULL) {
g_assert (*handle->early_completion_hook == handle);
*handle->early_completion_hook = NULL;
}
}
}

View file

@ -30,71 +30,66 @@
#include <bonobo/bonobo-ui-component.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
void nautilus_bonobo_set_accelerator (BonoboUIComponent *ui,
const char *path,
const char *accelerator);
char * nautilus_bonobo_get_label (BonoboUIComponent *ui,
const char *path);
void nautilus_bonobo_set_label (BonoboUIComponent *ui,
const char *path,
const char *label);
void nautilus_bonobo_set_tip (BonoboUIComponent *ui,
const char *path,
const char *tip);
void nautilus_bonobo_set_sensitive (BonoboUIComponent *ui,
const char *path,
gboolean sensitive);
void nautilus_bonobo_set_toggle_state (BonoboUIComponent *ui,
const char *path,
gboolean state);
void nautilus_bonobo_set_hidden (BonoboUIComponent *ui,
const char *path,
gboolean hidden);
gboolean nautilus_bonobo_get_hidden (BonoboUIComponent *ui,
const char *path);
void nautilus_bonobo_add_numbered_menu_item (BonoboUIComponent *ui,
const char *container_path,
guint index,
const char *label,
GdkPixbuf *pixbuf);
void nautilus_bonobo_add_numbered_toggle_menu_item (BonoboUIComponent *ui,
const char *container_path,
guint index,
const char *label);
char *nautilus_bonobo_get_numbered_menu_item_command
(BonoboUIComponent *ui,
const char *container_path,
guint index);
char *nautilus_bonobo_get_numbered_menu_item_path
(BonoboUIComponent *ui,
const char *container_path,
guint index);
void nautilus_bonobo_add_submenu (BonoboUIComponent *ui,
const char *container_path,
const char *label);
void nautilus_bonobo_add_menu_separator (BonoboUIComponent *ui,
const char *path);
void nautilus_bonobo_remove_menu_items_and_commands
(BonoboUIComponent *ui,
const char *container_path);
void nautilus_bonobo_set_label_for_menu_item_and_command
(BonoboUIComponent *ui,
const char *menu_item_path,
const char *command_path,
const char *label_with_underscore);
void nautilus_bonobo_set_icon (BonoboUIComponent *ui,
const char *path,
const char *icon_relative_path);
typedef struct NautilusBonoboActivationHandle NautilusBonoboActivationHandle;
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);
typedef void (*NautilusBonoboActivationCallback) (NautilusBonoboActivationHandle *handle,
Bonobo_Unknown activated_object,
gpointer callback_data);
void nautilus_bonobo_set_accelerator (BonoboUIComponent *ui,
const char *path,
const char *accelerator);
char * nautilus_bonobo_get_label (BonoboUIComponent *ui,
const char *path);
void nautilus_bonobo_set_label (BonoboUIComponent *ui,
const char *path,
const char *label);
void nautilus_bonobo_set_tip (BonoboUIComponent *ui,
const char *path,
const char *tip);
void nautilus_bonobo_set_sensitive (BonoboUIComponent *ui,
const char *path,
gboolean sensitive);
void nautilus_bonobo_set_toggle_state (BonoboUIComponent *ui,
const char *path,
gboolean state);
void nautilus_bonobo_set_hidden (BonoboUIComponent *ui,
const char *path,
gboolean hidden);
gboolean nautilus_bonobo_get_hidden (BonoboUIComponent *ui,
const char *path);
void nautilus_bonobo_add_numbered_menu_item (BonoboUIComponent *ui,
const char *container_path,
guint index,
const char *label,
GdkPixbuf *pixbuf);
void nautilus_bonobo_add_numbered_toggle_menu_item (BonoboUIComponent *ui,
const char *container_path,
guint index,
const char *label);
char * nautilus_bonobo_get_numbered_menu_item_command (BonoboUIComponent *ui,
const char *container_path,
guint index);
char * nautilus_bonobo_get_numbered_menu_item_path (BonoboUIComponent *ui,
const char *container_path,
guint index);
void nautilus_bonobo_add_submenu (BonoboUIComponent *ui,
const char *container_path,
const char *label);
void nautilus_bonobo_add_menu_separator (BonoboUIComponent *ui,
const char *path);
void nautilus_bonobo_remove_menu_items_and_commands (BonoboUIComponent *ui,
const char *container_path);
void nautilus_bonobo_set_label_for_menu_item_and_command (BonoboUIComponent *ui,
const char *menu_item_path,
const char *command_path,
const char *label_with_underscore);
void nautilus_bonobo_set_icon (BonoboUIComponent *ui,
const char *path,
const char *icon_relative_path);
NautilusBonoboActivationHandle *nautilus_bonobo_activate_from_id (const char *iid,
NautilusBonoboActivationCallback callback,
gpointer callback_data);
void nautilus_bonobo_activate_cancel (NautilusBonoboActivationHandle *handle);
#endif /* NAUTILUS_BONOBO_EXTENSIONS_H */

View file

@ -26,13 +26,19 @@
#include <config.h>
#include "nautilus-bonobo-extensions.h"
#include "nautilus-string.h"
#include "nautilus-string.h"
#include <bonobo/bonobo-ui-util.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <liboaf/oaf-async.h>
struct NautilusBonoboActivationHandle {
NautilusBonoboActivationHandle **early_completion_hook;
NautilusBonoboActivationCallback callback;
gpointer callback_data;
gboolean cancel;
};
void
nautilus_bonobo_set_accelerator (BonoboUIComponent *ui,
const char *path,
@ -423,44 +429,33 @@ nautilus_bonobo_set_icon (BonoboUIComponent *ui,
"filename", NULL);
}
struct _NautilusBonoboActivate {
NautilusBonoboActivateCallback activation_callback;
gpointer callback_data;
gboolean stop_activation;
};
static void
oaf_activation_callback (CORBA_Object object_reference,
oaf_activation_callback (Bonobo_Unknown activated_object,
const char *error_reason,
gpointer user_data)
gpointer callback_data)
{
NautilusBonoboActivate *activate_struct;
NautilusBonoboActivationHandle *handle;
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 (CORBA_OBJECT_NIL,
activate_struct->callback_data);
handle = (NautilusBonoboActivationHandle *) 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... */
if (handle->cancel) {
CORBA_exception_init (&ev);
Bonobo_Unknown_unref (activated_object, &ev);
CORBA_exception_free (&ev);
} else {
(* handle->callback) (handle,
activated_object,
handle->callback_data);
}
CORBA_exception_free (&ev);
}
if (handle->early_completion_hook != NULL) {
g_assert (*handle->early_completion_hook == handle);
*handle->early_completion_hook = NULL;
}
g_free (handle);
}
/**
* nautilus_bonobo_activate_from_id:
@ -469,67 +464,53 @@ oaf_activation_callback (CORBA_Object object_reference,
* @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.
* activation.
*/
NautilusBonoboActivate *
nautilus_bonobo_activate_from_id (const char *iid,
NautilusBonoboActivateCallback callback,
gpointer user_data)
NautilusBonoboActivationHandle *
nautilus_bonobo_activate_from_id (const char *iid,
NautilusBonoboActivationCallback callback,
gpointer callback_data)
{
NautilusBonoboActivate *activate_structure;
CORBA_Environment ev;
NautilusBonoboActivationHandle *handle;
if (iid == NULL || callback == NULL) {
return NULL;
g_return_val_if_fail (iid != NULL, NULL);
g_return_val_if_fail (callback != NULL, NULL);
handle = g_new0 (NautilusBonoboActivationHandle, 1);
handle->early_completion_hook = &handle;
handle->callback = callback;
handle->callback_data = callback_data;
oaf_activate_from_id_async ((char *) iid, 0,
oaf_activation_callback,
handle, NULL);
if (handle != NULL) {
handle->early_completion_hook = 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;
return handle;
}
/**
* nautilus_bonobo_activate_from_id:
* nautilus_bonobo_activate_stop:
* @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 not be called
* after this call.
* you should free your %NautilusBonoboActivate structure through
* nautilus_bonobo_activate_free after this call.
*/
void
nautilus_bonobo_activate_stop (NautilusBonoboActivate *activate_structure)
nautilus_bonobo_activate_cancel (NautilusBonoboActivationHandle *handle)
{
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);
if (handle != NULL) {
handle->cancel = TRUE;
if (handle->early_completion_hook != NULL) {
g_assert (*handle->early_completion_hook == handle);
*handle->early_completion_hook = NULL;
}
}
}

View file

@ -30,71 +30,66 @@
#include <bonobo/bonobo-ui-component.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
void nautilus_bonobo_set_accelerator (BonoboUIComponent *ui,
const char *path,
const char *accelerator);
char * nautilus_bonobo_get_label (BonoboUIComponent *ui,
const char *path);
void nautilus_bonobo_set_label (BonoboUIComponent *ui,
const char *path,
const char *label);
void nautilus_bonobo_set_tip (BonoboUIComponent *ui,
const char *path,
const char *tip);
void nautilus_bonobo_set_sensitive (BonoboUIComponent *ui,
const char *path,
gboolean sensitive);
void nautilus_bonobo_set_toggle_state (BonoboUIComponent *ui,
const char *path,
gboolean state);
void nautilus_bonobo_set_hidden (BonoboUIComponent *ui,
const char *path,
gboolean hidden);
gboolean nautilus_bonobo_get_hidden (BonoboUIComponent *ui,
const char *path);
void nautilus_bonobo_add_numbered_menu_item (BonoboUIComponent *ui,
const char *container_path,
guint index,
const char *label,
GdkPixbuf *pixbuf);
void nautilus_bonobo_add_numbered_toggle_menu_item (BonoboUIComponent *ui,
const char *container_path,
guint index,
const char *label);
char *nautilus_bonobo_get_numbered_menu_item_command
(BonoboUIComponent *ui,
const char *container_path,
guint index);
char *nautilus_bonobo_get_numbered_menu_item_path
(BonoboUIComponent *ui,
const char *container_path,
guint index);
void nautilus_bonobo_add_submenu (BonoboUIComponent *ui,
const char *container_path,
const char *label);
void nautilus_bonobo_add_menu_separator (BonoboUIComponent *ui,
const char *path);
void nautilus_bonobo_remove_menu_items_and_commands
(BonoboUIComponent *ui,
const char *container_path);
void nautilus_bonobo_set_label_for_menu_item_and_command
(BonoboUIComponent *ui,
const char *menu_item_path,
const char *command_path,
const char *label_with_underscore);
void nautilus_bonobo_set_icon (BonoboUIComponent *ui,
const char *path,
const char *icon_relative_path);
typedef struct NautilusBonoboActivationHandle NautilusBonoboActivationHandle;
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);
typedef void (*NautilusBonoboActivationCallback) (NautilusBonoboActivationHandle *handle,
Bonobo_Unknown activated_object,
gpointer callback_data);
void nautilus_bonobo_set_accelerator (BonoboUIComponent *ui,
const char *path,
const char *accelerator);
char * nautilus_bonobo_get_label (BonoboUIComponent *ui,
const char *path);
void nautilus_bonobo_set_label (BonoboUIComponent *ui,
const char *path,
const char *label);
void nautilus_bonobo_set_tip (BonoboUIComponent *ui,
const char *path,
const char *tip);
void nautilus_bonobo_set_sensitive (BonoboUIComponent *ui,
const char *path,
gboolean sensitive);
void nautilus_bonobo_set_toggle_state (BonoboUIComponent *ui,
const char *path,
gboolean state);
void nautilus_bonobo_set_hidden (BonoboUIComponent *ui,
const char *path,
gboolean hidden);
gboolean nautilus_bonobo_get_hidden (BonoboUIComponent *ui,
const char *path);
void nautilus_bonobo_add_numbered_menu_item (BonoboUIComponent *ui,
const char *container_path,
guint index,
const char *label,
GdkPixbuf *pixbuf);
void nautilus_bonobo_add_numbered_toggle_menu_item (BonoboUIComponent *ui,
const char *container_path,
guint index,
const char *label);
char * nautilus_bonobo_get_numbered_menu_item_command (BonoboUIComponent *ui,
const char *container_path,
guint index);
char * nautilus_bonobo_get_numbered_menu_item_path (BonoboUIComponent *ui,
const char *container_path,
guint index);
void nautilus_bonobo_add_submenu (BonoboUIComponent *ui,
const char *container_path,
const char *label);
void nautilus_bonobo_add_menu_separator (BonoboUIComponent *ui,
const char *path);
void nautilus_bonobo_remove_menu_items_and_commands (BonoboUIComponent *ui,
const char *container_path);
void nautilus_bonobo_set_label_for_menu_item_and_command (BonoboUIComponent *ui,
const char *menu_item_path,
const char *command_path,
const char *label_with_underscore);
void nautilus_bonobo_set_icon (BonoboUIComponent *ui,
const char *path,
const char *icon_relative_path);
NautilusBonoboActivationHandle *nautilus_bonobo_activate_from_id (const char *iid,
NautilusBonoboActivationCallback callback,
gpointer callback_data);
void nautilus_bonobo_activate_cancel (NautilusBonoboActivationHandle *handle);
#endif /* NAUTILUS_BONOBO_EXTENSIONS_H */

View file

@ -4,7 +4,7 @@
* libnautilus: A library for nautilus view implementations.
*
* Copyright (C) 1999, 2000 Red Hat, Inc.
* Copyright (C) 2000 Eazel, Inc.
* Copyright (C) 2000, 2001 Eazel, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -22,6 +22,7 @@
*
* Authors: Elliot Lee <sopwith@redhat.com>
* Maciej Stachowiak <mjs@eazel.com>
* Darin Adler <darin@eazel.com>
*
*/
@ -36,7 +37,9 @@
#include <bonobo/bonobo-control.h>
#include <bonobo/bonobo-main.h>
#include <bonobo/bonobo-ui-util.h>
#include <gtk/gtkmain.h>
#include <gtk/gtksignal.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <libnautilus-extensions/nautilus-gtk-macros.h>
enum {
@ -52,6 +55,8 @@ static guint signals[LAST_SIGNAL];
struct NautilusViewDetails {
BonoboControl *control;
GList *call_queue;
guint dequeue_calls_at_idle_id;
};
typedef struct {
@ -59,6 +64,15 @@ typedef struct {
NautilusView *bonobo_object;
} impl_POA_Nautilus_View;
typedef void (* ViewFunction) (NautilusView *view,
gpointer callback_data);
typedef struct {
ViewFunction call;
gpointer callback_data;
GDestroyNotify destroy_callback_data;
} IncomingCall;
static void impl_Nautilus_View_load_location (PortableServer_Servant servant,
CORBA_char *location,
CORBA_Environment *ev);
@ -97,11 +111,92 @@ static POA_Nautilus_View__vepv impl_Nautilus_View_vepv =
&libnautilus_Nautilus_View_epv
};
/* Makes a GList but does not copy the strings.
* Free the list with g_list_free.
*/
static void
execute_queued_calls (NautilusView *view)
{
GList *queue, *node;
IncomingCall *call;
/* We could receive more incoming calls while dispatching
* these, so keep going until the call queue is empty.
*/
while (view->details->call_queue != NULL) {
queue = g_list_reverse (view->details->call_queue);
view->details->call_queue = NULL;
for (node = queue; node != NULL; node = node->next) {
call = node->data;
(* call->call) (view, call->callback_data);
if (call->destroy_callback_data != NULL) {
(* call->destroy_callback_data) (call->callback_data);
}
}
g_list_free (queue);
}
}
static gboolean
dequeue_calls_at_idle (gpointer callback_data)
{
NautilusView *view;
view = NAUTILUS_VIEW (callback_data);
execute_queued_calls (view);
view->details->dequeue_calls_at_idle_id = 0;
return FALSE;
}
static void
discard_queued_calls (NautilusView *view)
{
GList *queue, *node;
IncomingCall *call;
queue = view->details->call_queue;
view->details->call_queue = NULL;
for (node = queue; node != NULL; node = node->next) {
call = node->data;
if (call->destroy_callback_data != NULL) {
(* call->destroy_callback_data) (call->callback_data);
}
}
g_list_free (queue);
g_assert (view->details->call_queue == NULL);
}
static void
queue_incoming_call (PortableServer_Servant servant,
ViewFunction call,
gpointer callback_data,
GDestroyNotify destroy_callback_data)
{
NautilusView *view;
IncomingCall *incoming_call;
view = ((impl_POA_Nautilus_View *) servant)->bonobo_object;
incoming_call = g_new (IncomingCall, 1);
incoming_call->call = call;
incoming_call->callback_data = callback_data;
incoming_call->destroy_callback_data = destroy_callback_data;
view->details->call_queue = g_list_prepend
(view->details->call_queue, incoming_call);
if (view->details->dequeue_calls_at_idle_id == 0) {
view->details->dequeue_calls_at_idle_id = gtk_idle_add
(dequeue_calls_at_idle, view);
}
}
GList *
nautilus_shallow_g_list_from_uri_list (const Nautilus_URIList *uri_list)
nautilus_g_list_from_uri_list (const Nautilus_URIList *uri_list)
{
GList *list;
guint i;
@ -109,7 +204,7 @@ nautilus_shallow_g_list_from_uri_list (const Nautilus_URIList *uri_list)
list = NULL;
for (i = 0; i < uri_list->_length; i++) {
list = g_list_prepend
(list, uri_list->_buffer[i]);
(list, g_strdup (uri_list->_buffer[i]));
}
return g_list_reverse (list);
}
@ -140,22 +235,97 @@ nautilus_uri_list_from_g_list (GList *list)
return uri_list;
}
static void
call_load_location (NautilusView *view,
gpointer callback_data)
{
gtk_signal_emit (GTK_OBJECT (view),
signals[LOAD_LOCATION],
callback_data);
}
static void
call_stop_loading (NautilusView *view,
gpointer callback_data)
{
gtk_signal_emit (GTK_OBJECT (view),
signals[STOP_LOADING]);
}
static void
call_selection_changed (NautilusView *view,
gpointer callback_data)
{
gtk_signal_emit (GTK_OBJECT (view),
signals[SELECTION_CHANGED],
callback_data);
}
static void
call_title_changed (NautilusView *view,
gpointer callback_data)
{
gtk_signal_emit (GTK_OBJECT (view),
signals[TITLE_CHANGED],
callback_data);
}
static void
call_history_changed (NautilusView *view,
gpointer callback_data)
{
gtk_signal_emit (GTK_OBJECT (view),
signals[HISTORY_CHANGED],
callback_data);
}
static void
list_deep_free_cover (gpointer callback_data)
{
gnome_vfs_list_deep_free (callback_data);
}
static Nautilus_History *
history_dup (const Nautilus_History *history)
{
Nautilus_History *dup;
int length, i;
length = history->_length;
dup = Nautilus_History__alloc ();
dup->_maximum = length;
dup->_length = length;
dup->_buffer = CORBA_sequence_Nautilus_HistoryItem_allocbuf (length);
for (i = 0; i < length; i++) {
dup->_buffer[i].title = CORBA_string_dup (history->_buffer[i].title);
dup->_buffer[i].location = CORBA_string_dup (history->_buffer[i].location);
dup->_buffer[i].icon = CORBA_string_dup (history->_buffer[i].icon);
}
CORBA_sequence_set_release (dup, CORBA_TRUE);
return dup;
}
static void
impl_Nautilus_View_load_location (PortableServer_Servant servant,
CORBA_char *location,
CORBA_Environment *ev)
{
gtk_signal_emit (GTK_OBJECT (((impl_POA_Nautilus_View *) servant)->bonobo_object),
signals[LOAD_LOCATION],
location);
queue_incoming_call (servant,
call_load_location,
g_strdup (location),
g_free);
}
static void
impl_Nautilus_View_stop_loading (PortableServer_Servant servant,
CORBA_Environment *ev)
{
gtk_signal_emit (GTK_OBJECT (((impl_POA_Nautilus_View *) servant)->bonobo_object),
signals[STOP_LOADING]);
queue_incoming_call (servant,
call_stop_loading,
NULL,
NULL);
}
static void
@ -163,15 +333,10 @@ impl_Nautilus_View_selection_changed (PortableServer_Servant servant,
const Nautilus_URIList *selection,
CORBA_Environment *ev)
{
GList *selection_as_g_list;
selection_as_g_list = nautilus_shallow_g_list_from_uri_list (selection);
gtk_signal_emit (GTK_OBJECT (((impl_POA_Nautilus_View *) servant)->bonobo_object),
signals[SELECTION_CHANGED],
selection_as_g_list);
g_list_free (selection_as_g_list);
queue_incoming_call (servant,
call_selection_changed,
nautilus_g_list_from_uri_list (selection),
list_deep_free_cover);
}
static void
@ -179,9 +344,10 @@ impl_Nautilus_View_title_changed (PortableServer_Servant servant,
const CORBA_char *title,
CORBA_Environment *ev)
{
gtk_signal_emit (GTK_OBJECT (((impl_POA_Nautilus_View *) servant)->bonobo_object),
signals[TITLE_CHANGED],
title);
queue_incoming_call (servant,
call_title_changed,
g_strdup (title),
g_free);
}
static void
@ -189,13 +355,15 @@ impl_Nautilus_View_history_changed (PortableServer_Servant servant,
const Nautilus_History *history,
CORBA_Environment *ev)
{
gtk_signal_emit (GTK_OBJECT (((impl_POA_Nautilus_View *) servant)->bonobo_object),
signals[HISTORY_CHANGED],
history);
queue_incoming_call (servant,
call_history_changed,
history_dup (history),
CORBA_free);
}
static void
impl_Nautilus_View__destroy (BonoboObject *object, PortableServer_Servant servant)
impl_Nautilus_View__destroy (BonoboObject *object,
PortableServer_Servant servant)
{
PortableServer_ObjectId *object_id;
CORBA_Environment ev;
@ -320,7 +488,6 @@ nautilus_view_construct (NautilusView *view,
(view, bonobo_control_new (widget));
}
NautilusView *
nautilus_view_construct_from_bonobo_control (NautilusView *view,
BonoboControl *control)
@ -335,12 +502,20 @@ nautilus_view_construct_from_bonobo_control (NautilusView *view,
return view;
}
static void
nautilus_view_destroy (GtkObject *object)
{
g_free (NAUTILUS_VIEW (object)->details);
NautilusView *view;
view = NAUTILUS_VIEW (object);
discard_queued_calls (view);
if (view->details->dequeue_calls_at_idle_id != 0) {
gtk_idle_remove (view->details->dequeue_calls_at_idle_id);
}
g_free (view->details);
NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object));
}

View file

@ -91,7 +91,7 @@ void nautilus_view_set_title (NautilusV
* which is why they are public.
*/
Nautilus_URIList * nautilus_uri_list_from_g_list (GList *list);
GList * nautilus_shallow_g_list_from_uri_list (const Nautilus_URIList *uri_list);
GList * nautilus_g_list_from_uri_list (const Nautilus_URIList *uri_list);
/* Simpler API for setting up and getting the UI component. */
BonoboUIComponent *nautilus_view_set_up_ui (NautilusView *view,

View file

@ -1553,9 +1553,7 @@ nautilus_window_set_content_view_widget (NautilusWindow *window,
if (new_view != NULL) {
gtk_widget_show (GTK_WIDGET (new_view));
nautilus_view_frame_activate (new_view);
/* FIXME bugzilla.eazel.com 1243:
* We should use inheritance instead of these special cases
* for the desktop window.
@ -1577,7 +1575,6 @@ nautilus_window_set_content_view_widget (NautilusWindow *window,
gtk_widget_hide (window->zoom_control);
}
window->content_view = new_view;
}

View file

@ -125,8 +125,6 @@ struct NautilusWindow {
NautilusLocationChangeType location_change_type;
guint location_change_distance;
gboolean views_shown;
gboolean view_bombed_out;
gboolean view_activation_complete;
gboolean sent_update_view;
gboolean cv_progress_initial;

View file

@ -1553,9 +1553,7 @@ nautilus_window_set_content_view_widget (NautilusWindow *window,
if (new_view != NULL) {
gtk_widget_show (GTK_WIDGET (new_view));
nautilus_view_frame_activate (new_view);
/* FIXME bugzilla.eazel.com 1243:
* We should use inheritance instead of these special cases
* for the desktop window.
@ -1577,7 +1575,6 @@ nautilus_window_set_content_view_widget (NautilusWindow *window,
gtk_widget_hide (window->zoom_control);
}
window->content_view = new_view;
}

View file

@ -125,8 +125,6 @@ struct NautilusWindow {
NautilusLocationChangeType location_change_type;
guint location_change_distance;
gboolean views_shown;
gboolean view_bombed_out;
gboolean view_activation_complete;
gboolean sent_update_view;
gboolean cv_progress_initial;

View file

@ -1553,9 +1553,7 @@ nautilus_window_set_content_view_widget (NautilusWindow *window,
if (new_view != NULL) {
gtk_widget_show (GTK_WIDGET (new_view));
nautilus_view_frame_activate (new_view);
/* FIXME bugzilla.eazel.com 1243:
* We should use inheritance instead of these special cases
* for the desktop window.
@ -1577,7 +1575,6 @@ nautilus_window_set_content_view_widget (NautilusWindow *window,
gtk_widget_hide (window->zoom_control);
}
window->content_view = new_view;
}

View file

@ -125,8 +125,6 @@ struct NautilusWindow {
NautilusLocationChangeType location_change_type;
guint location_change_distance;
gboolean views_shown;
gboolean view_bombed_out;
gboolean view_activation_complete;
gboolean sent_update_view;
gboolean cv_progress_initial;

View file

@ -174,10 +174,10 @@ impl_Nautilus_ViewFrame_open_location_force_new_window (PortableServer_Servant s
if (view == NULL) {
return;
}
selection_as_g_list = nautilus_shallow_g_list_from_uri_list (selection);
selection_as_g_list = nautilus_g_list_from_uri_list (selection);
nautilus_view_frame_open_location_force_new_window
(view, location, selection_as_g_list);
g_list_free (selection_as_g_list);
nautilus_g_list_free_deep (selection_as_g_list);
}
static void
@ -192,10 +192,10 @@ impl_Nautilus_ViewFrame_report_selection_change (PortableServer_Servant servant,
if (view == NULL) {
return;
}
selection_as_g_list = nautilus_shallow_g_list_from_uri_list (selection);
selection_as_g_list = nautilus_g_list_from_uri_list (selection);
nautilus_view_frame_report_selection_change
(view, selection_as_g_list);
g_list_free (selection_as_g_list);
nautilus_g_list_free_deep (selection_as_g_list);
}
static void

View file

@ -34,6 +34,8 @@
#include "nautilus-component-adapter-factory.h"
#include "nautilus-signaller.h"
#include "nautilus-window.h"
#include <bonobo/bonobo-zoomable-frame.h>
#include <bonobo/bonobo-zoomable.h>
#include <gtk/gtksignal.h>
#include <libnautilus-extensions/nautilus-bonobo-extensions.h>
#include <libnautilus-extensions/nautilus-gtk-extensions.h>
@ -41,9 +43,10 @@
#include <libnautilus-extensions/nautilus-undo-manager.h>
#include <libnautilus/nautilus-view.h>
#include <bonobo/bonobo-zoomable-frame.h>
#include <bonobo/bonobo-zoomable.h>
/* FIXME bugzilla.eazel.com 2456: Is a hard-coded 12 seconds wait to
* detect that a view is gone acceptable? Can a component that is
* working still take 12 seconds to respond?
*/
/* Milliseconds */
#define ATTACH_CLIENT_TIMEOUT 12000
@ -67,7 +70,6 @@ enum {
typedef enum {
VIEW_FRAME_EMPTY,
VIEW_FRAME_ACTIVATING,
VIEW_FRAME_NO_LOCATION,
VIEW_FRAME_WAITING,
VIEW_FRAME_UNDERWAY,
@ -86,13 +88,14 @@ struct NautilusViewFrameDetails {
guint check_if_view_is_gone_timeout_id;
char *activation_iid;
NautilusBonoboActivate *activate_structure;
NautilusBonoboActivationHandle *activation_handle;
};
static void nautilus_view_frame_initialize (NautilusViewFrame *view);
static void nautilus_view_frame_destroy (GtkObject *view);
static void nautilus_view_frame_finalize (GtkObject *view);
static void nautilus_view_frame_initialize_class (NautilusViewFrameClass *klass);
static void nautilus_view_frame_map (GtkWidget *view);
static void send_history (NautilusViewFrame *view);
static guint signals[LAST_SIGNAL];
@ -105,10 +108,15 @@ static void
nautilus_view_frame_initialize_class (NautilusViewFrameClass *klass)
{
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
object_class = GTK_OBJECT_CLASS (klass);
widget_class = GTK_WIDGET_CLASS (klass);
object_class->destroy = nautilus_view_frame_destroy;
object_class->finalize = nautilus_view_frame_finalize;
widget_class->map = nautilus_view_frame_map;
signals[CHANGE_SELECTION] = gtk_signal_new
("change_selection",
@ -246,14 +254,10 @@ nautilus_view_frame_initialize (NautilusViewFrame *view)
static void
nautilus_view_frame_destroy_client (NautilusViewFrame *view)
{
CORBA_Environment ev;
if (view->iid == NULL) {
return;
}
CORBA_exception_init (&ev);
g_free (view->iid);
view->iid = NULL;
@ -271,8 +275,6 @@ nautilus_view_frame_destroy_client (NautilusViewFrame *view)
*/
view->zoomable_frame = NULL;
CORBA_exception_free (&ev);
if (view->details->ui_container->win != NULL) {
bonobo_window_deregister_dead_components (view->details->ui_container->win);
}
@ -313,52 +315,6 @@ nautilus_view_frame_finalize (GtkObject *object)
NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, finalize, (object));
}
/* 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;
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;
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;
}
g_assert_not_reached ();
}
/* stimulus: successful activated_component call */
static void
view_frame_activated (NautilusViewFrame *view)
@ -366,34 +322,11 @@ view_frame_activated (NautilusViewFrame *view)
g_assert (NAUTILUS_IS_VIEW_FRAME (view));
switch (view->details->state) {
case VIEW_FRAME_ACTIVATING:
case VIEW_FRAME_EMPTY:
view->details->state = VIEW_FRAME_NO_LOCATION;
gtk_signal_emit (GTK_OBJECT (view), signals[CLIENT_LOADED]);
send_history (view);
return;
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;
}
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;
case VIEW_FRAME_NO_LOCATION:
case VIEW_FRAME_UNDERWAY:
case VIEW_FRAME_LOADED:
@ -416,9 +349,6 @@ view_frame_wait (NautilusViewFrame *view)
case VIEW_FRAME_EMPTY:
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:
@ -443,7 +373,6 @@ 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:
@ -476,7 +405,6 @@ 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:
@ -502,7 +430,6 @@ 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:
@ -529,7 +456,6 @@ view_frame_failed (NautilusViewFrame *view)
g_assert (NAUTILUS_IS_VIEW_FRAME (view));
switch (view->details->state) {
case VIEW_FRAME_ACTIVATING:
case VIEW_FRAME_EMPTY:
case VIEW_FRAME_LOADED:
case VIEW_FRAME_NO_LOCATION:
@ -588,29 +514,35 @@ get_CORBA_object (NautilusViewFrame *view)
}
static gboolean
check_if_view_is_gone (gpointer data)
check_if_view_is_gone (gpointer callback_data)
{
NautilusViewFrame *view;
CORBA_Environment ev;
gboolean ok;
gboolean view_is_gone;
view = NAUTILUS_VIEW_FRAME (data);
view = NAUTILUS_VIEW_FRAME (callback_data);
CORBA_exception_init (&ev);
ok = TRUE;
if (CORBA_Object_non_existent (get_CORBA_object (view), &ev)) {
view->details->check_if_view_is_gone_timeout_id = 0;
bonobo_window_deregister_dead_components (view->details->ui_container->win);
view_frame_failed (view);
ok = FALSE;
view_is_gone = CORBA_Object_non_existent (get_CORBA_object (view), &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
view_is_gone = TRUE;
}
CORBA_exception_free (&ev);
return ok;
if (!view_is_gone) {
return TRUE;
}
view->details->check_if_view_is_gone_timeout_id = 0;
bonobo_window_deregister_dead_components (view->details->ui_container->win);
view_frame_failed (view);
return FALSE;
}
static void
zoom_level_changed_callback (BonoboZoomableFrame *zframe, float zoom_level, NautilusViewFrame *view)
zoom_level_changed_callback (BonoboZoomableFrame *zframe,
float zoom_level,
NautilusViewFrame *view)
{
g_return_if_fail (zframe != NULL);
g_return_if_fail (BONOBO_IS_ZOOMABLE_FRAME (zframe));
@ -621,7 +553,8 @@ zoom_level_changed_callback (BonoboZoomableFrame *zframe, float zoom_level, Naut
}
static void
zoom_parameters_changed_callback (BonoboZoomableFrame *zframe, NautilusViewFrame *view)
zoom_parameters_changed_callback (BonoboZoomableFrame *zframe,
NautilusViewFrame *view)
{
g_return_if_fail (zframe != NULL);
g_return_if_fail (BONOBO_IS_ZOOMABLE_FRAME (zframe));
@ -643,8 +576,6 @@ attach_client (NautilusViewFrame *view, BonoboObjectClient *client)
g_return_val_if_fail (NAUTILUS_IS_VIEW_FRAME (view), FALSE);
CORBA_exception_init (&ev);
/* 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.
@ -693,16 +624,19 @@ attach_client (NautilusViewFrame *view, BonoboObjectClient *client)
GTK_SIGNAL_FUNC (zoom_parameters_changed_callback), view);
bonobo_zoomable_frame_bind_to_zoomable (view->zoomable_frame, zoomable);
bonobo_object_release_unref (zoomable, &ev);
bonobo_object_release_unref (zoomable, NULL);
}
/* Start with a view frame interface. */
view->view_frame = impl_Nautilus_ViewFrame__create (view, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
/* FIXME bugzilla.eazel.com 5041: Cleanup needed here. */
CORBA_exception_free (&ev);
return FALSE;
}
CORBA_exception_free (&ev);
/* Add a control frame interface. */
control_frame = bonobo_control_frame_new (bonobo_object_corba_objref (BONOBO_OBJECT (view->details->ui_container)));
bonobo_object_add_interface (BONOBO_OBJECT (view->view_frame),
@ -724,8 +658,6 @@ attach_client (NautilusViewFrame *view, BonoboObjectClient *client)
bonobo_object_release_unref (control, NULL);
CORBA_exception_free (&ev);
view->iid = g_strdup (view->details->activation_iid);
gtk_signal_connect_while_alive
@ -743,9 +675,6 @@ attach_client (NautilusViewFrame *view, BonoboObjectClient *client)
gtk_container_add (GTK_CONTAINER (view), view->client_widget);
gtk_widget_show (view->client_widget);
/* FIXME bugzilla.eazel.com 2456:
* Is a hard-coded timeout acceptable?
*/
g_assert (view->details->check_if_view_is_gone_timeout_id == 0);
view->details->check_if_view_is_gone_timeout_id
= g_timeout_add (ATTACH_CLIENT_TIMEOUT, check_if_view_is_gone, view);
@ -754,99 +683,66 @@ attach_client (NautilusViewFrame *view, BonoboObjectClient *client)
}
static void
activation_callback (CORBA_Object object_reference, gpointer data)
activation_callback (NautilusBonoboActivationHandle *handle,
Bonobo_Unknown activated_object,
gpointer callback_data)
{
NautilusViewFrame *view;
BonoboObjectClient *bonobo_object;
view = (NautilusViewFrame *) data;
view = NAUTILUS_VIEW_FRAME (callback_data);
g_assert (view->details->activation_handle == handle);
bonobo_object = bonobo_object_client_from_corba (object_reference);
view->details->activation_handle = NULL;
bonobo_object = bonobo_object_client_from_corba (activated_object);
attach_client (view, bonobo_object);
gtk_signal_emit (GTK_OBJECT (view), signals[CLIENT_LOADED],
bonobo_object);
}
void
nautilus_view_frame_load_client_async (NautilusViewFrame *view,
const char *iid)
{
NautilusBonoboActivate *activate_structure;
if (view->details->state == VIEW_FRAME_FAILED) {
return;
}
view_frame_activating (view);
view->details->activation_iid = g_strdup (iid);
activate_structure = nautilus_bonobo_activate_from_id
view->details->activation_handle = 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 following function does quite a few calls to
* the state changing functions to simulate async activation.
*/
gboolean /* returns TRUE if successful */
void
nautilus_view_frame_load_client (NautilusViewFrame *view, const char *iid)
{
BonoboObjectClient *component;
g_return_val_if_fail (NAUTILUS_IS_VIEW_FRAME (view), FALSE);
if (view->details->state == VIEW_FRAME_FAILED) {
return 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);
if (!attach_client (view, component)) {
view_frame_not_activated (view);
return FALSE;
}
view_frame_activated (view);
return TRUE;
}
void
nautilus_view_frame_stop_activation (NautilusViewFrame *view)
{
g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view));
if (view->details->state == VIEW_FRAME_FAILED) {
return;
}
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;
g_return_if_fail (view->details->state == VIEW_FRAME_EMPTY);
if (iid == NULL) {
view_frame_failed (view);
return;
}
component = bonobo_object_activate (iid, 0);
if (component == NULL) {
view_frame_failed (view);
return;
}
view->details->activation_iid = g_strdup (iid);
if (!attach_client (view, component)) {
view_frame_failed (view);
return;
}
view_frame_activated (view);
}
void
@ -878,7 +774,7 @@ nautilus_view_frame_load_location (NautilusViewFrame *view,
}
void
nautilus_view_frame_stop_loading (NautilusViewFrame *view)
nautilus_view_frame_stop (NautilusViewFrame *view)
{
CORBA_Environment ev;
@ -1322,15 +1218,27 @@ nautilus_view_frame_set_label (NautilusViewFrame *view,
}
/* Calls activate on the underlying control frame. */
void
nautilus_view_frame_activate (NautilusViewFrame *view)
static void
nautilus_view_frame_map (GtkWidget *view_as_widget)
{
NautilusViewFrame *view;
BonoboControlFrame *control_frame;
g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (view));
if (view->details->state == VIEW_FRAME_FAILED) {
view = NAUTILUS_VIEW_FRAME (view_as_widget);
NAUTILUS_CALL_PARENT_CLASS (GTK_WIDGET_CLASS, map, (view_as_widget));
switch (view->details->state) {
case VIEW_FRAME_EMPTY:
case VIEW_FRAME_NO_LOCATION:
case VIEW_FRAME_WAITING:
g_warning ("a view frame was mapped before it was underway");
break;
case VIEW_FRAME_FAILED:
return;
case VIEW_FRAME_UNDERWAY:
case VIEW_FRAME_LOADED:
break;
}
control_frame = BONOBO_CONTROL_FRAME (bonobo_object_query_local_interface
@ -1361,7 +1269,6 @@ send_history (NautilusViewFrame *view)
switch (view->details->state) {
case VIEW_FRAME_EMPTY:
case VIEW_FRAME_ACTIVATING:
case VIEW_FRAME_FAILED:
return;
case VIEW_FRAME_NO_LOCATION:
@ -1393,7 +1300,6 @@ nautilus_view_frame_get_is_underway (NautilusViewFrame *view)
switch (view->details->state) {
case VIEW_FRAME_EMPTY:
case VIEW_FRAME_ACTIVATING:
case VIEW_FRAME_NO_LOCATION:
case VIEW_FRAME_FAILED:
case VIEW_FRAME_WAITING:

View file

@ -104,17 +104,16 @@ typedef struct {
GtkType nautilus_view_frame_get_type (void);
NautilusViewFrame * nautilus_view_frame_new (BonoboUIContainer *ui_container,
NautilusUndoManager *undo_manager);
gboolean nautilus_view_frame_load_client (NautilusViewFrame *view,
void nautilus_view_frame_load_client (NautilusViewFrame *view,
const char *iid);
void nautilus_view_frame_load_client_async (NautilusViewFrame *view,
const char *iid);
void nautilus_view_frame_stop_activation (NautilusViewFrame *view);
const char * nautilus_view_frame_get_iid (NautilusViewFrame *view);
void nautilus_view_frame_stop (NautilusViewFrame *view);
/* calls to Nautilus:View functions */
void nautilus_view_frame_load_location (NautilusViewFrame *view,
const char *location);
void nautilus_view_frame_stop_loading (NautilusViewFrame *view);
void nautilus_view_frame_selection_changed (NautilusViewFrame *view,
GList *selection);
void nautilus_view_frame_title_changed (NautilusViewFrame *view,
@ -138,8 +137,6 @@ gboolean nautilus_view_frame_is_zoomable (NautilusVie
char * nautilus_view_frame_get_label (NautilusViewFrame *view);
void nautilus_view_frame_set_label (NautilusViewFrame *view,
const char *label);
void nautilus_view_frame_activate (NautilusViewFrame *view);
/* view state */
char * nautilus_view_frame_get_title (NautilusViewFrame *view);
gboolean nautilus_view_frame_get_is_underway (NautilusViewFrame *view);

View file

@ -92,15 +92,10 @@ typedef struct {
char *label;
} ViewFrameInfo;
static void connect_view (NautilusWindow *window,
static void connect_view (NautilusWindow *window,
NautilusViewFrame *view);
static void disconnect_view (NautilusWindow *window,
static void disconnect_view (NautilusWindow *window,
NautilusViewFrame *view);
static void disconnect_view_and_destroy (NautilusWindow *window,
NautilusViewFrame *view);
static void disconnect_and_destroy_sidebar_panel (NautilusWindow *window,
NautilusViewFrame *view);
static void cancel_location_change (NautilusWindow *window);
static void
@ -586,35 +581,32 @@ static void
location_has_really_changed (NautilusWindow *window)
{
/* Switch to the new content view. */
if (window->new_content_view != NULL) {
if (GTK_WIDGET (window->new_content_view)->parent == NULL) {
/* If we don't unref the old view until idle
* time, we avoid certain kinds of problems in
* in-process components, since they won't
* lose their ViewFrame in the middle of some
* operation. This still doesn't necessarily
* help for out of process components.
*/
if (window->content_view != NULL) {
ref_now_unref_at_idle_time (GTK_OBJECT (window->content_view));
}
disconnect_view (window, window->content_view);
nautilus_window_set_content_view_widget (window, window->new_content_view);
if (GTK_WIDGET (window->new_content_view)->parent == NULL) {
/* If we don't unref the old view until idle
* time, we avoid certain kinds of problems in
* in-process components, since they won't
* lose their ViewFrame in the middle of some
* operation. This still doesn't necessarily
* help for out of process components.
*/
if (window->content_view != NULL) {
ref_now_unref_at_idle_time (GTK_OBJECT (window->content_view));
}
gtk_object_unref (GTK_OBJECT (window->new_content_view));
window->new_content_view = NULL;
/* Update displayed view in menu. Only do this if we're not switching
* locations though, because if we are switching locations we'll
* install a whole new set of views in the menu later (the current
* views in the menu are for the old location).
*/
if (window->pending_ni == NULL) {
nautilus_window_synch_view_as_menu (window);
}
}
disconnect_view (window, window->content_view);
nautilus_window_set_content_view_widget (window, window->new_content_view);
}
gtk_object_unref (GTK_OBJECT (window->new_content_view));
window->new_content_view = NULL;
/* Update displayed view in menu. Only do this if we're not switching
* locations though, because if we are switching locations we'll
* install a whole new set of views in the menu later (the current
* views in the menu are for the old location).
*/
if (window->pending_ni == NULL) {
nautilus_window_synch_view_as_menu (window);
}
/* Tell the window we are finished. */
if (window->pending_ni != NULL) {
@ -803,21 +795,10 @@ report_nascent_content_view_failure_to_user (NautilusWindow *window,
}
static void
disconnect_destroy_unref_view (NautilusWindow *window, NautilusViewFrame *view_frame)
{
g_assert (NAUTILUS_IS_WINDOW (window));
g_assert (NAUTILUS_IS_VIEW_FRAME (view_frame));
disconnect_view_and_destroy (window, view_frame);
gtk_widget_unref (GTK_WIDGET (view_frame));
}
static NautilusViewFrame *
load_content_view (NautilusWindow *window,
NautilusViewIdentifier *id)
{
const char *iid;
NautilusViewFrame *content_view;
NautilusViewFrame *new_view;
/* FIXME bugzilla.eazel.com 1243:
@ -831,7 +812,7 @@ load_content_view (NautilusWindow *window,
*/
iid = NAUTILUS_DESKTOP_ICON_VIEW_IID;
} else {
g_return_val_if_fail (id, NULL);
g_return_if_fail (id != NULL);
iid = id->iid;
}
@ -847,44 +828,33 @@ load_content_view (NautilusWindow *window,
FALSE);
bonobo_ui_component_thaw (window->details->shell_ui, NULL);
nautilus_view_identifier_free (window->content_view_id);
window->content_view_id = nautilus_view_identifier_copy (id);
content_view = window->content_view;
if (content_view == NULL
|| strcmp (nautilus_view_frame_get_iid (content_view), iid) != 0) {
if (window->content_view == NULL
|| strcmp (nautilus_view_frame_get_iid (window->content_view), iid) != 0) {
new_view = nautilus_view_frame_new (window->details->ui_container,
window->application->undo_manager);
window->new_content_view = new_view;
gtk_object_ref (GTK_OBJECT (new_view));
gtk_object_sink (GTK_OBJECT (new_view));
set_view_frame_info (new_view, FALSE, id->name);
connect_view (window, new_view);
if (!nautilus_view_frame_load_client (new_view, iid)) {
/* FIXME bugzilla.eazel.com 5039: We need a way to report the specific
error that happens in this case - adapter
factory not found, component failed to
load, etc. */
report_nascent_content_view_failure_to_user (window, new_view);
disconnect_destroy_unref_view (window, new_view);
new_view = NULL;
}
/* Avoid being fooled by extra done notifications from the last view.
This is a HACK because the state machine SUCKS. */
window->cv_progress_done = FALSE;
window->cv_progress_error = FALSE;
nautilus_view_frame_load_client (new_view, iid);
} else {
gtk_object_ref (GTK_OBJECT (window->content_view));
new_view = window->content_view;
window->new_content_view = new_view;
gtk_object_ref (GTK_OBJECT (new_view));
window->view_activation_complete = TRUE;
}
if (new_view != NULL) {
nautilus_view_identifier_free (window->content_view_id);
window->content_view_id = nautilus_view_identifier_copy (id);
}
return new_view;
}
@ -914,11 +884,20 @@ report_sidebar_panel_failure_to_user (NautilusWindow *window, NautilusViewFrame
g_free (message);
}
static void
disconnect_and_destroy_sidebar_panel (NautilusWindow *window, NautilusViewFrame *view)
{
disconnect_view (window, view);
nautilus_window_remove_sidebar_panel (window, view);
gtk_widget_destroy (GTK_WIDGET (view));
}
static void
handle_view_failure (NautilusWindow *window,
NautilusViewFrame *view)
{
const char* current_iid;
const char *current_iid;
if (view_frame_is_sidebar_panel (view)) {
report_sidebar_panel_failure_to_user (window, view);
current_iid = nautilus_view_frame_get_iid (view);
@ -930,14 +909,25 @@ handle_view_failure (NautilusWindow *window,
gtk_container_remove (GTK_CONTAINER (GTK_WIDGET (window->content_view)->parent),
GTK_WIDGET (window->content_view));
}
/* FIXME bugzilla.eazel.com 5039: We need a
* way to report the specific error that
* happens in this case - adapter factory not
* found, component failed to load, etc.
*/
report_current_content_view_failure_to_user (window, view);
window->content_view = NULL;
window->cv_progress_error = TRUE;
} else {
window->reset_to_idle = TRUE;
window->cv_progress_error = TRUE;
/* FIXME bugzilla.eazel.com 5039: We need a
* way to report the specific error that
* happens in this case - adapter factory not
* found, component failed to load, etc.
*/
report_nascent_content_view_failure_to_user (window, view);
}
window->cv_progress_error = TRUE;
}
}
@ -956,7 +946,8 @@ free_location_change (NautilusWindow *window)
if (window->new_content_view != NULL) {
if (window->new_content_view != window->content_view) {
disconnect_view_and_destroy (window, window->new_content_view);
disconnect_view (window, window->new_content_view);
gtk_widget_destroy (GTK_WIDGET (window->new_content_view));
}
gtk_object_unref (GTK_OBJECT (window->new_content_view));
window->new_content_view = NULL;
@ -990,8 +981,6 @@ cancel_location_change (NautilusWindow *window)
free_location_change (window);
window->views_shown = FALSE;
window->view_bombed_out = FALSE;
window->view_activation_complete = FALSE;
window->cv_progress_initial = FALSE;
window->cv_progress_done = FALSE;
@ -1001,12 +990,12 @@ cancel_location_change (NautilusWindow *window)
}
static void
load_view_for_new_location (NautilusWindow *window)
load_content_view_for_new_location (NautilusWindow *window)
{
NautilusViewIdentifier *content_id;
content_id = nautilus_navigation_info_get_initial_content_id (window->pending_ni);
window->new_content_view = load_content_view (window, content_id);
load_content_view (window, content_id);
nautilus_view_identifier_free (content_id);
}
@ -1044,154 +1033,69 @@ set_view_location_and_selection (NautilusWindow *window)
g_free (location);
}
static gboolean
update_state (gpointer data)
static void
update_state (NautilusWindow *window)
{
NautilusWindow *window;
GList *p;
GList *node;
gboolean made_changes;
window = data;
if (window->making_changes) {
return FALSE;
return;
}
made_changes = FALSE;
window->making_changes++;
/* Now make any needed state changes based on available information */
do {
made_changes = FALSE;
if (window->view_bombed_out) {
window->view_bombed_out = FALSE;
for (p = window->error_views; p != NULL; p = p->next) {
handle_view_failure (window, NAUTILUS_VIEW_FRAME (p->data));
gtk_widget_unref (GTK_WIDGET (p->data));
/* Now make any needed state changes based on available information */
if (window->error_views != NULL) {
for (node = window->error_views; node != NULL; node = node->next) {
handle_view_failure (window, NAUTILUS_VIEW_FRAME (node->data));
gtk_widget_unref (GTK_WIDGET (node->data));
}
g_list_free (window->error_views);
window->error_views = NULL;
made_changes = TRUE;
}
g_list_free (window->error_views);
window->error_views = NULL;
made_changes = TRUE;
}
if (window->reset_to_idle) {
window->reset_to_idle = FALSE;
cancel_location_change (window);
made_changes = TRUE;
}
if (window->pending_ni != NULL
&& window->new_content_view == NULL
&& !window->cv_progress_error
&& !window->view_activation_complete) {
if (window->reset_to_idle) {
window->reset_to_idle = FALSE;
cancel_location_change (window);
made_changes = TRUE;
}
load_view_for_new_location (window);
if (window->pending_ni != NULL
&& window->new_content_view == NULL
&& !window->cv_progress_error) {
load_content_view_for_new_location (window);
made_changes = TRUE;
}
window->view_activation_complete = TRUE;
made_changes = TRUE;
}
if (window->view_activation_complete
&& !window->sent_update_view) {
if (window->view_activation_complete
&& !window->sent_update_view) {
set_view_location_and_selection (window);
window->sent_update_view = TRUE;
made_changes = TRUE;
}
set_view_location_and_selection (window);
if (!window->cv_progress_error
&& window->view_activation_complete
&& window->cv_progress_initial
&& window->new_content_view != NULL) {
location_has_really_changed (window);
made_changes = TRUE;
}
window->sent_update_view = TRUE;
made_changes = TRUE;
}
if (!window->cv_progress_error
&& window->view_activation_complete
&& window->cv_progress_initial
&& !window->views_shown) {
location_has_really_changed (window);
window->views_shown = TRUE;
made_changes = TRUE;
}
if (window->cv_progress_error
|| window->cv_progress_done) {
made_changes = TRUE;
window->reset_to_idle = TRUE;
}
if (window->cv_progress_error
|| window->cv_progress_done) {
window->reset_to_idle = TRUE;
made_changes = TRUE;
}
} while (made_changes);
window->making_changes--;
return made_changes;
}
typedef enum {
INITIAL_VIEW_SELECTED,
LOAD_DONE,
LOAD_UNDERWAY,
NEW_CONTENT_VIEW_READY,
STOP,
VIEW_FAILED,
} Stimulus;
static void
change_state (NautilusWindow *window,
Stimulus stimulus,
NautilusNavigationInfo *info,
NautilusViewFrame *new_view)
{
/* Ensure that changes happen in-order */
while (update_state (window)) { }
switch (stimulus) {
case INITIAL_VIEW_SELECTED: /* The information needed for a location change to continue has been received */
window->pending_ni = info;
window->cancel_tag = NULL;
break;
case VIEW_FAILED:
g_warning ("A view failed. The UI will handle this with a dialog but this should be debugged.");
window->view_bombed_out = TRUE;
gtk_object_ref (GTK_OBJECT (new_view));
window->error_views = g_list_prepend (window->error_views, new_view);
break;
case NEW_CONTENT_VIEW_READY:
g_return_if_fail (window->new_content_view == NULL);
/* Don't ref here, reference is held by widget hierarchy. */
window->new_content_view = new_view;
/* We only come here in cases where the location does not change,
* so the sidebar panels don't change either.
*/
if (window->pending_ni == NULL) {
window->view_activation_complete = TRUE;
}
window->views_shown = FALSE;
break;
case LOAD_UNDERWAY: /* We have received an "I am loading" indication from the content view */
nautilus_window_allow_stop (window, TRUE); /* for the case where we are "re-underway" */
window->cv_progress_initial = TRUE;
window->cv_progress_done = FALSE;
break;
case LOAD_DONE: /* The content view is done loading */
window->cv_progress_initial = TRUE;
window->cv_progress_done = TRUE;
break;
case STOP: /* Someone pressed the stop button or something */
window->reset_to_idle = TRUE;
break;
default:
g_assert_not_reached ();
break;
}
while (update_state (window)) { }
}
static void
@ -1259,9 +1163,6 @@ nautilus_window_end_location_change_callback (NautilusNavigationResult result_co
window->location_change_end_reached = TRUE;
if (result_code == NAUTILUS_NAVIGATION_RESULT_OK) {
/* Navigation successful. */
window->cancel_tag = navigation_info;
/* If the window is not yet showing (as is the case for nascent
* windows), position and show it only after we've got the
* metadata (since position info is stored there).
@ -1279,8 +1180,12 @@ nautilus_window_end_location_change_callback (NautilusNavigationResult result_co
g_free (location);
}
change_state (window, INITIAL_VIEW_SELECTED, navigation_info, NULL);
window->cancel_tag = navigation_info;
update_state (window);
window->pending_ni = navigation_info;
window->cancel_tag = NULL;
update_state (window);
return;
}
@ -1468,7 +1373,9 @@ nautilus_window_begin_location_change (NautilusWindow *window,
|| type == NAUTILUS_LOCATION_CHANGE_FORWARD
|| distance == 0);
change_state (window, STOP, NULL, NULL);
update_state (window);
window->reset_to_idle = TRUE;
update_state (window);
window->location_change_type = type;
window->location_change_distance = distance;
@ -1501,7 +1408,7 @@ static void
stop_loading (NautilusViewFrame *view)
{
if (view != NULL) {
nautilus_view_frame_stop_loading (view);
nautilus_view_frame_stop (view);
}
}
@ -1515,22 +1422,27 @@ stop_loading_cover (gpointer data, gpointer callback_data)
void
nautilus_window_stop_loading (NautilusWindow *window)
{
update_state (window);
stop_loading (window->content_view);
stop_loading (window->new_content_view);
g_list_foreach (window->sidebar_panels, stop_loading_cover, NULL);
change_state (window, STOP, NULL, NULL);
window->reset_to_idle = TRUE;
update_state (window);
}
void
nautilus_window_set_content_view (NautilusWindow *window, NautilusViewIdentifier *id)
nautilus_window_set_content_view (NautilusWindow *window,
NautilusViewIdentifier *id)
{
NautilusFile *file;
NautilusViewFrame *view;
g_return_if_fail (NAUTILUS_IS_WINDOW (window));
g_return_if_fail (window->location != NULL);
g_return_if_fail (window->new_content_view == NULL);
g_return_if_fail (id != NULL);
update_state (window);
file = nautilus_file_get (window->location);
nautilus_mime_set_default_component_for_file
(file, id->iid);
@ -1538,8 +1450,9 @@ nautilus_window_set_content_view (NautilusWindow *window, NautilusViewIdentifier
nautilus_window_allow_stop (window, TRUE);
view = load_content_view (window, id);
change_state (window, NEW_CONTENT_VIEW_READY, NULL, view);
load_content_view (window, id);
update_state (window);
}
static int
@ -1559,7 +1472,6 @@ nautilus_window_set_sidebar_panels (NautilusWindow *window,
NautilusViewFrame *sidebar_panel;
NautilusViewIdentifier *identifier;
const char *current_iid;
gboolean load_succeeded;
g_return_if_fail (NAUTILUS_IS_WINDOW (window));
@ -1608,14 +1520,7 @@ nautilus_window_set_sidebar_panels (NautilusWindow *window,
nautilus_view_frame_set_label (sidebar_panel, identifier->name);
set_view_frame_info (sidebar_panel, TRUE, identifier->name);
connect_view (window, sidebar_panel);
load_succeeded = nautilus_view_frame_load_client (sidebar_panel, identifier->iid);
/* If the load failed, tell the user. */
if (!load_succeeded) {
report_sidebar_panel_failure_to_user (window, sidebar_panel);
disconnect_destroy_unref_view (window, sidebar_panel);
continue;
}
nautilus_view_frame_load_client (sidebar_panel, identifier->iid);
/* tell panel about the location and selection, if we have them */
if (window->location != NULL) {
@ -1784,13 +1689,28 @@ change_status_callback (NautilusViewFrame *view,
nautilus_window_set_status (window, status);
}
static void
client_loaded_callback (NautilusViewFrame *view,
NautilusWindow *window)
{
g_assert (NAUTILUS_IS_WINDOW (window));
if (view == window->new_content_view) {
window->view_activation_complete = TRUE;
}
update_state (window);
}
static void
failed_callback (NautilusViewFrame *view,
NautilusWindow *window)
{
g_assert (NAUTILUS_IS_WINDOW (window));
change_state (window, VIEW_FAILED, NULL, view);
g_warning ("A view failed. The UI will handle this with a dialog but this should be debugged.");
gtk_object_ref (GTK_OBJECT (view));
window->error_views = g_list_prepend (window->error_views, view);
update_state (window);
}
static void
@ -1810,7 +1730,11 @@ load_underway_callback (NautilusViewFrame *view,
if (view == window->new_content_view
|| view == window->content_view) {
change_state (window, LOAD_UNDERWAY, NULL, NULL);
update_state (window);
nautilus_window_allow_stop (window, TRUE); /* for the case where we are "re-underway" */
window->cv_progress_initial = TRUE;
window->cv_progress_done = FALSE;
update_state (window);
}
}
@ -1820,14 +1744,21 @@ load_complete_callback (NautilusViewFrame *view,
{
g_assert (NAUTILUS_IS_WINDOW (window));
/* We intentionally ignore progress from sidebar panels. Some
sidebar panels may get their own progress indicators
later. */
/* FIXME bugzilla.eazel.com 2460: We intentionally ignore
* progress from sidebar panels. Some sidebar panels may get
* their own progress indicators later.
*/
/* FIXME bugzilla.eazel.com 2461: Is progress from either old
* or new really equally interesting?
*/
/* FIXME bugzilla.eazel.com 2461: Is progress from either old or new really equally interesting? */
if (view == window->new_content_view
|| view == window->content_view) {
change_state (window, LOAD_DONE, NULL, NULL);
update_state (window);
g_assert (window->cv_progress_initial);
window->cv_progress_done = TRUE;
update_state (window);
}
}
@ -1890,6 +1821,7 @@ title_changed_callback (NautilusViewFrame *view,
#define FOR_EACH_NAUTILUS_WINDOW_SIGNAL(macro) \
macro (change_selection) \
macro (change_status) \
macro (client_loaded) \
macro (failed) \
macro (get_history_list) \
macro (load_complete) \
@ -1937,21 +1869,6 @@ disconnect_view (NautilusWindow *window, NautilusViewFrame *view)
#undef DISCONNECT
}
static void
disconnect_and_destroy_sidebar_panel (NautilusWindow *window, NautilusViewFrame *view)
{
disconnect_view (window, view);
nautilus_window_remove_sidebar_panel (window, view);
gtk_widget_destroy (GTK_WIDGET (view));
}
static void
disconnect_view_and_destroy (NautilusWindow *window, NautilusViewFrame *view)
{
disconnect_view (window, view);
gtk_widget_destroy (GTK_WIDGET (view));
}
static void
disconnect_view_callback (gpointer list_item_data, gpointer callback_data)
{

View file

@ -1553,9 +1553,7 @@ nautilus_window_set_content_view_widget (NautilusWindow *window,
if (new_view != NULL) {
gtk_widget_show (GTK_WIDGET (new_view));
nautilus_view_frame_activate (new_view);
/* FIXME bugzilla.eazel.com 1243:
* We should use inheritance instead of these special cases
* for the desktop window.
@ -1577,7 +1575,6 @@ nautilus_window_set_content_view_widget (NautilusWindow *window,
gtk_widget_hide (window->zoom_control);
}
window->content_view = new_view;
}

View file

@ -125,8 +125,6 @@ struct NautilusWindow {
NautilusLocationChangeType location_change_type;
guint location_change_distance;
gboolean views_shown;
gboolean view_bombed_out;
gboolean view_activation_complete;
gboolean sent_update_view;
gboolean cv_progress_initial;

View file

@ -19,6 +19,7 @@
Author: Mathieu Lacage <mathieu@eazel.com>
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@ -31,36 +32,33 @@
#define IID "OAFIID:bonobo_calculator:fab8c2a7-9576-437c-aa3a-a8617408970f"
static void
activation_callback (CORBA_Object object_reference, gpointer data)
static void
activation_callback (NautilusBonoboActivationHandle *handle,
Bonobo_Unknown activated_object,
gpointer callback_data)
{
GtkWidget *window;
GtkWidget *control;
CORBA_Environment exc;
window = GTK_WIDGET (data);
window = GTK_WIDGET (callback_data);
if (CORBA_Object_is_nil (object_reference, &exc)) {
/* no activation */
if (activated_object == CORBA_OBJECT_NIL) {
g_print ("activation failed\n");
gtk_main_quit ();
} else {
control = bonobo_widget_new_control_from_objref (activated_object,
CORBA_OBJECT_NIL);
gtk_container_add (GTK_CONTAINER (window), control);
gtk_widget_show (GTK_WIDGET (control));
g_print ("activation suceeded\n");
}
control = bonobo_widget_new_control_from_objref (object_reference, CORBA_OBJECT_NIL);
gtk_container_add (GTK_CONTAINER (window), control);
gtk_widget_show (GTK_WIDGET (control));
g_print ("activation suceeded\n");
}
int main (int argc, char *argv[])
int
main (int argc, char *argv[])
{
NautilusBonoboActivate *activate;
GtkWidget *window;
NautilusBonoboActivationHandle *handle;
gtk_init (&argc, &argv);
oaf_init (argc, argv);
@ -72,15 +70,13 @@ int main (int argc, char *argv[])
gtk_signal_connect (GTK_OBJECT (window), "destroy",
gtk_main_quit, NULL);
gtk_widget_show_all (GTK_WIDGET (window));
activate = nautilus_bonobo_activate_from_id (IID, activation_callback, window);
handle = nautilus_bonobo_activate_from_id (IID, activation_callback, window);
#if 0
nautilus_bonobo_activate_stop (activate);
nautilus_bonobo_activate_stop (handle);
#endif
bonobo_main ();
return 0;
}

View file

@ -0,0 +1,2 @@
Makefile
Makefile.in