nautilus/libnautilus/nautilus-view.c
Darin Adler f683ed7935 reviewed by: Pavel Cisler <pavel@eazel.com>
Fix bug 5235 ("Forget History" eliminates history from Go menu,
	not History sidebar panel).

	* components/history/nautilus-history-view.c:
	(install_icons): Fix leak of pixmap and bitmap.
	(update_history): Replaced dual lock system with a single one.
	(button_press_callback): Only respect button 1, ignore others.
	(button_release_callback): Only respect button 1, ignore others,
	(history_changed_callback): A new single callback for when the
	history list changes to replace the multiple callbacks before.
	(nautilus_history_view_initialize_class),
	(nautilus_history_view_initialize),
	(nautilus_history_view_destroy), (main): Change the history view
	to use nautilus_view_standard_main which requires a subclass. This
	gets rid of a lot of boilerplate code.

	* libnautilus/nautilus-view-component.idl: Make every NautilusView
	get an explicit history_changed call instead of requiring them to
	guess when to get history. Removed the old get_history_list call
	and also renamed the HistoryList sequence to History.
	* libnautilus/nautilus-view.h:
	* libnautilus/nautilus-view.c:
	(impl_Nautilus_View_history_changed),
	(nautilus_view_initialize_class): Added the necessary stuff to
	cover the new history_changed call.

	* src/nautilus-view-frame.h:
	* src/nautilus-view-frame.c: (nautilus_view_frame_initialize):
	Connect handlers so we can send history_changed calls to the
	NautilusView when either the history or the icons change.
	(nautilus_view_frame_destroy): Change state to EMPTY so the
	history signal won't be sent once the frame is destroyed.
	(view_frame_activated): Send a history_changed to every
	newly-activated view.
	(get_CORBA_object): Helper function to make code that makes CORBA
	calls simpler.
	(check_if_view_is_gone): Use get_CORBA_object.
	(attach_client): Gave a nicer name, removed the code that makes
	the Nautilus_HistoryFrame interface.
	(nautilus_view_frame_load_client): Do the attach_client (formerly
	nautilus_view_frame_set_to_component) before calling
	view_frame_activated. This is needed since view_frame_activated
	now sends a history_changed to the view.
	(nautilus_view_frame_load_location),
	(nautilus_view_frame_stop_loading),
	(nautilus_view_frame_selection_changed),
	(nautilus_view_frame_title_changed): Use get_CORBA_object.
	(get_history_list): Made this private.
	(send_history): Helper function that sends history to the view if
	it's in the appropriate state.

	* src/Makefile.am:
	* src/nautilus-history-frame.c:
	* src/nautilus-history-frame.h:
	Removed the old NautilusHistoryFrame, which is no longer needed
	since we put the history call right in the NautilusView class.

	* src/nautilus-window-manage-views.c: (get_history_list_callback):
	Updated for Nautilus_HistoryList -> Nautilus_History change.

	Fix bug 5391 ("Esc" Canceling of an icon stretch doesn't restore
	icon position.).

	* libnautilus-extensions/nautilus-icon-private.h:
	* libnautilus-extensions/nautilus-icon-container.c:
	(clear_drag_state): Add a single bottleneck function to make sure
	the context menu timeout always gets canceled.
	(continue_stretching): Remove the unused "update_position" parameter.
	(undo_stretching): Consolidate the cancel_stretching function and
	restore the icon's position as well as its size. Also use the new
	bottleneck to clear the drag state.
	(button_release_event): Use the new bottleneck to clear the drag
	state.
	(show_context_menu_callback): Use the new bottleneck to clear the
	drag state.
	(nautilus_icon_container_set_selection),
	(nautilus_icon_container_select_list_unselect_others): Take
	advantage of the defaults in g_hash_table_new and use NULL, NULL
	instead of g_direct_hash, g_direct_equal.
	(nautilus_icon_container_show_stretch_handles): Save the position
	as well as the size.
	(compute_stretch): Add a FIXME with a bug number.

	Fix bug 5407 (Make "Hardware Overview" title translatable).

	* components/hardware/nautilus-hardware-view.c:
	(nautilus_hardware_view_destroy): Remove unused uri field.
	(extract_info): Fix storage leak.
	(get_RAM_description): Get rid of code that non-portably relies on
	long long. Mark strings for translation.
	(get_IDE_description): Get rid of code that non-portably relies on
	long long. Mark strings for translation.
	(setup_overview_form): Marked string for translation.
	(setup_CPU_form), (setup_RAM_form), (setup_IDE_form),
	(is_location), (nautilus_hardware_view_load_uri): Disable the
	views other than the overview for now since they are not ready to
	be seen.
	(nautilus_hardware_view_drag_data_received): Get rid of the code
	that makes the hardware view accept a URI list drag.

	Fix bug 5405 (nautilus --check fails when using LC_ALL=sv_SE due
	to missing entry in POTFILES.in).

	* po/POTFILES.in: Added nautilus-glib-extensions.c.

	Other changes.

	* src/nautilus-signaller.h:
	* src/nautilus-signaller.c: (nautilus_signaller_initialize_class),
	(nautilus_signaller_get_current):
	Change the NautilusSignaller class so that the interface calls the
	object a GtkObject * and the details of the class are hidden.

	* src/nautilus-property-browser.c: (emit_emblems_changed_signal):
	* src/nautilus-search-bar-criterion.c:
	(nautilus_search_bar_criterion_destroy),
	(nautilus_search_bar_criterion_new_from_values):
	* src/nautilus-window-menus.c:
	(nautilus_window_initialize_go_menu):
	* src/nautilus-window.c: (nautilus_send_history_list_changed):
	Now that nautilus_signaller_get_current returns a GtkObject,
	remove some unnecessary casts.

	* components/html/glibwww-callbacks.c: (get_sock_info),
	(glibwww_timer_register):
	* components/tree/nautilus-tree-model.c:
	(nautilus_tree_model_initialize):
	* components/tree/nautilus-tree-view.c:
	(nautilus_tree_view_initialize):
	* libnautilus-extensions/nautilus-directory-async.c:
	(async_job_start):
	* libnautilus-extensions/nautilus-directory.c:
	(nautilus_directory_notify_files_added),
	(nautilus_directory_notify_files_removed),
	(nautilus_directory_notify_files_moved):
	* libnautilus-extensions/nautilus-icon-factory.c:
	(nautilus_icon_factory_initialize):
	* libnautilus-extensions/nautilus-list.c:
	(nautilus_list_set_selection):
	* libnautilus-extensions/nautilus-merged-directory.c:
	(nautilus_merged_directory_initialize):
	* libnautilus-extensions/nautilus-trash-directory.c:
	(nautilus_trash_directory_initialize):
	* src/file-manager/fm-properties-window.c:
	(fm_properties_window_present):
	Take advantage of the defaults in g_hash_table_new and use NULL,
	NULL instead of g_direct_hash, g_direct_equal.
