nautilus-application.c 12.4 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 <libnautilus/libnautilus.h>
31
#include <bonobo.h>
32 33
#include "file-manager/fm-icon-view.h"
#include "file-manager/fm-list-view.h"
34
#include <libgnomevfs/gnome-vfs-init.h>
35
#include <libnautilus-extensions/nautilus-gnome-extensions.h>
36
#include <libnautilus-extensions/nautilus-global-preferences.h>
37
#include <libnautilus/nautilus-undo-manager.h>
38
#include <liboaf/liboaf.h>
39
#include "nautilus-desktop-window.h"
40

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

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

48 49 50 51 52 53 54 55
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,
56
				   CORBA_char *obj_iid,
57 58 59
				   CORBA_Environment * ev);
static CORBA_Object
impl_Nautilus_Application_create_object(impl_POA_Nautilus_Application *servant,
60
                                        CORBA_char *obj_iid,
61 62 63
					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
64 65 66
	NULL,			/* _private */
	(gpointer) &impl_Nautilus_Application__get_view_windows,
	(gpointer) &impl_Nautilus_Application_new_view_window
67 68

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

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

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

97 98 99 100 101
	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
102 103
	}

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

	return retval;
107 108
}

Gene Ragan's avatar
Gene Ragan committed
109

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

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

static CORBA_boolean
121 122 123
impl_Nautilus_Application_supports (impl_POA_Nautilus_Application * servant,
				    CORBA_char * obj_iid,
				    CORBA_Environment * ev)
124
{
125 126 127
	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;
128 129 130
}

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

139
	if (!impl_Nautilus_Application_supports (servant, obj_iid, ev)) {
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
140
		return CORBA_OBJECT_NIL;
141
	}
142
        
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
143 144 145 146 147
	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) {
148
		return impl_Nautilus_Application_new_view_window (servant, ev);
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
149
	} else {
150
		return CORBA_OBJECT_NIL;
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
151
	}
152
        
153 154
	view = fm_directory_view_get_nautilus_view (dir_view);
	return CORBA_Object_duplicate (bonobo_object_corba_objref (BONOBO_OBJECT (view)), ev);
155 156 157
}


158 159 160 161 162
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
163
	impl_POA_Nautilus_Application *newservant;
164

Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
165 166 167 168 169
	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);
170 171 172 173 174 175 176 177 178 179 180
}

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
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
	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;
201 202 203 204 205
}

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

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

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

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

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

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

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

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

237 238
	/* 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
239

240
	CORBA_exception_free (&ev);
241 242 243
}

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

static void
250
nautilus_app_destroy (GtkObject *object)
251
{
252 253 254 255 256 257
	/* 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.
258 259
	 */
	nautilus_global_preferences_shutdown ();
260

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

265

266
static void
267
display_caveat (GtkWindow *parent_window)
268
{
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
	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);

300 301 302 303 304 305 306 307 308
  	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
309
		   "unpredictable and may even delete or overwrite "
310 311 312 313
		   "files on your computer."
		   "\n\n"
		   "For more information, visit http://nautilus.eazel.com."));
    	gtk_label_set_line_wrap (GTK_LABEL (text), TRUE);
314 315 316 317 318
	gtk_widget_show (text);
  	gtk_box_pack_start (GTK_BOX (hbox), text, FALSE, FALSE, 0);

  	gnome_dialog_set_close (GNOME_DIALOG (dialog), TRUE);

319 320 321
	if (parent_window != NULL) {
		gnome_dialog_set_parent (GNOME_DIALOG (dialog), parent_window);
	}
322 323

	gtk_widget_show (GTK_WIDGET (dialog));
324 325
}

326
void
327
nautilus_app_startup (NautilusApp *app,
328 329
		      gboolean manage_desktop,
		      const char *urls[])
330
{
331
	const char **p;
332
	NautilusWindow *window;
333
	NautilusWindow *first_window;
334

335 336
	/* Set up the desktop. */
	if (manage_desktop) {
337 338
		gtk_widget_show (GTK_WIDGET (nautilus_desktop_window_new (app)));
	}
339

340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
  	/* Create the other windows. */
	first_window = NULL;
	if (urls != NULL) {
		for (p = urls; *p != NULL; p++) {
			window = nautilus_app_create_window (app);
			nautilus_window_goto_uri (window, *p);
			if (first_window == NULL) {
				first_window = window;
			}
		}
	}
	if (!manage_desktop && first_window == NULL) {
		first_window = nautilus_app_create_window (app);
		nautilus_window_go_home (first_window);
	}
355

356
	/* Show the "not ready for prime time" dialog after the first
357 358
	 * window appears, so it's on top.
	 */
359
	/* FIXME: It's not on top of the other windows. */
Darin Adler's avatar
Darin Adler committed
360
	if (g_getenv ("NAUTILUS_NO_CAVEAT_DIALOG") == NULL) {
361 362 363 364 365 366
	  	if (first_window == NULL) {
			display_caveat (NULL);
		} else {
			gtk_signal_connect (GTK_OBJECT (first_window), "show",
					    display_caveat, first_window);
		}
367
  	}
368 369 370
}

static void
371
nautilus_app_destroy_window (GtkObject *obj, NautilusApp *app)
372
{
373 374
	app->windows = g_slist_remove (app->windows, obj);
	if (app->windows == NULL) {
375
  		nautilus_app_quit();
376
	}
377 378 379 380 381
}

void 
nautilus_app_quit (void)
{
382 383
	gnome_vfs_shutdown ();
	gtk_main_quit ();
384 385 386
}

NautilusWindow *
387
nautilus_app_create_window (NautilusApp *app)
388
{
389
	NautilusWindow *window;
390
	
391 392
	window = NAUTILUS_WINDOW (gtk_object_new (nautilus_window_get_type (),
						  "app", BONOBO_OBJECT (app),
393 394 395 396
						  "app_id", "nautilus", NULL));
	
	gtk_signal_connect (GTK_OBJECT (window),
			    "destroy", nautilus_app_destroy_window, app);
397

Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
398
	/* Do not yet show the window. It will be shown later on if it can
399 400 401 402
	 * 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);
403

404
	return window;
405
}