Add support for relative project base path.

Improve and synchronize base path tooltips in project new and properties dialogs.
Fix minor GUI annoyances in project dialogs.	    


git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@1984 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
Enrico Tröger 2007-10-28 17:02:36 +00:00
parent e4a593a4e6
commit 2d77d3013a
5 changed files with 92 additions and 26 deletions

View File

@ -1,3 +1,12 @@
2007-10-28 Enrico Tröger <enrico.troeger@uvena.de>
* doc/geany.txt, src/build.c, src/project.c, src/project.h:
Add support for relative project base path.
Improve and synchronize base path tooltips in project new and
properties dialogs.
Fix minor GUI annoyances in project dialogs.
2007-10-26 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com> 2007-10-26 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
* plugins/svndiff.c, plugins/export.c, plugins/demoplugin.c, * plugins/svndiff.c, plugins/export.c, plugins/demoplugin.c,

View File

@ -1171,13 +1171,15 @@ You can set an optional description for the project, but it is not
used elsewhere by Geany. used elsewhere by Geany.
The *Base path* field is used as the directory to run the Make and Make The *Base path* field is used as the directory to run the Make and Make
custom commands in. custom commands in. It is also used as working directory for the project
specific *Run command*.
The specified path can be absolute or relative to the project's file name.
Run command Run command
``````````` ```````````
The Run command overrides the default run command. You can set this The *Run command* overrides the default run command. You can set this
to the executable or main script file for the project, and append to the executable or main script file for the project, and append
any command-line arguments. any command-line arguments.

View File

