Branch: refs/heads/master Author: LarsGit223 LarsGit223@users.noreply.github.com Committer: GitHub noreply@github.com Date: Thu, 11 Jul 2019 17:42:49 UTC Commit: b456154457195ed686b97748e626d8eda6112387 https://github.com/geany/geany-plugins/commit/b456154457195ed686b97748e626d8...
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).
plugins-commits@lists.geany.org