nautilus-application.c 12 KB
Newer Older
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
1
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 3 4 5 6 7 8

/*
 *  Nautilus
 *
 *  Copyright (C) 1999, 2000 Red Hat, Inc.
 *  Copyright (C) 2000 Eazel, Inc.
 *
9
 *  This program is free software; you can redistribute it and/or
10 11 12 13
 *  modify it under the terms of the GNU General Public License as
 *  published by the Free Software Foundation; either version 2 of the
 *  License, or (at your option) any later version.
 *
14
 *  This program is distributed in the hope that it will be useful,
15 16 17 18 19
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
20
 *  along with this program; if not, write to the Free Software
21 22 23 24 25 26
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Author: Elliot Lee <sopwith@redhat.com>,
 *
 */

27
#include <config.h>
28
#include "nautilus-application.h"
29

30
#include "nautilus-window-state.h"
31
#include <libnautilus/libnautilus.h>
32
#include <bonobo.h>
33 34
#include "file-manager/fm-icon-view.h"
#include "file-manager/fm-list-view.h"
35
#include <libgnomevfs/gnome-vfs-init.h>
36
#include <libnautilus-extensions/nautilus-gnome-extensions.h>
37
#include <libnautilus-extensions/nautilus-global-preferences.h>
38
#include <libnautilus/nautilus-undo-manager.h>
39
#include <liboaf/liboaf.h>
40
#include "nautilus-desktop-window.h"
41

42
typedef struct {
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
43 44
	POA_Nautilus_Application servant;
 	NautilusApp *app;
45

Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
46
	Nautilus_ViewWindowList attr_view_windows;
47
} impl_POA_Nautilus_Application;
48

49 50 51 52 53 54 55 56
static Nautilus_ViewWindowList *
impl_Nautilus_Application__get_view_windows(impl_POA_Nautilus_Application* servant,
                                            CORBA_Environment * ev);
static Nautilus_ViewWindow
impl_Nautilus_Application_new_view_window(impl_POA_Nautilus_Application *servant,
                                          CORBA_Environment * ev);
static CORBA_boolean
impl_Nautilus_Application_supports(impl_POA_Nautilus_Application * servant,
57
				   CORBA_char *obj_iid,
58 59 60
				   CORBA_Environment * ev);
static CORBA_Object
impl_Nautilus_Application_create_object(impl_POA_Nautilus_Application *servant,
61
                                        CORBA_char *obj_iid,
62 63 64
					GNOME_stringlist * params,
					CORBA_Environment * ev);
static POA_Nautilus_Application__epv impl_Nautilus_Application_epv = {
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
65 66 67
	NULL,			/* _private */
	(gpointer) &impl_Nautilus_Application__get_view_windows,
	(gpointer) &impl_Nautilus_Application_new_view_window
68 69

};
70
static POA_Bonobo_GenericFactory__epv impl_Nautilus_Application_Bonobo_GenericFactory_epv = {
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
71 72 73
	NULL,			/* _private */
	(gpointer) &impl_Nautilus_Application_supports,
	(gpointer) &impl_Nautilus_Application_create_object
74 75
};
static PortableServer_ServantBase__epv impl_Nautilus_Application_base_epv = {
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
76 77 78
	NULL,			/* _private data */
	NULL,			/* finalize routine */
	NULL,			/* default_POA routine */
79 80
};
static POA_Nautilus_Application__vepv impl_Nautilus_Application_vepv = {
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
81 82 83 84
	&impl_Nautilus_Application_base_epv,
	&impl_Nautilus_Application_Bonobo_GenericFactory_epv,
	NULL,
	&impl_Nautilus_Application_epv,
85 86 87
};

static Nautilus_ViewWindowList *
88 89
impl_Nautilus_Application__get_view_windows(impl_POA_Nautilus_Application *servant,
                                            CORBA_Environment * ev)
