/* menu.c - Created by Giampiero Caprino This file is part of Train Director Train Director is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Train Director 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 General Public License for more details. You should have received a copy of the GNU General Public License along with Train Director; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include "ask.h" #include "gtkopen.h" #include "trsim.h" #ifdef WIN32 #include #endif extern int is_windows; char project_name[256]; static GtkItemFactory *item_factory; static GtkItemFactoryEntry items[] = { { "/File/Open recent/1 -",NULL,NULL,1,NULL}, { "/File/Open recent/2 --",NULL,NULL,2,NULL}, { "/File/Open recent/3 ---",NULL,NULL,3,NULL}, }; void refresh_recent(void); /* remove filename from an absolute path */ #if 0 /* not needed, since we're using g_dirname() */ char *remove_flname(char *flname) { int i; for(i = strlen(flname); i > 0; i--) { if(flname[i] == '/') { flname[i + 1] = 0; return flname; } } } #endif /* 0 */ static void open_cmd(GtkWidget *w, gpointer data) { char *p; char buff[256]; char cmd[256]; #if defined(__unix__) char path[256]; if(data) { strcpy(buff, last_file[(GPOINTER_TO_INT(data)) - 1]); strcpy(path, buff); curpath = g_dirname(path); if(strstr(buff, ".sav")) sprintf(cmd, "restore %s", buff); else sprintf(cmd, "open %s", buff); remove_ext(cmd); trainsim_cmd(cmd); return; } #endif if(!project_name[0]) { strcpy(project_name, "default"); getcwd(buff, sizeof(buff)); for(p = buff + strlen(buff); p > buff; --p) { if(*p == '/' || *p == '\\' || *p == ':') { ++p; strcpy(project_name, p); break; } } } if(openFileDialog(project_name)) { #if defined(__unix__) update_last_file(project_name); save_last(); refresh_recent(); #endif if(strstr(project_name, ".sav")) sprintf(buff, "restore %s", project_name); else sprintf(buff, "open %s", project_name); remove_ext(buff); trainsim_cmd(buff); } } /* convert '/' to '\' to prevent problem with gtkitemfactory menu label*/ char *slash(char *s) { static char p[256]; int j = 0; while(*s) { p[j++] = (*s == '/') ? '\\' : *s; ++s; } p[j] = 0; return p; } /* refresh "open recent" menu */ void refresh_recent(void) { gchar *file; int i; gint n_items = sizeof (items) / sizeof (items[0]); /* delete old item in "open recent" menu */ gtk_item_factory_delete_entries(item_factory,n_items, items); /* refresh menu */ for(i = 0; i < 3; i++) { if(!last_file[i][0]) continue; file = g_strdup_printf("%s/%d %s", L("/File/Open recent"), i + 1, slash(last_file[i])); items[i].path = file; items[i].path[strlen(file)] = '\0'; items[i].callback=open_cmd; } gtk_item_factory_create_items(item_factory, n_items, items, items); } static void save_cmd(GtkWidget *w, gpointer data ) { char buff[256]; if(is_windows && saveFileDialog(project_name)) { sprintf(buff, "save %s", project_name); remove_ext(buff); trainsim_cmd(buff); } else trainsim_cmd("save tmp"); } static void savegame_cmd(GtkWidget *w, gpointer data ) { char buff[256]; if(is_windows && saveFileDialog(project_name)) { sprintf(buff, "savegame %s", project_name); remove_ext(buff); trainsim_cmd(buff); } else trainsim_cmd("savegame saved"); } static void restore_cmd(GtkWidget *w, gpointer data ) { char buff[256]; if(cont(L("Are you sure you want to restore\nthe simulation to its saved state?")) != ANSWER_YES) return; sprintf(buff, "restore %s", is_windows ? project_name : "saved"); remove_ext(buff); trainsim_cmd(buff); } static void new_cmd(GtkWidget *w, gpointer data ) { if(cont(L("This will delete the current layout.\nAre you sure you want to continue?")) != ANSWER_YES) return; trainsim_cmd("new"); } static void about_cmd(GtkWidget *w, gpointer data ) { trainsim_cmd("about"); } static void quit_cmd(GtkWidget *w, gpointer data ) { trainsim_cmd("quit"); } static void start_cmd(GtkWidget *w, gpointer data ) { if(frply) { fclose(frply); frply = 0; do_alert(L("Reply interrupted.")); return; } trainsim_cmd("run"); } static void edit_cmd(GtkWidget *w, gpointer data ) { trainsim_cmd(editing ? "noedit" : "edit"); } static void new_train_cmd(GtkWidget *w, gpointer data ) { trainsim_cmd("newtrain"); } static void log_cmd(GtkWidget *w, gpointer data ) { trainsim_cmd("log"); } static void stationsched_cmd(GtkWidget *w, gpointer data ) { trainsim_cmd("stationsched"); } static void graph_cmd(GtkWidget *w, gpointer data ) { trainsim_cmd("graph"); } static void itin_cmd(GtkWidget *w, gpointer data ) { trainsim_cmd("itinerary"); } static void info_cmd(GtkWidget *w, gpointer data ) { trainsim_cmd("info"); } static void options_cmd(GtkWidget *w, gpointer data ) { trainsim_cmd("options"); } static void restart_cmd(GtkWidget *w, gpointer data ) { trainsim_cmd("t0"); } static void slow_cmd(GtkWidget *w, gpointer data ) { trainsim_cmd("slow"); } static void fast_cmd(GtkWidget *w, gpointer data ) { trainsim_cmd("fast"); } static void open_sigs_cmd(GtkWidget *w, gpointer data ) { trainsim_cmd("greensigs"); } static void performance_cmd(GtkWidget *w, gpointer data ) { trainsim_cmd("performance"); } static void replay_cmd(GtkWidget *w, gpointer data ) { char *p; char buff[256]; char buff1[256]; strcpy(buff1, project_name); if(!buff1[0]) strcpy(buff1, "default"); if(openFileDialog(buff1)) { sprintf(buff, "replay %s", buff1); remove_ext(buff); trainsim_cmd(buff); } } /* This is the GtkItemFactoryEntry structure used to generate new menus. Item 1: The menu path. The letter after the underscore indicates an accelerator key once the menu is open. Item 2: The accelerator key for the entry Item 3: The callback function. Item 4: The callback action. This changes the parameters with which the function is called. The default is 0. Item 5: The item type, used to define what kind of an item it is. Here are the possible values: NULL -> "" "" -> "" "" -> create a title item "<Item>" -> create a simple item "<CheckItem>" -> create a check item "<ToggleItem>" -> create a toggle item "<RadioItem>" -> create a radio item <path> -> path of a radio item to link against "<Separator>" -> create a separator "<Branch>" -> create an item to hold sub items (optional) "<LastBranch>" -> create a right justified branch */ char *en_menu_items[] = { "/_File", /* 0 */ "/File/_Open", "/File/Open re_cent", "/File/_Save Game", "/File/_Restore", "/File/Save _As", /* 5 */ "/File/_Log", "/File/_Replay", "/File/About...", "/File/Quit", "/Edit/_Edit", /* 10 */ "/Edit/_New Train", "/Edit/Itinerary", "/Edit/_Save Layout", "/Edit/_Preferences", "/Edit/_New", /* 15 */ "/Edit/_Info", "/_Run", "/Run/_Start", "/Run/View _Graph", "/Run/Restart", /* 20 */ "/Run/_Fast", "/Run/S_low", "/Run/S_tation schedule", "/Run/Set sig. to green", "/Run/Performance", /* 25 */ NULL }; static GtkItemFactoryEntry menu_items[] = { { "/_File", NULL, NULL, 0, "<Branch>" }, { "/File/_Open", "<control>O", open_cmd, 0, NULL }, #if defined(__unix__) { "/File/Open re_cent",NULL,NULL,0,"<Branch>"}, #endif { "/File/_Save Game","<control>S", savegame_cmd, 0, NULL }, { "/File/_Restore", NULL, restore_cmd, 0, NULL }, #if 0 { "/File/Save _As", NULL, NULL, 0, NULL }, #endif { "/File/sep0", NULL, NULL, 0, "<Separator>" }, { "/File/_Log", NULL, log_cmd, 0, NULL }, { "/File/_Replay", NULL, replay_cmd, 0, NULL }, { "/File/sep1", NULL, NULL, 0, "<Separator>" }, { "/File/About...", NULL, about_cmd, 0, NULL }, { "/File/sep1", NULL, NULL, 0, "<Separator>" }, { "/File/Quit", "<control>Q", quit_cmd, 0, NULL }, { "/_Edit", NULL, NULL, 0, "<Branch>" }, { "/Edit/_Edit", "<control>E", edit_cmd, 0, NULL }, { "/Edit/_New Train", NULL, new_train_cmd, 0, NULL }, { "/Edit/Itinerary", NULL, itin_cmd, 0, NULL }, { "/Edit/_Save Layout", NULL, save_cmd, 0, NULL }, { "/Edit/_Preferences",NULL, options_cmd, 0, NULL }, { "/Edit/_New", "<control>N", new_cmd, 0, NULL }, { "/Edit/_Info", "<control>I", info_cmd, 0, NULL }, { "/_Run", NULL, NULL, 0, "<Branch>" }, { "/Run/_Start", "<control>S", start_cmd, 0, NULL }, /* { "/Run/View _Blocks", "<control>B", blocks_cmd, 0, NULL }, { "/Run/View S_peed", "<control>P", speed_cmd, 0, NULL }, { "/Run/View T_raditional", "<control>T", traditional_cmd, 0, NULL }, */ { "/Run/View _Graph", "<control>G", graph_cmd, 0, NULL }, { "/Run/Restart", NULL, restart_cmd, 0, NULL }, { "/Run/_Fast", "<control>X", fast_cmd, 0, NULL }, { "/Run/S_low", "<control>Z", slow_cmd, 0, NULL }, { "/Run/S_tation schedule", NULL, stationsched_cmd, 0, NULL }, { "/Run/Set sig. to green", NULL, open_sigs_cmd, 0, NULL }, { "/Run/Performance", NULL, performance_cmd, 0, NULL }, /* { "/Run/_Alert Sound", "<control>A", alert_cmd, 0, NULL }, */ #if 0 { "/_Help", NULL, NULL, 0, "<LastBranch>" }, { "/_Help/About", NULL, NULL, 0, NULL }, #endif }; void get_main_menu( GtkWidget *window, GtkWidget **menubar ) { GtkAccelGroup *accel_group; gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]); #if defined(__unix__) gint n_items = sizeof (items) / sizeof (items[0]); gchar *file; #endif int i, j; accel_group = gtk_accel_group_new (); /* This function initializes the item factory. Param 1: The type of menu - can be GTK_TYPE_MENU_BAR, GTK_TYPE_MENU, or GTK_TYPE_OPTION_MENU. Param 2: The path of the menu. Param 3: A pointer to a gtk_accel_group. The item factory sets up the accelerator table while generating menus. */ item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", accel_group); for(i = 0; i < nmenu_items; ++i) menu_items[i].path = L(menu_items[i].path); /* This function generates the menu items. Pass the item factory, the number of items in the array, the array itself, and any callback data for the the menu items. */ gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL); #if defined(__unix__) load_last(); for(i = 0; i < 3; i++) { if(last_file[i][0] != '\0') { file = g_strdup_printf("%s/%d %s", L("/File/Open recent"), i + 1, slash(last_file[i])); items[i].path = file; items[i].callback = open_cmd; } else items[i].path = L(items[i].path); } gtk_item_factory_create_items(item_factory, n_items, items, items); #endif /* Attach the new accelerator group to the window. */ gtk_window_add_accel_group (GTK_WINDOW (window), accel_group); if (menubar) /* Finally, return the actual menu bar created by the item factory. */ *menubar = gtk_item_factory_get_widget (item_factory, "<main>"); }