[geany/geany-plugins] 6dfe1b: workbench: added option to let git decide which files to display

LarsGit223 git-noreply at xxxxx
Thu Jul 18 19:17:45 UTC 2019


Branch:      refs/heads/master
Author:      LarsGit223 <lars_paulsen at web.de>
Committer:   LarsGit223 <lars_paulsen at web.de>
Date:        Thu, 18 Jul 2019 19:17:45 UTC
Commit:      6dfe1b64c1fa5f4a51738aaa1daa9b7cf8e32c47
             https://github.com/geany/geany-plugins/commit/6dfe1b64c1fa5f4a51738aaa1daa9b7cf8e32c47

Log Message:
-----------
workbench: added option to let git decide which files to display

In the directory settings it is now possible to choose between a
workbench or a git file filter. The later is new and lets git decide
which files to display depending on the contents of the .gitignore
file.

This also adds a new function to the utils-lib called
'gp_filelist_scan_directory_callback()'.


Modified Paths:
--------------
    build/workbench.m4
    utils/src/filelist.c
    utils/src/filelist.h
    workbench/README
    workbench/src/Makefile.am
    workbench/src/dialogs.c
    workbench/src/dialogs.h
    workbench/src/plugin_main.c
    workbench/src/popup_menu.c
    workbench/src/utils.c
    workbench/src/utils.h
    workbench/src/wb_project.c
    workbench/src/wb_project.h

