nautilus-application.c 11.7 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 <bonobo.h>
31 32
#include "file-manager/fm-icon-view.h"
#include "file-manager/fm-list-view.h"
33
#include <libnautilus-extensions/nautilus-gtk-macros.h>
34
#include <libnautilus-extensions/nautilus-stock-dialogs.h>
35
#include <libnautilus-extensions/nautilus-global-preferences.h>
36 37
#include <libnautilus-extensions/nautilus-file-utilities.h>
#include <libnautilus-extensions/nautilus-string-list.h>
38
#include <libnautilus-extensions/nautilus-undo-manager.h>
39
#include <liboaf/liboaf.h>
40
#include "nautilus-desktop-window.h"
41

42
typedef struct {
43 44
	POA_Bonobo_GenericFactory servant;
 	NautilusApplication *bonobo_object;
45
} impl_POA_Nautilus_Application;
46

47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
static CORBA_boolean manufactures                                (PortableServer_Servant    servant,
								  const CORBA_char         *iid,
								  CORBA_Environment        *ev);
static CORBA_Object  create_object                               (PortableServer_Servant    servant,
								  const CORBA_char         *iid,
								  const Bonobo_stringlist  *params,
								  CORBA_Environment        *ev);
static void          nautilus_application_initialize             (NautilusApplication      *application);
static void          nautilus_application_initialize_class       (NautilusApplicationClass *klass);
static void          nautilus_application_destroy                (GtkObject                *object);
static void          nautilus_application_check_user_directories (NautilusApplication      *application);

NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusApplication, nautilus_application, BONOBO_OBJECT_TYPE)

static POA_Bonobo_GenericFactory__epv factory_epv = {
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
62
	NULL,
63 64 65 66 67 68 69
	&manufactures,
	&create_object
};
static PortableServer_ServantBase__epv base_epv;
static POA_Bonobo_GenericFactory__vepv vepv = {
	&base_epv,
	&factory_epv
70 71 72
};

static CORBA_boolean
73 74 75
manufactures (PortableServer_Servant servant,
	      const CORBA_char *iid,
	      CORBA_Environment *ev)
76
{
77 78
	return strcmp (iid, "OAFIID:nautilus_file_manager_icon_view:42681b21-d5ca-4837-87d2-394d88ecc058") == 0
		|| strcmp (iid, "OAFIID:nautilus_file_manager_list_view:521e489d-0662-4ad7-ac3a-832deabe111c") == 0;
79 80 81
}

static CORBA_Object
82 83 84 85
create_object (PortableServer_Servant servant,
	       const CORBA_char *iid,
	       const Bonobo_stringlist *params,
	       CORBA_Environment *ev)
86
{
87
	FMDirectoryView *directory_view;
Darin Adler's avatar
Darin Adler committed
88
	NautilusView *view;
89

90 91 92 93
	if (strcmp (iid, "OAFIID:nautilus_file_manager_icon_view:42681b21-d5ca-4837-87d2-394d88ecc058") == 0) {
		directory_view = FM_DIRECTORY_VIEW (gtk_object_new (fm_icon_view_get_type (), NULL));
	} else if (strcmp (iid, "OAFIID:nautilus_file_manager_list_view:521e489d-0662-4ad7-ac3a-832deabe111c") == 0) {
		directory_view = FM_DIRECTORY_VIEW (gtk_object_new (fm_list_view_get_type (), NULL));
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
94
	} else {
95
		return CORBA_OBJECT_NIL;
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
96
	}
97
        
98
	view = fm_directory_view_get_nautilus_view (directory_view);
99
	return CORBA_Object_duplicate (bonobo_object_corba_objref (BONOBO_OBJECT (view)), ev);
100 101
}

102
static CORBA_Object
103 104 105
create_factory (PortableServer_POA poa,
		NautilusApplication *bonobo_object,
		CORBA_Environment *ev)
106
{
107
	impl_POA_Nautilus_Application *servant;
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
108

109 110 111 112
	servant = g_new0 (impl_POA_Nautilus_Application, 1);
	servant->servant.vepv = &vepv;
	POA_Bonobo_GenericFactory__init ((PortableServer_Servant) servant, ev);
	return bonobo_object_activate_servant (BONOBO_OBJECT (bonobo_object), servant);
113 114 115
}

