[geany/geany] 4b573b: Merge pull request #3042 from techee/project_create2

Jiří Techet git-noreply at geany.org
Fri May 13 00:19:35 UTC 2022


Branch:      refs/heads/master
Author:      Jiří Techet <techet at gmail.com>
Committer:   GitHub <noreply at github.com>
Date:        Fri, 13 May 2022 00:19:35 UTC
Commit:      4b573b7a402347cb6b74c07057d862b66959fa2a
             https://github.com/geany/geany/commit/4b573b7a402347cb6b74c07057d862b66959fa2a

Log Message:
-----------
Merge pull request #3042 from techee/project_create2

Improve user experience when creating new projects, attempt 2


Modified Paths:
--------------
    data/geany.glade
    doc/geany.txt
    src/callbacks.c
    src/callbacks.h
    src/keybindings.c
    src/keybindings.h
    src/keyfile.c
    src/plugindata.h
    src/project.c
    src/project.h
    src/ui_utils.c
    src/ui_utils.h

Modified: data/geany.glade
17 lines changed, 17 insertions(+), 0 deletions(-)
===================================================================
@@ -704,6 +704,12 @@
     <property name="stock">gtk-find</property>
     <property name="icon_size">1</property>
   </object>
+  <object class="GtkImage" id="image7">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="stock">gtk-new</property>
+    <property name="icon-size">1</property>
+  </object>
   <object class="GtkListStore" id="indent_mode_list">
     <columns>
       <!-- column-name item -->
@@ -7897,6 +7903,17 @@
                             <signal name="activate" handler="on_project_new1_activate" swapped="no"/>
                           </object>
                         </child>
+                        <child>
+                          <object class="GtkImageMenuItem" id="project_new_from_folder1">
+                            <property name="label" translatable="yes">New from _Folder...</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="use_underline">True</property>
+                            <property name="image">image7</property>
+                            <property name="use_stock">False</property>
+                            <signal name="activate" handler="on_project_new_from_folder1_activate" swapped="no"/>
+                          </object>
+                        </child>
                         <child>
                           <object class="GtkImageMenuItem" id="project_open1">
                             <property name="label" translatable="yes">_Open...</property>


Modified: doc/geany.txt
37 lines changed, 29 insertions(+), 8 deletions(-)
===================================================================
@@ -2776,14 +2776,35 @@ The project menu items are detailed below.
 New project
 ^^^^^^^^^^^
 
-To create a new project, fill in the *Name* field. By default this
-will setup a new project file ``~/projects/name.geany``. Usually it's
-best to store all your project files in the same directory (they are
-independent of any source directory trees).
-
-The Base path text field is setup to use ``~/projects/name``. This
-can safely be set to any existing path -- it will not touch the file
-structure contained in it.
+There are two ways of creating new projects, either by using
+*Project->New* menu item or by using *Project->New from Folder* menu
+item.
+
+New
+    This method is more suitable for creating new, empty projects from
+    scratch at the default location without having any existing sources.
+
+    To create a new project, fill in the *Name* field. By default this
+    will setup a new project file ``~/projects/name/name.geany``.
+
+    The *Base path* text field is setup to use ``~/projects/name``. This
+    can safely be set to any existing path -- it will not touch the file
+    structure contained in it.
+
+New from Folder
+    This method is more suitable when there is already some folder
+    containing source files for which you want to create a new project.
+
+    When using this method, Geany first opens a directory selection
+    dialog to select the folder containing the sources, and the
+    *Base path* field is set to that value.
+
+    Afterwards, Geany shows the same dialog as the *Project->New*
+    method but already pre-filled with the values based on the
+    *Base path* selection. The *Name* field is filled with the folder
+    name, the *Filename* field is filled with
+    ``base_path/name.geany`` and the *Base path* field is filled with
+    the path specified in the previous dialog.
 
 
 Project properties


Modified: src/callbacks.c
8 lines changed, 7 insertions(+), 1 deletions(-)
===================================================================
@@ -1387,7 +1387,13 @@ void on_previous_message1_activate(GtkMenuItem *menuitem, gpointer user_data)
 
 void on_project_new1_activate(GtkMenuItem *menuitem, gpointer user_data)
 {
-	project_new();
+	project_new(FALSE);
+}
+
+
+void on_project_new_from_folder1_activate(GtkMenuItem *menuitem, gpointer user_data)
+{
+	project_new(TRUE);
 }
 
 