Modified: build/workbench.m4
3 lines changed, 3 insertions(+), 0 deletions(-)
===================================================================
@@ -3,6 +3,9 @@ AC_DEFUN([GP_CHECK_WORKBENCH],
     GP_ARG_DISABLE([Workbench], [auto])
     GP_CHECK_UTILSLIB([Workbench])
 
+    GP_CHECK_PLUGIN_DEPS([Workbench], [WORKBENCH],
+                         [libgit2 >= 0.21])
+
     GP_COMMIT_PLUGIN_STATUS([Workbench])
     AC_CONFIG_FILES([
         workbench/Makefile


Modified: utils/src/filelist.c
109 lines changed, 107 insertions(+), 2 deletions(-)
===================================================================
@@ -39,6 +39,16 @@ typedef struct
 ScanDirParams;
 
 
+typedef struct
+{
+	GSList *filelist;
+	GHashTable *visited_paths;
+	void (*callback)(const gchar *path, gboolean *add, gboolean *enter, void *userdata);
+	void *userdata;
+}
+ScanDirParamsCallback;
+
+
 /** Get precompiled patterns.
  *
  * The function builds the precompiled patterns for @a patterns and returns them
@@ -48,7 +58,7 @@ ScanDirParams;
  * @return Pointer to GSList of patterns or NULL if patterns == NULL
  *
  **/
-static GSList *filelist_get_precompiled_patterns(gchar **patterns)
+GSList *filelist_get_precompiled_patterns(gchar **patterns)
 {
 	guint i;
 	GSList *pattern_list = NULL;
@@ -74,7 +84,7 @@ static GSList *filelist_get_precompiled_patterns(gchar **patterns)
  * @return TRUE if str matches the pattern, FALSE otherwise
  *
  **/
-static gboolean filelist_patterns_match(GSList *patterns, const gchar *str)
+gboolean filelist_patterns_match(GSList *patterns, const gchar *str)
 {
 	GSList *elem = NULL;
 	foreach_slist (elem, patterns)
@@ -360,3 +370,98 @@ gboolean gp_filelist_filepath_matches_patterns(const gchar *filepath, gchar **fi
 
 	return match;
 }
+
+
+/* Scan directory searchdir. Let a callback-function decide which files
+   to add and which directories to enter/crawl. */
+static void filelist_scan_directory_callback_int(const gchar *searchdir, ScanDirParamsCallback *params)
+{
+	GDir *dir;
+	gchar *locale_path = utils_get_locale_from_utf8(searchdir);
+	gchar *real_path = utils_get_real_path(locale_path);
+
+	dir = g_dir_open(locale_path, 0, NULL);
+	if (!dir || !real_path || g_hash_table_lookup(params->visited_paths, real_path))
+	{
+		if (dir != NULL)
+		{
+			g_dir_close(dir);
+		}
+		g_free(locale_path);
+		g_free(real_path);
+		return;
+	}
+
+	g_hash_table_insert(params->visited_paths, real_path, GINT_TO_POINTER(1));
+
+	while (TRUE)
+	{
+		const gchar *locale_name;
+		gchar *locale_filename, *utf8_filename, *utf8_name;
+		gboolean add, enter;
+
+		locale_name = g_dir_read_name(dir);
+		if (!locale_name)
+		{
+			break;
+		}
+
+		utf8_name = utils_get_utf8_from_locale(locale_name);
+		locale_filename = g_build_filename(locale_path, locale_name, NULL);
+		utf8_filename = utils_get_utf8_from_locale(locale_filename);
+
+		/* Call user callback. */
+		params->callback(locale_filename, &add, &enter, params->userdata);
+
+		/* Should the file/path be added to the list? */
+		if (add)
+		{
+			params->filelist = g_slist_prepend(params->filelist, g_strdup(utf8_filename));
+		}
+
+		/* If the path is a directory, should it be entered? */
+		if (enter && g_file_test(locale_filename, G_FILE_TEST_IS_DIR))
+		{
+			filelist_scan_directory_callback_int(utf8_filename, params);
+		}
+
+		g_free(utf8_filename);
+		g_free(locale_filename);
+		g_free(utf8_name);
+	}
+
+	g_dir_close(dir);
+	g_free(locale_path);
+}
+
+
+/** Scan a directory and return a list of files and directories.
+ *
+ * The function scans directory searchdir and returns a list of files.
+ * The list will only include files for which the callback function returned
+ * 'add == TRUE'. Sub-directories will only be scanned if the callback function
+ * returned 'enter == TRUE'.
+ * 
+ * @param searchdir Directory which shall be scanned
+ * @param callback  Function to be called to decide which files to add to
+ *                  the list and to decide which sub-directories to enter
+ *                  or to ignore.
+ * @param userdata  A pointer which is transparently passed through
+ *                  to the callback function.
+ * @return GSList of matched files
+ *
+ **/
+GSList *gp_filelist_scan_directory_callback(const gchar *searchdir,
+	void (*callback)(const gchar *path, gboolean *add, gboolean *enter, void *userdata),
+	void *userdata)
+{
+	ScanDirParamsCallback params = { 0 };
+
+	params.callback = callback;
+	params.userdata = userdata;
+	params.visited_paths = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+	filelist_scan_directory_callback_int(searchdir, &params);
+	g_hash_table_destroy(params.visited_paths);
+
+	return params.filelist;
+}


Modified: utils/src/filelist.h
5 lines changed, 5 insertions(+), 0 deletions(-)
===================================================================
@@ -28,12 +28,17 @@ typedef enum
 	FILELIST_FLAG_ADD_DIRS = 1,
 }FILELIST_FLAG;
 
+GSList *filelist_get_precompiled_patterns(gchar **patterns);
+gboolean filelist_patterns_match(GSList *patterns, const gchar *str);
 GSList *gp_filelist_scan_directory(guint *files, guint *folders, const gchar *searchdir, gchar **file_patterns,
 		gchar **ignored_dirs_patterns, gchar **ignored_file_patterns);
 GSList *gp_filelist_scan_directory_full(guint *files, guint *folders, const gchar *searchdir, gchar **file_patterns,
 		gchar **ignored_dirs_patterns, gchar **ignored_file_patterns, guint flags);
 gboolean gp_filelist_filepath_matches_patterns(const gchar *filepath, gchar **file_patterns,
 		gchar **ignored_dirs_patterns, gchar **ignored_file_patterns);
+GSList *gp_filelist_scan_directory_callback(const gchar *searchdir,
+	void (*callback)(const gchar *path, gboolean *add, gboolean *enter, void *userdata),
+	void *userdata);
 
 G_END_DECLS
 


Modified: workbench/README
8 lines changed, 6 insertions(+), 2 deletions(-)
===================================================================
@@ -93,8 +93,12 @@ These are the available items:
 **Directory settings**
   Select this item to change the directory settings. It is only available
   if you right clicked inside of a project directory. In the directory
-  settings you can set a filter which controls the files and sub-directories
-  that will be displayed or not.
+  settings you can set filters which control the files and sub-directories
+  that will be displayed or not. You can choose between a filter mechanism
+  controlled by the workbench plugin or controlled by git. In the later case
+  the .gitignore settings decide which files are displayed and which not.
+  This option is only available if the directory is/contains a git
+  repository.
 
 **Fold/unfold directory**
   Fold or unfold the items belonging to the directory. It is only available


Modified: workbench/src/Makefile.am
3 lines changed, 2 insertions(+), 1 deletions(-)
===================================================================
@@ -30,9 +30,10 @@ workbench_la_SOURCES = \
 
 workbench_la_CPPFLAGS = $(AM_CPPFLAGS) \
 	-DG_LOG_DOMAIN=\"Workbench\"
-workbench_la_CFLAGS = $(AM_CFLAGS) \
+workbench_la_CFLAGS = $(AM_CFLAGS) $(WORKBENCH_CFLAGS) \
 	-I$(top_srcdir)/utils/src
 workbench_la_LIBADD = $(COMMONLIBS) \
+	$(WORKBENCH_LIBS) \
 	$(top_builddir)/utils/src/libgeanypluginutils.la
 include $(top_srcdir)/build/cppcheck.mk
 


Modified: workbench/src/dialogs.c
227 lines changed, 166 insertions(+), 61 deletions(-)
===================================================================
@@ -25,6 +25,7 @@
 
 #include "wb_globals.h"
 #include "dialogs.h"
+#include "utils.h"
 
 extern GeanyPlugin *geany_plugin;
 
@@ -265,20 +266,65 @@ static gchar **split_patterns(const gchar *str)
 	return ret;
 }
 
+typedef struct S_DIALOG_DIR_SETTINGS_DATA
+{
+	GtkWidget *dialog;
+	GtkWidget *w_label_file_patterns;
+	GtkWidget *w_file_patterns;
+	GtkWidget *w_label_ignored_dirs_patterns;
+	GtkWidget *w_ignored_dirs_patterns;
+	GtkWidget *w_label_ignored_file_patterns;
+	GtkWidget *w_ignored_file_patterns;
+	GtkWidget *w_scan_mode_wb;
+	GtkWidget *w_scan_mode_git;
+}DIALOG_DIR_SETTINGS_DATA;
+
+static void button_filter_workbench_toggled(GtkToggleButton *togglebutton,
+											gpointer user_data)
+{
+	DIALOG_DIR_SETTINGS_DATA *data;
+
+	data = user_data;
+	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->w_scan_mode_wb)))
+	{
+		gtk_widget_set_sensitive (data->w_label_file_patterns, TRUE);
+		gtk_widget_set_sensitive (data->w_file_patterns, TRUE);
+		gtk_widget_set_sensitive (data->w_label_ignored_dirs_patterns, TRUE);
+		gtk_widget_set_sensitive (data->w_ignored_dirs_patterns, TRUE);
+		gtk_widget_set_sensitive (data->w_label_ignored_file_patterns, TRUE);
+		gtk_widget_set_sensitive (data->w_ignored_file_patterns, TRUE);
+	}
+	else
+	{
+		gtk_widget_set_sensitive (data->w_label_file_patterns, FALSE);
+		gtk_widget_set_sensitive (data->w_file_patterns, FALSE);
+		gtk_widget_set_sensitive (data->w_label_ignored_dirs_patterns, FALSE);
+		gtk_widget_set_sensitive (data->w_ignored_dirs_patterns, FALSE);
+		gtk_widget_set_sensitive (data->w_label_ignored_file_patterns, FALSE);
+		gtk_widget_set_sensitive (data->w_ignored_file_patterns, FALSE);
+	}
+}
+
+static void button_filter_git_toggled(GtkToggleButton *togglebutton,
+									gpointer user_data)
+{
+	/* Nothing to do for now... */
+}
 
 /** Shows the directory settings dialog.
  *
  * The dialog lets the user edit the settings for file patterns, irnored file patterns and
  * ignored directories patterns. On accept the result is directly stored in @a directory.
  *
+ * @param  project   The project to which directory belongs to
  * @param  directory Location of WB_PROJECT_DIR to store the settings into
  * @return TRUE if the settings have changed, FALSE otherwise
  *
  **/
