[Goodies-commits] r7735 - in parole/trunk: . common data/interfaces docs docs/plugin-api parole plugins plugins/properties po
Ali Abdallah
aliov at xfce.org
Thu Jul 16 17:03:07 CEST 2009
Author: aliov
Date: 2009-07-16 15:03:06 +0000 (Thu, 16 Jul 2009)
New Revision: 7735
Added:
parole/trunk/common/
parole/trunk/common/Makefile.am
parole/trunk/common/parole-about.c
parole/trunk/common/parole-about.h
parole/trunk/common/parole-builder.c
parole/trunk/common/parole-builder.h
parole/trunk/docs/
parole/trunk/docs/Makefile.am
parole/trunk/docs/plugin-api/
parole/trunk/docs/plugin-api/Makefile.am
parole/trunk/docs/plugin-api/Parole-Plugins-docs.sgml
parole/trunk/docs/plugin-api/Parole-Plugins-overrides.txt
parole/trunk/docs/plugin-api/Parole-Plugins-sections.txt
parole/trunk/docs/plugin-api/Parole-Plugins.types
parole/trunk/docs/plugin-api/version.xml.in
parole/trunk/parole/
parole/trunk/parole/Makefile.am
parole/trunk/parole/gmarshal.list
parole/trunk/parole/main.c
parole/trunk/parole/org.parole.media.list.xml
parole/trunk/parole/parole-conf-dialog.c
parole/trunk/parole/parole-conf-dialog.h
parole/trunk/parole/parole-conf.c
parole/trunk/parole/parole-conf.h
parole/trunk/parole/parole-dbus.c
parole/trunk/parole/parole-dbus.h
parole/trunk/parole/parole-debug.c
parole/trunk/parole/parole-debug.h
parole/trunk/parole/parole-filters.c
parole/trunk/parole/parole-filters.h
parole/trunk/parole/parole-gst.c
parole/trunk/parole/parole-gst.h
parole/trunk/parole/parole-mediachooser.c
parole/trunk/parole/parole-mediachooser.h
parole/trunk/parole/parole-mediafile.c
parole/trunk/parole/parole-mediafile.h
parole/trunk/parole/parole-medialist.c
parole/trunk/parole/parole-medialist.h
parole/trunk/parole/parole-module.c
parole/trunk/parole/parole-module.h
parole/trunk/parole/parole-player.c
parole/trunk/parole/parole-player.h
parole/trunk/parole/parole-plugin.c
parole/trunk/parole/parole-plugin.h
parole/trunk/parole/parole-plugins-manager.c
parole/trunk/parole/parole-plugins-manager.h
parole/trunk/parole/parole-rc-utils.c
parole/trunk/parole/parole-rc-utils.h
parole/trunk/parole/parole-screensaver.c
parole/trunk/parole/parole-screensaver.h
parole/trunk/parole/parole-sidebar.c
parole/trunk/parole/parole-sidebar.h
parole/trunk/parole/parole-statusbar.c
parole/trunk/parole/parole-statusbar.h
parole/trunk/parole/parole-stream.c
parole/trunk/parole/parole-stream.h
parole/trunk/parole/parole-utils.c
parole/trunk/parole/parole-utils.h
parole/trunk/parole/parole-vis.c
parole/trunk/parole/parole-vis.h
parole/trunk/parole/parole.h
parole/trunk/plugins/
parole/trunk/plugins/Makefile.am
parole/trunk/plugins/properties/
parole/trunk/plugins/properties/Makefile.am
parole/trunk/plugins/properties/stream-properties.c
Removed:
parole/trunk/src/
Modified:
parole/trunk/ChangeLog
parole/trunk/Makefile.am
parole/trunk/README
parole/trunk/TODO
parole/trunk/configure.ac.in
parole/trunk/data/interfaces/Makefile.am
parole/trunk/data/interfaces/parole.ui
parole/trunk/po/POTFILES.in
parole/trunk/po/parole-media-player.pot
Log:
* plugins/properties: media properties plugin (Read only,
needs to work the writing part with Taglib).
* No need to install the interface files anymore.
* Rename src dir to parole.
* Gtk doc for plugin api (not yet complete).
* parole/parole-player.c stop gst when the stream finishes
and no remaining media left in the list.
* parole/parole-player.c rename the media file shown in the media list
when we get a tag message from gst.
* parole/parole-stream.c Handle tag messages.
* parole/parole-module.{c,h} added a GTypeModule subclass
* parole/parole-mediafile.c expose GObject properties.
to handle plugins.
* put some code in the common dir.
* update POTFILES.in+README+TODO.
Modified: parole/trunk/ChangeLog
===================================================================
--- parole/trunk/ChangeLog 2009-07-16 15:03:04 UTC (rev 7734)
+++ parole/trunk/ChangeLog 2009-07-16 15:03:06 UTC (rev 7735)
@@ -1,3 +1,21 @@
+2009-07-16: Ali aliov at xfce.org
+ * Parole now has a simple plugin interface. (not yet complete).
+ * plugins/properties: media properties plugin (Read only,
+ needs to work the writing part with Taglib).
+ * No need to install the interface files anymore.
+ * Rename src dir to parole.
+ * Gtk doc for plugin api (not yet complete).
+ * parole/parole-player.c stop gst when the stream finishes
+ and no remaining media left in the list.
+ * parole/parole-player.c rename the media file shown in the media list
+ when we get a tag message from gst.
+ * parole/parole-stream.c Handle tag messages.
+ * parole/parole-module.{c,h} added a GTypeModule subclass
+ * parole/parole-mediafile.c expose GObject properties.
+ to handle plugins.
+ * put some code in the common dir.
+ * update POTFILES.in+README+TODO.
+
2009-07-08 9:00 Ali aliov at xfce.org
* data/interfaces/playlist.ui disable media list horizontal scrolling.
* po/POTFILES.in fix missing strings in the interface files.
Modified: parole/trunk/Makefile.am
===================================================================
--- parole/trunk/Makefile.am 2009-07-16 15:03:04 UTC (rev 7734)
+++ parole/trunk/Makefile.am 2009-07-16 15:03:06 UTC (rev 7735)
@@ -1,8 +1,12 @@
SUBDIRS = \
- data \
- src \
- po
+ data \
+ common \
+ parole \
+ plugins \
+ docs \
+ po
+
EXTRA_DIST = \
intltool-extract.in \
intltool-merge.in \
Modified: parole/trunk/README
===================================================================
--- parole/trunk/README 2009-07-16 15:03:04 UTC (rev 7734)
+++ parole/trunk/README 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,26 @@
+What is it?
+===========
+
+Parole is a modern simple media player based on the GStreamer framework and written to fit well
+in the Xfce desktop. Parole features playback of local media files, DVD/CD and live streams.
+Parole is extensible via plugins, for a complete how to write a plugin for Parole see
+the Plugins API documentation+the plugins directory which contains some usefull examples.
+
+Required packages
+=================
+Parole depends on the following packages:
+
+ - Gtk 2.16 or above.
+ - Glib 2.16 or above.
+ - Gio 2.16 or above.
+ - DBus 0.60 or above.
+ - DBus glib 0.70 or above.
+ - libxfcegui4 4.6.0 or above.
+ - libxfce4util 4.6.0 or above
+
+How to report bugs?
+===================
+
+Bugs should be reported to the Xfce bug tracking system
+(http://bugzilla.xfce.org, product Parole). You will need to
+create an account for yourself.
Modified: parole/trunk/TODO
===================================================================
--- parole/trunk/TODO 2009-07-16 15:03:04 UTC (rev 7734)
+++ parole/trunk/TODO 2009-07-16 15:03:06 UTC (rev 7735)
@@ -1 +1,16 @@
+=== Media player ===
+* Currenlty the media player doesn't play DVD/CD.
+* Complete the shortcut keys.
+* Handle playlist(s), save/load.
+* Better statusbar information.
+* Encoding support for subtitles.
+* Configure plugins dialog to load/unload plugins.
+* Generate the data from the interfaces files with
+ exo-csource to avoid having to install them.
+* ...
+=== Plugins ===
+* Support for Taglib in the media properties plugin.
+* Write a youtube plugin.
+* Subtitle downloader.
+* ...?
Added: parole/trunk/common/Makefile.am
===================================================================
--- parole/trunk/common/Makefile.am (rev 0)
+++ parole/trunk/common/Makefile.am 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,13 @@
+noinst_LTLIBRARIES = \
+ libparolecommon.la
+
+libparolecommon_la_SOURCES = \
+ parole-builder.c \
+ parole-builder.h \
+ parole-about.c \
+ parole-about.h
+
+libparolecommon_la_CFLAGS = \
+ -I$(top_srcdir)/data \
+ $(GTK_CFLAGS) \
+ $(LIBXFCE4UTIL_CFLAGS)
Added: parole/trunk/common/parole-about.c
===================================================================
--- parole/trunk/common/parole-about.c (rev 0)
+++ parole/trunk/common/parole-about.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,81 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libxfce4util/libxfce4util.h>
+
+#include "parole-about.h"
+
+static void
+parole_link_browser (GtkAboutDialog *about, const gchar *link, gpointer data)
+{
+ gchar *cmd = g_strdup_printf ("%s %s","xfbrowser4", link);
+ g_spawn_command_line_async (cmd, NULL);
+ g_free (cmd);
+
+}
+
+static void
+parole_link_mailto (GtkAboutDialog *about, const gchar *link, gpointer data)
+{
+ gchar *cmd = g_strdup_printf( "%s %s", "xdg-email", link);
+
+ g_spawn_command_line_async (cmd, NULL);
+
+ g_free (cmd);
+}
+
+void parole_about (const gchar *package)
+{
+ const gchar* authors[3] =
+ {
+ "Ali Abdallah <aliov at xfce.org>",
+ NULL
+ };
+
+ static const gchar *documenters[] =
+ {
+ "Ali Abdallah <aliov at xfce.org>",
+ NULL,
+ };
+
+
+ gtk_about_dialog_set_url_hook (parole_link_browser, NULL, NULL);
+ gtk_about_dialog_set_email_hook (parole_link_mailto, NULL, NULL);
+
+ gtk_show_about_dialog (NULL,
+ "authors", authors,
+ "copyright", "Copyright \302\251 2009 Ali Abdallah",
+ "destroy-with-parent", TRUE,
+ "documenters", documenters,
+ "license", XFCE_LICENSE_GPL,
+ "name", package,
+ "translator-credits", _("translator-credits"),
+ "version", PACKAGE_VERSION,
+ "website", "http://goodies.xfce.org",
+ NULL);
+}
Added: parole/trunk/common/parole-about.h
===================================================================
--- parole/trunk/common/parole-about.h (rev 0)
+++ parole/trunk/common/parole-about.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,29 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PAROLE_ABOUT_H
+#define __PAROLE_ABOUT_H
+
+#include <gtk/gtk.h>
+
+void parole_about (const gchar *package);
+
+
+#endif /* __PAROLE_ABOUT_H */
Added: parole/trunk/common/parole-builder.c
===================================================================
--- parole/trunk/common/parole-builder.c (rev 0)
+++ parole/trunk/common/parole-builder.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,86 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "interfaces/parole_ui.h"
+#include "parole-builder.h"
+
+GtkBuilder *
+parole_builder_get_main_interface (void)
+{
+ static gpointer parole_builder_object = NULL;
+
+ if ( G_LIKELY (parole_builder_object != NULL) )
+ {
+ g_object_ref (parole_builder_object);
+ }
+ else
+ {
+ parole_builder_object = parole_builder_new_from_string (parole_ui, parole_ui_length);
+ g_object_add_weak_pointer (parole_builder_object, &parole_builder_object);
+ }
+
+ return GTK_BUILDER (parole_builder_object);
+}
+
+GtkBuilder *parole_builder_new_from_file (const gchar *file)
+{
+ GtkBuilder *builder;
+ GError *error = NULL;
+
+ builder = gtk_builder_new ();
+
+ gtk_builder_add_from_file (GTK_BUILDER (builder),
+ file,
+ &error);
+
+ if ( error )
+ {
+ g_critical ("%s", error->message);
+ g_error_free (error);
+ }
+
+ return builder;
+}
+
+GtkBuilder *parole_builder_new_from_string (const gchar *ui, gsize length)
+{
+ GError *error = NULL;
+ GtkBuilder *builder;
+
+ builder = gtk_builder_new ();
+
+ gtk_builder_add_from_string (builder, ui, length, &error);
+
+ if ( error )
+ {
+ g_critical ("%s", error->message);
+ g_error_free (error);
+ }
+
+ return builder;
+}
Added: parole/trunk/common/parole-builder.h
===================================================================
--- parole/trunk/common/parole-builder.h (rev 0)
+++ parole/trunk/common/parole-builder.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,38 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PAROLE_BUILDER_H
+#define __PAROLE_BUILDER_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+GtkBuilder *parole_builder_get_main_interface (void);
+
+GtkBuilder *parole_builder_new_from_file (const gchar *file);
+
+GtkBuilder *parole_builder_new_from_string (const gchar *ui,
+ gsize length);
+
+G_END_DECLS
+
+#endif /* __PAROLE_BUILDER_H */
Modified: parole/trunk/configure.ac.in
===================================================================
--- parole/trunk/configure.ac.in 2009-07-16 15:03:04 UTC (rev 7734)
+++ parole/trunk/configure.ac.in 2009-07-16 15:03:06 UTC (rev 7735)
@@ -1,4 +1,6 @@
m4_define([intltool_minimum_version], [0.31])
+m4_define([parole_verinfo], [0:1:0])
+m4_define([parole_version_api], [0])
m4_define([parole_version_major], [0])
m4_define([parole_version_minor], [1])
m4_define([parole_version_micro], [0])
@@ -35,6 +37,20 @@
AC_DISABLE_STATIC
AC_PROG_LIBTOOL
+# ===================================================== #
+# Version information #
+# ===================================================== #
+PAROLE_VERINFO=parole_verinfo()
+PAROLE_VERSION_API=parole_version_api()
+PAROLE_VERSION_MAJOR=parole_version_major()
+PAROLE_VERSION_MINOR=parole_version_minor()
+PAROLE_VERSION_MICRO=parole_version_micro()
+AC_SUBST([PAROLE_VERINFO])
+AC_SUBST([PAROLE_VERSION_API])
+AC_SUBST([PAROLE_VERSION_MAJOR])
+AC_SUBST([PAROLE_VERSION_MINOR])
+AC_SUBST([PAROLE_VERSION_MICRO])
+
# ==================================================== #
# Check for headers needed for standard interfaces #
# ==================================================== #
@@ -92,28 +108,40 @@
# Taken from Gnome system tools
#=======================================================#
-# Pixmaps and interface files #
+# Pixmaps files #
#=======================================================#
if test "x${prefix}" = "xNONE"; then
AC_DEFINE_UNQUOTED(PIXMAPS_DIR, "${ac_default_prefix}/${DATADIRNAME}/${PACKAGE}/pixmaps", [pixmaps directory])
pixmapsdir="${ac_default_prefix}/${DATADIRNAME}/${PACKAGE}/pixmaps"
- AC_DEFINE_UNQUOTED(INTERFACES_DIR, "${ac_default_prefix}/${DATADIRNAME}/${PACKAGE}/ui", [path where UI files will be installed])
- interfacesdir="${ac_default_prefix}/${DATADIRNAME}/${PACKAGE}/ui"
else
AC_DEFINE_UNQUOTED(PIXMAPS_DIR, "${prefix}/${DATADIRNAME}/${PACKAGE}/pixmaps", [pixmaps directory])
pixmapsdir="${prefix}/${DATADIRNAME}/${PACKAGE}/pixmaps"
- AC_DEFINE_UNQUOTED(INTERFACES_DIR, "${prefix}/${DATADIRNAME}/${PACKAGE}/ui", [path where UI files will be installed])
- interfacesdir="${prefix}/${DATADIRNAME}/${PACKAGE}/ui"
fi
AC_SUBST(pixmapsdir)
-AC_SUBST(interfacesdir)
#=======================================================#
+# Check plugins to build #
+#=======================================================#
+
+# Stream Properties plugin.
+#--------------------------
+AC_ARG_ENABLE([properties-plugin], AC_HELP_STRING([--disable-properties-plugin], [Don't build parole stream properties plugin]),
+ [ac_properties_plugin=$enableval], [ac_properties_plugin=yes])
+AC_MSG_CHECKING([whether to build the Parole stream properties plugin])
+AM_CONDITIONAL([PAROLE_PROPERTIES_PLUGIN], [test x"$ac_properties_plugin" = x"yes"])
+AC_MSG_RESULT([$ac_properties_plugin])
+
+#=======================================================#
# Check for debugging support #
#=======================================================#
XDT_FEATURE_DEBUG
+#=======================================================#
+# Check for Gtk doc #
+#=======================================================#
+GTK_DOC_CHECK(1.9)
+
AC_OUTPUT([
Makefile
data/Makefile
@@ -122,20 +150,30 @@
data/icons/Makefile
data/mime/Makefile
data/desktop/Makefile
-src/Makefile
+common/Makefile
+parole/Makefile
+plugins/Makefile
+plugins/properties/Makefile
+docs/Makefile
+docs/plugin-api/version.xml
+docs/plugin-api/Makefile
po/Makefile.in
])
echo "
---------------------------------------------------
+------------------------------------------------------
Parole Media Player $VERSION
====================================
- prefix: $prefix
- interface_dir $interfacesdir
- pixmapsdir $pixmapsdir
- Notification $LIBNOTIFY_FOUND
- Debug support: $enable_debug
---------------------------------------------------
+ prefix: $prefix
+ pixmapsdir: $pixmapsdir
+ Notification: $LIBNOTIFY_FOUND
+ Debug: $enable_debug
+ Building plugin api docs: ${enable_gtk_doc}
+
+ Plugins to build:
+ -----------------
+ Stream Properties plugin: ${ac_properties_plugin}
+------------------------------------------------------
Configuration finished, type make to compile"
Modified: parole/trunk/data/interfaces/Makefile.am
===================================================================
--- parole/trunk/data/interfaces/Makefile.am 2009-07-16 15:03:04 UTC (rev 7734)
+++ parole/trunk/data/interfaces/Makefile.am 2009-07-16 15:03:06 UTC (rev 7735)
@@ -5,8 +5,31 @@
mediachooser.ui \
openlocation.ui
-interfaces_DATA = \
- $(interfaces)
+interfaces_h = \
+ $(interfaces:.ui=_ui.h)
+if MAINTAINER_MODE
+BUILT_SOURCES = $(interfaces_h)
+
+parole_ui.h: parole.ui
+ exo-csource --static --strip-comments --strip-content --name=parole_ui $< > $@
+
+parole-settings_ui.h: parole-settings.ui
+ exo-csource --static --strip-comments --strip-content --name=parole_settings_ui $< > $@
+
+playlist_ui.h: playlist.ui
+ exo-csource --static --strip-comments --strip-content --name=playlist_ui $< > $@
+
+mediachooser_ui.h: mediachooser.ui
+ exo-csource --static --strip-comments --strip-content --name=mediachooser_ui $< > $@
+
+openlocation_ui.h: openlocation.ui
+ exo-csource --static --strip-comments --strip-content --name=openlocation_ui $< > $@
+endif
+
+DISTCLEANFILES = \
+ $(interfaces_h)
+
EXTRA_DIST = \
- $(interfaces)
\ No newline at end of file
+ $(interfaces) \
+ $(interfaces_h)
\ No newline at end of file
Modified: parole/trunk/data/interfaces/parole.ui
===================================================================
--- parole/trunk/data/interfaces/parole.ui 2009-07-16 15:03:04 UTC (rev 7734)
+++ parole/trunk/data/interfaces/parole.ui 2009-07-16 15:03:06 UTC (rev 7735)
@@ -4,7 +4,7 @@
<!-- interface-naming-policy project-wide -->
<object class="GtkWindow" id="main-window">
<property name="window_position">center</property>
- <property name="default_width">720</property>
+ <property name="default_width">780</property>
<property name="default_height">440</property>
<signal name="destroy" handler="parole_player_destroy_cb"/>
<signal name="key_press_event" handler="parole_player_key_press"/>
@@ -19,7 +19,7 @@
<child>
<object class="GtkMenuItem" id="file-menu">
<property name="visible">True</property>
- <property name="label" translatable="yes">_File</property>
+ <property name="label" translatable="yes">_Media</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="menu1">
@@ -79,6 +79,13 @@
<object class="GtkMenu" id="menu4">
<property name="visible">True</property>
<child>
+ <object class="GtkMenuItem" id="plugins-menu-item">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Plugins</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
<object class="GtkImageMenuItem" id="preferences">
<property name="label">gtk-preferences</property>
<property name="visible">True</property>
@@ -123,11 +130,12 @@
<object class="GtkMenu" id="menu3">
<property name="visible">True</property>
<child>
- <object class="GtkImageMenuItem" id="imagemenuitem10">
+ <object class="GtkImageMenuItem" id="about">
<property name="label">gtk-about</property>
<property name="visible">True</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
+ <signal name="activate" handler="parole_show_about"/>
</object>
</child>
</object>
@@ -363,12 +371,11 @@
</packing>
</child>
<child>
- <object class="GtkVBox" id="list-box">
+ <object class="GtkNotebook" id="notebook-playlist">
<property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <placeholder/>
- </child>
+ <property name="can_focus">True</property>
+ <property name="scrollable">True</property>
+ <property name="enable_popup">True</property>
</object>
<packing>
<property name="resize">False</property>
@@ -392,62 +399,6 @@
</packing>
</child>
<child>
- <object class="GtkVBox" id="converter-box">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Nothing yet.</property>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child type="tab">
- <object class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Audio converter</property>
- </object>
- <packing>
- <property name="position">1</property>
- <property name="tab_fill">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="recorder-box">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkLabel" id="label4">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Nothing yet.</property>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">2</property>
- </packing>
- </child>
- <child type="tab">
- <object class="GtkLabel" id="label3">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Audio recorder</property>
- </object>
- <packing>
- <property name="position">2</property>
- <property name="tab_fill">False</property>
- </packing>
- </child>
- <child>
<object class="GtkVBox" id="albums-box">
<property name="visible">True</property>
<property name="orientation">vertical</property>
@@ -462,7 +413,7 @@
</child>
</object>
<packing>
- <property name="position">3</property>
+ <property name="position">1</property>
</packing>
</child>
<child type="tab">
@@ -471,336 +422,12 @@
<property name="label" translatable="yes">Albums</property>
</object>
<packing>
- <property name="position">3</property>
+ <property name="position">1</property>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
- <object class="GtkNotebook" id="notebook1">
- <property name="visible">True</property>
- <property name="show_tabs">False</property>
- <property name="scrollable">True</property>
- <property name="group_id">0</property>
- <child>
- <object class="GtkHBox" id="playerbox1">
- <property name="visible">True</property>
- <child>
- <object class="GtkVBox" id="vbox5">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkHBox" id="output1">
- <property name="visible">True</property>
- <child>
- <placeholder/>
- </child>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="vbox7">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="spacing">5</property>
- <child>
- <object class="GtkHScale" id="scale1">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="draw_value">False</property>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="hbox4">
- <property name="visible">True</property>
- <property name="spacing">5</property>
- <child>
- <object class="GtkButton" id="back1">
- <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">image10</property>
- <property name="relief">none</property>
- <property name="focus_on_click">False</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="stop1">
- <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">image11</property>
- <property name="relief">none</property>
- <property name="focus_on_click">False</property>
- <accelerator key="s" signal="clicked"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="play-pause1">
- <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">image12</property>
- <property name="relief">none</property>
- <property name="focus_on_click">False</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="forward1">
- <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">image13</property>
- <property name="relief">none</property>
- <property name="focus_on_click">False</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">3</property>
- </packing>
- </child>
- <child>
- <placeholder/>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkVSeparator" id="vseparator1">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="list-box1">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkScrolledWindow" id="scrolledwindow2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">automatic</property>
- <property name="vscrollbar_policy">automatic</property>
- <child>
- <object class="GtkTreeView" id="media-list1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="headers_visible">False</property>
- <property name="show_expanders">False</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="hbox5">
- <property name="visible">True</property>
- <child>
- <object class="GtkButton" id="add-media1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="image">image14</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="remove-media1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="image">image15</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="media-up1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="image">image16</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="media-down1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="image">image17</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">3</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- </object>
- </child>
- <child type="tab">
- <object class="GtkLabel" id="Player1">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Media player</property>
- </object>
- <packing>
- <property name="tab_fill">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="converter-box1">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkLabel" id="label6">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Nothing yet.</property>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child type="tab">
- <object class="GtkLabel" id="label7">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Audio converter</property>
- </object>
- <packing>
- <property name="position">1</property>
- <property name="tab_fill">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="recorder-box1">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkLabel" id="label8">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Nothing yet.</property>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">2</property>
- </packing>
- </child>
- <child type="tab">
- <object class="GtkLabel" id="label9">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Audio recorder</property>
- </object>
- <packing>
- <property name="position">2</property>
- <property name="tab_fill">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="albums-box1">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkLabel" id="label10">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Nothing yet.</property>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">3</property>
- </packing>
- </child>
- <child type="tab">
- <object class="GtkLabel" id="album1">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Albums</property>
- </object>
- <packing>
- <property name="position">3</property>
- <property name="tab_fill">False</property>
- </packing>
- </child>
- <child>
- <placeholder/>
- </child>
- <child type="tab">
- <placeholder/>
- </child>
- </object>
- <packing>
- <property name="position">4</property>
- </packing>
+ <placeholder/>
</child>
<child type="tab">
<placeholder/>
@@ -843,38 +470,6 @@
<property name="visible">True</property>
<property name="stock">gtk-network</property>
</object>
- <object class="GtkImage" id="image10">
- <property name="visible">True</property>
- <property name="stock">gtk-media-previous</property>
- </object>
- <object class="GtkImage" id="image11">
- <property name="visible">True</property>
- <property name="stock">gtk-media-stop</property>
- </object>
- <object class="GtkImage" id="image12">
- <property name="visible">True</property>
- <property name="stock">gtk-media-play</property>
- </object>
- <object class="GtkImage" id="image13">
- <property name="visible">True</property>
- <property name="stock">gtk-media-next</property>
- </object>
- <object class="GtkImage" id="image14">
- <property name="visible">True</property>
- <property name="stock">gtk-add</property>
- </object>
- <object class="GtkImage" id="image15">
- <property name="visible">True</property>
- <property name="stock">gtk-remove</property>
- </object>
- <object class="GtkImage" id="image16">
- <property name="visible">True</property>
- <property name="stock">gtk-go-up</property>
- </object>
- <object class="GtkImage" id="image17">
- <property name="visible">True</property>
- <property name="stock">gtk-go-down</property>
- </object>
<object class="GtkImage" id="image6">
<property name="visible">True</property>
<property name="stock">gtk-media-previous</property>
Added: parole/trunk/docs/Makefile.am
===================================================================
--- parole/trunk/docs/Makefile.am (rev 0)
+++ parole/trunk/docs/Makefile.am 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,2 @@
+SUBDIRS = \
+ plugin-api
\ No newline at end of file
Added: parole/trunk/docs/plugin-api/Makefile.am
===================================================================
--- parole/trunk/docs/plugin-api/Makefile.am (rev 0)
+++ parole/trunk/docs/plugin-api/Makefile.am 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,101 @@
+## Process this file with automake to produce Makefile.in
+
+AUTOMAKE_OPTIONS = 1.7
+
+# This is a blank Makefile.am for using gtk-doc.
+# Copy this to your project's API docs directory and modify the variables to
+# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
+# of using the various options.
+
+# The name of the module, e.g. 'glib'.
+DOC_MODULE=Parole-Plugins
+
+# The top-level SGML file. You can change this if you want to.
+DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
+
+# The directory containing the source code. Relative to $(srcdir).
+# gtk-doc will search all .c & .h files beneath here for inline comments
+# documenting the functions and macros.
+# e.g. DOC_SOURCE_DIR=../../../gtk
+DOC_SOURCE_DIR=../../parole
+
+# Extra options to supply to gtkdoc-scan.
+# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
+SCAN_OPTIONS=--ignore-headers=config.h --rebuild-types
+
+# Extra options to supply to gtkdoc-mkdb.
+# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml
+MKDB_OPTIONS=--sgml-mode --output-format=xml
+
+# Extra options to supply to gtkdoc-mktmpl
+# e.g. MKTMPL_OPTIONS=--only-section-tmpl
+MKTMPL_OPTIONS=
+
+# Extra options to supply to gtkdoc-mkhtml
+MKHTML_OPTIONS=
+
+# Extra options to supply to gtkdoc-fixref. Not normally needed.
+# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
+FIXXREF_OPTIONS=
+
+# Used for dependencies. The docs will be rebuilt if any of these change.
+# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
+# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
+CFILE_GLOB=$(top_srcdir)/parole/*.c
+HFILE_GLOB=$(top_srcdir)/parole/*.h
+
+# Header files to ignore when scanning.
+# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
+IGNORE_HFILES=
+ parole-player.h \
+ parole-gst.h \
+ parole-vis.h \
+ parole-statusbar.h \
+ parole-builder.h \
+ parole-mediachooser.h \
+ parole-filters.h \
+ parole-screensaver.h \
+ parole-conf.h \
+ parole-conf-dialog.h \
+ parole-rc-utils.h \
+ parole-utils.h \
+ parole-dbus.h \
+ parole-debug.h \
+ parole-plugin-manager.h
+
+# Images to copy into HTML directory.
+# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
+HTML_IMAGES=
+
+# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
+# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
+content_files= \
+ version.xml
+
+# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
+# Only needed if you are using gtkdoc-scangobj to dynamically query widget
+# signals and properties.
+# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
+# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
+GTKDOC_CFLAGS= \
+ $(GTK_CFLAGS) \
+ $(GLIB_CFLAGS) \
+ $(GOBJECT_CFLAGS) \
+ -I$(top_srcdir)/parole \
+ -I$(top_builddir)/parole
+
+GTKDOC_LIBS= \
+ $(GTK_LIBS) \
+ $(GLIB_LIBS) \
+ $(GOBJECT_LIBS) \
+ $(top_builddir)/parole/libparole.la
+
+if ENABLE_GTK_DOC
+include $(top_srcdir)/gtk-doc.make
+else
+EXTRA_DIST=
+endif
+
+EXTRA_DIST += \
+ version.xml.in
+
Added: parole/trunk/docs/plugin-api/Parole-Plugins-docs.sgml
===================================================================
--- parole/trunk/docs/plugin-api/Parole-Plugins-docs.sgml (rev 0)
+++ parole/trunk/docs/plugin-api/Parole-Plugins-docs.sgml 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
+[
+ <!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
+ <!ENTITY version SYSTEM "version.xml">
+ <!ENTITY date "July 2009">
+]>
+<book id="index">
+ <bookinfo>
+ <title>Parole Plugins Reference Manual</title>
+ <releaseinfo>
+ for Parole-Plugins &version;
+ </releaseinfo>
+ <pubdate>&date;</pubdate>
+
+ <copyright>
+ <year>2009</year>
+ <holder>Ali Abdallah</holder>
+ </copyright>
+
+ <legalnotice id="legalnotice">
+ <para>
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.1 or
+ any later version published by the Free Software Foundation; with no
+ Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
+ Texts. The complete license text is available from the <ulink
+ type="http" url="http://www.gnu.org/">Free Software Foundation</ulink>.
+ </para>
+ </legalnotice>
+
+ </bookinfo>
+
+ <chapter>
+ <title>Parole Plugins Overview</title>
+ <xi:include href="xml/parole.xml"/>
+
+ <xi:include href="xml/parole-plugin.xml"/>
+ <xi:include href="xml/parole-mediafile.xml"/>
+ <xi:include href="xml/parole-stream.xml"/>
+ </chapter>
+
+ <index id="api-index-full">
+ <title>API Index</title>
+ <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
+ </index>
+
+ <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
+</book>
Added: parole/trunk/docs/plugin-api/Parole-Plugins-sections.txt
===================================================================
--- parole/trunk/docs/plugin-api/Parole-Plugins-sections.txt (rev 0)
+++ parole/trunk/docs/plugin-api/Parole-Plugins-sections.txt 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,311 @@
+<SECTION>
+<FILE>parole-plugin</FILE>
+ParolePluginContainer
+ParoleState
+<TITLE>ParolePlugin</TITLE>
+ParolePlugin
+parole_plugin_new
+parole_plugin_get_main_window
+parole_plugin_pack_widget
+parole_plugin_play_uri
+parole_plugin_play_file
+parole_plugin_pause_playing
+parole_plugin_resume
+parole_plugin_stop_playing
+parole_plugin_seek
+<SUBSECTION Standard>
+PAROLE_PLUGIN
+PAROLE_IS_PLUGIN
+PAROLE_TYPE_PLUGIN
+parole_plugin_get_type
+</SECTION>
+
+<SECTION>
+<FILE>parole-mediachooser</FILE>
+ParoleMediaChooserPrivate
+media_files_opened
+media_file_opened
+parole_media_chooser_open_local
+parole_media_chooser_open_location
+<SUBSECTION Standard>
+PAROLE_MEDIA_CHOOSER
+PAROLE_IS_MEDIA_CHOOSER
+PAROLE_TYPE_MEDIA_CHOOSER
+parole_media_chooser_get_type
+</SECTION>
+
+<SECTION>
+<FILE>parole-plugins-manager</FILE>
+ParolePluginsManagerPrivate
+parole_plugins_manager_new
+parole_plugins_manager_load_plugins
+parole_plugins_manager_pack
+<SUBSECTION Standard>
+PAROLE_PLUGINS_MANAGER
+PAROLE_IS_PLUGINS_MANAGER
+PAROLE_TYPE_PLUGINS_MANAGER
+parole_plugins_manager_get_type
+</SECTION>
+
+<SECTION>
+<FILE>parole-module</FILE>
+ParoleModulePrivate
+constructor
+parole_module_new
+<SUBSECTION Standard>
+PAROLE_MODULE
+PAROLE_IS_MODULE
+PAROLE_TYPE_MODULE
+parole_module_get_type
+</SECTION>
+
+<SECTION>
+<FILE>parole-screensaver</FILE>
+PAROLE_SCREEN_SAVER
+ParoleScreenSaverPrivate
+parole_screen_saver_new
+parole_screen_saver_inhibit
+parole_screen_saver_uninhibit
+<SUBSECTION Standard>
+PAROLE_IS_SCREENSAVER
+PAROLE_TYPE_SCREENSAVER
+parole_screen_saver_get_type
+</SECTION>
+
+<SECTION>
+<FILE>parole-sidebar</FILE>
+ParoleSidebarPrivate
+parole_sidebar_new
+parole_sidebar_set_visible
+<SUBSECTION Standard>
+PAROLE_SIDEBAR
+PAROLE_IS_SIDEBAR
+PAROLE_TYPE_SIDEBAR
+parole_sidebar_get_type
+</SECTION>
+
+<SECTION>
+<FILE>parole-gst</FILE>
+ParoleMediaState
+ParoleGstPrivate
+media_state
+media_progressed
+buffering
+media_tag
+error
+parole_gst_new
+parole_gst_play_file
+parole_gst_pause
+parole_gst_resume
+parole_gst_stop
+parole_gst_null_state
+parole_gst_seek
+parole_gst_set_volume
+parole_gst_get_volume
+<SUBSECTION Standard>
+PAROLE_GST
+PAROLE_IS_GST
+PAROLE_TYPE_GST
+parole_gst_get_type
+</SECTION>
+
+<SECTION>
+<FILE>parole-mediafile</FILE>
+<TITLE>ParoleMediaFile</TITLE>
+ParoleMediaFile
+parole_media_file_new
+parole_media_file_get_file_name
+parole_media_file_get_display_name
+parole_media_file_get_uri
+parole_media_file_get_content_type
+<SUBSECTION Standard>
+PAROLE_MEDIA_FILE
+PAROLE_IS_MEDIA_FILE
+PAROLE_TYPE_MEDIA_FILE
+parole_media_file_get_type
+</SECTION>
+
+<SECTION>
+<FILE>parole-player</FILE>
+ParolePlayerPrivate
+parole_player_new
+parole_player_get_media_list
+<SUBSECTION Standard>
+PAROLE_PLAYER
+PAROLE_IS_PLAYER
+PAROLE_TYPE_PLAYER
+parole_player_get_type
+</SECTION>
+
+<SECTION>
+<FILE>parole-medialist</FILE>
+ParoleMediaListPrivate
+media_activated
+media_cursor_changed
+parole_media_list_new
+parole_media_list_get_selected_row
+parole_media_list_get_next_row
+parole_media_list_set_row_pixbuf
+parole_media_list_set_row_name
+parole_media_list_open
+parole_media_list_open_location
+parole_media_list_add_files
+<SUBSECTION Standard>
+PAROLE_MEDIA_LIST
+PAROLE_IS_MEDIA_LIST
+PAROLE_TYPE_MEDIA_LIST
+parole_media_list_get_type
+</SECTION>
+
+<SECTION>
+<FILE>parole-conf-dialog</FILE>
+ParoleConfDialogPrivate
+parole_conf_dialog_new
+parole_conf_dialog_open
+<SUBSECTION Standard>
+PAROLE_CONF_DIALOG
+PAROLE_IS_CONF_DIALOG
+PAROLE_TYPE_CONF_DIALOG
+parole_conf_dialog_get_type
+</SECTION>
+
+<SECTION>
+<FILE>parole-statusbar</FILE>
+ParoleStatusbarPrivate
+parole_statusbar_new
+parole_statusbar_set_text
+parole_statusbar_set_duration
+parole_statusbar_set_position
+parole_statusbar_set_buffering
+parole_statusbar_set_visible
+<SUBSECTION Standard>
+PAROLE_STATUSBAR
+PAROLE_IS_STATUSBAR
+PAROLE_TYPE_STATUSBAR
+parole_statusbar_get_type
+</SECTION>
+
+<SECTION>
+<FILE>parole-conf</FILE>
+ParoleConfPrivate
+parole_conf_new
+<SUBSECTION Standard>
+PAROLE_CONF
+PAROLE_IS_CONF
+PAROLE_TYPE_CONF
+parole_conf_get_type
+</SECTION>
+
+<SECTION>
+<FILE>parole-stream</FILE>
+<TITLE>ParoleStream</TITLE>
+ParoleStream
+parole_stream_new
+parole_stream_init_properties
+<SUBSECTION Standard>
+PAROLE_STREAM
+PAROLE_IS_STREAM
+PAROLE_TYPE_STREAM
+parole_stream_get_type
+</SECTION>
+
+<SECTION>
+<FILE>enum-gtypes</FILE>
+parole_media_state_get_type
+ENUM_GTYPE_MEDIA_STATE
+parole_plugin_container_get_type
+ENUM_GTYPE_PLUGIN_CONTAINER
+parole_state_get_type
+ENUM_GTYPE_STATE
+</SECTION>
+
+<SECTION>
+<FILE>parole-rc-utils</FILE>
+parole_rc_write_entry_bool
+parole_rc_write_entry_int
+parole_rc_write_entry_string
+parole_rc_read_entry_bool
+parole_rc_read_entry_int
+parole_rc_read_entry_string
+</SECTION>
+
+<SECTION>
+<FILE>org.parole.media.list</FILE>
+g_marshal_value_peek_boolean
+g_marshal_value_peek_char
+g_marshal_value_peek_uchar
+g_marshal_value_peek_int
+g_marshal_value_peek_uint
+g_marshal_value_peek_long
+g_marshal_value_peek_ulong
+g_marshal_value_peek_int64
+g_marshal_value_peek_uint64
+g_marshal_value_peek_enum
+g_marshal_value_peek_flags
+g_marshal_value_peek_float
+g_marshal_value_peek_double
+g_marshal_value_peek_string
+g_marshal_value_peek_param
+g_marshal_value_peek_boxed
+g_marshal_value_peek_pointer
+g_marshal_value_peek_object
+dbus_glib_marshal_parole_media_list_BOOLEAN__BOXED_POINTER
+</SECTION>
+
+<SECTION>
+<FILE>parole-utils</FILE>
+parole_window_busy_cursor
+parole_window_invisible_cursor
+thunar_file_compare_by_name
+parole_get_name_without_extension
+parole_get_subtitle_path
+</SECTION>
+
+<SECTION>
+<FILE>parole</FILE>
+parole_plugin_constructor
+ParolePluginConstruct
+PAROLE_PLUGIN_CONSTRUCT
+</SECTION>
+
+<SECTION>
+<FILE>gmarshal</FILE>
+</SECTION>
+
+<SECTION>
+<FILE>stamp-enum-gtypes</FILE>
+</SECTION>
+
+<SECTION>
+<FILE>parole-filters</FILE>
+parole_get_supported_audio_filter
+parole_get_supported_video_filter
+parole_get_supported_media_filter
+parole_file_filter
+parole_get_media_files
+</SECTION>
+
+<SECTION>
+<FILE>parole-vis</FILE>
+parole_vis_get_plugins
+</SECTION>
+
+<SECTION>
+<FILE>parole-debug</FILE>
+PAROLE_DEBUG_ENUM
+PAROLE_DEBUG_ENUM_FULL
+parole_debug_enum
+parole_debug_enum_full
+</SECTION>
+
+<SECTION>
+<FILE>parole-dbus</FILE>
+PAROLE_DBUS_NAME
+PAROLE_DBUS_PATH
+PAROLE_DBUS_INTERFACE
+parole_g_session_bus_get
+parole_dbus_name_has_owner
+parole_dbus_register_name
+parole_dbus_release_name
+</SECTION>
+
Added: parole/trunk/docs/plugin-api/Parole-Plugins.types
===================================================================
--- parole/trunk/docs/plugin-api/Parole-Plugins.types (rev 0)
+++ parole/trunk/docs/plugin-api/Parole-Plugins.types 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,17 @@
+parole_plugin_get_type
+parole_media_state_get_type
+parole_plugin_container_get_type
+parole_state_get_type
+parole_media_chooser_get_type
+parole_plugins_manager_get_type
+parole_module_get_type
+parole_screen_saver_get_type
+parole_sidebar_get_type
+parole_gst_get_type
+parole_media_file_get_type
+parole_player_get_type
+parole_media_list_get_type
+parole_conf_dialog_get_type
+parole_statusbar_get_type
+parole_conf_get_type
+parole_stream_get_type
Added: parole/trunk/docs/plugin-api/version.xml.in
===================================================================
--- parole/trunk/docs/plugin-api/version.xml.in (rev 0)
+++ parole/trunk/docs/plugin-api/version.xml.in 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1 @@
+ at VERSION@
Added: parole/trunk/parole/Makefile.am
===================================================================
--- parole/trunk/parole/Makefile.am (rev 0)
+++ parole/trunk/parole/Makefile.am 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,181 @@
+bin_PROGRAMS = parole-media-player
+
+noinst_LTLIBRARIES = \
+ libparole.la
+
+INCLUDES = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/common \
+ -I$(top_srcdir)/data \
+ -I$(top_srcdir)/data/mime \
+ -DLOCALEDIR=\"$(localedir)\" \
+ -DG_LOG_DOMAIN=\"parole\" \
+ -DPAROLE_PLUGINS_DIR=\"$(libdir)/parole-$(PAROLE_VERSION_API)\"\
+ $(GTK_CFLAGS) \
+ $(GLIB_CFLAGS) \
+ $(GOBJECT_CFLAGS) \
+ $(GTHREAD_CFLAGS) \
+ $(GIO_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ $(DBUS_GLIB_CFLAGS) \
+ $(LIBXFCE4GUI_CFLAGS) \
+ $(LIBXFCE4UTIL_CFLAGS) \
+ $(GST_CFLAGS) \
+ $(GST_BASE_CFLAGS) \
+ $(GST_INTERFACES_CFLAGS)
+
+PAROLE_LDFLAGS = \
+ -export-dynamic \
+ -no-undefined \
+ -export-symbols-regex "^[[^_]].*"
+
+PAROLE_LIBS = \
+ $(top_srcdir)/common/libparolecommon.la \
+ $(GTK_LIBS) \
+ $(GLIB_LIBS) \
+ $(GOBJECT_LIBS) \
+ $(GTHREAD_LIBS) \
+ $(GIO_LIBS) \
+ $(DBUS_LIBS) \
+ $(DBUS_GLIB_LIBS) \
+ $(LIBXFCE4GUI_LIBS) \
+ $(LIBXFCE4UTIL_LIBS) \
+ $(GST_LIBS) \
+ $(GST_BASE_LIBS) \
+ $(GST_INTERFACES_LIBS)
+
+GENERATED_FILES = \
+ gmarshal.c \
+ gmarshal.h \
+ enum-gtypes.c \
+ enum-gtypes.h \
+ org.parole.media.list.h
+
+INST_HFILES = \
+ parole.h \
+ parole-plugin.h \
+ parole-mediafile.h \
+ parole-stream.h
+
+NOINST_HFILES = \
+ parole-player.h \
+ parole-gst.h \
+ parole-vis.h \
+ parole-statusbar.h \
+ parole-sidebar.h \
+ parole-mediachooser.h \
+ parole-filters.h \
+ parole-screensaver.h \
+ parole-conf.h \
+ parole-conf-dialog.h \
+ parole-rc-utils.h \
+ parole-utils.h \
+ parole-dbus.h \
+ parole-medialist.h \
+ parole-debug.h \
+ parole-plugins-manager.h \
+ parole-module.h
+
+libparole_headers = \
+ $(INST_HFILES)
+
+libparole_includedir = \
+ $(includedir)/parole
+
+libparole_include_HEADERS = \
+ $(libparole_headers)
+
+libparole_la_SOURCES = \
+ $(GENERATED_FILES) \
+ $(INST_HFILES) \
+ $(NOINST_HFILES) \
+ parole-player.c \
+ parole-gst.c \
+ parole-stream.c \
+ parole-mediafile.c \
+ parole-vis.c \
+ parole-sidebar.c \
+ parole-statusbar.c \
+ parole-medialist.c \
+ parole-mediachooser.c \
+ parole-filters.c \
+ parole-screensaver.c \
+ parole-conf.c \
+ parole-conf-dialog.c \
+ parole-rc-utils.c \
+ parole-utils.c \
+ parole-dbus.c \
+ parole-debug.c \
+ parole-plugins-manager.c \
+ parole-plugin.c \
+ parole-module.c
+
+libparole_la_LDFLAGS = \
+ $(PAROLE_LDFLAGS)
+
+libparole_la_LIBADD = \
+ $(PAROLE_LIBS)
+
+parole_media_player_SOURCES = \
+ main.c
+
+parole_media_player_LDADD = \
+ libparole.la \
+ $(PAROLE_LIBS)
+
+parole_media_player_LDFLAGS = \
+ $(PAROLE_LDFLAGS)
+
+parole_glib_enum_headers = \
+ parole-gst.h \
+ parole-plugin.h
+
+if MAINTAINER_MODE
+
+BUILT_SOURCES = \
+ $(GENERATED_FILES)
+
+gmarshal.c: gmarshal.list
+ echo "#include \"gmarshal.h\"" > $@ && \
+ glib-genmarshal $< --prefix=_gmarshal --body >> $@
+
+gmarshal.h: gmarshal.list
+ glib-genmarshal $< --prefix=_gmarshal --header > $@
+
+enum-gtypes.h: stamp-enum-gtypes.h
+ @true
+stamp-enum-gtypes.h: $(parole_glib_enum_headers) Makefile
+ ( cd $(srcdir) && glib-mkenums \
+ --fhead "#ifndef __ENUM_GTYPES_H__\n#define __ENUM_GTYPES_H__\n#include <glib-object.h>\nG_BEGIN_DECLS\n" \
+ --fprod "/* enumerations from \"@filename@\" */\n" \
+ --vhead "GType @enum_name at _get_type (void);\n#define ENUM_GTYPE_ at ENUMSHORT@ (@enum_name at _get_type())\n" \
+ --ftail "G_END_DECLS\n\n#endif /* __ENUM_GTYPES_H__ */" \
+ $(parole_glib_enum_headers) ) > xgen-enum \
+ && (cmp -s xgen-enum enum-gtypes.h || cp xgen-enum enum-gtypes.h) \
+ && rm -f xgen-enum \
+ && echo timestamp > $(@F)
+
+enum-gtypes.c: $(parole_glib_enum_headers) Makefile
+ ( cd $(srcdir) && glib-mkenums \
+ --fhead "#include \"enum-gtypes.h\"\n\n" \
+ --fhead "#include \"parole-gst.h\"\n\n" \
+ --fhead "#include \"parole-plugin.h\"\n\n" \
+ --fprod "\n/* enumerations from \"@filename@\" */" \
+ --vhead "GType\n at enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G at Type@Value values[] = {" \
+ --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
+ --vtail " { 0, NULL, NULL }\n };\n etype = g_ at type@_register_static (\"@EnumName@\", values);\n }\n return etype;\n}\n" \
+ $(parole_glib_enum_headers) ) >> xgen-enum \
+ && cp xgen-enum enum-gtypes.c \
+ && rm -f xgen-enum
+
+org.parole.media.list.h: $(srcdir)/org.parole.media.list.xml
+ dbus-binding-tool --mode=glib-server --prefix=parole_media_list $< >$@
+
+endif
+
+EXTRA_DIST = \
+ gmarshal.list
+
+DISTCLEANFILES = \
+ $(BUILT_SOURCES) \
+ stamp-enum-gtypes.h
Added: parole/trunk/parole/gmarshal.list
===================================================================
--- parole/trunk/parole/gmarshal.list (rev 0)
+++ parole/trunk/parole/gmarshal.list 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,3 @@
+VOID:OBJECT,ENUM
+VOID:OBJECT,DOUBLE
+VOID:OBJECT,INT
Added: parole/trunk/parole/main.c
===================================================================
--- parole/trunk/parole/main.c (rev 0)
+++ parole/trunk/parole/main.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,163 @@
+/*
+ * * Copyright (C) 2008-2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <unistd.h>
+#include <signal.h>
+
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <gst/gst.h>
+
+#include <libxfce4util/libxfce4util.h>
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include "parole-player.h"
+#include "parole-plugins-manager.h"
+#include "parole-utils.h"
+#include "parole-dbus.h"
+#include "parole-builder.h"
+
+static void
+parole_send_files (gchar **filenames)
+{
+ GFile *file;
+ DBusGConnection *bus;
+ DBusGProxy *proxy;
+ gchar **out_paths;
+ GError *error = NULL;
+ guint i;
+
+ bus = parole_g_session_bus_get ();
+
+ out_paths = g_new (gchar *, g_strv_length (filenames));
+
+ for ( i = 0; filenames && filenames[i]; i++)
+ {
+ file = g_file_new_for_commandline_arg (filenames[i]);
+ out_paths[i] = g_file_get_path (file);
+ g_object_unref (file);
+ }
+
+ proxy = dbus_g_proxy_new_for_name (bus,
+ PAROLE_DBUS_NAME,
+ PAROLE_DBUS_PATH,
+ PAROLE_DBUS_INTERFACE);
+
+ dbus_g_proxy_call (proxy, "AddFiles", &error,
+ G_TYPE_STRV, out_paths,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+
+ if ( error )
+ {
+ g_critical ("Unable to send media files to Parole: %s", error->message);
+ g_error_free (error);
+ }
+
+ g_object_unref (proxy);
+ dbus_g_connection_unref (bus);
+ g_strfreev (out_paths);
+}
+
+int main (int argc, char **argv)
+{
+ ParolePlayer *player;
+ ParolePluginsManager *plugins;
+ GtkBuilder *builder;
+
+ GError *error = NULL;
+ gchar **filenames = NULL;
+ gboolean new_instance = FALSE;
+
+ GOptionEntry option_entries[] =
+ {
+ {"new-instance", 'i', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &new_instance, N_("Open a new instance"), NULL },
+ {G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, N_("Media to play"), NULL},
+ { NULL, },
+ };
+
+ if ( !g_thread_supported () )
+ g_thread_init (NULL);
+
+ xfce_textdomain (GETTEXT_PACKAGE, LOCALEDIR, "UTF-8");
+
+ gst_init (&argc, &argv);
+
+ if ( !gtk_init_with_args (&argc, &argv, (gchar *)"", option_entries, (gchar *)PACKAGE, &error))
+ {
+ if (G_LIKELY (error) )
+ {
+ g_printerr ("%s: %s.\n", G_LOG_DOMAIN, error->message);
+ g_printerr (_("Type '%s --help' for usage."), G_LOG_DOMAIN);
+ g_printerr ("\n");
+ g_error_free (error);
+ }
+ else
+ {
+ g_error ("Unable to open display.");
+ }
+
+ return EXIT_FAILURE;
+ }
+
+ if ( parole_dbus_name_has_owner (PAROLE_DBUS_NAME) )
+ {
+ TRACE ("Parole is already running");
+ if ( filenames && filenames[0] != NULL )
+ parole_send_files (filenames);
+ }
+ else
+ {
+ builder = parole_builder_get_main_interface ();
+ parole_dbus_register_name (PAROLE_DBUS_NAME);
+ player = parole_player_new ();
+
+ if ( filenames && filenames[0] != NULL )
+ {
+ ParoleMediaList *list;
+ list = parole_player_get_media_list (player);
+ parole_media_list_add_files (list, filenames);
+ }
+ plugins = parole_plugins_manager_new ();
+ parole_plugins_manager_load_plugins (plugins);
+ g_object_unref (builder);
+
+ gdk_notify_startup_complete ();
+ gtk_main ();
+
+ parole_dbus_release_name (PAROLE_DBUS_NAME);
+ g_object_unref (plugins);
+ }
+
+ gst_deinit ();
+ return 0;
+}
Added: parole/trunk/parole/org.parole.media.list.xml
===================================================================
--- parole/trunk/parole/org.parole.media.list.xml (rev 0)
+++ parole/trunk/parole/org.parole.media.list.xml 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<node name="/">
+ <interface name="org.Parole.Media.Player">
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol"
+ value="parole_media_list_dbus"/>
+ <annotation name="org.freedesktop.DBus.GLib.ClientCSymbol"
+ value="parole_media_list_dbus_client"/>
+
+ <method name="AddFiles">
+ <arg type="as" name="files" direction="in"/>
+ </method>
+
+ </interface>
+</node>
Added: parole/trunk/parole/parole-conf-dialog.c
===================================================================
--- parole/trunk/parole/parole-conf-dialog.c (rev 0)
+++ parole/trunk/parole/parole-conf-dialog.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,287 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "common/parole-builder.h"
+#include "interfaces/parole-settings_ui.h"
+
+#include "parole-conf-dialog.h"
+#include "parole-conf.h"
+#include "parole-vis.h"
+
+/*
+ * GtkBuilder Callbacks
+ */
+
+void parole_conf_dialog_response_cb (GtkDialog *dialog,
+ gint response_id,
+ ParoleConfDialog *self);
+
+void parole_conf_dialog_enable_vis_changed_cb (GtkToggleButton *widget,
+ ParoleConfDialog *self);
+
+void parole_conf_dialog_vis_plugin_changed_cb (GtkComboBox *widget,
+ ParoleConfDialog *self);
+
+void parole_conf_dialog_font_set_cb (GtkFontButton *button,
+ ParoleConfDialog *self);
+
+void parole_conf_dialog_enable_subtitle_changed_cb (GtkToggleButton *widget,
+ ParoleConfDialog *self);
+
+/*
+ * End of GtkBuilder callbacks
+ */
+
+#define PAROLE_CONF_DIALOG_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_CONF_DIALOG, ParoleConfDialogPrivate))
+
+struct ParoleConfDialogPrivate
+{
+ ParoleConf *conf;
+
+ GHashTable *vis_plugins;
+
+ GtkWidget *vis_combox;
+ GtkWidget *toggle_vis;
+ GtkWidget *toggle_subtitle;
+ GtkWidget *font_button;
+};
+
+G_DEFINE_TYPE (ParoleConfDialog, parole_conf_dialog, G_TYPE_OBJECT)
+
+static void
+parole_conf_dialog_destroy (GtkWidget *widget, ParoleConfDialog *self)
+{
+ gtk_widget_destroy (widget);
+ g_object_unref (self);
+}
+
+void parole_conf_dialog_response_cb (GtkDialog *dialog, gint response_id, ParoleConfDialog *self)
+{
+ switch (response_id)
+ {
+ case GTK_RESPONSE_HELP:
+ break;
+ default:
+ parole_conf_dialog_destroy (GTK_WIDGET (dialog), self);
+ break;
+ }
+}
+
+void parole_conf_dialog_enable_vis_changed_cb (GtkToggleButton *widget, ParoleConfDialog *self)
+{
+ gboolean active;
+
+ active = gtk_toggle_button_get_active (widget);
+
+ g_object_set (G_OBJECT (self->priv->conf),
+ "vis-enabled", active,
+ NULL);
+
+ gtk_widget_set_sensitive (self->priv->vis_combox, active);
+}
+
+void parole_conf_dialog_vis_plugin_changed_cb (GtkComboBox *widget, ParoleConfDialog *self)
+{
+ gchar *active;
+ GstElementFactory *f;
+
+ active = gtk_combo_box_get_active_text (widget);
+
+ f = g_hash_table_lookup (self->priv->vis_plugins, active);
+
+ if ( f )
+ {
+ g_object_set (G_OBJECT (self->priv->conf),
+ "vis-name", GST_PLUGIN_FEATURE_NAME (f),
+ NULL);
+ }
+
+ g_free (active);
+}
+
+void parole_conf_dialog_font_set_cb (GtkFontButton *button, ParoleConfDialog *self)
+{
+ g_object_set (G_OBJECT (self->priv->conf),
+ "subtitle-font", gtk_font_button_get_font_name (button),
+ NULL);
+}
+
+void parole_conf_dialog_enable_subtitle_changed_cb (GtkToggleButton *widget, ParoleConfDialog *self)
+{
+ gboolean active;
+
+ active = gtk_toggle_button_get_active (widget);
+
+ g_object_set (G_OBJECT (self->priv->conf),
+ "enable-subtitle", active,
+ NULL);
+
+ gtk_widget_set_sensitive (self->priv->font_button, active);
+
+}
+
+static void
+parole_conf_dialog_finalize (GObject *object)
+{
+ ParoleConfDialog *self;
+
+ self = PAROLE_CONF_DIALOG (object);
+
+ g_object_unref (self->priv->conf);
+ g_hash_table_destroy (self->priv->vis_plugins);
+
+ G_OBJECT_CLASS (parole_conf_dialog_parent_class)->finalize (object);
+}
+
+static void
+parole_conf_dialog_class_init (ParoleConfDialogClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = parole_conf_dialog_finalize;
+
+ g_type_class_add_private (klass, sizeof (ParoleConfDialogPrivate));
+}
+
+static void
+parole_conf_dialog_init (ParoleConfDialog *self)
+{
+ self->priv = PAROLE_CONF_DIALOG_GET_PRIVATE (self);
+ self->priv->conf = parole_conf_new ();
+
+ self->priv->vis_plugins = parole_vis_get_plugins ();
+}
+
+static void
+parole_conf_dialog_add_vis_plugins (gpointer key, gpointer value, GtkWidget *combox)
+{
+ gtk_combo_box_append_text (GTK_COMBO_BOX (combox), (const gchar *) key);
+}
+
+static gboolean
+parole_conf_dialog_set_default_vis_plugin (GtkTreeModel *model, GtkTreePath *path,
+ GtkTreeIter *iter, ParoleConfDialog *self)
+{
+ GstElementFactory *f;
+ gchar *vis_name;
+ gchar *combox_text;
+ gboolean ret = FALSE;
+
+ g_object_get (G_OBJECT (self->priv->conf),
+ "vis-name", &vis_name,
+ NULL);
+
+ gtk_tree_model_get (model, iter,
+ 0, &combox_text,
+ -1);
+
+ f = g_hash_table_lookup (self->priv->vis_plugins, combox_text);
+
+ if ( !g_strcmp0 (vis_name, "none") )
+ {
+ if ( !g_strcmp0 (GST_PLUGIN_FEATURE_NAME (f), "Goom") )
+ ret = TRUE;
+ }
+ else if ( !g_strcmp0 (GST_PLUGIN_FEATURE_NAME (f), vis_name) )
+ {
+ ret = TRUE;
+ }
+
+ if ( ret == TRUE )
+ gtk_combo_box_set_active_iter (GTK_COMBO_BOX (self->priv->vis_combox), iter);
+
+ return ret;
+}
+
+static void
+parole_conf_dialog_set_defaults (ParoleConfDialog *self)
+{
+ GtkTreeModel *model;
+ gboolean vis_enabled;
+ gboolean subtitle;
+ gchar *subtitle_font;
+
+ g_object_get (G_OBJECT (self->priv->conf),
+ "vis-enabled", &vis_enabled,
+ "enable-subtitle", &subtitle,
+ "subtitle-font", &subtitle_font,
+ NULL);
+
+ gtk_widget_set_sensitive (self->priv->vis_combox, vis_enabled);
+ gtk_widget_set_sensitive (self->priv->font_button, subtitle);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->priv->toggle_vis), vis_enabled);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->priv->toggle_subtitle), subtitle);
+
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (self->priv->vis_combox));
+
+ gtk_tree_model_foreach (model,
+ (GtkTreeModelForeachFunc) parole_conf_dialog_set_default_vis_plugin,
+ self);
+
+ gtk_font_button_set_font_name (GTK_FONT_BUTTON (self->priv->font_button), subtitle_font);
+ g_free (subtitle_font);
+}
+
+ParoleConfDialog *
+parole_conf_dialog_new (void)
+{
+ ParoleConfDialog *parole_conf_dialog = NULL;
+ parole_conf_dialog = g_object_new (PAROLE_TYPE_CONF_DIALOG, NULL);
+ return parole_conf_dialog;
+}
+
+void parole_conf_dialog_open (ParoleConfDialog *self, GtkWidget *parent)
+{
+ GtkBuilder *builder;
+ GtkWidget *dialog;
+ GtkWidget *combox;
+
+ builder = parole_builder_new_from_string (parole_settings_ui, parole_settings_ui_length);
+
+ dialog = GTK_WIDGET (gtk_builder_get_object (builder, "settings-dialog"));
+ combox = GTK_WIDGET (gtk_builder_get_object (builder, "vis-combobox"));
+
+ self->priv->toggle_vis = GTK_WIDGET (gtk_builder_get_object (builder, "enable-vis"));
+ self->priv->toggle_subtitle = GTK_WIDGET (gtk_builder_get_object (builder, "enable-subtitle"));
+ self->priv->font_button = GTK_WIDGET (gtk_builder_get_object (builder, "fontbutton"));
+
+ g_hash_table_foreach (self->priv->vis_plugins, (GHFunc) parole_conf_dialog_add_vis_plugins, combox);
+
+ gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent));
+
+ self->priv->vis_combox = combox;
+
+ parole_conf_dialog_set_defaults (self);
+
+ gtk_builder_connect_signals (builder, self);
+
+ g_object_unref (builder);
+ gtk_widget_show_all (dialog);
+}
Added: parole/trunk/parole/parole-conf-dialog.h
===================================================================
--- parole/trunk/parole/parole-conf-dialog.h (rev 0)
+++ parole/trunk/parole/parole-conf-dialog.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,56 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PAROLE_CONF_DIALOG_H
+#define __PAROLE_CONF_DIALOG_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define PAROLE_TYPE_CONF_DIALOG (parole_conf_dialog_get_type () )
+#define PAROLE_CONF_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_CONF_DIALOG, ParoleConfDialog))
+#define PAROLE_IS_CONF_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_CONF_DIALOG))
+
+typedef struct ParoleConfDialogPrivate ParoleConfDialogPrivate;
+
+typedef struct
+{
+ GObject parent;
+ ParoleConfDialogPrivate *priv;
+
+} ParoleConfDialog;
+
+typedef struct
+{
+ GObjectClass parent_class;
+
+} ParoleConfDialogClass;
+
+GType parole_conf_dialog_get_type (void) G_GNUC_CONST;
+ParoleConfDialog *parole_conf_dialog_new (void);
+
+void parole_conf_dialog_open (ParoleConfDialog *self,
+ GtkWidget *parent);
+
+G_END_DECLS
+
+#endif /* __PAROLE_CONF_DIALOG_H */
Added: parole/trunk/parole/parole-conf.c
===================================================================
--- parole/trunk/parole/parole-conf.c (rev 0)
+++ parole/trunk/parole/parole-conf.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,205 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include "parole-conf.h"
+#include "parole-rc-utils.h"
+
+#define PAROLE_CONF_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_CONF, ParoleConfPrivate))
+
+struct ParoleConfPrivate
+{
+ gchar *vis_sink;
+ gboolean enable_vis;
+ gboolean enable_subtitle;
+ gchar *subtitle_font;
+};
+
+static gpointer parole_conf_object = NULL;
+
+G_DEFINE_TYPE (ParoleConf, parole_conf, G_TYPE_OBJECT)
+
+enum
+{
+ PROP_0,
+ PROP_VIS_ENABLED,
+ PROP_VIS_NAME,
+ PROP_SUBTITLE_ENABLED,
+ PROP_SUBTITLE_FONT,
+};
+
+static void parole_conf_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ ParoleConf *conf;
+ conf = PAROLE_CONF (object);
+
+ switch (prop_id)
+ {
+ case PROP_VIS_ENABLED:
+ conf->priv->enable_vis = g_value_get_boolean (value);
+ g_object_notify (G_OBJECT (conf), "vis-enabled");
+ parole_rc_write_entry_bool ("VIS_ENABLED", conf->priv->enable_vis);
+ break;
+ case PROP_VIS_NAME:
+ if ( conf->priv->vis_sink )
+ g_free (conf->priv->vis_sink);
+ conf->priv->vis_sink = g_strdup (g_value_get_string (value));
+ g_object_notify (G_OBJECT (conf), "vis-name");
+ parole_rc_write_entry_string ("VIS_NAME", conf->priv->vis_sink);
+ break;
+ case PROP_SUBTITLE_ENABLED:
+ conf->priv->enable_subtitle = g_value_get_boolean (value);
+ g_object_notify (G_OBJECT (conf), "enable-subtitle");
+ parole_rc_write_entry_bool ("ENABLE_SUBTITLE", conf->priv->enable_subtitle);
+ break;
+ case PROP_SUBTITLE_FONT:
+ if ( conf->priv->subtitle_font )
+ g_free (conf->priv->subtitle_font);
+ conf->priv->subtitle_font = g_strdup (g_value_get_string (value));
+ g_object_notify (G_OBJECT (conf), "subtitle-font");
+ parole_rc_write_entry_string ("SUBTITLE_FONT", conf->priv->subtitle_font);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void parole_conf_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ ParoleConf *conf;
+ conf = PAROLE_CONF (object);
+
+ switch (prop_id)
+ {
+ case PROP_VIS_ENABLED:
+ g_value_set_boolean (value, conf->priv->enable_vis);
+ break;
+ case PROP_VIS_NAME:
+ g_value_set_string (value, conf->priv->vis_sink);
+ break;
+ case PROP_SUBTITLE_ENABLED:
+ g_value_set_boolean (value, conf->priv->enable_subtitle);
+ break;
+ case PROP_SUBTITLE_FONT:
+ g_value_set_string (value, conf->priv->subtitle_font);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+parole_conf_finalize (GObject *object)
+{
+ ParoleConf *conf;
+
+ conf = PAROLE_CONF (object);
+
+ g_free (conf->priv->vis_sink);
+ g_free (conf->priv->subtitle_font);
+
+ G_OBJECT_CLASS (parole_conf_parent_class)->finalize (object);
+}
+
+static void
+parole_conf_class_init (ParoleConfClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = parole_conf_finalize;
+
+ object_class->get_property = parole_conf_get_property;
+ object_class->set_property = parole_conf_set_property;
+
+ g_object_class_install_property (object_class,
+ PROP_VIS_ENABLED,
+ g_param_spec_boolean ("vis-enabled",
+ NULL, NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_VIS_NAME,
+ g_param_spec_string ("vis-name",
+ NULL, NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_SUBTITLE_ENABLED,
+ g_param_spec_boolean ("enable-subtitle",
+ NULL, NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_SUBTITLE_FONT,
+ g_param_spec_string ("subtitle-font",
+ NULL, NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_type_class_add_private (klass, sizeof (ParoleConfPrivate));
+}
+
+static void
+parole_conf_init (ParoleConf *conf)
+{
+ conf->priv = PAROLE_CONF_GET_PRIVATE (conf);
+
+ conf->priv->enable_vis = parole_rc_read_entry_bool ("VIS_ENABLED", FALSE);
+ conf->priv->vis_sink = g_strdup (parole_rc_read_entry_string ("VIS_NAME", "none"));
+ conf->priv->enable_subtitle = parole_rc_read_entry_bool ("ENABLE_SUBTITLE", TRUE);
+ conf->priv->subtitle_font = g_strdup (parole_rc_read_entry_string ("SUBTITLE_FONT", "Sans 12"));
+}
+
+ParoleConf *
+parole_conf_new (void)
+{
+ if ( parole_conf_object != NULL )
+ {
+ g_object_ref (parole_conf_object);
+ }
+ else
+ {
+ parole_conf_object = g_object_new (PAROLE_TYPE_CONF, NULL);
+ g_object_add_weak_pointer (parole_conf_object, &parole_conf_object);
+ }
+
+ return PAROLE_CONF (parole_conf_object);
+}
Added: parole/trunk/parole/parole-conf.h
===================================================================
--- parole/trunk/parole/parole-conf.h (rev 0)
+++ parole/trunk/parole/parole-conf.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,52 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PAROLE_CONF_H
+#define __PAROLE_CONF_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define PAROLE_TYPE_CONF (parole_conf_get_type () )
+#define PAROLE_CONF(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_CONF, ParoleConf))
+#define PAROLE_IS_CONF(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_CONF))
+
+typedef struct ParoleConfPrivate ParoleConfPrivate;
+
+typedef struct
+{
+ GObject parent;
+ ParoleConfPrivate *priv;
+
+} ParoleConf;
+
+typedef struct
+{
+ GObjectClass parent_class;
+
+} ParoleConfClass;
+
+GType parole_conf_get_type (void) G_GNUC_CONST;
+ParoleConf *parole_conf_new (void);
+
+G_END_DECLS
+
+#endif /* __PAROLE_CONF_H */
Added: parole/trunk/parole/parole-dbus.c
===================================================================
--- parole/trunk/parole/parole-dbus.c (rev 0)
+++ parole/trunk/parole/parole-dbus.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,121 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <glib.h>
+
+#include "parole-dbus.h"
+
+static DBusConnection *
+parole_session_bus_get (void)
+{
+ return dbus_g_connection_get_connection (parole_g_session_bus_get ());
+}
+
+DBusGConnection *
+parole_g_session_bus_get (void)
+{
+ static DBusGConnection *bus = NULL;
+ GError *error = NULL;
+
+ if ( bus == NULL )
+ {
+ bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+
+ if ( error )
+ {
+ g_error ("%s", error->message);
+ }
+ }
+ return bus;
+}
+
+gboolean parole_dbus_name_has_owner (const gchar *name)
+{
+ DBusError error;
+ gboolean ret;
+
+ dbus_error_init (&error);
+
+ ret = dbus_bus_name_has_owner (parole_session_bus_get (), name, &error);
+
+ if ( dbus_error_is_set (&error) )
+ {
+ g_warning ("Failed to get name owner: %s\n", error.message);
+ dbus_error_free (&error);
+ }
+
+ return ret;
+}
+
+gboolean parole_dbus_register_name (const gchar *name)
+{
+ DBusError error;
+ int ret;
+
+ dbus_error_init (&error);
+
+ ret =
+ dbus_bus_request_name (parole_session_bus_get (),
+ name,
+ DBUS_NAME_FLAG_DO_NOT_QUEUE,
+ &error);
+
+ if ( dbus_error_is_set (&error) )
+ {
+ g_warning ("Error: %s\n", error.message);
+ dbus_error_free (&error);
+ return FALSE;
+ }
+
+ return ret == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER ? TRUE : FALSE;
+}
+
+gboolean parole_dbus_release_name (const gchar *name)
+{
+ DBusError error;
+ int ret;
+
+ dbus_error_init (&error);
+
+ ret =
+ dbus_bus_release_name (parole_session_bus_get (),
+ name,
+ &error);
+
+ if ( dbus_error_is_set (&error) )
+ {
+ g_warning ("Error: %s\n", error.message);
+ dbus_error_free (&error);
+ return FALSE;
+ }
+
+ return ret == -1 ? FALSE : TRUE;
+}
Added: parole/trunk/parole/parole-dbus.h
===================================================================
--- parole/trunk/parole/parole-dbus.h (rev 0)
+++ parole/trunk/parole/parole-dbus.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,38 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PAROLE_DBUS_H_
+#define __PAROLE_DBUS_H_
+
+#include <dbus/dbus-glib.h>
+
+#define PAROLE_DBUS_NAME "org.Parole.Media.Player"
+#define PAROLE_DBUS_PATH "/org/Parole/Media/Player"
+#define PAROLE_DBUS_INTERFACE "org.Parole.Media.Player"
+
+DBusGConnection *parole_g_session_bus_get (void);
+
+gboolean parole_dbus_name_has_owner (const gchar *name);
+
+gboolean parole_dbus_register_name (const gchar *name);
+
+gboolean parole_dbus_release_name (const gchar *name);
+
+#endif /* __PAROLE_DBUS_ */
Added: parole/trunk/parole/parole-debug.c
===================================================================
--- parole/trunk/parole/parole-debug.c (rev 0)
+++ parole/trunk/parole/parole-debug.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,81 @@
+/*
+ * * Copyright (C) 2008-2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+#include <glib/gprintf.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include "parole-debug.h"
+
+#if defined(DEBUG) && defined(G_HAVE_ISO_VARARGS)
+
+void parole_debug_enum (const gchar *func, const gchar *file, gint line,
+ const gchar *text, gint v_enum, GType type)
+{
+ gchar *content = NULL;
+ GValue __value__ = { 0, };
+
+ g_value_init (&__value__, type);
+ g_value_set_enum (&__value__, v_enum);
+
+ content = g_strdup_value_contents (&__value__);
+
+ fprintf(stdout, "TRACE[%s:%d] %s(): %s : %s", file, line , func, text, content);
+ fprintf(stdout, "\n");
+
+ g_value_unset (&__value__);
+ g_free (content);
+}
+
+void parole_debug_enum_full (const gchar *func, const gchar *file, gint line,
+ gint v_enum, GType type, const gchar *format, ...)
+{
+ va_list args;
+ gchar *buffer;
+
+ gchar *content = NULL;
+ GValue __value__ = { 0, };
+
+ g_value_init (&__value__, type);
+ g_value_set_enum (&__value__, v_enum);
+
+ content = g_strdup_value_contents (&__value__);
+
+ va_start (args, format);
+ g_vasprintf (&buffer, format, args);
+ va_end (args);
+
+ fprintf(stdout, "TRACE[%s:%d] %s(): ", file, line, func);
+ fprintf(stdout, "%s: %s", buffer, content);
+ fprintf(stdout, "\n");
+
+ g_value_unset (&__value__);
+ g_free (content);
+ g_free (buffer);
+}
+
+#endif /*#if defined(DEBUG) && defined(G_HAVE_ISO_VARARGS)*/
Added: parole/trunk/parole/parole-debug.h
===================================================================
--- parole/trunk/parole/parole-debug.h (rev 0)
+++ parole/trunk/parole/parole-debug.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,66 @@
+/*
+ * * Copyright (C) 2008-2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PAROLE_DEBUG_H
+#define __PAROLE_DEBUG_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdarg.h>
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#if defined(DEBUG) && defined(G_HAVE_ISO_VARARGS)
+
+#define PAROLE_DEBUG_ENUM(_text, _value, _type)\
+ parole_debug_enum (__func__, __FILE__, __LINE__, _text, _value, _type)
+
+#define PAROLE_DEBUG_ENUM_FULL(_value, _type, ...)\
+ parole_debug_enum_full (__func__, __FILE__, __LINE__, _value, _type, __VA_ARGS__)
+
+void parole_debug_enum (const gchar *func,
+ const gchar *file,
+ gint line,
+ const gchar *text,
+ gint v_enum,
+ GType type);
+
+void parole_debug_enum_full (const gchar *func,
+ const gchar *file,
+ gint line,
+ gint v_enum,
+ GType type,
+ const gchar *format,
+ ...) G_GNUC_PRINTF (6, 7);
+
+
+#else
+
+#define PAROLE_DEBUG_ENUM(_text, _value, _type)
+#define PAROLE_DEBUG_ENUM_FULL(_value, _type, ...)
+
+#endif
+
+G_END_DECLS
+
+#endif /* __XFPM_DEBUG_H */
Added: parole/trunk/parole/parole-filters.c
===================================================================
--- parole/trunk/parole/parole-filters.c (rev 0)
+++ parole/trunk/parole/parole-filters.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,152 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libxfce4util/libxfce4util.h>
+#include <glib.h>
+
+#include "parole-filters.h"
+#include "parole-utils.h"
+#include "data/mime/parole-mime-types.h"
+
+/*
+ * Supported Audio formats.
+ */
+GtkFileFilter *parole_get_supported_audio_filter (void)
+{
+ GtkFileFilter *filter;
+ guint i;
+
+ filter = gtk_file_filter_new ();
+
+ gtk_file_filter_set_name (filter, _("Audio"));
+
+ for ( i = 0; i < G_N_ELEMENTS (audio_mime_types); i++)
+ gtk_file_filter_add_mime_type (filter, audio_mime_types[i]);
+
+ return filter;
+}
+
+/*
+ * Supported Video formats.
+ */
+GtkFileFilter *parole_get_supported_video_filter (void)
+{
+ GtkFileFilter *filter;
+ guint i;
+
+ filter = gtk_file_filter_new ();
+
+ gtk_file_filter_set_name (filter, _("Video"));
+
+ for ( i = 0; i < G_N_ELEMENTS (video_mime_types); i++)
+ gtk_file_filter_add_mime_type (filter, video_mime_types[i]);
+
+ return filter;
+}
+
+/*
+ * Supported Audio And Video.
+ */
+GtkFileFilter *parole_get_supported_media_filter (void)
+{
+ GtkFileFilter *filter;
+ guint i;
+
+ filter = gtk_file_filter_new ();
+
+ gtk_file_filter_set_name (filter, _("Audio and video"));
+
+ for ( i = 0; i < G_N_ELEMENTS (audio_mime_types); i++)
+ gtk_file_filter_add_mime_type (filter, audio_mime_types[i]);
+
+ for ( i = 0; i < G_N_ELEMENTS (video_mime_types); i++)
+ gtk_file_filter_add_mime_type (filter, video_mime_types[i]);
+
+ return filter;
+}
+
+gboolean parole_file_filter (GtkFileFilter *filter, ParoleMediaFile *file)
+{
+ GtkFileFilterInfo filter_info;
+
+ gboolean ret;
+
+ filter_info.display_name = parole_media_file_get_display_name (file);
+ filter_info.mime_type = parole_media_file_get_content_type (file);
+
+ filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME | GTK_FILE_FILTER_MIME_TYPE;
+
+ ret = gtk_file_filter_filter (filter, &filter_info);
+
+ return ret;
+}
+
+void parole_get_media_files (GtkFileFilter *filter, const gchar *path, GSList **list)
+{
+ GSList *list_internal = NULL;
+ GDir *dir;
+ const gchar *name;
+ ParoleMediaFile *file;
+
+ if ( g_file_test (path, G_FILE_TEST_IS_REGULAR ) )
+ {
+ file = parole_media_file_new (path);
+ if ( parole_file_filter (filter, file) )
+ *list = g_slist_append (*list, file);
+ else
+ g_object_unref (file);
+ }
+ else if ( g_file_test (path, G_FILE_TEST_IS_DIR ) )
+ {
+ dir = g_dir_open (path, 0, NULL);
+
+ if ( G_UNLIKELY (dir == NULL) )
+ return;
+
+ while ( (name = g_dir_read_name (dir)) )
+ {
+ gchar *path_internal = g_strdup_printf ("%s/%s", path, name);
+ if ( g_file_test (path_internal, G_FILE_TEST_IS_DIR) )
+ {
+ parole_get_media_files (filter, path_internal, list);
+ }
+ else if ( g_file_test (path_internal, G_FILE_TEST_IS_REGULAR) )
+ {
+ file = parole_media_file_new (path_internal);
+ if ( parole_file_filter (filter, file) )
+ list_internal = g_slist_append (list_internal, file);
+ else
+ g_object_unref (file);
+ }
+ g_free (path_internal);
+ }
+ list_internal = g_slist_sort (list_internal, (GCompareFunc) thunar_file_compare_by_name);
+ g_dir_close (dir);
+ *list = g_slist_concat (*list, list_internal);
+ }
+}
Added: parole/trunk/parole/parole-filters.h
===================================================================
--- parole/trunk/parole/parole-filters.h (rev 0)
+++ parole/trunk/parole/parole-filters.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,40 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PAROLE_FILTERS_H
+#define __PAROLE_FILTERS_H
+
+#include <gtk/gtk.h>
+#include "parole-mediafile.h"
+
+GtkFileFilter *parole_get_supported_audio_filter (void);
+
+GtkFileFilter *parole_get_supported_video_filter (void);
+
+GtkFileFilter *parole_get_supported_media_filter (void);
+
+gboolean parole_file_filter (GtkFileFilter *filter,
+ ParoleMediaFile *file);
+
+void parole_get_media_files (GtkFileFilter *filter,
+ const gchar *path,
+ GSList **list);
+
+#endif /* PAROLE_FILTERS_H */
Added: parole/trunk/parole/parole-gst.c
===================================================================
--- parole/trunk/parole/parole-gst.c (rev 0)
+++ parole/trunk/parole/parole-gst.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,1146 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <gst/gst.h>
+#include <gst/interfaces/xoverlay.h>
+
+#include <libxfce4util/libxfce4util.h>
+#include <libxfcegui4/libxfcegui4.h>
+
+#include <gdk/gdkx.h>
+
+#include "parole-gst.h"
+#include "parole-utils.h"
+#include "parole-conf.h"
+#include "parole-utils.h"
+#include "enum-gtypes.h"
+#include "gmarshal.h"
+
+#define HIDE_WINDOW_CURSOR_TIMEOUT 3.0f
+
+#define PAROLE_GST_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_GST, ParoleGstPrivate))
+
+static void parole_gst_play_file_internal (ParoleGst *gst);
+static void parole_gst_change_state (ParoleGst *gst,
+ GstState new);
+struct ParoleGstPrivate
+{
+ GstElement *playbin;
+ GstElement *video_sink;
+ GstElement *vis_sink;
+
+ GMutex *lock;
+ GstState state;
+ GstState target;
+
+ ParoleStream *stream;
+ gulong tick_id;
+ GdkPixbuf *logo;
+ GTimer *hidecursor_timer;
+
+ ParoleConf *conf;
+ gboolean update;
+ gboolean with_vis;
+};
+
+enum
+{
+ MEDIA_STATE,
+ MEDIA_PROGRESSED,
+ MEDIA_TAG,
+ BUFFERING,
+ ERROR,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (ParoleGst, parole_gst, GTK_TYPE_WIDGET)
+
+static void
+parole_gst_finalize (GObject *object)
+{
+ ParoleGst *gst;
+
+ gst = PAROLE_GST (object);
+
+ TRACE ("start");
+
+ if ( gst->priv->tick_id != 0)
+ g_source_remove (gst->priv->tick_id);
+
+ parole_stream_init_properties (gst->priv->stream);
+ g_object_unref (gst->priv->stream);
+ g_object_unref (gst->priv->playbin);
+
+ g_object_unref (gst->priv->logo);
+ g_mutex_free (gst->priv->lock);
+
+ g_object_unref (gst->priv->conf);
+
+ G_OBJECT_CLASS (parole_gst_parent_class)->finalize (object);
+}
+
+static void
+parole_gst_set_cursor_visible (ParoleGst *gst, gboolean visible)
+{
+ if ( visible )
+ {
+ gst->priv->target == gst->priv->state ? gdk_window_set_cursor (GTK_WIDGET (gst)->window, NULL):
+ parole_window_busy_cursor (GTK_WIDGET (gst)->window);
+ }
+ else
+ parole_window_invisible_cursor (GTK_WIDGET (gst)->window);
+}
+
+static void
+parole_gst_set_window_cursor (GdkWindow *window, GdkCursor *cursor)
+{
+ if ( window )
+ gdk_window_set_cursor (window, cursor);
+}
+
+static gboolean
+parole_gst_configure_event_cb (GtkWidget *widget, GdkEventConfigure *ev, ParoleGst *gst)
+{
+
+
+ return FALSE;
+}
+
+static void
+parole_gst_realize (GtkWidget *widget)
+{
+ ParoleGst *gst;
+ GdkWindowAttr attr;
+ GdkColor color;
+ gint mask;
+
+ GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+ gst = PAROLE_GST (widget);
+
+ attr.x = widget->allocation.x;
+ attr.y = widget->allocation.y;
+ attr.width = widget->allocation.width;
+ attr.height = widget->allocation.height;
+ attr.visual = gtk_widget_get_visual (widget);
+ attr.colormap = gtk_widget_get_colormap (widget);
+ attr.wclass = GDK_INPUT_OUTPUT;
+ attr.window_type = GDK_WINDOW_CHILD;
+ attr.event_mask = gtk_widget_get_events (widget) |
+ GDK_EXPOSURE_MASK |
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK |
+ GDK_KEY_PRESS_MASK;
+
+ mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+
+ widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
+ &attr, mask);
+
+ gdk_window_set_user_data (widget->window, widget);
+ gdk_color_parse ("black", &color);
+ gdk_colormap_alloc_color (gtk_widget_get_colormap (widget), &color,
+ TRUE, TRUE);
+
+ gdk_window_set_background (widget->window, &color);
+ widget->style = gtk_style_attach (widget->style, widget->window);
+
+ g_signal_connect (gtk_widget_get_toplevel (widget), "configure_event",
+ G_CALLBACK (parole_gst_configure_event_cb), gst);
+}
+
+static void
+parole_gst_show (GtkWidget *widget)
+{
+ ParoleGst *gst;
+
+ gst = PAROLE_GST (widget);
+
+ gdk_window_show (widget->window);
+
+ if ( GTK_WIDGET_CLASS (parole_gst_parent_class)->show )
+ GTK_WIDGET_CLASS (parole_gst_parent_class)->show (widget);
+}
+
+static void
+parole_gst_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
+{
+ g_return_if_fail (allocation != NULL);
+
+ widget->allocation = *allocation;
+
+ if ( GTK_WIDGET_REALIZED (widget) )
+ {
+ gdk_window_move_resize (widget->window,
+ allocation->x, allocation->y,
+ allocation->width, allocation->height);
+
+ gtk_widget_queue_draw (widget);
+ }
+}
+
+static void
+parole_gst_draw_logo (ParoleGst *gst)
+{
+ GdkPixbuf *pix;
+ GdkRegion *region;
+ GdkRectangle rect;
+ GtkWidget *widget;
+
+ widget = GTK_WIDGET (gst);
+
+ if ( !widget->window )
+ return;
+
+ rect.x = 0;
+ rect.y = 0;
+
+ rect.width = widget->allocation.width;
+ rect.height = widget->allocation.height;
+
+ region = gdk_region_rectangle (&rect);
+
+ gdk_window_begin_paint_region (widget->window,
+ region);
+
+ gdk_window_clear_area (widget->window,
+ 0, 0,
+ widget->allocation.width,
+ widget->allocation.height);
+
+ pix = gdk_pixbuf_scale_simple (gst->priv->logo,
+ widget->allocation.width,
+ widget->allocation.height,
+ GDK_INTERP_BILINEAR);
+
+ gdk_draw_pixbuf (GDK_DRAWABLE (widget->window),
+ GTK_WIDGET(widget)->style->fg_gc[0],
+ pix,
+ 0, 0, 0, 0,
+ widget->allocation.width,
+ widget->allocation.height,
+ GDK_RGB_DITHER_NONE,
+ 0, 0);
+
+ gdk_pixbuf_unref (pix);
+ gdk_window_end_paint (GTK_WIDGET (gst)->window);
+}
+
+static void
+parole_gst_set_x_overlay (ParoleGst *gst)
+{
+ GstElement *video_sink;
+
+ g_object_get (G_OBJECT (gst->priv->playbin),
+ "video-sink", &video_sink,
+ NULL);
+
+ g_assert (video_sink != NULL);
+
+ gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (video_sink),
+ GDK_WINDOW_XWINDOW (GTK_WIDGET (gst)->window));
+
+ gst_object_unref (video_sink);
+}
+
+static gboolean
+parole_gst_expose_event (GtkWidget *widget, GdkEventExpose *ev)
+{
+ ParoleGst *gst;
+ gboolean playing_video;
+
+ if ( ev && ev->count > 0 )
+ return TRUE;
+
+ gst = PAROLE_GST (widget);
+
+ g_object_get (G_OBJECT (gst->priv->stream),
+ "has-video", &playing_video,
+ NULL);
+
+ parole_gst_set_x_overlay (gst);
+
+ if ( (gst->priv->state < GST_STATE_PAUSED || !gst->priv->with_vis) && !playing_video)
+ parole_gst_draw_logo (gst);
+ else
+ {
+ TRACE ("Exposing GST");
+ gst_x_overlay_expose (GST_X_OVERLAY (gst->priv->video_sink));
+ }
+
+ return TRUE;
+}
+
+static void
+parole_gst_load_logo (ParoleGst *gst)
+{
+ gchar *path;
+
+ path = g_strdup_printf ("%s/parole.png", PIXMAPS_DIR);
+ gst->priv->logo = gdk_pixbuf_new_from_file (path, NULL);
+ g_free (path);
+}
+
+static gboolean
+parole_gst_tick_timeout (gpointer data)
+{
+ ParoleGst *gst;
+
+ gint64 pos;
+ GstFormat format = GST_FORMAT_TIME;
+ gdouble value;
+
+ gst = PAROLE_GST (data);
+
+ gst_element_query_position (gst->priv->playbin, &format, &pos);
+
+ if ( G_UNLIKELY (format != GST_FORMAT_TIME ) )
+ goto out;
+
+ value = ( pos / ((gdouble) 60 * 1000 * 1000 * 1000 ));
+
+ g_signal_emit (G_OBJECT (gst), signals [MEDIA_PROGRESSED], 0, gst->priv->stream, value);
+
+out:
+ if ( g_timer_elapsed (gst->priv->hidecursor_timer, NULL ) > HIDE_WINDOW_CURSOR_TIMEOUT )
+ parole_gst_set_cursor_visible (gst, FALSE);
+
+ return TRUE;
+}
+
+static void
+parole_gst_tick (ParoleGst *gst)
+{
+ if ( gst->priv->state >= GST_STATE_PAUSED )
+ {
+ if ( gst->priv->tick_id != 0 )
+ {
+ return;
+ }
+ gst->priv->tick_id = g_timeout_add (1000, (GSourceFunc) parole_gst_tick_timeout, gst);
+ }
+ else if ( gst->priv->tick_id != 0)
+ {
+ g_source_remove (gst->priv->tick_id);
+ gst->priv->tick_id = 0;
+ }
+}
+
+static void
+parole_gst_query_capabilities (ParoleGst *gst)
+{
+ GstQuery *query;
+ gboolean seekable;
+
+ query = gst_query_new_seeking (GST_FORMAT_TIME);
+
+ if ( gst_element_query (gst->priv->playbin, query) )
+ {
+ gst_query_parse_seeking (query,
+ NULL,
+ &seekable,
+ NULL,
+ NULL);
+ }
+ gst_query_unref (query);
+
+ g_object_set (G_OBJECT (gst->priv->stream),
+ "seekable", seekable,
+ NULL);
+}
+
+static void
+parole_gst_query_duration (ParoleGst *gst)
+{
+ gint64 absolute_duration = 0;
+ gdouble duration = 0;
+
+ GstFormat gst_time = GST_FORMAT_TIME;
+
+ gst_element_query_duration (gst->priv->playbin,
+ &gst_time,
+ &absolute_duration);
+
+ if (gst_time == GST_FORMAT_TIME)
+ {
+ duration = absolute_duration / ((gdouble) 60 * 1000 * 1000 * 1000);
+ g_object_set (G_OBJECT (gst->priv->stream),
+ "absolute-duration", absolute_duration,
+ "duration", duration,
+ NULL);
+ }
+}
+
+static void
+parole_gst_set_subtitle_font (ParoleGst *gst)
+{
+ gchar *font;
+
+ g_object_get (G_OBJECT (gst->priv->conf),
+ "subtitle-font", &font,
+ NULL);
+
+ TRACE ("Setting subtitle font %s\n", font);
+
+ g_object_set (G_OBJECT (gst->priv->playbin),
+ "subtitle-font-desc", font,
+ NULL);
+ g_free (font);
+}
+
+static void
+parole_gst_set_subtitle_encoding (ParoleGst *gst)
+{
+ g_object_set (G_OBJECT (gst->priv->playbin),
+ "subtitle-encoding", "UTF-8",
+ NULL);
+}
+
+static void
+parole_gst_load_subtitle (ParoleGst *gst)
+{
+ ParoleMediaFile *file;
+ const gchar *uri;
+ gchar *sub;
+ gchar *sub_uri;
+ gboolean sub_enabled;
+
+ g_object_get (G_OBJECT (gst->priv->conf),
+ "enable-subtitle", &sub_enabled,
+ NULL);
+
+ if ( !sub_enabled )
+ return;
+
+ g_object_get (G_OBJECT (gst->priv->stream),
+ "media-file", &file,
+ NULL);
+
+ uri = parole_media_file_get_uri (file);
+ sub = parole_get_subtitle_path (uri);
+
+ if ( sub )
+ {
+ TRACE ("Found subtitle with path %s", sub);
+ sub_uri = g_filename_to_uri (sub, NULL, NULL);
+ g_object_set (G_OBJECT (gst->priv->playbin),
+ "suburi", sub_uri,
+ NULL);
+ g_free (sub);
+ g_free (sub_uri);
+ }
+ g_object_unref (file);
+}
+
+static void
+parole_gst_query_info (ParoleGst *gst)
+{
+ const GList *info = NULL;
+ GObject *obj;
+ GParamSpec *pspec;
+ GEnumValue *val;
+ gint type;
+ gboolean has_video = FALSE;
+
+ g_object_get (G_OBJECT (gst->priv->playbin),
+ "stream-info", &info,
+ NULL);
+
+ for ( ; info != NULL; info = info->next )
+ {
+ obj = info->data;
+
+ g_object_get (obj,
+ "type", &type,
+ NULL);
+
+ pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (obj), "type");
+ val = g_enum_get_value (G_PARAM_SPEC_ENUM (pspec)->enum_class, type);
+
+ if ( g_ascii_strcasecmp (val->value_name, "video") == 0 ||
+ g_ascii_strcasecmp (val->value_nick, "video") == 0)
+ {
+ TRACE ("Stream has video");
+ g_object_set (G_OBJECT (gst->priv->stream),
+ "has-video", TRUE,
+ NULL);
+ has_video = TRUE;
+ }
+ if ( g_ascii_strcasecmp (val->value_name, "audio") == 0 ||
+ g_ascii_strcasecmp (val->value_nick, "audio") == 0)
+ {
+ TRACE ("Stream has audio");
+ g_object_set (G_OBJECT (gst->priv->stream),
+ "has-audio", TRUE,
+ NULL);
+ }
+ }
+
+ if ( !has_video )
+ gtk_widget_queue_draw (GTK_WIDGET (gst));
+}
+
+static void
+parole_gst_update_vis (ParoleGst *gst)
+{
+ gchar *vis_name;
+
+ g_object_get (G_OBJECT (gst->priv->conf),
+ "vis-enabled", &gst->priv->with_vis,
+ "vis-name", &vis_name,
+ NULL);
+
+ TRACE ("Vis name %s enabled %d\n", vis_name, gst->priv->with_vis);
+
+ if ( gst->priv->with_vis )
+ {
+ gst->priv->vis_sink = gst_element_factory_make (vis_name, "vis");
+ g_object_set (G_OBJECT (gst->priv->playbin),
+ "vis-plugin", gst->priv->vis_sink,
+ NULL);
+ }
+ else
+ {
+ g_object_set (G_OBJECT (gst->priv->playbin),
+ "vis-plugin", NULL,
+ NULL);
+ gtk_widget_queue_draw (GTK_WIDGET (gst));
+ }
+
+ gst->priv->update = FALSE;
+ g_free (vis_name);
+}
+
+static void
+parole_gst_evaluate_state (ParoleGst *gst, GstState old, GstState new, GstState pending)
+{
+ TRACE ("State change new %i old %i pending %i", new, old, pending);
+
+ gst->priv->state = new;
+
+ parole_gst_tick (gst);
+
+ if ( gst->priv->update && new == GST_STATE_NULL)
+ parole_gst_update_vis (gst);
+
+ if ( gst->priv->target == new )
+ parole_gst_set_window_cursor (GTK_WIDGET (gst)->window, NULL);
+
+ if ( gst->priv->target == GST_STATE_PLAYING && pending >= GST_STATE_READY)
+ parole_gst_set_x_overlay (gst);
+
+ switch (gst->priv->state)
+ {
+ case GST_STATE_PLAYING:
+ parole_gst_query_duration (gst);
+ parole_gst_query_capabilities (gst);
+ parole_gst_query_info (gst);
+
+ g_signal_emit (G_OBJECT (gst), signals [MEDIA_STATE], 0,
+ gst->priv->stream, PAROLE_MEDIA_STATE_PLAYING);
+ break;
+ case GST_STATE_PAUSED:
+ g_signal_emit (G_OBJECT (gst), signals [MEDIA_STATE], 0,
+ gst->priv->stream, PAROLE_MEDIA_STATE_PAUSED);
+ break;
+ case GST_STATE_READY:
+ g_signal_emit (G_OBJECT (gst), signals [MEDIA_STATE], 0,
+ gst->priv->stream, PAROLE_MEDIA_STATE_STOPPED);
+
+ if ( gst->priv->target == GST_STATE_PLAYING)
+ {
+ parole_gst_play_file_internal (gst);
+ }
+ else if ( gst->priv->target == GST_STATE_PAUSED)
+ {
+ parole_gst_change_state (gst, GST_STATE_PAUSED);
+ }
+ else if ( gst->priv->target == GST_STATE_READY)
+ {
+ parole_gst_draw_logo (gst);
+ }
+ break;
+ case GST_STATE_NULL:
+ g_signal_emit (G_OBJECT (gst), signals [MEDIA_STATE], 0,
+ gst->priv->stream, PAROLE_MEDIA_STATE_STOPPED);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+parole_gst_handle_element_message (ParoleGst *gst, GstMessage *message)
+{
+ if ( !message->structure )
+ goto out;
+
+ if ( gst_structure_has_name (message->structure, "prepare-xwindow-id") )
+ parole_gst_set_x_overlay (gst);
+out:
+ ;
+}
+
+static void
+parole_gst_get_meta_data (ParoleGst *gst, GstTagList *tag)
+{
+ gchar *str;
+
+ if ( gst_tag_list_get_string_index (tag, GST_TAG_TITLE, 0, &str) )
+ {
+ TRACE ("title:%s", str);
+ g_object_set (G_OBJECT (gst->priv->stream),
+ "title", str,
+ NULL);
+ g_free (str);
+ }
+
+ if ( gst_tag_list_get_string_index (tag, GST_TAG_ARTIST, 0, &str) )
+ {
+ TRACE ("artist:%s", str);
+ g_object_set (G_OBJECT (gst->priv->stream),
+ "artist", str,
+ NULL);
+ g_free (str);
+ }
+
+ if ( gst_tag_list_get_string_index (tag, GST_TAG_DATE, 0, &str) )
+ {
+ TRACE ("year:%s", str);
+ g_object_set (G_OBJECT (gst->priv->stream),
+ "year", str,
+ NULL);
+ g_free (str);
+ }
+
+ if ( gst_tag_list_get_string_index (tag, GST_TAG_ALBUM, 0, &str) )
+ {
+ TRACE ("album:%s", str);
+ g_object_set (G_OBJECT (gst->priv->stream),
+ "album", str,
+ NULL);
+ g_free (str);
+ }
+
+ if ( gst_tag_list_get_string_index (tag, GST_TAG_COMMENT, 0, &str) )
+ {
+ TRACE ("comment:%s", str);
+ g_object_set (G_OBJECT (gst->priv->stream),
+ "comment", str,
+ NULL);
+ g_free (str);
+ }
+
+ g_signal_emit (G_OBJECT (gst), signals [MEDIA_TAG], 0, gst->priv->stream);
+}
+
+static gboolean
+parole_gst_bus_event (GstBus *bus, GstMessage *msg, gpointer data)
+{
+ ParoleGst *gst;
+
+ gst = PAROLE_GST (data);
+
+ switch (GST_MESSAGE_TYPE (msg))
+ {
+ case GST_MESSAGE_EOS:
+ TRACE ("End of stream");
+ g_signal_emit (G_OBJECT (gst), signals [MEDIA_STATE], 0,
+ gst->priv->stream, PAROLE_MEDIA_STATE_FINISHED);
+ break;
+ case GST_MESSAGE_ERROR:
+ {
+ GError *error = NULL;
+ gchar *debug;
+ parole_gst_set_window_cursor (GTK_WIDGET (gst)->window, NULL);
+ gst->priv->target = GST_STATE_NULL;
+ parole_gst_change_state (gst, GST_STATE_NULL);
+ gst_message_parse_error (msg, &error, &debug);
+ TRACE ("*** ERROR %s : %s ***", error->message, debug);
+ g_signal_emit (G_OBJECT (gst), signals [ERROR], 0, error->message);
+ g_error_free (error);
+ g_free (debug);
+ break;
+ }
+ case GST_MESSAGE_BUFFERING:
+ {
+ gint per = 0;
+ gst_message_parse_buffering (msg, &per);
+ TRACE ("Buffering %d %%", per);
+ g_signal_emit (G_OBJECT (gst), signals [BUFFERING], 0,
+ gst->priv->stream, per);
+ break;
+ }
+ case GST_MESSAGE_STATE_CHANGED:
+ {
+ GstState old, new, pending;
+ gst_message_parse_state_changed (msg, &old, &new, &pending);
+
+ if ( GST_MESSAGE_SRC (msg) == GST_OBJECT (gst->priv->playbin) )
+ parole_gst_evaluate_state (gst, old, new, pending);
+ break;
+ }
+ case GST_MESSAGE_WARNING:
+ break;
+ case GST_MESSAGE_INFO:
+ TRACE ("Info message:");
+ break;
+ case GST_MESSAGE_TAG:
+ {
+ GstTagList *tag_list;
+
+ TRACE ("Tag message:");
+ gst_message_parse_tag (msg, &tag_list);
+ parole_gst_get_meta_data (gst, tag_list);
+ gst_tag_list_free (tag_list);
+ break;
+ }
+ case GST_MESSAGE_STATE_DIRTY:
+ TRACE ("Stream is dirty");
+ break;
+ case GST_MESSAGE_STEP_DONE:
+ break;
+ case GST_MESSAGE_CLOCK_PROVIDE:
+ break;
+ case GST_MESSAGE_CLOCK_LOST:
+ break;
+ case GST_MESSAGE_NEW_CLOCK:
+ break;
+ case GST_MESSAGE_STRUCTURE_CHANGE:
+ break;
+ case GST_MESSAGE_STREAM_STATUS:
+ TRACE ("Stream status");
+ break;
+ case GST_MESSAGE_APPLICATION:
+ TRACE ("Application message");
+ break;
+ case GST_MESSAGE_ELEMENT:
+ parole_gst_handle_element_message (gst, msg);
+ break;
+ case GST_MESSAGE_SEGMENT_START:
+ break;
+ case GST_MESSAGE_DURATION:
+ break;
+ case GST_MESSAGE_LATENCY:
+ break;
+ case GST_MESSAGE_ASYNC_START:
+ break;
+ case GST_MESSAGE_ASYNC_DONE:
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+static void
+parole_gst_change_state (ParoleGst *gst, GstState new)
+{
+ GstStateChangeReturn ret;
+
+ ret = gst_element_set_state (GST_ELEMENT (gst->priv->playbin), new);
+
+ switch (ret)
+ {
+ case GST_STATE_CHANGE_SUCCESS:
+ parole_gst_evaluate_state (gst,
+ GST_STATE_RETURN (gst->priv->playbin),
+ GST_STATE (gst->priv->playbin),
+ GST_STATE_PENDING (gst->priv->playbin));
+ break;
+ case GST_STATE_CHANGE_ASYNC:
+ TRACE ("State will change async");
+ break;
+ case GST_STATE_CHANGE_FAILURE:
+ gst->priv->target = GST_STATE_NULL;
+ parole_gst_change_state (gst, GST_STATE_NULL);
+ g_signal_emit (G_OBJECT (gst), signals [ERROR], 0, _("Error in changing state to ready"));
+ break;
+ case GST_STATE_CHANGE_NO_PREROLL:
+ TRACE ("State change no_preroll");
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+parole_gst_play_file_internal (ParoleGst *gst)
+{
+ ParoleMediaFile *file;
+
+ TRACE ("Start");
+
+ if ( G_UNLIKELY (GST_STATE (gst->priv->playbin) == GST_STATE_PLAYING ) )
+ {
+ TRACE ("*** Error *** This is a bug, playbin element is already playing");
+ }
+
+ g_object_get (G_OBJECT (gst->priv->stream),
+ "media-file", &file,
+ NULL);
+
+ g_object_set (G_OBJECT (gst->priv->playbin),
+ "uri", parole_media_file_get_uri (file),
+ "suburi", NULL,
+ NULL);
+
+ parole_gst_load_subtitle (gst);
+
+ parole_gst_change_state (gst, GST_STATE_PLAYING);
+ g_object_unref (file);
+}
+
+static void
+parole_gst_construct (GObject *object)
+{
+ ParoleGst *gst;
+ GstBus *bus;
+
+ gst = PAROLE_GST (object);
+
+ gst->priv->playbin = gst_element_factory_make ("playbin", "player");
+
+ if ( G_UNLIKELY (gst->priv->playbin == NULL) )
+ {
+ xfce_err (_("Unable to load playbin GStreamer plugin"
+ ", check your GStreamer installation"));
+
+ g_error ("playbin load failed");
+ }
+
+ gst->priv->video_sink = gst_element_factory_make ("xvimagesink", "video");
+
+ if ( G_UNLIKELY (gst->priv->video_sink == NULL) )
+ {
+ g_debug ("xvimagesink not found, trying to load ximagesink");
+ gst->priv->video_sink = gst_element_factory_make ("ximagesink", "video");
+
+ if ( G_UNLIKELY (gst->priv->video_sink == NULL) )
+ {
+ xfce_err (_("Unable to load video GStreamer plugin"
+ ", check your GStreamer installation"));
+ g_error ("ximagesink load failed");
+ }
+ }
+
+ parole_gst_update_vis (gst);
+
+ g_object_set (G_OBJECT (gst->priv->playbin),
+ "video-sink", gst->priv->video_sink,
+ NULL);
+
+ /*
+ * Listen to the bus events.
+ */
+ bus = gst_pipeline_get_bus (GST_PIPELINE (gst->priv->playbin));
+ gst_bus_add_watch (bus, parole_gst_bus_event, gst);
+ g_object_unref (bus);
+
+ parole_gst_load_logo (gst);
+
+ parole_gst_set_subtitle_encoding (gst);
+ parole_gst_set_subtitle_font (gst);
+}
+
+static gboolean
+parole_gst_motion_notify_event (GtkWidget *widget, GdkEventMotion *ev)
+{
+ ParoleGst *gst;
+ gboolean ret = FALSE;
+
+ gst = PAROLE_GST (widget);
+
+ g_timer_reset (gst->priv->hidecursor_timer);
+ parole_gst_set_cursor_visible (gst, TRUE);
+
+ if (GTK_WIDGET_CLASS (parole_gst_parent_class)->motion_notify_event)
+ ret |= GTK_WIDGET_CLASS (parole_gst_parent_class)->motion_notify_event (widget, ev);
+
+ return ret;
+}
+
+static void
+parole_gst_conf_notify_cb (GObject *object, GParamSpec *spec, ParoleGst *gst)
+{
+ if ( !g_strcmp0 ("vis-enabled", spec->name) || !g_strcmp0 ("vis-name", spec->name))
+ {
+ gst->priv->update = TRUE;
+ }
+ else if ( !g_strcmp0 ("subtitle-font", spec->name ) && gst->priv->state >= GST_STATE_PAUSED )
+ parole_gst_set_subtitle_font (gst);
+}
+
+static void
+parole_gst_class_init (ParoleGstClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->finalize = parole_gst_finalize;
+ object_class->constructed = parole_gst_construct;
+
+ widget_class->realize = parole_gst_realize;
+ widget_class->show = parole_gst_show;
+ widget_class->size_allocate = parole_gst_size_allocate;
+ widget_class->expose_event = parole_gst_expose_event;
+ widget_class->motion_notify_event = parole_gst_motion_notify_event;
+
+ signals[MEDIA_STATE] =
+ g_signal_new ("media-state",
+ PAROLE_TYPE_GST,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ParoleGstClass, media_state),
+ NULL, NULL,
+ _gmarshal_VOID__OBJECT_ENUM,
+ G_TYPE_NONE, 2,
+ PAROLE_TYPE_STREAM, ENUM_GTYPE_MEDIA_STATE);
+
+ signals[MEDIA_PROGRESSED] =
+ g_signal_new ("media-progressed",
+ PAROLE_TYPE_GST,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ParoleGstClass, media_progressed),
+ NULL, NULL,
+ _gmarshal_VOID__OBJECT_DOUBLE,
+ G_TYPE_NONE, 2,
+ G_TYPE_OBJECT, G_TYPE_DOUBLE);
+
+ signals [MEDIA_TAG] =
+ g_signal_new ("media-tag",
+ PAROLE_TYPE_GST,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ParoleGstClass, media_tag),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ G_TYPE_OBJECT);
+
+ signals[BUFFERING] =
+ g_signal_new ("buffering",
+ PAROLE_TYPE_GST,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ParoleGstClass, buffering),
+ NULL, NULL,
+ _gmarshal_VOID__OBJECT_INT,
+ G_TYPE_NONE, 2,
+ G_TYPE_OBJECT, G_TYPE_INT);
+
+ signals[ERROR] =
+ g_signal_new ("error",
+ PAROLE_TYPE_GST,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ParoleGstClass, error),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ g_type_class_add_private (klass, sizeof (ParoleGstPrivate));
+}
+
+static void
+parole_gst_init (ParoleGst *gst)
+{
+ gst->priv = PAROLE_GST_GET_PRIVATE (gst);
+
+ gst->priv->state = GST_STATE_VOID_PENDING;
+ gst->priv->target = GST_STATE_VOID_PENDING;
+ gst->priv->lock = g_mutex_new ();
+ gst->priv->stream = parole_stream_new ();
+ gst->priv->tick_id = 0;
+ gst->priv->hidecursor_timer = g_timer_new ();
+ gst->priv->update = FALSE;
+ gst->priv->vis_sink = NULL;
+
+ gst->priv->conf = parole_conf_new ();
+
+ g_signal_connect (G_OBJECT (gst->priv->conf), "notify",
+ G_CALLBACK (parole_gst_conf_notify_cb), gst);
+
+ GTK_WIDGET_SET_FLAGS (GTK_WIDGET (gst), GTK_CAN_FOCUS);
+
+ /*
+ * Disable double buffering on the video output to avoid
+ * flickering when resizing the window.
+ */
+ GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (gst), GTK_DOUBLE_BUFFERED);
+}
+
+GtkWidget *
+parole_gst_new (void)
+{
+ static gpointer parole_gst_object = NULL;
+
+ if ( G_LIKELY (parole_gst_object != NULL ) )
+ {
+ //g_object_ref (parole_gst_object);
+ }
+ else
+ {
+ parole_gst_object = g_object_new (PAROLE_TYPE_GST, NULL);
+ g_object_add_weak_pointer (parole_gst_object, &parole_gst_object);
+ }
+
+ return GTK_WIDGET (parole_gst_object);
+}
+
+void parole_gst_play_file (ParoleGst *gst, ParoleMediaFile *file)
+{
+ g_mutex_lock (gst->priv->lock);
+
+ gst->priv->target = GST_STATE_PLAYING;
+
+ parole_stream_init_properties (gst->priv->stream);
+
+ g_object_set (G_OBJECT (gst->priv->stream),
+ "media-file", g_object_ref (file),
+ NULL);
+
+ g_mutex_unlock (gst->priv->lock);
+
+ parole_window_busy_cursor (GTK_WIDGET (gst)->window);
+
+ if ( gst->priv->state < GST_STATE_PAUSED )
+ parole_gst_play_file_internal (gst);
+ else if ( gst->priv->update )
+ parole_gst_change_state (gst, GST_STATE_NULL);
+ else
+ parole_gst_change_state (gst, GST_STATE_READY);
+}
+
+void parole_gst_pause (ParoleGst *gst)
+{
+ g_mutex_lock (gst->priv->lock);
+
+ gst->priv->target = GST_STATE_PAUSED;
+
+ g_mutex_unlock (gst->priv->lock);
+
+ parole_window_busy_cursor (GTK_WIDGET (gst)->window);
+ parole_gst_change_state (gst, GST_STATE_PAUSED);
+}
+
+void parole_gst_resume (ParoleGst *gst)
+{
+ g_mutex_lock (gst->priv->lock);
+
+ gst->priv->target = GST_STATE_PLAYING;
+
+ g_mutex_unlock (gst->priv->lock);
+
+ parole_window_busy_cursor (GTK_WIDGET (gst)->window);
+ parole_gst_change_state (gst, GST_STATE_PLAYING);
+}
+
+void parole_gst_stop (ParoleGst *gst)
+{
+ g_mutex_lock (gst->priv->lock);
+
+ parole_stream_init_properties (gst->priv->stream);
+ gst->priv->target = GST_STATE_READY;
+
+ g_mutex_unlock (gst->priv->lock);
+
+ parole_window_busy_cursor (GTK_WIDGET (gst)->window);
+
+ parole_gst_change_state (gst, GST_STATE_READY);
+}
+
+void parole_gst_null_state (ParoleGst *gst)
+{
+ g_mutex_lock (gst->priv->lock);
+
+ parole_stream_init_properties (gst->priv->stream);
+ gst->priv->target = GST_STATE_NULL;
+
+ g_mutex_unlock (gst->priv->lock);
+
+ parole_window_busy_cursor (GTK_WIDGET (gst)->window);
+
+ parole_gst_change_state (gst, GST_STATE_NULL);
+}
+
+void parole_gst_seek (ParoleGst *gst, gdouble pos)
+{
+ gint64 seek;
+ gint64 absolute_duration;
+ gdouble duration;
+ gboolean seekable;
+ gboolean ret;
+
+ TRACE ("Seeking");
+
+ g_object_get (G_OBJECT (gst->priv->stream),
+ "absolute-duration", &absolute_duration,
+ "duration", &duration,
+ "seekable", &seekable,
+ NULL);
+
+#ifdef DEBUG
+ g_return_if_fail (duration != 0);
+ g_return_if_fail (absolute_duration != 0);
+ g_return_if_fail (seekable == TRUE);
+#endif
+
+ seek = (gint64) (pos * absolute_duration) / duration;
+
+ ret = gst_element_seek (gst->priv->playbin,
+ 1.0,
+ GST_FORMAT_TIME,
+ GST_SEEK_FLAG_KEY_UNIT | GST_SEEK_FLAG_FLUSH,
+ GST_SEEK_TYPE_SET, seek,
+ GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
+
+ if ( !ret )
+ {
+ g_warning ("Failed to seek element");
+ }
+}
+
+void parole_gst_set_volume (ParoleGst *gst, gdouble value)
+{
+ g_object_set (G_OBJECT (gst->priv->playbin),
+ "volume", value,
+ NULL);
+}
+
+gdouble parole_gst_get_volume (ParoleGst *gst)
+{
+ gdouble volume;
+
+ g_object_get (G_OBJECT (gst->priv->playbin),
+ "volume", &volume,
+ NULL);
+ return volume;
+}
Added: parole/trunk/parole/parole-gst.h
===================================================================
--- parole/trunk/parole/parole-gst.h (rev 0)
+++ parole/trunk/parole/parole-gst.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,106 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PAROLE_GST_H
+#define __PAROLE_GST_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "parole-stream.h"
+#include "parole-mediafile.h"
+
+G_BEGIN_DECLS
+
+#define PAROLE_TYPE_GST (parole_gst_get_type () )
+#define PAROLE_GST(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_GST, ParoleGst))
+#define PAROLE_IS_GST(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_GST))
+
+/*
+ * Keep this order to be compatible with the ParoleState enum
+ * used by the plugin interface.
+ */
+typedef enum /*< prefix=PAROLE_MEDIA_STATE_ >*/
+{
+ PAROLE_MEDIA_STATE_STOPPED,
+ PAROLE_MEDIA_STATE_FINISHED,
+ PAROLE_MEDIA_STATE_PAUSED,
+ PAROLE_MEDIA_STATE_PLAYING
+
+} ParoleMediaState;
+
+typedef struct ParoleGstPrivate ParoleGstPrivate;
+
+typedef struct
+{
+ GtkWidget parent;
+ ParoleGstPrivate *priv;
+
+} ParoleGst;
+
+typedef struct
+{
+ GtkWidgetClass parent_class;
+
+ void (*media_state) (ParoleGst *gst,
+ const ParoleStream *stream,
+ ParoleMediaState state);
+
+ void (*media_progressed) (ParoleGst *gst,
+ const ParoleStream *stream,
+ gdouble value);
+
+ void (*buffering) (ParoleGst *gst,
+ const ParoleStream *stream,
+ gint percentage);
+
+ void (*media_tag) (ParoleGst *gst,
+ const ParoleStream *stream);
+
+ void (*error) (ParoleGst *gst,
+ const gchar *error);
+
+} ParoleGstClass;
+
+GType parole_gst_get_type (void) G_GNUC_CONST;
+GtkWidget *parole_gst_new (void);
+
+void parole_gst_play_file (ParoleGst *gst,
+ ParoleMediaFile *file);
+
+void parole_gst_pause (ParoleGst *gst);
+
+void parole_gst_resume (ParoleGst *gst);
+
+void parole_gst_stop (ParoleGst *gst);
+
+void parole_gst_null_state (ParoleGst *gst);
+
+void parole_gst_seek (ParoleGst *gst,
+ gdouble pos);
+
+void parole_gst_set_volume (ParoleGst *gst,
+ gdouble value);
+
+gdouble parole_gst_get_volume (ParoleGst *gst);
+
+G_END_DECLS
+
+#endif /* __PAROLE_GST_H */
Added: parole/trunk/parole/parole-mediachooser.c
===================================================================
--- parole/trunk/parole/parole-mediachooser.c (rev 0)
+++ parole/trunk/parole/parole-mediachooser.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,333 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <glib.h>
+
+#include <libxfce4util/libxfce4util.h>
+#include <libxfcegui4/libxfcegui4.h>
+
+#include "common/parole-builder.h"
+#include "interfaces/mediachooser_ui.h"
+#include "interfaces/openlocation_ui.h"
+
+#include "parole-mediachooser.h"
+
+#include "parole-mediafile.h"
+#include "parole-filters.h"
+#include "parole-rc-utils.h"
+#include "parole-utils.h"
+
+
+/*
+ * GtkBuilder Callbacks
+ */
+void parole_media_chooser_open (GtkWidget *widget,
+ ParoleMediaChooser *chooser);
+
+void parole_media_chooser_close (GtkWidget *widget,
+ ParoleMediaChooser *chooser);
+
+void media_chooser_folder_changed_cb (GtkWidget *widget,
+ gpointer data);
+
+void parole_media_chooser_open_location_cb (GtkButton *bt,
+ ParoleMediaChooser *chooser);
+
+#define MEDIA_CHOOSER_INTERFACE_FILE INTERFACES_DIR "/mediachooser.ui"
+#define OPEN_LOCATION_INTERFACE_FILE INTERFACES_DIR "/openlocation.ui"
+
+enum
+{
+ MEDIA_FILES_OPENED,
+ MEDIA_FILE_OPENED,
+ LOCATION_OPENED,
+ LAST_SIGNAL
+};
+
+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));
+}
+
+void
+media_chooser_folder_changed_cb (GtkWidget *widget, gpointer data)
+{
+ gchar *folder;
+ folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (widget));
+
+ if ( folder )
+ {
+ parole_rc_write_entry_string ("media-chooser-folder", folder);
+ g_free (folder);
+ }
+}
+
+static void
+parole_media_chooser_add_many (ParoleMediaChooser *chooser, GtkWidget *file_chooser)
+{
+ GSList *files;
+ GtkFileFilter *filter;
+ gchar *file;
+ guint i;
+ guint len;
+
+ files = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (file_chooser));
+ filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (file_chooser));
+
+ if ( G_UNLIKELY (files == NULL) )
+ return;
+
+ len = g_slist_length (files);
+
+ for ( i = 0; i < len; i++)
+ {
+ GSList *media_files = NULL;
+ file = g_slist_nth_data (files, i);
+ parole_get_media_files (filter, file, &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)
+{
+ ParoleMediaFile *file;
+ GtkWidget *file_chooser;
+ gboolean multiple;
+ gchar *filename;
+
+ file_chooser = GTK_WIDGET (g_object_get_data (G_OBJECT (chooser), "file-chooser"));
+
+ multiple = gtk_file_chooser_get_select_multiple (GTK_FILE_CHOOSER (file_chooser));
+
+ /*
+ * Emit one file opened
+ */
+ if ( multiple == FALSE )
+ {
+ filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));
+
+ if ( G_LIKELY (filename != NULL ) )
+ {
+ file = parole_media_file_new (filename);
+ g_signal_emit (G_OBJECT (chooser), signals [MEDIA_FILE_OPENED], 0, file);
+ g_free (filename);
+ }
+ parole_media_chooser_close (NULL, chooser);
+ }
+ else
+ {
+ parole_window_busy_cursor (GTK_WIDGET (chooser)->window);
+ parole_media_chooser_add_many (chooser, file_chooser);
+ parole_media_chooser_close (NULL, chooser);
+ }
+}
+
+void
+parole_media_chooser_open_location_cb (GtkButton *bt, ParoleMediaChooser *chooser)
+{
+ ParoleMediaFile *file;
+ GtkWidget *entry;
+ const gchar *location;
+
+ entry = GTK_WIDGET (g_object_get_data (G_OBJECT (chooser), "entry"));
+ location = gtk_entry_get_text (GTK_ENTRY (entry));
+
+ if ( !location || strlen (location) == 0)
+ goto out;
+
+ TRACE ("Location %s", location);
+
+ file = parole_media_file_new (location);
+ gtk_widget_hide (GTK_WIDGET (chooser));
+ g_signal_emit (G_OBJECT (chooser), signals [MEDIA_FILE_OPENED], 0, file);
+out:
+ parole_media_chooser_close (NULL, chooser);
+}
+
+static void
+parole_media_chooser_open_internal (GtkWidget *chooser, gboolean multiple)
+{
+ ParoleMediaChooser *media_chooser;
+ GtkWidget *vbox;
+ GtkWidget *file_chooser;
+ GtkBuilder *builder;
+ GtkWidget *open;
+ GtkWidget *img;
+ 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"));
+
+ vbox = GTK_WIDGET (gtk_builder_get_object (builder, "vbox"));
+ open = GTK_WIDGET (gtk_builder_get_object (builder, "open"));
+
+ gtk_window_set_title (GTK_WINDOW (chooser), multiple == TRUE ? _("Add media files") : _("Open media file"));
+
+ 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 ());
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (file_chooser), parole_get_supported_video_filter ());
+
+ folder = parole_rc_read_entry_string ("media-chooser-folder", NULL);
+
+ if ( folder )
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (file_chooser), folder);
+
+ gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (file_chooser), multiple);
+
+ img = gtk_image_new_from_stock (multiple ? GTK_STOCK_ADD : GTK_STOCK_OPEN, GTK_ICON_SIZE_BUTTON);
+
+ g_object_set (G_OBJECT (open),
+ "image", img,
+ "label", multiple ? _("Add") : _("Open"),
+ NULL);
+
+ g_object_set_data (G_OBJECT (chooser), "file-chooser", file_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 (parole_media_chooser_close), chooser);
+
+ g_object_unref (builder);
+}
+
+static void
+parole_media_chooser_open_location_internal (GtkWidget *chooser)
+{
+ GtkBuilder *builder;
+ GtkWidget *vbox;
+ GtkWidget *open;
+ GtkWidget *entry;
+
+ builder = parole_builder_new_from_string (openlocation_ui, openlocation_ui_length);
+
+ vbox = GTK_WIDGET (gtk_builder_get_object (builder, "vbox"));
+ entry = GTK_WIDGET (gtk_builder_get_object (builder, "entry"));
+ open = GTK_WIDGET (gtk_builder_get_object (builder, "open"));
+
+ g_object_set_data (G_OBJECT (chooser), "entry", entry);
+
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (chooser)->vbox), vbox);
+
+ gtk_builder_connect_signals (builder, chooser);
+ g_signal_connect (chooser, "destroy",
+ G_CALLBACK (parole_media_chooser_close), chooser);
+ g_object_unref (builder);
+}
+
+static void
+parole_media_chooser_finalize (GObject *object)
+{
+ ParoleMediaChooser *parole_media_chooser;
+
+ parole_media_chooser = PAROLE_MEDIA_CHOOSER (object);
+
+ G_OBJECT_CLASS (parole_media_chooser_parent_class)->finalize (object);
+}
+
+static void
+parole_media_chooser_class_init (ParoleMediaChooserClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ signals[MEDIA_FILES_OPENED] =
+ g_signal_new("media-files-opened",
+ PAROLE_TYPE_MEDIA_CHOOSER,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ParoleMediaChooserClass, media_files_opened),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+
+ signals[MEDIA_FILE_OPENED] =
+ g_signal_new("media-file-opened",
+ PAROLE_TYPE_MEDIA_CHOOSER,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ParoleMediaChooserClass, media_file_opened),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_OBJECT);
+
+ object_class->finalize = parole_media_chooser_finalize;
+}
+
+static void
+parole_media_chooser_init (ParoleMediaChooser *chooser)
+{
+ gtk_window_set_modal (GTK_WINDOW (chooser), TRUE);
+}
+
+static GtkWidget *
+parole_media_chooser_new (GtkWidget *parent)
+{
+ ParoleMediaChooser *chooser;
+
+ chooser = g_object_new (PAROLE_TYPE_MEDIA_CHOOSER, NULL);
+
+ if ( parent )
+ gtk_window_set_transient_for (GTK_WINDOW (chooser), GTK_WINDOW (parent));
+
+ return GTK_WIDGET (chooser);
+}
+
+GtkWidget *parole_media_chooser_open_local (GtkWidget *parent, gboolean multiple)
+{
+ GtkWidget *dialog;
+
+ dialog = parole_media_chooser_new (parent);
+
+ parole_media_chooser_open_internal (dialog, multiple);
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 680, 480);
+
+ return dialog;
+}
+
+GtkWidget *parole_media_chooser_open_location (GtkWidget *parent)
+{
+ GtkWidget *dialog;
+
+ dialog = parole_media_chooser_new (parent);
+
+ parole_media_chooser_open_location_internal (dialog);
+
+ return dialog;
+}
Added: parole/trunk/parole/parole-mediachooser.h
===================================================================
--- parole/trunk/parole/parole-mediachooser.h (rev 0)
+++ parole/trunk/parole/parole-mediachooser.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,64 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PAROLE_MEDIA_CHOOSER_H
+#define __PAROLE_MEDIA_CHOOSER_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "parole-mediafile.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,
+ GPtrArray *array);
+
+ void (*media_file_opened) (ParoleMediaChooser *chooser,
+ ParoleMediaFile *file);
+
+} ParoleMediaChooserClass;
+
+GType parole_media_chooser_get_type (void) G_GNUC_CONST;
+
+GtkWidget *parole_media_chooser_open_local (GtkWidget *parent,
+ gboolean multiple);
+
+GtkWidget *parole_media_chooser_open_location (GtkWidget *parent);
+
+G_END_DECLS
+
+#endif /* __PAROLE_MEDIA_CHOOSER_H */
Added: parole/trunk/parole/parole-mediafile.c
===================================================================
--- parole/trunk/parole/parole-mediafile.c (rev 0)
+++ parole/trunk/parole/parole-mediafile.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,333 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include "parole-mediafile.h"
+
+#define PAROLE_MEDIA_FILE_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_MEDIA_FILE, ParoleMediaFilePrivate))
+
+typedef struct _ParoleMediaFilePrivate ParoleMediaFilePrivate;
+
+struct _ParoleMediaFilePrivate
+{
+ gchar *filename;
+ gchar *display_name;
+ gchar *uri;
+ gchar *content_type;
+
+};
+
+enum
+{
+ PROP_0,
+ PROP_PATH,
+ PROP_DISPLAY_NAME,
+ PROP_URI,
+ PROP_CONTENT_TYPE
+};
+
+G_DEFINE_TYPE (ParoleMediaFile, parole_media_file, G_TYPE_OBJECT)
+
+static void
+parole_media_file_finalize (GObject *object)
+{
+ ParoleMediaFile *file;
+ ParoleMediaFilePrivate *priv;
+
+ file = PAROLE_MEDIA_FILE (object);
+ priv = PAROLE_MEDIA_FILE_GET_PRIVATE (file);
+
+ g_debug ("media file object finalized %s", priv->display_name);
+
+ if ( priv->filename )
+ g_free (priv->filename);
+
+ if ( priv->uri )
+ g_free (priv->uri);
+
+ if ( priv->display_name )
+ g_free (priv->display_name);
+
+ if ( priv->content_type )
+ g_free (priv->content_type);
+
+ G_OBJECT_CLASS (parole_media_file_parent_class)->finalize (object);
+}
+
+static void
+parole_media_file_set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ ParoleMediaFile *file;
+ file = PAROLE_MEDIA_FILE (object);
+
+ switch (prop_id)
+ {
+ case PROP_PATH:
+ PAROLE_MEDIA_FILE_GET_PRIVATE (file)->filename = g_strdup (g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+parole_media_file_get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ ParoleMediaFile *file;
+
+ file = PAROLE_MEDIA_FILE (object);
+
+ switch (prop_id)
+ {
+ case PROP_PATH:
+ g_value_set_string (value, PAROLE_MEDIA_FILE_GET_PRIVATE (file)->filename);
+ break;
+ case PROP_URI:
+ g_value_set_string (value, PAROLE_MEDIA_FILE_GET_PRIVATE (file)->filename);
+ break;
+ case PROP_CONTENT_TYPE:
+ g_value_set_string (value, PAROLE_MEDIA_FILE_GET_PRIVATE (file)->content_type);
+ break;
+ case PROP_DISPLAY_NAME:
+ g_value_set_string (value, PAROLE_MEDIA_FILE_GET_PRIVATE (file)->display_name);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+parole_media_file_constructed (GObject *object)
+{
+ GFile *gfile;
+ GFileInfo *info;
+ ParoleMediaFile *file;
+ ParoleMediaFilePrivate *priv;
+ GError *error = NULL;
+
+ file = PAROLE_MEDIA_FILE (object);
+ priv = PAROLE_MEDIA_FILE_GET_PRIVATE (file);
+
+ gfile = g_file_new_for_commandline_arg (priv->filename);
+
+ info = g_file_query_info (gfile,
+ "standard::*,",
+ 0,
+ NULL,
+ &error);
+
+ if ( error )
+ {
+ if ( G_LIKELY (error->code == G_IO_ERROR_NOT_SUPPORTED) )
+ {
+ g_error_free (error);
+ priv->display_name = g_file_get_basename (gfile);
+ }
+ else
+ {
+ priv->display_name = g_strdup (priv->filename);
+ }
+ g_warning ("Unable to read file info %s", error->message);
+ goto out;
+ }
+
+ priv->display_name = g_strdup (g_file_info_get_display_name (info));
+ priv->content_type = g_strdup (g_file_info_get_content_type (info));
+
+ g_object_unref (info);
+out:
+ priv->uri = g_file_get_uri (gfile);
+ g_object_unref (gfile);
+}
+
+static void
+parole_media_file_class_init (ParoleMediaFileClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = parole_media_file_finalize;
+
+ object_class->constructed = parole_media_file_constructed;
+ object_class->set_property = parole_media_file_set_property;
+ object_class->get_property = parole_media_file_get_property;
+
+ /**
+ * ParoleMediaFile:filename:
+ *
+ * The filename of the file.
+ *
+ * Since: 0.1
+ **/
+ g_object_class_install_property (object_class,
+ PROP_PATH,
+ g_param_spec_string ("filename",
+ NULL, NULL,
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY|
+ G_PARAM_READWRITE));
+
+ /**
+ * ParoleMediaFile:display-name:
+ *
+ * a UTF-8 name that can be displayed in the UI.
+ *
+ * Since: 0.1
+ **/
+ g_object_class_install_property (object_class,
+ PROP_DISPLAY_NAME,
+ g_param_spec_string ("display-name",
+ NULL, NULL,
+ NULL,
+ G_PARAM_READABLE));
+
+ /**
+ * ParoleMediaFile:uri:
+ *
+ * The Uri of the file.
+ *
+ * Since: 0.1
+ **/
+ g_object_class_install_property (object_class,
+ PROP_URI,
+ g_param_spec_string ("uri",
+ NULL, NULL,
+ NULL,
+ G_PARAM_READABLE));
+
+ /**
+ * ParoleMediaFile:content-type:
+ *
+ * The content type of the file.
+ *
+ * Since: 0.1
+ **/
+ g_object_class_install_property (object_class,
+ PROP_CONTENT_TYPE,
+ g_param_spec_string ("content-type",
+ NULL, NULL,
+ NULL,
+ G_PARAM_READABLE));
+
+ g_type_class_add_private (klass, sizeof (ParoleMediaFilePrivate));
+}
+
+static void
+parole_media_file_init (ParoleMediaFile *file)
+{
+ ParoleMediaFilePrivate *priv;
+
+ priv = PAROLE_MEDIA_FILE_GET_PRIVATE (file);
+
+ priv->filename = NULL;
+ priv->display_name = NULL;
+ priv->uri = NULL;
+ priv->content_type = NULL;
+}
+
+/**
+ * parole_media_file_new:
+ * @filename: filename.
+ *
+ *
+ *
+ * Returns: A new #ParoleMediaFile object.
+ **/
+ParoleMediaFile *
+parole_media_file_new (const gchar *filename)
+{
+ ParoleMediaFile *file = NULL;
+ file = g_object_new (PAROLE_TYPE_MEDIA_FILE, "filename", filename, NULL);
+ return file;
+}
+
+/**
+ * parole_media_file_get_file_name:
+ * @file: a #ParoleMediaFile.
+ *
+ *
+ * Returns: A string containing the file name.
+ **/
+const gchar *
+parole_media_file_get_file_name (const ParoleMediaFile *file)
+{
+ g_return_val_if_fail (PAROLE_IS_MEDIA_FILE (file), NULL);
+
+ return PAROLE_MEDIA_FILE_GET_PRIVATE (file)->filename;
+}
+
+/**
+ * parole_media_file_get_display_name:
+ * @file: a #ParoleMediaFile.
+ *
+ *
+ * Returns: A string containing the display name.
+ **/
+const gchar *
+parole_media_file_get_display_name (const ParoleMediaFile *file)
+{
+ g_return_val_if_fail (PAROLE_IS_MEDIA_FILE (file), NULL);
+
+ return PAROLE_MEDIA_FILE_GET_PRIVATE (file)->display_name;
+}
+
+/**
+ * parole_media_file_get_uri:
+ * @file: a #ParoleMediaFile.
+ *
+ *
+ * Returns: A string containing the file uri.
+ **/
+const gchar *
+parole_media_file_get_uri (const ParoleMediaFile *file)
+{
+ g_return_val_if_fail (PAROLE_IS_MEDIA_FILE (file), NULL);
+
+ return PAROLE_MEDIA_FILE_GET_PRIVATE (file)->uri;
+}
+
+/**
+ * parole_media_file_get_content_type:
+ * @file: a #ParoleMediaFile.
+ *
+ *
+ * Returns: A string containing the content type of the file.
+ **/
+const gchar *
+parole_media_file_get_content_type (const ParoleMediaFile *file)
+{
+ g_return_val_if_fail (PAROLE_IS_MEDIA_FILE (file), NULL);
+
+ return PAROLE_MEDIA_FILE_GET_PRIVATE (file)->content_type;
+}
Added: parole/trunk/parole/parole-mediafile.h
===================================================================
--- parole/trunk/parole/parole-mediafile.h (rev 0)
+++ parole/trunk/parole/parole-mediafile.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,59 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PAROLE_MEDIA_FILE_H
+#define __PAROLE_MEDIA_FILE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define PAROLE_TYPE_MEDIA_FILE (parole_media_file_get_type () )
+#define PAROLE_MEDIA_FILE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_MEDIA_FILE, ParoleMediaFile))
+#define PAROLE_IS_MEDIA_FILE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_MEDIA_FILE))
+
+typedef struct _ParoleMediaFile ParoleMediaFile;
+typedef struct _ParoleMediaFileClass ParoleMediaFileClass;
+
+struct _ParoleMediaFile
+{
+ GObject parent;
+};
+
+struct _ParoleMediaFileClass
+{
+ GObjectClass parent_class;
+};
+
+GType parole_media_file_get_type (void) G_GNUC_CONST;
+
+ParoleMediaFile *parole_media_file_new (const gchar *filename);
+
+const gchar G_CONST_RETURN *parole_media_file_get_file_name (const ParoleMediaFile *file) G_GNUC_PURE;
+
+const gchar G_CONST_RETURN *parole_media_file_get_display_name (const ParoleMediaFile *file) G_GNUC_PURE;
+
+const gchar G_CONST_RETURN *parole_media_file_get_uri (const ParoleMediaFile *file) G_GNUC_PURE;
+
+const gchar G_CONST_RETURN *parole_media_file_get_content_type (const ParoleMediaFile *file) G_GNUC_PURE;
+
+G_END_DECLS
+
+#endif /* __PAROLE_MEDIA_FILE_H */
Added: parole/trunk/parole/parole-medialist.c
===================================================================
--- parole/trunk/parole/parole-medialist.c (rev 0)
+++ parole/trunk/parole/parole-medialist.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,695 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <libxfce4util/libxfce4util.h>
+#include <libxfcegui4/libxfcegui4.h>
+
+#include "common/parole-builder.h"
+#include "interfaces/playlist_ui.h"
+
+#include "parole-medialist.h"
+#include "parole-mediafile.h"
+#include "parole-mediachooser.h"
+
+#include "parole-filters.h"
+#include "parole-utils.h"
+#include "parole-dbus.h"
+
+static void parole_media_list_dbus_class_init (ParoleMediaListClass *klass);
+static void parole_media_list_dbus_init (ParoleMediaList *list);
+
+/*
+ * Callbacks for GtkBuilder
+ */
+void parole_media_list_media_up_clicked_cb (GtkButton *button,
+ ParoleMediaList *list);
+
+void parole_media_list_media_down_clicked_cb (GtkButton *button,
+ ParoleMediaList *list);
+
+void parole_media_list_add_clicked_cb (GtkButton *button,
+ ParoleMediaList *list);
+
+void parole_media_list_remove_clicked_cb (GtkButton *button,
+ ParoleMediaList *list);
+
+void parole_media_list_row_activated_cb (GtkTreeView *view,
+ GtkTreePath *path,
+ GtkTreeViewColumn *col,
+ ParoleMediaList *list);
+
+void parole_media_list_cursor_changed_cb (GtkTreeView *view,
+ ParoleMediaList *list);
+
+gboolean parole_media_list_button_release_event (GtkWidget *widget,
+ GdkEventButton *ev,
+ ParoleMediaList *list);
+
+void parole_media_list_drag_data_received_cb (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ GtkSelectionData *data,
+ guint info,
+ guint drag_time,
+ ParoleMediaList *list);
+/*
+ * End of GtkBuilder callbacks
+ */
+
+
+#define PLAYLIST_FILE INTERFACES_DIR "/playlist.ui"
+
+#define PAROLE_MEDIA_LIST_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_MEDIA_LIST, ParoleMediaListPrivate))
+
+struct ParoleMediaListPrivate
+{
+ GtkWidget *view;
+ GtkWidget *box;
+ GtkListStore *store;
+};
+
+enum
+{
+ MEDIA_ACTIVATED,
+ MEDIA_CURSOR_CHANGED,
+ LAST_SIGNAL
+};
+
+static GtkTargetEntry target_entry[] =
+{
+ { "STRING", 0, 0 },
+ { "text/uri-list", 0, 1 },
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (ParoleMediaList, parole_media_list, GTK_TYPE_VBOX)
+
+static void
+parole_media_list_add (ParoleMediaList *list, ParoleMediaFile *file, gboolean emit)
+{
+ GtkListStore *list_store;
+ GtkTreePath *path;
+ GtkTreeRowReference *row;
+ GtkTreeIter iter;
+
+ list_store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (list->priv->view)));
+
+ gtk_list_store_append (list_store, &iter);
+
+ gtk_list_store_set (list_store,
+ &iter,
+ NAME_COL, parole_media_file_get_display_name (file),
+ DATA_COL, file,
+ -1);
+
+ if ( emit )
+ {
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (list_store), &iter);
+ row = gtk_tree_row_reference_new (GTK_TREE_MODEL (list_store), path);
+ gtk_tree_path_free (path);
+ g_signal_emit (G_OBJECT (list), signals [MEDIA_ACTIVATED], 0, row);
+ }
+ /*
+ * Unref it as the list store will have
+ * a reference anyway.
+ */
+ g_object_unref (file);
+}
+
+static void
+parole_media_list_file_opened_cb (ParoleMediaChooser *chooser, ParoleMediaFile *file, ParoleMediaList *list)
+{
+ parole_media_list_add (list, file, TRUE);
+}
+
+static void
+parole_media_list_files_opened_cb (ParoleMediaChooser *chooser, GSList *files, ParoleMediaList *list)
+{
+ ParoleMediaFile *file;
+ guint len;
+ guint i;
+
+ len = g_slist_length (files);
+
+ for ( i = 0; i < len; i++)
+ {
+ file = g_slist_nth_data (files, i);
+ parole_media_list_add (list, file, FALSE);
+ }
+}
+
+static void
+parole_media_list_open_internal (ParoleMediaList *list, gboolean multiple)
+{
+ GtkWidget *chooser;
+
+ chooser = parole_media_chooser_open_local (gtk_widget_get_toplevel (GTK_WIDGET (list)),
+ multiple);
+
+ if ( multiple )
+ g_signal_connect (G_OBJECT (chooser), "media_files_opened",
+ G_CALLBACK (parole_media_list_files_opened_cb), list);
+ else
+ g_signal_connect (G_OBJECT (chooser), "media_file_opened",
+ G_CALLBACK (parole_media_list_file_opened_cb), list);
+
+ gtk_widget_show_all (GTK_WIDGET (chooser));
+}
+
+static void
+parole_media_list_open_location_internal (ParoleMediaList *list)
+{
+ GtkWidget *chooser;
+
+ chooser = parole_media_chooser_open_location (gtk_widget_get_toplevel (GTK_WIDGET (list)));
+
+ g_signal_connect (G_OBJECT (chooser), "media_file_opened",
+ G_CALLBACK (parole_media_list_file_opened_cb), list);
+
+ gtk_widget_show_all (GTK_WIDGET (chooser));
+}
+
+static gboolean
+parole_media_list_add_by_path (ParoleMediaList *list, const gchar *path, gboolean emit)
+{
+ GSList *file_list = NULL;
+ GtkFileFilter *filter;
+ ParoleMediaFile *file;
+ guint len;
+ gboolean ret = FALSE;
+
+ filter = parole_get_supported_media_filter ();
+ g_object_ref_sink (filter);
+
+ parole_get_media_files (filter, path, &file_list);
+
+ for ( len = 0; len < g_slist_length (file_list); len++)
+ {
+ file = g_slist_nth_data (file_list, len);
+ parole_media_list_add (list, file, len == 0 ? emit : FALSE);
+ ret = TRUE;
+ }
+
+ g_object_unref (filter);
+ g_slist_free (file_list);
+ return ret;
+}
+
+void parole_media_list_drag_data_received_cb (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ GtkSelectionData *data,
+ guint info,
+ guint drag_time,
+ ParoleMediaList *list)
+{
+ gchar **uri_list;
+ gchar *path;
+ guint i;
+ guint added = 0;
+
+ parole_window_busy_cursor (GTK_WIDGET (list)->window);
+
+ 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);
+ if ( parole_media_list_add_by_path (list, path, i == 0 ? TRUE : FALSE) )
+ added++;
+
+ g_free (path);
+ }
+
+ g_strfreev (uri_list);
+
+ gdk_window_set_cursor (GTK_WIDGET (list)->window, NULL);
+ gtk_drag_finish (drag_context, added == i ? TRUE : FALSE, FALSE, drag_time);
+}
+
+void
+parole_media_list_add_clicked_cb (GtkButton *button, ParoleMediaList *list)
+{
+ parole_media_list_open_internal (list, TRUE);
+}
+
+void
+parole_media_list_remove_clicked_cb (GtkButton *button, ParoleMediaList *list)
+{
+ GtkTreeSelection *sel;
+ GtkTreeIter iter;
+
+ sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (list->priv->view));
+
+ if ( !gtk_tree_selection_get_selected (sel, NULL, &iter) )
+ return;
+
+ gtk_list_store_remove (list->priv->store,
+ &iter);
+
+ /*
+ * Returns the number of children that iter has.
+ * As a special case, if iter is NULL,
+ * then the number of toplevel nodes is returned. Gtk API doc.
+ */
+ if ( gtk_tree_model_iter_n_children (GTK_TREE_MODEL (list->priv->store), NULL) == 0 )
+ /*
+ * Will emit the signal media_cursor_changed with FALSE because there is no any
+ * row remaining so the player can disable click on the play button.
+ */
+ g_signal_emit (G_OBJECT (list), signals [MEDIA_CURSOR_CHANGED], 0, FALSE);
+}
+
+void
+parole_media_list_media_down_clicked_cb (GtkButton *button, ParoleMediaList *list)
+{
+ GtkTreeSelection *sel;
+ GtkTreeIter iter;
+ GtkTreeIter *pos_iter;
+
+ sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (list->priv->view));
+
+ if ( !gtk_tree_selection_get_selected (sel, NULL, &iter) )
+ return;
+
+ /* Save the selected iter to the selected row */
+ pos_iter = gtk_tree_iter_copy (&iter);
+
+ /* We are on the last node in the list!*/
+ if ( !gtk_tree_model_iter_next (GTK_TREE_MODEL (list->priv->store), &iter) )
+ {
+ /* Return false if tree is empty*/
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list->priv->store), &iter))
+ {
+ gtk_list_store_move_before (GTK_LIST_STORE (list->priv->store), pos_iter, &iter);
+ }
+ }
+ else
+ {
+ gtk_list_store_move_after (GTK_LIST_STORE (list->priv->store), pos_iter, &iter);
+ }
+
+ gtk_tree_iter_free (pos_iter);
+}
+
+void
+parole_media_list_media_up_clicked_cb (GtkButton *button, ParoleMediaList *list)
+{
+ GtkTreeSelection *sel;
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ GtkTreeIter *pos_iter;
+
+ sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (list->priv->view));
+
+ if ( !gtk_tree_selection_get_selected (sel, NULL, &iter) )
+ return;
+
+ /* Save the selected iter to the selected row */
+ pos_iter = gtk_tree_iter_copy (&iter);
+
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (list->priv->store), &iter);
+
+ /* We are on the top of the list */
+ if ( !gtk_tree_path_prev (path) )
+ {
+ /* Passing NULL as the last argument will cause this call to move
+ * the iter to the end of the list, Gtk API doc*/
+ gtk_list_store_move_before (GTK_LIST_STORE (list->priv->store), &iter, NULL);
+ }
+ else
+ {
+ if (gtk_tree_model_get_iter (GTK_TREE_MODEL (list->priv->store), &iter, path))
+ gtk_list_store_move_before (GTK_LIST_STORE (list->priv->store), pos_iter, &iter);
+ }
+
+ gtk_tree_path_free (path);
+ gtk_tree_iter_free (pos_iter);
+}
+
+void
+parole_media_list_row_activated_cb (GtkTreeView *view, GtkTreePath *path,
+ GtkTreeViewColumn *col, ParoleMediaList *list)
+{
+ GtkTreeModel *model;
+ GtkTreeRowReference *row;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (list->priv->view));
+
+ row = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (list->priv->view)),
+ path);
+
+ g_signal_emit (G_OBJECT (list), signals [MEDIA_ACTIVATED], 0, row);
+}
+
+void
+parole_media_list_cursor_changed_cb (GtkTreeView *view, ParoleMediaList *list)
+{
+ GtkTreeSelection *sel;
+ GtkTreeIter iter;
+
+ sel = gtk_tree_view_get_selection (view);
+
+ if ( !gtk_tree_selection_get_selected (sel, NULL, &iter ) )
+ {
+ g_signal_emit (G_OBJECT (list), signals [MEDIA_CURSOR_CHANGED], 0, FALSE);
+ }
+ else
+ {
+ g_signal_emit (G_OBJECT (list), signals [MEDIA_CURSOR_CHANGED], 0, TRUE);
+ }
+}
+
+static void
+parole_media_list_clear_list (ParoleMediaList *list)
+{
+ gtk_list_store_clear (GTK_LIST_STORE (list->priv->store));
+}
+
+static void
+parole_media_list_show_menu (ParoleMediaList *list, guint button, guint activate_time)
+{
+ GtkWidget *menu, *mi;
+
+ menu = gtk_menu_new ();
+
+ mi = gtk_image_menu_item_new_from_stock (GTK_STOCK_CLEAR, NULL);
+ gtk_widget_set_sensitive (mi, TRUE);
+ gtk_widget_show (mi);
+ g_signal_connect_swapped (mi, "activate",
+ G_CALLBACK (parole_media_list_clear_list), list);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+
+ g_signal_connect_swapped (menu, "selection-done",
+ G_CALLBACK (gtk_widget_destroy), menu);
+
+ gtk_menu_popup (GTK_MENU (menu),
+ NULL, NULL,
+ NULL, NULL,
+ button, activate_time);
+}
+
+gboolean
+parole_media_list_button_release_event (GtkWidget *widget, GdkEventButton *ev, ParoleMediaList *list)
+{
+ if ( ev->button == 3 )
+ {
+ parole_media_list_show_menu (list, ev->button, ev->time);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+parole_media_list_finalize (GObject *object)
+{
+ ParoleMediaList *list;
+
+ list = PAROLE_MEDIA_LIST (object);
+
+ G_OBJECT_CLASS (parole_media_list_parent_class)->finalize (object);
+}
+
+static void
+parole_media_list_class_init (ParoleMediaListClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = parole_media_list_finalize;
+
+ signals[MEDIA_ACTIVATED] =
+ g_signal_new ("media-activated",
+ PAROLE_TYPE_MEDIA_LIST,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ParoleMediaListClass, media_activated),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+
+ signals[MEDIA_CURSOR_CHANGED] =
+ g_signal_new ("media-cursor-changed",
+ PAROLE_TYPE_MEDIA_LIST,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ParoleMediaListClass, media_cursor_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+
+ g_type_class_add_private (klass, sizeof (ParoleMediaListPrivate));
+
+ parole_media_list_dbus_class_init (klass);
+}
+
+static void
+parole_media_list_setup_view (ParoleMediaList *list)
+{
+ GtkListStore *list_store;
+ GtkTreeViewColumn *col;
+ GtkCellRenderer *renderer;
+
+ list_store = gtk_list_store_new (COL_NUMBERS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_OBJECT);
+
+ gtk_tree_view_set_model (GTK_TREE_VIEW (list->priv->view), GTK_TREE_MODEL(list_store));
+
+ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (list->priv->view), TRUE);
+ col = gtk_tree_view_column_new ();
+
+ renderer = gtk_cell_renderer_pixbuf_new ();
+
+ gtk_tree_view_column_pack_start(col, renderer, FALSE);
+ gtk_tree_view_column_set_attributes(col, renderer, "pixbuf", PIXBUF_COL, NULL);
+
+ renderer = gtk_cell_renderer_text_new();
+
+ gtk_tree_view_column_pack_start (col, renderer, TRUE);
+ gtk_tree_view_column_set_attributes (col, renderer, "text", NAME_COL, NULL);
+ g_object_set (renderer,
+ "ellipsize", PANGO_ELLIPSIZE_END,
+ NULL);
+
+ gtk_tree_view_append_column (GTK_TREE_VIEW (list->priv->view), col);
+ gtk_tree_view_column_set_title (col, _("Media list"));
+
+ gtk_drag_dest_set (list->priv->view, GTK_DEST_DEFAULT_ALL, target_entry, G_N_ELEMENTS (target_entry),
+ GDK_ACTION_COPY | GDK_ACTION_MOVE);
+
+ list->priv->store = list_store;
+}
+
+static void
+parole_media_list_init (ParoleMediaList *list)
+{
+ GtkBuilder *builder;
+ GtkWidget *box;
+
+ list->priv = PAROLE_MEDIA_LIST_GET_PRIVATE (list);
+
+ builder = parole_builder_new_from_string (playlist_ui, playlist_ui_length);
+
+ list->priv->view = GTK_WIDGET (gtk_builder_get_object (builder, "media-list"));
+ box = GTK_WIDGET (gtk_builder_get_object (builder, "playlist-box"));
+
+ parole_media_list_setup_view (list);
+
+ gtk_builder_connect_signals (builder, list);
+
+ gtk_box_pack_start (GTK_BOX (list), box, TRUE, TRUE, 0);
+
+ g_object_unref (builder);
+
+ gtk_widget_show_all (GTK_WIDGET (list));
+
+ parole_media_list_dbus_init (list);
+}
+
+GtkWidget *
+parole_media_list_new (void)
+{
+ static gpointer list = NULL;
+
+ if ( G_LIKELY (list != NULL ) )
+ {
+ g_object_ref (list);
+ }
+ else
+ {
+ list = g_object_new (PAROLE_TYPE_MEDIA_LIST, NULL);
+ g_object_add_weak_pointer (list, &list);
+ }
+
+ return GTK_WIDGET (list);
+}
+
+/*
+ * Public functions.
+ *
+ */
+GtkTreeRowReference *parole_media_list_get_next_row (ParoleMediaList *list, GtkTreeRowReference *row)
+{
+ GtkTreeRowReference *next;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+
+ g_return_val_if_fail (row != NULL, NULL);
+
+ if ( !gtk_tree_row_reference_valid (row) )
+ return NULL;
+
+ path = gtk_tree_row_reference_get_path (row);
+
+ gtk_tree_path_next (path);
+
+ if ( gtk_tree_model_get_iter (GTK_TREE_MODEL (list->priv->store), &iter, path))
+ {
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (list->priv->store), &iter);
+ next = gtk_tree_row_reference_new (GTK_TREE_MODEL (list->priv->store), path);
+ gtk_tree_path_free (path);
+ return next;
+ }
+
+ return NULL;
+}
+
+GtkTreeRowReference *parole_media_list_get_selected_row (ParoleMediaList *list)
+{
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeSelection *sel;
+ GtkTreeRowReference *row;
+ GtkTreeIter iter;
+
+ sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (list->priv->view));
+
+ if (!gtk_tree_selection_get_selected (sel, &model, &iter))
+ return NULL;
+
+ path = gtk_tree_model_get_path (model, &iter);
+
+ row = gtk_tree_row_reference_new (model, path);
+
+ gtk_tree_path_free (path);
+
+ return row;
+}
+
+void parole_media_list_set_row_pixbuf (ParoleMediaList *list, GtkTreeRowReference *row, GdkPixbuf *pix)
+{
+ 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, PIXBUF_COL, pix, -1);
+ }
+ gtk_tree_path_free (path);
+ }
+}
+
+void parole_media_list_set_row_name (ParoleMediaList *list, GtkTreeRowReference *row, const gchar *name)
+{
+ 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, NAME_COL, name, -1);
+ }
+ gtk_tree_path_free (path);
+ }
+}
+
+void parole_media_list_open (ParoleMediaList *list, gboolean multiple)
+{
+ parole_media_list_open_internal (list, multiple);
+}
+
+void parole_media_list_open_location (ParoleMediaList *list)
+{
+ parole_media_list_open_location_internal (list);
+}
+
+void parole_media_list_add_files (ParoleMediaList *list, gchar **filenames)
+{
+ guint i;
+
+ for ( i = 0; filenames && filenames[i] != NULL; i++)
+ parole_media_list_add_by_path (list, filenames[i], i == 0 ? TRUE : FALSE);
+}
+
+static gboolean parole_media_list_dbus_add_files (ParoleMediaList *list,
+ gchar **in_files,
+ GError **error);
+
+#include "org.parole.media.list.h"
+
+/*
+ * DBus server implementation
+ */
+static void
+parole_media_list_dbus_class_init (ParoleMediaListClass *klass)
+{
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
+ &dbus_glib_parole_media_list_object_info);
+}
+
+static void
+parole_media_list_dbus_init (ParoleMediaList *list)
+{
+ dbus_g_connection_register_g_object (parole_g_session_bus_get (),
+ PAROLE_DBUS_PATH,
+ G_OBJECT (list));
+}
+
+static gboolean parole_media_list_dbus_add_files (ParoleMediaList *list,
+ gchar **in_files,
+ GError **error)
+{
+ TRACE ("Adding files for DBus request");
+
+ parole_media_list_add_files (list, in_files);
+
+ return TRUE;
+}
Added: parole/trunk/parole/parole-medialist.h
===================================================================
--- parole/trunk/parole/parole-medialist.h (rev 0)
+++ parole/trunk/parole/parole-medialist.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,90 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PAROLE_MEDIA_LIST_H
+#define __PAROLE_MEDIA_LIST_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define PAROLE_TYPE_MEDIA_LIST (parole_media_list_get_type () )
+#define PAROLE_MEDIA_LIST(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_MEDIA_LIST, ParoleMediaList))
+#define PAROLE_IS_MEDIA_LIST(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_MEDIA_LIST))
+
+enum
+{
+ PIXBUF_COL,
+ NAME_COL,
+ DATA_COL,
+ COL_NUMBERS
+};
+
+typedef struct ParoleMediaListPrivate ParoleMediaListPrivate;
+
+typedef struct
+{
+ GtkVBox parent;
+
+ ParoleMediaListPrivate *priv;
+
+} ParoleMediaList;
+
+typedef struct
+{
+ GtkVBoxClass parent_class;
+
+ void (*media_activated) (ParoleMediaList *list,
+ GtkTreeRowReference *row);
+
+ void (*media_cursor_changed) (ParoleMediaList *list,
+ gboolean media_selected);
+
+} ParoleMediaListClass;
+
+GType parole_media_list_get_type (void) G_GNUC_CONST;
+
+GtkWidget *parole_media_list_new (void);
+
+GtkTreeRowReference *parole_media_list_get_selected_row (ParoleMediaList *list);
+
+GtkTreeRowReference *parole_media_list_get_next_row (ParoleMediaList *list,
+ GtkTreeRowReference *row);
+
+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_open (ParoleMediaList *list,
+ gboolean multiple);
+
+void parole_media_list_open_location (ParoleMediaList *list);
+
+void parole_media_list_add_files (ParoleMediaList *list,
+ gchar **filenames);
+
+G_END_DECLS
+
+#endif /* __PAROLE_MEDIA_LIST_H */
Added: parole/trunk/parole/parole-module.c
===================================================================
--- parole/trunk/parole/parole-module.c (rev 0)
+++ parole/trunk/parole/parole-module.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,107 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "parole-module.h"
+
+G_DEFINE_TYPE (ParoleModule, parole_module, G_TYPE_TYPE_MODULE)
+
+static gboolean
+parole_module_load (GTypeModule *gtype_module)
+{
+ ParoleModule *module;
+ ParolePlugin *plugin;
+
+ module = PAROLE_MODULE (gtype_module);
+
+ module->mod = g_module_open (gtype_module->name, G_MODULE_BIND_LOCAL);
+
+ if ( G_UNLIKELY (module->mod == NULL) )
+ {
+ g_critical ("Failed to load plugin : %s", g_module_error ());
+ return FALSE;
+ }
+
+ if ( !g_module_symbol (module->mod, "parole_plugin_constructor", (gpointer) &module->constructor) )
+ {
+ g_critical ("Plugin %s missing required constructor symbol", gtype_module->name);
+ g_module_close (module->mod);
+ return FALSE;
+ }
+
+ plugin = (*module->constructor) ();
+
+ g_object_set_data (G_OBJECT (module), "plugin", plugin);
+
+ return TRUE;
+}
+
+static void
+parole_module_unload (GTypeModule *gtype_module)
+{
+ ParoleModule *module;
+ ParolePlugin *plugin;
+
+ module = PAROLE_MODULE (gtype_module);
+
+ plugin = g_object_get_data (G_OBJECT (module), "plugin");
+
+ if (plugin)
+ {
+ g_signal_emit_by_name (G_OBJECT (plugin), "free-data", 0);
+ g_object_unref (plugin);
+ }
+
+ g_module_close (module->mod);
+ module->constructor = NULL;
+}
+
+static void
+parole_module_class_init (ParoleModuleClass *klass)
+{
+ GTypeModuleClass *gtype_module_class = G_TYPE_MODULE_CLASS (klass);
+
+ gtype_module_class->load = parole_module_load;
+ gtype_module_class->unload = parole_module_unload;
+}
+
+static void
+parole_module_init (ParoleModule *module)
+{
+}
+
+ParoleModule *
+parole_module_new (const gchar *filename)
+{
+ ParoleModule *module = NULL;
+
+ module = g_object_new (PAROLE_TYPE_MODULE, NULL);
+
+ g_type_module_set_name (G_TYPE_MODULE (module), filename);
+
+ return module;
+}
Added: parole/trunk/parole/parole-module.h
===================================================================
--- parole/trunk/parole/parole-module.h (rev 0)
+++ parole/trunk/parole/parole-module.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,58 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PAROLE_MODULE_H
+#define __PAROLE_MODULE_H
+
+#include <glib-object.h>
+
+#include "parole-plugin.h"
+
+G_BEGIN_DECLS
+
+#define PAROLE_TYPE_MODULE (parole_module_get_type () )
+#define PAROLE_MODULE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_MODULE, ParoleModule))
+#define PAROLE_IS_MODULE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_MODULE))
+
+typedef struct ParoleModulePrivate ParoleModulePrivate;
+
+typedef struct
+{
+ GTypeModule parent;
+
+ GModule *mod;
+
+ ParolePlugin *(*constructor) (void);
+
+} ParoleModule;
+
+typedef struct
+{
+ GTypeModuleClass parent_class;
+
+} ParoleModuleClass;
+
+GType parole_module_get_type (void) G_GNUC_CONST;
+
+ParoleModule *parole_module_new (const gchar *filename);
+
+G_END_DECLS
+
+#endif /* __PAROLE_MODULE_H */
Added: parole/trunk/parole/parole-player.c
===================================================================
--- parole/trunk/parole/parole-player.c (rev 0)
+++ parole/trunk/parole/parole-player.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,969 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+#include <libxfce4util/libxfce4util.h>
+#include <libxfcegui4/libxfcegui4.h>
+
+#include "common/parole-builder.h"
+#include "common/parole-about.h"
+
+#include "parole-player.h"
+#include "parole-sidebar.h"
+#include "parole-gst.h"
+#include "parole-mediachooser.h"
+#include "parole-mediafile.h"
+#include "parole-statusbar.h"
+#include "parole-screensaver.h"
+#include "parole-conf-dialog.h"
+#include "parole-conf.h"
+#include "parole-rc-utils.h"
+#include "parole-utils.h"
+#include "enum-gtypes.h"
+#include "parole-debug.h"
+
+/*
+ * GtkBuilder Callbacks
+ */
+gboolean parole_player_range_button_press (GtkWidget *widget,
+ GdkEventButton *ev,
+ ParolePlayer *player);
+
+gboolean parole_player_range_button_release (GtkWidget *widget,
+ GdkEventButton *ev,
+ ParolePlayer *player);
+
+void parole_player_range_value_changed (GtkRange *range,
+ ParolePlayer *player);
+
+void parole_player_play_pause_clicked (GtkButton *button,
+ ParolePlayer *player);
+
+void parole_player_stop_clicked (GtkButton *button,
+ ParolePlayer *player);
+
+void parole_player_destroy_cb (GtkObject *window,
+ ParolePlayer *player);
+
+gboolean parole_player_delete_event_cb (GtkWidget *widget,
+ GdkEvent *ev,
+ ParolePlayer *player);
+
+void parole_player_show_hide_playlist (GtkButton *button,
+ ParolePlayer *player);
+
+/*Menu items callbacks*/
+void parole_player_menu_open_cb (GtkWidget *widget,
+ ParolePlayer *player);
+
+void parole_player_menu_open_location_cb (GtkWidget *widget,
+ ParolePlayer *player);
+
+void parole_player_menu_add_cb (GtkWidget *widget,
+ ParolePlayer *player);
+
+void parole_player_menu_exit_cb (GtkWidget *widget,
+ ParolePlayer *player);
+
+void parole_player_open_preferences_cb (GtkWidget *widget,
+ ParolePlayer *player);
+
+void parole_player_volume_value_changed_cb (GtkRange *range,
+ ParolePlayer *player);
+
+void parole_player_full_screen_activated_cb (GtkWidget *widget,
+ ParolePlayer *player);
+
+void parole_show_about (GtkWidget *widget);
+
+gboolean parole_player_key_press (GtkWidget *widget,
+ GdkEventKey *ev,
+ ParolePlayer *player);
+/*
+ * End of GtkBuilder Callbacks
+ */
+
+#define INTERFACE_FILE INTERFACES_DIR "/parole.ui"
+
+#define PAROLE_PLAYER_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_PLAYER, ParolePlayerPrivate))
+
+struct ParolePlayerPrivate
+{
+ ParoleMediaList *list;
+ ParoleStatusbar *status;
+ ParoleScreenSaver *screen_saver;
+ ParoleSidebar *sidebar;
+
+ GtkWidget *gst;
+
+ GtkWidget *window;
+ GtkWidget *playlist_box;
+ GtkWidget *show_hide_playlist;
+ GtkWidget *play_pause;
+ GtkWidget *stop;
+ GtkWidget *range;
+
+ GtkWidget *volume;
+ GtkWidget *volume_image;
+ GtkWidget *menu_bar;
+ GtkWidget *play_box;
+
+ gboolean exit;
+
+ gboolean full_screen;
+
+ ParoleMediaState state;
+ gboolean user_seeking;
+ gboolean internal_range_change;
+ gboolean buffering;
+
+ GtkTreeRowReference *row;
+
+};
+
+G_DEFINE_TYPE (ParolePlayer, parole_player, G_TYPE_OBJECT)
+
+void parole_show_about (GtkWidget *widget)
+{
+ parole_about (_("Parole Media Player"));
+}
+
+void parole_player_show_hide_playlist (GtkButton *button, ParolePlayer *player)
+{
+ GtkWidget *img;
+ gboolean visible;
+
+ g_object_get (G_OBJECT (player->priv->show_hide_playlist),
+ "image", &img,
+ NULL);
+
+ visible = GTK_WIDGET_VISIBLE (player->priv->playlist_box);
+
+ if ( !visible )
+ {
+ g_object_set (G_OBJECT (img),
+ "stock", GTK_STOCK_GO_FORWARD,
+ NULL);
+
+ gtk_widget_show_all (player->priv->playlist_box);
+ gtk_widget_set_tooltip_text (GTK_WIDGET (player->priv->show_hide_playlist), _("Hide playlist"));
+ }
+ else
+ {
+ g_object_set (G_OBJECT (img),
+ "stock", GTK_STOCK_GO_BACK,
+ NULL);
+
+ gtk_widget_hide_all (player->priv->playlist_box);
+ gtk_widget_set_tooltip_text (GTK_WIDGET (player->priv->show_hide_playlist), _("Show playlist"));
+ }
+ g_object_unref (img);
+}
+
+static void
+parole_player_change_range_value (ParolePlayer *player, gdouble value)
+{
+ player->priv->internal_range_change = TRUE;
+ gtk_range_set_value (GTK_RANGE (player->priv->range), value);
+ player->priv->internal_range_change = FALSE;
+}
+
+static void
+parole_player_media_activated_cb (ParoleMediaList *list, GtkTreeRowReference *row, ParolePlayer *player)
+{
+ ParoleMediaFile *file;
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+
+ parole_player_change_range_value (player, 0);
+
+ if ( player->priv->row )
+ {
+ parole_media_list_set_row_pixbuf (player->priv->list, player->priv->row, NULL);
+ gtk_tree_row_reference_free (player->priv->row);
+ player->priv->row = NULL;
+ }
+
+ player->priv->row = row;
+ model = gtk_tree_row_reference_get_model (row);
+
+ if ( gtk_tree_model_get_iter (model, &iter, gtk_tree_row_reference_get_path (row)) )
+ {
+ gtk_tree_model_get (model, &iter, DATA_COL, &file, -1);
+
+ if ( file )
+ {
+ TRACE ("Trying to play media file %s", parole_media_file_get_uri (file));
+ gtk_widget_set_sensitive (player->priv->stop, TRUE);
+ parole_gst_play_file (PAROLE_GST (player->priv->gst), file);
+ g_object_unref (file);
+ }
+ }
+}
+
+static void
+parole_player_media_cursor_changed_cb (ParoleMediaList *list, gboolean media_selected, ParolePlayer *player)
+{
+ if (!player->priv->state != PAROLE_MEDIA_STATE_PLAYING)
+ gtk_widget_set_sensitive (player->priv->play_pause, media_selected);
+
+}
+
+static void
+parole_player_media_progressed_cb (ParoleGst *gst, const ParoleStream *stream, gdouble value, ParolePlayer *player)
+{
+#ifdef DEBUG
+ g_return_if_fail (value > 0);
+#endif
+
+ if ( !player->priv->user_seeking && player->priv->state == PAROLE_MEDIA_STATE_PLAYING )
+ {
+ parole_player_change_range_value (player, value);
+ }
+ parole_statusbar_set_position (player->priv->status,
+ player->priv->state == PAROLE_MEDIA_STATE_PLAYING,
+ value);
+}
+
+static void
+parole_player_set_playpause_widget_image (GtkWidget *widget, const gchar *stock_id)
+{
+ GtkWidget *img;
+
+ g_object_get (G_OBJECT (widget),
+ "image", &img,
+ NULL);
+
+ g_object_set (G_OBJECT (img),
+ "stock", stock_id,
+ NULL);
+
+ g_object_unref (img);
+}
+
+static void
+parole_player_set_playpause_button_image (GtkWidget *widget, const gchar *stock_id)
+{
+ GtkWidget *img;
+
+ g_object_get (G_OBJECT (widget),
+ "image", &img,
+ NULL);
+
+ g_object_set (G_OBJECT (img),
+ "stock", stock_id,
+ NULL);
+
+ g_object_unref (img);
+}
+
+static void
+parole_player_playing (ParolePlayer *player, const ParoleStream *stream)
+{
+ GdkPixbuf *pix = NULL;
+ gdouble duration;
+ gboolean seekable;
+
+ player->priv->state = PAROLE_MEDIA_STATE_PLAYING;
+ pix = xfce_themed_icon_load ("gtk-media-play-ltr", 16);
+
+ parole_media_list_set_row_pixbuf (player->priv->list, player->priv->row, pix);
+
+ g_object_get (G_OBJECT (stream),
+ "seekable", &seekable,
+ "duration", &duration,
+ NULL);
+
+ gtk_widget_set_sensitive (player->priv->play_pause, TRUE);
+ gtk_widget_set_sensitive (player->priv->stop, TRUE);
+
+ parole_player_set_playpause_button_image (player->priv->play_pause, GTK_STOCK_MEDIA_PAUSE);
+
+ gtk_widget_set_sensitive (player->priv->range, seekable);
+
+ if ( seekable )
+ {
+ parole_statusbar_set_duration (player->priv->status, duration);
+ gtk_range_set_range (GTK_RANGE (player->priv->range), 0, duration);
+ }
+ else
+ {
+ parole_statusbar_set_text (player->priv->status, _("Playing"));
+ gtk_widget_set_tooltip_text (GTK_WIDGET (player->priv->range), _("Media stream is not seekable"));
+ parole_player_change_range_value (player, 0);
+ }
+
+ if ( pix )
+ g_object_unref (pix);
+}
+
+static void
+parole_player_paused (ParolePlayer *player)
+{
+ GdkPixbuf *pix = NULL;
+
+ player->priv->state = PAROLE_MEDIA_STATE_PAUSED;
+
+ TRACE ("Player paused");
+
+ if ( !player->priv->buffering )
+ parole_statusbar_set_text (player->priv->status, _("Paused"));
+
+ pix = xfce_themed_icon_load ("gtk-media-pause", 16);
+ parole_media_list_set_row_pixbuf (player->priv->list, player->priv->row, pix);
+
+ gtk_widget_set_sensitive (player->priv->play_pause, TRUE);
+ gtk_widget_set_sensitive (player->priv->stop, TRUE);
+
+ parole_player_set_playpause_widget_image (player->priv->play_pause, GTK_STOCK_MEDIA_PLAY);
+
+ if ( pix )
+ g_object_unref (pix);
+
+ parole_statusbar_set_text (player->priv->status, _("Paused"));
+}
+
+static void
+parole_player_quit (ParolePlayer *player)
+{
+ gtk_widget_destroy (player->priv->window);
+ g_object_unref (player);
+ gtk_main_quit ();
+}
+
+static void
+parole_player_stopped (ParolePlayer *player)
+{
+ TRACE ("Player stopped");
+
+ player->priv->state = PAROLE_MEDIA_STATE_STOPPED;
+
+ parole_statusbar_set_text (player->priv->status, _("Stopped"));
+
+ gtk_widget_set_sensitive (player->priv->play_pause, FALSE);
+ gtk_widget_set_sensitive (player->priv->stop, FALSE);
+
+ parole_player_change_range_value (player, 0);
+ gtk_widget_set_sensitive (player->priv->range, FALSE);
+
+ parole_player_set_playpause_widget_image (player->priv->play_pause, GTK_STOCK_MEDIA_PLAY);
+
+ parole_media_list_set_row_pixbuf (player->priv->list, player->priv->row, NULL);
+
+ if ( player->priv->exit )
+ {
+ parole_player_quit (player);
+ }
+}
+
+static void
+parole_player_play_selected_row (ParolePlayer *player)
+{
+ GtkTreeRowReference *row;
+
+ row = parole_media_list_get_selected_row (player->priv->list);
+
+ if ( row )
+ {
+ parole_player_media_activated_cb (player->priv->list, row, player);
+ }
+}
+
+static void
+parole_player_play_next (ParolePlayer *player)
+{
+ GtkTreeRowReference *row;
+
+ if ( player->priv->row )
+ {
+ parole_media_list_set_row_pixbuf (player->priv->list, player->priv->row, NULL);
+ row = parole_media_list_get_next_row (player->priv->list, player->priv->row);
+
+ if ( row )
+ {
+ parole_player_media_activated_cb (player->priv->list, row, player);
+ return;
+ }
+ else
+ {
+ TRACE ("No remaining media in the list");
+ gtk_tree_row_reference_free (player->priv->row);
+ player->priv->row = NULL;
+ }
+ }
+
+ parole_gst_stop (PAROLE_GST (player->priv->gst));
+}
+
+static void
+parole_player_media_state_cb (ParoleGst *gst, const ParoleStream *stream, ParoleMediaState state, ParolePlayer *player)
+{
+ gboolean has_video;
+
+ PAROLE_DEBUG_ENUM ("State callback", state, ENUM_GTYPE_MEDIA_STATE);
+
+ if ( state == PAROLE_MEDIA_STATE_PLAYING && has_video )
+ parole_screen_saver_inhibit (player->priv->screen_saver);
+ else
+ parole_screen_saver_uninhibit (player->priv->screen_saver);
+
+ g_object_get (G_OBJECT (stream),
+ "has-video", &has_video,
+ NULL);
+
+ if ( state == PAROLE_MEDIA_STATE_PLAYING )
+ {
+ parole_player_playing (player, stream);
+ }
+ else if ( state == PAROLE_MEDIA_STATE_PAUSED )
+ {
+ parole_player_paused (player);
+ }
+ else if ( state == PAROLE_MEDIA_STATE_STOPPED )
+ {
+ parole_player_stopped (player);
+ }
+ else if ( state == PAROLE_MEDIA_STATE_FINISHED )
+ {
+ TRACE ("***Playback finished***");
+ parole_player_play_next (player);
+ }
+}
+
+void
+parole_player_play_pause_clicked (GtkButton *button, ParolePlayer *player)
+{
+ if ( player->priv->state == PAROLE_MEDIA_STATE_PLAYING )
+ parole_gst_pause (PAROLE_GST (player->priv->gst));
+ else if ( player->priv->state == PAROLE_MEDIA_STATE_PAUSED )
+ parole_gst_resume (PAROLE_GST (player->priv->gst));
+ else
+ parole_player_play_selected_row (player);
+}
+
+void
+parole_player_stop_clicked (GtkButton *button, ParolePlayer *player)
+{
+ parole_gst_stop (PAROLE_GST (player->priv->gst));
+}
+
+gboolean
+parole_player_range_button_release (GtkWidget *widget, GdkEventButton *ev, ParolePlayer *player)
+{
+ if ( ev->button == 3 )
+ {
+ player->priv->user_seeking = TRUE;
+ }
+
+ return FALSE;
+}
+
+gboolean
+parole_player_range_button_press (GtkWidget *widget, GdkEventButton *ev, ParolePlayer *player)
+{
+ gdouble value;
+
+ value = gtk_range_get_value (GTK_RANGE (player->priv->range));
+
+ if ( ev->button == 3 )
+ {
+ player->priv->user_seeking = FALSE;
+ }
+
+ return FALSE;
+}
+
+void
+parole_player_range_value_changed (GtkRange *range, ParolePlayer *player)
+{
+ gdouble value;
+
+ if ( !player->priv->internal_range_change )
+ {
+ value = gtk_range_get_value (GTK_RANGE (range));
+ player->priv->user_seeking = TRUE;
+ parole_gst_seek (PAROLE_GST (player->priv->gst), value);
+ player->priv->user_seeking = FALSE;
+ }
+}
+
+static void
+parole_player_error_cb (ParoleGst *gst, const gchar *error, ParolePlayer *player)
+{
+ xfce_err ("%s", error);
+ parole_screen_saver_uninhibit (player->priv->screen_saver);
+ parole_player_stopped (player);
+}
+
+static void
+parole_player_media_tag_cb (ParoleGst *gst, const ParoleStream *stream, ParolePlayer *player)
+{
+ gchar *title;
+
+ if ( player->priv->row )
+ {
+ g_object_get (G_OBJECT (stream),
+ "title", &title,
+ NULL);
+ if ( title )
+ {
+ parole_media_list_set_row_name (player->priv->list, player->priv->row, title);
+ g_free (title);
+ }
+ }
+}
+
+static void
+parole_player_buffering_cb (ParoleGst *gst, const ParoleStream *stream, gint percentage, ParolePlayer *player)
+{
+ if ( percentage == 100 )
+ {
+ player->priv->buffering = FALSE;
+ parole_gst_resume (PAROLE_GST (player->priv->gst));
+ }
+ else
+ {
+ player->priv->buffering = TRUE;
+ parole_statusbar_set_buffering (player->priv->status, percentage);
+
+ if ( player->priv->state == PAROLE_MEDIA_STATE_PLAYING )
+ parole_gst_pause (PAROLE_GST (player->priv->gst));
+ }
+}
+
+gboolean parole_player_delete_event_cb (GtkWidget *widget, GdkEvent *ev, ParolePlayer *player)
+{
+ parole_window_busy_cursor (GTK_WIDGET (player->priv->window)->window);
+
+ player->priv->exit = TRUE;
+ parole_gst_null_state (PAROLE_GST (player->priv->gst));
+
+ return TRUE;
+}
+
+void
+parole_player_destroy_cb (GtkObject *window, ParolePlayer *player)
+{
+}
+
+static void
+parole_player_play_menu_item_activate (ParolePlayer *player)
+{
+ gtk_widget_activate (player->priv->play_pause);
+}
+
+static void
+parole_player_stop_menu_item_activate (ParolePlayer *player)
+{
+ gtk_widget_activate (player->priv->stop);
+}
+
+static void
+parole_player_next_menu_item_activate (ParolePlayer *player)
+{
+
+}
+
+static void
+parole_player_previous_menu_item_activate (ParolePlayer *player)
+{
+
+}
+
+static void
+parole_player_full_screen_menu_item_activate (ParolePlayer *player)
+{
+ if ( player->priv->full_screen )
+ {
+ parole_sidebar_set_visible (player->priv->sidebar, TRUE);
+ parole_statusbar_set_visible (player->priv->status, TRUE);
+ gtk_widget_show (player->priv->play_box);
+ gtk_widget_show (player->priv->menu_bar);
+ gtk_widget_show (player->priv->playlist_box);
+ gtk_window_unfullscreen (GTK_WINDOW (player->priv->window));
+ player->priv->full_screen = FALSE;
+ }
+ else
+ {
+ parole_sidebar_set_visible (player->priv->sidebar, FALSE);
+ parole_statusbar_set_visible (player->priv->status, FALSE);
+ gtk_widget_hide (player->priv->play_box);
+ gtk_widget_hide (player->priv->menu_bar);
+ gtk_widget_hide (player->priv->playlist_box);
+ gtk_window_fullscreen (GTK_WINDOW (player->priv->window));
+ player->priv->full_screen = TRUE;
+ }
+}
+
+void parole_player_full_screen_activated_cb (GtkWidget *widget, ParolePlayer *player)
+{
+ parole_player_full_screen_menu_item_activate (player);
+}
+
+static void
+parole_player_show_menu (ParolePlayer *player, guint button, guint activate_time)
+{
+ GtkWidget *menu, *mi;
+ gboolean sensitive;
+
+ menu = gtk_menu_new ();
+
+ /*Play menu item
+ */
+ mi = gtk_image_menu_item_new_from_stock (player->priv->state == PAROLE_MEDIA_STATE_PLAYING
+ ? GTK_STOCK_MEDIA_PAUSE : GTK_STOCK_MEDIA_PLAY,
+ NULL);
+
+ g_object_get (G_OBJECT (player->priv->play_pause),
+ "sensitive", &sensitive,
+ NULL);
+
+ gtk_widget_set_sensitive (mi, sensitive);
+ gtk_widget_show (mi);
+ g_signal_connect_swapped (mi, "activate",
+ G_CALLBACK (parole_player_play_menu_item_activate), player);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+
+ /*Stop menu item
+ */
+ mi = gtk_image_menu_item_new_from_stock (GTK_STOCK_MEDIA_STOP, NULL);
+
+ gtk_widget_set_sensitive (mi, player->priv->state == PAROLE_MEDIA_STATE_PLAYING);
+ gtk_widget_show (mi);
+ g_signal_connect_swapped (mi, "activate",
+ G_CALLBACK (parole_player_stop_menu_item_activate), player);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+
+ /*Next chapter menu item
+ */
+ mi = gtk_image_menu_item_new_from_stock (GTK_STOCK_MEDIA_NEXT, NULL);
+
+ gtk_widget_set_sensitive (mi, player->priv->state == PAROLE_MEDIA_STATE_PLAYING);
+ gtk_widget_show (mi);
+ g_signal_connect_swapped (mi, "activate",
+ G_CALLBACK (parole_player_next_menu_item_activate), player);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+
+ /*Previous chapter menu item
+ */
+ mi = gtk_image_menu_item_new_from_stock (GTK_STOCK_MEDIA_PREVIOUS, NULL);
+
+ gtk_widget_set_sensitive (mi, player->priv->state == PAROLE_MEDIA_STATE_PLAYING);
+ gtk_widget_show (mi);
+ g_signal_connect_swapped (mi, "activate",
+ G_CALLBACK (parole_player_previous_menu_item_activate), player);
+ 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);
+
+ /*
+ * Un/Full screen
+ */
+ mi = gtk_image_menu_item_new_from_stock (player->priv->full_screen ? GTK_STOCK_LEAVE_FULLSCREEN:
+ GTK_STOCK_FULLSCREEN, NULL);
+ gtk_widget_show (mi);
+ g_signal_connect_swapped (mi, "activate",
+ G_CALLBACK (parole_player_full_screen_menu_item_activate), player);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+
+
+ g_signal_connect_swapped (menu, "selection-done",
+ G_CALLBACK (gtk_widget_destroy), menu);
+
+ gtk_menu_popup (GTK_MENU (menu),
+ NULL, NULL,
+ NULL, NULL,
+ button, activate_time);
+}
+
+static gboolean
+parole_player_gst_widget_button_press (GtkWidget *widget, GdkEventButton *ev, ParolePlayer *player)
+{
+ if ( ev->button == 3)
+ {
+ parole_player_show_menu (player, ev->button, ev->time);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+parole_player_gst_widget_motion_notify_event (GtkWidget *widget, GdkEventMotion *ev, ParolePlayer *player)
+{
+ gint pointer_y;
+
+ if ( player->priv->full_screen )
+ {
+ pointer_y = (gint) ev->y;
+ if ( pointer_y >= widget->allocation.height - 10 )
+ gtk_widget_show (player->priv->play_box);
+ else
+ gtk_widget_hide (player->priv->play_box);
+ }
+ return FALSE;
+}
+
+void
+parole_player_menu_open_cb (GtkWidget *widget, ParolePlayer *player)
+{
+ parole_media_list_open (player->priv->list, FALSE);
+}
+
+void
+parole_player_menu_open_location_cb (GtkWidget *widget, ParolePlayer *player)
+{
+ parole_media_list_open_location (player->priv->list);
+}
+
+void
+parole_player_menu_add_cb (GtkWidget *widget, ParolePlayer *player)
+{
+ parole_media_list_open (player->priv->list, TRUE);
+}
+
+void parole_player_open_preferences_cb (GtkWidget *widget, ParolePlayer *player)
+{
+ ParoleConfDialog *dialog;
+
+ dialog = parole_conf_dialog_new ();
+
+ parole_conf_dialog_open (dialog, player->priv->window);
+}
+
+void
+parole_player_menu_exit_cb (GtkWidget *widget, ParolePlayer *player)
+{
+ parole_player_delete_event_cb (NULL, NULL, player);
+}
+
+static const gchar *
+parole_player_get_volume_icon_name (gdouble value)
+{
+ if ( value == 1. )
+ return "audio-volume-high";
+ else if ( value > 0.5 )
+ return "audio-volume-medium";
+ else if ( value > 0 )
+ return "audio-volume-low";
+
+ return "audio-volume-muted";
+}
+
+static void
+parole_player_set_volume_image (ParolePlayer *player, gdouble value)
+{
+ GdkPixbuf *icon;
+
+ icon = xfce_themed_icon_load (parole_player_get_volume_icon_name (value),
+ player->priv->volume_image->allocation.width);
+ if ( icon )
+ {
+ g_object_set (G_OBJECT (player->priv->volume_image),
+ "pixbuf", icon,
+ NULL);
+ gdk_pixbuf_unref (icon);
+ }
+}
+
+static void
+parole_player_change_volume (ParolePlayer *player, gdouble value)
+{
+ parole_gst_set_volume (PAROLE_GST (player->priv->gst), value);
+ parole_player_set_volume_image (player, value);
+}
+
+void
+parole_player_volume_value_changed_cb (GtkRange *range, ParolePlayer *player)
+{
+ gdouble value;
+ value = gtk_range_get_value (range);
+ parole_player_change_volume (player, value);
+ parole_rc_write_entry_int ("volume", (gint)(value * 100));
+}
+
+static void
+parole_player_finalize (GObject *object)
+{
+ ParolePlayer *player;
+
+ player = PAROLE_PLAYER (object);
+
+ TRACE ("start");
+
+ g_object_unref (player->priv->gst);
+ g_object_unref (player->priv->status);
+ g_object_unref (player->priv->screen_saver);
+ g_object_unref (player->priv->sidebar);
+
+ G_OBJECT_CLASS (parole_player_parent_class)->finalize (object);
+}
+
+static void
+parole_player_class_init (ParolePlayerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = parole_player_finalize;
+
+ g_type_class_add_private (klass, sizeof (ParolePlayerPrivate));
+}
+
+gboolean
+parole_player_key_press (GtkWidget *widget, GdkEventKey *ev, ParolePlayer *player)
+{
+ if ( ev->keyval == GDK_F11 )
+ {
+ parole_player_full_screen_menu_item_activate (player);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+parole_player_init (ParolePlayer *player)
+{
+ GtkBuilder *builder;
+
+ player->priv = PAROLE_PLAYER_GET_PRIVATE (player);
+
+ builder = parole_builder_get_main_interface ();
+
+ player->priv->gst = parole_gst_new ();
+ /*
+ * Since ParoleGst is derived from GtkWidget and packed in the media output
+ * box the destroy event on the window will destroy the ParoleGst widget
+ * so we ref it to clean up the gst objects before quitting.
+ */
+ g_object_ref (player->priv->gst);
+ player->priv->sidebar = parole_sidebar_new ();
+ player->priv->status = parole_statusbar_new ();
+ player->priv->screen_saver = parole_screen_saver_new ();
+ player->priv->list = PAROLE_MEDIA_LIST (parole_media_list_new ());
+
+ player->priv->state = PAROLE_MEDIA_STATE_STOPPED;
+ player->priv->user_seeking = FALSE;
+ player->priv->internal_range_change = FALSE;
+ player->priv->exit = FALSE;
+ player->priv->full_screen = FALSE;
+ player->priv->buffering = FALSE;
+ player->priv->row = NULL;
+
+ /*
+ * Gst signals
+ */
+ g_signal_connect (G_OBJECT (player->priv->gst), "media-state",
+ G_CALLBACK (parole_player_media_state_cb), player);
+
+ g_signal_connect (G_OBJECT (player->priv->gst), "media-progressed",
+ G_CALLBACK (parole_player_media_progressed_cb), player);
+
+ g_signal_connect (G_OBJECT (player->priv->gst), "media-tag",
+ G_CALLBACK (parole_player_media_tag_cb), player);
+
+ g_signal_connect (G_OBJECT (player->priv->gst), "error",
+ G_CALLBACK (parole_player_error_cb), player);
+
+ g_signal_connect (G_OBJECT (player->priv->gst), "buffering",
+ G_CALLBACK (parole_player_buffering_cb), player);
+
+ g_signal_connect (G_OBJECT (player->priv->gst), "button-release-event",
+ G_CALLBACK (parole_player_gst_widget_button_press), player);
+
+ g_signal_connect (G_OBJECT (player->priv->gst), "motion-notify-event",
+ G_CALLBACK (parole_player_gst_widget_motion_notify_event), player);
+
+ player->priv->window = GTK_WIDGET (gtk_builder_get_object (builder, "main-window"));
+
+ player->priv->play_pause = GTK_WIDGET (gtk_builder_get_object (builder, "play-pause"));
+ player->priv->stop = GTK_WIDGET (gtk_builder_get_object (builder, "stop"));
+ player->priv->range = GTK_WIDGET (gtk_builder_get_object (builder, "scale"));
+
+ player->priv->volume = GTK_WIDGET (gtk_builder_get_object (builder, "volume"));
+ player->priv->volume_image = GTK_WIDGET (gtk_builder_get_object (builder, "volume-image"));
+
+ player->priv->menu_bar = GTK_WIDGET (gtk_builder_get_object (builder, "menubar"));
+ player->priv->play_box = GTK_WIDGET (gtk_builder_get_object (builder, "play-box"));
+ player->priv->playlist_box = GTK_WIDGET (gtk_builder_get_object (builder, "notebook-playlist"));
+ player->priv->show_hide_playlist = GTK_WIDGET (gtk_builder_get_object (builder, "show-hide-list"));
+
+ gtk_range_set_range (GTK_RANGE (player->priv->volume), 0, 1.0);
+
+ gtk_range_set_value (GTK_RANGE (player->priv->volume),
+ (gdouble) (parole_rc_read_entry_int ("volume", 100)/100.));
+
+ /*
+ * Pack the playlist.
+ */
+ gtk_notebook_append_page (GTK_NOTEBOOK (player->priv->playlist_box),
+ GTK_WIDGET (player->priv->list),
+ gtk_label_new (_("Playlist")));
+
+ /*
+ * Pack the statusbar.
+ */
+ gtk_widget_show_all (player->priv->window);
+
+ gtk_box_pack_start (GTK_BOX (gtk_builder_get_object (builder, "output")),
+ player->priv->gst,
+ TRUE, TRUE, 0);
+
+ gtk_widget_realize (player->priv->gst);
+ gtk_widget_show (player->priv->gst);
+
+ parole_player_change_volume (player,
+ (gdouble) (parole_rc_read_entry_int ("volume", 100)/100.));
+
+ g_signal_connect (player->priv->list, "media_activated",
+ G_CALLBACK (parole_player_media_activated_cb), player);
+
+ g_signal_connect (player->priv->list, "media_cursor_changed",
+ G_CALLBACK (parole_player_media_cursor_changed_cb), player);
+
+ gtk_builder_connect_signals (builder, player);
+ g_object_unref (builder);
+}
+
+ParolePlayer *
+parole_player_new (void)
+{
+ ParolePlayer *player = NULL;
+ player = g_object_new (PAROLE_TYPE_PLAYER, NULL);
+ return player;
+}
+
+ParoleMediaList *parole_player_get_media_list (ParolePlayer *player)
+{
+ return player->priv->list;
+}
Added: parole/trunk/parole/parole-player.h
===================================================================
--- parole/trunk/parole/parole-player.h (rev 0)
+++ parole/trunk/parole/parole-player.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,55 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PAROLE_PLAYER_H
+#define __PAROLE_PLAYER_H
+
+#include <glib-object.h>
+#include "parole-medialist.h"
+
+G_BEGIN_DECLS
+
+#define PAROLE_TYPE_PLAYER (parole_player_get_type () )
+#define PAROLE_PLAYER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_PLAYER, ParolePlayer))
+#define PAROLE_IS_PLAYER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_PLAYER))
+
+typedef struct ParolePlayerPrivate ParolePlayerPrivate;
+
+typedef struct
+{
+ GObject parent;
+ ParolePlayerPrivate *priv;
+
+} ParolePlayer;
+
+typedef struct
+{
+ GObjectClass parent_class;
+
+} ParolePlayerClass;
+
+GType parole_player_get_type (void) G_GNUC_CONST;
+ParolePlayer *parole_player_new (void);
+
+ParoleMediaList *parole_player_get_media_list (ParolePlayer *player);
+
+G_END_DECLS
+
+#endif /* __PAROLE_PLAYER_H */
Added: parole/trunk/parole/parole-plugin.c
===================================================================
--- parole/trunk/parole/parole-plugin.c (rev 0)
+++ parole/trunk/parole/parole-plugin.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,468 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "parole-plugin.h"
+#include "parole-medialist.h"
+#include "parole-plugins-manager.h"
+#include "parole-gst.h"
+#include "gmarshal.h"
+#include "enum-gtypes.h"
+
+static void parole_plugin_finalize (GObject *object);
+
+static void parole_plugin_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
+static void parole_plugin_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+#define PAROLE_PLUGIN_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_PLUGIN, ParolePluginPrivate))
+
+typedef struct _ParolePluginPrivate ParolePluginPrivate;
+
+struct _ParolePluginPrivate
+{
+ ParoleGst *gst;
+
+ gchar *title;
+ gchar *author;
+ gchar *desc;
+
+ gboolean packed;
+
+
+ /* sig id's*/
+ gulong gst_sig1;
+ gulong gst_sig2;
+};
+
+enum
+{
+ PROP_0,
+ PROP_TITLE,
+ PROP_DESC,
+ PROP_AUTHOR
+};
+
+enum
+{
+ STATE_CHANGED,
+ TAG_MESSAGE,
+ FREE_DATA,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (ParolePlugin, parole_plugin, G_TYPE_OBJECT)
+
+static void
+parole_plugin_media_state_changed_cb (ParoleGst *gst, const ParoleStream *stream,
+ ParoleMediaState state, ParolePlugin *plugin)
+{
+ g_signal_emit (G_OBJECT (plugin), signals [STATE_CHANGED], 0, stream, state);
+}
+
+static void
+parole_plugin_media_tag_cb (ParoleGst *gst, const ParoleStream *stream, ParolePlugin *plugin)
+{
+ g_signal_emit (G_OBJECT (plugin), signals [TAG_MESSAGE], 0, stream);
+}
+
+static void
+parole_plugin_class_init (ParolePluginClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = parole_plugin_finalize;
+
+ object_class->get_property = parole_plugin_get_property;
+ object_class->set_property = parole_plugin_set_property;
+
+ /**
+ * ParolePlugin::state-changed:
+ * @plugin: the object which received the signal.
+ * @stream: a #ParoleStream.
+ * @state: the new state.
+ *
+ * Since: 0.1
+ **/
+ signals[STATE_CHANGED] =
+ g_signal_new ("state-changed",
+ PAROLE_TYPE_PLUGIN,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ParolePluginClass, state_changed),
+ NULL, NULL,
+ _gmarshal_VOID__OBJECT_ENUM,
+ G_TYPE_NONE, 2,
+ PAROLE_TYPE_STREAM, ENUM_GTYPE_STATE);
+
+ /**
+ * ParolePlugin::tag-message:
+ * @plugin: the object which received the signal.
+ * @stream: a #ParoleStream.
+ *
+ * Since: 0.1
+ **/
+ signals[TAG_MESSAGE] =
+ g_signal_new ("tag-message",
+ PAROLE_TYPE_PLUGIN,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ParolePluginClass, tag_message),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, PAROLE_TYPE_STREAM);
+
+ /**
+ * ParolePlugin::free-data:
+ * @plugin: the object which received the signal.
+ *
+ * Emitted before unloading the plugin from memory, so
+ * any dynamiclly allocated memory should be freed in this signal
+ * handler.
+ *
+ * Since: 0.1
+ **/
+ signals [FREE_DATA] =
+ g_signal_new ("free-data",
+ PAROLE_TYPE_PLUGIN,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(ParolePluginClass, free_data),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0, G_TYPE_NONE);
+
+ /**
+ * ParolePlugin:title:
+ *
+ * Title to display for this plugin.
+ *
+ * Since: 0.1
+ **/
+ g_object_class_install_property (object_class,
+ PROP_TITLE,
+ g_param_spec_string ("title",
+ NULL, NULL,
+ NULL,
+ G_PARAM_READWRITE|
+ G_PARAM_CONSTRUCT_ONLY));
+
+ /**
+ * ParolePlugin:desc:
+ *
+ * Description of the plugin.
+ *
+ * Since: 0.1
+ **/
+ g_object_class_install_property (object_class,
+ PROP_DESC,
+ g_param_spec_string ("desc",
+ NULL, NULL,
+ NULL,
+ G_PARAM_READWRITE|
+ G_PARAM_CONSTRUCT_ONLY));
+
+ /**
+ * ParolePlugin:author:
+ *
+ * Author of the plugin.
+ *
+ * Since: 0.1
+ **/
+ g_object_class_install_property (object_class,
+ PROP_AUTHOR,
+ g_param_spec_string ("author",
+ NULL, NULL,
+ NULL,
+ G_PARAM_READWRITE|
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_type_class_add_private (klass, sizeof (ParolePluginPrivate));
+}
+
+static void
+parole_plugin_init (ParolePlugin *plugin)
+{
+ ParolePluginPrivate *priv;
+
+ priv = PAROLE_PLUGIN_GET_PRIVATE (plugin);
+
+ priv->title = NULL;
+ priv->packed = FALSE;
+
+ priv->gst = PAROLE_GST (parole_gst_new ());
+
+ priv->gst_sig1 = g_signal_connect (G_OBJECT (priv->gst), "media-state",
+ G_CALLBACK (parole_plugin_media_state_changed_cb), plugin);
+
+ priv->gst_sig2 = g_signal_connect (G_OBJECT (priv->gst), "media-tag",
+ G_CALLBACK (parole_plugin_media_tag_cb), plugin);
+}
+
+static void parole_plugin_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ ParolePlugin *plugin;
+ plugin = PAROLE_PLUGIN (object);
+
+ switch (prop_id)
+ {
+ case PROP_TITLE:
+ PAROLE_PLUGIN_GET_PRIVATE (plugin)->title = g_value_dup_string (value);
+ break;
+ case PROP_DESC:
+ PAROLE_PLUGIN_GET_PRIVATE (plugin)->desc = g_value_dup_string (value);
+ break;
+ case PROP_AUTHOR:
+ PAROLE_PLUGIN_GET_PRIVATE (plugin)->author = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void parole_plugin_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+
+ GParamSpec *pspec)
+{
+ ParolePlugin *plugin;
+ plugin = PAROLE_PLUGIN (object);
+
+ switch (prop_id)
+ {
+ case PROP_TITLE:
+ g_value_set_string (value, PAROLE_PLUGIN_GET_PRIVATE (plugin)->title);
+ break;
+ case PROP_DESC:
+ g_value_set_string (value, PAROLE_PLUGIN_GET_PRIVATE (plugin)->desc);
+ break;
+ case PROP_AUTHOR:
+ g_value_set_string (value, PAROLE_PLUGIN_GET_PRIVATE (plugin)->author);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+parole_plugin_finalize (GObject *object)
+{
+ ParolePlugin *plugin;
+ ParolePluginPrivate *priv;
+
+ plugin = PAROLE_PLUGIN (object);
+
+ priv = PAROLE_PLUGIN_GET_PRIVATE (plugin);
+
+ if ( G_IS_OBJECT (priv->gst) )
+ {
+ if (g_signal_handler_is_connected (priv->gst, priv->gst_sig1))
+ g_signal_handler_disconnect (priv->gst, priv->gst_sig1);
+
+ if ( g_signal_handler_is_connected (priv->gst, priv->gst_sig2))
+ g_signal_handler_disconnect (priv->gst, priv->gst_sig2);
+ }
+
+ if ( priv->title )
+ g_free (priv->title);
+
+ G_OBJECT_CLASS (parole_plugin_parent_class)->finalize (object);
+}
+
+
+/**
+ * parole_plugin_new:
+ * @title: title.
+ *
+ *
+ *
+ * Returns: A new #ParolePlugin object.
+ **/
+ParolePlugin *
+parole_plugin_new (const gchar *title, const gchar *desc, const gchar *author)
+{
+ ParolePlugin *plugin = NULL;
+
+ plugin = g_object_new (PAROLE_TYPE_PLUGIN,
+ "title", title,
+ "desc", desc,
+ "author", author,
+ NULL);
+ return plugin;
+}
+
+/**
+ * parole_plugin_get_main_window:
+ * @plugin: a #ParolePlugin.
+ *
+ * Get the main window of the media player.
+ *
+ * Returns: the main window widget.
+ **/
+GtkWidget *parole_plugin_get_main_window (ParolePlugin *plugin)
+{
+
+
+ return NULL;
+}
+
+/**
+ * parole_plugin_pack_widget:
+ * @plugin: a #ParolePlugin.
+ * @widget: a #GtkWidget.
+ * @container: a ParolePluginContainer type.
+ *
+ * This function inserts a tab containing the @widget, the tab can be either
+ * on the playlist when PAROLE_PLUGIN_CONTAINER_PLAYLIST is specified or in the
+ * main view when PAROLE_PLUGIN_CONTAINER_VIEW is specified.
+ *
+ *
+ * Note: You can call this function only one time.
+ **/
+void parole_plugin_pack_widget (ParolePlugin *plugin, GtkWidget *widget, ParolePluginContainer container)
+{
+ ParolePluginsManager *manager;
+ ParolePluginPrivate *priv;
+
+ g_return_if_fail (PAROLE_IS_PLUGIN (plugin));
+
+ priv = PAROLE_PLUGIN_GET_PRIVATE (plugin);
+
+ g_return_if_fail (priv->packed == FALSE);
+
+ manager = parole_plugins_manager_new ();
+
+ parole_plugins_manager_pack (manager, plugin, widget, container);
+
+ g_object_unref (manager);
+
+ priv->packed = TRUE;
+}
+
+/**
+ * parole_plugin_play_uri:
+ * @plugin: a #ParolePlugin.
+ * @uri: uri of the file to play.
+ *
+ * Play a uri.
+ *
+ * Returns: TRUE on success, FALSE otherwise.
+ **/
+gboolean parole_plugin_play_uri (ParolePlugin *plugin, const gchar *uri)
+{
+
+
+ return TRUE;
+}
+
+/**
+ * parole_plugin_play_file:
+ * @plugin: a #ParolePlugin.
+ * @file: a #ParoleMefiaFile to play.
+ *
+ * Play a #ParoleMediaFile.
+ *
+ * Returns: TRUE on success, FALSE otherwise.
+ **/
+gboolean parole_plugin_play_file (ParolePlugin *plugin, ParoleMediaFile *file)
+{
+
+
+
+ return TRUE;
+}
+
+/**
+ * parole_plugin_pause_playing:
+ * @plugin: a #ParolePlugin.
+ *
+ * Causes the media player to pause any playback.
+ *
+ * Returns: TRUE on success, FALSE otherwise.
+ **/
+gboolean parole_plugin_pause_playing (ParolePlugin *plugin)
+{
+
+ return TRUE;
+}
+
+/**
+ * parole_plugin_pause_playing:
+ * @plugin: a #ParolePlugin.
+ *
+ * Causes the media player to resume playing the currently paused stream.
+ *
+ * Returns: TRUE on success, FALSE otherwise.
+ **/
+gboolean parole_plugin_resume (ParolePlugin *plugin)
+{
+
+
+ return TRUE;
+}
+
+/**
+ * parole_plugin_stop_playing:
+ * @plugin: a #ParolePlugin.
+ *
+ * Causes the media player to stop any playback.
+ *
+ * Returns: TRUE on success, FALSE otherwise.
+ **/
+gboolean parole_plugin_stop_playing (ParolePlugin *plugin)
+{
+
+ return TRUE;
+}
+
+/**
+ * parole_plugin_seek:
+ * @plugin: a #ParolePlugin.
+ * @pos: position.
+ *
+ * Seek the current playing stream.
+ *
+ * Returns: False is the stream is not seekable or an error occurs, TRUE otherwise.
+ **/
+gboolean parole_plugin_seek (ParolePlugin *plugin, gdouble pos)
+{
+
+
+ return TRUE;
+}
Added: parole/trunk/parole/parole-plugin.h
===================================================================
--- parole/trunk/parole/parole-plugin.h (rev 0)
+++ parole/trunk/parole/parole-plugin.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,104 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PAROLE_PLUGIN_H
+#define __PAROLE_PLUGIN_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include <parole/parole-stream.h>
+#include <parole/parole-mediafile.h>
+
+G_BEGIN_DECLS
+
+#define PAROLE_TYPE_PLUGIN (parole_plugin_get_type () )
+#define PAROLE_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_PLUGIN, ParolePlugin))
+#define PAROLE_IS_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_PLUGIN))
+
+typedef struct _ParolePlugin ParolePlugin;
+typedef struct _ParolePluginClass ParolePluginClass;
+
+typedef enum
+{
+ PAROLE_PLUGIN_CONTAINER_PLAYLIST,
+ PAROLE_PLUGIN_CONTAINER_VIEW
+} ParolePluginContainer;
+
+
+typedef enum
+{
+
+ PAROLE_STATE_STOPPED,
+ PAROLE_STATE_PLAYBACK_FINISHED,
+ PAROLE_STATE_PAUSED,
+ PAROLE_STATE_PLAYING
+
+} ParoleState;
+
+struct _ParolePlugin
+{
+ GObject parent;
+};
+
+struct _ParolePluginClass
+{
+ GObjectClass parent_class;
+
+ void (*state_changed) (ParolePlugin *plugin,
+ const ParoleStream *stream,
+ ParoleState state);
+
+ void (*tag_message) (ParolePlugin *plugin,
+ const ParoleStream *stream);
+
+ void (*free_data) (ParolePlugin *plugin);
+};
+
+GType parole_plugin_get_type (void) G_GNUC_CONST;
+
+ParolePlugin *parole_plugin_new (const gchar *title,
+ const gchar *desc,
+ const gchar *author);
+
+GtkWidget *parole_plugin_get_main_window (ParolePlugin *plugin);
+
+void parole_plugin_pack_widget (ParolePlugin *plugin,
+ GtkWidget *widget,
+ ParolePluginContainer container);
+
+gboolean parole_plugin_play_uri (ParolePlugin *plugin,
+ const gchar *uri);
+
+gboolean parole_plugin_play_file (ParolePlugin *plugin,
+ ParoleMediaFile *file);
+
+gboolean parole_plugin_pause_playing (ParolePlugin *plugin);
+
+gboolean parole_plugin_resume (ParolePlugin *plugin);
+
+gboolean parole_plugin_stop_playing (ParolePlugin *plugin);
+
+gboolean parole_plugin_seek (ParolePlugin *plugin,
+ gdouble pos);
+
+G_END_DECLS
+
+#endif /* __PAROLE_PLUGIN_H */
Added: parole/trunk/parole/parole-plugins-manager.c
===================================================================
--- parole/trunk/parole/parole-plugins-manager.c (rev 0)
+++ parole/trunk/parole/parole-plugins-manager.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,201 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <libxfce4util/libxfce4util.h>
+
+#include "common/parole-builder.h"
+
+#include "parole-plugins-manager.h"
+#include "parole-module.h"
+
+static void parole_plugins_manager_finalize (GObject *object);
+
+#define PAROLE_PLUGINS_MANAGER_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_PLUGINS_MANAGER, ParolePluginsManagerPrivate))
+
+struct ParolePluginsManagerPrivate
+{
+ GtkWidget *list_nt;
+ GtkWidget *view_nt;
+
+ GPtrArray *array;
+};
+
+G_DEFINE_TYPE (ParolePluginsManager, parole_plugins_manager, G_TYPE_OBJECT)
+
+static void
+parole_plugins_manager_unload_all (gpointer data, gpointer user_data)
+{
+
+ ParoleModule *module;
+
+ module = PAROLE_MODULE (data);
+
+ g_type_module_unuse (G_TYPE_MODULE (data));
+ g_object_unref (G_OBJECT (module));
+}
+
+static void
+parole_plugins_manager_show_plugins_pref (GtkWidget *widget, ParolePluginsManager *manager)
+{
+
+}
+
+static void
+parole_plugins_manager_class_init (ParolePluginsManagerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = parole_plugins_manager_finalize;
+
+ g_type_class_add_private (klass, sizeof (ParolePluginsManagerPrivate));
+}
+
+static void
+parole_plugins_manager_init (ParolePluginsManager *manager)
+{
+ ParolePlugin *plugin;
+ GtkBuilder *builder;
+
+ manager->priv = PAROLE_PLUGINS_MANAGER_GET_PRIVATE (manager);
+
+ manager->priv->array = g_ptr_array_new ();
+
+ builder = parole_builder_get_main_interface ();
+ manager->priv->list_nt = GTK_WIDGET (gtk_builder_get_object (builder, "notebook-playlist"));
+
+ g_signal_connect (gtk_builder_get_object (builder, "plugins-menu-item"), "activate",
+ G_CALLBACK (parole_plugins_manager_show_plugins_pref), manager);
+
+ g_object_unref (builder);
+
+ plugin = parole_plugin_new (NULL, NULL, NULL);
+ g_object_unref (plugin);
+}
+
+static void
+parole_plugins_manager_finalize (GObject *object)
+{
+ ParolePluginsManager *manager;
+
+ manager = PAROLE_PLUGINS_MANAGER (object);
+
+ g_ptr_array_foreach (manager->priv->array,
+ (GFunc)parole_plugins_manager_unload_all, NULL);
+ g_ptr_array_free (manager->priv->array, TRUE);
+
+ G_OBJECT_CLASS (parole_plugins_manager_parent_class)->finalize (object);
+}
+
+static void
+parole_plugins_manager_add (ParolePluginsManager *manager, const gchar *filename)
+{
+ ParoleModule *module;
+
+ module = parole_module_new (filename);
+
+ if ( g_type_module_use (G_TYPE_MODULE (module)) )
+ g_ptr_array_add (manager->priv->array, module);
+ else
+ g_object_unref (module);
+
+}
+
+ParolePluginsManager *
+parole_plugins_manager_new (void)
+{
+ static gpointer parole_plugins_manager_object = NULL;
+
+ if ( G_LIKELY (parole_plugins_manager_object != NULL) )
+ {
+ g_object_ref (parole_plugins_manager_object);
+ }
+ else
+ {
+ parole_plugins_manager_object = g_object_new (PAROLE_TYPE_PLUGINS_MANAGER, NULL);
+ g_object_add_weak_pointer (parole_plugins_manager_object, &parole_plugins_manager_object);
+ }
+
+ return PAROLE_PLUGINS_MANAGER (parole_plugins_manager_object);
+}
+
+void parole_plugins_manager_load_plugins (ParolePluginsManager *manager)
+{
+ GDir *dir;
+ const gchar *name;
+ gchar *path;
+ GError *error = NULL;
+
+ dir = g_dir_open (PAROLE_PLUGINS_DIR, 0, &error);
+
+ if ( error )
+ {
+ g_critical ("Error opening plugins dir: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ while ( (name = g_dir_read_name (dir) ))
+ {
+ if ( g_str_has_suffix (name, "." G_MODULE_SUFFIX) )
+ {
+ path = g_build_filename (PAROLE_PLUGINS_DIR, name, NULL);
+ TRACE ("loading module with path %s", path);
+ parole_plugins_manager_add (manager, path);
+ g_free (path);
+ }
+ }
+
+ g_dir_close (dir);
+}
+
+void parole_plugins_manager_pack (ParolePluginsManager *manager, ParolePlugin *plugin,
+ GtkWidget *widget, ParolePluginContainer container)
+{
+ gchar *title;
+
+ g_object_get (G_OBJECT (plugin),
+ "title", &title,
+ NULL);
+
+ if ( container == PAROLE_PLUGIN_CONTAINER_PLAYLIST )
+ {
+ gtk_notebook_append_page (GTK_NOTEBOOK (manager->priv->list_nt), widget, gtk_label_new (title));
+ gtk_widget_show_all (widget);
+ }
+ else if ( container == PAROLE_PLUGIN_CONTAINER_VIEW )
+ {
+
+ }
+
+ if ( title )
+ g_free (title);
+
+}
Added: parole/trunk/parole/parole-plugins-manager.h
===================================================================
--- parole/trunk/parole/parole-plugins-manager.h (rev 0)
+++ parole/trunk/parole/parole-plugins-manager.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,61 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PAROLE_PLUGINS_MANAGER_H
+#define __PAROLE_PLUGINS_MANAGER_H
+
+#include <glib-object.h>
+#include "parole-plugin.h"
+
+G_BEGIN_DECLS
+
+#define PAROLE_TYPE_PLUGINS_MANAGER (parole_plugins_manager_get_type () )
+#define PAROLE_PLUGINS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_PLUGINS_MANAGER, ParolePluginsManager))
+#define PAROLE_IS_PLUGINS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_PLUGINS_MANAGER))
+
+typedef struct ParolePluginsManagerPrivate ParolePluginsManagerPrivate;
+
+typedef struct
+{
+ GObject parent;
+ ParolePluginsManagerPrivate *priv;
+
+} ParolePluginsManager;
+
+typedef struct
+{
+ GObjectClass parent_class;
+
+} ParolePluginsManagerClass;
+
+GType parole_plugins_manager_get_type (void) G_GNUC_CONST;
+
+ParolePluginsManager *parole_plugins_manager_new (void);
+
+void parole_plugins_manager_load_plugins (ParolePluginsManager *manager);
+
+void parole_plugins_manager_pack (ParolePluginsManager *manager,
+ ParolePlugin *plugin,
+ GtkWidget *widget,
+ ParolePluginContainer container);
+
+G_END_DECLS
+
+#endif /* __PAROLE_PLUGIN_MANAGER_H */
Added: parole/trunk/parole/parole-rc-utils.c
===================================================================
--- parole/trunk/parole/parole-rc-utils.c (rev 0)
+++ parole/trunk/parole/parole-rc-utils.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,101 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <libxfce4util/libxfce4util.h>
+
+#include "parole-rc-utils.h"
+
+#define MEDIA_PLAYER_RESOURCE_FILE "xfce4/parole/parole-media-player.rc"
+
+static XfceRc *
+open_resource_file (gboolean readonly)
+{
+ gchar *file;
+ XfceRc *rc;
+ file = xfce_resource_save_location (XFCE_RESOURCE_CONFIG, MEDIA_PLAYER_RESOURCE_FILE, TRUE);
+ rc = xfce_rc_simple_open (file, readonly);
+ g_free (file);
+
+ return rc;
+}
+
+void parole_rc_write_entry_bool (const gchar *property, gboolean value)
+{
+ XfceRc *rc = open_resource_file (FALSE);
+
+ xfce_rc_write_bool_entry (rc, property, value);
+ xfce_rc_close (rc);
+}
+
+void parole_rc_write_entry_int (const gchar *property, gint value)
+{
+ XfceRc *rc = open_resource_file (FALSE);
+
+ xfce_rc_write_int_entry (rc, property, value);
+ xfce_rc_close (rc);
+}
+
+void parole_rc_write_entry_string (const gchar *property, const gchar *value)
+{
+ XfceRc *rc = open_resource_file (FALSE);
+
+ xfce_rc_write_entry (rc, property, value);
+ xfce_rc_close (rc);
+}
+
+gboolean parole_rc_read_entry_bool (const gchar *property, gboolean fallback)
+{
+ XfceRc *rc = open_resource_file (TRUE);
+
+ if ( rc )
+ return xfce_rc_read_bool_entry (rc, property, fallback);
+
+ return fallback;
+}
+
+gint parole_rc_read_entry_int (const gchar *property, gint fallback)
+{
+ XfceRc *rc = open_resource_file (TRUE);
+
+ if ( rc )
+ return xfce_rc_read_int_entry (rc, property, fallback);
+
+ return fallback;
+}
+
+const gchar *parole_rc_read_entry_string (const gchar *property, const gchar *fallback)
+{
+ XfceRc *rc = open_resource_file (TRUE);
+
+ if ( rc )
+ return xfce_rc_read_entry (rc, property, fallback);
+
+ return fallback;
+}
Added: parole/trunk/parole/parole-rc-utils.h
===================================================================
--- parole/trunk/parole/parole-rc-utils.h (rev 0)
+++ parole/trunk/parole/parole-rc-utils.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,43 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __RC_UTILS_
+#define __RC_UTILS_
+
+void parole_rc_write_entry_bool (const gchar *property,
+ gboolean value);
+
+void parole_rc_write_entry_int (const gchar *property,
+ gint value);
+
+void parole_rc_write_entry_string (const gchar *property,
+ const gchar *value);
+
+gboolean parole_rc_read_entry_bool (const gchar *property,
+ gboolean fallback);
+
+gint parole_rc_read_entry_int (const gchar *property,
+ gint fallback);
+
+const gchar *parole_rc_read_entry_string (const gchar *property,
+ const gchar *fallback);
+
+
+#endif /* __RC_UTILS_ */
Added: parole/trunk/parole/parole-screensaver.c
===================================================================
--- parole/trunk/parole/parole-screensaver.c (rev 0)
+++ parole/trunk/parole/parole-screensaver.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,107 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <X11/Xlib.h>
+
+#include <gdk/gdkx.h>
+
+#include "parole-screensaver.h"
+
+#define RESET_SCREENSAVER_TIMEOUT 6
+
+#define PAROLE_SCREEN_SAVER_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_SCREENSAVER, ParoleScreenSaverPrivate))
+
+struct ParoleScreenSaverPrivate
+{
+ gulong reset_id;
+};
+
+G_DEFINE_TYPE (ParoleScreenSaver, parole_screen_saver, G_TYPE_OBJECT)
+
+
+static void
+parole_screen_saver_finalize (GObject *object)
+{
+ ParoleScreenSaver *saver;
+
+ saver = PAROLE_SCREEN_SAVER (object);
+
+ G_OBJECT_CLASS (parole_screen_saver_parent_class)->finalize (object);
+}
+
+static void
+parole_screen_saver_class_init (ParoleScreenSaverClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = parole_screen_saver_finalize;
+
+ g_type_class_add_private (klass, sizeof (ParoleScreenSaverPrivate));
+}
+
+static void
+parole_screen_saver_init (ParoleScreenSaver *saver)
+{
+ saver->priv = PAROLE_SCREEN_SAVER_GET_PRIVATE (saver);
+
+ saver->priv->reset_id = 0;
+}
+
+static gboolean
+parole_screen_saver_reset_timeout (gpointer data)
+{
+ XResetScreenSaver (GDK_DISPLAY ());
+ return TRUE;
+}
+
+ParoleScreenSaver *
+parole_screen_saver_new (void)
+{
+ ParoleScreenSaver *saver = NULL;
+ saver = g_object_new (PAROLE_TYPE_SCREENSAVER, NULL);
+ return saver;
+}
+
+void parole_screen_saver_inhibit (ParoleScreenSaver *saver)
+{
+ parole_screen_saver_uninhibit (saver);
+
+ saver->priv->reset_id = g_timeout_add_seconds (RESET_SCREENSAVER_TIMEOUT,
+ (GSourceFunc) parole_screen_saver_reset_timeout,
+ NULL);
+}
+
+void parole_screen_saver_uninhibit (ParoleScreenSaver *saver)
+{
+ if ( saver->priv->reset_id != 0 )
+ {
+ g_source_remove (saver->priv->reset_id);
+ saver->priv->reset_id = 0;
+ }
+}
Added: parole/trunk/parole/parole-screensaver.h
===================================================================
--- parole/trunk/parole/parole-screensaver.h (rev 0)
+++ parole/trunk/parole/parole-screensaver.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,56 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PAROLE_SCREEN_SAVER_H
+#define __PAROLE_SCREEN_SAVER_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define PAROLE_TYPE_SCREENSAVER (parole_screen_saver_get_type () )
+#define PAROLE_SCREEN_SAVER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_SCREENSAVER, ParoleScreenSaver))
+#define PAROLE_IS_SCREENSAVER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_SCREENSAVER))
+
+typedef struct ParoleScreenSaverPrivate ParoleScreenSaverPrivate;
+
+typedef struct
+{
+ GObject parent;
+ ParoleScreenSaverPrivate *priv;
+
+} ParoleScreenSaver;
+
+typedef struct
+{
+ GObjectClass parent_class;
+
+} ParoleScreenSaverClass;
+
+GType parole_screen_saver_get_type (void) G_GNUC_CONST;
+ParoleScreenSaver *parole_screen_saver_new (void);
+
+void parole_screen_saver_inhibit (ParoleScreenSaver *saver);
+
+void parole_screen_saver_uninhibit (ParoleScreenSaver *saver);
+
+G_END_DECLS
+
+#endif /* __PAROLE_SCREEN_SAVER_H */
Added: parole/trunk/parole/parole-sidebar.c
===================================================================
--- parole/trunk/parole/parole-sidebar.c (rev 0)
+++ parole/trunk/parole/parole-sidebar.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,197 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <glib.h>
+
+#include <libxfce4util/libxfce4util.h>
+#include <libxfcegui4/libxfcegui4.h>
+
+#include "common/parole-builder.h"
+
+#include "parole-sidebar.h"
+
+#define PAROLE_SIDEBAR_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_SIDEBAR, ParoleSidebarPrivate))
+
+struct ParoleSidebarPrivate
+{
+ GtkWidget *treeview;
+ GtkWidget *nt;
+
+ gboolean visible;
+};
+
+enum
+{
+ PIXBUF_COL,
+ NAME_COL,
+ NOTEBOOK_NUMBER,
+ COL_NUMBERS
+};
+
+G_DEFINE_TYPE (ParoleSidebar, parole_sidebar, G_TYPE_OBJECT)
+
+static void
+parole_sidebar_finalize (GObject *object)
+{
+ ParoleSidebar *sidebar;
+
+ sidebar = PAROLE_SIDEBAR (object);
+
+ G_OBJECT_CLASS (parole_sidebar_parent_class)->finalize (object);
+}
+
+static void
+parole_sidebar_class_init (ParoleSidebarClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = parole_sidebar_finalize;
+
+ g_type_class_add_private (klass, sizeof (ParoleSidebarPrivate));
+}
+
+static void
+parole_sidebar_cursor_changed_cb (ParoleSidebar *sidebar)
+{
+ GtkTreeSelection *sel;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gint int_data = 0;
+
+ sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (sidebar->priv->treeview));
+
+ if ( !gtk_tree_selection_get_selected (sel, &model, &iter))
+ return;
+
+ gtk_tree_model_get (model,
+ &iter,
+ NOTEBOOK_NUMBER,
+ &int_data,
+ -1);
+
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (sidebar->priv->nt), int_data);
+}
+
+static void
+parole_sidebar_setup (ParoleSidebar *sidebar)
+{
+ GtkListStore *list_store;
+ GtkTreeViewColumn *col;
+ GtkCellRenderer *renderer;
+ GtkTreeSelection *sel;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ GdkPixbuf *pix;
+ guint i = 0;
+
+ list_store = gtk_list_store_new (COL_NUMBERS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_INT);
+
+ gtk_tree_view_set_model (GTK_TREE_VIEW (sidebar->priv->treeview), GTK_TREE_MODEL(list_store));
+
+ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (sidebar->priv->treeview), TRUE);
+ col = gtk_tree_view_column_new ();
+
+ renderer = gtk_cell_renderer_pixbuf_new ();
+
+ gtk_tree_view_column_pack_start(col, renderer, FALSE);
+ gtk_tree_view_column_set_attributes(col, renderer, "pixbuf", PIXBUF_COL, NULL);
+
+ renderer = gtk_cell_renderer_text_new();
+
+ gtk_tree_view_column_pack_start (col, renderer, FALSE);
+ gtk_tree_view_column_set_attributes (col, renderer, "markup", NAME_COL, NULL);
+
+ gtk_tree_view_append_column (GTK_TREE_VIEW (sidebar->priv->treeview), col);
+
+ /*
+ * Multimedia tab
+ */
+ pix = xfce_themed_icon_load ("multimedia", 24);
+ gtk_list_store_append (list_store, &iter);
+ gtk_list_store_set (list_store, &iter, PIXBUF_COL, pix, NAME_COL, _("<b>Media \nplayer\n</b>"), NOTEBOOK_NUMBER, i, -1);
+ i++;
+ if ( pix )
+ g_object_unref (pix);
+
+ /*
+ * Album
+ */
+ pix = xfce_themed_icon_load ("", 24);
+ gtk_list_store_append (list_store, &iter);
+ gtk_list_store_set (list_store, &iter, PIXBUF_COL, pix, NAME_COL, _("<b>Albums\n</b>"), NOTEBOOK_NUMBER, i, -1);
+ i++;
+ if ( pix )
+ g_object_unref (pix);
+
+ g_signal_connect_swapped (G_OBJECT (sidebar->priv->treeview), "cursor_changed",
+ G_CALLBACK (parole_sidebar_cursor_changed_cb), sidebar);
+
+ sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (sidebar->priv->treeview));
+ path = gtk_tree_path_new_first ();
+ gtk_tree_selection_select_path (sel, path);
+ gtk_tree_path_free (path);
+}
+
+static void
+parole_sidebar_init (ParoleSidebar *sidebar)
+{
+ GtkBuilder *builder;
+
+ sidebar->priv = PAROLE_SIDEBAR_GET_PRIVATE (sidebar);
+
+ builder = parole_builder_get_main_interface ();
+
+ sidebar->priv->visible = TRUE;
+ sidebar->priv->treeview = GTK_WIDGET (gtk_builder_get_object (builder, "treeview"));
+ sidebar->priv->nt = GTK_WIDGET (gtk_builder_get_object (builder, "notebook"));
+
+ parole_sidebar_setup (sidebar);
+
+ g_object_unref (builder);
+}
+
+ParoleSidebar *
+parole_sidebar_new (void)
+{
+ ParoleSidebar *sidebar = NULL;
+ sidebar = g_object_new (PAROLE_TYPE_SIDEBAR, NULL);
+ return sidebar;
+}
+
+void parole_sidebar_set_visible (ParoleSidebar *sidebar, gboolean visible)
+{
+ if ( visible )
+ {
+ if ( sidebar->priv->visible )
+ gtk_widget_show_all (sidebar->priv->treeview);
+ }
+ else
+ gtk_widget_hide_all (sidebar->priv->treeview);
+}
Added: parole/trunk/parole/parole-sidebar.h
===================================================================
--- parole/trunk/parole/parole-sidebar.h (rev 0)
+++ parole/trunk/parole/parole-sidebar.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,55 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PAROLE_SIDEBAR_H
+#define __PAROLE_SIDEBAR_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define PAROLE_TYPE_SIDEBAR (parole_sidebar_get_type () )
+#define PAROLE_SIDEBAR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_SIDEBAR, ParoleSidebar))
+#define PAROLE_IS_SIDEBAR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_SIDEBAR))
+
+typedef struct ParoleSidebarPrivate ParoleSidebarPrivate;
+
+typedef struct
+{
+ GObject parent;
+ ParoleSidebarPrivate *priv;
+
+} ParoleSidebar;
+
+typedef struct
+{
+ GObjectClass parent_class;
+
+} ParoleSidebarClass;
+
+GType parole_sidebar_get_type (void) G_GNUC_CONST;
+ParoleSidebar *parole_sidebar_new (void);
+
+void parole_sidebar_set_visible (ParoleSidebar *sidebar,
+ gboolean visible);
+
+G_END_DECLS
+
+#endif /* __PAROLE_SIDEBAR_H */
Added: parole/trunk/parole/parole-statusbar.c
===================================================================
--- parole/trunk/parole/parole-statusbar.c (rev 0)
+++ parole/trunk/parole/parole-statusbar.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,150 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+
+#include <libxfcegui4/libxfcegui4.h>
+
+#include "common/parole-builder.h"
+
+#include "parole-statusbar.h"
+
+#define PAROLE_STATUSBAR_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_STATUSBAR, ParoleStatusbarPrivate))
+
+struct ParoleStatusbarPrivate
+{
+ GtkWidget *box;
+ GtkWidget *progress;
+ GtkWidget *label;
+
+ gdouble duration;
+};
+
+G_DEFINE_TYPE (ParoleStatusbar, parole_statusbar, G_TYPE_OBJECT)
+
+static void
+parole_statusbar_finalize (GObject *object)
+{
+ ParoleStatusbar *statusbar;
+
+ statusbar = PAROLE_STATUSBAR (object);
+
+ G_OBJECT_CLASS (parole_statusbar_parent_class)->finalize (object);
+}
+
+static void
+parole_statusbar_class_init (ParoleStatusbarClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = parole_statusbar_finalize;
+
+ g_type_class_add_private (klass, sizeof (ParoleStatusbarPrivate));
+}
+
+static void
+parole_statusbar_init (ParoleStatusbar *statusbar)
+{
+ GtkWidget *box;
+ GtkBuilder *builder;
+
+ statusbar->priv = PAROLE_STATUSBAR_GET_PRIVATE (statusbar);
+ statusbar->priv->duration = 0;
+
+ builder = parole_builder_get_main_interface ();
+
+ box = GTK_WIDGET (gtk_builder_get_object (builder, "statusbox"));
+
+ statusbar->priv->progress = gtk_progress_bar_new ();
+ gtk_widget_hide (statusbar->priv->progress);
+ statusbar->priv->label = gtk_label_new (NULL);
+
+ gtk_misc_set_alignment (GTK_MISC (statusbar->priv->label), 0.0, 0.5);
+
+ gtk_widget_set_size_request (statusbar->priv->progress, 180, 20);
+
+ gtk_box_pack_start (GTK_BOX (box), statusbar->priv->label, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (box), statusbar->priv->progress, FALSE, FALSE, 0);
+
+ gtk_widget_show (box);
+ gtk_widget_show (statusbar->priv->label);
+ g_object_unref (builder);
+ statusbar->priv->box = box;
+}
+
+ParoleStatusbar *
+parole_statusbar_new (void)
+{
+ ParoleStatusbar *statusbar = NULL;
+ statusbar = g_object_new (PAROLE_TYPE_STATUSBAR, NULL);
+ return statusbar;
+}
+
+void parole_statusbar_set_text (ParoleStatusbar *bar, const gchar *text)
+{
+ gtk_label_set_text (GTK_LABEL (bar->priv->label), text);
+ gtk_widget_show (bar->priv->label);
+ gtk_widget_hide (bar->priv->progress);
+}
+
+void parole_statusbar_set_duration (ParoleStatusbar *bar, gdouble duration)
+{
+ bar->priv->duration = duration;
+}
+
+void parole_statusbar_set_position (ParoleStatusbar *bar, gboolean playing, gdouble position)
+{
+ gchar *text;
+
+ if ( bar->priv->duration != 0)
+ text = g_strdup_printf ("%s %4.2f/%4.2f", playing ? _("Playing") : ("Paused"), position, bar->priv->duration);
+ else
+ text = g_strdup_printf ("%s %4.2f", playing ? _("Playing") : ("Paused"), position);
+
+ parole_statusbar_set_text (bar, text);
+ g_free (text);
+}
+
+void parole_statusbar_set_buffering (ParoleStatusbar *bar, gint percentage)
+{
+ gchar *buff;
+
+ buff = g_strdup_printf ("%s %d%%", _("Buffering"), percentage);
+
+ gtk_progress_bar_set_text (GTK_PROGRESS_BAR (bar->priv->progress), buff);
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (bar->priv->progress), (gdouble) percentage/100);
+ gtk_widget_hide (bar->priv->label);
+ gtk_widget_show (bar->priv->progress);
+ g_free (buff);
+}
+
+void parole_statusbar_set_visible (ParoleStatusbar *bar, gboolean visible)
+{
+ visible ? gtk_widget_show (bar->priv->box) : gtk_widget_hide (bar->priv->box);
+}
Added: parole/trunk/parole/parole-statusbar.h
===================================================================
--- parole/trunk/parole/parole-statusbar.h (rev 0)
+++ parole/trunk/parole/parole-statusbar.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,68 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PAROLE_STATUSBAR_H
+#define __PAROLE_STATUSBAR_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define PAROLE_TYPE_STATUSBAR (parole_statusbar_get_type () )
+#define PAROLE_STATUSBAR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_STATUSBAR, ParoleStatusbar))
+#define PAROLE_IS_STATUSBAR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_STATUSBAR))
+
+typedef struct ParoleStatusbarPrivate ParoleStatusbarPrivate;
+
+typedef struct
+{
+ GObject parent;
+ ParoleStatusbarPrivate *priv;
+
+} ParoleStatusbar;
+
+typedef struct
+{
+ GObjectClass parent_class;
+
+} ParoleStatusbarClass;
+
+GType parole_statusbar_get_type (void) G_GNUC_CONST;
+ParoleStatusbar *parole_statusbar_new (void);
+
+void parole_statusbar_set_text (ParoleStatusbar *bar,
+ const gchar *text);
+
+void parole_statusbar_set_duration (ParoleStatusbar *bar,
+ gdouble duration);
+
+void parole_statusbar_set_position (ParoleStatusbar *bar,
+ gboolean playing,
+ gdouble position);
+
+void parole_statusbar_set_buffering (ParoleStatusbar *bar,
+ gint percentage);
+
+void parole_statusbar_set_visible (ParoleStatusbar *bar,
+ gboolean visible);
+
+G_END_DECLS
+
+#endif /* __PAROLE_STATUSBAR_H */
Added: parole/trunk/parole/parole-stream.c
===================================================================
--- parole/trunk/parole/parole-stream.c (rev 0)
+++ parole/trunk/parole/parole-stream.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,429 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include "parole-stream.h"
+#include "parole-mediafile.h"
+
+#define PAROLE_STREAM_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_STREAM, ParoleStreamPrivate))
+
+#define PAROLE_STREAM_FREE_STR_PROP(str) \
+ if ( str ) \
+ g_free (str); \
+ str = NULL; \
+
+#define PAROLE_STREAM_DUP_GVALUE_STRING(str, value) \
+ PAROLE_STREAM_FREE_STR_PROP (str); \
+ str = g_value_dup_string (value); \
+
+typedef struct _ParoleStreamPrivate ParoleStreamPrivate;
+
+struct _ParoleStreamPrivate
+{
+ /*Properties*/
+ gpointer media_file;
+
+ gboolean has_audio;
+ gboolean has_video;
+ gboolean live;
+ gboolean seekable;
+ gdouble duration;
+ gint64 absolute_duration;
+
+ gchar *title;
+ gchar *artist;
+ gchar *year;
+ gchar *album;
+ gchar *comment;
+};
+
+enum
+{
+ PROP_0,
+ PROP_MEDIA_FILE,
+ PROP_LIVE,
+ PROP_HAS_AUDIO,
+ PROP_HAS_VIDEO,
+ PROP_SEEKABLE,
+ PROP_DURATION,
+ PROP_ABSOLUTE_DURATION,
+ PROP_TITLE,
+ PROP_ARTIST,
+ PROP_YEAR,
+ PROP_ALBUM,
+ PROP_COMMENT
+};
+
+G_DEFINE_TYPE (ParoleStream, parole_stream, G_TYPE_OBJECT)
+
+static void parole_stream_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ ParoleStream *stream;
+ stream = PAROLE_STREAM (object);
+
+ switch (prop_id)
+ {
+ case PROP_LIVE:
+ PAROLE_STREAM_GET_PRIVATE (stream)->live = g_value_get_boolean (value);
+ break;
+ case PROP_HAS_AUDIO:
+ PAROLE_STREAM_GET_PRIVATE (stream)->has_audio = g_value_get_boolean (value);
+ break;
+ case PROP_HAS_VIDEO:
+ PAROLE_STREAM_GET_PRIVATE (stream)->has_video = g_value_get_boolean (value);
+ break;
+ case PROP_MEDIA_FILE:
+ PAROLE_STREAM_GET_PRIVATE (stream)->media_file = g_value_get_object (value);
+ break;
+ case PROP_SEEKABLE:
+ PAROLE_STREAM_GET_PRIVATE (stream)->seekable = g_value_get_boolean (value);
+ break;
+ case PROP_DURATION:
+ PAROLE_STREAM_GET_PRIVATE (stream)->duration = g_value_get_double (value);
+ break;
+ case PROP_ABSOLUTE_DURATION:
+ PAROLE_STREAM_GET_PRIVATE (stream)->absolute_duration = g_value_get_int64 (value);
+ break;
+ case PROP_TITLE:
+ PAROLE_STREAM_DUP_GVALUE_STRING (PAROLE_STREAM_GET_PRIVATE (stream)->title, value);
+ break;
+ case PROP_ARTIST:
+ PAROLE_STREAM_DUP_GVALUE_STRING (PAROLE_STREAM_GET_PRIVATE (stream)->artist, value);
+ break;
+ case PROP_YEAR:
+ PAROLE_STREAM_DUP_GVALUE_STRING (PAROLE_STREAM_GET_PRIVATE (stream)->year, value);
+ break;
+ case PROP_ALBUM:
+ PAROLE_STREAM_DUP_GVALUE_STRING (PAROLE_STREAM_GET_PRIVATE (stream)->album, value);
+ break;
+ case PROP_COMMENT:
+ PAROLE_STREAM_DUP_GVALUE_STRING (PAROLE_STREAM_GET_PRIVATE (stream)->comment, value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void parole_stream_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ ParoleStream *stream;
+ stream = PAROLE_STREAM (object);
+
+ switch (prop_id)
+ {
+ case PROP_LIVE:
+ g_value_set_boolean (value, PAROLE_STREAM_GET_PRIVATE (stream)->live);
+ break;
+ case PROP_HAS_AUDIO:
+ g_value_set_boolean (value, PAROLE_STREAM_GET_PRIVATE (stream)->has_audio);
+ break;
+ case PROP_HAS_VIDEO:
+ g_value_set_boolean (value, PAROLE_STREAM_GET_PRIVATE (stream)->has_video);
+ break;
+ case PROP_MEDIA_FILE:
+ g_value_set_object (value, PAROLE_STREAM_GET_PRIVATE (stream)->media_file);
+ break;
+ case PROP_SEEKABLE:
+ g_value_set_boolean (value, PAROLE_STREAM_GET_PRIVATE (stream)->seekable);
+ break;
+ case PROP_DURATION:
+ g_value_set_double (value, PAROLE_STREAM_GET_PRIVATE (stream)->duration);
+ break;
+ case PROP_ABSOLUTE_DURATION:
+ g_value_set_int64 (value, PAROLE_STREAM_GET_PRIVATE (stream)->absolute_duration);
+ break;
+ case PROP_TITLE:
+ g_value_set_string (value, PAROLE_STREAM_GET_PRIVATE (stream)->title);
+ break;
+ case PROP_ARTIST:
+ g_value_set_string (value, PAROLE_STREAM_GET_PRIVATE (stream)->artist);
+ break;
+ case PROP_YEAR:
+ g_value_set_string (value, PAROLE_STREAM_GET_PRIVATE (stream)->year);
+ break;
+ case PROP_ALBUM:
+ g_value_set_string (value, PAROLE_STREAM_GET_PRIVATE (stream)->album);
+ break;
+ case PROP_COMMENT:
+ g_value_set_string (value, PAROLE_STREAM_GET_PRIVATE (stream)->comment);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+parole_stream_finalize (GObject *object)
+{
+ ParoleStream *stream;
+ ParoleStreamPrivate *priv;
+
+ stream = PAROLE_STREAM (object);
+ priv = PAROLE_STREAM_GET_PRIVATE (stream);
+
+ if ( priv->media_file )
+ g_object_unref (priv->media_file);
+
+ G_OBJECT_CLASS (parole_stream_parent_class)->finalize (object);
+}
+
+static void
+parole_stream_class_init (ParoleStreamClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = parole_stream_finalize;
+
+ object_class->get_property = parole_stream_get_property;
+ object_class->set_property = parole_stream_set_property;
+
+ /**
+ * ParoleStream:media-file:
+ *
+ * Currently playing #ParoleMediaFile.
+ *
+ * Since: 0.1
+ **/
+ g_object_class_install_property (object_class,
+ PROP_MEDIA_FILE,
+ g_param_spec_object ("media-file",
+ NULL, NULL,
+ PAROLE_TYPE_MEDIA_FILE,
+ G_PARAM_READWRITE));
+
+ /**
+ * ParoleStream:has-audio:
+ *
+ * Whether the stream has audio.
+ *
+ * Since: 0.1
+ **/
+ g_object_class_install_property (object_class,
+ PROP_HAS_AUDIO,
+ g_param_spec_boolean ("has-audio",
+ NULL, NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+ /**
+ * ParoleStream:has-video:
+ *
+ * Whether the stream has video.
+ *
+ * Since: 0.1
+ **/
+ g_object_class_install_property (object_class,
+ PROP_HAS_VIDEO,
+ g_param_spec_boolean ("has-video",
+ NULL, NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ /**
+ * ParoleStream:live:
+ *
+ * Whether the stream is a live stream.
+ *
+ * Since: 0.1
+ **/
+ g_object_class_install_property (object_class,
+ PROP_LIVE,
+ g_param_spec_boolean ("live",
+ NULL, NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ /**
+ * ParoleStream:seekable:
+ *
+ * Whether the stream is seekable, for example live
+ * streams are not seekable.
+ *
+ * Since: 0.1
+ **/
+ g_object_class_install_property (object_class,
+ PROP_SEEKABLE,
+ g_param_spec_boolean ("seekable",
+ NULL, NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ /**
+ * ParoleStream:duration:
+ *
+ *
+ *
+ * Since: 0.1
+ **/
+ g_object_class_install_property (object_class,
+ PROP_DURATION,
+ g_param_spec_double("duration",
+ NULL, NULL,
+ 0, G_MAXDOUBLE,
+ 0,
+ G_PARAM_READWRITE));
+
+ /**
+ * ParoleStream:absolute-duration:
+ *
+ *
+ *
+ * Since: 0.1
+ **/
+ g_object_class_install_property (object_class,
+ PROP_ABSOLUTE_DURATION,
+ g_param_spec_int64 ("absolute-duration",
+ NULL, NULL,
+ 0, G_MAXINT64,
+ 0,
+ G_PARAM_READWRITE));
+
+ /**
+ * ParoleStream:title:
+ *
+ *
+ *
+ * Since: 0.1
+ **/
+ g_object_class_install_property (object_class,
+ PROP_TITLE,
+ g_param_spec_string ("title",
+ NULL, NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+
+ /**
+ * ParoleStream:artist:
+ *
+ *
+ *
+ * Since: 0.1
+ **/
+ g_object_class_install_property (object_class,
+ PROP_ARTIST,
+ g_param_spec_string ("artist",
+ NULL, NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * ParoleStream:year:
+ *
+ *
+ *
+ * Since: 0.1
+ **/
+ g_object_class_install_property (object_class,
+ PROP_YEAR,
+ g_param_spec_string ("year",
+ NULL, NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * ParoleStream:album:
+ *
+ *
+ *
+ * Since: 0.1
+ **/
+ g_object_class_install_property (object_class,
+ PROP_ALBUM,
+ g_param_spec_string ("album",
+ NULL, NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * ParoleStream:comment:
+ *
+ *
+ *
+ * Since: 0.1
+ **/
+ g_object_class_install_property (object_class,
+ PROP_COMMENT,
+ g_param_spec_string ("comment",
+ NULL, NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_type_class_add_private (klass, sizeof (ParoleStreamPrivate));
+}
+
+static void
+parole_stream_init (ParoleStream *stream)
+{
+ ParoleStreamPrivate *priv;
+ priv = PAROLE_STREAM_GET_PRIVATE (stream);
+
+ priv->media_file = NULL;
+ parole_stream_init_properties (stream);
+}
+
+ParoleStream *
+parole_stream_new (void)
+{
+ ParoleStream *stream = NULL;
+ stream = g_object_new (PAROLE_TYPE_STREAM, NULL);
+ return stream;
+}
+
+void parole_stream_init_properties (ParoleStream *stream)
+{
+ ParoleStreamPrivate *priv;
+
+ priv = PAROLE_STREAM_GET_PRIVATE (stream);
+ priv->live = FALSE;
+ priv->seekable = FALSE;
+ priv->has_audio = FALSE;
+ priv->has_video = FALSE;
+ priv->absolute_duration = 0;
+ priv->duration = 0;
+
+ if ( priv->media_file )
+ g_object_unref (priv->media_file);
+
+ PAROLE_STREAM_FREE_STR_PROP (priv->title);
+ PAROLE_STREAM_FREE_STR_PROP (priv->artist);
+ PAROLE_STREAM_FREE_STR_PROP (priv->year);
+ PAROLE_STREAM_FREE_STR_PROP (priv->album);
+ PAROLE_STREAM_FREE_STR_PROP (priv->comment);
+
+ priv->media_file = NULL;
+}
Added: parole/trunk/parole/parole-stream.h
===================================================================
--- parole/trunk/parole/parole-stream.h (rev 0)
+++ parole/trunk/parole/parole-stream.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,54 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PAROLE_STREAM_H
+#define __PAROLE_STREAM_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define PAROLE_TYPE_STREAM (parole_stream_get_type () )
+#define PAROLE_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_STREAM, ParoleStream))
+#define PAROLE_IS_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_STREAM))
+
+typedef struct _ParoleStream ParoleStream;
+typedef struct _ParoleStreamClass ParoleStreamClass;
+
+struct _ParoleStream
+{
+ GObject parent;
+
+};
+
+struct _ParoleStreamClass
+{
+ GObjectClass parent_class;
+};
+
+GType parole_stream_get_type (void) G_GNUC_CONST;
+
+ParoleStream *parole_stream_new (void);
+
+void parole_stream_init_properties (ParoleStream *stream);
+
+G_END_DECLS
+
+#endif /* __PAROLE_STREAM_H */
Added: parole/trunk/parole/parole-utils.c
===================================================================
--- parole/trunk/parole/parole-utils.c (rev 0)
+++ parole/trunk/parole/parole-utils.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,348 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gst/gst.h>
+#include <glib.h>
+
+#include <libxfce4util/libxfce4util.h>
+
+#include "parole-utils.h"
+
+/* List from xine-lib's demux_sputext.c */
+static const char subtitle_ext[][4] = {
+ "asc",
+ "txt",
+ "sub",
+ "srt",
+ "smi",
+ "ssa",
+ "ass"
+};
+
+void parole_window_busy_cursor (GdkWindow *window)
+{
+ GdkCursor *cursor;
+
+ if ( G_UNLIKELY (window == NULL) )
+ return;
+
+ cursor = gdk_cursor_new (GDK_WATCH);
+ gdk_window_set_cursor (window, cursor);
+ gdk_cursor_unref (cursor);
+
+ gdk_flush ();
+}
+
+void parole_window_invisible_cursor (GdkWindow *window)
+{
+ GdkBitmap *empty_bitmap;
+ GdkCursor *cursor;
+ GdkColor color;
+
+ char cursor_bits[] = { 0x0 };
+
+ if ( G_UNLIKELY (window == NULL) )
+ return;
+
+ color.red = color.green = color.blue = 0;
+ color.pixel = 0;
+
+ empty_bitmap = gdk_bitmap_create_from_data (window,
+ cursor_bits,
+ 1, 1);
+
+ cursor = gdk_cursor_new_from_pixmap (empty_bitmap,
+ empty_bitmap,
+ &color,
+ &color, 0, 0);
+
+ gdk_window_set_cursor (window, cursor);
+
+ gdk_cursor_unref (cursor);
+
+ g_object_unref (empty_bitmap);
+}
+
+/*
+ * compare_by_name_using_number
+ *
+ * * Copyright (c) 2005-2007 Benedikt Meurer <benny at xfce.org>
+ *
+ */
+static gint
+compare_by_name_using_number (const gchar *ap,
+ const gchar *bp)
+{
+ guint anum;
+ guint bnum;
+
+ /* determine the numbers in ap and bp */
+ anum = strtoul (ap, NULL, 10);
+ bnum = strtoul (bp, NULL, 10);
+
+ /* compare the numbers */
+ if (anum < bnum)
+ return -1;
+ else if (anum > bnum)
+ return 1;
+
+ /* the numbers are equal, and so the higher first digit should
+ * be sorted first, i.e. 'file10' before 'file010', since we
+ * also sort 'file10' before 'file011'.
+ */
+ return (*bp - *ap);
+}
+
+/*
+ * thunar_file_compare_by_name
+ *
+ * * Copyright (c) 2005-2007 Benedikt Meurer <benny at xfce.org>
+ *
+ */
+gint
+thunar_file_compare_by_name (ParoleMediaFile *file_a,
+ ParoleMediaFile *file_b,
+ gboolean case_sensitive)
+{
+ const gchar *ap;
+ const gchar *bp;
+ guint ac;
+ guint bc;
+
+
+ /* we compare only the display names (UTF-8!) */
+ ap = parole_media_file_get_display_name (file_a);
+ bp = parole_media_file_get_display_name (file_b);
+
+ /* check if we should ignore case */
+ if (G_LIKELY (case_sensitive))
+ {
+ /* try simple (fast) ASCII comparison first */
+ for (;; ++ap, ++bp)
+ {
+ /* check if the characters differ or we have a non-ASCII char */
+ ac = *((const guchar *) ap);
+ bc = *((const guchar *) bp);
+ if (ac != bc || ac == 0 || ac > 127)
+ break;
+ }
+
+ /* fallback to Unicode comparison */
+ if (G_UNLIKELY (ac > 127 || bc > 127))
+ {
+ for (;; ap = g_utf8_next_char (ap), bp = g_utf8_next_char (bp))
+ {
+ /* check if characters differ or end of string */
+ ac = g_utf8_get_char (ap);
+ bc = g_utf8_get_char (bp);
+ if (ac != bc || ac == 0)
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* try simple (fast) ASCII comparison first (case-insensitive!) */
+ for (;; ++ap, ++bp)
+ {
+ /* check if the characters differ or we have a non-ASCII char */
+ ac = *((const guchar *) ap);
+ bc = *((const guchar *) bp);
+ if (g_ascii_tolower (ac) != g_ascii_tolower (bc) || ac == 0 || ac > 127)
+ break;
+ }
+
+ /* fallback to Unicode comparison (case-insensitive!) */
+ if (G_UNLIKELY (ac > 127 || bc > 127))
+ {
+ for (;; ap = g_utf8_next_char (ap), bp = g_utf8_next_char (bp))
+ {
+ /* check if characters differ or end of string */
+ ac = g_utf8_get_char (ap);
+ bc = g_utf8_get_char (bp);
+ if (g_unichar_tolower (ac) != g_unichar_tolower (bc) || ac == 0)
+ break;
+ }
+ }
+ }
+
+ /* if both strings are equal, we're done */
+ if (G_UNLIKELY (ac == bc || (!case_sensitive && g_unichar_tolower (ac) == g_unichar_tolower (bc))))
+ return 0;
+
+ /* check if one of the characters that differ is a digit */
+ if (G_UNLIKELY (g_ascii_isdigit (ac) || g_ascii_isdigit (bc)))
+ {
+ /* if both strings differ in a digit, we use a smarter comparison
+ * to get sorting 'file1', 'file5', 'file10' done the right way.
+ */
+ if (g_ascii_isdigit (ac) && g_ascii_isdigit (bc))
+ return compare_by_name_using_number (ap, bp);
+
+ /* a second case is '20 file' and '2file', where comparison by number
+ * makes sense, if the previous char for both strings is a digit.
+ */
+ if (ap > parole_media_file_get_display_name (file_a) && bp > parole_media_file_get_display_name (file_b)
+ && g_ascii_isdigit (*(ap - 1)) && g_ascii_isdigit (*(bp - 1)))
+ {
+ return compare_by_name_using_number (ap - 1, bp - 1);
+ }
+ }
+
+ /* otherwise, if they differ in a unicode char, use the
+ * appropriate collate function for the current locale (only
+ * if charset is UTF-8, else the required transformations
+ * would be too expensive)
+ */
+#ifdef HAVE_STRCOLL
+ if ((ac > 127 || bc > 127) && g_get_charset (NULL))
+ {
+ /* case-sensitive is easy, case-insensitive is expensive,
+ * but we use a simple optimization to make it fast.
+ */
+ if (G_LIKELY (case_sensitive))
+ {
+ return strcoll (ap, bp);
+ }
+ else
+ {
+ /* we use a trick here, so we don't need to allocate
+ * and transform the two strings completely first (8
+ * byte for each buffer, so all compilers should align
+ * them properly)
+ */
+ gchar abuf[8];
+ gchar bbuf[8];
+
+ /* transform the unicode chars to strings and
+ * make sure the strings are nul-terminated.
+ */
+ abuf[g_unichar_to_utf8 (ac, abuf)] = '\0';
+ bbuf[g_unichar_to_utf8 (bc, bbuf)] = '\0';
+
+ /* compare the unicode chars (as strings) */
+ return strcoll (abuf, bbuf);
+ }
+ }
+#endif
+
+ /* else, they differ in an ASCII character */
+ if (G_UNLIKELY (!case_sensitive))
+ return (g_unichar_tolower (ac) > g_unichar_tolower (bc)) ? 1 : -1;
+ else
+ return (ac > bc) ? 1 : -1;
+}
+
+gchar *
+parole_get_name_without_extension (const gchar *name)
+{
+ guint len, suffix;
+ gchar *ret;
+
+ len = strlen (name);
+
+ for ( suffix = len -1; suffix > 0; suffix--)
+ {
+ if ( name [suffix] == '.' )
+ break;
+ }
+
+ ret = g_strndup (name, sizeof (char) * (suffix));
+ return ret;
+}
+
+static gchar *
+parole_get_subtitle_in_dir (const gchar *dir_path, const gchar *file)
+{
+ gchar *sub_path = NULL;
+ gchar *file_no_ext;
+ guint i;
+
+ file_no_ext = parole_get_name_without_extension (file);
+
+ for ( i = 0; i < G_N_ELEMENTS (subtitle_ext); i++)
+ {
+ sub_path = g_strdup_printf ("%s/%s.%s", dir_path, file_no_ext, subtitle_ext[i]);
+
+ if ( g_file_test (sub_path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR ) )
+ break;
+
+ g_free (sub_path);
+ sub_path = NULL;
+ }
+ g_free (file_no_ext);
+
+ return sub_path;
+}
+
+gchar *parole_get_subtitle_path (const gchar *uri)
+{
+ GFile *file, *parent;
+ GFileInfo *info;
+ GError *error = NULL;
+ gchar *path;
+ gchar *file_name;
+ gchar *ret = NULL;
+
+ file = g_file_new_for_commandline_arg (uri);
+ parent = g_file_get_parent (file);
+
+ if ( !parent )
+ {
+ g_object_unref (file);
+ return NULL;
+ }
+
+ info = g_file_query_info (file,
+ "standard::*,",
+ 0,
+ NULL,
+ &error);
+
+ if ( error )
+ {
+ g_warning ("%s: \n", error->message);
+ g_error_free (error);
+ return NULL;
+ }
+
+ file_name = g_strdup (g_file_info_get_display_name (info));
+
+ path = g_file_get_path (parent);
+
+ ret = parole_get_subtitle_in_dir (path, file_name);
+
+ g_object_unref (file);
+ g_object_unref (parent);
+ g_object_unref (info);
+
+ g_free (file_name);
+ g_free (path);
+
+ return ret;
+}
Added: parole/trunk/parole/parole-utils.h
===================================================================
--- parole/trunk/parole/parole-utils.h (rev 0)
+++ parole/trunk/parole/parole-utils.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,41 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PAROLE_UTILS_H_
+#define __PAROLE_UTILS_H_
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include "parole-mediafile.h"
+
+void parole_window_busy_cursor (GdkWindow *window);
+
+void parole_window_invisible_cursor (GdkWindow *window);
+
+gint thunar_file_compare_by_name (ParoleMediaFile *file_a,
+ ParoleMediaFile *file_b,
+ gboolean case_sensitive);
+
+gchar *parole_get_name_without_extension (const gchar *name)G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+
+gchar *parole_get_subtitle_path (const gchar *uri) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+
+#endif /* __PAROLE_UTILS_ */
Added: parole/trunk/parole/parole-vis.c
===================================================================
--- parole/trunk/parole/parole-vis.c (rev 0)
+++ parole/trunk/parole/parole-vis.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,73 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gst/gst.h>
+#include <glib.h>
+
+#include "parole-vis.h"
+
+static gboolean
+parole_vis_filter (GstPluginFeature *feature, gpointer data)
+{
+ GstElementFactory *factory;
+
+ if ( !GST_IS_ELEMENT_FACTORY (feature) )
+ return FALSE;
+
+ factory = GST_ELEMENT_FACTORY (feature);
+
+ if ( !g_strrstr (gst_element_factory_get_klass (factory), "Visualization"))
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+parole_vis_get_name (GstElementFactory *factory, GHashTable **hash)
+{
+ g_hash_table_insert (*hash, g_strdup (gst_element_factory_get_longname (factory)), factory);
+}
+
+GHashTable *parole_vis_get_plugins (void)
+{
+ GList *plugins = NULL;
+ GHashTable *hash;
+
+ hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+ plugins = gst_registry_feature_filter (gst_registry_get_default (),
+ parole_vis_filter,
+ FALSE,
+ NULL);
+
+ g_list_foreach (plugins, (GFunc) parole_vis_get_name, &hash);
+
+ gst_plugin_feature_list_free (plugins);
+
+ return hash;
+}
Added: parole/trunk/parole/parole-vis.h
===================================================================
--- parole/trunk/parole/parole-vis.h (rev 0)
+++ parole/trunk/parole/parole-vis.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,31 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PAROLE_VIS_H_
+#define __PAROLE_VIS_H_
+
+#include <gst/gst.h>
+#include <glib.h>
+
+GHashTable *parole_vis_get_plugins (void);
+
+//GstElement *parole_vis_get_for_name (void)
+
+#endif /* __PAROLE_VIS_H_ */
Added: parole/trunk/parole/parole.h
===================================================================
--- parole/trunk/parole/parole.h (rev 0)
+++ parole/trunk/parole/parole.h 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,53 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <parole/parole-plugin.h>
+
+ParolePlugin *parole_plugin_constructor (void);
+
+/**
+ * ParolePluginConstruct:
+ * @plugin: A #ParolePlugin.
+ *
+ * Argument registration function to be used with
+ * the registration macro PAROLE_PLUGIN_CONSTRUCT().
+ *
+ **/
+typedef void (*ParolePluginConstruct) (ParolePlugin *plugin);
+
+/**
+ * PAROLE_PLUGIN_CONSTRUCT:
+ * @construct: a function that can be cast to #ParolePluginConstruct type.
+ * @title: title.
+ * @desc: description.
+ * @author: author.
+ *
+ **/
+#define PAROLE_PLUGIN_CONSTRUCT(construct, title, desc, author) \
+ G_MODULE_EXPORT ParolePlugin *parole_plugin_constructor (void) \
+ { \
+ ParolePlugin *plugin; \
+ ParolePluginConstruct constructor \
+ = (ParolePluginConstruct) construct; \
+ \
+ plugin = parole_plugin_new (title, desc, author); \
+ constructor (plugin); \
+ return plugin; \
+ }
Added: parole/trunk/plugins/Makefile.am
===================================================================
--- parole/trunk/plugins/Makefile.am (rev 0)
+++ parole/trunk/plugins/Makefile.am 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,5 @@
+SUBDIRS =
+
+if PAROLE_PROPERTIES_PLUGIN
+SUBDIRS+=properties
+endif
Added: parole/trunk/plugins/properties/Makefile.am
===================================================================
--- parole/trunk/plugins/properties/Makefile.am (rev 0)
+++ parole/trunk/plugins/properties/Makefile.am 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,25 @@
+INCLUDES = \
+ -I$(top_builddir) \
+ -I$(top_srcdir) \
+ -DG_LOG_DOMAIN=\"stream_properties\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
+ -DPACKAGE_LOCALE_DIR=\"$(localedir)\"
+
+pluginsdir = \
+ $(libdir)/parole-$(PAROLE_VERSION_API)
+
+plugins_LTLIBRARIES = \
+ stream-properties.la
+
+stream_properties_la_SOURCES = \
+ stream-properties.c
+
+stream_properties_la_CFLAGS = \
+ $(PLATFORM_CFLAGS) \
+ $(GTK_CFLAGS)
+
+stream_properties_la_LDFLAGS = \
+ -avoid-version \
+ -export-dynamic \
+ -module \
+ $(PLATFORM_LDFLAGS)
Added: parole/trunk/plugins/properties/stream-properties.c
===================================================================
--- parole/trunk/plugins/properties/stream-properties.c (rev 0)
+++ parole/trunk/plugins/properties/stream-properties.c 2009-07-16 15:03:06 UTC (rev 7735)
@@ -0,0 +1,286 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include <parole/parole.h>
+
+typedef struct
+{
+ GtkWidget *title;
+ GtkWidget *artist;
+ GtkWidget *album;
+ GtkWidget *year;
+ GtkWidget *comment;
+
+} PluginData;
+
+static void
+init_media_tag_entries (PluginData *data)
+{
+ gtk_entry_set_text (GTK_ENTRY (data->title), _("Unknown"));
+ gtk_entry_set_text (GTK_ENTRY (data->artist), _("Unknown"));
+ gtk_entry_set_text (GTK_ENTRY (data->album), _("Unknown"));
+ gtk_entry_set_text (GTK_ENTRY (data->year), _("Unknown"));
+ gtk_entry_set_text (GTK_ENTRY (data->comment), _("Unknown"));
+}
+
+static GtkWidget *create_properties_widget (PluginData *data)
+{
+ PangoFontDescription *pfd;
+
+ GtkWidget *label;
+ GtkWidget *vbox;
+ GtkWidget *table;
+ GtkWidget *align;
+ guint i = 0;
+
+ vbox = gtk_vbox_new (FALSE, 0);
+ table = gtk_table_new (5, 2, FALSE);
+ pfd = pango_font_description_from_string("bold");
+
+ /*
+ * Title
+ */
+ align = gtk_alignment_new (0.0, 0.5, 0, 0);
+
+ label = gtk_label_new (_("Title:"));
+ gtk_container_add (GTK_CONTAINER(align), label);
+ gtk_widget_modify_font (label, pfd);
+
+ gtk_table_attach (GTK_TABLE(table), align,
+ 0, 1, i, i+1,
+ GTK_SHRINK, GTK_SHRINK,
+ 2, 8);
+
+ data->title = gtk_entry_new ();
+ align = gtk_alignment_new (0.0, 0.5, 0, 0);
+ gtk_container_add (GTK_CONTAINER (align), data->title);
+ gtk_table_attach (GTK_TABLE (table), align,
+ 1, 2, i, i+1,
+ GTK_SHRINK, GTK_SHRINK,
+ 2, 8);
+ i++;
+
+ /*
+ * Artist
+ */
+ align = gtk_alignment_new (0.0, 0.5, 0, 0);
+
+ label = gtk_label_new (_("Artist:"));
+ gtk_container_add (GTK_CONTAINER(align), label);
+ gtk_widget_modify_font (label, pfd);
+
+ gtk_table_attach (GTK_TABLE(table), align,
+ 0, 1, i, i+1,
+ GTK_SHRINK, GTK_SHRINK,
+ 2, 8);
+
+ data->artist = gtk_entry_new ();
+ align = gtk_alignment_new (0.0, 0.5, 0, 0);
+ gtk_container_add (GTK_CONTAINER (align), data->artist);
+ gtk_table_attach (GTK_TABLE (table), align,
+ 1, 2, i, i+1,
+ GTK_SHRINK, GTK_SHRINK,
+ 2, 8);
+ i++;
+
+ /*
+ * Album
+ */
+ align = gtk_alignment_new (0.0, 0.5, 0, 0);
+
+ label = gtk_label_new (_("Album:"));
+ gtk_container_add (GTK_CONTAINER(align), label);
+ gtk_widget_modify_font (label, pfd);
+
+ gtk_table_attach (GTK_TABLE(table), align,
+ 0, 1, i, i+1,
+ GTK_SHRINK, GTK_SHRINK,
+ 2, 8);
+
+ data->album = gtk_entry_new ();
+ align = gtk_alignment_new (0.0, 0.5, 0, 0);
+ gtk_container_add (GTK_CONTAINER (align), data->album);
+ gtk_table_attach (GTK_TABLE (table), align,
+ 1, 2, i, i+1,
+ GTK_SHRINK, GTK_SHRINK,
+ 2, 8);
+ i++;
+
+ /*
+ * Year
+ */
+ align = gtk_alignment_new (0.0, 0.5, 0, 0);
+
+ label = gtk_label_new (_("Year:"));
+ gtk_container_add (GTK_CONTAINER (align), label);
+ gtk_widget_modify_font (label, pfd);
+
+ gtk_table_attach (GTK_TABLE(table), align,
+ 0, 1, i, i+1,
+ GTK_SHRINK, GTK_SHRINK,
+ 2, 8);
+
+ data->year = gtk_entry_new ();
+ align = gtk_alignment_new (0.0, 0.5, 0, 0);
+ gtk_container_add (GTK_CONTAINER (align), data->year);
+ gtk_table_attach (GTK_TABLE (table), align,
+ 1, 2, i, i+1,
+ GTK_SHRINK, GTK_SHRINK,
+ 2, 8);
+ i++;
+
+ /*
+ * Comment
+ */
+ align = gtk_alignment_new (0.0, 0.5, 0, 0);
+
+ label = gtk_label_new (_("Comment:"));
+ gtk_container_add (GTK_CONTAINER(align), label);
+ gtk_widget_modify_font (label, pfd);
+
+ gtk_table_attach (GTK_TABLE(table), align,
+ 0, 1, i, i+1,
+ GTK_SHRINK, GTK_SHRINK,
+ 2, 8);
+
+ data->comment = gtk_entry_new ();
+ align = gtk_alignment_new (0.0, 0.5, 0, 0);
+ gtk_container_add (GTK_CONTAINER (align), data->comment);
+ gtk_table_attach (GTK_TABLE (table), align,
+ 1, 2, i, i+1,
+ GTK_SHRINK, GTK_SHRINK,
+ 2, 8);
+ i++;
+
+ gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
+
+ init_media_tag_entries (data);
+
+#ifndef HAVE_CTAG_LIB
+ gtk_entry_set_editable (GTK_ENTRY (data->title), FALSE);
+ gtk_entry_set_editable (GTK_ENTRY (data->album), FALSE);
+ gtk_entry_set_editable (GTK_ENTRY (data->artist), FALSE);
+ gtk_entry_set_editable (GTK_ENTRY (data->year), FALSE);
+ gtk_entry_set_editable (GTK_ENTRY (data->comment), FALSE);
+#endif
+
+ return vbox;
+}
+
+static void
+state_changed_cb (ParolePlugin *plugin, const ParoleStream *stream, ParoleState state, PluginData *data)
+{
+ if ( state <= PAROLE_STATE_PLAYBACK_FINISHED )
+ init_media_tag_entries (data);
+}
+
+static void
+tag_message_cb (ParolePlugin *plugin, const ParoleStream *stream, PluginData *data)
+{
+ gchar *str = NULL;
+
+ g_object_get (G_OBJECT (stream),
+ "title", &str,
+ NULL);
+
+ if ( str )
+ {
+ gtk_entry_set_text (GTK_ENTRY (data->title), str);
+ g_free (str);
+ }
+
+ g_object_get (G_OBJECT (stream),
+ "comment", &str,
+ NULL);
+
+ if ( str )
+ {
+ gtk_entry_set_text (GTK_ENTRY (data->comment), str);
+ g_free (str);
+ }
+
+ g_object_get (G_OBJECT (stream),
+ "artist", &str,
+ NULL);
+
+ if ( str )
+ {
+ gtk_entry_set_text (GTK_ENTRY (data->artist), str);
+ g_free (str);
+ }
+
+ g_object_get (G_OBJECT (stream),
+ "year", &str,
+ NULL);
+
+ if ( str )
+ {
+ gtk_entry_set_text (GTK_ENTRY (data->year), str);
+ g_free (str);
+ }
+
+ g_object_get (G_OBJECT (stream),
+ "album", &str,
+ NULL);
+
+ if ( str )
+ {
+ gtk_entry_set_text (GTK_ENTRY (data->album), str);
+ g_free (str);
+ }
+
+}
+
+static void
+free_data_cb (ParolePlugin *plugin, PluginData *data)
+{
+ g_free (data);
+}
+
+G_MODULE_EXPORT static void
+construct (ParolePlugin *plugin)
+{
+ PluginData *data;
+ GtkWidget *vbox;
+
+ data = g_new0 (PluginData, 1);
+
+ vbox = create_properties_widget (data);
+
+ parole_plugin_pack_widget (plugin, vbox, PAROLE_PLUGIN_CONTAINER_PLAYLIST);
+
+ g_signal_connect (plugin, "state_changed",
+ G_CALLBACK (state_changed_cb), data);
+
+ g_signal_connect (plugin, "tag-message",
+ G_CALLBACK (tag_message_cb), data);
+
+ g_signal_connect (plugin, "free-data",
+ G_CALLBACK (free_data_cb), data);
+}
+
+PAROLE_PLUGIN_CONSTRUCT (construct, /* Construct function */
+ _("Properties"), /* Title */
+ _("Read media properties"), /* Description */
+ "Ali Abdallah"); /* Author */
Modified: parole/trunk/po/POTFILES.in
===================================================================
--- parole/trunk/po/POTFILES.in 2009-07-16 15:03:04 UTC (rev 7734)
+++ parole/trunk/po/POTFILES.in 2009-07-16 15:03:06 UTC (rev 7735)
@@ -5,12 +5,12 @@
[type: gettext/glade]data/interfaces/openlocation.ui
[type: gettext/glade]data/interfaces/parole-settings.ui
data/desktop/parole.desktop.in.in
-src/main.c
-src/gst.c
-src/builder.c
-src/mediachooser.c
-src/medialist.c
-src/player.c
-src/sidebar.c
-src/statusbar.c
-src/filters.c
+parole/main.c
+parole/parole-gst.c
+parole/parole-mediachooser.c
+parole/parole-medialist.c
+parole/parole-player.c
+parole/parole-sidebar.c
+parole/parole-statusbar.c
+parole/parole-filters.c
+plugins/properties/stream-properties.c
Modified: parole/trunk/po/parole-media-player.pot
===================================================================
--- parole/trunk/po/parole-media-player.pot 2009-07-16 15:03:04 UTC (rev 7734)
+++ parole/trunk/po/parole-media-player.pot 2009-07-16 15:03:06 UTC (rev 7735)
@@ -8,7 +8,7 @@
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-07-07 09:09+0200\n"
+"POT-Creation-Date: 2009-07-16 16:57+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
"Language-Team: LANGUAGE <LL at li.org>\n"
@@ -21,34 +21,30 @@
msgstr ""
#: ../data/interfaces/parole.ui.h:2
-msgid "Audio converter"
+msgid "Media player"
msgstr ""
#: ../data/interfaces/parole.ui.h:3
-msgid "Audio recorder"
+msgid "Nothing yet."
msgstr ""
#: ../data/interfaces/parole.ui.h:4
-msgid "Media player"
+msgid "Plugins"
msgstr ""
#: ../data/interfaces/parole.ui.h:5
-msgid "Nothing yet."
+msgid "_Edit"
msgstr ""
#: ../data/interfaces/parole.ui.h:6
-msgid "_Edit"
+msgid "_Help"
msgstr ""
#: ../data/interfaces/parole.ui.h:7
-msgid "_File"
+msgid "_Media"
msgstr ""
#: ../data/interfaces/parole.ui.h:8
-msgid "_Help"
-msgstr ""
-
-#: ../data/interfaces/parole.ui.h:9
msgid "_View"
msgstr ""
@@ -108,106 +104,149 @@
msgid "gtk-help"
msgstr ""
-#: ../data/desktop/parole.desktop.in.in.h:1
+#: ../data/desktop/parole.desktop.in.in.h:1 ../parole/parole-player.c:156
msgid "Parole Media Player"
msgstr ""
-#: ../src/main.c:97
+#: ../parole/main.c:103
+msgid "Open a new instance"
+msgstr ""
+
+#: ../parole/main.c:104
msgid "Media to play"
msgstr ""
-#: ../src/main.c:113
+#: ../parole/main.c:120
#, c-format
msgid "Type '%s --help' for usage."
msgstr ""
-#: ../src/gst.c:726
+#: ../parole/parole-gst.c:787
msgid "Error in changing state to ready"
msgstr ""
-#: ../src/gst.c:775
+#: ../parole/parole-gst.c:836
msgid ""
"Unable to load playbin GStreamer plugin, check your GStreamer installation"
msgstr ""
-#: ../src/gst.c:790
+#: ../parole/parole-gst.c:851
msgid ""
"Unable to load video GStreamer plugin, check your GStreamer installation"
msgstr ""
-#: ../src/builder.c:69
-msgid "Check your Parole installation"
-msgstr ""
-
-#: ../src/mediachooser.c:197
+#: ../parole/parole-mediachooser.c:203
msgid "Add media files"
msgstr ""
-#: ../src/mediachooser.c:197
+#: ../parole/parole-mediachooser.c:203
msgid "Open media file"
msgstr ""
-#: ../src/mediachooser.c:214
+#: ../parole/parole-mediachooser.c:220
msgid "Add"
msgstr ""
-#: ../src/mediachooser.c:214
+#: ../parole/parole-mediachooser.c:220
msgid "Open"
msgstr ""
-#: ../src/medialist.c:503
+#: ../parole/parole-medialist.c:506
msgid "Media list"
msgstr ""
-#: ../src/player.c:171
+#: ../parole/parole-player.c:177
msgid "Hide playlist"
msgstr ""
-#: ../src/player.c:180
+#: ../parole/parole-player.c:186
msgid "Show playlist"
msgstr ""
-#: ../src/player.c:313 ../src/statusbar.c:125 ../src/statusbar.c:127
+#: ../parole/parole-player.c:319 ../parole/parole-statusbar.c:126
+#: ../parole/parole-statusbar.c:128
msgid "Playing"
msgstr ""
-#: ../src/player.c:314
+#: ../parole/parole-player.c:320
msgid "Media stream is not seekable"
msgstr ""
-#: ../src/player.c:332 ../src/player.c:345
+#: ../parole/parole-player.c:338 ../parole/parole-player.c:351
msgid "Paused"
msgstr ""
-#: ../src/player.c:363
+#: ../parole/parole-player.c:369
msgid "Stopped"
msgstr ""
-#: ../src/sidebar.c:137
+#: ../parole/parole-player.c:931
+msgid "Playlist"
+msgstr ""
+
+#: ../parole/parole-sidebar.c:138
msgid ""
"<b>Media \n"
"player\n"
"</b>"
msgstr ""
-#: ../src/sidebar.c:147
+#: ../parole/parole-sidebar.c:148
msgid ""
"<b>Albums\n"
"</b>"
msgstr ""
-#: ../src/statusbar.c:137
+#: ../parole/parole-statusbar.c:138
msgid "Buffering"
msgstr ""
-#: ../src/filters.c:46
+#: ../parole/parole-filters.c:46
msgid "Audio"
msgstr ""
-#: ../src/filters.c:64
+#: ../parole/parole-filters.c:64
msgid "Video"
msgstr ""
-#: ../src/filters.c:82
+#: ../parole/parole-filters.c:82
msgid "Audio and video"
msgstr ""
+
+#: ../plugins/properties/stream-properties.c:40
+#: ../plugins/properties/stream-properties.c:41
+#: ../plugins/properties/stream-properties.c:42
+#: ../plugins/properties/stream-properties.c:43
+#: ../plugins/properties/stream-properties.c:44
+msgid "Unknown"
+msgstr ""
+
+#: ../plugins/properties/stream-properties.c:66
+msgid "Title:"
+msgstr ""
+
+#: ../plugins/properties/stream-properties.c:89
+msgid "Artist:"
+msgstr ""
+
+#: ../plugins/properties/stream-properties.c:112
+msgid "Album:"
+msgstr ""
+
+#: ../plugins/properties/stream-properties.c:135
+msgid "Year:"
+msgstr ""
+
+#: ../plugins/properties/stream-properties.c:158
+msgid "Comment:"
+msgstr ""
+
+#. Construct function
+#: ../plugins/properties/stream-properties.c:284
+msgid "Properties"
+msgstr ""
+
+#. Title
+#: ../plugins/properties/stream-properties.c:285
+msgid "Read media properties"
+msgstr ""
More information about the Goodies-commits
mailing list