90
{
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
91
	Nautilus_ViewWindowList *retval;
92 93
	int i;
	GSList *ltmp;
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
94

95 96
	retval = Nautilus_ViewWindowList__alloc ();
	retval->_length = g_slist_length (servant->app->windows);
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
97

98 99 100 101 102
	retval->_buffer = CORBA_sequence_Nautilus_ViewWindow_allocbuf (retval->_length);
	for(i = 0, ltmp = servant->app->windows; ltmp; ltmp = ltmp->next, i++) {
		CORBA_Object obj;
		obj = bonobo_object_corba_objref(NAUTILUS_WINDOW(ltmp->data)->ntl_viewwindow);
		retval->_buffer[i] = CORBA_Object_duplicate(obj, ev);
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
103 104
	}

105
	CORBA_sequence_set_release (retval, CORBA_TRUE);
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
106 107

	return retval;
108 109
}

Gene Ragan's avatar
Gene Ragan committed
110

111
static Nautilus_ViewWindow
112 113
impl_Nautilus_Application_new_view_window (impl_POA_Nautilus_Application *servant,
					   CORBA_Environment * ev)
114
{
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
115
	NautilusWindow *win;
116

Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
117 118
	win = nautilus_app_create_window (servant->app);
	return CORBA_Object_duplicate (bonobo_object_corba_objref (BONOBO_OBJECT (win)), ev);
119 120 121
}

static CORBA_boolean
122 123 124
impl_Nautilus_Application_supports (impl_POA_Nautilus_Application * servant,
				    CORBA_char * obj_iid,
				    CORBA_Environment * ev)
125
{
126 127 128
	return strcmp(obj_iid, "OAFIID:ntl_file_manager_icon_view:42681b21-d5ca-4837-87d2-394d88ecc058") == 0
		|| strcmp(obj_iid, "OAFIID:ntl_file_manager_list_view:521e489d-0662-4ad7-ac3a-832deabe111c") == 0
		|| strcmp(obj_iid, "OAFIID:ntl_window:88e8b2e4-b627-4221-b566-5ba32185c88d") == 0;
129 130 131
}

static CORBA_Object
132 133 134 135
impl_Nautilus_Application_create_object (impl_POA_Nautilus_Application *servant,
					 CORBA_char *obj_iid,
					 GNOME_stringlist * params,
					 CORBA_Environment * ev)
136
{
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
137
	FMDirectoryView *dir_view;
Darin Adler's avatar
Darin Adler committed
138
	NautilusView *view;
139

140
	if (!impl_Nautilus_Application_supports (servant, obj_iid, ev)) {
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
141
		return CORBA_OBJECT_NIL;
142
	}
143
        
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
144 145 146 147 148
	if (strcmp (obj_iid, "OAFIID:ntl_file_manager_icon_view:42681b21-d5ca-4837-87d2-394d88ecc058") == 0) {
		dir_view = FM_DIRECTORY_VIEW (gtk_object_new (fm_icon_view_get_type (), NULL));
	} else if (strcmp (obj_iid, "OAFIID:ntl_file_manager_list_view:521e489d-0662-4ad7-ac3a-832deabe111c") == 0) {
		dir_view = FM_DIRECTORY_VIEW (gtk_object_new (fm_list_view_get_type (), NULL));
	} else if (strcmp (obj_iid,"OAFIID:ntl_window:88e8b2e4-b627-4221-b566-5ba32185c88d") == 0) {
149
		return impl_Nautilus_Application_new_view_window (servant, ev);
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
150
	} else {
151
		return CORBA_OBJECT_NIL;
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
152
	}
153
        
154 155
	view = fm_directory_view_get_nautilus_view (dir_view);
	return CORBA_Object_duplicate (bonobo_object_corba_objref (BONOBO_OBJECT (view)), ev);
156 157 158
}


159 160 161 162 163
static CORBA_Object
impl_Nautilus_Application__create(PortableServer_POA poa,
                                  NautilusApp *app,
				  CORBA_Environment * ev)
{
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
164
	impl_POA_Nautilus_Application *newservant;
165

Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
166 167 168 169 170
	newservant = g_new0(impl_POA_Nautilus_Application, 1);
	newservant->servant.vepv = &impl_Nautilus_Application_vepv;
	newservant->servant.vepv->Bonobo_Unknown_epv = NAUTILUS_APP_CLASS(GTK_OBJECT(app)->klass)->unknown_epv;
	POA_Nautilus_Application__init((PortableServer_Servant) newservant, ev);
	return bonobo_object_activate_servant(BONOBO_OBJECT(app), newservant);
171 172 173 174 175 176 177 178 179 180 181
}