-gboolean dialogs_directory_settings(WB_PROJECT_DIR *directory)
+gboolean dialogs_directory_settings(WB_PROJECT *project, WB_PROJECT_DIR *directory)
 {
-	GtkWidget *w_file_patterns, *w_ignored_dirs_patterns, *w_ignored_file_patterns;
-	GtkWidget *dialog, *label, *content_area;
+	DIALOG_DIR_SETTINGS_DATA *data;
+	GtkWidget *label, *content_area;
 	GtkWidget *vbox, *hbox, *hbox1;
 #if GTK_CHECK_VERSION(3, 4, 0)
 	GtkWidget *grid;
@@ -287,17 +333,22 @@ gboolean dialogs_directory_settings(WB_PROJECT_DIR *directory)
 #endif
 	GtkDialogFlags flags;
 	gchar *file_patterns_old, *ignored_file_patterns_old, *ignored_dirs_patterns_old;
+	WB_PROJECT_SCAN_MODE scan_mode_old, scan_mode;
+	gchar *abs_path;
 	gboolean changed;
+	guint row = 0;
+
+	data = g_new0(DIALOG_DIR_SETTINGS_DATA, 1);
 
 	/* Create the widgets */
 	flags = GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT;
-	dialog = gtk_dialog_new_with_buttons(_("Directory settings"),
-										 GTK_WINDOW(wb_globals.geany_plugin->geany_data->main_widgets->window),
-										 flags,
-										 _("_Cancel"), GTK_RESPONSE_CANCEL,
-										 _("_OK"), GTK_RESPONSE_ACCEPT,
-										 NULL);
-	content_area = gtk_dialog_get_content_area(GTK_DIALOG (dialog));
+	data->dialog = gtk_dialog_new_with_buttons(_("Directory settings"),
+											   GTK_WINDOW(wb_globals.geany_plugin->geany_data->main_widgets->window),
+											   flags,
+											   _("_Cancel"), GTK_RESPONSE_CANCEL,
+											   _("_OK"), GTK_RESPONSE_ACCEPT,
+											   NULL);
+	content_area = gtk_dialog_get_content_area(GTK_DIALOG (data->dialog));
 
 	vbox = gtk_vbox_new(FALSE, 0);
 
@@ -311,87 +362,105 @@ gboolean dialogs_directory_settings(WB_PROJECT_DIR *directory)
 	gtk_table_set_col_spacings(GTK_TABLE(table), 10);
 #endif
 
-	label = gtk_label_new(_("File patterns:"));
+	data->w_scan_mode_wb = gtk_radio_button_new_with_label (NULL, _("filter files using the workbench plugin"));
+	g_signal_connect(data->w_scan_mode_wb, "toggled",
+			G_CALLBACK(button_filter_workbench_toggled), data);
+	gtk_box_pack_start(GTK_BOX(vbox), data->w_scan_mode_wb, FALSE, FALSE, 6);
+
+	data->w_label_file_patterns = gtk_label_new(_("File patterns:"));
 #if GTK_CHECK_VERSION(3, 16, 0)
-	gtk_label_set_xalign (GTK_LABEL(label), 0);
-	gtk_label_set_yalign (GTK_LABEL(label), 0);
+	gtk_label_set_xalign (GTK_LABEL(data->w_label_file_patterns), 0);
+	gtk_label_set_yalign (GTK_LABEL(data->w_label_file_patterns), 0);
 #else
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+	gtk_misc_set_alignment(GTK_MISC(data->w_label_file_patterns), 0, 0);
 #endif
-	w_file_patterns = gtk_entry_new();
+	data->w_file_patterns = gtk_entry_new();
 #if GTK_CHECK_VERSION(3, 4, 0)
-	gtk_grid_attach (GTK_GRID(grid), label, 0, 0, 1, 1);
-	gtk_grid_attach (GTK_GRID(grid), w_file_patterns, 1, 0, 1, 1);
-	gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
-	gtk_widget_set_hexpand (label, FALSE);
-	gtk_widget_set_valign (w_file_patterns, GTK_ALIGN_BASELINE);
-	gtk_widget_set_hexpand (w_file_patterns, TRUE);
+	gtk_grid_attach (GTK_GRID(grid), data->w_label_file_patterns, 0, row, 1, 1);
+	gtk_grid_attach (GTK_GRID(grid), data->w_file_patterns, 1, row, 1, 1);
+	gtk_widget_set_valign (data->w_label_file_patterns, GTK_ALIGN_BASELINE);
+	gtk_widget_set_hexpand (data->w_label_file_patterns, FALSE);
+	gtk_widget_set_valign (data->w_file_patterns, GTK_ALIGN_BASELINE);
+	gtk_widget_set_hexpand (data->w_file_patterns, TRUE);
 #else
-	ui_table_add_row(GTK_TABLE(table), 0, label, w_file_patterns, NULL);
+	ui_table_add_row(GTK_TABLE(table), row + 1, data->w_label_file_patterns, data->w_file_patterns, NULL);
 #endif
-	ui_entry_add_clear_icon(GTK_ENTRY(w_file_patterns));
-	gtk_widget_set_tooltip_text(w_file_patterns,
+	row++;
+	ui_entry_add_clear_icon(GTK_ENTRY(data->w_file_patterns));
+	gtk_widget_set_tooltip_text(data->w_file_patterns,
 		_("Space separated list of patterns that are used to identify files "
 		  "that shall be displayed in the directory tree."));
 	file_patterns_old = g_strjoinv(" ", wb_project_dir_get_file_patterns(directory));
-	gtk_entry_set_text(GTK_ENTRY(w_file_patterns), file_patterns_old);
+	gtk_entry_set_text(GTK_ENTRY(data->w_file_patterns), file_patterns_old);
 
-	label = gtk_label_new(_("Ignored file patterns:"));
+	data->w_label_ignored_file_patterns = gtk_label_new(_("Ignored file patterns:"));
 #if GTK_CHECK_VERSION(3, 16, 0)
-	gtk_label_set_xalign (GTK_LABEL(label), 0);
-	gtk_label_set_yalign (GTK_LABEL(label), 0);
+	gtk_label_set_xalign (GTK_LABEL(data->w_label_ignored_file_patterns), 0);
+	gtk_label_set_yalign (GTK_LABEL(data->w_label_ignored_file_patterns), 0);
 #else
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+	gtk_misc_set_alignment(GTK_MISC(data->w_label_ignored_file_patterns), 0, 0);
 #endif
-	w_ignored_file_patterns = gtk_entry_new();
-	ui_entry_add_clear_icon(GTK_ENTRY(w_ignored_file_patterns));
+	data->w_ignored_file_patterns = gtk_entry_new();
+	ui_entry_add_clear_icon(GTK_ENTRY(data->w_ignored_file_patterns));
 #if GTK_CHECK_VERSION(3, 4, 0)
-	gtk_grid_attach (GTK_GRID(grid), label, 0, 1, 1, 1);
-	gtk_grid_attach (GTK_GRID(grid), w_ignored_file_patterns, 1, 1, 1, 1);
-	gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
-	gtk_widget_set_hexpand (label, FALSE);
-	gtk_widget_set_valign (w_ignored_file_patterns, GTK_ALIGN_BASELINE);
-	gtk_widget_set_hexpand (w_ignored_file_patterns, TRUE);
+	gtk_grid_attach (GTK_GRID(grid), data->w_label_ignored_file_patterns, 0, row, 1, 1);
+	gtk_grid_attach (GTK_GRID(grid), data->w_ignored_file_patterns, 1, row, 1, 1);
+	gtk_widget_set_valign (data->w_label_ignored_file_patterns, GTK_ALIGN_BASELINE);
+	gtk_widget_set_hexpand (data->w_label_ignored_file_patterns, FALSE);
+	gtk_widget_set_valign (data->w_ignored_file_patterns, GTK_ALIGN_BASELINE);
+	gtk_widget_set_hexpand (data->w_ignored_file_patterns, TRUE);
 #else
-	ui_table_add_row(GTK_TABLE(table), 2, label, w_ignored_file_patterns, NULL);
+	ui_table_add_row(GTK_TABLE(table), row + 1, data->w_label_ignored_file_patterns, data->w_ignored_file_patterns, NULL);
 #endif
-	gtk_widget_set_tooltip_text(w_ignored_file_patterns,
+	row++;
+	gtk_widget_set_tooltip_text(data->w_ignored_file_patterns,
 		_("Space separated list of patterns that are used to identify files "
 		  "that shall not be displayed in the directory tree."));
 	ignored_file_patterns_old = g_strjoinv(" ", wb_project_dir_get_ignored_file_patterns(directory));
-	gtk_entry_set_text(GTK_ENTRY(w_ignored_file_patterns), ignored_file_patterns_old);
+	gtk_entry_set_text(GTK_ENTRY(data->w_ignored_file_patterns), ignored_file_patterns_old);
 
-	label = gtk_label_new(_("Ignored directory patterns:"));
+	data->w_label_ignored_dirs_patterns = gtk_label_new(_("Ignored directory patterns:"));
 #if GTK_CHECK_VERSION(3, 16, 0)
-	gtk_label_set_xalign (GTK_LABEL(label), 0);
-	gtk_label_set_yalign (GTK_LABEL(label), 0);
+	gtk_label_set_xalign (GTK_LABEL(data->w_label_ignored_dirs_patterns), 0);
+	gtk_label_set_yalign (GTK_LABEL(data->w_label_ignored_dirs_patterns), 0);
 #else
-	gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+	gtk_misc_set_alignment(GTK_MISC(data->w_label_ignored_dirs_patterns), 0, 0);
 #endif
-	w_ignored_dirs_patterns = gtk_entry_new();
-	ui_entry_add_clear_icon(GTK_ENTRY(w_ignored_dirs_patterns));
+	data->w_ignored_dirs_patterns = gtk_entry_new();
+	ui_entry_add_clear_icon(GTK_ENTRY(data->w_ignored_dirs_patterns));
 #if GTK_CHECK_VERSION(3, 4, 0)
-	gtk_grid_attach (GTK_GRID(grid), label, 0, 2, 1, 1);
-	gtk_grid_attach (GTK_GRID(grid), w_ignored_dirs_patterns, 1, 2, 1, 1);
-	gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
-	gtk_widget_set_hexpand (label, FALSE);
-	gtk_widget_set_valign (w_ignored_dirs_patterns, GTK_ALIGN_BASELINE);
-	gtk_widget_set_hexpand (w_ignored_dirs_patterns, TRUE);
+	gtk_grid_attach (GTK_GRID(grid), data->w_label_ignored_dirs_patterns, 0, row, 1, 1);
+	gtk_grid_attach (GTK_GRID(grid), data->w_ignored_dirs_patterns, 1, row, 1, 1);
+	gtk_widget_set_valign (data->w_label_ignored_dirs_patterns, GTK_ALIGN_BASELINE);
+	gtk_widget_set_hexpand (data->w_label_ignored_dirs_patterns, FALSE);
+	gtk_widget_set_valign (data->w_ignored_dirs_patterns, GTK_ALIGN_BASELINE);
+	gtk_widget_set_hexpand (data->w_ignored_dirs_patterns, TRUE);
 #else
-	ui_table_add_row(GTK_TABLE(table), 3, label, w_ignored_dirs_patterns, NULL);
+	ui_table_add_row(GTK_TABLE(table), row + 1, data->w_label_ignored_dirs_patterns, data->w_ignored_dirs_patterns, NULL);
 #endif
-	gtk_widget_set_tooltip_text(w_ignored_dirs_patterns,
+	row++;
+	gtk_widget_set_tooltip_text(data->w_ignored_dirs_patterns,
 		_("Space separated list of patterns that are used to identify directories "
 		  "that shall not be scanned for source files."));
 	ignored_dirs_patterns_old = g_strjoinv(" ", wb_project_dir_get_ignored_dirs_patterns(directory));
-	gtk_entry_set_text(GTK_ENTRY(w_ignored_dirs_patterns), ignored_dirs_patterns_old);
+	gtk_entry_set_text(GTK_ENTRY(data->w_ignored_dirs_patterns), ignored_dirs_patterns_old);
 
+#if GTK_CHECK_VERSION(3, 12, 0)
+	gtk_widget_set_margin_start (grid, 32);
+#endif
 #if GTK_CHECK_VERSION(3, 4, 0)
 	gtk_box_pack_start(GTK_BOX(vbox), grid, FALSE, FALSE, 6);
 #else
 	gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 6);
 #endif
 
+	data->w_scan_mode_git = gtk_radio_button_new_with_label (
+		gtk_radio_button_get_group(GTK_RADIO_BUTTON (data->w_scan_mode_wb)),
+		_("filter files using git (.gitignore)"));
+	g_signal_connect(data->w_scan_mode_git, "toggled",
+			G_CALLBACK(button_filter_git_toggled), data);
+	gtk_box_pack_start(GTK_BOX(vbox), data->w_scan_mode_git, FALSE, FALSE, 6);
+
 	hbox1 = gtk_hbox_new(FALSE, 0);
 	label = gtk_label_new(_("Note: the patterns above affect only the workbench directory and are not used in the Find in Files\n"
 	"dialog."));
@@ -405,35 +474,71 @@ gboolean dialogs_directory_settings(WB_PROJECT_DIR *directory)
 	gtk_container_add(GTK_CONTAINER (content_area), label);
 	gtk_container_add(GTK_CONTAINER (content_area), hbox);
 
-	gtk_widget_show_all(dialog);
-	gint result = gtk_dialog_run(GTK_DIALOG(dialog));
+
+	scan_mode_old = wb_project_dir_get_scan_mode(directory);
+	abs_path = get_combined_path(wb_project_get_filename(project),
+		wb_project_dir_get_base_dir(directory));
+	if (!is_git_repository(abs_path))
+	{
+		/* Disable git filter option if the directory is not a git repository. */
+		gtk_widget_set_sensitive (data->w_scan_mode_git, FALSE);
+	}
+	else
+	{
+		/* Both options are possible, set the active option from
+		   the current settings. */
+		if (scan_mode_old == WB_PROJECT_SCAN_MODE_WORKBENCH)
+		{
+			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->w_scan_mode_wb), TRUE);
+		}
+		else
+		{
+			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->w_scan_mode_git), TRUE);
+		}
+	}
+	g_free(abs_path);
+
+
+	gtk_widget_show_all(data->dialog);
+	gint result = gtk_dialog_run(GTK_DIALOG(data->dialog));
 	changed = FALSE;
 	if (result == GTK_RESPONSE_ACCEPT)
 	{
 		const gchar *str;
 		gchar **file_patterns, **ignored_dirs_patterns, **ignored_file_patterns;
 
-		str = gtk_entry_get_text(GTK_ENTRY(w_file_patterns));
+		scan_mode = WB_PROJECT_SCAN_MODE_WORKBENCH;
+		if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->w_scan_mode_git)))
+		{
+			scan_mode = WB_PROJECT_SCAN_MODE_GIT;
+		}
+		if (scan_mode_old != scan_mode)
+		{
+			changed = TRUE;
+		}
+
+		str = gtk_entry_get_text(GTK_ENTRY(data->w_file_patterns));
 		if (g_strcmp0(str, file_patterns_old) != 0)
 		{
 			changed = TRUE;
 		}
 		file_patterns = split_patterns(str);
 