static void
116
nautilus_application_initialize_class (NautilusApplicationClass *klass)
117
{
118
	GTK_OBJECT_CLASS (klass)->destroy = nautilus_application_destroy;
119 120 121
}

static void
122
nautilus_application_initialize (NautilusApplication *application)
123
{
124
	CORBA_Environment ev;
125 126
	CORBA_Object corba_object;
	OAF_RegistrationResult result;
127
	
128
	CORBA_exception_init (&ev);
129

130 131 132 133 134 135
	corba_object = create_factory (bonobo_poa (), application, &ev);
	result = oaf_active_server_register ("OAFIID:nautilus_file_manager_factory:bd1e1862-92d7-4391-963e-37583f0daef3",
					     corba_object);
	/* FIXME: Report this error somehow. */
	g_assert (result == OAF_REG_SUCCESS);
	bonobo_object_construct (BONOBO_OBJECT (application), corba_object);
136

137
	/* Create an undo manager */
138
	application->undo_manager = nautilus_undo_manager_new ();
Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
139

140
	CORBA_exception_free (&ev);
141 142
}

143 144
NautilusApplication *
nautilus_application_new (void)
145
{
146
	return NAUTILUS_APPLICATION (gtk_object_new (nautilus_application_get_type (), NULL));
147 148 149
}

static void
150
nautilus_application_destroy (GtkObject *object)
151
{
152 153
	/* Shut down preferences. This is needed so that the global
	 * preferences object and all its allocations are freed. Not
154 155 156
	 * 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,
157
	 * but it adds noise to memory profile tool runs.
158 159
	 */
	nautilus_global_preferences_shutdown ();
160

161
	nautilus_bookmarks_exiting ();
162

163 164
	NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object));
}
165

166
static void
167
display_caveat (GtkWindow *parent_window)
168
{
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
	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);
	
Darin Adler's avatar
Darin Adler committed
194
	file_name = nautilus_pixmap_file ("About_Image.png");
195 196 197 198 199
	pixmap = gnome_pixmap_new_from_file (file_name);
	g_free (file_name);
	gtk_widget_show (pixmap);
	gtk_container_add (GTK_CONTAINER (frame), pixmap);

200 201 202 203 204 205 206 207 208
  	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
209
		   "unpredictable and may even delete or overwrite "
210 211 212 213
		   "files on your computer."
		   "\n\n"
		   "For more information, visit http://nautilus.eazel.com."));
    	gtk_label_set_line_wrap (GTK_LABEL (text), TRUE);
214 215 216 217 218
	gtk_widget_show (text);
  	gtk_box_pack_start (GTK_BOX (hbox), text, FALSE, FALSE, 0);

  	gnome_dialog_set_close (GNOME_DIALOG (dialog), TRUE);

219 220 221
	if (parent_window != NULL) {
		gnome_dialog_set_parent (GNOME_DIALOG (dialog), parent_window);
	}
222 223

	gtk_widget_show (GTK_WIDGET (dialog));
224 225
}

226
static void
227
nautilus_application_check_user_directories (NautilusApplication *application)
228 229 230 231 232 233
{
	const char		*user_directory;
	const char		*user_main_directory;
	const char		*desktop_directory;
	NautilusStringList	*dir_list;
	
234
	g_assert (NAUTILUS_IS_APPLICATION (application));
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277

	user_directory = nautilus_get_user_directory ();
	user_main_directory = nautilus_get_user_main_directory ();
	desktop_directory = nautilus_get_desktop_directory ();

	dir_list = nautilus_string_list_new ();
	
	/* FIXME bugzilla.eazel.com 1115: Need better name for "User Directory"
	 * and "User Data Directory".
	 */

	if (!g_file_test (user_directory, G_FILE_TEST_ISDIR)) {
		nautilus_string_list_insert (dir_list, "User Directory");
	}
	    
	if (!g_file_test (user_main_directory, G_FILE_TEST_ISDIR)) {
		nautilus_string_list_insert (dir_list, "User Main Directory");
	}
	    
	if (!g_file_test (desktop_directory, G_FILE_TEST_ISDIR)) {
		nautilus_string_list_insert (dir_list, "Desktop Directory");
	}

	if (nautilus_string_list_get_length (dir_list) > 0) {
		char *dir_list_concatenated;
		char *error_string;

		dir_list_concatenated = nautilus_string_list_as_concatenated_string (dir_list, "\n");
		
		error_string = g_strdup_printf ("%s\n\n%s\n\n%s",
						"The following directories are missing:",
						dir_list_concatenated,
						"Please restart Nautilus to fix this problem.");

		nautilus_error_dialog (error_string);

		g_free (dir_list_concatenated);
		g_free (error_string);
	}

	nautilus_string_list_free (dir_list);
}