Modified: src/callbacks.h
2 lines changed, 2 insertions(+), 0 deletions(-)
===================================================================
@@ -144,6 +144,8 @@ void on_next_message1_activate(GtkMenuItem *menuitem, gpointer user_data);
 
 void on_project_new1_activate(GtkMenuItem *menuitem, gpointer user_data);
 
+void on_project_new_from_folder1_activate(GtkMenuItem *menuitem, gpointer user_data);
+
 void on_project_open1_activate(GtkMenuItem *menuitem, gpointer user_data);
 
 void on_project_close1_activate(GtkMenuItem *menuitem, gpointer user_data);


Modified: src/keybindings.c
5 lines changed, 5 insertions(+), 0 deletions(-)
===================================================================
@@ -366,6 +366,8 @@ static void init_default_kb(void)
 
 	add_kb(group, GEANY_KEYS_PROJECT_NEW, NULL,
 		0, 0, "project_new", _("New"), "project_new1");
+	add_kb(group, GEANY_KEYS_PROJECT_NEW_FROM_FOLDER, NULL,
+		0, 0, "project_new_from_folder", _("New from Folder"), "project_new_from_folder1");
 	add_kb(group, GEANY_KEYS_PROJECT_OPEN, NULL,
 		0, 0, "project_open", _("Open"), "project_open1");
 	add_kb(group, GEANY_KEYS_PROJECT_PROPERTIES, NULL,
@@ -1502,6 +1504,9 @@ static gboolean cb_func_project_action(guint key_id)
 		case GEANY_KEYS_PROJECT_NEW:
 			on_project_new1_activate(NULL, NULL);
 			break;
+		case GEANY_KEYS_PROJECT_NEW_FROM_FOLDER:
+			on_project_new_from_folder1_activate(NULL, NULL);
+			break;
 		case GEANY_KEYS_PROJECT_OPEN:
 			on_project_open1_activate(NULL, NULL);
 			break;


Modified: src/keybindings.h
2 lines changed, 2 insertions(+), 0 deletions(-)
===================================================================
@@ -277,6 +277,8 @@ enum GeanyKeyBindingID
 												 * @since 1.34 (API 238) */
 	GEANY_KEYS_FILE_RELOAD_ALL,					/**< Keybinding.
 												 * @since 1.38 (API 240) */
+	GEANY_KEYS_PROJECT_NEW_FROM_FOLDER,			/**< Keybinding.
+												 * @since 1.39 (API 243) */
 	GEANY_KEYS_COUNT	/* must not be used by plugins */
 };
 


Modified: src/keyfile.c
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -824,7 +824,7 @@ static void load_dialog_prefs(GKeyFile *config)
 	prefs.confirm_exit = utils_get_setting_boolean(config, PACKAGE, "pref_main_confirm_exit", FALSE);
 	prefs.suppress_status_messages = utils_get_setting_boolean(config, PACKAGE, "pref_main_suppress_status_messages", FALSE);
 	prefs.load_session = utils_get_setting_boolean(config, PACKAGE, "pref_main_load_session", TRUE);
-	project_prefs.project_file_in_basedir = utils_get_setting_boolean(config, PACKAGE, "pref_main_project_file_in_basedir", FALSE);
+	project_prefs.project_file_in_basedir = utils_get_setting_boolean(config, PACKAGE, "pref_main_project_file_in_basedir", TRUE);
 	prefs.save_winpos = utils_get_setting_boolean(config, PACKAGE, "pref_main_save_winpos", TRUE);
 	prefs.save_wingeom = utils_get_setting_boolean(config, PACKAGE, "pref_main_save_wingeom", prefs.save_winpos);
 	prefs.beep_on_errors = utils_get_setting_boolean(config, PACKAGE, "beep_on_errors", TRUE);


Modified: src/plugindata.h
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -57,7 +57,7 @@ G_BEGIN_DECLS
  * @warning You should not test for values below 200 as previously
  * @c GEANY_API_VERSION was defined as an enum value, not a macro.
  */