-		str = gtk_entry_get_text(GTK_ENTRY(w_ignored_dirs_patterns));
+		str = gtk_entry_get_text(GTK_ENTRY(data->w_ignored_dirs_patterns));
 		if (g_strcmp0(str, ignored_dirs_patterns_old) != 0)
 		{
 			changed = TRUE;
 		}
 		ignored_dirs_patterns = split_patterns(str);
 
-		str = gtk_entry_get_text(GTK_ENTRY(w_ignored_file_patterns));
+		str = gtk_entry_get_text(GTK_ENTRY(data->w_ignored_file_patterns));
 		if (g_strcmp0(str, ignored_file_patterns_old) != 0)
 		{
 			changed = TRUE;
 		}
 		ignored_file_patterns = split_patterns(str);
 
+		wb_project_dir_set_scan_mode(project, directory, scan_mode);
 		wb_project_dir_set_file_patterns(directory, file_patterns);
 		wb_project_dir_set_ignored_dirs_patterns(directory, ignored_dirs_patterns);
 		wb_project_dir_set_ignored_file_patterns(directory, ignored_file_patterns);
@@ -446,7 +551,7 @@ gboolean dialogs_directory_settings(WB_PROJECT_DIR *directory)
 	g_free(file_patterns_old);
 	g_free(ignored_file_patterns_old);
 	g_free(ignored_dirs_patterns_old);
