diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2012-05-31 19:07:16 +0200 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2012-05-31 19:07:16 +0200 |
commit | d76fdf9cb931d6d189938102a98a71030ea907ad (patch) | |
tree | 74b06c42185705beab93f24ecb2adc66c3f2800c | |
parent | f6963e8221643daa152b0fe26886e327e1a7f8b3 (diff) | |
download | gtk-vlc-player-d76fdf9cb931d6d189938102a98a71030ea907ad.tar.gz |
allow transcript formatting without markup (like search-as-you type)
* controlled via checkbox
* if markup is disabled the entered text is only regular expressions
* default text attributes are used according to some constants (in configure.ac, later they will be configurable via config file)
* fixed return value of gtk_experiment_transcript_load_formats()
* care about possible capture mismatches in regular expressions (capture braces are inserted automatically - the user is not allowed specify own captures)
* display state of interactive format via icon (successful/error)
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | lib/gtk-experiment-widgets/gtk-experiment-transcript-formats.c | 113 | ||||
-rw-r--r-- | lib/gtk-experiment-widgets/gtk-experiment-transcript.h | 2 | ||||
-rw-r--r-- | src/default.ui | 100 | ||||
-rw-r--r-- | src/experiment-player.h | 4 | ||||
-rw-r--r-- | src/format-selection.c | 39 | ||||
-rw-r--r-- | src/main.c | 2 |
7 files changed, 222 insertions, 42 deletions
diff --git a/configure.ac b/configure.ac index 3b71842..1d2544f 100644 --- a/configure.ac +++ b/configure.ac @@ -225,6 +225,10 @@ AC_DEFINE(EXPERIMENT_TRANSCRIPT_EXT, ["xml"], [File extension of experiment tran AC_DEFINE(DEFAULT_FORMAT_DIR, ["."], [Default directory for selecting formats]) AC_DEFINE(EXPERIMENT_FORMAT_FILTER, ["*.fmt"], [Format file filter]) +AC_DEFINE(DEFAULT_INTERACTIVE_FORMAT_FONT, ["bold"], [Default interactive format font description]) +AC_DEFINE(DEFAULT_INTERACTIVE_FORMAT_FGCOLOR, [NULL], [Default interactive format foreground color]) +AC_DEFINE(DEFAULT_INTERACTIVE_FORMAT_BGCOLOR, [NULL], [Default interactive format background color]) + AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile]) AC_CONFIG_FILES([lib/gtk-vlc-player/Makefile]) AC_CONFIG_FILES([lib/experiment-reader/Makefile lib/experiment-reader/tests/Makefile]) diff --git a/lib/gtk-experiment-widgets/gtk-experiment-transcript-formats.c b/lib/gtk-experiment-widgets/gtk-experiment-transcript-formats.c index 2bbe761..e64c827 100644 --- a/lib/gtk-experiment-widgets/gtk-experiment-transcript-formats.c +++ b/lib/gtk-experiment-widgets/gtk-experiment-transcript-formats.c @@ -20,6 +20,9 @@ #include "gtk-experiment-transcript-private.h" +#define FORMAT_REGEX_COMPILE_FLAGS (G_REGEX_CASELESS) +#define FORMAT_REGEX_MATCH_FLAGS (0) + static gboolean gtk_experiment_transcript_parse_format(GtkExperimentTranscriptFormat *fmt, const gchar *str) @@ -27,6 +30,7 @@ gtk_experiment_transcript_parse_format(GtkExperimentTranscriptFormat *fmt, PangoAttrIterator *iter; gchar *pattern, pattern_captures[255], *p; + gint capture_count = 0; if (!pango_parse_markup(str, -1, 0, &fmt->attribs, &pattern, NULL, NULL)) @@ -44,16 +48,22 @@ gtk_experiment_transcript_parse_format(GtkExperimentTranscriptFormat *fmt, strncpy(p, pattern + start, end - start); p += end - start; *p++ = ')'; + + capture_count++; } } while (pango_attr_iterator_next(iter)); pango_attr_iterator_destroy(iter); *p = '\0'; g_free(pattern); - fmt->regexp = g_regex_new(pattern_captures, G_REGEX_CASELESS, 0, NULL); - if (fmt->regexp == NULL) { - pango_attr_list_unref(fmt->attribs); + fmt->regexp = g_regex_new(pattern_captures, + FORMAT_REGEX_COMPILE_FLAGS, 0, NULL); + if (fmt->regexp == NULL || + g_regex_get_capture_count(fmt->regexp) != capture_count) { + gtk_experiment_transcript_free_format(fmt); + fmt->regexp = NULL; fmt->attribs = NULL; + return TRUE; } @@ -71,7 +81,7 @@ gtk_experiment_transcript_apply_format(GtkExperimentTranscriptFormat *fmt, if (fmt->regexp == NULL || fmt->attribs == NULL) return; - g_regex_match(fmt->regexp, text, 0, &match_info); + g_regex_match(fmt->regexp, text, FORMAT_REGEX_MATCH_FLAGS, &match_info); while (g_match_info_matches(match_info)) { PangoAttrIterator *iter; @@ -132,21 +142,25 @@ gtk_experiment_transcript_free_formats(GSList *formats) * API */ +/** @todo report errors using GError */ gboolean gtk_experiment_transcript_load_formats(GtkExperimentTranscript *trans, const gchar *filename) { FILE *file; gchar buf[255]; + gboolean res = TRUE; gtk_experiment_transcript_free_formats(trans->priv->formats); trans->priv->formats = NULL; - if (filename == NULL || !*filename) + if (filename == NULL || !*filename) { + res = FALSE; goto redraw; + } if ((file = g_fopen(filename, "r")) == NULL) - return TRUE; + goto redraw; while (fgets((char *)buf, sizeof(buf)-1, file) != NULL) { GtkExperimentTranscriptFormat *fmt; @@ -165,7 +179,10 @@ gtk_experiment_transcript_load_formats(GtkExperimentTranscript *trans, if (gtk_experiment_transcript_parse_format(fmt, buf)) { g_free(fmt); fclose(file); - return TRUE; + gtk_experiment_transcript_free_formats(trans->priv->formats); + trans->priv->formats = NULL; + + goto redraw; } trans->priv->formats = g_slist_prepend(trans->priv->formats, fmt); @@ -173,33 +190,91 @@ gtk_experiment_transcript_load_formats(GtkExperimentTranscript *trans, trans->priv->formats = g_slist_reverse(trans->priv->formats); fclose(file); + res = FALSE; redraw: gtk_experiment_transcript_text_layer_redraw(trans); - return FALSE; + return res; } gboolean gtk_experiment_transcript_set_interactive_format(GtkExperimentTranscript *trans, - const gchar *format, + const gchar *format_str, gboolean with_markup) { + static PangoAttrList *default_attribs = NULL; + + GtkExperimentTranscriptFormat *fmt = &trans->priv->interactive_format; + gchar *pattern; gboolean res = TRUE; - gtk_experiment_transcript_free_format(&trans->priv->interactive_format); - trans->priv->interactive_format.regexp = NULL; - trans->priv->interactive_format.attribs = NULL; + if (default_attribs == NULL) { + PangoAttribute *attrib; + PangoFontDescription *font; + PangoColor color; + + default_attribs = pango_attr_list_new(); + + font = pango_font_description_from_string(DEFAULT_INTERACTIVE_FORMAT_FONT); + if (font != NULL) { + attrib = pango_attr_font_desc_new(font); + attrib->end_index = 1; + pango_attr_list_insert(default_attribs, attrib); + pango_font_description_free(font); + } + + if (DEFAULT_INTERACTIVE_FORMAT_FGCOLOR != NULL && + pango_color_parse(&color, DEFAULT_INTERACTIVE_FORMAT_FGCOLOR)) { + attrib = pango_attr_foreground_new(color.red, + color.green, + color.blue); + attrib->end_index = 1; + pango_attr_list_insert(default_attribs, attrib); + } + + if (DEFAULT_INTERACTIVE_FORMAT_BGCOLOR != NULL && + pango_color_parse(&color, DEFAULT_INTERACTIVE_FORMAT_BGCOLOR)) { + attrib = pango_attr_background_new(color.red, + color.green, + color.blue); + attrib->end_index = 1; + pango_attr_list_insert(default_attribs, attrib); + } + } - if (format == NULL || *format == '\0') { + gtk_experiment_transcript_free_format(fmt); + fmt->regexp = NULL; + fmt->attribs = NULL; + + if (format_str == NULL || !*format_str) { res = FALSE; - } else if (with_markup) { - res = gtk_experiment_transcript_parse_format(&trans->priv->interactive_format, - format); - } else { - /** @todo !with_markup, default attributes */ - res = TRUE; + goto redraw; + } + + if (with_markup) { + res = gtk_experiment_transcript_parse_format(fmt, format_str); + goto redraw; + } + /* else if (!with_markup) */ + + fmt->attribs = pango_attr_list_copy(default_attribs); + if (fmt->attribs == NULL) + goto redraw; + + pattern = g_strconcat("(", format_str, ")", NULL); + fmt->regexp = g_regex_new(pattern, FORMAT_REGEX_COMPILE_FLAGS, 0, NULL); + g_free(pattern); + if (fmt->regexp == NULL || + g_regex_get_capture_count(fmt->regexp) != 1) { + gtk_experiment_transcript_free_format(fmt); + fmt->regexp = NULL; + fmt->attribs = NULL; + + goto redraw; } + res = FALSE; +redraw: gtk_experiment_transcript_text_layer_redraw(trans); return res; } diff --git a/lib/gtk-experiment-widgets/gtk-experiment-transcript.h b/lib/gtk-experiment-widgets/gtk-experiment-transcript.h index a242a57..fa4b7ab 100644 --- a/lib/gtk-experiment-widgets/gtk-experiment-transcript.h +++ b/lib/gtk-experiment-widgets/gtk-experiment-transcript.h @@ -71,7 +71,7 @@ gboolean gtk_experiment_transcript_load_filename(GtkExperimentTranscript *trans, gboolean gtk_experiment_transcript_load_formats(GtkExperimentTranscript *trans, const gchar *filename); gboolean gtk_experiment_transcript_set_interactive_format(GtkExperimentTranscript *trans, - const gchar *format, + const gchar *format_str, gboolean with_markup); GtkAdjustment *gtk_experiment_transcript_get_time_adjustment(GtkExperimentTranscript *trans); diff --git a/src/default.ui b/src/default.ui index ee9195e..d526dbd 100644 --- a/src/default.ui +++ b/src/default.ui @@ -13,7 +13,6 @@ <child> <object class="GtkVBox" id="player_window_vbox"> <property name="visible">True</property> - <property name="orientation">vertical</property> <child> <object class="GtkMenuBar" id="player_window_menubar"> <property name="visible">True</property> @@ -265,7 +264,6 @@ audio-volume-medium</property> <child> <object class="GtkVBox" id="info_window_vbox"> <property name="visible">True</property> - <property name="orientation">vertical</property> <child> <object class="GtkMenuBar" id="info_window_menubar"> <property name="visible">True</property> @@ -356,41 +354,107 @@ audio-volume-medium</property> </packing> </child> <child> - <object class="GtkEntry" id="transcript_wizard_entry"> + <object class="GtkComboBox" id="transcript_wizard_combo"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - <signal name="changed" handler="generic_transcript_entry_changed_cb" object="transcript_wizard_widget"/> + <signal name="changed" handler="generic_transcript_combo_changed_cb" object="transcript_wizard_widget"/> </object> <packing> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> <property name="y_options">GTK_FILL</property> </packing> </child> <child> - <object class="GtkEntry" id="transcript_proband_entry"> + <object class="GtkHBox" id="transcript_wizard_entry_hbox"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="invisible_char">●</property> - <signal name="changed" handler="generic_transcript_entry_changed_cb" object="transcript_proband_widget"/> + <child> + <object class="GtkEntry" id="transcript_wizard_entry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">●</property> + <property name="primary_icon_stock">gtk-apply</property> + <signal name="changed" handler="generic_transcript_entry_changed_cb" object="transcript_wizard_widget"/> + </object> + <packing> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkVSeparator" id="transcript_wizard_entry_separator"> + <property name="visible">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="padding">5</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="transcript_wizard_entry_check"> + <property name="label" translatable="yes">Markup</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="draw_indicator">True</property> + <signal name="toggled" handler="generic_transcript_entry_check_toggled_cb" object="transcript_wizard_entry"/> + </object> + <packing> + <property name="expand">False</property> + <property name="position">2</property> + </packing> + </child> </object> <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> <property name="top_attach">2</property> <property name="bottom_attach">3</property> <property name="y_options">GTK_FILL</property> </packing> </child> <child> - <object class="GtkComboBox" id="transcript_wizard_combo"> + <object class="GtkHBox" id="transcript_proband_entry_hbox"> <property name="visible">True</property> - <signal name="changed" handler="generic_transcript_combo_changed_cb" object="transcript_wizard_widget"/> + <child> + <object class="GtkEntry" id="transcript_proband_entry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">●</property> + <property name="primary_icon_stock">gtk-apply</property> + <signal name="changed" handler="generic_transcript_entry_changed_cb" object="transcript_proband_widget"/> + </object> + <packing> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkVSeparator" id="transcript_proband_entry_separator"> + <property name="visible">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="padding">5</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="transcript_proband_entry_check"> + <property name="label" translatable="yes">Markup</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="draw_indicator">True</property> + <signal name="toggled" handler="generic_transcript_entry_check_toggled_cb" object="transcript_proband_entry"/> + </object> + <packing> + <property name="expand">False</property> + <property name="position">2</property> + </packing> + </child> </object> <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> <property name="y_options">GTK_FILL</property> </packing> </child> diff --git a/src/experiment-player.h b/src/experiment-player.h index a7cda8a..018cabd 100644 --- a/src/experiment-player.h +++ b/src/experiment-player.h @@ -37,7 +37,9 @@ extern gchar *quickopen_directory; void format_selection_init(const gchar *dir); extern GtkWidget *transcript_wizard_combo, - *transcript_proband_combo; + *transcript_proband_combo, + *transcript_wizard_entry_check, + *transcript_proband_entry_check; #define BUILDER_INIT(BUILDER, VAR) do { \ VAR = GTK_WIDGET(gtk_builder_get_object(BUILDER, #VAR)); \ diff --git a/src/format-selection.c b/src/format-selection.c index 8a11ae1..2e14028 100644 --- a/src/format-selection.c +++ b/src/format-selection.c @@ -17,7 +17,9 @@ static void refresh_formats_store(GtkListStore *store); GtkWidget *transcript_wizard_combo, - *transcript_proband_combo; + *transcript_proband_combo, + *transcript_wizard_entry_check, + *transcript_proband_entry_check; static gchar *formats_directory; @@ -93,14 +95,45 @@ generic_transcript_combo_changed_cb(gpointer user_data, GtkComboBox *combo) #endif } + + void generic_transcript_entry_changed_cb(gpointer user_data, GtkEditable *editable) { GtkExperimentTranscript *trans = GTK_EXPERIMENT_TRANSCRIPT(user_data); const gchar *text = gtk_entry_get_text(GTK_ENTRY(editable)); - /** @todo enable/disable markup */ - gtk_experiment_transcript_set_interactive_format(trans, text, TRUE); + GtkToggleButton *toggle; + gboolean isMarkup; + + gboolean res; + + toggle = trans == GTK_EXPERIMENT_TRANSCRIPT(transcript_wizard_widget) + ? GTK_TOGGLE_BUTTON(transcript_wizard_entry_check) + : GTK_TOGGLE_BUTTON(transcript_proband_entry_check); + isMarkup = gtk_toggle_button_get_active(toggle); + + res = gtk_experiment_transcript_set_interactive_format(trans, text, + isMarkup); + + gtk_entry_set_icon_from_stock(GTK_ENTRY(editable), + GTK_ENTRY_ICON_PRIMARY, + res ? "gtk-dialog-error" : "gtk-apply"); + gtk_entry_set_icon_sensitive(GTK_ENTRY(editable), + GTK_ENTRY_ICON_PRIMARY, + text != NULL && *text); +} + +void +generic_transcript_entry_check_toggled_cb(gpointer user_data, + GtkToggleButton *widget __attribute__((unused))) +{ + gint position = 0; + + /* + * Hack to update the transcript's interactive format + */ + gtk_editable_insert_text(GTK_EDITABLE(user_data), "", 0, &position); } static void @@ -287,6 +287,8 @@ main(int argc, char *argv[]) BUILDER_INIT(builder, transcript_wizard_combo); BUILDER_INIT(builder, transcript_proband_combo); + BUILDER_INIT(builder, transcript_wizard_entry_check); + BUILDER_INIT(builder, transcript_proband_entry_check); BUILDER_INIT(builder, navigator_scrolledwindow); BUILDER_INIT(builder, navigator_widget); |