278
void
279 280 281
nautilus_application_startup (NautilusApplication *application,
			      gboolean manage_desktop,
			      const char *urls[])
282
{
283
	const char **p;
284
	NautilusWindow *window;
285
	NautilusWindow *first_window;
286

287 288 289
	/* Check the user's ~/.nautilus directories and post warnings if there
	 * are problems
	 */
290
	nautilus_application_check_user_directories (application);
291

292 293
	/* Set up the desktop. */
	if (manage_desktop) {
294
		gtk_widget_show (GTK_WIDGET (nautilus_desktop_window_new (application)));
295
	}
296

297 298 299 300
  	/* Create the other windows. */
	first_window = NULL;
	if (urls != NULL) {
		for (p = urls; *p != NULL; p++) {
301
			window = nautilus_application_create_window (application);
302 303 304 305 306 307
			nautilus_window_goto_uri (window, *p);
			if (first_window == NULL) {
				first_window = window;
			}
		}
	}
308 309 310 311 312
	/* FIXME bugzilla.eazel.com 1051: Change this logic back so it won't
	 * make a new window when asked to manage the desktop, once we have
	 * a way to get rid of the desktop.
	 */
	if (/* !manage_desktop && */ first_window == NULL) {
313
		first_window = nautilus_application_create_window (application);
314 315
		nautilus_window_go_home (first_window);
	}
316

317
	/* Show the "not ready for prime time" dialog after the first
318 319
	 * window appears, so it's on top.
	 */
John Sullivan's avatar
John Sullivan committed
320
	/* FIXME bugzilla.eazel.com 1256: It's not on top of the other windows. */
Darin Adler's avatar
Darin Adler committed
321
	if (g_getenv ("NAUTILUS_NO_CAVEAT_DIALOG") == NULL) {
322 323 324 325 326 327
	  	if (first_window == NULL) {
			display_caveat (NULL);
		} else {
			gtk_signal_connect (GTK_OBJECT (first_window), "show",
					    display_caveat, first_window);
		}
328
  	}
329 330 331
}

static void
332
nautilus_application_destroy_window (GtkObject *obj, NautilusApplication *application)
333
{
334 335 336
	application->windows = g_slist_remove (application->windows, obj);
	if (application->windows == NULL) {
  		nautilus_application_quit();
337
	}
338 339 340
}

void 
341
nautilus_application_quit (void)
342
{
343
	gtk_main_quit ();
344 345 346
}

NautilusWindow *
347
nautilus_application_create_window (NautilusApplication *application)
348
{
349
	NautilusWindow *window;
350 351

	g_return_val_if_fail (NAUTILUS_IS_APPLICATION (application), NULL);
352
	
353
	window = NAUTILUS_WINDOW (gtk_object_new (nautilus_window_get_type (),
354
						  "app", GTK_OBJECT (application),
355 356
						  "app_id", "nautilus", NULL));
	gtk_signal_connect (GTK_OBJECT (window),
357 358 359 360
			    "destroy", nautilus_application_destroy_window,
			    application);

	application->windows = g_slist_prepend (application->windows, window);
361

Gene Z. Ragan's avatar
CVS:  
Gene Z. Ragan committed
362
	/* Do not yet show the window. It will be shown later on if it can
363 364 365
	 * successfully display its initial URI. Otherwise it will be destroyed
	 * without ever having seen the light of day.
	 */
366

367
	return window;
368
}