The R Project SVN R

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
13974 hornik 1
/*
2
 *  R : A Computer Language for Statistical Data Analysis
3
 *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
4
 *  Copyright (C) 1997--2000  Robert Gentleman, Ross Ihaka
5
 *                            and the R Development Core Team
6
 *
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  (at your option) any later version.
11
 *
12
 *  This program is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU General Public License
18
 *  along with this program; if not, write to the Free Software
19
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 */
21
 
22
         /* See ../unix/system.txt for a description of functions */
23
 
24
#ifdef HAVE_CONFIG_H
25
#include <config.h>
26
#endif
27
 
28
#include <gnome.h>
29
#include <glade/glade.h>
30
#include <libgnome/libgnome.h>
18798 martyn 31
 
32
#if defined(HAVE_LOCALE_H)
18636 martyn 33
#include <locale.h>
18798 martyn 34
#endif
13974 hornik 35
 
19084 ripley 36
/* used to have Mac conditionals, but not used on classic MacOS */
18798 martyn 37
#ifdef HAVE_STAT
19084 ripley 38
# include <sys/types.h>
39
# ifdef HAVE_SYS_STAT_H
18798 martyn 40
#  include <sys/stat.h>
19084 ripley 41
# endif
18798 martyn 42
#endif
13974 hornik 43
 
44
#include <Rversion.h>
45
 
46
#include "Defn.h"
47
#include "Fileio.h"
48
#include "Rdevices.h"
49
 
50
#include "../../unix/Runix.h"
51
 
52
#include "devGNOME.h"
53
 
54
#include "Startup.h"
55
 
56
#include "gtkconsole.h"
57
#include "terminal.h"
58
#include "terminal-prefs.h"
59
 
60
	/*--- Initialization Code ---*/
61
 
15750 hornik 62
extern SA_TYPE SaveAction;
63
extern SA_TYPE RestoreAction;
13974 hornik 64
 
65
static gboolean R_gnome_initialised = FALSE; /* true once gnome_init has been called */
66
 
67
static GList *messages_list = NULL;
68
 
69
/*
70
 *  1) FATAL MESSAGES AT STARTUP
71
 */
72
 
73
void Rgnome_Suicide(char *s)
74
{
75
    GtkWidget *dialog;
76
    gchar *message;
77
 
78
    /* Create the error message */
79
    message = g_strdup_printf("R: Fatal error\n\n%s", s);
80
 
81
    dialog = gnome_message_box_new(message,
82
				   GNOME_MESSAGE_BOX_ERROR,
83
				   GNOME_STOCK_BUTTON_CLOSE,
84
				   NULL);
85
 
86
    if(R_gtk_main_window != NULL)
87
	gnome_dialog_set_parent(GNOME_DIALOG(dialog), GTK_WINDOW(R_gtk_main_window));
88
    gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
89
    gnome_dialog_set_default(GNOME_DIALOG(dialog), 0);
90
 
91
    gnome_dialog_run_and_close(GNOME_DIALOG(dialog));
92
 
93
    Rgnome_CleanUp(SA_SUICIDE, 2, 0);
94
}
95
 
96
 
97
 
98
/*
99
 *  3) ACTIONS DURING (LONG) COMPUTATIONS
100
 */
101
 
102
void Rgnome_Busy(int which)
103
{
104
    if(which == 1) {
105
	gnome_appbar_set_default(GNOME_APPBAR(GNOME_APP(R_gtk_main_window)->statusbar),
106
				 "Working...");
107
	while(gtk_events_pending())
108
	    gtk_main_iteration();
109
    }
110
    else {
111
	gnome_appbar_set_default(GNOME_APPBAR(GNOME_APP(R_gtk_main_window)->statusbar),
112
				 "");
113
    }    
114
}
115
 
116
/*
117
 *  4) INITIALIZATION AND TERMINATION ACTIONS
118
 */
119
 
120
/*
121
   R_CleanUp is invoked at the end of the session to give the user the
122
   option of saving their data.
123
   If ask == SA_SAVEASK the user should be asked if possible (and this
124
   option should not occur in non-interactive use).
125
   If ask = SA_SAVE or SA_NOSAVE the decision is known.
126
   If ask = SA_DEFAULT use the SaveAction set at startup.
127
   In all these cases run .Last() unless quitting is cancelled.
128
   If ask = SA_SUICIDE, no save, no .Last, possibly other things.
129
 */
130
 