2001-01-04 02:15:56 +00:00

555 lines
15 KiB
C

/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* libnautilus: A library for nautilus view implementations.
*
* Copyright (C) 1999, 2000 Red Hat, Inc.
* Copyright (C) 2000 Eazel, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Authors: Elliot Lee <sopwith@redhat.com>
* Maciej Stachowiak <mjs@eazel.com>
*
*/
/* nautilus-view.c: Implementation for object that represents a
nautilus view implementation. */
#include <config.h>
#include "nautilus-view.h"
#include "nautilus-bonobo-workarounds.h"
#include "nautilus-undo.h"
#include <bonobo/bonobo-control.h>
#include <bonobo/bonobo-main.h>
#include <bonobo/bonobo-ui-util.h>
#include <gtk/gtksignal.h>
#include <libnautilus-extensions/nautilus-gtk-macros.h>
enum {
HISTORY_CHANGED,
LOAD_LOCATION,
SELECTION_CHANGED,
STOP_LOADING,
TITLE_CHANGED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL];
struct NautilusViewDetails {
BonoboControl *control;
};
typedef struct {
POA_Nautilus_View servant;
NautilusView *bonobo_object;
} impl_POA_Nautilus_View;
static void impl_Nautilus_View_load_location (PortableServer_Servant servant,
CORBA_char *location,
CORBA_Environment *ev);
static void impl_Nautilus_View_stop_loading (PortableServer_Servant servant,
CORBA_Environment *ev);
static void impl_Nautilus_View_selection_changed (PortableServer_Servant servant,
const Nautilus_URIList *selection,
CORBA_Environment *ev);
static void impl_Nautilus_View_title_changed (PortableServer_Servant servant,
const CORBA_char *title,
CORBA_Environment *ev);
static void impl_Nautilus_View_history_changed (PortableServer_Servant servant,
const Nautilus_History *history,
CORBA_Environment *ev);
static void nautilus_view_initialize (NautilusView *view);
static void nautilus_view_destroy (GtkObject *object);
static void nautilus_view_initialize_class (NautilusViewClass *klass);
NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusView, nautilus_view, BONOBO_OBJECT_TYPE)
static POA_Nautilus_View__epv libnautilus_Nautilus_View_epv =
{
NULL,
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
};
static PortableServer_ServantBase__epv base_epv;
static POA_Nautilus_View__vepv impl_Nautilus_View_vepv =
{
&base_epv,
NULL,
&libnautilus_Nautilus_View_epv
};
/* Makes a GList but does not copy the strings.
* Free the list with g_list_free.
*/
GList *
nautilus_shallow_g_list_from_uri_list (const Nautilus_URIList *uri_list)
{
GList *list;
guint i;
list = NULL;
for (i = 0; i < uri_list->_length; i++) {
list = g_list_prepend
(list, uri_list->_buffer[i]);
}
return g_list_reverse (list);
}
/* Must CORBA_free this list before destroying the URI's in
* the source list.
*/
Nautilus_URIList *
nautilus_uri_list_from_g_list (GList *list)
{
int length;
Nautilus_URIList *uri_list;
int i;
GList *p;
length = g_list_length (list);
uri_list = Nautilus_URIList__alloc ();
uri_list->_maximum = length;
uri_list->_length = length;
uri_list->_buffer = CORBA_sequence_Nautilus_URI_allocbuf (length);
for (i = 0, p = list; i < length; i++, p = p->next) {
g_assert (p != NULL);
uri_list->_buffer[i] = CORBA_string_dup (p->data);
}
CORBA_sequence_set_release (uri_list, CORBA_TRUE);
return uri_list;
}
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);
}
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]);
}
static void
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);
}
static void
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);
}
static void
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);
}
static void
impl_Nautilus_View__destroy (BonoboObject *object, PortableServer_Servant servant)
{
PortableServer_ObjectId *object_id;
CORBA_Environment ev;
CORBA_exception_init (&ev);
object_id = PortableServer_POA_servant_to_id (bonobo_poa (), servant, &ev);
PortableServer_POA_deactivate_object (bonobo_poa (), object_id, &ev);
CORBA_free (object_id);
object->servant = NULL;
POA_Nautilus_View__fini (servant, &ev);
g_free (servant);
CORBA_exception_free (&ev);
}
static Nautilus_ViewFrame
impl_Nautilus_View__create (NautilusView *bonobo_object,
CORBA_Environment * ev)
{
impl_POA_Nautilus_View *servant;
impl_Nautilus_View_vepv.Bonobo_Unknown_epv = nautilus_bonobo_object_get_epv ();
servant = g_new0 (impl_POA_Nautilus_View, 1);
servant->servant.vepv = &impl_Nautilus_View_vepv;
POA_Nautilus_View__init ((PortableServer_Servant) servant, ev);
gtk_signal_connect (GTK_OBJECT (bonobo_object), "destroy",
GTK_SIGNAL_FUNC (impl_Nautilus_View__destroy), servant);
servant->bonobo_object = bonobo_object;
return bonobo_object_activate_servant (BONOBO_OBJECT (bonobo_object), servant);
}
static void
nautilus_view_initialize_class (NautilusViewClass *klass)
{
GtkObjectClass *object_class;
object_class = (GtkObjectClass*) klass;
object_class->destroy = nautilus_view_destroy;
signals[LOAD_LOCATION] =
gtk_signal_new ("load_location",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (NautilusViewClass, load_location),
gtk_marshal_NONE__STRING,
GTK_TYPE_NONE, 1, GTK_TYPE_STRING);
signals[STOP_LOADING] =
gtk_signal_new ("stop_loading",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (NautilusViewClass, stop_loading),
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
signals[SELECTION_CHANGED] =
gtk_signal_new ("selection_changed",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (NautilusViewClass, selection_changed),
gtk_marshal_NONE__POINTER,
GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
signals[TITLE_CHANGED] =
gtk_signal_new ("title_changed",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (NautilusViewClass, title_changed),
gtk_marshal_NONE__STRING,
GTK_TYPE_NONE, 1, GTK_TYPE_STRING);
signals[HISTORY_CHANGED] =
gtk_signal_new ("history_changed",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (NautilusViewClass, history_changed),
gtk_marshal_NONE__POINTER,
GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
}
static void
nautilus_view_initialize (NautilusView *view)
{
CORBA_Environment ev;
CORBA_exception_init (&ev);
view->details = g_new0 (NautilusViewDetails, 1);
bonobo_object_construct
(BONOBO_OBJECT (view),
impl_Nautilus_View__create (view, &ev));
CORBA_exception_free (&ev);
}
NautilusView *
nautilus_view_new (GtkWidget *widget)
{
return nautilus_view_new_from_bonobo_control
(bonobo_control_new (widget));
}
NautilusView *
nautilus_view_new_from_bonobo_control (BonoboControl *control)
{
return nautilus_view_construct_from_bonobo_control
(NAUTILUS_VIEW (gtk_object_new (NAUTILUS_TYPE_VIEW, NULL)),
control);
}
NautilusView *
nautilus_view_construct (NautilusView *view,
GtkWidget *widget)
{
return nautilus_view_construct_from_bonobo_control
(view, bonobo_control_new (widget));
}
NautilusView *
nautilus_view_construct_from_bonobo_control (NautilusView *view,
BonoboControl *control)
{
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
g_return_val_if_fail (BONOBO_IS_CONTROL (control), NULL);
view->details->control = control;
bonobo_object_add_interface (BONOBO_OBJECT (view), BONOBO_OBJECT (control));
nautilus_undo_set_up_bonobo_control (control);
return view;
}
static void
nautilus_view_destroy (GtkObject *object)
{
g_free (NAUTILUS_VIEW (object)->details);
NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object));
}
static Nautilus_ViewFrame
view_frame_call_begin (NautilusView *view, CORBA_Environment *ev)
{
Nautilus_ViewFrame view_frame;
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), CORBA_OBJECT_NIL);
CORBA_exception_init (ev);
view_frame = Bonobo_Unknown_queryInterface
(bonobo_control_get_control_frame (nautilus_view_get_bonobo_control (view)),
"IDL:Nautilus/ViewFrame:1.0", ev);
if (ev->_major != CORBA_NO_EXCEPTION) {
view_frame = CORBA_OBJECT_NIL;
}
return view_frame;
}
static void
view_frame_call_end (Nautilus_ViewFrame frame, CORBA_Environment *ev)
{
if (frame != CORBA_OBJECT_NIL) {
bonobo_object_release_unref (frame, ev);
}
CORBA_exception_free (ev);
}
void
nautilus_view_open_location_in_this_window (NautilusView *view,
const char *location)
{
CORBA_Environment ev;
Nautilus_ViewFrame view_frame;
view_frame = view_frame_call_begin (view, &ev);
if (view_frame != CORBA_OBJECT_NIL) {
Nautilus_ViewFrame_open_location_in_this_window
(view_frame, (CORBA_char *) location, &ev);
}
view_frame_call_end (view_frame, &ev);
}
void
nautilus_view_open_location_prefer_existing_window (NautilusView *view,
const char *location)
{
CORBA_Environment ev;
Nautilus_ViewFrame view_frame;
view_frame = view_frame_call_begin (view, &ev);
if (view_frame != CORBA_OBJECT_NIL) {
Nautilus_ViewFrame_open_location_prefer_existing_window
(view_frame, (CORBA_char *) location, &ev);
}
view_frame_call_end (view_frame, &ev);
}
void
nautilus_view_open_location_force_new_window (NautilusView *view,
const char *location,
GList *selection)
{
CORBA_Environment ev;
Nautilus_ViewFrame view_frame;
Nautilus_URIList *uri_list;
view_frame = view_frame_call_begin (view, &ev);
if (view_frame != CORBA_OBJECT_NIL) {
uri_list = nautilus_uri_list_from_g_list (selection);
Nautilus_ViewFrame_open_location_force_new_window
(view_frame, (CORBA_char *) location, uri_list, &ev);
CORBA_free (uri_list);
}
view_frame_call_end (view_frame, &ev);
}
void
nautilus_view_report_selection_change (NautilusView *view,
GList *selection)
{
CORBA_Environment ev;
Nautilus_ViewFrame view_frame;
Nautilus_URIList *uri_list;
view_frame = view_frame_call_begin (view, &ev);
if (view_frame != CORBA_OBJECT_NIL) {
uri_list = nautilus_uri_list_from_g_list (selection);
Nautilus_ViewFrame_report_selection_change (view_frame, uri_list, &ev);
CORBA_free (uri_list);
}
view_frame_call_end (view_frame, &ev);
}
void
nautilus_view_report_status (NautilusView *view,
const char *status)
{
CORBA_Environment ev;
Nautilus_ViewFrame view_frame;
view_frame = view_frame_call_begin (view, &ev);
if (view_frame != CORBA_OBJECT_NIL) {
Nautilus_ViewFrame_report_status (view_frame, status, &ev);
}
view_frame_call_end (view_frame, &ev);
}
void
nautilus_view_report_load_underway (NautilusView *view)
{
CORBA_Environment ev;
Nautilus_ViewFrame view_frame;
view_frame = view_frame_call_begin (view, &ev);
if (view_frame != CORBA_OBJECT_NIL) {
Nautilus_ViewFrame_report_load_underway (view_frame, &ev);
}
view_frame_call_end (view_frame, &ev);
}
void
nautilus_view_report_load_progress (NautilusView *view,
double fraction_done)
{
CORBA_Environment ev;
Nautilus_ViewFrame view_frame;
view_frame = view_frame_call_begin (view, &ev);
if (view_frame != CORBA_OBJECT_NIL) {
Nautilus_ViewFrame_report_load_progress (view_frame, fraction_done, &ev);
}
view_frame_call_end (view_frame, &ev);
}
void
nautilus_view_report_load_complete (NautilusView *view)
{
CORBA_Environment ev;
Nautilus_ViewFrame view_frame;
view_frame = view_frame_call_begin (view, &ev);
if (view_frame != CORBA_OBJECT_NIL) {
Nautilus_ViewFrame_report_load_complete (view_frame, &ev);
}
view_frame_call_end (view_frame, &ev);
}
void
nautilus_view_report_load_failed (NautilusView *view)
{
CORBA_Environment ev;
Nautilus_ViewFrame view_frame;
view_frame = view_frame_call_begin (view, &ev);
if (view_frame != CORBA_OBJECT_NIL) {
Nautilus_ViewFrame_report_load_failed (view_frame, &ev);
}
view_frame_call_end (view_frame, &ev);
}
void
nautilus_view_set_title (NautilusView *view,
const char *title)
{
CORBA_Environment ev;
Nautilus_ViewFrame view_frame;
view_frame = view_frame_call_begin (view, &ev);
if (view_frame != CORBA_OBJECT_NIL) {
Nautilus_ViewFrame_set_title (view_frame, title, &ev);
}
view_frame_call_end (view_frame, &ev);
}
BonoboControl *
nautilus_view_get_bonobo_control (NautilusView *view)
{
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
return view->details->control;
}
BonoboUIComponent *
nautilus_view_set_up_ui (NautilusView *view,
const char *datadir,
const char *ui_file_name,
const char *application_name)
{
BonoboUIComponent *ui_component;
Bonobo_UIContainer ui_container;
/* Get the UI component that's pre-made by the control. */
ui_component = bonobo_control_get_ui_component (view->details->control);
/* Connect the UI component to the control frame's UI container. */
ui_container = bonobo_control_get_remote_ui_container (view->details->control);
bonobo_ui_component_set_container (ui_component, ui_container);
bonobo_object_release_unref (ui_container, NULL);
/* Set up the UI from an XML file. */
bonobo_ui_util_set_ui (ui_component, datadir, ui_file_name, application_name);
return ui_component;
}