[geany/geany-plugins] b45615: Merge pull request #875 from LarsGit223/wb-search-projects
LarsGit223
git-noreply at xxxxx
Thu Jul 11 17:42:49 UTC 2019
Branch: refs/heads/master
Author: LarsGit223 <LarsGit223 at users.noreply.github.com>
Committer: GitHub <noreply at github.com>
Date: Thu, 11 Jul 2019 17:42:49 UTC
Commit: b456154457195ed686b97748e626d8eda6112387
https://github.com/geany/geany-plugins/commit/b456154457195ed686b97748e626d8eda6112387
Log Message:
-----------
Merge pull request #875 from LarsGit223/wb-search-projects
workbench: added new feature "Search projects"
Modified Paths:
--------------
po/POTFILES.in
workbench/README
workbench/src/Makefile.am
workbench/src/menu.c
workbench/src/menu.h
workbench/src/search_projects.c
workbench/src/search_projects.h
workbench/src/sidebar.c
workbench/src/workbench.c
Modified: po/POTFILES.in
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -321,6 +321,7 @@ workbench/src/dialogs.c
workbench/src/menu.c
workbench/src/plugin_main.c
workbench/src/popup_menu.c
+workbench/src/search_projects.c
workbench/src/sidebar.c
workbench/src/utils.c
workbench/src/wb_globals.c
Modified: workbench/README
6 lines changed, 6 insertions(+), 0 deletions(-)
===================================================================
@@ -39,6 +39,12 @@ menu:
Open the Workbench settings dialog. After the settings have been
confirmed with "OK" they will be written back to the workbench file
(if any value was changed).
+**Item "Search projects"**
+ Search for projects to add them to the Workbench. This lets the user
+ select a directory to search through. The directory and it's sub-directories
+ are scanned for project files (".geany"). All found files are listed and
+ after scanning is done the user can select the projects which shall be
+ added to the Workbench.
**Item "Close"**
Closes the opened Workbench.
Modified: workbench/src/Makefile.am
2 lines changed, 2 insertions(+), 0 deletions(-)
===================================================================
@@ -15,6 +15,8 @@ workbench_la_SOURCES = \
wb_monitor.c \
dialogs.h \
dialogs.c \
+ search_projects.h \
+ search_projects.c \
menu.h \
menu.c \
popup_menu.h \
Modified: workbench/src/menu.c
29 lines changed, 29 insertions(+), 0 deletions(-)
===================================================================
@@ -27,6 +27,7 @@
#include "dialogs.h"
#include "menu.h"
#include "sidebar.h"
+#include "search_projects.h"
extern GeanyPlugin *geany_plugin;
@@ -37,6 +38,7 @@ typedef struct
GtkWidget *item_new;
GtkWidget *item_open;
GtkWidget *item_settings;
+ GtkWidget *item_search_projects;
GtkWidget *item_close;
}WB_MENU_DATA;
static WB_MENU_DATA menu_data;
@@ -58,12 +60,21 @@ void menu_set_context(MENU_CONTEXT context)
gtk_widget_set_sensitive(menu_data.item_new, FALSE);
gtk_widget_set_sensitive(menu_data.item_open, FALSE);
gtk_widget_set_sensitive(menu_data.item_settings, TRUE);
+ gtk_widget_set_sensitive(menu_data.item_search_projects, TRUE);
gtk_widget_set_sensitive(menu_data.item_close, TRUE);
break;
+ case MENU_CONTEXT_SEARCH_PROJECTS_SCANING:
+ gtk_widget_set_sensitive(menu_data.item_new, FALSE);
+ gtk_widget_set_sensitive(menu_data.item_open, FALSE);
+ gtk_widget_set_sensitive(menu_data.item_settings, TRUE);
+ gtk_widget_set_sensitive(menu_data.item_search_projects, FALSE);
+ gtk_widget_set_sensitive(menu_data.item_close, FALSE);
+ break;
case MENU_CONTEXT_WB_CLOSED:
gtk_widget_set_sensitive(menu_data.item_new, TRUE);
gtk_widget_set_sensitive(menu_data.item_open, TRUE);
gtk_widget_set_sensitive(menu_data.item_settings, FALSE);
+ gtk_widget_set_sensitive(menu_data.item_search_projects, FALSE);
gtk_widget_set_sensitive(menu_data.item_close, FALSE);
break;
}
@@ -164,6 +175,17 @@ static void item_workbench_settings_activate_cb(G_GNUC_UNUSED GtkMenuItem *menui
}
+/* The function handles the menu item "Search projects" */
+static void item_workbench_search_projects_activate_cb(G_GNUC_UNUSED GtkMenuItem *menuitem, G_GNUC_UNUSED gpointer user_data)
+{
+ if (wb_globals.opened_wb != NULL)
+ {
+ search_projects(wb_globals.opened_wb);
+ }
+ sidebar_update(SIDEBAR_CONTEXT_PROJECT_ADDED, NULL);
+}
+
+
/* The function handles the menu item "Close workbench" */
static void item_close_workbench_activate_cb(G_GNUC_UNUSED GtkMenuItem *menuitem, G_GNUC_UNUSED gpointer user_data)
{
@@ -206,6 +228,13 @@ gboolean menu_init(void)
g_signal_connect(menu_data.item_settings, "activate",
G_CALLBACK(item_workbench_settings_activate_cb), NULL);
+ /* Create new menu item "Search Projects" */
+ menu_data.item_search_projects = gtk_menu_item_new_with_mnemonic(_("Search _projects"));
+ gtk_widget_show(menu_data.item_search_projects);
+ gtk_menu_shell_append(GTK_MENU_SHELL (menu_data.menu), menu_data.item_search_projects);
+ g_signal_connect(menu_data.item_search_projects, "activate",
+ G_CALLBACK(item_workbench_search_projects_activate_cb), NULL);
+
/* Create new menu item "Close Workbench" */
menu_data.item_close = gtk_menu_item_new_with_mnemonic(_("_Close"));
gtk_widget_show(menu_data.item_close);
Modified: workbench/src/menu.h
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -24,6 +24,7 @@ typedef enum
MENU_CONTEXT_WB_CREATED,
MENU_CONTEXT_WB_OPENED,
MENU_CONTEXT_WB_CLOSED,
+ MENU_CONTEXT_SEARCH_PROJECTS_SCANING,
}MENU_CONTEXT;
void menu_set_context(MENU_CONTEXT context);
Modified: workbench/src/search_projects.c
537 lines changed, 537 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,537 @@
+/*
+ * Copyright 2017 LarsGit223
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * This file contains all the code for handling the "Search projects"
+ * menu item/action.
+ */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "wb_globals.h"
+#include "dialogs.h"
+#include "sidebar.h"
+#include "menu.h"
+
+
+typedef enum
+{
+ SCAN_DIR_STATE_ENTER,
+ SCAN_DIR_STATE_CONTINUE,
+}SCAN_DIR_STATE;
+
+
+enum
+{
+ SEARCH_PROJECTS_COLUMN_IMPORT,
+ SEARCH_PROJECTS_COLUMN_PATH,
+ SEARCH_PROJECTS_N_COLUMNS,
+};
+
+
+typedef struct
+{
+ gchar *path;
+ gchar *locale_path;
+ gchar *real_path;
+ GDir *dir;
+}SCAN_DIR_STATE_DATA;
+
+
+typedef struct
+{
+ SCAN_DIR_STATE state;
+ gchar *searchdir;
+ glong prj_count;
+ GHashTable *visited_paths;
+ GPtrArray *data;
+}SCAN_DIR_PARAMS;
+
+
+typedef struct S_SEARCH_PROJECTS_DIALOG
+{
+ gboolean stopped;
+ GtkWidget *dialog;
+ GtkWidget *vbox;
+ GtkWidget *label;
+ GtkWidget *label_dir;
+ GtkWidget *list_vbox;
+ GtkWidget *list_view;
+ GtkListStore *list_store;
+ SCAN_DIR_PARAMS *params;
+}SEARCH_PROJECTS_DIALOG;
+
+
+/** Shows the dialog "Select search directory".
+ *
+ * The dialog lets the user choose an existing folder.
+ *
+ * @return The filename
+ *
+ **/
+static gchar *dialogs_select_search_directory(void)
+{
+ gchar *filename = NULL;
+ GtkWidget *dialog;
+
+ dialog = gtk_file_chooser_dialog_new(_("Select search directory"),
+ GTK_WINDOW(wb_globals.geany_plugin->geany_data->main_widgets->window), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+ _("_Cancel"), GTK_RESPONSE_CANCEL,
+ _("_Add"), GTK_RESPONSE_ACCEPT, NULL);
+
+ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
+ {
+ filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+ }
+
+ gtk_widget_destroy(dialog);
+
+ return filename;
+}
+
+
+/* Free data used during searching.
+ Freeing the widgets is done by gtk through calling 'destroy()'. */
+static void search_projects_free_data(SEARCH_PROJECTS_DIALOG *data)
+{
+ if (data->params != NULL)
+ {
+ g_free(data->params->searchdir);
+ g_hash_table_destroy(data->params->visited_paths);
+ g_ptr_array_free(data->params->data, FALSE);
+ g_free(data->params);
+ data->params = NULL;
+ }
+
+ g_free(data);
+}
+
+
+/* Callback function for clicking on a list item */
+static void list_view_on_row_activated (GtkTreeView *treeview,
+ GtkTreePath *path, G_GNUC_UNUSED GtkTreeViewColumn *col, G_GNUC_UNUSED gpointer userdata)
+{
+ gboolean value;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ SEARCH_PROJECTS_DIALOG *data = userdata;
+
+ model = gtk_tree_view_get_model(treeview);
+
+ if (gtk_tree_model_get_iter(model, &iter, path))
+ {
+ gtk_tree_model_get(model, &iter, SEARCH_PROJECTS_COLUMN_IMPORT, &value, -1);
+ gtk_list_store_set(data->list_store, &iter,
+ SEARCH_PROJECTS_COLUMN_IMPORT, !value,
+ -1);
+ }
+}
+
+static void search_projects_shutdown(SEARCH_PROJECTS_DIALOG *data)
+{
+ /* Close and free dialog. */
+ gtk_widget_destroy(GTK_WIDGET(data->dialog));
+
+ menu_set_context(MENU_CONTEXT_WB_OPENED);
+
+ /* Free data. */
+ search_projects_free_data(data);
+}
+
+
+/* Handle "OK" and "Cancel" button. */
+static void dialog_on_button_pressed(GtkDialog *dialog, gint response_id,
+ gpointer user_data)
+{
+ gboolean value;
+ gchar *filename;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GError *error = NULL;
+ SEARCH_PROJECTS_DIALOG *data = user_data;
+
+ if (response_id == GTK_RESPONSE_ACCEPT)
+ {
+ model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->list_view));
+ if (gtk_tree_model_get_iter_first(model, &iter))
+ {
+ do
+ {
+ gtk_tree_model_get(model, &iter, SEARCH_PROJECTS_COLUMN_IMPORT, &value, -1);
+ if (value == TRUE)
+ {
+ gtk_tree_model_get(model, &iter, SEARCH_PROJECTS_COLUMN_PATH, &filename, -1);
+ workbench_add_project(wb_globals.opened_wb, filename);
+ }
+ }while (gtk_tree_model_iter_next(model, &iter));
+ }
+
+ /* Save the workbench file (.geanywb). */
+ if (!workbench_save(wb_globals.opened_wb, &error))
+ {
+ dialogs_show_msgbox(GTK_MESSAGE_INFO, _("Could not save workbench file: %s"), error->message);
+ }
+ sidebar_update(SIDEBAR_CONTEXT_PROJECT_ADDED, NULL);
+ }
+
+
+ if (response_id == GTK_RESPONSE_ACCEPT ||
+ response_id == GTK_RESPONSE_CANCEL ||
+ data->stopped == TRUE)
+ {
+ search_projects_shutdown(data);
+ }
+ else
+ {
+ /* Set stop marker (scanning might still be in progress). */
+ data->stopped = TRUE;
+ }
+}
+
+
+/* Push scan data on the stack. */
+static void scan_dir_data_push(SCAN_DIR_PARAMS *params, gchar *path,
+ gchar *locale_path, gchar *real_path, GDir *dir)
+{
+ SCAN_DIR_STATE_DATA *state_data;
+
+ state_data = g_new0(SCAN_DIR_STATE_DATA, 1);
+ state_data->path = path;
+ state_data->locale_path = locale_path;
+ state_data->real_path = real_path;
+ state_data->dir = dir;
+
+ g_ptr_array_add(params->data, state_data);
+}
+
+
+/* Pop scan data from the stack. */
+static void scan_dir_data_pop(SCAN_DIR_PARAMS *params)
+{
+ SCAN_DIR_STATE_DATA *state_data;
+
+ if (params->data->len > 0)
+ {
+ state_data = params->data->pdata[params->data->len - 1];
+ g_free(state_data->path);
+ g_free(state_data->locale_path);
+ g_free(state_data->real_path);
+
+ g_ptr_array_remove_index(params->data, params->data->len - 1);
+ }
+}
+
+
+/* The function needs to be called if scanning comes to an end (scanning
+ done or an error occurred. */
+static void search_projects_scan_directory_end (SEARCH_PROJECTS_DIALOG *data)
+{
+ gchar *text;
+
+ if (data->stopped == FALSE)
+ {
+ text = g_strdup_printf(_("Found %lu project files in directory \"%s\".\nPlease select the projects to add to the workbench."),
+ data->params->prj_count, data->params->searchdir);
+ gtk_label_set_text((GtkLabel *)data->label, text);
+ g_free(text);
+
+ gtk_widget_destroy(data->label_dir);
+ gtk_widget_set_sensitive(data->dialog, TRUE);
+
+ data->stopped = TRUE;
+ }
+ else
+ {
+ /* Dialog has been deleted as timer was running. */
+ search_projects_shutdown(data);
+ }
+}
+
+
+/* Start/continue scanning of the directory. This is a timer callback
+ function to enable working with geany during long scans instead of
+ blocking everything. */
+static gboolean search_projects_scan_directory_do_work (gpointer user_data)
+{
+ SEARCH_PROJECTS_DIALOG *data = user_data;
+ SCAN_DIR_STATE_DATA *state_data;
+ gchar *text;
+ guint repeats = 0;
+
+ if (data->stopped == TRUE ||
+ data->params->data->len == 0)
+ {
+ /* Abort. */
+ search_projects_scan_directory_end(data);
+ return FALSE;
+ }
+
+ while (repeats < 50)
+ {
+ const gchar *locale_name;
+ gchar *locale_filename, *utf8_filename, *utf8_name;
+ GtkTreeIter iter;
+
+ if (data->stopped == TRUE)
+ {
+ /* Abort. */
+ search_projects_scan_directory_end(data);
+ return FALSE;
+ }
+
+ repeats++;
+ state_data = data->params->data->pdata[data->params->data->len - 1];
+
+ if (data->params->state == SCAN_DIR_STATE_ENTER)
+ {
+ /* Data must already be on the stack. */
+
+ /* Add missing state data. */
+ state_data->locale_path = utils_get_locale_from_utf8(state_data->path);
+ state_data->real_path = utils_get_real_path(state_data->locale_path);
+
+ if (state_data->real_path &&
+ g_hash_table_lookup(data->params->visited_paths, state_data->real_path))
+ {
+ /* Seen this already. Leave dir. */
+ scan_dir_data_pop(data->params);
+ data->params->state = SCAN_DIR_STATE_CONTINUE;
+ return TRUE;
+ }
+
+ state_data->dir = g_dir_open(state_data->locale_path, 0, NULL);
+ if (!state_data->dir || !state_data->real_path)
+ {
+ if (state_data->dir != NULL)
+ {
+ g_dir_close(state_data->dir);
+ }
+
+ /* Abort on error. */
+ search_projects_scan_directory_end(data);
+ return FALSE;
+ }
+
+ g_hash_table_insert(data->params->visited_paths, g_strdup(state_data->real_path), GINT_TO_POINTER(1));
+
+ text = g_strdup_printf("%s", state_data->locale_path);
+ gtk_label_set_text((GtkLabel *)data->label_dir, text);
+ g_free(text);
+ }
+
+
+ if (data->params->data->len == 0)
+ {
+ /* Internal error. Abort. */
+ search_projects_scan_directory_end(data);
+ return FALSE;
+ }
+ data->params->state = SCAN_DIR_STATE_CONTINUE;
+ state_data = data->params->data->pdata[data->params->data->len - 1];
+
+ /* Get next directory entry. */
+ locale_name = g_dir_read_name(state_data->dir);
+ if (!locale_name)
+ {
+ g_dir_close(state_data->dir);
+ scan_dir_data_pop(data->params);
+ break;
+ }
+
+ utf8_name = utils_get_utf8_from_locale(locale_name);
+ locale_filename = g_build_filename(state_data->locale_path, locale_name, NULL);
+ utf8_filename = utils_get_utf8_from_locale(locale_filename);
+
+ if (g_file_test(locale_filename, G_FILE_TEST_IS_DIR))
+ {
+ scan_dir_data_push(data->params, g_strdup(locale_filename), NULL, NULL, NULL);
+ data->params->state = SCAN_DIR_STATE_ENTER;
+ }
+ else if (g_file_test(locale_filename, G_FILE_TEST_IS_REGULAR))
+ {
+ if (g_str_has_suffix(utf8_name, ".geany"))
+ {
+ data->params->prj_count++;
+ gtk_list_store_append (data->list_store, &iter);
+ gtk_list_store_set (data->list_store, &iter,
+ SEARCH_PROJECTS_COLUMN_PATH, locale_filename,
+ SEARCH_PROJECTS_COLUMN_IMPORT, FALSE,
+ -1);
+ }
+ }
+
+ g_free(utf8_filename);
+ g_free(locale_filename);
+ g_free(utf8_name);
+ }
+
+ if (data->params->data->len == 0)
+ {
+ /* Finished. */
+ search_projects_scan_directory_end(data);
+ return FALSE;
+ }
+
+ /* Continue. */
+ return TRUE;
+}
+
+
+/* The function prepares the required data for scaning and starts a timer
+ for calling 'search_projects_scan_directory_do_work()' periodically
+ until work is done. */
+static void search_projects_scan_directory_start (const gchar *searchdir, SEARCH_PROJECTS_DIALOG *data)
+{
+ SCAN_DIR_PARAMS *params;
+
+ params = g_new0(SCAN_DIR_PARAMS, 1);
+
+ params->state = SCAN_DIR_STATE_ENTER;
+ params->searchdir = g_strdup(searchdir);
+ params->prj_count = 0;
+ params->visited_paths = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+ params->data = g_ptr_array_new();
+
+ scan_dir_data_push(params, g_strdup(searchdir), NULL, NULL, NULL);
+ data->params = params;
+
+ menu_set_context(MENU_CONTEXT_SEARCH_PROJECTS_SCANING);
+ plugin_timeout_add(wb_globals.geany_plugin, 1, search_projects_scan_directory_do_work, data);
+}
+
+
+/** Search for projects.
+ *
+ * Search for projects to be added to the workbench. First the function
+ * 'dialogs_select_search_directory()' is called to open the dialog
+ * "Select search directory". Scanning then started by calling
+ * 'search_projects_scan_directory_start()'. The dialog shows a list
+ * of found project files ("*.geany") and is held insenstive until search
+ * has finished. Then the user can check the projects we likes to add.
+ * Clicking "OK" then makes the projects being added to the workbench.
+ * Clicking "Cancel" or closing the dialog aborts everything and the
+ * workbench is un-changed.
+ *
+ * @param wb The workbench to add the found/selected projects to.
+ *
+ **/
+void search_projects(WORKBENCH *wb)
+{
+ gchar *directory;
+ GtkWidget *content_area;
+ GtkDialogFlags flags;
+ GtkWidget *scrollwin;
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+ GtkTreeSelection *sel;
+ GList *focus_chain = NULL;
+ SEARCH_PROJECTS_DIALOG *search_projects;
+
+ /* First, the user needs to select a directory to scan. */
+ directory = dialogs_select_search_directory();
+ if (directory == NULL)
+ {
+ return;
+ }
+
+ search_projects = g_new0(SEARCH_PROJECTS_DIALOG, 1);
+
+ /* Create the widgets */
+ flags = GTK_DIALOG_DESTROY_WITH_PARENT;
+ search_projects->dialog = gtk_dialog_new_with_buttons(_("Search projects"),
+ GTK_WINDOW(wb_globals.geany_plugin->geany_data->main_widgets->window),
+ flags,
+ _("_Cancel"), GTK_RESPONSE_CANCEL,
+ _("_OK"), GTK_RESPONSE_ACCEPT,
+ NULL);
+ g_signal_connect(search_projects->dialog, "response", G_CALLBACK(dialog_on_button_pressed), search_projects);
+ content_area = gtk_dialog_get_content_area(GTK_DIALOG (search_projects->dialog));
+ gtk_widget_set_sensitive(search_projects->dialog, FALSE);
+
+ /* VBox for the list view */
+ search_projects->vbox = gtk_vbox_new(FALSE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(search_projects->vbox), 12);
+
+
+ /* List view */
+ search_projects->list_view = gtk_tree_view_new();
+ g_signal_connect(search_projects->list_view, "row-activated", (GCallback)list_view_on_row_activated, search_projects);
+
+ search_projects->list_store = gtk_list_store_new(SEARCH_PROJECTS_N_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING);
+ gtk_tree_view_set_model(GTK_TREE_VIEW(search_projects->list_view), GTK_TREE_MODEL(search_projects->list_store));
+
+ column = gtk_tree_view_column_new();
+ gtk_tree_view_column_set_spacing(column, 10);
+ gtk_tree_view_column_set_resizable(column, FALSE);
+ gtk_tree_view_column_set_title(column, _("Add to workbench?"));
+ renderer = gtk_cell_renderer_toggle_new();
+ gtk_tree_view_column_pack_start(column, renderer, FALSE);
+ gtk_tree_view_column_add_attribute(column, renderer, "active", SEARCH_PROJECTS_COLUMN_IMPORT);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(search_projects->list_view), column);
+
+ column = gtk_tree_view_column_new();
+ gtk_tree_view_column_set_spacing(column, 10);
+ gtk_tree_view_column_set_resizable (column, TRUE);
+ gtk_tree_view_column_set_title(column, _("Project path"));
+ renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_column_pack_start(column, renderer, TRUE);
+ gtk_tree_view_column_add_attribute(column, renderer, "text", SEARCH_PROJECTS_COLUMN_PATH);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(search_projects->list_view), column);
+
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(search_projects->list_view), TRUE);
+ gtk_tree_view_set_enable_search(GTK_TREE_VIEW(search_projects->list_view), FALSE);
+
+ ui_widget_modify_font_from_string(search_projects->list_view,
+ wb_globals.geany_plugin->geany_data->interface_prefs->tagbar_font);
+
+ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(search_projects->list_view));
+ gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
+
+ /*Add label to vbox */
+ search_projects->label = gtk_label_new (_("Scanning directory:"));
+ gtk_box_pack_start(GTK_BOX(search_projects->vbox), search_projects->label, FALSE, FALSE, 6);
+
+ /*Add label for current directory to vbox */
+ search_projects->label_dir = gtk_label_new (NULL);
+ gtk_box_pack_start(GTK_BOX(search_projects->vbox), search_projects->label_dir, FALSE, FALSE, 6);
+
+ /*Add list view to vbox */
+ focus_chain = g_list_prepend(focus_chain, search_projects->list_view);
+ gtk_container_set_focus_chain(GTK_CONTAINER(search_projects->vbox), focus_chain);
+ g_list_free(focus_chain);
+ scrollwin = gtk_scrolled_window_new(NULL, NULL);
+ gtk_widget_set_size_request(scrollwin, 400, 200);
+#if GTK_CHECK_VERSION(3, 0, 0)
+ gtk_widget_set_vexpand(scrollwin, TRUE);
+#endif
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_container_add(GTK_CONTAINER(scrollwin), search_projects->list_view);
+ gtk_box_pack_start(GTK_BOX(search_projects->vbox), scrollwin, TRUE, TRUE, 0);
+
+ gtk_widget_show_all(search_projects->vbox);
+
+ gtk_container_add(GTK_CONTAINER (content_area), search_projects->vbox);
+ gtk_widget_show_all(search_projects->dialog);
+
+ search_projects_scan_directory_start(directory, search_projects);
+ g_free(directory);
+
+ return;
+}
Modified: workbench/src/search_projects.h
24 lines changed, 24 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2019 LarsGit223
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __WB_SEARCH_PROJECTS_H__
+#define __WB_SEARCH_PROJECTS_H__
+
+void search_projects(WORKBENCH *wb);
+
+#endif
Modified: workbench/src/sidebar.c
3 lines changed, 2 insertions(+), 1 deletions(-)
===================================================================
@@ -883,7 +883,8 @@ static void sidebar_update_workbench(GtkTreeIter *iter, gint *position)
if (count == 0)
{
gtk_tree_store_clear(sidebar.file_store);
- sidebar_show_intro_message(_("Add a project\nusing the context menu."), TRUE);
+ sidebar_show_intro_message(_("Add a project using the context menu\n"
+ "or select \"Search projects\" from the menu."), TRUE);
}
else
{
Modified: workbench/src/workbench.c
6 lines changed, 6 insertions(+), 0 deletions(-)
===================================================================
@@ -534,6 +534,12 @@ gboolean workbench_add_project(WORKBENCH *wb, const gchar *filename)
/* Load project to import base path. */
wb_project_load(project, filename, NULL);
+ /* Start immediate scan if enabled. */
+ if (wb->rescan_projects_on_open == TRUE)
+ {
+ wb_project_rescan(project);
+ }
+
wb->modified = TRUE;
return TRUE;
}
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
More information about the Plugins-Commits
mailing list