-	gtk_widget_destroy(dialog);
+	gtk_widget_destroy(data->dialog);
 
 	return changed;
 }


Modified: workbench/src/dialogs.h
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -25,7 +25,7 @@ gchar *dialogs_create_new_workbench(void);
 gchar *dialogs_open_workbench(void);
 gchar *dialogs_add_project(void);
 gchar *dialogs_add_directory(WB_PROJECT *project);
-gboolean dialogs_directory_settings(WB_PROJECT_DIR *directory);
+gboolean dialogs_directory_settings(WB_PROJECT *project, WB_PROJECT_DIR *directory);
 gboolean dialogs_workbench_settings(WORKBENCH *workbench);
 
 #endif


Modified: workbench/src/plugin_main.c
16 lines changed, 15 insertions(+), 1 deletions(-)
===================================================================
@@ -25,6 +25,7 @@
 
 #include <sys/time.h>
 #include <string.h>
+#include <git2.h>
 
 #include <wb_globals.h>
 
@@ -34,6 +35,13 @@
 #include "idle_queue.h"
 #include "tm_control.h"
 
+
+#if ! defined (LIBGIT2_SOVERSION) || LIBGIT2_SOVERSION < 22
+# define git_libgit2_init     git_threads_init
+# define git_libgit2_shutdown git_threads_shutdown
+#endif
+
+
 GeanyPlugin *geany_plugin;
 GeanyData *geany_data;
 
@@ -80,6 +88,9 @@ static gboolean plugin_workbench_init(GeanyPlugin *plugin, G_GNUC_UNUSED gpointe
 	menu_set_context(MENU_CONTEXT_WB_CLOSED);
 	sidebar_show_intro_message(_("Create or open a workbench\nusing the workbench menu."), FALSE);
 
+	/* Init libgit2. */
+	git_libgit2_init();
+
 	return TRUE;
 }
 
@@ -90,6 +101,9 @@ static void plugin_workbench_cleanup(G_GNUC_UNUSED GeanyPlugin *plugin, G_GNUC_U
 	menu_cleanup();
 	sidebar_cleanup();
 	wb_tm_control_cleanup();
+
+	/* Shutdown/cleanup libgit2. */
+	git_libgit2_shutdown();
 }
 
 
@@ -117,7 +131,7 @@ void geany_load_module(GeanyPlugin *plugin)
 	/* Set metadata */
 	plugin->info->name = _("Workbench");
 	plugin->info->description = _("Manage and customize multiple projects.");
-	plugin->info->version = "1.08";
+	plugin->info->version = "1.09";
 	plugin->info->author = "LarsGit223";
 
 	/* Set functions */


Modified: workbench/src/popup_menu.c
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -432,7 +432,7 @@ static void popup_menu_on_directory_settings(G_GNUC_UNUSED GtkMenuItem * menuite
 	if (sidebar_file_view_get_selected_context(&context)
 		&& context.project != NULL && context.directory != NULL)
 	{
-		if (dialogs_directory_settings(context.directory))
+		if (dialogs_directory_settings(context.project, context.directory))
 		{
 			wb_project_set_modified(context.project, TRUE);
 			wb_project_dir_rescan(context.project, context.directory);


Modified: workbench/src/utils.c
13 lines changed, 13 insertions(+), 0 deletions(-)
===================================================================
@@ -292,3 +292,16 @@ void close_all_files_in_list(GPtrArray *list)
 		}
 	}
 }