-#define GEANY_API_VERSION 243
+#define GEANY_API_VERSION 244
 
 /* hack to have a different ABI when built with different GTK major versions
  * because loading plugins linked to a different one leads to crashes.


Modified: src/project.c
105 lines changed, 85 insertions(+), 20 deletions(-)
===================================================================
@@ -83,6 +83,8 @@ static gboolean update_config(const PropertyDialogElements *e, gboolean new_proj
 static void on_file_save_button_clicked(GtkButton *button, PropertyDialogElements *e);
 static gboolean load_config(const gchar *filename);
 static gboolean write_config(void);
+static void update_new_project_dlg(GtkEditable *editable, PropertyDialogElements *e,
+	const gchar *base_p);
 static void on_name_entry_changed(GtkEditable *editable, PropertyDialogElements *e);
 static void on_entries_changed(GtkEditable *editable, PropertyDialogElements *e);
 static void on_radio_long_line_custom_toggled(GtkToggleButton *radio, GtkWidget *spin_long_line);
@@ -141,7 +143,7 @@ static gboolean handle_current_session(void)
 /* TODO: this should be ported to Glade like the project preferences dialog,
  * then we can get rid of the PropertyDialogElements struct altogether as
  * widgets pointers can be accessed through ui_lookup_widget(). */
-void project_new(void)
+void project_new(gboolean from_folder)
 {
 	GtkWidget *vbox;
 	GtkWidget *table;
@@ -150,8 +152,28 @@ void project_new(void)
 	GtkWidget *bbox;
 	GtkWidget *label;
 	gchar *tooltip;
+	gchar *base_path = NULL;
 	PropertyDialogElements e = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, FALSE };
 
