void sc_speller_reinit_enchant_dict(void) { const gchar *lang = sc_info->default_language; /* Release a previous dict object */ if (sc_speller_dict != NULL) enchant_broker_free_dict(sc_speller_broker, sc_speller_dict); #if HAVE_ENCHANT_1_5 { const gchar *old_path; gchar *new_path; /* add custom dictionary path for myspell (primarily used on Windows) */ old_path = enchant_broker_get_param(sc_speller_broker, "enchant.myspell.dictionary.path"); if (old_path != NULL) new_path = g_strconcat( old_path, G_SEARCHPATH_SEPARATOR_S, sc_info->dictionary_dir, NULL); else new_path = sc_info->dictionary_dir; enchant_broker_set_param(sc_speller_broker, "enchant.myspell.dictionary.path", new_path); if (new_path != sc_info->dictionary_dir) g_free(new_path); } #endif create_dicts_array(); /* Check if the stored default dictionary is (still) available, fall back to the first * one in the list if not */ if (! NZV(lang) || ! check_default_lang()) { if (sc_info->dicts->len > 0) { lang = g_ptr_array_index(sc_info->dicts, 0); g_warning("Stored language ('%s') could not be loaded. Falling back to '%s'", sc_info->default_language, lang); } else g_warning("Stored language ('%s') could not be loaded.", sc_info->default_language); } /* Request new dict object */ if (NZV(lang)) sc_speller_dict = enchant_broker_request_dict(sc_speller_broker, lang); else sc_speller_dict = NULL; if (sc_speller_dict == NULL) { broker_init_failed(); gtk_widget_set_sensitive(sc_info->menu_item, FALSE); } else { gtk_widget_set_sensitive(sc_info->menu_item, TRUE); } }
static void on_document_save(G_GNUC_UNUSED GObject *object, GeanyDocument *doc) { gchar *f; g_return_if_fail(NZV(doc->real_path)); f = utils_build_path(app->configdir, "filetype_extensions.conf", NULL); if (utils_str_equal(doc->real_path, f)) filetypes_reload_extensions(); g_free(f); f = utils_build_path(app->configdir, GEANY_FILEDEFS_SUBDIR, "filetypes.common", NULL); if (utils_str_equal(doc->real_path, f)) { guint i; /* Note: we don't reload other filetypes, even though the named styles may have changed. * The user can do this manually with 'Tools->Reload Configuration' */ filetypes_load_config(GEANY_FILETYPES_NONE, TRUE); foreach_document(i) document_reload_config(documents[i]); } g_free(f); }
static gboolean in_vc_git(const gchar * filename) { gint exit_code; const gchar *argv[] = { "git", "ls-files", "--", NULL, NULL }; gchar *dir; gchar *base_name; gboolean ret = FALSE; gchar *std_output; if (!find_dir(filename, ".git", TRUE)) return FALSE; if (g_file_test(filename, G_FILE_TEST_IS_DIR)) return TRUE; dir = g_path_get_dirname(filename); base_name = g_path_get_basename(filename); argv[3] = base_name; exit_code = execute_custom_command(dir, (const gchar **) argv, NULL, &std_output, NULL, dir, NULL, NULL); if (NZV(std_output)) { ret = TRUE; g_free(std_output); } g_free(base_name); g_free(dir); return ret; }
static gboolean in_vc_bzr(const gchar * filename) { const gchar *argv[] = { "bzr", "log", NULL, NULL }; gchar *dir; gchar *base_name; gboolean ret = FALSE; gchar *std_output; if (!find_dir(filename, ".bzr", TRUE)) return FALSE; if (g_file_test(filename, G_FILE_TEST_IS_DIR)) return TRUE; dir = g_path_get_dirname(filename); base_name = g_path_get_basename(filename); argv[2] = base_name; execute_custom_command(dir, (const gchar **) argv, NULL, &std_output, NULL, filename, NULL, NULL); if (NZV(std_output)) { ret = TRUE; } g_free(std_output); g_free(base_name); g_free(dir); return ret; }
static void dictionary_dir_button_clicked_cb(GtkButton *button, gpointer item) { GtkWidget *dialog; gchar *text; /* initialise the dialog */ dialog = gtk_file_chooser_dialog_new(_("Select Directory"), NULL, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); text = utils_get_locale_from_utf8(gtk_entry_get_text(GTK_ENTRY(item))); if (NZV(text)) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), text); /* run it */ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { gchar *utf8_filename, *tmp; tmp = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); utf8_filename = utils_get_utf8_from_locale(tmp); gtk_entry_set_text(GTK_ENTRY(item), utf8_filename); g_free(utf8_filename); g_free(tmp); } gtk_widget_destroy(dialog); }
/* Strip punctuation and white space, more or less Unicode-safe. * The offset of the start of the word is stored in offset if non-NULL. */ static gchar *strip_word(const gchar *word_to_check, gint *result_offset) { gunichar c; gchar *word = g_strdup(word_to_check); gchar *word_start = word; gchar *word_end; gint offset = 0; gint word_len; gint new_word_len; /* strip from the left */ do { c = g_utf8_get_char_validated(word, -1); if (is_word_sep(c)) { /* skip this character */ word = g_utf8_next_char(word); } else break; } while (c != (gunichar) -1 && c != 0 && *word != '\0'); word_len = strlen(word_to_check); offset = word - word_start; new_word_len = word_len - offset; if (new_word_len <= 0) { /* empty or only punctuation in input string */ *result_offset = 0; g_free(word_start); return NULL; } /* move the string in-place and truncate it */ g_memmove(word_start, word, new_word_len); word = word_start; word[new_word_len] = '\0'; if (! NZV(word)) { g_free(word); return NULL; } /* strip from the right */ word_end = word + strlen(word); do { word_end = g_utf8_prev_char(word_end); c = g_utf8_get_char_validated(word_end, -1); if (is_word_sep(c)) { /* skip this character */ *word_end = '\0'; } else break; } while (c != (gunichar) -1 && word_end >= word); if (result_offset != NULL) *result_offset = offset; return word; }
static void add_page_header(DocInfo *dinfo, cairo_t *cr, gint width, gint page_nr) { gint ph_height = dinfo->line_height * 3; gchar *data; gchar *datetime; gchar *tmp_file_name = (dinfo->doc->file_name != NULL) ? dinfo->doc->file_name : GEANY_STRING_UNTITLED; gchar *file_name = (printing_prefs.page_header_basename) ? g_path_get_basename(tmp_file_name) : g_strdup(tmp_file_name); PangoLayout *layout = dinfo->layout; /* draw the frame */ cairo_set_line_width(cr, 0.3); cairo_set_source_rgb(cr, 0, 0, 0); cairo_rectangle(cr, 2, 2, width - 4, ph_height - 4); cairo_stroke(cr); /* width - 8: 2px between doc border and frame border, 2px between frame border and text * and this on left and right side, so (2 + 2) * 2 */ pango_layout_set_width(layout, (width - 8) * PANGO_SCALE); if ((g_utf8_strlen(file_name, -1) * dinfo->font_width) >= ((width - 4) - (dinfo->font_width * 2))) /* if the filename is wider than the available space on the line, skip parts of it */ pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_MIDDLE); data = g_strdup_printf("<b>%s</b>", file_name); pango_layout_set_markup(layout, data, -1); pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); cairo_move_to(cr, 4, dinfo->line_height * 0.5); pango_cairo_show_layout(cr, layout); g_free(data); g_free(file_name); data = g_strdup_printf(_("<b>Page %d of %d</b>"), page_nr + 1, dinfo->n_pages); pango_layout_set_markup(layout, data, -1); pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); cairo_move_to(cr, 4, dinfo->line_height * 1.5); pango_cairo_show_layout(cr, layout); g_free(data); datetime = utils_get_date_time(printing_prefs.page_header_datefmt, &(dinfo->print_time)); if (G_LIKELY(NZV(datetime))) { data = g_strdup_printf("<b>%s</b>", datetime); pango_layout_set_markup(layout, data, -1); pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT); cairo_move_to(cr, 2, dinfo->line_height * 1.5); pango_cairo_show_layout(cr, layout); g_free(data); } g_free(datetime); /* reset layout and re-position cairo context */ pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); pango_layout_set_ellipsize(layout, FALSE); pango_layout_set_justify(layout, FALSE); pango_layout_set_width(layout, width * PANGO_SCALE); cairo_move_to(cr, 0, dinfo->line_height * 3); }
void show_doc(const gchar * word, gint cmd_num) { GeanyDocument *doc; const gchar *ftype; gchar *command; gchar *tmp; gboolean intern; doc = document_get_current(); g_return_if_fail(doc != NULL && doc->file_name != NULL); ftype = doc->file_type->name; command = config_get_command(ftype, cmd_num, &intern); if (!NZV(command)) { g_free(command); return; } tmp = strstr(command, "%w"); if (tmp != NULL) { tmp[1] = 's'; setptr(command, g_strdup_printf(command, word)); } if (intern) { g_spawn_command_line_sync(command, &tmp, NULL, NULL, NULL); if (NZV(tmp)) { show_output(tmp, "*DOC*", NULL, doc->file_type->id); } else { show_doc(word, cmd_num + 1); } g_free(tmp); } else { g_spawn_command_line_async(command, NULL); } g_free(command); }
static gint sc_speller_check_word(GeanyDocument *doc, gint line_number, const gchar *word, gint start_pos, gint end_pos) { gsize n_suggs = 0; g_return_val_if_fail(sc_speller_dict != NULL, 0); g_return_val_if_fail(doc != NULL, 0); g_return_val_if_fail(word != NULL, 0); g_return_val_if_fail(start_pos >= 0 && end_pos >= 0, 0); if (! NZV(word)) return 0; /* ignore numbers or words starting with digits */ if (isdigit(*word)) return 0; /* ignore non-text */ if (! sc_speller_is_text(doc, start_pos)) return 0; /* early out if the word is spelled correctly */ if (enchant_dict_check(sc_speller_dict, word, -1) == 0) return 0; editor_indicator_set_on_range(doc->editor, GEANY_INDICATOR_ERROR, start_pos, end_pos); if (sc_info->use_msgwin && line_number != -1) { gsize j; gchar **suggs; GString *str; str = g_string_sized_new(256); suggs = enchant_dict_suggest(sc_speller_dict, word, -1, &n_suggs); if (suggs != NULL) { g_string_append_printf(str, "line %d: %s | ", line_number + 1, word); g_string_append(str, _("Try: ")); /* Now find the misspellings in the line, limit suggestions to a maximum of 15 (for now) */ for (j = 0; j < MIN(n_suggs, 15); j++) { g_string_append(str, suggs[j]); g_string_append_c(str, ' '); } msgwin_msg_add(COLOR_RED, line_number + 1, doc, "%s", str->str); if (suggs != NULL && n_suggs > 0) enchant_dict_free_string_list(sc_speller_dict, suggs); } g_string_free(str, TRUE); } return n_suggs; }
void vte_init(void) { if (vte_info.have_vte == FALSE) { /* vte_info.have_vte can be false even if VTE is compiled in, think of command line option */ geany_debug("Disabling terminal support"); return; } if (NZV(vte_info.lib_vte)) { module = g_module_open(vte_info.lib_vte, G_MODULE_BIND_LAZY); } #ifdef VTE_MODULE_PATH else { module = g_module_open(VTE_MODULE_PATH, G_MODULE_BIND_LAZY); } #endif if (module == NULL) { gint i; const gchar *sonames[] = { "libvte.so", "libvte.so.4", "libvte.so.8", "libvte.so.9", NULL }; for (i = 0; sonames[i] != NULL && module == NULL; i++) { module = g_module_open(sonames[i], G_MODULE_BIND_LAZY); } } if (module == NULL) { vte_info.have_vte = FALSE; geany_debug("Could not load libvte.so, embedded terminal support disabled"); return; } else { vf = g_new0(struct VteFunctions, 1); if (vte_register_symbols(module)) vte_info.have_vte = TRUE; else { vte_info.have_vte = FALSE; g_free(vf); /* FIXME: is closing the module safe? see vte_close() and test on FreeBSD */ /*g_module_close(module);*/ module = NULL; return; } } create_vte(); /* setup the F10 menu override (so it works before the widget is first realised). */ override_menu_key(); }
static void on_compiler_treeview_copy_all_activate(GtkMenuItem *menuitem, gpointer user_data) { GtkListStore *store = msgwindow.store_compiler; GtkTreeIter iter; GString *str = g_string_new(""); gint str_idx = 1; gboolean valid; switch (GPOINTER_TO_INT(user_data)) { case MSG_STATUS: store = msgwindow.store_status; str_idx = 0; break; case MSG_COMPILER: /* default values */ break; case MSG_MESSAGE: store = msgwindow.store_msg; str_idx = 3; break; } /* walk through the list and copy every line into a string */ valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter); while (valid) { gchar *line; gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, str_idx, &line, -1); if (NZV(line)) { g_string_append(str, line); g_string_append_c(str, '\n'); } g_free(line); valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter); } /* copy the string into the clipboard */ if (str->len > 0) { gtk_clipboard_set_text( gtk_clipboard_get(gdk_atom_intern("CLIPBOARD", FALSE)), str->str, str->len); } g_string_free(str, TRUE); }
static void on_comboboxType_changed(GtkComboBox * combobox, G_GNUC_UNUSED gpointer user_data) { gchar *from, *to; GtkWidget *cmd0 = ui_lookup_widget(GTK_WIDGET(combobox), "entryCommand0"); GtkWidget *cmd1 = ui_lookup_widget(GTK_WIDGET(combobox), "entryCommand1"); GtkWidget *intern = ui_lookup_widget(GTK_WIDGET(combobox), "cbIntern"); gchar *cmd0_txt = (gchar *) gtk_entry_get_text(GTK_ENTRY(cmd0)); gchar *cmd1_txt = (gchar *) gtk_entry_get_text(GTK_ENTRY(cmd1)); gboolean intern_b = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(intern)); GKeyFile *config = (GKeyFile *) g_object_get_data(G_OBJECT(combobox), "config"); from = g_object_get_data(G_OBJECT(combobox), "current"); to = gtk_combo_box_get_active_text(combobox); if (from != NULL) { if (NZV(cmd0_txt)) g_key_file_set_string(config, from, "command0", cmd0_txt); else g_key_file_remove_key(config, from, "command0", NULL); if (NZV(cmd1_txt)) g_key_file_set_string(config, from, "command1", cmd1_txt); else g_key_file_remove_key(config, from, "command1", NULL); g_key_file_set_boolean(config, from, "internal", intern_b); g_free(from); } g_object_set_data(G_OBJECT(combobox), "current", g_strdup(to)); cmd0_txt = utils_get_setting_string(config, to, "command0", ""); cmd1_txt = utils_get_setting_string(config, to, "command1", ""); intern_b = utils_get_setting_boolean(config, to, "internal", FALSE); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(intern), intern_b); gtk_entry_set_text(GTK_ENTRY(cmd0), cmd0_txt); gtk_entry_set_text(GTK_ENTRY(cmd1), cmd1_txt); }
/* get a :line:column specifier from the end of a filename (if present), * return the line/column values, and remove the specifier from the string * (Note that *line and *column must both be set to -1 initially) */ static void get_line_and_column_from_filename(gchar *filename, gint *line, gint *column) { gsize i; gint colon_count = 0; gboolean have_number = FALSE; gsize len; g_assert(*line == -1 && *column == -1); if (G_UNLIKELY(! NZV(filename))) return; /* allow to open files like "test:0" */ if (g_file_test(filename, G_FILE_TEST_EXISTS)) return; len = strlen(filename); for (i = len - 1; i >= 1; i--) { gboolean is_colon = filename[i] == ':'; gboolean is_digit = g_ascii_isdigit(filename[i]); if (! is_colon && ! is_digit) break; if (is_colon) { if (++colon_count > 1) break; /* bail on 2+ colons in a row */ } else colon_count = 0; if (is_digit) have_number = TRUE; if (is_colon && have_number) { gint number = atoi(&filename[i + 1]); filename[i] = '\0'; have_number = FALSE; *column = *line; *line = number; } if (*column >= 0) break; /* line and column are set, so we're done */ } }
void vte_init(void) { if (vte_info.have_vte == FALSE) { /* vte_info.have_vte can be false even if VTE is compiled in, think of command line option */ geany_debug("Disabling terminal support"); return; } if (NZV(vte_info.lib_vte)) { module = g_module_open(vte_info.lib_vte, G_MODULE_BIND_LAZY); } #ifdef VTE_MODULE_PATH else { module = g_module_open(VTE_MODULE_PATH, G_MODULE_BIND_LAZY); } #endif if (module == NULL) { gint i; const gchar *sonames[] = { "/opt/local/lib/libvte.dylib", NULL }; for (i = 0; sonames[i] != NULL && module == NULL; i++) { module = g_module_open(sonames[i], G_MODULE_BIND_LAZY); } } if (module == NULL) { vte_info.have_vte = FALSE; geany_debug("Could not load libvte.dylib, embedded terminal support disabled"); return; } else { vte_info.have_vte = TRUE; vf = g_new0(struct VteFunctions, 1); vte_register_symbols(module); } create_vte(); /* setup the F10 menu override (so it works before the widget is first realised). */ override_menu_key(); }
/* Parses a color in `str` which can be an HTML color (ex. #0099cc), * an abbreviated HTML color (ex. #09c) or a hex string color * (ex. 0x0099cc). The result of the conversion is stored into the * location pointed to by `clr`. */ static void parse_color(GKeyFile *kf, const gchar *str, gint *clr) { gint c; gchar hex_clr[9] = { 0 }; gchar *named_color = NULL; const gchar *start; g_return_if_fail(clr != NULL); if (G_UNLIKELY(! NZV(str))) return; named_color = g_key_file_get_string(kf, "named_colors", str, NULL); if (named_color) str = named_color; if (str[0] == '#') start = str + 1; else if (strlen(str) > 1 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) start = str + 2; else { geany_debug("Bad color '%s'", str); g_free(named_color); return; } if (strlen(start) == 3) { snprintf(hex_clr, 9, "0x%c%c%c%c%c%c", start[0], start[0], start[1], start[1], start[2], start[2]); } else snprintf(hex_clr, 9, "0x%s", start); g_free(named_color); c = utils_strtod(hex_clr, NULL, FALSE); if (c > -1) { *clr = c; return; } geany_debug("Bad color '%s'", str); }
/* simple file print using an external tool */ static void print_external(GeanyDocument *doc) { gchar *cmdline; if (doc->file_name == NULL) return; if (! NZV(printing_prefs.external_print_cmd)) { dialogs_show_msgbox(GTK_MESSAGE_ERROR, _("Please set a print command in the preferences dialog first.")); return; } cmdline = g_strdup(printing_prefs.external_print_cmd); utils_str_replace_all(&cmdline, "%f", doc->file_name); if (dialogs_show_question( _("The file \"%s\" will be printed with the following command:\n\n%s"), doc->file_name, cmdline)) { GError *error = NULL; #ifdef G_OS_WIN32 gchar *tmp_cmdline = g_strdup(cmdline); #else /* /bin/sh -c emulates the system() call and makes complex commands possible * but only needed on non-win32 systems due to the lack of win32's shell capabilities */ gchar *tmp_cmdline = g_strconcat("/bin/sh -c \"", cmdline, "\"", NULL); #endif if (! g_spawn_command_line_async(tmp_cmdline, &error)) { dialogs_show_msgbox(GTK_MESSAGE_ERROR, _("Printing of \"%s\" failed (return code: %s)."), doc->file_name, error->message); g_error_free(error); } else { msgwin_status_add(_("File %s printed."), doc->file_name); } g_free(tmp_cmdline); } g_free(cmdline); }
static void vte_drag_data_received(GtkWidget *widget, GdkDragContext *drag_context, gint UP(x), gint UP(y), GtkSelectionData *data, guint info, guint ltime) { if (info == TARGET_TEXT_PLAIN) { if (data->format == 8 && data->length > 0) vf->vte_terminal_feed_child(VTE_TERMINAL(widget), (const gchar*) data->data, data->length); } else { gchar *text = (gchar*) gtk_selection_data_get_text(data); if (NZV(text)) vf->vte_terminal_feed_child(VTE_TERMINAL(widget), text, strlen(text)); g_free(text); } gtk_drag_finish(drag_context, TRUE, FALSE, ltime); }
static void load_named_styles(GKeyFile *config, GKeyFile *config_home) { const gchar *scheme = editor_prefs.color_scheme; gboolean free_kf = FALSE; if (named_style_hash) g_hash_table_destroy(named_style_hash); /* reloading */ named_style_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); if (NZV(scheme)) { gchar *path, *path_home; path = g_build_path(G_DIR_SEPARATOR_S, app->datadir, GEANY_COLORSCHEMES_SUBDIR, scheme, NULL); path_home = g_build_path(G_DIR_SEPARATOR_S, app->configdir, GEANY_COLORSCHEMES_SUBDIR, scheme, NULL); if (g_file_test(path, G_FILE_TEST_EXISTS) || g_file_test(path_home, G_FILE_TEST_EXISTS)) { config = utils_key_file_new(path); config_home = utils_key_file_new(path_home); free_kf = TRUE; } /* if color scheme is missing, use default */ g_free(path); g_free(path_home); } /* first set default to the "default" named style */ add_named_style(config, "default"); read_named_style("default", &gsd_default); /* in case user overrides but not with both colors */ add_named_style(config_home, "default"); read_named_style("default", &gsd_default); get_named_styles(config); /* home overrides any system named style */ get_named_styles(config_home); if (free_kf) { g_key_file_free(config); g_key_file_free(config_home); } }
gchar *sc_speller_get_default_lang(void) { const gchar *lang = g_getenv("LANG"); gchar *result = NULL; if (NZV(lang)) { if (*lang == 'C' || *lang == 'c') lang = "en"; else { /* if we have something like de_DE.UTF-8, strip everything from the period to the end */ gchar *period = strchr(lang, '.'); if (period != NULL) result = g_strndup(lang, g_utf8_pointer_to_offset(lang, period)); } } else lang = "en"; return (result != NULL) ? result : g_strdup(lang); }
static void on_compiler_treeview_copy_activate(GtkMenuItem *menuitem, gpointer user_data) { GtkWidget *tv = NULL; GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter; gint str_idx = 1; switch (GPOINTER_TO_INT(user_data)) { case MSG_STATUS: tv = msgwindow.tree_status; str_idx = 0; break; case MSG_COMPILER: tv = msgwindow.tree_compiler; break; case MSG_MESSAGE: tv = msgwindow.tree_msg; str_idx = 3; break; } selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)); if (gtk_tree_selection_get_selected(selection, &model, &iter)) { gchar *string; gtk_tree_model_get(model, &iter, str_idx, &string, -1); if (NZV(string)) { gtk_clipboard_set_text(gtk_clipboard_get(gdk_atom_intern("CLIPBOARD", FALSE)), string, -1); } g_free(string); } }
/* Ensures utf8_dir exists and is writable and * set backup_dir to the locale encoded form of utf8_dir */ static gboolean backupcopy_set_backup_dir(const gchar *utf8_dir) { gchar *tmp; if (G_UNLIKELY(! NZV(utf8_dir))) return FALSE; tmp = utils_get_locale_from_utf8(utf8_dir); if (! g_path_is_absolute(tmp) || ! g_file_test(tmp, G_FILE_TEST_EXISTS) || ! g_file_test(tmp, G_FILE_TEST_IS_DIR)) { g_free(tmp); return FALSE; } /** TODO add utils_is_file_writeable() to the plugin API and make use of it **/ SETPTR(backupcopy_backup_dir, tmp); return TRUE; }
/* Constructs the project's base path which is used for "Make all" and "Execute". * The result is an absolute string in UTF-8 encoding which is either the same as * base path if it is absolute or it is built out of project file name's dir and base_path. * If there is no project or project's base_path is invalid, NULL will be returned. * The returned string should be freed when no longer needed. */ gchar *project_get_base_path(void) { GeanyProject *project = app->project; if (project && NZV(project->base_path)) { if (g_path_is_absolute(project->base_path)) return g_strdup(project->base_path); else { /* build base_path out of project file name's dir and base_path */ gchar *path; gchar *dir = g_path_get_dirname(project->file_name); if (utils_str_equal(project->base_path, "./")) return dir; else path = g_strconcat(dir, G_DIR_SEPARATOR_S, project->base_path, NULL); g_free(dir); return path; } } return NULL; }
static void backupcopy_dir_button_clicked_cb(GtkButton *button, gpointer item) { /** TODO add win32_show_pref_file_dialog to the plugin API and use it **/ /* #ifdef G_OS_WIN32 win32_show_pref_file_dialog(item); #else */ GtkWidget *dialog; gchar *text; /* initialize the dialog */ dialog = gtk_file_chooser_dialog_new(_("Select Directory"), NULL, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); text = utils_get_locale_from_utf8(gtk_entry_get_text(GTK_ENTRY(item))); if (NZV(text)) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), text); /* run it */ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { gchar *utf8_filename, *tmp; tmp = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); utf8_filename = utils_get_utf8_from_locale(tmp); gtk_entry_set_text(GTK_ENTRY(item), utf8_filename); g_free(utf8_filename); g_free(tmp); } gtk_widget_destroy(dialog); }
/* sets the project base path and the project file name according to the project name */ static void on_name_entry_changed(GtkEditable *editable, PropertyDialogElements *e) { gchar *base_path; gchar *file_name; gchar *name; const gchar *project_dir = local_prefs.project_file_path; if (entries_modified) return; name = gtk_editable_get_chars(editable, 0, -1); if (NZV(name)) { base_path = g_strconcat(project_dir, G_DIR_SEPARATOR_S, name, G_DIR_SEPARATOR_S, NULL); if (project_prefs.project_file_in_basedir) file_name = g_strconcat(project_dir, G_DIR_SEPARATOR_S, name, G_DIR_SEPARATOR_S, name, "." GEANY_PROJECT_EXT, NULL); else file_name = g_strconcat(project_dir, G_DIR_SEPARATOR_S, name, "." GEANY_PROJECT_EXT, NULL); } else { base_path = g_strconcat(project_dir, G_DIR_SEPARATOR_S, NULL); file_name = g_strconcat(project_dir, G_DIR_SEPARATOR_S, NULL); } g_free(name); gtk_entry_set_text(GTK_ENTRY(e->base_path), base_path); gtk_entry_set_text(GTK_ENTRY(e->file_name), file_name); entries_modified = FALSE; g_free(base_path); g_free(file_name); }
GtkWidget *plugin_configure(GtkDialog *dialog) { GtkWidget *label, *vbox, *combo, *check_type, *check_msgwin, *check_toolbar, *check_editor_menu; #ifdef HAVE_ENCHANT_1_5 GtkWidget *entry_dir, *hbox, *button, *image; #endif vbox = gtk_vbox_new(FALSE, 6); check_type = gtk_check_button_new_with_label(_("Check spelling while typing")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_type), sc_info->check_while_typing); gtk_box_pack_start(GTK_BOX(vbox), check_type, FALSE, FALSE, 6); check_toolbar = gtk_check_button_new_with_label( _("Show toolbar item to toggle spell checking")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_toolbar), sc_info->show_toolbar_item); gtk_box_pack_start(GTK_BOX(vbox), check_toolbar, FALSE, FALSE, 3); check_editor_menu = gtk_check_button_new_with_label( _("Show editor menu item to show spelling suggestions")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_editor_menu), sc_info->show_editor_menu_item); gtk_box_pack_start(GTK_BOX(vbox), check_editor_menu, FALSE, FALSE, 3); check_msgwin = gtk_check_button_new_with_label( _("Print misspelled words and suggestions in the messages window")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_msgwin), sc_info->use_msgwin); gtk_box_pack_start(GTK_BOX(vbox), check_msgwin, FALSE, FALSE, 3); label = gtk_label_new(_("Language to use for the spell check:")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 3); combo = gtk_combo_box_text_new(); populate_dict_combo(GTK_COMBO_BOX(combo)); if (sc_info->dicts->len > 20) gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(combo), 3); else if (sc_info->dicts->len > 10) gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(combo), 2); gtk_box_pack_start(GTK_BOX(vbox), combo, FALSE, FALSE, 6); #ifdef HAVE_ENCHANT_1_5 label = gtk_label_new_with_mnemonic(_("_Directory to look for dictionary files:")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); entry_dir = gtk_entry_new(); ui_entry_add_clear_icon(GTK_ENTRY(entry_dir)); gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry_dir); ui_widget_set_tooltip_text(entry_dir, _("Read additional dictionary files from this directory. " "For now, this only works with myspell dictionaries.")); if (NZV(sc_info->dictionary_dir)) gtk_entry_set_text(GTK_ENTRY(entry_dir), sc_info->dictionary_dir); button = gtk_button_new(); g_signal_connect(button, "clicked", G_CALLBACK(dictionary_dir_button_clicked_cb), entry_dir); image = gtk_image_new_from_stock("gtk-open", GTK_ICON_SIZE_BUTTON); gtk_container_add(GTK_CONTAINER(button), image); hbox = gtk_hbox_new(FALSE, 6); gtk_box_pack_start(GTK_BOX(hbox), entry_dir, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); g_object_set_data(G_OBJECT(dialog), "dict_dir", entry_dir); #endif g_object_set_data(G_OBJECT(dialog), "combo", combo); g_object_set_data(G_OBJECT(dialog), "check_type", check_type); g_object_set_data(G_OBJECT(dialog), "check_msgwin", check_msgwin); g_object_set_data(G_OBJECT(dialog), "check_toolbar", check_toolbar); g_object_set_data(G_OBJECT(dialog), "check_editor_menu", check_editor_menu); g_signal_connect(dialog, "response", G_CALLBACK(configure_response_cb), NULL); gtk_widget_show_all(vbox); return vbox; }
/* Verifies data for New & Properties dialogs. * Returns: FALSE if the user needs to change any data. */ static gboolean update_config(const PropertyDialogElements *e, gboolean new_project) { const gchar *name, *file_name, *base_path; gchar *locale_filename; gsize name_len; gint err_code = 0; GeanyProject *p; g_return_val_if_fail(e != NULL, TRUE); name = gtk_entry_get_text(GTK_ENTRY(e->name)); name_len = strlen(name); if (name_len == 0) { SHOW_ERR(_("The specified project name is too short.")); gtk_widget_grab_focus(e->name); return FALSE; } else if (name_len > MAX_NAME_LEN) { SHOW_ERR1(_("The specified project name is too long (max. %d characters)."), MAX_NAME_LEN); gtk_widget_grab_focus(e->name); return FALSE; } if (new_project) file_name = gtk_entry_get_text(GTK_ENTRY(e->file_name)); else file_name = gtk_label_get_text(GTK_LABEL(e->file_name)); if (G_UNLIKELY(! NZV(file_name))) { SHOW_ERR(_("You have specified an invalid project filename.")); gtk_widget_grab_focus(e->file_name); return FALSE; } locale_filename = utils_get_locale_from_utf8(file_name); base_path = gtk_entry_get_text(GTK_ENTRY(e->base_path)); if (NZV(base_path)) { /* check whether the given directory actually exists */ gchar *locale_path = utils_get_locale_from_utf8(base_path); if (! g_path_is_absolute(locale_path)) { /* relative base path, so add base dir of project file name */ gchar *dir = g_path_get_dirname(locale_filename); SETPTR(locale_path, g_strconcat(dir, G_DIR_SEPARATOR_S, locale_path, NULL)); g_free(dir); } if (! g_file_test(locale_path, G_FILE_TEST_IS_DIR)) { gboolean create_dir; create_dir = dialogs_show_question_full(NULL, GTK_STOCK_OK, GTK_STOCK_CANCEL, _("Create the project's base path directory?"), _("The path \"%s\" does not exist."), base_path); if (create_dir) err_code = utils_mkdir(locale_path, TRUE); if (! create_dir || err_code != 0) { if (err_code != 0) SHOW_ERR1(_("Project base directory could not be created (%s)."), g_strerror(err_code)); gtk_widget_grab_focus(e->base_path); utils_free_pointers(2, locale_path, locale_filename, NULL); return FALSE; } } g_free(locale_path); } /* finally test whether the given project file can be written */ if ((err_code = utils_is_file_writable(locale_filename)) != 0 || (err_code = g_file_test(locale_filename, G_FILE_TEST_IS_DIR) ? EISDIR : 0) != 0) { SHOW_ERR1(_("Project file could not be written (%s)."), g_strerror(err_code)); gtk_widget_grab_focus(e->file_name); g_free(locale_filename); return FALSE; } g_free(locale_filename); if (app->project == NULL) { create_project(); new_project = TRUE; } p = app->project; SETPTR(p->name, g_strdup(name)); SETPTR(p->file_name, g_strdup(file_name)); /* use "." if base_path is empty */ SETPTR(p->base_path, g_strdup(NZV(base_path) ? base_path : "./")); if (! new_project) /* save properties specific fields */ { GtkTextIter start, end; GtkTextBuffer *buffer; GeanyDocument *doc = document_get_current(); GeanyBuildCommand *oldvalue; GeanyFiletype *ft = doc ? doc->file_type : NULL; GtkWidget *widget; gchar *tmp; GString *str; GSList *node; /* get and set the project description */ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(e->description)); gtk_text_buffer_get_start_iter(buffer, &start); gtk_text_buffer_get_end_iter(buffer, &end); SETPTR(p->description, g_strdup(gtk_text_buffer_get_text(buffer, &start, &end, FALSE))); foreach_slist(node, stash_groups) stash_group_update(node->data, e->dialog); /* read the project build menu */ oldvalue = ft ? ft->projfilecmds : NULL; build_read_project(ft, e->build_properties); if (ft != NULL && ft->projfilecmds != oldvalue && ft->project_list_entry < 0) { if (p->build_filetypes_list == NULL) p->build_filetypes_list = g_ptr_array_new(); ft->project_list_entry = p->build_filetypes_list->len; g_ptr_array_add(p->build_filetypes_list, ft); } build_menu_update(doc); widget = ui_lookup_widget(e->dialog, "radio_long_line_disabled_project"); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) p->long_line_behaviour = 0; else { widget = ui_lookup_widget(e->dialog, "radio_long_line_default_project"); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) p->long_line_behaviour = 1; else /* "Custom" radio button must be checked */ p->long_line_behaviour = 2; } widget = ui_lookup_widget(e->dialog, "spin_long_line_project"); p->long_line_column = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); apply_editor_prefs(); /* get and set the project file patterns */ tmp = g_strdup(gtk_entry_get_text(GTK_ENTRY(e->patterns))); g_strfreev(p->file_patterns); g_strstrip(tmp); str = g_string_new(tmp); do {} while (utils_string_replace_all(str, " ", " ")); p->file_patterns = g_strsplit(str->str, " ", -1); g_string_free(str, TRUE); g_free(tmp); } update_ui(); return TRUE; }
static void configure_response_cb(GtkDialog *dialog, gint response, G_GNUC_UNUSED gpointer data) { if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY) { GKeyFile *config = g_key_file_new(); gchar *str; const gchar *text_dir, *text_time; gchar *config_dir = g_path_get_dirname(config_file); enable_autosave = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(pref_widgets.checkbox_enable_autosave)); enable_instantsave = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(pref_widgets.checkbox_enable_instantsave)); enable_backupcopy = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(pref_widgets.checkbox_enable_backupcopy)); autosave_interval = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(pref_widgets.autosave_interval_spin)); autosave_print_msg = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(pref_widgets.autosave_print_msg_checkbox)); autosave_save_all = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(pref_widgets.autosave_save_all_radio2)); g_free(instantsave_default_ft); instantsave_default_ft = gtk_combo_box_text_get_active_text( GTK_COMBO_BOX_TEXT(pref_widgets.instantsave_ft_combo)); text_dir = gtk_entry_get_text(GTK_ENTRY(pref_widgets.backupcopy_entry_dir)); text_time = gtk_entry_get_text(GTK_ENTRY(pref_widgets.backupcopy_entry_time)); backupcopy_dir_levels = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(pref_widgets.backupcopy_spin_dir_levels)); g_key_file_load_from_file(config, config_file, G_KEY_FILE_NONE, NULL); g_key_file_set_boolean(config, "saveactions", "enable_autosave", enable_autosave); g_key_file_set_boolean(config, "saveactions", "enable_instantsave", enable_instantsave); g_key_file_set_boolean(config, "saveactions", "enable_backupcopy", enable_backupcopy); g_key_file_set_boolean(config, "autosave", "print_messages", autosave_print_msg); g_key_file_set_boolean(config, "autosave", "save_all", autosave_save_all); g_key_file_set_integer(config, "autosave", "interval", autosave_interval); if (instantsave_default_ft != NULL) g_key_file_set_string(config, "instantsave", "default_ft", instantsave_default_ft); g_key_file_set_integer(config, "backupcopy", "dir_levels", backupcopy_dir_levels); g_key_file_set_string(config, "backupcopy", "time_fmt", text_time); SETPTR(backupcopy_time_fmt, g_strdup(text_time)); if (enable_backupcopy) { if (NZV(text_dir) && backupcopy_set_backup_dir(text_dir)) { g_key_file_set_string(config, "backupcopy", "backup_dir", text_dir); } else { dialogs_show_msgbox(GTK_MESSAGE_ERROR, _("Backup directory does not exist or is not writable.")); } } if (! g_file_test(config_dir, G_FILE_TEST_IS_DIR) && utils_mkdir(config_dir, TRUE) != 0) { dialogs_show_msgbox(GTK_MESSAGE_ERROR, _("Plugin configuration directory could not be created.")); } else { /* write config to file */ str = g_key_file_to_data(config, NULL, NULL); utils_write_file(config_file, str); g_free(str); } if (enable_autosave) autosave_set_timeout(); /* apply the changes */ g_free(config_dir); g_key_file_free(config); } }
static GSList * get_commit_files_cvs(const gchar * dir) { enum { FIRST_CHAR, SKIP_SPACE, FILE_NAME, }; gchar *txt; GSList *ret = NULL; gint pstatus = FIRST_CHAR; const gchar *p; gchar *base_name; const gchar *start = NULL; CommitItem *item; const gchar *status = NULL; gchar *filename; const char *argv[] = { "cvs", "-nq", "update", NULL }; execute_custom_command(dir, argv, NULL, &txt, NULL, dir, NULL, NULL); if (!NZV(txt)) return NULL; p = txt; while (*p) { if (*p == '\r') { } else if (pstatus == FIRST_CHAR) { status = NULL; if (*p == '?') status = FILE_STATUS_UNKNOWN; else if (*p == 'M') status = FILE_STATUS_MODIFIED; else if (*p == 'D') status = FILE_STATUS_DELETED; else if (*p == 'A') status = FILE_STATUS_ADDED; if (!status || *(p + 1) != ' ') { /* skip unknown status line */ while (*p) { p++; if (*p == '\n') { p++; break; } } pstatus = FIRST_CHAR; continue; } pstatus = SKIP_SPACE; } else if (pstatus == SKIP_SPACE) { if (*p == ' ' || *p == '\t') { } else { start = p; pstatus = FILE_NAME; } } else if (pstatus == FILE_NAME) { if (*p == '\n') { if (status != FILE_STATUS_UNKNOWN) { base_name = g_malloc0(p - start + 1); memcpy(base_name, start, p - start); filename = g_build_filename(dir, base_name, NULL); g_free(base_name); item = g_new(CommitItem, 1); item->status = status; item->path = filename; ret = g_slist_append(ret, item); } pstatus = FIRST_CHAR; } } p++; } g_free(txt); return ret; }
gboolean socket_lock_input_cb(GIOChannel *source, GIOCondition condition, gpointer data) { gint fd, sock; gchar buf[BUFFER_LENGTH]; struct sockaddr_in caddr; socklen_t caddr_len = sizeof(caddr); GtkWidget *window = data; gboolean popup = FALSE; fd = g_io_channel_unix_get_fd(source); sock = accept(fd, (struct sockaddr *)&caddr, &caddr_len); /* first get the command */ while (socket_fd_gets(sock, buf, sizeof(buf)) != -1) { if (strncmp(buf, "open", 4) == 0) { cl_options.readonly = strncmp(buf+4, "ro", 2) == 0; /* open in readonly? */ while (socket_fd_gets(sock, buf, sizeof(buf)) != -1 && *buf != '.') { handle_input_filename(g_strstrip(buf)); } popup = TRUE; } else if (strncmp(buf, "doclist", 7) == 0) { gchar *doc_list = build_document_list(); if (NZV(doc_list)) socket_fd_write_all(sock, doc_list, strlen(doc_list)); else /* send ETX (end-of-text) in case we have no open files, we must send anything * otherwise the client would hang on reading */ socket_fd_write_all(sock, "\3", 1); g_free(doc_list); } else if (strncmp(buf, "line", 4) == 0) { while (socket_fd_gets(sock, buf, sizeof(buf)) != -1 && *buf != '.') { g_strstrip(buf); /* remove \n char */ /* on any error we get 0 which should be safe enough as fallback */ cl_options.goto_line = atoi(buf); } } else if (strncmp(buf, "column", 6) == 0) { while (socket_fd_gets(sock, buf, sizeof(buf)) != -1 && *buf != '.') { g_strstrip(buf); /* remove \n char */ /* on any error we get 0 which should be safe enough as fallback */ cl_options.goto_column = atoi(buf); } } #ifdef G_OS_WIN32 else if (strncmp(buf, "window", 6) == 0) { HWND hwnd = (HWND) gdk_win32_drawable_get_handle( GDK_DRAWABLE(gtk_widget_get_window(window))); socket_fd_write(sock, (gchar *)&hwnd, sizeof(hwnd)); } #endif } if (popup) { #ifdef GDK_WINDOWING_X11 /* Set the proper interaction time on the window. This seems necessary to make * gtk_window_present() really bring the main window into the foreground on some * window managers like Gnome's metacity. * Code taken from Gedit. */ gdk_x11_window_set_user_time(gtk_widget_get_window(window), gdk_x11_get_server_time(gtk_widget_get_window(window))); #endif gtk_window_present(GTK_WINDOW(window)); #ifdef G_OS_WIN32 gdk_window_show(gtk_widget_get_window(window)); #endif } socket_fd_close(sock); return TRUE; }
static void create_file_save_as_dialog(const gchar *extension, ExportFunc func, gboolean show_zoom_level_checkbox) { GtkWidget *dialog, *vbox; GeanyDocument *doc; ExportInfo *exi; g_return_if_fail(extension != NULL); doc = document_get_current(); g_return_if_fail(doc != NULL); exi = g_new(ExportInfo, 1); exi->doc = doc; exi->export_func = func; exi->have_zoom_level_checkbox = FALSE; dialog = gtk_file_chooser_dialog_new(_("Export File"), GTK_WINDOW(geany->main_widgets->window), GTK_FILE_CHOOSER_ACTION_SAVE, NULL, NULL); gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE); gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), TRUE); gtk_window_set_type_hint(GTK_WINDOW(dialog), GDK_WINDOW_TYPE_HINT_DIALOG); gtk_widget_set_name(dialog, "GeanyExportDialog"); gtk_dialog_add_buttons(GTK_DIALOG(dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); /* file chooser extra widget */ vbox = gtk_vbox_new(FALSE, 0); gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(dialog), vbox); { GtkWidget *check_line_numbers; check_line_numbers = gtk_check_button_new_with_mnemonic(_("_Insert line numbers")); gtk_widget_set_tooltip_text(check_line_numbers, _("Insert line numbers before each line in the exported document")); gtk_box_pack_start(GTK_BOX(vbox), check_line_numbers, FALSE, FALSE, 0); gtk_widget_show_all(vbox); ui_hookup_widget(dialog, check_line_numbers, "check_line_numbers"); } if (show_zoom_level_checkbox) { GtkWidget *check_zoom_level; check_zoom_level = gtk_check_button_new_with_mnemonic(_("_Use current zoom level")); gtk_widget_set_tooltip_text(check_zoom_level, _("Renders the font size of the document together with the current zoom level")); gtk_box_pack_start(GTK_BOX(vbox), check_zoom_level, FALSE, FALSE, 0); gtk_widget_show_all(vbox); ui_hookup_widget(dialog, check_zoom_level, "check_zoom_level"); exi->have_zoom_level_checkbox = TRUE; } g_signal_connect(dialog, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); g_signal_connect(dialog, "response", G_CALLBACK(on_file_save_dialog_response), exi); gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(geany->main_widgets->window)); /* if the current document has a filename we use it as the default. */ gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(dialog)); if (doc->file_name != NULL) { gchar *base_name = g_path_get_basename(doc->file_name); gchar *file_name; gchar *locale_filename; gchar *locale_dirname; const gchar *suffix = ""; if (g_str_has_suffix(doc->file_name, extension)) suffix = "_export"; file_name = g_strconcat(base_name, suffix, extension, NULL); locale_filename = utils_get_locale_from_utf8(doc->file_name); locale_dirname = g_path_get_dirname(locale_filename); /* set the current name to base_name.html which probably doesn't exist yet so * gtk_file_chooser_set_filename() can't be used and we need * gtk_file_chooser_set_current_folder() additionally */ gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), locale_dirname); gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), file_name); g_free(locale_dirname); g_free(locale_filename); g_free(file_name); g_free(base_name); } else { const gchar *default_open_path = geany->prefs->default_open_path; gchar *fname = g_strconcat(GEANY_STRING_UNTITLED, extension, NULL); gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(dialog)); gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), fname); /* use default startup directory(if set) if no files are open */ if (NZV(default_open_path) && g_path_is_absolute(default_open_path)) { gchar *locale_path = utils_get_locale_from_utf8(default_open_path); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), locale_path); g_free(locale_path); } g_free(fname); } gtk_dialog_run(GTK_DIALOG(dialog)); }