+
+
+gboolean is_git_repository(gchar *path)
+{
+	gboolean is_git_repo;
+	gchar *git_path;
+
+	git_path = g_build_filename(path, ".git", NULL);
+	is_git_repo = g_file_test(git_path, G_FILE_TEST_IS_DIR);
+	g_free(git_path);
+
+	return is_git_repo;
+}


Modified: workbench/src/utils.h
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -28,5 +28,6 @@ gchar *get_combined_path(const gchar *base, const gchar *relative);
 gchar *get_any_relative_path (const gchar *base, const gchar *target);
 void open_all_files_in_list(GPtrArray *list);
 void close_all_files_in_list(GPtrArray *list);
+gboolean is_git_repository(gchar *path);
 
 #endif


Modified: workbench/src/wb_project.c
318 lines changed, 288 insertions(+), 30 deletions(-)
===================================================================
@@ -20,6 +20,7 @@
  * Code for the WB_PROJECT structure.
  */
 #include <glib/gstdio.h>
+#include <git2.h>
 
 #ifdef HAVE_CONFIG_H
 # include "config.h"
@@ -52,15 +53,29 @@ struct S_WB_PROJECT_DIR
 {
 	gchar *name;
 	gchar *base_dir;
+	WB_PROJECT_SCAN_MODE scan_mode;
 	gchar **file_patterns;	/**< Array of filename extension patterns. */
 	gchar **ignored_dirs_patterns;
 	gchar **ignored_file_patterns;
+	git_repository *git_repo;
 	guint file_count;
 	guint subdir_count;
 	GHashTable *file_table; /* contains all file names within base_dir */
 	gboolean is_prj_base_dir;
 };
 