static void nautilus_app_init		(NautilusApp		 *app);
static void nautilus_app_class_init	(NautilusAppClass	 *klass);
static void nautilus_app_destroy        (GtkObject *object);

static GtkObjectClass *app_parent_class = NULL;

GtkType
nautilus_app_get_type (void)
{
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
	static GtkType App_type = 0;

	if (!App_type)
	{
		static const GtkTypeInfo App_info =
		{
			"NautilusApp",
			sizeof (NautilusApp),
			sizeof (NautilusAppClass),
			(GtkClassInitFunc) nautilus_app_class_init,
			(GtkObjectInitFunc) nautilus_app_init,
			/* reserved_1 */ NULL,
			/* reserved_2 */ NULL,
			(GtkClassInitFunc) NULL,
      		};

		App_type = gtk_type_unique (bonobo_object_get_type (), &App_info);
	}

	return App_type;
202 203 204 205 206
}

static void
nautilus_app_class_init (NautilusAppClass *klass)
{
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
207
	GtkObjectClass *object_class;
208

Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
209
	klass->unknown_epv = bonobo_object_get_epv();
210

Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
211 212
	object_class = (GtkObjectClass*) klass;
	object_class->destroy = nautilus_app_destroy;
213

Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
214
	app_parent_class = gtk_type_class (gtk_object_get_type ());
215 216 217 218 219
}

static void
nautilus_app_init (NautilusApp *app)
{
220
	CORBA_Environment ev;
221 222
	CORBA_Object objref;
	Nautilus_Undo_Manager undo_manager;
223
	
224
	CORBA_exception_init (&ev);
225

226
	objref = impl_Nautilus_Application__create (bonobo_poa (), app, &ev);
227
	oaf_active_server_register ("OAFIID:ntl_file_manager_factory:bd1e1862-92d7-4391-963e-37583f0daef3",
228 229
				    objref);
	bonobo_object_construct (BONOBO_OBJECT(app), objref);
230

231
	/* Init undo manager */
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
232
	app->undo_manager = BONOBO_OBJECT (nautilus_undo_manager_new ());
233 234
	undo_manager = bonobo_object_corba_objref (BONOBO_OBJECT (app->undo_manager));

235 236 237
	/* Stash a global reference to the object */
	nautilus_undo_manager_stash_global_undo (undo_manager);

238 239
	/* Add it to the application object */
	nautilus_attach_undo_manager (GTK_OBJECT (app), undo_manager);
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
240

241
	CORBA_exception_free (&ev);
242 243 244
}

GtkObject *
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
245
nautilus_app_new (void)
246
{
247
	return gtk_object_new (nautilus_app_get_type (), NULL);
248 249 250
}

static void
251
nautilus_app_destroy (GtkObject *object)
252
{
253 254 255 256 257 258
	/* Shut down preferences.  This is needed so that the global
	 * preferences object and all its allocations are freed.  Not
	 * calling this function would have NOT cause the user to lose
	 * preferences.  The only effect would be to leak those
	 * objects - which would be collected at exit() time anyway,
	 * but it adds noice to memory profile tool runs.
259 260
	 */
	nautilus_global_preferences_shutdown ();
261

262
	nautilus_bookmarks_exiting ();
263
	GTK_OBJECT_CLASS(app_parent_class)->destroy (object);
264 265
}

266