131
void Rgnome_CleanUp(SA_TYPE saveact, int status, int runLast)
132
{
133
    GtkWidget *dialog;
134
    gint which; /* yes = 0, no = 1, cancel = 2 || -1 */
20664 ripley 135
    char *tmpdir, buf[1000];
13974 hornik 136
 
137
/*
138
    GList *curfile = R_gtk_editfiles;
139
    R_gtk_edititem *edititem;
140
*/
141
    if(saveact == SA_DEFAULT) /* The normal case apart from R_Suicide */
142
	saveact = SaveAction;
143
 
144
    if(saveact == SA_SAVEASK) {
145
	if(R_Interactive) {
146
	    R_ClearerrConsole();
147
	    R_FlushConsole();
148
	    dialog = gnome_message_box_new(
149
		"Do you want to save your workspace image?\n\n"
150
 
151
		"Choose Yes to save an image and exit, choose\n"
152
		"No to exit without saving, or choose Cancel to\n"
153
		"return to R.",
154
		GNOME_MESSAGE_BOX_QUESTION,
155
		GNOME_STOCK_BUTTON_YES,
156
		GNOME_STOCK_BUTTON_NO,
157
		GNOME_STOCK_BUTTON_CANCEL,
158
		NULL);
159
 
160
	    gnome_dialog_set_parent(GNOME_DIALOG(dialog), GTK_WINDOW(R_gtk_main_window));
161
	    gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
162
	    gnome_dialog_set_default(GNOME_DIALOG(dialog), 0);
163
 
164
	    which = gnome_dialog_run_and_close(GNOME_DIALOG(dialog));
165
	    switch(which) {
166
	    case 0:
167
		saveact = SA_SAVE;
168
		break;
169
	    case 1:
170
		saveact = SA_NOSAVE;
171
		break;
172
	    default:
173
		jump_to_toplevel();
174
		break;
175
	    }
176
	}
177
	else saveact = SaveAction;
178
    }
179
 
180
    switch (saveact) {
181
    case SA_SAVE:
182
	if(runLast) R_dot_Last();
183
	if(R_DirtyImage) R_SaveGlobalEnv();
184
	if(R_Interactive)
185
	    gtk_console_save_history(GTK_CONSOLE(R_gtk_terminal_text), 
186
				     R_HistoryFile, R_HistorySize, NULL);
187
	break;
188
    case SA_NOSAVE:
189
	if(runLast) R_dot_Last();
190
	break;
191
    case SA_SUICIDE:
192
    default:
193
	break;
194
    }
195
 
15884 luke 196
    R_RunExitFinalizers();
197
 
13974 hornik 198
    /* save GUI preferences */
199
    R_gnome_prefs_save();
200
/* unlink all the files we opened for editing 
201
    while(curfile != NULL) {
202
      edititem = (R_gtk_edititem *) curfile->data;
203
      unlink(edititem->filename);
204
      curfile = g_list_next(curfile);
205
    }
206
*/
20663 ripley 207
    if((tmpdir = getenv("R_SESSION_TMPDIR"))) {
208
	sprintf(buf, "rm -rf %s", tmpdir);
26152 luke 209
	R_system(buf);
20663 ripley 210
    }
13974 hornik 211
 
212
 
213
    /* close all the graphics devices */
214
    KillAllDevices();
215
    fpu_setup(0);
216
 
217
    exit(status);
218
}
219
 
220
void Rgnome_ShowMessage(char *s)
221
{
222
    GtkWidget *dialog;
223
    gchar *s_copy;
224
 
225
    if(R_gnome_initialised) {
226
        dialog = gnome_message_box_new(s,
227
                                       GNOME_MESSAGE_BOX_WARNING,
228
                                       GNOME_STOCK_BUTTON_OK,
229
                                       NULL);
230
 
231
        if(R_gtk_main_window != NULL)
232
            gnome_dialog_set_parent(GNOME_DIALOG(dialog), GTK_WINDOW(R_gtk_main_window));
233
        gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
234
        gnome_dialog_set_default(GNOME_DIALOG(dialog), 0);
235
 
236
        gnome_dialog_run_and_close(GNOME_DIALOG(dialog));    
237
    }
238
    else {
239
        /* queue the message */
240
        s_copy = g_strdup(s);
241
 
242
        messages_list = g_list_append(messages_list,
243
                                      (gpointer) s_copy);
244
    }
245
}
246
 
247
void R_ShowQueuedMessages(void)
248
{
249
    GList *l;
250
 
251
    for(l = messages_list; l != NULL; l = l->next) {
252
        R_ShowMessage((char *) l->data);
253
        g_free(l->data);
254
    }
255
 
256
    g_list_free(messages_list);
257
    messages_list = NULL;
258
}
259
 