+	if (from_folder)
+	{
+		GeanyDocument *doc = document_get_current();
+		gchar *start_path;
+
+		if (doc && doc->file_name)
+			start_path = g_path_get_dirname(doc->file_name);
+		else if (!EMPTY(local_prefs.project_file_path))
+			start_path = g_strdup(local_prefs.project_file_path);
+		else
+			start_path = utils_get_utf8_from_locale(g_get_home_dir());
+
+		base_path = ui_get_project_directory(start_path);
+		g_free(start_path);
+
+		if (!base_path)
+			return;
+	}
+
 	e.dialog = gtk_dialog_new_with_buttons(_("New Project"), GTK_WINDOW(main_widgets.window),
 										 GTK_DIALOG_DESTROY_WITH_PARENT,
 										 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
@@ -185,7 +207,7 @@ void project_new(void)
 	e.file_name = gtk_entry_new();
 	gtk_entry_set_activates_default(GTK_ENTRY(e.file_name), TRUE);
 	ui_entry_add_clear_icon(GTK_ENTRY(e.file_name));
-	gtk_entry_set_width_chars(GTK_ENTRY(e.file_name), 30);
+	gtk_entry_set_width_chars(GTK_ENTRY(e.file_name), 40);
 	tooltip = g_strdup_printf(
 		_("Path of the file representing the project and storing its settings. "
 		"It should normally have the \"%s\" extension."), "."GEANY_PROJECT_EXT);
@@ -218,13 +240,20 @@ void project_new(void)
 
 	gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
 
-	/* signals */
-	g_signal_connect(e.name, "changed", G_CALLBACK(on_name_entry_changed), &e);
-	/* run the callback manually to initialise the base_path and file_name fields */
-	on_name_entry_changed(GTK_EDITABLE(e.name), &e);
+	if (base_path)
+	{
+		update_new_project_dlg(GTK_EDITABLE(e.name), &e, base_path);
+		g_free(base_path);
+	}
+	else
+	{
+		/* signals */
+		g_signal_connect(e.name, "changed", G_CALLBACK(on_name_entry_changed), &e);
+		g_signal_connect(e.file_name, "changed", G_CALLBACK(on_entries_changed), &e);
+		g_signal_connect(e.base_path, "changed", G_CALLBACK(on_entries_changed), &e);
 
-	g_signal_connect(e.file_name, "changed", G_CALLBACK(on_entries_changed), &e);
-	g_signal_connect(e.base_path, "changed", G_CALLBACK(on_entries_changed), &e);
+		update_new_project_dlg(GTK_EDITABLE(e.name), &e, NULL);
+	}
 
 	gtk_widget_show_all(e.dialog);
 	run_new_dialog(&e);
@@ -950,35 +979,64 @@ static void on_file_save_button_clicked(GtkButton *button, PropertyDialogElement
 }
 
 
-/* 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)
+/* sets the New Project dialog entries according to the base path or project name */
+static void update_new_project_dlg(GtkEditable *editable, PropertyDialogElements *e,
+	const gchar *base_p)
 {
 	gchar *base_path;
 	gchar *file_name;
-	gchar *name;
-	const gchar *project_dir = local_prefs.project_file_path;
+	gchar *project_dir = NULL;
 
 	if (e->entries_modified)
 		return;
 
-	name = gtk_editable_get_chars(editable, 0, -1);
-	if (!EMPTY(name))
+	if (!EMPTY(local_prefs.project_file_path))
+		project_dir = g_strdup(local_prefs.project_file_path);
+	else
 	{
-		base_path = g_strconcat(project_dir, G_DIR_SEPARATOR_S,
-			name, G_DIR_SEPARATOR_S, NULL);
+		GeanyDocument *doc = document_get_current();
+
+		if (doc && doc->file_name)
+			project_dir = g_path_get_dirname(doc->file_name);
+		else
+			project_dir = utils_get_utf8_from_locale(g_get_home_dir());
+	}
+
+	if (!EMPTY(base_p))
+	{
+		gchar *name = g_path_get_basename(base_p);
+
+		base_path = g_strdup(base_p);
+		gtk_entry_set_text(GTK_ENTRY(e->name), name);
 		if (project_prefs.project_file_in_basedir)
-			file_name = g_strconcat(project_dir, G_DIR_SEPARATOR_S, name, G_DIR_SEPARATOR_S,
+			file_name = g_strconcat(base_path, 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);
+		g_free(name);
 	}
 	else
 	{
-		base_path = g_strconcat(project_dir, G_DIR_SEPARATOR_S, NULL);
-		file_name = g_strconcat(project_dir, G_DIR_SEPARATOR_S, NULL);
+		gchar *name = gtk_editable_get_chars(editable, 0, -1);
+		if (!EMPTY(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);
 	}
-	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);
@@ -987,6 +1045,13 @@ static void on_name_entry_changed(GtkEditable *editable, PropertyDialogElements
 
 	g_free(base_path);
 	g_free(file_name);
+	g_free(project_dir);
+}
+
+
+static void on_name_entry_changed(GtkEditable *editable, PropertyDialogElements *e)
+{
+	update_new_project_dlg(editable, e, NULL);
 }
 
 


Modified: src/project.h
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -66,7 +66,7 @@ void project_init(void);
 void project_finalize(void);
 
 
-void project_new(void);
+void project_new(gboolean from_folder);
 
 void project_open(void);
 


Modified: src/ui_utils.c
15 lines changed, 15 insertions(+), 0 deletions(-)
===================================================================
@@ -1999,6 +1999,21 @@ static gchar *run_file_chooser(const gchar *title, GtkFileChooserAction action,
 #endif
 
 
+gchar *ui_get_project_directory(const gchar *path)
+{
+	gchar *utf8_path;
+	const gchar *title = _("Select Project Base Path");
+
+#ifdef G_OS_WIN32
+	utf8_path = win32_show_folder_dialog(ui_widgets.prefs_dialog, title, path);
+#else
+	utf8_path = run_file_chooser(title, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, path);
+#endif
+
+	return utf8_path;
+}
+
+
 static void ui_path_box_open_clicked(GtkButton *button, gpointer user_data)
 {
 	GtkFileChooserAction action = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button), "action"));


Modified: src/ui_utils.h
2 lines changed, 2 insertions(+), 0 deletions(-)
===================================================================
@@ -366,6 +366,8 @@ gint ui_encodings_combo_box_get_active_encoding(GtkComboBox *combo);
 
 gboolean ui_encodings_combo_box_set_active_encoding(GtkComboBox *combo, gint enc);
 
+gchar *ui_get_project_directory(const gchar *path);
+
 #endif /* GEANY_PRIVATE */
 
 G_END_DECLS



--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).


More information about the Commits mailing list