When invalid regex is enter, show an error icon and tooltip with error message
This commit is contained in:
parent
ea7ca1b365
commit
cbd0d33735
@ -131,7 +131,7 @@ moo_edit_action_set_file_filter (MooEditAction *action,
|
||||
_moo_edit_filter_free (action->priv->file_filter);
|
||||
|
||||
if (string && string[0])
|
||||
action->priv->file_filter = _moo_edit_filter_new (string);
|
||||
action->priv->file_filter = _moo_edit_filter_new (string, MOO_EDIT_FILTER_ACTION);
|
||||
else
|
||||
action->priv->file_filter = NULL;
|
||||
|
||||
|
@ -36,7 +36,8 @@ MOO_DEBUG_INIT(filters, FALSE)
|
||||
typedef enum {
|
||||
MOO_EDIT_FILTER_LANGS,
|
||||
MOO_EDIT_FILTER_GLOBS,
|
||||
MOO_EDIT_FILTER_REGEX
|
||||
MOO_EDIT_FILTER_REGEX,
|
||||
MOO_EDIT_FILTER_INVALID
|
||||
} MooEditFilterType;
|
||||
|
||||
struct MooEditFilter {
|
||||
@ -45,6 +46,7 @@ struct MooEditFilter {
|
||||
GSList *langs;
|
||||
GSList *globs;
|
||||
GRegex *regex;
|
||||
char *string;
|
||||
} u;
|
||||
};
|
||||
|
||||
@ -60,8 +62,15 @@ typedef struct {
|
||||
static FilterSettingsStore *settings_store;
|
||||
|
||||
|
||||
static char *filter_settings_store_get_setting (FilterSettingsStore *store,
|
||||
MooEdit *doc);
|
||||
static char *filter_settings_store_get_setting (FilterSettingsStore *store,
|
||||
MooEdit *doc);
|
||||
|
||||
static MooEditFilter *moo_edit_filter_new_langs (const char *string,
|
||||
GError **error);
|
||||
static MooEditFilter *moo_edit_filter_new_regex (const char *string,
|
||||
GError **error);
|
||||
static MooEditFilter *moo_edit_filter_new_globs (const char *string,
|
||||
GError **error);
|
||||
|
||||
static char *
|
||||
moo_edit_filter_get_string (MooEditFilter *filter,
|
||||
@ -87,6 +96,8 @@ moo_edit_filter_get_string (MooEditFilter *filter,
|
||||
case MOO_EDIT_FILTER_REGEX:
|
||||
g_string_append (str, "regex:");
|
||||
break;
|
||||
case MOO_EDIT_FILTER_INVALID:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,34 +115,57 @@ moo_edit_filter_get_string (MooEditFilter *filter,
|
||||
case MOO_EDIT_FILTER_REGEX:
|
||||
g_string_append (str, g_regex_get_pattern (filter->u.regex));
|
||||
break;
|
||||
case MOO_EDIT_FILTER_INVALID:
|
||||
g_string_append (str, filter->u.string);
|
||||
break;
|
||||
}
|
||||
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
static MooEditFilter *
|
||||
_moo_edit_filter_new_full (const char *string,
|
||||
gboolean default_regex)
|
||||
MooEditFilter *
|
||||
_moo_edit_filter_new_full (const char *string,
|
||||
MooEditFilterKind kind,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (string && string[0], NULL);
|
||||
|
||||
if (!strncmp (string, "langs:", strlen ("langs:")))
|
||||
return _moo_edit_filter_new_langs (string + strlen ("langs:"));
|
||||
return moo_edit_filter_new_langs (string + strlen ("langs:"), error);
|
||||
if (!strncmp (string, "globs:", strlen ("globs:")))
|
||||
return _moo_edit_filter_new_globs (string + strlen ("globs:"));
|
||||
return moo_edit_filter_new_globs (string + strlen ("globs:"), error);
|
||||
if (!strncmp (string, "regex:", strlen ("regex:")))
|
||||
return _moo_edit_filter_new_regex (string + strlen ("regex:"));
|
||||
return moo_edit_filter_new_regex (string + strlen ("regex:"), error);
|
||||
|
||||
if (default_regex)
|
||||
return _moo_edit_filter_new_regex (string);
|
||||
else
|
||||
return _moo_edit_filter_new_globs (string);
|
||||
switch (kind)
|
||||
{
|
||||
case MOO_EDIT_FILTER_CONFIG:
|
||||
return moo_edit_filter_new_regex (string, error);
|
||||
case MOO_EDIT_FILTER_ACTION:
|
||||
return moo_edit_filter_new_globs (string, error);
|
||||
}
|
||||
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
MooEditFilter *
|
||||
_moo_edit_filter_new (const char *string)
|
||||
_moo_edit_filter_new (const char *string,
|
||||
MooEditFilterKind kind)
|
||||
{
|
||||
return _moo_edit_filter_new_full (string, FALSE);
|
||||
GError *error = NULL;
|
||||
MooEditFilter *filter;
|
||||
|
||||
g_return_val_if_fail (string != NULL, NULL);
|
||||
|
||||
filter = _moo_edit_filter_new_full (string, kind, &error);
|
||||
|
||||
if (error)
|
||||
{
|
||||
g_warning ("could not parse filter '%s': %s", string, error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
static GSList *
|
||||
@ -160,12 +194,13 @@ _moo_edit_parse_langs (const char *string)
|
||||
return g_slist_reverse (list);
|
||||
}
|
||||
|
||||
MooEditFilter *
|
||||
_moo_edit_filter_new_langs (const char *string)
|
||||
static MooEditFilter *
|
||||
moo_edit_filter_new_langs (const char *string,
|
||||
GError **error)
|
||||
{
|
||||
MooEditFilter *filt;
|
||||
|
||||
g_return_val_if_fail (string != NULL, NULL);
|
||||
moo_return_error_if_fail_p (string != NULL);
|
||||
|
||||
filt = g_new0 (MooEditFilter, 1);
|
||||
filt->type = MOO_EDIT_FILTER_LANGS;
|
||||
@ -174,28 +209,38 @@ _moo_edit_filter_new_langs (const char *string)
|
||||
return filt;
|
||||
}
|
||||
|
||||
MooEditFilter *
|
||||
_moo_edit_filter_new_regex (const char *string)
|
||||
static MooEditFilter *
|
||||
moo_edit_regex_new_invalid (const char *string,
|
||||
GError **error)
|
||||
{
|
||||
MooEditFilter *filt;
|
||||
|
||||
moo_return_error_if_fail_p (string != NULL);
|
||||
|
||||
filt = g_new0 (MooEditFilter, 1);
|
||||
filt->type = MOO_EDIT_FILTER_INVALID;
|
||||
filt->u.string = g_strdup (string);
|
||||
|
||||
return filt;
|
||||
}
|
||||
|
||||
static MooEditFilter *
|
||||
moo_edit_filter_new_regex (const char *string,
|
||||
GError **error)
|
||||
{
|
||||
MooEditFilter *filt;
|
||||
GRegex *regex;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_val_if_fail (string != NULL, NULL);
|
||||
moo_return_error_if_fail_p (string != NULL);
|
||||
|
||||
regex = g_regex_new (string, G_REGEX_OPTIMIZE
|
||||
#ifdef __WIN32__
|
||||
| G_REGEX_CASELESS
|
||||
#endif
|
||||
, 0, &error);
|
||||
, 0, error);
|
||||
|
||||
if (!regex)
|
||||
{
|
||||
g_warning ("%s: invalid regex '%s': %s", G_STRFUNC,
|
||||
string, error->message);
|
||||
g_error_free (NULL);
|
||||
return NULL;
|
||||
}
|
||||
return moo_edit_regex_new_invalid (string, NULL);
|
||||
|
||||
filt = g_new0 (MooEditFilter, 1);
|
||||
filt->type = MOO_EDIT_FILTER_REGEX;
|
||||
@ -230,12 +275,13 @@ parse_globs (const char *string)
|
||||
return g_slist_reverse (list);
|
||||
}
|
||||
|
||||
MooEditFilter *
|
||||
_moo_edit_filter_new_globs (const char *string)
|
||||
static MooEditFilter *
|
||||
moo_edit_filter_new_globs (const char *string,
|
||||
GError **error)
|
||||
{
|
||||
MooEditFilter *filt;
|
||||
|
||||
g_return_val_if_fail (string != NULL, NULL);
|
||||
moo_return_error_if_fail_p (string != NULL);
|
||||
|
||||
filt = g_new0 (MooEditFilter, 1);
|
||||
filt->type = MOO_EDIT_FILTER_GLOBS;
|
||||
@ -244,6 +290,13 @@ _moo_edit_filter_new_globs (const char *string)
|
||||
return filt;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_moo_edit_filter_valid (MooEditFilter *filter)
|
||||
{
|
||||
g_return_val_if_fail (filter != NULL, FALSE);
|
||||
return filter->type != MOO_EDIT_FILTER_INVALID;
|
||||
}
|
||||
|
||||
void
|
||||
_moo_edit_filter_free (MooEditFilter *filter)
|
||||
{
|
||||
@ -260,6 +313,9 @@ _moo_edit_filter_free (MooEditFilter *filter)
|
||||
if (filter->u.regex)
|
||||
g_regex_unref (filter->u.regex);
|
||||
break;
|
||||
case MOO_EDIT_FILTER_INVALID:
|
||||
g_free (filter->u.string);
|
||||
break;
|
||||
}
|
||||
|
||||
g_free (filter);
|
||||
@ -334,6 +390,8 @@ _moo_edit_filter_match (MooEditFilter *filter,
|
||||
return moo_edit_filter_check_langs (filter->u.langs, doc);
|
||||
case MOO_EDIT_FILTER_REGEX:
|
||||
return moo_edit_filter_check_regex (filter->u.regex, doc);
|
||||
case MOO_EDIT_FILTER_INVALID:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_return_val_if_reached (FALSE);
|
||||
@ -362,7 +420,7 @@ filter_setting_new (const char *filter,
|
||||
g_return_val_if_fail (config != NULL, NULL);
|
||||
|
||||
setting = g_new0 (FilterSetting, 1);
|
||||
setting->filter = _moo_edit_filter_new_full (filter, TRUE);
|
||||
setting->filter = _moo_edit_filter_new (filter, MOO_EDIT_FILTER_CONFIG);
|
||||
setting->config = g_strdup (config);
|
||||
|
||||
if (!setting->filter)
|
||||
|
@ -27,20 +27,27 @@ G_BEGIN_DECLS
|
||||
|
||||
typedef struct MooEditFilter MooEditFilter;
|
||||
|
||||
MooEditFilter *_moo_edit_filter_new (const char *string);
|
||||
MooEditFilter *_moo_edit_filter_new_langs (const char *string);
|
||||
MooEditFilter *_moo_edit_filter_new_regex (const char *string);
|
||||
MooEditFilter *_moo_edit_filter_new_globs (const char *string);
|
||||
void _moo_edit_filter_free (MooEditFilter *filter);
|
||||
gboolean _moo_edit_filter_match (MooEditFilter *filter,
|
||||
MooEdit *doc);
|
||||
typedef enum {
|
||||
MOO_EDIT_FILTER_CONFIG,
|
||||
MOO_EDIT_FILTER_ACTION
|
||||
} MooEditFilterKind;
|
||||
|
||||
MooEditFilter *_moo_edit_filter_new (const char *string,
|
||||
MooEditFilterKind kind);
|
||||
MooEditFilter *_moo_edit_filter_new_full (const char *string,
|
||||
MooEditFilterKind kind,
|
||||
GError **error);
|
||||
gboolean _moo_edit_filter_valid (MooEditFilter *filter);
|
||||
void _moo_edit_filter_free (MooEditFilter *filter);
|
||||
gboolean _moo_edit_filter_match (MooEditFilter *filter,
|
||||
MooEdit *doc);
|
||||
|
||||
void _moo_edit_filter_settings_load (void);
|
||||
|
||||
GSList *_moo_edit_filter_settings_get_strings (void);
|
||||
void _moo_edit_filter_settings_set_strings (GSList *strings);
|
||||
void _moo_edit_filter_settings_set_strings (GSList *strings);
|
||||
|
||||
char *_moo_edit_filter_settings_get_for_doc (MooEdit *doc);
|
||||
char *_moo_edit_filter_settings_get_for_doc (MooEdit *doc);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -796,6 +796,8 @@ prefs_page_apply_lang_prefs (MooPrefsPage *page)
|
||||
*/
|
||||
|
||||
enum {
|
||||
FILTER_COLUMN_INVALID,
|
||||
FILTER_COLUMN_INVALID_TOOLTIP,
|
||||
FILTER_COLUMN_FILTER,
|
||||
FILTER_COLUMN_CONFIG,
|
||||
FILTER_NUM_COLUMNS
|
||||
@ -820,6 +822,65 @@ filter_store_get_modified (gpointer store)
|
||||
_moo_tree_helper_get_modified (g_object_get_data (store, "tree-helper"));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_filter (const char *string,
|
||||
char **message)
|
||||
{
|
||||
gboolean result;
|
||||
MooEditFilter *filter;
|
||||
GError *error = NULL;
|
||||
|
||||
if (message)
|
||||
*message = NULL;
|
||||
|
||||
if (!string || !string[0])
|
||||
return TRUE;
|
||||
|
||||
filter = _moo_edit_filter_new_full (string, MOO_EDIT_FILTER_CONFIG, &error);
|
||||
g_return_val_if_fail (filter != NULL, FALSE);
|
||||
|
||||
result = _moo_edit_filter_valid (filter);
|
||||
|
||||
if (error && message)
|
||||
*message = g_strdup (error->message);
|
||||
|
||||
if (error)
|
||||
g_error_free (error);
|
||||
|
||||
_moo_edit_filter_free (filter);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
check_filter_row (GtkListStore *store,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
gboolean invalid;
|
||||
char *filter = NULL;
|
||||
char *message = NULL;
|
||||
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (store), iter,
|
||||
FILTER_COLUMN_FILTER, &filter,
|
||||
-1);
|
||||
g_return_if_fail (filter != NULL);
|
||||
|
||||
invalid = !check_filter (filter, &message);
|
||||
|
||||
if (invalid)
|
||||
gtk_list_store_set (store, iter,
|
||||
FILTER_COLUMN_INVALID, TRUE,
|
||||
FILTER_COLUMN_INVALID_TOOLTIP, message,
|
||||
-1);
|
||||
else
|
||||
gtk_list_store_set (store, iter,
|
||||
FILTER_COLUMN_INVALID, FALSE,
|
||||
FILTER_COLUMN_INVALID_TOOLTIP, NULL,
|
||||
-1);
|
||||
|
||||
g_free (message);
|
||||
g_free (filter);
|
||||
}
|
||||
|
||||
static void
|
||||
populate_filter_settings_store (GtkListStore *store)
|
||||
{
|
||||
@ -832,15 +893,27 @@ populate_filter_settings_store (GtkListStore *store)
|
||||
while (l)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
const char *filter;
|
||||
const char *config;
|
||||
gboolean valid;
|
||||
char *message = NULL;
|
||||
|
||||
g_return_if_fail (l->next != NULL);
|
||||
|
||||
filter = l->data;
|
||||
config = l->next->data;
|
||||
valid = check_filter (filter, &message);
|
||||
|
||||
gtk_list_store_append (store, &iter);
|
||||
gtk_list_store_set (store, &iter,
|
||||
FILTER_COLUMN_FILTER, l->data,
|
||||
FILTER_COLUMN_CONFIG, l->next->data,
|
||||
FILTER_COLUMN_INVALID, !valid,
|
||||
FILTER_COLUMN_INVALID_TOOLTIP, message,
|
||||
FILTER_COLUMN_FILTER, filter,
|
||||
FILTER_COLUMN_CONFIG, config,
|
||||
-1);
|
||||
|
||||
g_free (message);
|
||||
|
||||
l = l->next->next;
|
||||
}
|
||||
|
||||
@ -879,6 +952,7 @@ filter_cell_edited (GtkCellRendererText *cell,
|
||||
{
|
||||
gtk_list_store_set (store, &iter, column, text, -1);
|
||||
filter_store_set_modified (store, TRUE);
|
||||
check_filter_row (store, &iter);
|
||||
}
|
||||
|
||||
g_free (old_text);
|
||||
@ -887,18 +961,43 @@ filter_cell_edited (GtkCellRendererText *cell,
|
||||
|
||||
|
||||
static void
|
||||
create_filter_cell (GtkTreeView *treeview,
|
||||
GtkListStore *store,
|
||||
const char *title,
|
||||
int column_id)
|
||||
filter_icon_data_func (G_GNUC_UNUSED GtkTreeViewColumn *column,
|
||||
GtkCellRenderer *cell,
|
||||
GtkTreeModel *model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
gboolean invalid;
|
||||
gtk_tree_model_get (model, iter, FILTER_COLUMN_INVALID, &invalid, -1);
|
||||
g_object_set (cell, "visible", invalid, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
create_filter_column (GtkTreeView *treeview,
|
||||
GtkListStore *store,
|
||||
const char *title,
|
||||
int column_id)
|
||||
{
|
||||
GtkTreeViewColumn *column;
|
||||
GtkCellRenderer *cell;
|
||||
|
||||
cell = gtk_cell_renderer_text_new ();
|
||||
column = gtk_tree_view_column_new_with_attributes (title, cell, "text", column_id, NULL);
|
||||
column = gtk_tree_view_column_new ();
|
||||
gtk_tree_view_column_set_title (column, title);
|
||||
gtk_tree_view_append_column (treeview, column);
|
||||
|
||||
if (column_id == FILTER_COLUMN_FILTER)
|
||||
{
|
||||
cell = gtk_cell_renderer_pixbuf_new ();
|
||||
g_object_set (cell, "stock-id", GTK_STOCK_DIALOG_ERROR, NULL);
|
||||
gtk_tree_view_column_pack_start (column, cell, FALSE);
|
||||
gtk_tree_view_column_set_cell_data_func (column, cell,
|
||||
(GtkTreeCellDataFunc) filter_icon_data_func,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
cell = gtk_cell_renderer_text_new ();
|
||||
gtk_tree_view_column_pack_start (column, cell, TRUE);
|
||||
gtk_tree_view_column_set_attributes (column, cell, "text", column_id, NULL);
|
||||
|
||||
g_object_set (cell, "editable", TRUE, NULL);
|
||||
g_object_set_data (G_OBJECT (cell), "filter-store-column-id", GINT_TO_POINTER (column_id));
|
||||
g_signal_connect (cell, "edited", G_CALLBACK (filter_cell_edited), store);
|
||||
@ -911,14 +1010,16 @@ filter_treeview_init (PrefsFiltersXml *gxml)
|
||||
GtkListStore *store;
|
||||
MooTreeHelper *helper;
|
||||
|
||||
store = gtk_list_store_new (FILTER_NUM_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
|
||||
store = gtk_list_store_new (FILTER_NUM_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
|
||||
populate_filter_settings_store (store);
|
||||
gtk_tree_view_set_model (gxml->filter_treeview, GTK_TREE_MODEL (store));
|
||||
|
||||
/* Column label on File Filters prefs page */
|
||||
create_filter_cell (gxml->filter_treeview, store, C_("filter-prefs-column", "Filter"), FILTER_COLUMN_FILTER);
|
||||
create_filter_column (gxml->filter_treeview, store, C_("filter-prefs-column", "Filter"), FILTER_COLUMN_FILTER);
|
||||
/* Column label on File Filters prefs page */
|
||||
create_filter_cell (gxml->filter_treeview, store, C_("filter-prefs-column", "Options"), FILTER_COLUMN_CONFIG);
|
||||
create_filter_column (gxml->filter_treeview, store, C_("filter-prefs-column", "Options"), FILTER_COLUMN_CONFIG);
|
||||
|
||||
gtk_tree_view_set_tooltip_column (gxml->filter_treeview, FILTER_COLUMN_INVALID_TOOLTIP);
|
||||
|
||||
helper = _moo_tree_helper_new (GTK_WIDGET (gxml->filter_treeview),
|
||||
GTK_WIDGET (gxml->new_filter_setting),
|
||||
|
@ -4038,7 +4038,7 @@ moo_edit_window_set_action_filter (const char *action_id,
|
||||
g_return_if_fail (type < N_ACTION_CHECKS);
|
||||
|
||||
if (filter_string && filter_string[0])
|
||||
filter = _moo_edit_filter_new (filter_string);
|
||||
filter = _moo_edit_filter_new (filter_string, MOO_EDIT_FILTER_ACTION);
|
||||
|
||||
if (filter)
|
||||
moo_edit_window_set_action_check (action_id, type,
|
||||
|
Loading…
x
Reference in New Issue
Block a user