[Xfce4-commits] <parole:master> Add some nice features from the new version, like media tooltips, open containing folder, media length.
Ali Abdallah
noreply at xfce.org
Fri Apr 15 16:44:04 CEST 2011
Updating branch refs/heads/master
to 6d95f5740234781afc222d6017728702d8bed5c0 (commit)
from ef9b1bcc2ff829085dfc77e6bf53e650e26ce445 (commit)
commit 6d95f5740234781afc222d6017728702d8bed5c0
Author: Ali Abdallah <aliov at xfce.org>
Date: Fri Apr 15 15:50:18 2011 +0200
Add some nice features from the new version, like media tooltips, open
containing folder, media length.
common/parole-common.c | 43 +++
common/parole-common.h | 11 +
data/interfaces/playlist.ui | 261 +++++++++++--------
src/parole-conf.c | 80 ++++++-
src/parole-conf.h | 7 +-
src/parole-mediachooser.c | 212 +++++++++------
src/parole-mediachooser.h | 24 +--
src/parole-medialist.c | 616 ++++++++++++++++++++++++++++++++++++++++---
src/parole-medialist.h | 11 +-
src/parole-open-location.c | 107 +++-----
src/parole-open-location.h | 21 +--
src/parole-utils.c | 74 +++++
src/parole-utils.h | 4 +
13 files changed, 1127 insertions(+), 344 deletions(-)
diff --git a/common/parole-common.c b/common/parole-common.c
index 695e919..424d70e 100644
--- a/common/parole-common.c
+++ b/common/parole-common.c
@@ -28,8 +28,51 @@
#include <glib.h>
+#include <libxfce4util/libxfce4util.h>
+
#include "parole-common.h"
+
+static void
+parole_dialog_show (GtkWindow *parent,
+ GtkMessageType type,
+ const gchar *window_title,
+ const gchar *title,
+ const gchar *msg)
+{
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new_with_markup (parent,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ type,
+ GTK_BUTTONS_CLOSE,
+ "<span size='larger'><b>%s</b></span>",
+ title);
+
+ gtk_window_set_title (GTK_WINDOW (dialog), window_title);
+
+ gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), "%s", msg);
+
+
+ g_signal_connect_swapped (dialog,
+ "response",
+ G_CALLBACK (gtk_widget_destroy),
+ dialog);
+
+ gtk_widget_show_all (dialog);
+}
+
+void parole_dialog_info (GtkWindow *parent, const gchar *title, const gchar *msg)
+{
+ parole_dialog_show (parent, GTK_MESSAGE_INFO, _("Message"), title, msg);
+}
+
+void parole_dialog_error (GtkWindow *parent, const gchar *title, const gchar *msg)
+{
+ parole_dialog_show (parent, GTK_MESSAGE_ERROR, _("Error"), title, msg);
+}
+
+
void parole_window_busy_cursor (GdkWindow *window)
{
GdkCursor *cursor;
diff --git a/common/parole-common.h b/common/parole-common.h
index 1cae844..3c12bfe 100644
--- a/common/parole-common.h
+++ b/common/parole-common.h
@@ -24,8 +24,19 @@
#include <gtk/gtk.h>
#include <gdk/gdk.h>
+
+void parole_dialog_info (GtkWindow *parent,
+ const gchar *title,
+ const gchar *msg);
+
+void parole_dialog_error (GtkWindow *parent,
+ const gchar *title,
+ const gchar *msg);
+
void parole_window_busy_cursor (GdkWindow *window);
void parole_window_invisible_cursor (GdkWindow *window);
+
+
#endif /* __PAROLE_COMMON_ */
diff --git a/data/interfaces/playlist.ui b/data/interfaces/playlist.ui
index 44304e7..3dc9f3e 100644
--- a/data/interfaces/playlist.ui
+++ b/data/interfaces/playlist.ui
@@ -1,135 +1,174 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="2.16"/>
<!-- interface-naming-policy project-wide -->
- <object class="GtkVBox" id="playlist-box">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="spacing">5</property>
- <child>
- <object class="GtkScrolledWindow" id="scrolledwindow1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">never</property>
- <property name="vscrollbar_policy">automatic</property>
- <property name="shadow_type">in</property>
- <child>
- <object class="GtkTreeView" id="media-list">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="headers_visible">False</property>
- <property name="rules_hint">True</property>
- <signal name="key_press_event" handler="parole_media_list_key_press"/>
- <signal name="row_activated" handler="parole_media_list_row_activated_cb"/>
- <signal name="button_release_event" handler="parole_media_list_button_release_event"/>
- <signal name="drag_data_received" handler="parole_media_list_drag_data_received_cb"/>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="hbox3">
- <property name="visible">True</property>
- <property name="spacing">2</property>
- <property name="homogeneous">True</property>
- <child>
- <object class="GtkButton" id="add-media">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="image">image1</property>
- <signal name="clicked" handler="parole_media_list_add_clicked_cb"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="save-playlist">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="image">image5</property>
- <signal name="clicked" handler="parole_media_list_save_cb"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="remove-media">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="image">image2</property>
- <signal name="clicked" handler="parole_media_list_remove_clicked_cb"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="media-up">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="image">image3</property>
- <signal name="clicked" handler="parole_media_list_media_up_clicked_cb"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="media-down">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="image">image4</property>
- <signal name="clicked" handler="parole_media_list_media_down_clicked_cb"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">4</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="stock">gtk-add</property>
</object>
<object class="GtkImage" id="image2">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="stock">gtk-remove</property>
</object>
<object class="GtkImage" id="image3">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="stock">gtk-go-up</property>
</object>
<object class="GtkImage" id="image4">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="stock">gtk-go-down</property>
</object>
<object class="GtkImage" id="image5">
<property name="visible">True</property>
+ <property name="can_focus">False</property>
<property name="stock">gtk-save-as</property>
</object>
+ <object class="GtkVBox" id="playlist-box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">5</property>
+ <child>
+ <object class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="window_placement_set">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="media-list">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="headers_visible">False</property>
+ <property name="rules_hint">True</property>
+ <signal name="key-press-event" handler="parole_media_list_key_press" swapped="no"/>
+ <signal name="row-activated" handler="parole_media_list_row_activated_cb" swapped="no"/>
+ <signal name="button-release-event" handler="parole_media_list_button_release_event" swapped="no"/>
+ <signal name="drag-data-received" handler="parole_media_list_drag_data_received_cb" swapped="no"/>
+ <signal name="query-tooltip" handler="parole_media_list_query_tooltip" swapped="no"/>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">2</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkButton" id="add-media">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="image">image1</property>
+ <signal name="clicked" handler="parole_media_list_add_clicked_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="save-playlist">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="image">image5</property>
+ <signal name="clicked" handler="parole_media_list_save_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="remove-media">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="image">image2</property>
+ <signal name="clicked" handler="parole_media_list_remove_clicked_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="media-up">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="image">image3</property>
+ <signal name="clicked" handler="parole_media_list_media_up_clicked_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="media-down">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="image">image4</property>
+ <signal name="clicked" handler="parole_media_list_media_down_clicked_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">4</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
</interface>
diff --git a/src/parole-conf.c b/src/parole-conf.c
index 04bfce4..f5f1bbc 100644
--- a/src/parole-conf.c
+++ b/src/parole-conf.c
@@ -65,6 +65,13 @@ enum
PROP_ASPECT_RATIO,
PROP_WINDOW_WIDTH,
PROP_WINDOW_HEIGHT,
+ PROP_MINIMIZED,
+ PROP_MULTIMEDIA_KEYS,
+ /*Playlist*/
+ PROP_REPLACE_PLAYLIST,
+ PROP_SCAN_FOLDER_RECURSIVELY,
+ PROP_START_PLAYING_OPENED_FILES,
+ PROP_REMOVE_DUPLICATED_PLAYLIST_ENTRIES,
N_PROP
};
@@ -242,6 +249,13 @@ parole_conf_class_init (ParoleConfClass *klass)
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
+ PROP_MINIMIZED,
+ g_param_spec_boolean ("minimized",
+ NULL, NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
PROP_SUBTITLE_FONT,
g_param_spec_string ("subtitle-font",
NULL, NULL,
@@ -309,20 +323,62 @@ parole_conf_class_init (ParoleConfClass *klass)
PROP_WINDOW_WIDTH,
g_param_spec_int ("window-width",
NULL, NULL,
- 320,
+ 100,
G_MAXINT16,
- 780,
+ 760,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_WINDOW_HEIGHT,
g_param_spec_int ("window-height",
NULL, NULL,
- 220,
+ 100,
G_MAXINT16,
- 480,
+ 420,
G_PARAM_READWRITE));
-
+
+ g_object_class_install_property (object_class,
+ PROP_MULTIMEDIA_KEYS,
+ g_param_spec_boolean ("multimedia-keys",
+ NULL, NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+
+ /**
+ *Playlist options
+ **/
+ g_object_class_install_property (object_class,
+ PROP_REPLACE_PLAYLIST,
+ g_param_spec_boolean ("replace-playlist",
+ NULL, NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_SCAN_FOLDER_RECURSIVELY,
+ g_param_spec_boolean ("scan-recursive",
+ NULL, NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_START_PLAYING_OPENED_FILES,
+ g_param_spec_boolean ("play-opened-files",
+ NULL, NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+
+ /**
+ *
+ * Remove duplicated entries from the playlist.
+ **/
+ g_object_class_install_property (object_class,
+ PROP_REMOVE_DUPLICATED_PLAYLIST_ENTRIES,
+ g_param_spec_boolean ("remove-duplicated",
+ NULL, NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
g_type_class_add_private (klass, sizeof (ParoleConfPrivate));
}
@@ -414,3 +470,17 @@ parole_conf_new (void)
return PAROLE_CONF (parole_conf_object);
}
+
+
+gboolean parole_conf_get_property_bool (ParoleConf *conf,
+ const gchar *name)
+{
+ gboolean value;
+
+ g_object_get (G_OBJECT (conf),
+ name, &value,
+ NULL);
+
+ return value;
+}
+
diff --git a/src/parole-conf.h b/src/parole-conf.h
index 79910a2..73021aa 100644
--- a/src/parole-conf.h
+++ b/src/parole-conf.h
@@ -45,9 +45,12 @@ typedef struct
} ParoleConfClass;
-GType parole_conf_get_type (void) G_GNUC_CONST;
+GType parole_conf_get_type (void) G_GNUC_CONST;
-ParoleConf *parole_conf_new (void);
+ParoleConf *parole_conf_new (void);
+
+gboolean parole_conf_get_property_bool (ParoleConf *conf,
+ const gchar *name);
G_END_DECLS
diff --git a/src/parole-mediachooser.c b/src/parole-mediachooser.c
index c51fb79..098ec71 100644
--- a/src/parole-mediachooser.c
+++ b/src/parole-mediachooser.c
@@ -30,7 +30,6 @@
#include <glib.h>
#include <libxfce4util/libxfce4util.h>
-#include <libxfcegui4/libxfcegui4.h>
#include <parole/parole-file.h>
@@ -44,15 +43,16 @@
#include "common/parole-common.h"
-#include "gmarshal.h"
-
/*
* GtkBuilder Callbacks
*/
-void parole_media_chooser_open (GtkWidget *widget,
- ParoleMediaChooser *chooser);
+void parole_media_chooser_add_clicked (GtkWidget *widget,
+ ParoleMediaChooser *chooser);
+
+void parole_media_chooser_close_clicked (GtkWidget *widget,
+ ParoleMediaChooser *chooser);
-void parole_media_chooser_close (GtkWidget *widget,
+void parole_media_chooser_destroy_cb (GtkWidget *widget,
ParoleMediaChooser *chooser);
void media_chooser_folder_changed_cb (GtkWidget *widget,
@@ -70,6 +70,24 @@ void parole_media_chooser_replace_toggled_cb (GtkToggleButton *button,
void start_playing_toggled_cb (GtkToggleButton *button,
gpointer data);
+struct ParoleMediaChooser
+{
+ GObject parent;
+
+ ParoleConf *conf;
+ GtkWidget *window;
+ GtkWidget *info;
+
+};
+
+struct ParoleMediaChooserClass
+{
+ GObjectClass parent_class;
+
+ void (*media_files_opened) (ParoleMediaChooser *chooser,
+ GSList *list);
+};
+
enum
{
MEDIA_FILES_OPENED,
@@ -78,12 +96,7 @@ enum
static guint signals [LAST_SIGNAL] = { 0 };
-G_DEFINE_TYPE (ParoleMediaChooser, parole_media_chooser, GTK_TYPE_DIALOG)
-
-void parole_media_chooser_close (GtkWidget *widget, ParoleMediaChooser *chooser)
-{
- gtk_widget_destroy (GTK_WIDGET (chooser));
-}
+G_DEFINE_TYPE (ParoleMediaChooser, parole_media_chooser, G_TYPE_OBJECT)
void
media_chooser_folder_changed_cb (GtkWidget *widget, gpointer data)
@@ -105,11 +118,7 @@ parole_media_chooser_add (ParoleMediaChooser *chooser, GtkWidget *file_chooser)
GSList *files;
GtkFileFilter *filter;
GtkWidget *recursive;
- GtkWidget *replace;
- GtkWidget *play_opened;
gboolean scan_recursive;
- gboolean replace_playlist;
- gboolean play;
gchar *file;
guint i;
guint len;
@@ -121,12 +130,8 @@ parole_media_chooser_add (ParoleMediaChooser *chooser, GtkWidget *file_chooser)
return;
recursive = g_object_get_data (G_OBJECT (chooser), "recursive");
- replace = g_object_get_data (G_OBJECT (chooser), "replace-playlist");
- play_opened = g_object_get_data (G_OBJECT (chooser), "play");
scan_recursive = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (recursive));
- replace_playlist = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (replace));
- play = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (play_opened));
len = g_slist_length (files);
@@ -136,63 +141,110 @@ parole_media_chooser_add (ParoleMediaChooser *chooser, GtkWidget *file_chooser)
parole_get_media_files (filter, file, scan_recursive, &media_files);
}
- g_signal_emit (G_OBJECT (chooser), signals [MEDIA_FILES_OPENED], 0, play, replace_playlist, media_files);
+ g_signal_emit (G_OBJECT (chooser), signals [MEDIA_FILES_OPENED], 0, media_files);
g_slist_free (media_files);
g_slist_foreach (files, (GFunc) g_free, NULL);
g_slist_free (files);
}
-void
-parole_media_chooser_open (GtkWidget *widget, ParoleMediaChooser *chooser)
+static gboolean
+parole_media_chooser_add_idle (gpointer data)
{
+ ParoleMediaChooser *chooser;
GtkWidget *file_chooser;
-
+
+ chooser = PAROLE_MEDIA_CHOOSER (data);
+
file_chooser = GTK_WIDGET (g_object_get_data (G_OBJECT (chooser), "file-chooser"));
- parole_window_busy_cursor (GTK_WIDGET (chooser)->window);
parole_media_chooser_add (chooser, file_chooser);
- gtk_widget_destroy (GTK_WIDGET (chooser));
+
+ gtk_widget_destroy (chooser->window);
+
+ return FALSE;
+}
+
+static void
+parole_media_chooser_open (ParoleMediaChooser *chooser)
+{
+ GtkWidget *img;
+ gchar *path;
+
+ parole_window_busy_cursor (chooser->window->window);
+
+ path = g_build_filename (PIXMAPS_DIR, "loader.gif", NULL);
+
+ img = gtk_image_new_from_file (path);
+ g_free (path);
+
+ gtk_box_pack_start (GTK_BOX (chooser->info), img, FALSE, FALSE, 0);
+ gtk_widget_show_all (chooser->info);
+
+ g_idle_add ((GSourceFunc) parole_media_chooser_add_idle, chooser);
+}
+
+void parole_media_chooser_add_clicked (GtkWidget *widget, ParoleMediaChooser *chooser)
+{
+ parole_media_chooser_open (chooser);
+}
+
+void parole_media_chooser_close_clicked (GtkWidget *widget, ParoleMediaChooser *chooser)
+{
+ gtk_widget_destroy (chooser->window);
+}
+
+void parole_media_chooser_destroy_cb (GtkWidget *widget, ParoleMediaChooser *chooser)
+{
+ g_object_unref (chooser);
}
void media_chooser_file_activate_cb (GtkFileChooser *filechooser, ParoleMediaChooser *chooser)
{
- parole_media_chooser_open (NULL, chooser);
+ parole_media_chooser_open (chooser);
}
-void parole_media_chooser_recursive_toggled_cb (GtkToggleButton *recursive,
- gpointer data)
+void parole_media_chooser_recursive_toggled_cb (GtkToggleButton *recursive,
+ gpointer data)
{
- parole_rc_write_entry_bool ("scan-recursive",
- PAROLE_RC_GROUP_GENERAL,
- gtk_toggle_button_get_active (recursive));
+ ParoleMediaChooser *chooser;
+
+ chooser = PAROLE_MEDIA_CHOOSER (data);
+
+ g_object_set (G_OBJECT (chooser->conf),
+ "scan-recursive", gtk_toggle_button_get_active (recursive),
+ NULL);
}
void parole_media_chooser_replace_toggled_cb (GtkToggleButton *button,
gpointer data)
{
- parole_rc_write_entry_bool ("replace-playlist",
- PAROLE_RC_GROUP_GENERAL,
- gtk_toggle_button_get_active (button));
+ ParoleMediaChooser *chooser;
+
+ chooser = PAROLE_MEDIA_CHOOSER (data);
+
+ g_object_set (G_OBJECT (chooser->conf),
+ "replace-playlist", gtk_toggle_button_get_active (button),
+ NULL);
}
void start_playing_toggled_cb (GtkToggleButton *button,
gpointer data)
{
- parole_rc_write_entry_bool ("play-opened-files",
- PAROLE_RC_GROUP_GENERAL,
- gtk_toggle_button_get_active (button));
+ ParoleMediaChooser *chooser;
+
+ chooser = PAROLE_MEDIA_CHOOSER (data);
+
+ g_object_set (G_OBJECT (chooser->conf),
+ "play-opened-files", gtk_toggle_button_get_active (button),
+ NULL);
}
static void
-parole_media_chooser_open_internal (GtkWidget *chooser)
+parole_media_chooser_open_internal (ParoleMediaChooser *media_chooser)
{
- ParoleMediaChooser *media_chooser;
- GtkWidget *vbox;
GtkWidget *file_chooser;
GtkBuilder *builder;
- GtkWidget *open;
- GtkWidget *img;
GtkWidget *recursive;
GtkWidget *replace;
GtkWidget *play_opened;
@@ -201,17 +253,13 @@ parole_media_chooser_open_internal (GtkWidget *chooser)
gboolean play;
const gchar *folder;
- media_chooser = PAROLE_MEDIA_CHOOSER (chooser);
-
builder = parole_builder_new_from_string (mediachooser_ui, mediachooser_ui_length);
- file_chooser = GTK_WIDGET (gtk_builder_get_object (builder, "filechooserwidget"));
+ media_chooser->window = GTK_WIDGET (gtk_builder_get_object (builder, "chooser"));
+ media_chooser->info = GTK_WIDGET (gtk_builder_get_object (builder, "info"));
- vbox = GTK_WIDGET (gtk_builder_get_object (builder, "vbox"));
- open = GTK_WIDGET (gtk_builder_get_object (builder, "open"));
+ file_chooser = GTK_WIDGET (gtk_builder_get_object (builder, "filechooserwidget"));
- gtk_window_set_title (GTK_WINDOW (chooser), _("Add media files"));
-
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (file_chooser), parole_get_supported_files_filter ());
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (file_chooser), parole_get_supported_media_filter ());
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (file_chooser), parole_get_supported_audio_filter ());
@@ -224,44 +272,41 @@ parole_media_chooser_open_internal (GtkWidget *chooser)
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (file_chooser), folder);
gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (file_chooser), TRUE);
-
- scan_recursive = parole_rc_read_entry_bool ("scan-recursive", PAROLE_RC_GROUP_GENERAL, TRUE);
+
+ g_object_get (G_OBJECT (media_chooser->conf),
+ "scan-recursive", &scan_recursive,
+ "replace-playlist", &replace_playlist,
+ "play-opened-files", &play,
+ NULL);
recursive = GTK_WIDGET (gtk_builder_get_object (builder, "recursive"));
replace = GTK_WIDGET (gtk_builder_get_object (builder, "replace"));
play_opened = GTK_WIDGET (gtk_builder_get_object (builder, "play-added-files"));
- scan_recursive = parole_rc_read_entry_bool ("scan-recursive", PAROLE_RC_GROUP_GENERAL, TRUE);
- replace_playlist = parole_rc_read_entry_bool ("replace-playlist", PAROLE_RC_GROUP_GENERAL, FALSE);
- play = parole_rc_read_entry_bool ("play-opened-files", PAROLE_RC_GROUP_GENERAL, TRUE);
-
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (recursive), scan_recursive);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (replace), replace_playlist);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (play_opened), play);
- img = gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON);
-
- g_object_set (G_OBJECT (open),
- "image", img,
- "label", _("Add"),
- NULL);
+ g_object_set_data (G_OBJECT (media_chooser), "file-chooser", file_chooser);
+ g_object_set_data (G_OBJECT (media_chooser), "recursive", recursive);
- g_object_set_data (G_OBJECT (chooser), "file-chooser", file_chooser);
- g_object_set_data (G_OBJECT (chooser), "recursive", recursive);
- g_object_set_data (G_OBJECT (chooser), "replace-playlist", replace);
- g_object_set_data (G_OBJECT (chooser), "play", play_opened);
+ gtk_builder_connect_signals (builder, media_chooser);
- gtk_container_add (GTK_CONTAINER (GTK_DIALOG (media_chooser)->vbox), vbox);
- gtk_builder_connect_signals (builder, chooser);
- g_signal_connect (chooser, "destroy",
- G_CALLBACK (gtk_widget_destroy), chooser);
-
g_object_unref (builder);
}
static void
parole_media_chooser_finalize (GObject *object)
{
+ ParoleMediaChooser *chooser;
+
+ chooser = PAROLE_MEDIA_CHOOSER (object);
+
+ g_object_unref (chooser->conf);
+
+ if ( chooser->window )
+ gtk_widget_destroy (chooser->window);
+
G_OBJECT_CLASS (parole_media_chooser_parent_class)->finalize (object);
}
@@ -276,10 +321,8 @@ parole_media_chooser_class_init (ParoleMediaChooserClass *klass)
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ParoleMediaChooserClass, media_files_opened),
NULL, NULL,
- _gmarshal_VOID__BOOLEAN_BOOLEAN_POINTER,
- G_TYPE_NONE, 3,
- G_TYPE_BOOLEAN,
- G_TYPE_BOOLEAN,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
G_TYPE_POINTER);
object_class->finalize = parole_media_chooser_finalize;
@@ -288,22 +331,25 @@ parole_media_chooser_class_init (ParoleMediaChooserClass *klass)
static void
parole_media_chooser_init (ParoleMediaChooser *chooser)
{
- gtk_window_set_modal (GTK_WINDOW (chooser), TRUE);
+ chooser->conf = parole_conf_new ();
}
-GtkWidget *parole_media_chooser_open_local (GtkWidget *parent)
+ParoleMediaChooser *parole_media_chooser_open_local (GtkWidget *parent)
{
ParoleMediaChooser *chooser;
chooser = g_object_new (PAROLE_TYPE_MEDIA_CHOOSER, NULL);
+ parole_media_chooser_open_internal (chooser);
+
+ gtk_window_set_modal (GTK_WINDOW (chooser->window), TRUE);
+
if ( parent )
- gtk_window_set_transient_for (GTK_WINDOW (chooser), GTK_WINDOW (parent));
+ gtk_window_set_transient_for (GTK_WINDOW (chooser->window), GTK_WINDOW (parent));
- gtk_window_set_position (GTK_WINDOW (chooser), GTK_WIN_POS_CENTER_ON_PARENT);
- parole_media_chooser_open_internal (GTK_WIDGET (chooser));
-
- gtk_window_set_default_size (GTK_WINDOW (chooser), 680, 480);
+ gtk_window_set_position (GTK_WINDOW (chooser->window), GTK_WIN_POS_CENTER_ON_PARENT);
+
+ gtk_widget_show_all (chooser->window);
- return GTK_WIDGET (chooser);
+ return chooser;
}
diff --git a/src/parole-mediachooser.h b/src/parole-mediachooser.h
index 46718f0..36e61d4 100644
--- a/src/parole-mediachooser.h
+++ b/src/parole-mediachooser.h
@@ -24,34 +24,20 @@
#include <glib-object.h>
#include <gtk/gtk.h>
+#include "parole-conf.h"
+
G_BEGIN_DECLS
#define PAROLE_TYPE_MEDIA_CHOOSER (parole_media_chooser_get_type () )
#define PAROLE_MEDIA_CHOOSER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_MEDIA_CHOOSER, ParoleMediaChooser))
#define PAROLE_IS_MEDIA_CHOOSER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_MEDIA_CHOOSER))
-typedef struct ParoleMediaChooserPrivate ParoleMediaChooserPrivate;
-
-typedef struct
-{
- GtkDialog parent;
-
-} ParoleMediaChooser;
-
-typedef struct
-{
- GtkDialogClass parent_class;
-
- void (*media_files_opened) (ParoleMediaChooser *chooser,
- gboolean play,
- gboolean replace,
- GSList *list);
-
-} ParoleMediaChooserClass;
+typedef struct ParoleMediaChooser ParoleMediaChooser;
+typedef struct ParoleMediaChooserClass ParoleMediaChooserClass;
GType parole_media_chooser_get_type (void) G_GNUC_CONST;
-GtkWidget *parole_media_chooser_open_local (GtkWidget *parent);
+ParoleMediaChooser *parole_media_chooser_open_local (GtkWidget *parent);
G_END_DECLS
diff --git a/src/parole-medialist.c b/src/parole-medialist.c
index 9ff5304..e9b70ed 100644
--- a/src/parole-medialist.c
+++ b/src/parole-medialist.c
@@ -26,18 +26,15 @@
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <gio/gio.h>
-
-#ifdef XFCE_DISABLE_DEPRECATED
-#undef XFCE_DISABLE_DEPRECATED
-#endif
#include <libxfce4util/libxfce4util.h>
-#include <libxfcegui4/libxfcegui4.h>
#include <parole/parole-file.h>
@@ -48,6 +45,7 @@
#include "parole-medialist.h"
#include "parole-mediachooser.h"
#include "parole-open-location.h"
+#include "parole-conf.h"
#include "parole-filters.h"
#include "parole-pl-parser.h"
@@ -146,6 +144,14 @@ void parole_media_list_close_save_dialog_cb (GtkButton *button,
void parole_media_list_save_playlist_cb (GtkButton *button,
ParolePlaylistSave *data);
+
+gboolean parole_media_list_query_tooltip (GtkWidget *widget,
+ gint x,
+ gint y,
+ gboolean keyboard_mode,
+ GtkTooltip *tooltip,
+ ParoleMediaList *list);
+
/*
* End of GtkBuilder callbacks
*/
@@ -156,6 +162,7 @@ void parole_media_list_save_playlist_cb (GtkButton *button,
struct ParoleMediaListPrivate
{
DBusGConnection *bus;
+ ParoleConf *conf;
GtkWidget *view;
GtkWidget *box;
GtkListStore *store;
@@ -188,6 +195,17 @@ parole_media_list_set_widget_sensitive (ParoleMediaList *list, gboolean sensitiv
gtk_widget_set_sensitive (GTK_WIDGET (list->priv->save), sensitive);
}
+/**
+ * parole_media_list_add:
+ * @ParoleMediaList: a #ParoleMediaList
+ * @file: a #ParoleFile
+ * @emit: TRUE to emit a play signal.
+ * @select_row: TRUE to select the added row
+ *
+ * All the media items added to the media list view are added by
+ * this function, setting emit to TRUE will cause the player to
+ * start playing the added file.
+ **/
static void
parole_media_list_add (ParoleMediaList *list, ParoleFile *file, gboolean emit, gboolean select_row)
{
@@ -205,16 +223,19 @@ parole_media_list_add (ParoleMediaList *list, ParoleFile *file, gboolean emit, g
&iter,
NAME_COL, parole_file_get_display_name (file),
DATA_COL, file,
+ LENGTH_COL, parole_taglibc_get_media_length (file),
+ PIXBUF_COL, NULL,
-1);
- if ( emit )
+ if ( emit || select_row )
{
path = gtk_tree_model_get_path (GTK_TREE_MODEL (list_store), &iter);
row = gtk_tree_row_reference_new (GTK_TREE_MODEL (list_store), path);
if ( select_row )
parole_media_list_select_path (list, path);
gtk_tree_path_free (path);
- g_signal_emit (G_OBJECT (list), signals [MEDIA_ACTIVATED], 0, row);
+ if ( emit )
+ g_signal_emit (G_OBJECT (list), signals [MEDIA_ACTIVATED], 0, row);
gtk_tree_row_reference_free (row);
}
@@ -238,14 +259,25 @@ parole_media_list_add (ParoleMediaList *list, ParoleFile *file, gboolean emit, g
}
+/**
+ * parole_media_list_files_open:
+ * @ParoleMediaList: a #ParoleMediaList
+ * @files: a #GSList contains a list of #ParoleFile
+ * @emit: TRUE to emit a play signal.
+ *
+ **/
static void
-parole_media_list_files_open (ParoleMediaList *list, GSList *files,
- gboolean replace, gboolean emit)
+parole_media_list_files_open (ParoleMediaList *list, GSList *files, gboolean emit)
{
ParoleFile *file;
+ gboolean replace;
guint len;
guint i;
+ g_object_get (G_OBJECT (list->priv->conf),
+ "replace-playlist", &replace,
+ NULL);
+
len = g_slist_length (files);
TRACE ("Adding files");
@@ -266,12 +298,16 @@ parole_media_list_files_open (ParoleMediaList *list, GSList *files,
static void
parole_media_list_files_opened_cb (ParoleMediaChooser *chooser,
- gboolean play,
- gboolean replace,
GSList *files,
ParoleMediaList *list)
{
- parole_media_list_files_open (list, files, replace, play);
+ gboolean play;
+
+ g_object_get (G_OBJECT (list->priv->conf),
+ "play-opened-files", &play,
+ NULL);
+
+ parole_media_list_files_open (list, files, play);
}
static void
@@ -293,29 +329,37 @@ parole_media_list_location_opened_cb (ParoleOpenLocation *obj, const gchar *loca
static void
parole_media_list_open_internal (ParoleMediaList *list)
{
- GtkWidget *chooser;
+ ParoleMediaChooser *chooser;
+
+ TRACE ("start");
chooser = parole_media_chooser_open_local (gtk_widget_get_toplevel (GTK_WIDGET (list)));
g_signal_connect (G_OBJECT (chooser), "media_files_opened",
G_CALLBACK (parole_media_list_files_opened_cb), list);
-
- gtk_widget_show_all (GTK_WIDGET (chooser));
}
static void
parole_media_list_open_location_internal (ParoleMediaList *list)
{
- GtkWidget *location;
+ ParoleOpenLocation *location;
location = parole_open_location (gtk_widget_get_toplevel (GTK_WIDGET (list)));
g_signal_connect (G_OBJECT (location), "location-opened",
- G_CALLBACK (parole_media_list_location_opened_cb), list);
-
- gtk_widget_show_all (GTK_WIDGET (location));
+ G_CALLBACK (parole_media_list_location_opened_cb), list);
}
+/**
+ * parole_media_list_get_files:
+ * @list: a #ParoleMediaList
+ *
+ * Get a #GSList of all #ParoleFile media files currently displayed in the
+ * media list view
+ *
+ * Returns: a #GSList contains a list of #ParoleFile
+ *
+ **/
static GSList *
parole_media_list_get_files (ParoleMediaList *list)
{
@@ -351,15 +395,20 @@ void parole_media_list_drag_data_received_cb (GtkWidget *widget,
gchar *path;
guint i;
guint added = 0;
+ gboolean play;
parole_window_busy_cursor (GTK_WIDGET (list)->window);
+ g_object_get (G_OBJECT (list->priv->conf),
+ "play-opened-files", &play,
+ NULL);
+
uri_list = g_uri_list_extract_uris ((const gchar *)data->data);
for ( i = 0; uri_list[i] != NULL; i++)
{
path = g_filename_from_uri (uri_list[i], NULL, NULL);
- added += parole_media_list_add_by_path (list, path, i == 0 ? TRUE : FALSE);
+ added += parole_media_list_add_by_path (list, path, i == 0 ? play : FALSE);
g_free (path);
}
@@ -392,6 +441,16 @@ void parole_media_list_close_save_dialog_cb (GtkButton *button, ParolePlaylistSa
g_free (data);
}
+/**
+ * parole_media_list_get_first_selected_row:
+ * @list: a #ParoleMediaList
+ *
+ * Gets the first selected row in the media list view.
+ *
+ * Returns: a #GtkTreeRowReference for the selected row, or NULL if no one is
+ * currently selected.
+ *
+ **/
static GtkTreeRowReference *
parole_media_list_get_first_selected_row (ParoleMediaList *list)
{
@@ -438,7 +497,12 @@ void parole_media_list_save_playlist_cb (GtkButton *button, ParolePlaylistSave *
if ( g_access (dirname, W_OK) == -1 )
{
- xfce_err ("%s %s %s", _("Error saving playlist file"), dirname, _("Permission denied"));
+ gchar *msg;
+ msg = g_strdup_printf ("%s %s", dirname, _("Permission denied"));
+ parole_dialog_error (GTK_WINDOW (gtk_widget_get_toplevel (data->list->priv->view)),
+ _("Error saving playlist file"),
+ msg);
+ g_free (msg);
goto out;
}
@@ -447,7 +511,9 @@ void parole_media_list_save_playlist_cb (GtkButton *button, ParolePlaylistSave *
format = parole_pl_parser_guess_format_from_extension (filename);
if ( format == PAROLE_PL_FORMAT_UNKNOWN )
{
- xfce_info ("%s", _("Unknown playlist format, Please select a support playlist format"));
+ parole_dialog_info (GTK_WINDOW (gtk_widget_get_toplevel (data->list->priv->view)),
+ _("Unknown playlist format"),
+ _("Please chooser a supported playlist format"));
goto out;
}
}
@@ -463,6 +529,64 @@ out:
g_free (dirname);
}
+
+gboolean parole_media_list_query_tooltip (GtkWidget *widget,
+ gint x,
+ gint y,
+ gboolean keyboard_mode,
+ GtkTooltip *tooltip,
+ ParoleMediaList *list)
+
+{
+ GtkTreePath *path;
+
+ if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (list->priv->view),
+ x,
+ y,
+ &path,
+ NULL,
+ NULL,
+ NULL))
+ {
+ GtkTreeIter iter;
+
+ if ( path && gtk_tree_model_get_iter (GTK_TREE_MODEL (list->priv->store), &iter, path))
+ {
+ ParoleFile *file;
+ gchar *tip;
+ gchar *name;
+ gchar *len;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (list->priv->store), &iter,
+ DATA_COL, &file,
+ NAME_COL, &name,
+ LENGTH_COL, &len,
+ -1);
+
+ if (!len)
+ {
+ len = g_strdup (_("Unknown"));
+ }
+
+ tip = g_strdup_printf ("File: %s\nName: %s\nLength: %s",
+ parole_file_get_file_name (file),
+ name,
+ len);
+
+ gtk_tooltip_set_text (tooltip, tip);
+ g_free (tip);
+ g_free (name);
+ g_free (len);
+ gtk_tree_path_free (path);
+
+ return TRUE;
+ }
+ }
+
+
+ return FALSE;
+}
+
void parole_media_list_format_cursor_changed_cb (GtkTreeView *view, ParolePlaylistSave *data)
{
GtkTreeIter iter;
@@ -562,8 +686,42 @@ void parole_media_list_save_cb (GtkButton *button, ParoleMediaList *list)
g_object_unref (builder);
}
+/**
+ * parole_media_list_get_first_path:
+ * @model: a #GtkTreeModel
+ *
+ * Get the first path in the model, or NULL if the model is empty
+ *
+ * Returns: a #GtkTreePath
+ **/
+static GtkTreePath *
+parole_media_list_get_first_path (GtkTreeModel *model)
+{
+ GtkTreePath *path = NULL;
+ GtkTreeIter iter;
+
+ if (gtk_tree_model_get_iter_first (model, &iter) )
+ {
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
+ }
+
+ return path;
+}
+
+/**
+ *
+ * parole_media_list_paths_to_row_list:
+ * @path_list: a #GList contains a list of #GtkTreePath
+ * @GtkTreeModel: a #GtkTreeModel that contains the paths
+ *
+ * Converts a list of #GtkTreePath to a list of #GtkTreeRowReference
+ *
+ * Returns: a #GList contains a list of #GtkTreeRowReference.
+ *
+ *
+ **/
static GList *
-parole_media_list_path_to_row_list (GList *path_list, GtkTreeModel *model)
+parole_media_list_paths_to_row_list (GList *path_list, GtkTreeModel *model)
{
GList *row_list = NULL;
guint len, i;
@@ -585,6 +743,11 @@ parole_media_list_path_to_row_list (GList *path_list, GtkTreeModel *model)
return row_list;
}
+/**
+ * parole_media_list_remove_clicked_cb:
+ *
+ *
+ **/
void
parole_media_list_remove_clicked_cb (GtkButton *button, ParoleMediaList *list)
{
@@ -592,12 +755,40 @@ parole_media_list_remove_clicked_cb (GtkButton *button, ParoleMediaList *list)
GList *path_list = NULL;
GList *row_list = NULL;
GtkTreeIter iter;
+ gboolean row_selected = FALSE;
gint nch;
guint len, i;
-
+
+ /* Get the GtkTreePath GList of all selected rows */
path_list = gtk_tree_selection_get_selected_rows (list->priv->sel, &model);
- row_list = parole_media_list_path_to_row_list (path_list, model);
+ /**
+ * Convert them to row references so when we remove one the others always points
+ * to the correct node.
+ **/
+ row_list = parole_media_list_paths_to_row_list (path_list, model);
+
+ /**
+ * Select first path before the first path
+ * that we going to remove.
+ **/
+ if (g_list_length (path_list) != 0)
+ {
+ GtkTreePath *path, *prev;
+
+ /* Get first item */
+ path = g_list_nth_data (path_list, 0);
+
+ /* copy it as we don't mess with the list*/
+ prev = gtk_tree_path_copy (path);
+
+ if ( gtk_tree_path_prev (prev) )
+ {
+ parole_media_list_select_path (list, prev);
+ row_selected = TRUE;
+ }
+ gtk_tree_path_free (prev);
+ }
g_list_foreach (path_list, (GFunc) gtk_tree_path_free, NULL);
g_list_free (path_list);
@@ -621,6 +812,15 @@ parole_media_list_remove_clicked_cb (GtkButton *button, ParoleMediaList *list)
g_list_foreach (row_list, (GFunc) gtk_tree_row_reference_free, NULL);
g_list_free (row_list);
+ /* No row was selected, then select the first one*/
+ if (!row_selected)
+ {
+ GtkTreePath *path;
+ path = parole_media_list_get_first_path (model);
+ parole_media_list_select_path (list, path);
+ gtk_tree_path_free (path);
+ }
+
/*
* Returns the number of children that iter has.
* As a special case, if iter is NULL,
@@ -644,6 +844,16 @@ parole_media_list_remove_clicked_cb (GtkButton *button, ParoleMediaList *list)
}
}
+/**
+ * parole_media_list_move_on_down:
+ *
+ * @store: a #GtkListStore
+ * @iter: a #GtkTreeIter
+ *
+ * Move the node pointed to by @iter one step down, if the node is the last
+ * one then move it to the first position in the @store.
+ *
+ **/
static void
parole_media_list_move_one_down (GtkListStore *store, GtkTreeIter *iter)
{
@@ -669,6 +879,15 @@ parole_media_list_move_one_down (GtkListStore *store, GtkTreeIter *iter)
gtk_tree_iter_free (pos_iter);
}
+/**
+ * parole_media_list_move_many_down:
+ * @path_list: a #GList contains list of #GtkTreePath
+ * @model: a #GtkTreeModel
+ *
+ * Moves down many nodes pointed to by the paths that are in
+ * the list.
+ *
+ **/
static void
parole_media_list_move_many_down (GList *path_list, GtkTreeModel *model)
{
@@ -677,7 +896,7 @@ parole_media_list_move_many_down (GList *path_list, GtkTreeModel *model)
guint len;
guint i;
- row_list = parole_media_list_path_to_row_list (path_list, model);
+ row_list = parole_media_list_paths_to_row_list (path_list, model);
len = g_list_length (row_list);
@@ -700,6 +919,11 @@ parole_media_list_move_many_down (GList *path_list, GtkTreeModel *model)
g_list_free (row_list);
}
+/**
+ * parole_media_list_media_down_clicked_cb:
+ *
+ *
+ **/
void
parole_media_list_media_down_clicked_cb (GtkButton *button, ParoleMediaList *list)
{
@@ -728,6 +952,17 @@ parole_media_list_media_down_clicked_cb (GtkButton *button, ParoleMediaList *lis
g_list_free (path_list);
}
+
+/**
+ * parole_media_list_move_on_up:
+ *
+ * @store: a #GtkListStore
+ * @iter: a #GtkTreeIter
+ *
+ * Move the node pointed to by @iter one step up, if the node is the first
+ * one then move it to the last position in the @store.
+ *
+ **/
static void
parole_media_list_move_one_up (GtkListStore *store, GtkTreeIter *iter)
{
@@ -756,6 +991,15 @@ parole_media_list_move_one_up (GtkListStore *store, GtkTreeIter *iter)
gtk_tree_iter_free (pos_iter);
}
+/**
+ * parole_media_list_move_many_up:
+ * @path_list: a #GList contains list of #GtkTreePath
+ * @model: a #GtkTreeModel
+ *
+ * Moves up many nodes pointed to by the paths that are in
+ * the list.
+ *
+ **/
static void
parole_media_list_move_many_up (GList *path_list, GtkTreeModel *model)
{
@@ -764,7 +1008,7 @@ parole_media_list_move_many_up (GList *path_list, GtkTreeModel *model)
guint len;
guint i;
- row_list = parole_media_list_path_to_row_list (path_list, model);
+ row_list = parole_media_list_paths_to_row_list (path_list, model);
len = g_list_length (row_list);
@@ -787,6 +1031,11 @@ parole_media_list_move_many_up (GList *path_list, GtkTreeModel *model)
g_list_free (row_list);
}
+/**
+ * parole_media_list_media_up_clicked_cb:
+ *
+ *
+ **/
void
parole_media_list_media_up_clicked_cb (GtkButton *button, ParoleMediaList *list)
{
@@ -815,6 +1064,11 @@ parole_media_list_media_up_clicked_cb (GtkButton *button, ParoleMediaList *list)
g_list_free (path_list);
}
+/**
+ * parole_media_list_row_activated_cb:
+ *
+ *
+ **/
void
parole_media_list_row_activated_cb (GtkTreeView *view, GtkTreePath *path,
GtkTreeViewColumn *col, ParoleMediaList *list)
@@ -838,6 +1092,90 @@ parole_media_list_selection_changed_cb (GtkTreeSelection *sel, ParoleMediaList *
}
static void
+parole_media_list_open_folder (GtkWidget *menu)
+{
+ gchar *dirname;
+
+ dirname = (gchar *) g_object_get_data (G_OBJECT (menu), "folder");
+
+ if (dirname)
+ {
+ gchar *uri;
+ uri = g_filename_to_uri (dirname, NULL, NULL);
+ TRACE ("Opening %s", dirname);
+ gtk_show_uri (gtk_widget_get_screen (menu), uri, GDK_CURRENT_TIME, NULL);
+
+ g_free (uri);
+ }
+}
+
+static void
+parole_media_list_add_open_containing_folder (ParoleMediaList *list, GtkWidget *menu,
+ gint x, gint y)
+{
+
+ GtkTreePath *path;
+
+
+ if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (list->priv->view),
+ x,
+ y,
+ &path,
+ NULL,
+ NULL,
+ NULL))
+ {
+
+ GtkTreeIter iter;
+
+ if ( path && gtk_tree_model_get_iter (GTK_TREE_MODEL (list->priv->store), &iter, path))
+ {
+ ParoleFile *file;
+ const gchar *filename;
+ const gchar *uri;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (list->priv->store), &iter,
+ DATA_COL, &file,
+ -1);
+
+ filename = parole_file_get_file_name (file);
+ uri = parole_file_get_uri (file);
+
+ if (g_str_has_prefix (uri, "file:///"))
+ {
+ GtkWidget *mi, *img;
+ gchar *dirname;
+
+ dirname = g_path_get_dirname (filename);
+
+ /* Clear */
+ mi = gtk_image_menu_item_new_with_label (_("Open Containing Folder"));
+ img = gtk_image_new_from_stock (GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), img);
+ gtk_widget_set_sensitive (mi, TRUE);
+ gtk_widget_show (mi);
+ g_signal_connect_swapped (mi, "activate",
+ G_CALLBACK (parole_media_list_open_folder), menu);
+
+ g_object_set_data (G_OBJECT (menu), "folder", dirname);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+
+
+ mi = gtk_separator_menu_item_new ();
+ gtk_widget_show (mi);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+
+
+ }
+
+ gtk_tree_path_free (path);
+ }
+ }
+}
+
+
+static void
parole_media_list_clear_list (ParoleMediaList *list)
{
gtk_list_store_clear (GTK_LIST_STORE (list->priv->store));
@@ -845,6 +1183,24 @@ parole_media_list_clear_list (ParoleMediaList *list)
}
static void
+replace_list_activated_cb (GtkWidget *mi, ParoleConf *conf)
+{
+ g_object_set (G_OBJECT (conf),
+ "replace-playlist", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (mi)),
+ NULL);
+
+}
+
+static void
+play_opened_files_activated_cb (GtkWidget *mi, ParoleConf *conf)
+{
+ g_object_set (G_OBJECT (conf),
+ "play-opened-files", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (mi)),
+ NULL);
+
+}
+
+static void
save_list_activated_cb (GtkWidget *mi)
{
gboolean active;
@@ -855,12 +1211,123 @@ save_list_activated_cb (GtkWidget *mi)
}
static void
-parole_media_list_show_menu (ParoleMediaList *list, guint button, guint activate_time)
+repeat_activated_cb (GtkWidget *mi, ParoleConf *conf)
+{
+ g_object_set (G_OBJECT (conf),
+ "repeat", gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (mi)),
+ NULL);
+}
+
+static void
+shuffle_activated_cb (GtkWidget *mi, ParoleConf *conf)
+{
+ g_object_set (G_OBJECT (conf),
+ "shuffle", gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (mi)),
+ NULL);
+}
+
+static void
+parole_media_list_destroy_menu (GtkWidget *menu)
+{
+ gchar *dirname;
+
+ dirname = (gchar *) g_object_get_data (G_OBJECT (menu), "folder");
+
+ if (dirname)
+ {
+ g_free (dirname);
+ }
+
+ gtk_widget_destroy (menu);
+}
+
+static void
+parole_media_list_show_menu (ParoleMediaList *list, GdkEventButton *ev)
{
GtkWidget *menu, *mi;
+ gboolean val;
+ guint button = ev->button;
+ guint activate_time = ev->time;
menu = gtk_menu_new ();
+
+ parole_media_list_add_open_containing_folder (list, menu, (gint)ev->x, (gint)ev->y);
+
+ /**
+ * Repeat playing.
+ **/
+ g_object_get (G_OBJECT (list->priv->conf),
+ "repeat", &val,
+ NULL);
+
+ mi = gtk_check_menu_item_new_with_label (_("Repeat"));
+ gtk_widget_set_sensitive (mi, TRUE);
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi), val);
+ g_signal_connect (mi, "activate",
+ G_CALLBACK (repeat_activated_cb), list->priv->conf);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+ gtk_widget_show (mi);
+
+ /**
+ * Shuffle playing.
+ **/
+ g_object_get (G_OBJECT (list->priv->conf),
+ "shuffle", &val,
+ NULL);
+
+ mi = gtk_check_menu_item_new_with_label (_("Shuffle"));
+ gtk_widget_set_sensitive (mi, TRUE);
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi), val);
+ g_signal_connect (mi, "activate",
+ G_CALLBACK (shuffle_activated_cb), list->priv->conf);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+ gtk_widget_show (mi);
+
+ /**
+ * Separator
+ **/
+ mi = gtk_separator_menu_item_new ();
+ gtk_widget_show (mi);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+
+ /**
+ * replace playlist
+ **/
+ g_object_get (G_OBJECT (list->priv->conf),
+ "replace-playlist", &val,
+ NULL);
+
+ mi = gtk_check_menu_item_new_with_label (_("Replace playlist when opening files"));
+ gtk_widget_set_sensitive (mi, TRUE);
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi), val);
+ g_signal_connect (mi, "activate",
+ G_CALLBACK (replace_list_activated_cb), list->priv->conf);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+ gtk_widget_show (mi);
+
+ /**
+ * Play when files are open.
+ **/
+
+ g_object_get (G_OBJECT (list->priv->conf),
+ "play-opened-files", &val,
+ NULL);
+ mi = gtk_check_menu_item_new_with_label (_("Play opened files"));
+ gtk_widget_set_sensitive (mi, TRUE);
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi), val);
+ g_signal_connect (mi, "activate",
+ G_CALLBACK (play_opened_files_activated_cb), list->priv->conf);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+ gtk_widget_show (mi);
+
+ /**
+ * Remember media list entries
+ **/
mi = gtk_check_menu_item_new_with_label (_("Remember playlist"));
gtk_widget_set_sensitive (mi, TRUE);
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi),
@@ -874,6 +1341,9 @@ parole_media_list_show_menu (ParoleMediaList *list, guint button, guint activate
gtk_widget_show (mi);
+ /**
+ * Separator
+ **/
mi = gtk_separator_menu_item_new ();
gtk_widget_show (mi);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
@@ -889,7 +1359,7 @@ parole_media_list_show_menu (ParoleMediaList *list, guint button, guint activate
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
g_signal_connect_swapped (menu, "selection-done",
- G_CALLBACK (gtk_widget_destroy), menu);
+ G_CALLBACK (parole_media_list_destroy_menu), menu);
gtk_menu_popup (GTK_MENU (menu),
NULL, NULL,
@@ -902,7 +1372,7 @@ parole_media_list_button_release_event (GtkWidget *widget, GdkEventButton *ev, P
{
if ( ev->button == 3 )
{
- parole_media_list_show_menu (list, ev->button, ev->time);
+ parole_media_list_show_menu (list, ev);
return TRUE;
}
@@ -992,7 +1462,7 @@ parole_media_list_setup_view (ParoleMediaList *list)
GtkTreeViewColumn *col;
GtkCellRenderer *renderer;
- list_store = gtk_list_store_new (COL_NUMBERS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_OBJECT);
+ list_store = gtk_list_store_new (COL_NUMBERS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_OBJECT);
gtk_tree_view_set_model (GTK_TREE_VIEW (list->priv->view), GTK_TREE_MODEL(list_store));
@@ -1004,6 +1474,11 @@ parole_media_list_setup_view (ParoleMediaList *list)
gtk_tree_view_column_pack_start(col, renderer, FALSE);
gtk_tree_view_column_set_attributes(col, renderer, "pixbuf", PIXBUF_COL, NULL);
+
+ /**
+ * Name col
+ *
+ **/
renderer = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start (col, renderer, TRUE);
@@ -1012,6 +1487,17 @@ parole_media_list_setup_view (ParoleMediaList *list)
"ellipsize", PANGO_ELLIPSIZE_END,
NULL);
+
+ /**
+ * Media length
+ *
+ **/
+ renderer = gtk_cell_renderer_text_new();
+
+ gtk_tree_view_column_pack_start (col, renderer, FALSE);
+ gtk_tree_view_column_set_attributes (col, renderer, "text", LENGTH_COL, NULL);
+
+
gtk_tree_view_append_column (GTK_TREE_VIEW (list->priv->view), col);
gtk_tree_view_column_set_title (col, _("Media list"));
@@ -1037,6 +1523,8 @@ parole_media_list_init (ParoleMediaList *list)
list->priv->bus = parole_g_session_bus_get ();
+ list->priv->conf = parole_conf_new ();
+
builder = parole_builder_new_from_string (playlist_ui, playlist_ui_length);
list->priv->view = GTK_WIDGET (gtk_builder_get_object (builder, "media-list"));
@@ -1082,8 +1570,13 @@ parole_media_list_get (void)
void parole_media_list_load (ParoleMediaList *list)
{
gboolean load_saved_list;
+ gboolean play;
GSList *fileslist = NULL;
+ g_object_get (G_OBJECT (list->priv->conf),
+ "play-opened-files", &play,
+ NULL);
+
load_saved_list = parole_rc_read_entry_bool ("SAVE_LIST_ON_EXIT", PAROLE_RC_GROUP_GENERAL, FALSE);
if ( load_saved_list )
@@ -1098,7 +1591,7 @@ void parole_media_list_load (ParoleMediaList *list)
fileslist = parole_pl_parser_parse_from_file_by_extension (playlist_file);
g_free (playlist_file);
- parole_media_list_files_opened_cb (NULL, FALSE, FALSE, fileslist, list);
+ parole_media_list_files_open (list, fileslist, play);
g_slist_free (fileslist);
}
}
@@ -1120,7 +1613,7 @@ parole_media_list_add_by_path (ParoleMediaList *list, const gchar *path, gboolea
parole_get_media_files (filter, path, TRUE, &files_list);
- parole_media_list_files_open (list, files_list, FALSE, emit);
+ parole_media_list_files_open (list, files_list, emit);
len = g_slist_length (files_list);
ret = len == 0 ? FALSE : TRUE;
@@ -1150,7 +1643,7 @@ GtkTreeRowReference *parole_media_list_get_next_row (ParoleMediaList *list,
if ( gtk_tree_model_get_iter (GTK_TREE_MODEL (list->priv->store), &iter, path))
{
next = gtk_tree_row_reference_new (GTK_TREE_MODEL (list->priv->store), path);
- parole_media_list_select_path (list, path);
+ //parole_media_list_select_path (list, path);
}
else if ( repeat ) /* Repeat playing ?*/
{
@@ -1184,7 +1677,7 @@ GtkTreeRowReference *parole_media_list_get_prev_row (ParoleMediaList *list,
if ( gtk_tree_model_get_iter (GTK_TREE_MODEL (list->priv->store), &iter, path))
{
prev = gtk_tree_row_reference_new (GTK_TREE_MODEL (list->priv->store), path);
- parole_media_list_select_path (list, path);
+ //parole_media_list_select_path (list, path);
}
else
prev = row;
@@ -1217,7 +1710,7 @@ GtkTreeRowReference *parole_media_list_get_row_random (ParoleMediaList *list)
if ( gtk_tree_model_get_iter (GTK_TREE_MODEL (list->priv->store), &iter, path))
{
row = gtk_tree_row_reference_new (GTK_TREE_MODEL (list->priv->store), path);
- parole_media_list_select_path (list, path);
+ //parole_media_list_select_path (list, path);
}
gtk_tree_path_free (path);
@@ -1237,6 +1730,13 @@ gboolean parole_media_list_is_empty (ParoleMediaList *list)
return !gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list->priv->store), &iter);
}
+/**
+ * parole_media_list_get_first_row:
+ * @list: a #ParoleMediaList
+ *
+ *
+ * Returns: a #GtkTreeRowReference of the first row in the media list.
+ **/
GtkTreeRowReference *parole_media_list_get_first_row (ParoleMediaList *list)
{
GtkTreeRowReference *row = NULL;
@@ -1250,11 +1750,30 @@ GtkTreeRowReference *parole_media_list_get_first_row (ParoleMediaList *list)
return row;
}
+/**
+ * parole_media_list_get_selected_row:
+ * @list: a #ParoleMediaList
+ *
+ *
+ * Returns: a #GtkTreeRowReference of the selected row.
+ **/
GtkTreeRowReference *parole_media_list_get_selected_row (ParoleMediaList *list)
{
return parole_media_list_get_first_selected_row (list);
}
+void parole_media_list_select_row (ParoleMediaList *list, GtkTreeRowReference *row)
+{
+ GtkTreePath *path;
+
+ if ( gtk_tree_row_reference_valid (row) )
+ {
+ path = gtk_tree_row_reference_get_path (row);
+ parole_media_list_select_path (list, path);
+ gtk_tree_path_free (path);
+ }
+}
+
void parole_media_list_set_row_pixbuf (ParoleMediaList *list, GtkTreeRowReference *row, GdkPixbuf *pix)
{
GtkTreeIter iter;
@@ -1289,6 +1808,23 @@ void parole_media_list_set_row_name (ParoleMediaList *list, GtkTreeRowReference
}
}
+void parole_media_list_set_row_length (ParoleMediaList *list, GtkTreeRowReference *row, const gchar *len)
+{
+ GtkTreeIter iter;
+ GtkTreePath *path;
+
+ if ( gtk_tree_row_reference_valid (row) )
+ {
+ path = gtk_tree_row_reference_get_path (row);
+
+ if ( gtk_tree_model_get_iter (GTK_TREE_MODEL (list->priv->store), &iter, path) )
+ {
+ gtk_list_store_set (list->priv->store, &iter, LENGTH_COL, len, -1);
+ }
+ gtk_tree_path_free (path);
+ }
+}
+
void parole_media_list_open (ParoleMediaList *list)
{
parole_media_list_open_internal (list);
@@ -1306,9 +1842,9 @@ gboolean parole_media_list_add_files (ParoleMediaList *list, gchar **filenames)
for ( i = 0; filenames && filenames[i] != NULL; i++)
{
- /**
- * File on disk
- **/
+ /*
+ * File on disk?
+ */
if ( g_file_test (filenames[i], G_FILE_TEST_EXISTS ) )
{
added += parole_media_list_add_by_path (list, filenames[i], i == 0 ? TRUE : FALSE);
@@ -1323,7 +1859,7 @@ gboolean parole_media_list_add_files (ParoleMediaList *list, gchar **filenames)
}
}
- return added == i;
+ return added > 0;
}
void parole_media_list_save_list (ParoleMediaList *list)
diff --git a/src/parole-medialist.h b/src/parole-medialist.h
index 821dd11..a548f43 100644
--- a/src/parole-medialist.h
+++ b/src/parole-medialist.h
@@ -33,6 +33,7 @@ enum
{
PIXBUF_COL,
NAME_COL,
+ LENGTH_COL,
DATA_COL,
COL_NUMBERS
};
@@ -81,6 +82,9 @@ GtkTreeRowReference *parole_media_list_get_first_row (ParoleMedia
GtkTreeRowReference *parole_media_list_get_selected_row (ParoleMediaList *list);
+void parole_media_list_select_row (ParoleMediaList *list,
+ GtkTreeRowReference *row);
+
GtkTreeRowReference *parole_media_list_get_next_row (ParoleMediaList *list,
GtkTreeRowReference *row,
gboolean repeat);
@@ -93,11 +97,16 @@ GtkTreeRowReference *parole_media_list_get_row_random (ParoleMediaList *list)
void parole_media_list_set_row_pixbuf (ParoleMediaList *list,
GtkTreeRowReference *row,
GdkPixbuf *pix);
-
+
void parole_media_list_set_row_name (ParoleMediaList *list,
GtkTreeRowReference *row,
const gchar *name);
+
+void parole_media_list_set_row_length (ParoleMediaList *list,
+ GtkTreeRowReference *row,
+ const gchar *length);
+
void parole_media_list_open (ParoleMediaList *list);
void parole_media_list_open_location (ParoleMediaList *list);
diff --git a/src/parole-open-location.c b/src/parole-open-location.c
index 4b0d955..0d0af5d 100644
--- a/src/parole-open-location.c
+++ b/src/parole-open-location.c
@@ -30,15 +30,26 @@
#include "parole-open-location.h"
#include "parole-rc-utils.h"
+#include "parole-builder.h"
+
+#include "interfaces/open-location_ui.h"
static void parole_open_location_finalize (GObject *object);
-#define PAROLE_OPEN_LOCATION_GET_PRIVATE(o) \
-(G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_OPEN_LOCATION, ParoleOpenLocationPrivate))
+struct ParoleOpenLocation
+{
+ GObject parent;
+
+
+ GtkWidget *entry;
+};
-struct ParoleOpenLocationPrivate
+struct ParoleOpenLocationClass
{
- GtkWidget *entry;
+ GObjectClass parent_class;
+
+ void (*location_opened) (ParoleOpenLocation *self,
+ const gchar *address);
};
enum
@@ -55,7 +66,7 @@ enum
static guint signals [LAST_SIGNAL] = { 0 };
-G_DEFINE_TYPE (ParoleOpenLocation, parole_open_location, GTK_TYPE_DIALOG)
+G_DEFINE_TYPE (ParoleOpenLocation, parole_open_location, G_TYPE_OBJECT)
static void
parole_open_location_response_cb (GtkDialog *dialog, gint response_id, ParoleOpenLocation *self)
@@ -64,19 +75,19 @@ parole_open_location_response_cb (GtkDialog *dialog, gint response_id, ParoleOpe
if ( response_id == GTK_RESPONSE_OK )
{
- location = gtk_entry_get_text (GTK_ENTRY (self->priv->entry));
+ location = gtk_entry_get_text (GTK_ENTRY (self->entry));
if ( !location || strlen (location) == 0)
goto out;
TRACE ("Location %s", location);
- gtk_widget_hide (GTK_WIDGET (self));
+ gtk_widget_hide (GTK_WIDGET (dialog));
g_signal_emit (G_OBJECT (self), signals [LOCATION_OPENED], 0, location);
}
out:
- gtk_widget_destroy (GTK_WIDGET (self));
+ gtk_widget_destroy (GTK_WIDGET (dialog));
}
static GtkTreeModel *
@@ -134,14 +145,11 @@ parole_open_location_class_init (ParoleOpenLocationClass *klass)
NULL, NULL,
g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE, 1, G_TYPE_STRING);
-
- g_type_class_add_private (klass, sizeof (ParoleOpenLocationPrivate));
}
static void
parole_open_location_init (ParoleOpenLocation *self)
{
- self->priv = PAROLE_OPEN_LOCATION_GET_PRIVATE (self);
}
static void
@@ -161,37 +169,32 @@ parole_open_location_clear_history (GtkTreeModel *model)
gtk_list_store_clear (GTK_LIST_STORE (model));
}
-GtkWidget *parole_open_location (GtkWidget *parent)
+ParoleOpenLocation *parole_open_location (GtkWidget *parent)
{
+ ParoleOpenLocation *self;
+ GtkWidget *dialog;
GtkEntryCompletion *cmpl;
GtkTreeModel *model;
- GtkWidget *label;
- GtkWidget *clear;
- GtkWidget *img;
- GtkWidget *vbox;
- GtkWidget *hbox;
-
- ParoleOpenLocation *self = NULL;
+ GtkBuilder *builder;
self = g_object_new (PAROLE_TYPE_OPEN_LOCATION, NULL);
- if ( parent )
- gtk_window_set_transient_for (GTK_WINDOW (self), GTK_WINDOW (parent));
+ builder = parole_builder_new_from_string (open_location_ui, open_location_ui_length);
- gtk_window_set_title (GTK_WINDOW (self), _("Open location..."));
- gtk_window_set_default_size (GTK_WINDOW (self), 360, 40);
- gtk_window_set_position (GTK_WINDOW (self), GTK_WIN_POS_CENTER_ON_PARENT);
+ dialog = GTK_WIDGET (gtk_builder_get_object (builder, "open-location"));
- label = gtk_label_new (NULL);
- gtk_label_set_markup (GTK_LABEL (label), _("<b>Open location of media file or live stream:</b>"));
+ if ( parent )
+ gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent));
+
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ON_PARENT);
- self->priv->entry = gtk_entry_new ();
+ self->entry = GTK_WIDGET (gtk_builder_get_object (builder, "entry"));
model = parole_open_location_get_completion_model ();
- gtk_entry_set_activates_default (GTK_ENTRY (self->priv->entry), TRUE);
+ gtk_entry_set_activates_default (GTK_ENTRY (self->entry), TRUE);
cmpl = gtk_entry_completion_new ();
- gtk_entry_set_completion (GTK_ENTRY (self->priv->entry), cmpl);
+ gtk_entry_set_completion (GTK_ENTRY (self->entry), cmpl);
gtk_entry_completion_set_model (cmpl, model);
gtk_entry_completion_set_text_column (cmpl, 0);
@@ -199,46 +202,20 @@ GtkWidget *parole_open_location (GtkWidget *parent)
(GtkEntryCompletionMatchFunc) parole_open_location_match,
model,
NULL);
-
- img = gtk_image_new_from_stock (GTK_STOCK_CLEAR, GTK_ICON_SIZE_BUTTON);
-
- clear = gtk_button_new_with_label (_("Clear history"));
- g_signal_connect_swapped (clear, "clicked",
- G_CALLBACK (parole_open_location_clear_history), model);
-
- g_object_set (G_OBJECT (clear),
- "image", img,
- NULL);
-
- vbox = gtk_vbox_new (TRUE, 4);
- hbox = gtk_hbox_new (FALSE, 8);
-
- gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (hbox), self->priv->entry, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (hbox), clear, FALSE, FALSE, 0);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (self)->vbox),
- vbox,
- TRUE,
- TRUE,
- 0);
-
- gtk_dialog_add_buttons (GTK_DIALOG (self),
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OPEN, GTK_RESPONSE_OK,
- NULL);
-
- gtk_dialog_set_default_response (GTK_DIALOG (self), GTK_RESPONSE_OK);
+ g_signal_connect_swapped (gtk_builder_get_object (builder, "clear-history"), "clicked",
+ G_CALLBACK (parole_open_location_clear_history), model);
- g_signal_connect (self, "delete-event",
- G_CALLBACK (gtk_widget_destroy), self);
+ g_signal_connect (dialog, "delete-event",
+ G_CALLBACK (gtk_widget_destroy), NULL);
- g_signal_connect (self, "response",
+ g_signal_connect (dialog, "response",
G_CALLBACK (parole_open_location_response_cb), self);
-
- gtk_widget_show_all (GTK_WIDGET (self));
- return GTK_WIDGET (self);
+ gtk_widget_show_all (dialog);
+ g_object_unref (builder);
+
+ return self;
}
diff --git a/src/parole-open-location.h b/src/parole-open-location.h
index 15ee1b1..2c25994 100644
--- a/src/parole-open-location.h
+++ b/src/parole-open-location.h
@@ -30,27 +30,12 @@ G_BEGIN_DECLS
#define PAROLE_OPEN_LOCATION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_OPEN_LOCATION, ParoleOpenLocation))
#define PAROLE_IS_OPEN_LOCATION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_OPEN_LOCATION))
-typedef struct ParoleOpenLocationPrivate ParoleOpenLocationPrivate;
-
-typedef struct
-{
- GtkDialog parent;
- ParoleOpenLocationPrivate *priv;
-
-} ParoleOpenLocation;
-
-typedef struct
-{
- GtkDialogClass parent_class;
-
- void (*location_opened) (ParoleOpenLocation *self,
- const gchar *address);
-
-} ParoleOpenLocationClass;
+typedef struct ParoleOpenLocation ParoleOpenLocation;
+typedef struct ParoleOpenLocationClass ParoleOpenLocationClass;
GType parole_open_location_get_type (void) G_GNUC_CONST;
-GtkWidget *parole_open_location (GtkWidget *parent);
+ParoleOpenLocation *parole_open_location (GtkWidget *parent);
G_END_DECLS
diff --git a/src/parole-utils.c b/src/parole-utils.c
index b0cb8c8..96b21ec 100644
--- a/src/parole-utils.c
+++ b/src/parole-utils.c
@@ -38,6 +38,10 @@
#include <linux/cdrom.h>
#endif
+#ifdef HAVE_TAGLIBC
+#include <taglib/tag_c.h>
+#endif
+
#include <libxfce4util/libxfce4util.h>
#include <parole/parole.h>
@@ -595,3 +599,73 @@ parole_get_uri_from_unix_device (const gchar *device)
return uri;
}
+
+/**
+ * parole_format_media_length:
+ *
+ * @total_seconds: lenght of the media file in seconds
+ *
+ * Returns : formated string for the media lenght
+ **/
+gchar *parole_format_media_length (gint total_seconds)
+{
+ gchar *timestring;
+
+ gint hours;
+ gint minutes;
+ gint seconds;
+
+ minutes = total_seconds / 60;
+ seconds = total_seconds % 60;
+ hours = minutes / 60;
+ minutes = minutes % 60;
+
+ if ( hours == 0 )
+ {
+ timestring = g_strdup_printf ("%02i:%02i", minutes, seconds);
+ }
+ else
+ {
+ timestring = g_strdup_printf ("%i:%02i:%02i", hours, minutes, seconds);
+ }
+
+ return timestring;
+}
+
+
+/**
+ * parole_taglibc_get_media_length:
+ *
+ * @ParoleFile: a ParoleFile
+ *
+ * Returns: the length of the media only if the file is a local
+ * media file.
+ **/
+gchar *parole_taglibc_get_media_length (ParoleFile *file)
+{
+ #ifdef HAVE_TAGLIBC
+
+ TagLib_File *tag_file;
+
+ if (g_str_has_prefix (parole_file_get_uri (file), "file:/"))
+ {
+ tag_file = taglib_file_new (parole_file_get_file_name (file));
+
+ if ( tag_file )
+ {
+ gint length = 0;
+ const TagLib_AudioProperties *prop = taglib_file_audioproperties (tag_file);
+
+ if (prop)
+ length = taglib_audioproperties_length (prop);
+
+ taglib_file_free (tag_file);
+
+ if (length != 0)
+ return parole_format_media_length (length);
+ }
+ }
+ #endif /* HAVE_TAGLIBC */
+
+ return NULL;
+}
diff --git a/src/parole-utils.h b/src/parole-utils.h
index d38a2ef..9726015 100644
--- a/src/parole-utils.h
+++ b/src/parole-utils.h
@@ -50,4 +50,8 @@ gchar *parole_guess_uri_from_mount (GMount *mount);
gchar *parole_get_uri_from_unix_device (const gchar *device);
+gchar *parole_format_media_length (gint total_seconds);
+
+gchar *parole_taglibc_get_media_length (ParoleFile *file);
+
#endif /* __PAROLE_UTILS_ */
More information about the Xfce4-commits
mailing list