@ -300,7 +300,7 @@ static gchar *get_object_filename(gint idx)
static GPid build_make_file(gint idx, gint build_opts) static GPid build_make_file(gint idx, gint build_opts)
{ {
GString *cmdstr; GString *cmdstr;
const gchar *dir = NULL; gchar *dir = NULL;
GPid pid; GPid pid;
if (idx < 0 || doc_list[idx].file_name == NULL) return (GPid) 1; if (idx < 0 || doc_list[idx].file_name == NULL) return (GPid) 1;
@ -331,6 +331,7 @@ static GPid build_make_file(gint idx, gint build_opts)
} }
pid = build_spawn_cmd(idx, cmdstr->str, dir); // if dir is NULL, idx filename is used pid = build_spawn_cmd(idx, cmdstr->str, dir); // if dir is NULL, idx filename is used
g_free(dir);
g_string_free(cmdstr, TRUE); g_string_free(cmdstr, TRUE);
return pid; return pid;
} }
@ -636,9 +637,14 @@ static gchar *prepare_run_script(gint idx)
return NULL; return NULL;
} }
working_dir = (have_project) ? if (have_project)
utils_get_locale_from_utf8(project->base_path) : {
g_path_get_dirname(locale_filename); gchar *project_base_path = project_get_make_dir();
working_dir = utils_get_locale_from_utf8(project_base_path);
g_free(project_base_path);
}
else
working_dir = g_path_get_dirname(locale_filename);
if (chdir(working_dir) != 0) if (chdir(working_dir) != 0)
{ {

View File

@ -28,6 +28,7 @@
#include "geany.h" #include "geany.h"
#include <string.h> #include <string.h>
#include <unistd.h>
#include "project.h" #include "project.h"
#include "dialogs.h" #include "dialogs.h"
@ -46,7 +47,7 @@ ProjectPrefs project_prefs = {NULL};
static struct static struct
{ {
gchar *project_file_path; gchar *project_file_path; // in UTF-8
} local_prefs = {NULL}; } local_prefs = {NULL};
@ -153,7 +154,8 @@ void project_new()
e->base_path = gtk_entry_new(); e->base_path = gtk_entry_new();
gtk_tooltips_set_tip(tooltips, e->base_path, gtk_tooltips_set_tip(tooltips, e->base_path,
_("Base directory of all files that make up the project. " _("Base directory of all files that make up the project. "
"This can be a new path, or an existing directory tree."), NULL); "This can be a new path, or an existing directory tree absolute "
"or relative to the project filename."), NULL);
bbox = ui_path_box_new(_("Choose Project Base Path"), bbox = ui_path_box_new(_("Choose Project Base Path"),
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_ENTRY(e->base_path)); GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_ENTRY(e->base_path));
@ -219,6 +221,7 @@ void project_open()
#else #else
GtkWidget *dialog; GtkWidget *dialog;
GtkFileFilter *filter; GtkFileFilter *filter;
gchar *locale_path;
#endif #endif
if (! close_open_project()) return; if (! close_open_project()) return;
@ -256,7 +259,13 @@ void project_open()
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter); gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), dir); locale_path = utils_get_locale_from_utf8(dir);
if (g_file_test(locale_path, G_FILE_TEST_EXISTS) &&
g_file_test(locale_path, G_FILE_TEST_IS_DIR))
{
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), locale_path);
}
g_free(locale_path);
gtk_widget_show_all(dialog); gtk_widget_show_all(dialog);
run_open_dialog(GTK_DIALOG(dialog)); run_open_dialog(GTK_DIALOG(dialog));
@ -374,8 +383,9 @@ void project_properties()
e->base_path = gtk_entry_new(); e->base_path = gtk_entry_new();
gtk_tooltips_set_tip(tooltips, e->base_path, gtk_tooltips_set_tip(tooltips, e->base_path,
_("Directory to run Make All from. " _("Base directory of all files that make up the project. "
"Leave blank to use the default command."), NULL); "This can be a new path, or an existing directory tree absolute "
"or relative to the project filename."), NULL);
bbox = ui_path_box_new(_("Choose Project Base Path"), bbox = ui_path_box_new(_("Choose Project Base Path"),
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_ENTRY(e->base_path)); GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_ENTRY(e->base_path));
gtk_table_attach(GTK_TABLE(table), bbox, 1, 2, 3, 4, gtk_table_attach(GTK_TABLE(table), bbox, 1, 2, 3, 4,
@ -505,6 +515,7 @@ static gboolean close_open_project()
static gboolean update_config(const PropertyDialogElements *e) static gboolean update_config(const PropertyDialogElements *e)
{ {
const gchar *name, *file_name, *base_path; const gchar *name, *file_name, *base_path;
gchar *locale_filename;
gint name_len; gint name_len;
gboolean new_project = FALSE; gboolean new_project = FALSE;
GeanyProject *p; GeanyProject *p;
@ -534,10 +545,27 @@ static gboolean update_config(const PropertyDialogElements *e)
return FALSE; return FALSE;
} }
// finally test whether the given project file can be written
locale_filename = utils_get_locale_from_utf8(file_name);
if (utils_write_file(file_name, "") != 0)
{
SHOW_ERR(_("Project file could not be written."));
gtk_widget_grab_focus(e->file_name);
return FALSE;
}
base_path = gtk_entry_get_text(GTK_ENTRY(e->base_path)); base_path = gtk_entry_get_text(GTK_ENTRY(e->base_path));
if (NZV(base_path)) if (NZV(base_path))
{ // check whether the given directory actually exists { // check whether the given directory actually exists
gchar *locale_path = utils_get_locale_from_utf8(base_path); 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)) if (! g_file_test(locale_path, G_FILE_TEST_IS_DIR))
{ {
if (dialogs_show_question_full(NULL, GTK_STOCK_OK, GTK_STOCK_CANCEL, if (dialogs_show_question_full(NULL, GTK_STOCK_OK, GTK_STOCK_CANCEL,
@ -556,14 +584,7 @@ static gboolean update_config(const PropertyDialogElements *e)
} }
g_free(locale_path); g_free(locale_path);
} }
g_free(locale_filename);
// finally test whether the given project file can be written
if (utils_write_file(file_name, "") != 0)
{
SHOW_ERR(_("Project file could not be written."));
gtk_widget_grab_focus(e->file_name);
return FALSE;
}
if (app->project == NULL) if (app->project == NULL)
{ {
@ -579,7 +600,7 @@ static gboolean update_config(const PropertyDialogElements *e)
p->file_name = g_strdup(file_name); p->file_name = g_strdup(file_name);
if (p->base_path != NULL) g_free(p->base_path); if (p->base_path != NULL) g_free(p->base_path);
p->base_path = g_strdup(base_path); p->base_path = g_strdup(NZV(base_path) ? base_path : "./"); // use "." if base_path is empty
if (! new_project) // save properties specific fields if (! new_project) // save properties specific fields
{ {
@ -629,6 +650,18 @@ static void run_dialog(GtkWidget *dialog, GtkWidget *entry)
{ {
if (g_file_test(locale_filename, G_FILE_TEST_EXISTS)) if (g_file_test(locale_filename, G_FILE_TEST_EXISTS))
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), utf8_filename); gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), utf8_filename);
else // if the file doesn't yet exist, use at least the current directory
{
gchar *locale_dir = g_path_get_dirname(locale_filename);
gchar *name = g_path_get_basename(utf8_filename);
if (g_file_test(locale_dir, G_FILE_TEST_EXISTS))
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), locale_dir);
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), name);
g_free(name);
g_free(locale_dir);
}
} }
else else
if (gtk_file_chooser_get_action(GTK_FILE_CHOOSER(dialog)) != GTK_FILE_CHOOSER_ACTION_OPEN) if (gtk_file_chooser_get_action(GTK_FILE_CHOOSER(dialog)) != GTK_FILE_CHOOSER_ACTION_OPEN)
@ -849,10 +882,27 @@ static gboolean write_config()
} }
const gchar *project_get_make_dir() /* 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_make_dir()
{ {
if (app->project != NULL && NZV(app->project->base_path)) if (app->project != NULL && NZV(app->project->base_path))
return app->project->base_path; {
if (g_path_is_absolute(app->project->base_path))
return g_strdup(app->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(app->project->file_name);
path = g_strconcat(dir, G_DIR_SEPARATOR_S, app->project->base_path, NULL);
g_free(dir);
return path;
}
}
else else
return NULL; return NULL;
} }
@ -911,8 +961,7 @@ void project_apply_prefs()
const gchar *str; const gchar *str;
str = gtk_entry_get_text(GTK_ENTRY(path_entry)); str = gtk_entry_get_text(GTK_ENTRY(path_entry));
g_free(local_prefs.project_file_path); setptr(local_prefs.project_file_path, g_strdup(str));
local_prefs.project_file_path = g_strdup(str);
} }

View File

@ -34,7 +34,7 @@ struct _GeanyProject
gchar *file_name; // where the project file is stored (in UTF-8) gchar *file_name; // where the project file is stored (in UTF-8)
gchar *base_path; // base path of the project directory (in UTF-8) gchar *base_path; // base path of the project directory (in UTF-8, maybe relative)
gchar *run_cmd; // project run command (in UTF-8) gchar *run_cmd; // project run command (in UTF-8)
// ... // fields for build process(run arguments and so on) should be added // ... // fields for build process(run arguments and so on) should be added
@ -60,7 +60,7 @@ void project_properties();
gboolean project_load_file(const gchar *locale_file_name); gboolean project_load_file(const gchar *locale_file_name);
const gchar *project_get_make_dir(); gchar *project_get_make_dir();
void project_save_prefs(GKeyFile *config); void project_save_prefs(GKeyFile *config);