267
static void
268
display_caveat (GtkWindow *parent_window)
269
{
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
	GtkWidget *dialog;
	GtkWidget *frame;
	GtkWidget *pixmap;
	GtkWidget *hbox;
	GtkWidget *text;
	char *file_name;

	dialog = gnome_dialog_new (_("Nautilus: caveat"),
				   GNOME_STOCK_BUTTON_OK,
				   NULL);
  	gtk_container_set_border_width (GTK_CONTAINER (dialog), GNOME_PAD);
  	gtk_window_set_policy (GTK_WINDOW (dialog), FALSE, FALSE, FALSE);

  	hbox = gtk_hbox_new (FALSE, GNOME_PAD);
  	gtk_container_set_border_width (GTK_CONTAINER (hbox), GNOME_PAD);
  	gtk_widget_show (hbox);
  	gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), 
  			    hbox,
  			    FALSE, FALSE, 0);

	frame = gtk_frame_new (NULL);
	gtk_widget_show (frame);
	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
  	gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, FALSE, 0);
	
	file_name = gnome_pixmap_file ("nautilus/About_Image.png");
	pixmap = gnome_pixmap_new_from_file (file_name);
	g_free (file_name);
	gtk_widget_show (pixmap);
	gtk_container_add (GTK_CONTAINER (frame), pixmap);

301 302 303 304 305 306 307 308 309
  	text = gtk_label_new
		(_("The Nautilus shell is under development; it's not "
  		   "ready for daily use. Many features, including some "
  		   "of the best ones, are not yet done, partly done, or "
  		   "unstable. The program doesn't look or act the way "
  		   "it will in version 1.0."
		   "\n\n"
		   "If you do decide to test this version of Nautilus, "
		   "beware. The program could do something "
John Sullivan's avatar
John Sullivan committed
310
		   "unpredictable and may even delete or overwrite "
311 312 313 314
		   "files on your computer."
		   "\n\n"
		   "For more information, visit http://nautilus.eazel.com."));
    	gtk_label_set_line_wrap (GTK_LABEL (text), TRUE);
315 316 317 318 319 320 321 322
	gtk_widget_show (text);
  	gtk_box_pack_start (GTK_BOX (hbox), text, FALSE, FALSE, 0);

  	gnome_dialog_set_close (GNOME_DIALOG (dialog), TRUE);

  	gnome_dialog_set_parent (GNOME_DIALOG (dialog), parent_window);

	gtk_widget_show (GTK_WIDGET (dialog));
323 324
}

325
void
326 327 328
nautilus_app_startup (NautilusApp *app,
		      const char *initial_url,
		      gboolean handle_desktop)
329
{
330 331 332 333 334
	NautilusWindow *window;

	if (handle_desktop) {
		gtk_widget_show (GTK_WIDGET (nautilus_desktop_window_new (app)));
	}
335

336
  	/* Set default configuration */
337
  	window = nautilus_app_create_window (app);
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
338
  	bonobo_activate ();
339
  	nautilus_window_set_initial_state (window, initial_url);
340 341 342 343

	/* Show the "not ready for prime time" dialog after this
	 * window appears, so it's on top.
	 */
Darin Adler's avatar
Darin Adler committed
344
	if (g_getenv ("NAUTILUS_NO_CAVEAT_DIALOG") == NULL) {
345 346
	  	gtk_signal_connect (GTK_OBJECT (window), "show",
	  			    display_caveat, window);
347
  	}
348 349 350
}

static void
351
nautilus_app_destroy_window (GtkObject *obj, NautilusApp *app)
352
{
353 354
	app->windows = g_slist_remove (app->windows, obj);
	if (app->windows == NULL) {
355
  		nautilus_app_quit();
356
	}
357 358 359 360 361
}

void 
nautilus_app_quit (void)
{
362 363
	gnome_vfs_shutdown ();
	gtk_main_quit ();
364 365 366
}

NautilusWindow *
367
nautilus_app_create_window (NautilusApp *app)
368
{
369
	NautilusWindow *window;
370
	
371 372
	window = NAUTILUS_WINDOW (gtk_object_new (nautilus_window_get_type(),
						  "app", BONOBO_OBJECT(app),
373 374 375 376
						  "app_id", "nautilus", NULL));
	
	gtk_signal_connect (GTK_OBJECT (window),
			    "destroy", nautilus_app_destroy_window, app);
377

Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
378
	/* Do not yet show the window. It will be shown later on if it can
379 380 381 382
	 * successfully display its initial URI. Otherwise it will be destroyed
	 * without ever having seen the light of day.
	 */
	app->windows = g_slist_prepend (app->windows, window);
383

384
	return window;
385
}