+
+typedef struct
+{
+	guint file_count;
+	guint subdir_count;
+	GSList *file_patterns_list;
+	GSList *ignored_dirs_list;
+	GSList *ignored_file_list;
+	git_repository *git_repo;
+}SCAN_PARAMS;
+
+
 struct S_WB_PROJECT
 {
 	gchar     *filename;
@@ -202,6 +217,7 @@ static WB_PROJECT_DIR *wb_project_dir_new(WB_PROJECT *prj, const gchar *utf8_bas
 	WB_PROJECT_DIR *dir = g_new0(WB_PROJECT_DIR, 1);
 	dir->base_dir = g_strdup(utf8_base_dir);
 	dir->file_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+	dir->scan_mode = WB_PROJECT_SCAN_MODE_WORKBENCH;
 
 	offset = strlen(dir->base_dir)-1;
 	while (offset > 0
@@ -261,6 +277,7 @@ gboolean wb_project_dir_get_is_prj_base_dir (WB_PROJECT_DIR *directory)
 	return FALSE;
 }
 
+
 /** Get the name of a project dir.
  *
  * @param directory The project dir
@@ -415,6 +432,79 @@ gboolean wb_project_dir_set_ignored_file_patterns (WB_PROJECT_DIR *directory, gc
 }
 
 
+/** Get the scan mode of a project dir.
+ *
+ * @param directory The project dir
+ * @return WB_PROJECT_SCAN_MODE (the scan mode)
+ *
+ **/
+WB_PROJECT_SCAN_MODE wb_project_dir_get_scan_mode (WB_PROJECT_DIR *directory)
+{
+	if (directory != NULL)
+	{
+		return directory->scan_mode;
+	}
+
+	return WB_PROJECT_SCAN_MODE_INVALID;
+}
+
+
+/* Open or close the git repository in directory as required. */
+static void wb_project_dir_prepare_git_repo(WB_PROJECT *project, WB_PROJECT_DIR *directory)
+{
+	gchar *path;
+
+	path = get_combined_path(project->filename, directory->base_dir);
+	if (directory->scan_mode == WB_PROJECT_SCAN_MODE_GIT)
+	{
+		if (directory->git_repo == NULL)
+		{
+			if (git_repository_open(&(directory->git_repo), path) != 0)
+			{
+				directory->git_repo = NULL;
+				ui_set_statusbar(TRUE,
+					_("Failed to open git repository in folder %s."), path);
+			}
+			else
+			{
+				ui_set_statusbar(TRUE,
+					_("Opened git repository in folder %s."), path);
+			}
+		}
+	}
+	else
+	{
+		if (directory->git_repo != NULL)
+		{
+			git_repository_free(directory->git_repo);
+			directory->git_repo = NULL;
+			ui_set_statusbar(TRUE,
+				_("Closed git repository in folder %s."), path);
+		}
+	}
+	g_free(path);
+}
+
+
+/** Set the scan mode of a project dir.
+ *
+ * @param directory The project dir
+ * @param mode      The scan mode to set
+ * @return FALSE if directory is NULL, TRUE otherwise
+ *
+ **/
+gboolean wb_project_dir_set_scan_mode(WB_PROJECT *project, WB_PROJECT_DIR *directory, WB_PROJECT_SCAN_MODE mode)
+{
+	if (directory != NULL)
+	{
+		directory->scan_mode = mode;
+		wb_project_dir_prepare_git_repo(project, directory);
+		return TRUE;
+	}
+	return FALSE;
+}
+
+
 /* Remove all files contained in the project dir from the tm-workspace */
 static void wb_project_dir_remove_from_tm_workspace(WB_PROJECT_DIR *root)
 {
@@ -472,29 +562,127 @@ static guint wb_project_get_file_count(WB_PROJECT *prj)
 	return filenum;
 }
 
+
+/* Callback function for 'gp_filelist_scan_directory_callback', scan mode
+   'workbench', the plugin decides which files to add to the filelist. */
+static void scan_mode_workbench_cb(const gchar *path, gboolean *add, gboolean *enter, void *userdata)
+{
+	SCAN_PARAMS *params = userdata;
+
+	*enter = FALSE;
+	*add = FALSE;
+
+	if (g_file_test(path, G_FILE_TEST_IS_DIR))
+	{
+		if (!filelist_patterns_match(params->ignored_dirs_list, path))
+		{
+			*enter = TRUE;
+			*add = TRUE;
+		}
+	}
+	else if (g_file_test(path, G_FILE_TEST_IS_REGULAR))
+	{
+		if (filelist_patterns_match(params->file_patterns_list, path) &&
+			!filelist_patterns_match(params->ignored_file_list, path))
+		{
+			*enter = TRUE;
+			*add = TRUE;
+		}
+	}
+}
+
+
+/* Callback function for 'gp_filelist_scan_directory_callback', scan mode
+   'git', libgit2 decides which files to add to the filelist. */
+static void scan_mode_git_cb(const gchar *path, gboolean *add, gboolean *enter, void *userdata)
+{
+	gint ignored;
+	SCAN_PARAMS *params = userdata;
+
+	*enter = TRUE;
+	*add = TRUE;
+	if (params->git_repo != NULL)
+	{
+		git_ignore_path_is_ignored(&ignored, params->git_repo, path);
+		if (ignored > 0)
+		{
+			*enter = FALSE;
+			*add = FALSE;
+		}
+	}
+}
+
+
+/* Scan a path according to the settings given in parameter root. */
+static GSList *wb_project_dir_scan_directory(WB_PROJECT_DIR *root, const gchar *searchdir,
+											 guint *file_count, guint *subdir_count)
+{
+	GSList *filelist;
+	SCAN_PARAMS params = { 0 };
+
+	if (root->scan_mode != WB_PROJECT_SCAN_MODE_GIT)
+	{
+		if (!root->file_patterns || !root->file_patterns[0])
+		{
+			const gchar *all_pattern[] = { "*", NULL };
+			params.file_patterns_list = filelist_get_precompiled_patterns((gchar **)all_pattern);
+		}
+		else
+		{
+			params.file_patterns_list = filelist_get_precompiled_patterns(root->file_patterns);
+		}
+
+		params.ignored_dirs_list = filelist_get_precompiled_patterns(root->ignored_dirs_patterns);
+		params.ignored_file_list = filelist_get_precompiled_patterns(root->ignored_file_patterns);
+
+		filelist = gp_filelist_scan_directory_callback
+						(searchdir, scan_mode_workbench_cb, &params);
+
+		g_slist_foreach(params.file_patterns_list, (GFunc) g_pattern_spec_free, NULL);
+		g_slist_free(params.file_patterns_list);
+
+		g_slist_foreach(params.ignored_dirs_list, (GFunc) g_pattern_spec_free, NULL);
+		g_slist_free(params.ignored_dirs_list);
+
+		g_slist_foreach(params.ignored_file_list, (GFunc) g_pattern_spec_free, NULL);
+		g_slist_free(params.ignored_file_list);
+	}
+	else
+	{
+		params.git_repo = root->git_repo;
+		filelist = gp_filelist_scan_directory_callback
+						(searchdir, scan_mode_git_cb, &params);
+	}
+
+	if (file_count != NULL)
+	{
+		*file_count = params.file_count;
+	}
+	if (subdir_count != NULL)
+	{
+		*subdir_count = params.subdir_count;
+	}
+
+	return filelist;
+}
+
+
 /* Rescan/update the file list of a project dir. */
 static guint wb_project_dir_rescan_int(WB_PROJECT *prj, WB_PROJECT_DIR *root)
 {
 	GSList *lst;
 	GSList *elem = NULL;
 	guint filenum = 0;
 	gchar *searchdir;
-	gchar **file_patterns = NULL;
 
 	wb_project_dir_remove_from_tm_workspace(root);
 	g_hash_table_remove_all(root->file_table);
 
-	if (root->file_patterns && root->file_patterns[0])
-	{
-		file_patterns = root->file_patterns;
-	}
-
 	searchdir = get_combined_path(prj->filename, root->base_dir);
 	root->file_count = 0;
 	root->subdir_count = 0;
-	lst = gp_filelist_scan_directory_full(&(root->file_count), &(root->subdir_count),
-		searchdir, file_patterns, root->ignored_dirs_patterns, root->ignored_file_patterns,
-		FILELIST_FLAG_ADD_DIRS);
+	lst = wb_project_dir_scan_directory
+			(root, searchdir, &(root->file_count), &(root->subdir_count));
 	g_free(searchdir);
 
 	foreach_slist(elem, lst)
@@ -515,22 +703,54 @@ static guint wb_project_dir_rescan_int(WB_PROJECT *prj, WB_PROJECT_DIR *root)
 }
 
 
+/* Single check if a path is to be ignored or not. */
+static gboolean wb_project_dir_path_is_ignored(WB_PROJECT_DIR *root, const gchar *filepath)
+{
+	if (root->scan_mode == WB_PROJECT_SCAN_MODE_WORKBENCH)
+	{
+		gchar **file_patterns = NULL;
+		gboolean matches;
+
+		if (root->file_patterns && root->file_patterns[0])
+		{
+			file_patterns = root->file_patterns;
+		}
+
+		matches = gp_filelist_filepath_matches_patterns(filepath,
+			file_patterns, root->ignored_dirs_patterns, root->ignored_file_patterns);
+		if (!matches)
+		{
+			/* Ignore it. */
+			return TRUE;
+		}
+	}
+	else
+	{
+		if (root->git_repo != NULL)
+		{
+			gint ignored;
+
+			git_ignore_path_is_ignored(&ignored, root->git_repo, filepath);
+			if (ignored > 0)
+			{
+				/* Ignore it. */
+				return TRUE;
+			}
+		}
+	}
+
+	/* Do not ignore it. */
+	return FALSE;
+}
+
+
 /* Add a new file to the project directory and update the sidebar. */
 static void wb_project_dir_add_file_int(WB_PROJECT *prj, WB_PROJECT_DIR *root, const gchar *filepath)
 {
-	gboolean matches;
-	gchar **file_patterns = NULL;
 	SIDEBAR_CONTEXT context;
 	WB_MONITOR *monitor = NULL;
 
-	if (root->file_patterns && root->file_patterns[0])
-	{
-		file_patterns = root->file_patterns;
-	}
-
-	matches = gp_filelist_filepath_matches_patterns(filepath,
-		file_patterns, root->ignored_dirs_patterns, root->ignored_file_patterns);
-	if (!matches)
+	if (wb_project_dir_path_is_ignored(root, filepath))
 	{
 		/* Ignore it. */
 		return;
@@ -562,9 +782,8 @@ static void wb_project_dir_add_file_int(WB_PROJECT *prj, WB_PROJECT_DIR *root, c
 	{
 		GSList *scanned, *elem = NULL;
 
-		scanned = gp_filelist_scan_directory_full(&(root->file_count), &(root->subdir_count),
-			filepath, file_patterns, root->ignored_dirs_patterns, root->ignored_file_patterns,
-			FILELIST_FLAG_ADD_DIRS);
+		scanned = wb_project_dir_scan_directory
+				(root, filepath, &(root->file_count), &(root->subdir_count));
 
 		foreach_slist(elem, scanned)
 		{
@@ -655,18 +874,15 @@ static gboolean wb_project_dir_remove_child (gpointer key, gpointer value, gpoin
 void wb_project_dir_remove_file(WB_PROJECT *prj, WB_PROJECT_DIR *root, const gchar *filepath)
 {
 	gboolean matches, was_dir;
-	gchar **file_patterns = NULL;
 	WB_MONITOR *monitor;
 
-	if (root->file_patterns && root->file_patterns[0])
-	{
-		file_patterns = root->file_patterns;
-	}
-
 	if (g_file_test(filepath, G_FILE_TEST_EXISTS))
 	{
-		matches = gp_filelist_filepath_matches_patterns(filepath,
-			file_patterns, root->ignored_dirs_patterns, root->ignored_file_patterns);
+		matches = FALSE;
+		if (wb_project_dir_path_is_ignored(root, filepath) == FALSE)
+		{
+			matches = TRUE;
+		}
 	}
 	else
 	{
@@ -1070,6 +1286,15 @@ static void wb_project_save_directories (gpointer data, gpointer user_data)
 	{
 		g_key_file_set_string(tmp->kf, "Workbench", "Prj-BaseDir", dir->base_dir);
 
+		if (dir->scan_mode == WB_PROJECT_SCAN_MODE_WORKBENCH)
+		{
+			g_key_file_set_string(tmp->kf, "Workbench", "Prj-ScanMode", "Workbench");
+		}
+		else
+		{
+			g_key_file_set_string(tmp->kf, "Workbench", "Prj-ScanMode", "Git");
+		}
+
 		str = g_strjoinv(";", dir->file_patterns);
 		g_key_file_set_string(tmp->kf, "Workbench", "Prj-FilePatterns", str);
 		g_free(str);
@@ -1087,6 +1312,16 @@ static void wb_project_save_directories (gpointer data, gpointer user_data)
 		g_snprintf(key, sizeof(key), "Dir%u-BaseDir", tmp->dir_count);
 		g_key_file_set_string(tmp->kf, "Workbench", key, dir->base_dir);
 
+		g_snprintf(key, sizeof(key), "Dir%u-ScanMode", tmp->dir_count);
+		if (dir->scan_mode == WB_PROJECT_SCAN_MODE_WORKBENCH)
+		{
+			g_key_file_set_string(tmp->kf, "Workbench", key, "Workbench");
+		}
+		else
+		{
+			g_key_file_set_string(tmp->kf, "Workbench", key, "Git");
+		}
+
 		g_snprintf(key, sizeof(key), "Dir%u-FilePatterns", tmp->dir_count);
 		str = g_strjoinv(";", dir->file_patterns);
 		g_key_file_set_string(tmp->kf, "Workbench", key, str);
@@ -1415,6 +1650,17 @@ gboolean wb_project_load(WB_PROJECT *prj, const gchar *filename, GError **error)
 			{
 				wb_project_dir_set_is_prj_base_dir(new_dir, TRUE);
 
+				str = g_key_file_get_string(kf, "Workbench", "Prj-ScanMode", NULL);
+				if (g_strcmp0(str, "Git") != 0)
+				{
+					wb_project_dir_set_scan_mode(prj, new_dir, WB_PROJECT_SCAN_MODE_WORKBENCH);
+				}
+				else
+				{
+					wb_project_dir_set_scan_mode(prj, new_dir, WB_PROJECT_SCAN_MODE_GIT);
+				}
+				g_free(str);
+
 				str = g_key_file_get_string(kf, "Workbench", "Prj-FilePatterns", NULL);
 				if (str != NULL)
 				{
@@ -1457,6 +1703,18 @@ gboolean wb_project_load(WB_PROJECT *prj, const gchar *filename, GError **error)
 				break;
 			}
 
+			g_snprintf(key, sizeof(key), "Dir%u-ScanMode", index);
+			str = g_key_file_get_string(kf, "Workbench", key, NULL);
+			if (g_strcmp0(str, "Git") != 0)
+			{
+				wb_project_dir_set_scan_mode(prj, new_dir, WB_PROJECT_SCAN_MODE_WORKBENCH);
+			}
+			else
+			{
+				wb_project_dir_set_scan_mode(prj, new_dir, WB_PROJECT_SCAN_MODE_GIT);
+			}
+			g_free(str);
+
 			g_snprintf(key, sizeof(key), "Dir%u-FilePatterns", index);
 			str = g_key_file_get_string(kf, "Workbench", key, NULL);
 			if (str != NULL)


Modified: workbench/src/wb_project.h
9 lines changed, 9 insertions(+), 0 deletions(-)
===================================================================
@@ -24,6 +24,13 @@
 typedef struct S_WB_PROJECT WB_PROJECT;
 typedef struct S_WB_PROJECT_DIR WB_PROJECT_DIR;
 
+typedef enum
+{
+	WB_PROJECT_SCAN_MODE_INVALID,
+	WB_PROJECT_SCAN_MODE_WORKBENCH,
+	WB_PROJECT_SCAN_MODE_GIT,
+}WB_PROJECT_SCAN_MODE;
+
 WB_PROJECT *wb_project_new(const gchar *filename);
 void wb_project_free(WB_PROJECT *prj);
 
@@ -51,6 +58,8 @@ gchar **wb_project_dir_get_ignored_dirs_patterns (WB_PROJECT_DIR *directory);
 gboolean wb_project_dir_set_ignored_dirs_patterns (WB_PROJECT_DIR *directory, gchar **new);
 gchar **wb_project_dir_get_ignored_file_patterns (WB_PROJECT_DIR *directory);
 gboolean wb_project_dir_set_ignored_file_patterns (WB_PROJECT_DIR *directory, gchar **new);
+WB_PROJECT_SCAN_MODE wb_project_dir_get_scan_mode (WB_PROJECT_DIR *directory);
+gboolean wb_project_dir_set_scan_mode (WB_PROJECT *project, WB_PROJECT_DIR *directory, WB_PROJECT_SCAN_MODE mode);
 guint wb_project_dir_rescan(WB_PROJECT *prj, WB_PROJECT_DIR *root);
 gchar *wb_project_dir_get_info (WB_PROJECT_DIR *dir);
 gboolean wb_project_dir_file_is_included(WB_PROJECT_DIR *dir, const gchar *filename);



--------------
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