260
	/*--- Initialization Code ---*/
261
 
262
 
263
void R_set_gnome_prefs(Rstart Rp)
264
{
265
    Rp->RestoreAction = prefs_get_restoreact();
266
    Rp->SaveAction = prefs_get_saveact();
267
}
268
static const struct poptOption popt_options[] = {
269
  { NULL, '\0', 0, NULL, 0, NULL, NULL }
270
};
271
 
272
void R_set_SaveAction(int sa)
273
{
274
    SaveAction = sa;
275
}
276
 
277
void gnome_start(int ac, char **av, Rstart Rp)
278
{
279
    char *p;
280
    int value, ierr;
281
    struct stat sb;
282
 
283
 
284
    /* Gnome startup preferences */
285
    gnomelib_init("R",
286
		  g_strdup_printf("%s.%s %s (%s-%s-%s)", R_MAJOR,
287
				  R_MINOR, R_STATUS, R_YEAR, R_MONTH,
288
				  R_DAY));
289
    R_gnome_prefs_cmd_load(RestoreAction, SaveAction);
290
    R_set_gnome_prefs(Rp);
291
 
292
    /* command line params */
293
    R_common_command_line(&ac, av, Rp);
294
 
295
    /* Initialise Gnome library */
296
    gnome_init("R",
297
	       g_strdup_printf("%s.%s %s (%s-%s-%s)", R_MAJOR, R_MINOR,
298
			       R_STATUS, R_YEAR, R_MONTH, R_DAY),
299
	       ac, av);
300
    R_gnome_initialised = TRUE;
301
 
18636 martyn 302
    /* Reset locale information */
18798 martyn 303
    #if defined(HAVE_LOCALE_H)
18636 martyn 304
    setlocale(LC_ALL, "C");
305
    setlocale(LC_CTYPE, "");/*- make ISO-latin1 etc. work for LOCALE users */
306
    setlocale(LC_COLLATE, "");/*- alphabetically sorting */
307
    setlocale(LC_TIME, "");/*- names and defaults for date-time formats */
18798 martyn 308
    #endif 
18636 martyn 309
 
13974 hornik 310
    /* Initialise libglade */
311
    glade_gnome_init();
312
 
313
    /* Gnome GUI preferences */
314
    R_gnome_prefs_gui_load();
315
 
316
    R_ShowQueuedMessages();
317
 
318
    R_SetParams(Rp);
15427 hornik 319
    if(!Rp->NoRenviron) {
320
	process_site_Renviron();
321
	process_user_Renviron();
322
    }
13974 hornik 323
 
324
    R_Interactive = isatty(0);
325
    if((R_Home = R_HomeDir()) == NULL) {
326
	R_Suicide("R home directory is not defined");
327
    }
328
    glade_interface_file = g_strdup_printf(GLADE_INTERFACE_FILE, R_Home);
329
    if(stat(glade_interface_file, &sb) == -1) {
330
	R_Suicide("GNOME interface file not found");
331
    }
332
 
333
/*
334
 *  Since users' expectations for save/no-save will differ, we decided
335
 *  that they should be forced to specify in the non-interactive case.
336
 */
337
    if (!R_Interactive && SaveAction != SA_SAVE && SaveAction != SA_NOSAVE)
338
	R_Suicide("you must specify `--save', `--no-save' or `--vanilla'");
339
 
340
    if ((R_HistoryFile = getenv("R_HISTFILE")) == NULL)
341
	R_HistoryFile = ".Rhistory";
342
    R_HistorySize = 512;
343
    if ((p = getenv("R_HISTSIZE"))) {
20327 hornik 344
	value = R_Decode2Long(p, &ierr);
13974 hornik 345
	if (ierr != 0 || value < 0)
346
	    fprintf(stderr, "WARNING: invalid R_HISTSIZE ignored;");
347
	else
348
	    R_HistorySize = value;
349
    }
350
 
351
    /* create console */
352
    R_gtk_terminal_new();
353
 
354
    /* restore command history */
355
    if(R_RestoreHistory)
356
	gtk_console_restore_history(GTK_CONSOLE(R_gtk_terminal_text), 
357
				    R_HistoryFile, R_HistorySize, NULL);
358
 
359
    fpu_setup(1);
360
 
361
 
362
    /* start main loop */
363
    mainloop();
364
    /*++++++  in ../main/main.c */
365
}