add text box to set durations from formatted strings

This commit is contained in:
Brandon Lewis 2010-07-27 15:25:20 +02:00 committed by Edward Hervey
parent 496c654728
commit d67801792d
2 changed files with 139 additions and 6 deletions

View file

@ -18,9 +18,13 @@
* Boston, MA 02111-1307, USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <ges/ges.h>
#include <regex.h>
typedef struct App
{
@ -44,6 +48,8 @@ typedef struct App
GtkComboBox *halign;
GtkComboBox *valign;
GtkEntry *text;
GtkEntry *seconds;
GtkWidget *generic_duration;
GstState state;
GType selected_type;
} App;
@ -108,6 +114,9 @@ void connect_to_title_source (GESTimelineObject * object, App * app);
void disconnect_from_title_source (GESTimelineObject * object, App * app);
void seconds_notify_text_changed_cb (GtkEntry * widget, GParamSpec * unused,
App * app);
/* UI state functions *******************************************************/
static void
@ -194,6 +203,9 @@ app_selection_changed_cb (GtkTreeSelection * selection, App * app)
gtk_widget_set_visible (app->text_properties,
app->selected_type == GES_TYPE_TIMELINE_TITLE_SOURCE);
gtk_widget_set_visible (app->generic_duration,
app->selected_type == GES_TYPE_TIMELINE_TITLE_SOURCE);
}
gboolean
@ -278,6 +290,74 @@ text_notify_text_changed_cb (GtkEntry * widget, GParamSpec * unused, App * app)
}
}
static gboolean
check_time (const gchar * time)
{
static regex_t re;
static gboolean compiled = FALSE;
if (!compiled) {
compiled = TRUE;
regcomp (&re, "^[0-9][0-9]:[0-5][0-9]:[0-5][0-9](.[0-9]+)?$",
REG_EXTENDED | REG_NOSUB);
}
if (!regexec (&re, time, (size_t) 0, NULL, 0))
return TRUE;
return FALSE;
}
static guint64
str_to_time (const gchar * str)
{
guint64 ret;
guint64 h, m;
gdouble s;
gchar buf[15];
buf[0] = str[0];
buf[1] = str[1];
buf[2] = '\0';
h = strtoull (buf, NULL, 10);
buf[0] = str[3];
buf[1] = str[4];
buf[2] = '\0';
m = strtoull (buf, NULL, 10);
strncpy (buf, &str[6], sizeof (buf));
s = strtod (buf, NULL);
ret = (h * 3600 * GST_SECOND) +
(m * 60 * GST_SECOND) + ((guint64) (s * GST_SECOND));
return ret;
}
void
seconds_notify_text_changed_cb (GtkEntry * widget, GParamSpec * unused,
App * app)
{
GList *tmp;
const gchar *text;
text = gtk_entry_get_text (app->seconds);
if (!check_time (text)) {
gtk_entry_set_icon_from_stock (app->seconds,
GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_DIALOG_WARNING);
} else {
gtk_entry_set_icon_from_stock (app->seconds,
GTK_ENTRY_ICON_SECONDARY, NULL);
for (tmp = app->selected_objects; tmp; tmp = tmp->next) {
g_object_set (GES_TIMELINE_OBJECT (tmp->data), "duration",
(guint64) str_to_time (text), NULL);
}
}
}
/* application methods ******************************************************/
static void selection_foreach (GtkTreeModel * model, GtkTreePath * path,
@ -653,11 +733,23 @@ disconnect_from_filesource (GESTimelineObject * object, App * app)
void
connect_to_title_source (GESTimelineObject * object, App * app)
{
gdouble s;
guint64 duration;
gchar buf[30];
GESTimelineTitleSource *obj;
obj = GES_TIMELINE_TITLE_SOURCE (object);
gtk_combo_box_set_active (app->halign, obj->halign);
gtk_combo_box_set_active (app->valign, obj->valign);
gtk_entry_set_text (app->text, obj->text);
duration = GES_TIMELINE_OBJECT_DURATION (object);
s = (duration / (float) GST_SECOND);
g_snprintf (buf, sizeof (buf), "%02u:%02u:%02u.%09u",
GST_TIME_ARGS (duration));
gtk_entry_set_text (app->seconds, buf);
}
void
@ -717,12 +809,17 @@ create_ui (App * app)
GET_WIDGET (app->add_file, "add_file", GTK_ACTION);
GET_WIDGET (app->delete, "delete", GTK_ACTION);
GET_WIDGET (app->play, "play", GTK_ACTION);
GET_WIDGET (app->seconds, "seconds", GTK_ENTRY);
GET_WIDGET (app->generic_duration, "generic_duration", GTK_WIDGET);
/* get text notifications */
g_signal_connect (app->text, "notify::text",
G_CALLBACK (text_notify_text_changed_cb), app);
g_signal_connect (app->seconds, "notify::text",
G_CALLBACK (seconds_notify_text_changed_cb), app);
/* we care when the tree selection changes */
if (!(app->selection = gtk_tree_view_get_selection (timeline)))

View file

@ -133,8 +133,8 @@
<child>
<object class="GtkImageMenuItem" id="delete_item">
<property name="visible">True</property>
<property name="related_action">delete</property>
<property name="use_action_appearance">True</property>
<property name="related_action">delete</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
@ -161,15 +161,15 @@
<child>
<object class="GtkMenuItem" id="add_file_item">
<property name="visible">True</property>
<property name="related_action">add_file</property>
<property name="use_action_appearance">True</property>
<property name="related_action">add_file</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem4">
<property name="visible">True</property>
<property name="related_action">add_text</property>
<property name="use_action_appearance">True</property>
<property name="related_action">add_text</property>
</object>
</child>
<child>
@ -181,8 +181,8 @@
<child>
<object class="GtkImageMenuItem" id="menuitem2">
<property name="visible">True</property>
<property name="related_action">play</property>
<property name="use_action_appearance">True</property>
<property name="related_action">play</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
@ -357,6 +357,40 @@
<object class="GtkVBox" id="vbox2">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkHBox" id="generic_duration">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="xpad">12</property>
<property name="label" translatable="yes">Duration:</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="seconds">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="filesource_properties">
<property name="visible">True</property>
@ -444,7 +478,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
<property name="position">1</property>
</packing>
</child>
<child>
@ -540,7 +574,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
<property name="position">2</property>
</packing>
</child>
</object>
@ -570,12 +604,14 @@
<object class="GtkTreeSelection" id="selection"/>
<object class="GtkSizeGroup" id="LabelSizeGroup">
<widgets>
<widget name="label4"/>
<widget name="label3"/>
<widget name="label2"/>
<widget name="label_inpoint"/>
<widget name="label_duration"/>
<widget name="label_duration"/>
<widget name="label_inpoint"/>
<widget name="label4"/>
</widgets>
</object>
<object class="GtkAction" id="delete">