/* Create new module */ static void menubar_new_mod_cb(GtkWidget * widget, gpointer data) { gchar *modnam = NULL; gchar *modfile; gchar *confdir; GtkWidget *module = NULL; (void)widget; (void)data; sat_log_log(SAT_LOG_LEVEL_DEBUG, _("%s: Starting new module configurator..."), __func__); modnam = mod_cfg_new(); if (modnam) { sat_log_log(SAT_LOG_LEVEL_DEBUG, _("%s: New module name is %s."), __func__, modnam); confdir = get_modules_dir(); modfile = g_strconcat(confdir, G_DIR_SEPARATOR_S, modnam, ".mod", NULL); g_free(confdir); /* create new module */ module = gtk_sat_module_new(modfile); if (module == NULL) { GtkWidget *dialog; dialog = gtk_message_dialog_new(GTK_WINDOW(app), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Could not open %s. " "Please examine the log messages " "for details."), modnam); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } else { mod_mgr_add_module(module, TRUE); } g_free(modnam); g_free(modfile); } else { sat_log_log(SAT_LOG_LEVEL_DEBUG, _("%s: New module config cancelled."), __func__); } }
/** \brief Close and permanently delete module. * * This function is called when the user selects the delete menu * item in the GtkSatModule popup menu. First it will close the module * with gtk_sat_module_close_cb, which will close the current module, * whereafter the module file will be deleted from the disk. */ static void delete_cb (GtkWidget *menuitem, gpointer data) { gchar *file; GtkWidget *dialog; gchar *moddir; moddir = get_modules_dir (); file = g_strconcat (moddir, G_DIR_SEPARATOR_S, GTK_SAT_MODULE (data)->name, ".mod", NULL); g_free (moddir); gtk_sat_module_close_cb (menuitem, data); /* ask user to confirm removal */ dialog = gtk_message_dialog_new_with_markup (NULL, //GTK_WINDOW (parent), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("This operation will permanently delete\n<b>%s</b>\n"\ "from the disk.\nDo you you want to proceed?"), file); switch (gtk_dialog_run (GTK_DIALOG (dialog))) { case GTK_RESPONSE_YES: if (g_remove (file)) { sat_log_log (SAT_LOG_LEVEL_ERROR, _("%s:%d: Failed to delete %s."), __FILE__, __LINE__, file); } else { sat_log_log (SAT_LOG_LEVEL_ERROR, _("%s:%d: %s deleted permanently."), __FILE__, __LINE__, file); } break; default: break; } gtk_widget_destroy (dialog); g_free (file); }
static void menubar_open_mod_cb(GtkWidget * widget, gpointer data) { gchar *modnam = NULL; gchar *modfile; gchar *confdir; GtkWidget *module = NULL; (void)widget; (void)data; sat_log_log(SAT_LOG_LEVEL_DEBUG, _("%s: Open existing module..."), __func__); modnam = select_module(); if (modnam) { sat_log_log(SAT_LOG_LEVEL_DEBUG, _("%s: Open module %s."), __func__, modnam); confdir = get_modules_dir(); modfile = g_strconcat(confdir, G_DIR_SEPARATOR_S, modnam, ".mod", NULL); g_free(confdir); /* create new module */ module = gtk_sat_module_new(modfile); if (module == NULL) { /* mod manager could not create the module */ GtkWidget *dialog; dialog = gtk_message_dialog_new(GTK_WINDOW(app), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Could not open %s. " "Please examine the log " "messages for details."), modnam); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } else { /* if module state was window or user does not want to restore the state of the modules, pack the module into the notebook */ if ((GTK_SAT_MODULE(module)->state == GTK_SAT_MOD_STATE_DOCKED) || !sat_cfg_get_bool(SAT_CFG_BOOL_MOD_STATE)) { mod_mgr_add_module(module, TRUE); } else { mod_mgr_add_module(module, FALSE); create_module_window(module); } } g_free(modnam); g_free(modfile); } else { sat_log_log(SAT_LOG_LEVEL_DEBUG, _("%s: Open module cancelled."), __func__); } }
static gchar *select_module() { GtkWidget *dialog; /* the dialog window */ GtkWidget *modlist; /* the treeview widget */ GtkListStore *liststore; /* the list store data structure */ GtkCellRenderer *renderer; GtkTreeViewColumn *column; GtkTreeIter item; /* new item added to the list store */ GtkTreeSelection *selection; GtkTreeModel *selmod; GtkTreeModel *listtreemodel; GtkWidget *swin; GDir *dir = NULL; /* directory handle */ GError *error = NULL; /* error flag and info */ gchar *dirname; /* directory name */ const gchar *filename; /* file name */ gchar **buffv; guint count = 0; /* create and fill data model */ liststore = gtk_list_store_new(1, G_TYPE_STRING); /* scan for .mod files in the user config directory and add the contents of each .mod file to the list store */ dirname = get_modules_dir(); dir = g_dir_open(dirname, 0, &error); if (dir) { sat_log_log(SAT_LOG_LEVEL_DEBUG, _("%s:%s: Scanning directory %s for modules."), __FILE__, __func__, dirname); while ((filename = g_dir_read_name(dir))) { if (g_str_has_suffix(filename, ".mod")) { /* strip extension and add to list */ buffv = g_strsplit(filename, ".mod", 0); gtk_list_store_append(liststore, &item); gtk_list_store_set(liststore, &item, 0, buffv[0], -1); g_strfreev(buffv); count++; } } } else { sat_log_log(SAT_LOG_LEVEL_ERROR, _("%s:%d: Failed to open module dir %s (%s)"), __FILE__, __LINE__, dirname, error->message); g_clear_error(&error); } g_free(dirname); g_dir_close(dir); if (count < 1) { /* tell user that there are no modules, try "New" instead */ dialog = gtk_message_dialog_new(GTK_WINDOW(app), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, _("You do not have any modules " "set up yet. Please use File->New " "in order to create a module.")); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); return NULL; } /* create tree view */ modlist = gtk_tree_view_new(); listtreemodel = GTK_TREE_MODEL(liststore); gtk_tree_view_set_model(GTK_TREE_VIEW(modlist), listtreemodel); g_object_unref(liststore); /* connecting row activated signal postponed so that we can attach dialog window */ swin = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); /* sort the tree by name */ gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(listtreemodel), 0, compare_func, NULL, NULL); gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(listtreemodel), 0, GTK_SORT_ASCENDING); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Module"), renderer, "text", 0, NULL); gtk_tree_view_insert_column(GTK_TREE_VIEW(modlist), column, -1); gtk_widget_show(modlist); /* create dialog */ dialog = gtk_dialog_new_with_buttons(_("Select a module"), GTK_WINDOW(app), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL); gtk_window_set_default_size(GTK_WINDOW(dialog), -1, 200); gtk_container_add(GTK_CONTAINER(swin), modlist); gtk_widget_show(swin); gtk_box_pack_start(GTK_BOX (gtk_dialog_get_content_area(GTK_DIALOG(dialog))), swin, TRUE, TRUE, 0); /* double clicking in list will open clicked module */ g_signal_connect(modlist, "row-activated", G_CALLBACK(select_module_row_activated_cb), dialog); switch (gtk_dialog_run(GTK_DIALOG(dialog))) { /* user pressed OK */ case GTK_RESPONSE_OK: selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(modlist)); if (gtk_tree_selection_get_selected(selection, &selmod, &item)) { gtk_tree_model_get(selmod, &item, 0, &dirname, -1); sat_log_log(SAT_LOG_LEVEL_DEBUG, _("%s:%s: Selected module is: %s"), __FILE__, __func__, dirname); } else { sat_log_log(SAT_LOG_LEVEL_ERROR, _("%s:%s: No selection is list of modules."), __FILE__, __func__); dirname = NULL; } break; /* everything else is regarded as CANCEL */ default: dirname = NULL; break; } gtk_widget_destroy(dialog); return dirname; }
/** \brief Create and initialise module manger. * \return The main module container widget (GtkNotebook). * * This function creates and initialises the module manager widget, which * consist of a GtkNotebook container. Before returning the container to the * caller, the function checks whether any modules should be restored (ie. * openend), if yes, it creates them and adds them to the notebook. * */ GtkWidget * mod_mgr_create (void) { gchar *openmods = NULL; gchar **mods; gint count,i; GtkWidget *module; gchar *modfile; gchar *confdir; /* create notebook */ nbook = gtk_notebook_new (); gtk_notebook_set_scrollable (GTK_NOTEBOOK (nbook), TRUE); gtk_notebook_popup_enable (GTK_NOTEBOOK (nbook)); g_object_set (G_OBJECT (nbook), "homogeneous", TRUE, NULL); g_signal_connect (G_OBJECT (nbook), "switch-page", G_CALLBACK (switch_page_cb), NULL); /* get list of modules which should be open */ openmods = sat_cfg_get_str (SAT_CFG_STR_OPEN_MODULES); if (openmods) { mods = g_strsplit (openmods, ";", 0); count = g_strv_length (mods); for (i = 0; i < count; i++) { /* get data file name */ confdir = get_modules_dir (); modfile = g_strconcat (confdir, G_DIR_SEPARATOR_S, mods[i], ".mod", NULL); g_free (confdir); /* create module */ module = gtk_sat_module_new (modfile); if (IS_GTK_SAT_MODULE (module)) { /* if module state was window or user does not want to restore the state of the modules, pack the module into the notebook */ if ((GTK_SAT_MODULE (module)->state == GTK_SAT_MOD_STATE_DOCKED) || !sat_cfg_get_bool (SAT_CFG_BOOL_MOD_STATE)) { mod_mgr_add_module (module, TRUE); } else { mod_mgr_add_module (module, FALSE); create_module_window (module); } } else { sat_log_log (SAT_LOG_LEVEL_ERROR, _("%s: Failed to restore %s"), __FUNCTION__, mods[i]); } g_free (modfile); } g_strfreev (mods); g_free (openmods); /* disable tabs if only one page in notebook */ if ((gtk_notebook_get_n_pages (GTK_NOTEBOOK(nbook))) == 1) { gtk_notebook_set_show_tabs (GTK_NOTEBOOK (nbook), FALSE); } else { gtk_notebook_set_show_tabs (GTK_NOTEBOOK (nbook), TRUE); } } else { sat_log_log (SAT_LOG_LEVEL_MSG, _("%s: No modules have to be restored."), __FUNCTION__); } return nbook; }
/** \brief Clone module. * * This function is called when the user selects the clone * menu item in the GtkSatModule popup menu. the function creates * a dialog in which the user is asked for a new module name. * When a valid module name is available and the user clicks on OK, * an exact copy of the currwent module is created. * By default, the nes module will be opened but the user has the * possibility to override this in the dialog window. * */ static void clone_cb (GtkWidget *menuitem, gpointer data) { GtkWidget *dialog; GtkWidget *entry; GtkWidget *label; GtkWidget *toggle; GtkWidget *vbox; GtkAllocation aloc; guint response; GtkSatModule *module = GTK_SAT_MODULE (data); GtkSatModule *newmod; gchar *source,*target; gchar *icon; /* icon file name */ gchar *title; /* window title */ (void) menuitem; /* avoid unused parameter compiler warning */ dialog = gtk_dialog_new_with_buttons (_("Clone Module"), GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (module))), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); /* label */ label = gtk_label_new (_("Name of new module:")); vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_box_pack_start (GTK_BOX(vbox), label, FALSE, FALSE, 0); /* name entry */ entry = gtk_entry_new (); gtk_entry_set_max_length (GTK_ENTRY (entry), 25); gtk_entry_set_text (GTK_ENTRY (entry), module->name); gtk_widget_set_tooltip_text (entry, _("Enter a short name for this module.\n"\ "Allowed characters: 0..9, a..z, A..Z, - and _")); /*not sure what to do with the old private tip the new api does not like them _("The name will be used to identify the module " \ "and it is also used a file name for saving the data."\ "Max length is 25 characters.")); */ /* attach changed signal so that we can enable OK button when a proper name has been entered oh, btw. disable OK button to begin with.... */ gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, FALSE); g_signal_connect (entry, "changed", G_CALLBACK (name_changed), dialog); gtk_box_pack_start (GTK_BOX( vbox ), entry, FALSE, FALSE, 0); /* check button */ toggle = gtk_check_button_new_with_label (_("Open module when created")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), TRUE); gtk_widget_set_tooltip_text ( toggle, _("If checked, the new module will be opened "\ "after it has been created")); gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 20); gtk_widget_show_all (vbox); /* run dialog */ response = gtk_dialog_run (GTK_DIALOG (dialog)); switch (response) { case GTK_RESPONSE_OK: sat_log_log (SAT_LOG_LEVEL_INFO, _("%s:%d: Cloning %s => %s"), __FILE__, __LINE__, module->name, gtk_entry_get_text (GTK_ENTRY (entry))); /* build full file names */ gchar *moddir = get_modules_dir (); source = g_strconcat (moddir, G_DIR_SEPARATOR_S, module->name, ".mod", NULL); target = g_strconcat (moddir, G_DIR_SEPARATOR_S, gtk_entry_get_text (GTK_ENTRY (entry)), ".mod", NULL); g_free (moddir); /* copy file */ if (gpredict_file_copy (source, target)) { sat_log_log (SAT_LOG_LEVEL_ERROR, _("%s:%d: Failed to clone %s."), __FILE__, __LINE__, module->name); } else { sat_log_log (SAT_LOG_LEVEL_INFO, _("%s:%d: Successfully cloned %s."), __FILE__, __LINE__, module->name); /* open module if requested */ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle))) { newmod = GTK_SAT_MODULE (gtk_sat_module_new (target)); newmod->state = module->state; if (newmod->state == GTK_SAT_MOD_STATE_DOCKED) { /* add to module manager */ mod_mgr_add_module (GTK_WIDGET (newmod), TRUE); } else { /* add to module manager */ mod_mgr_add_module (GTK_WIDGET (newmod), FALSE); /* create window */ newmod->win = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (newmod->win), newmod->name); title = g_strconcat (_("GPREDICT: "), newmod->name, " (", newmod->qth->name, ")", NULL); gtk_window_set_title (GTK_WINDOW (newmod->win), title); g_free (title); /* use size of source module */ gtk_widget_get_allocation(GTK_WIDGET (module), &aloc); gtk_window_set_default_size (GTK_WINDOW (newmod->win), aloc.width, aloc.height); g_signal_connect (G_OBJECT (newmod->win), "configure_event", G_CALLBACK (module_window_config_cb), newmod); /* add module to window */ gtk_container_add (GTK_CONTAINER (newmod->win), GTK_WIDGET (newmod)); /* window icon */ icon = icon_file_name ("gpredict-icon.png"); if (g_file_test (icon, G_FILE_TEST_EXISTS)) { gtk_window_set_icon_from_file (GTK_WINDOW (newmod->win), icon, NULL); } g_free (icon); /* show window */ gtk_widget_show_all (newmod->win); } } } /* clean up */ g_free (source); g_free (target); break; case GTK_RESPONSE_CANCEL: sat_log_log (SAT_LOG_LEVEL_INFO, _("%s:%d: Cloning cancelled by user."), __FILE__, __LINE__); break; default: sat_log_log (SAT_LOG_LEVEL_INFO, _("%s:%d: Cloning interrupted."), __FILE__, __LINE__); break; } gtk_widget_destroy (dialog); }