[vlc-devel] [PATCH 4/4] Qt: add fingerprinting ui

Francois Cartegnie fcvlcdev at free.fr
Sat Feb 16 16:18:31 CET 2013


---
 modules/gui/qt4/Modules.am                    |    8 ++
 modules/gui/qt4/adapters/chromaprint.cpp      |   76 ++++++++++++++
 modules/gui/qt4/adapters/chromaprint.hpp      |   55 ++++++++++
 modules/gui/qt4/components/info_panels.cpp    |   30 +++++-
 modules/gui/qt4/components/info_panels.hpp    |    5 +
 modules/gui/qt4/dialogs/fingerprintdialog.cpp |  115 ++++++++++++++++++++
 modules/gui/qt4/dialogs/fingerprintdialog.hpp |   61 +++++++++++
 modules/gui/qt4/ui/fingerprintdialog.ui       |  138 +++++++++++++++++++++++++
 8 files changed, 486 insertions(+), 2 deletions(-)
 create mode 100644 modules/gui/qt4/adapters/chromaprint.cpp
 create mode 100644 modules/gui/qt4/adapters/chromaprint.hpp
 create mode 100644 modules/gui/qt4/dialogs/fingerprintdialog.cpp
 create mode 100644 modules/gui/qt4/dialogs/fingerprintdialog.hpp
 create mode 100644 modules/gui/qt4/ui/fingerprintdialog.ui

diff --git a/modules/gui/qt4/Modules.am b/modules/gui/qt4/Modules.am
index 0fce86c..a3a3cc4 100644
--- a/modules/gui/qt4/Modules.am
+++ b/modules/gui/qt4/Modules.am
@@ -23,6 +23,7 @@ nodist_SOURCES_qt4 = \
 		extensions_manager.moc.cpp \
 		recents.moc.cpp \
 		adapters/seekpoints.moc.cpp \
+		adapters/chromaprint.moc.cpp \
 		variables.moc.cpp \
 		dialogs/playlist.moc.cpp \
 		dialogs/bookmarks.moc.cpp \
@@ -45,6 +46,7 @@ nodist_SOURCES_qt4 = \
 		dialogs/vlm.moc.cpp \
 		dialogs/firstrun.moc.cpp \
 		dialogs/extensions.moc.cpp \
+		dialogs/fingerprintdialog.moc.cpp \
 		components/extended_panels.moc.cpp \
 		components/info_panels.moc.cpp \
 		components/preferences_widgets.moc.cpp \
@@ -96,6 +98,7 @@ nodist_SOURCES_qt4 = \
 		ui/messages_panel.h \
 		ui/about.h \
 		ui/update.h \
+		ui/fingerprintdialog.h \
 		styles/seekstyle.moc.cpp \
 		dialogs/ml_configuration.moc.cpp \
 		components/playlist/ml_model.moc.cpp \
@@ -277,6 +280,7 @@ SOURCES_qt4 = 	qt4.cpp \
 		extensions_manager.cpp \
 		recents.cpp \
 		adapters/seekpoints.cpp \
+		adapters/chromaprint.cpp \
 		variables.cpp \
 		dialogs/playlist.cpp \
 		dialogs/bookmarks.cpp \
@@ -300,6 +304,7 @@ SOURCES_qt4 = 	qt4.cpp \
 		dialogs/firstrun.cpp \
 		dialogs/podcast_configuration.cpp \
 		dialogs/extensions.cpp \
+		dialogs/fingerprintdialog.cpp \
 		components/extended_panels.cpp \
 		components/info_panels.cpp \
 		components/preferences_widgets.cpp \
@@ -352,6 +357,7 @@ noinst_HEADERS = \
 	extensions_manager.hpp \
 	recents.hpp \
 	adapters/seekpoints.hpp \
+	adapters/chromaprint.hpp \
 	variables.hpp \
 	dialogs/playlist.hpp \
 	dialogs/bookmarks.hpp \
@@ -375,6 +381,7 @@ noinst_HEADERS = \
 	dialogs/firstrun.hpp \
 	dialogs/podcast_configuration.hpp \
 	dialogs/extensions.hpp \
+	dialogs/fingerprintdialog.hpp \
 	components/extended_panels.hpp \
 	components/info_panels.hpp \
 	components/preferences_widgets.hpp \
@@ -441,5 +448,6 @@ EXTRA_DIST += \
 	ui/update.ui \
 	ui/sout.ui \
 	ui/vlm.ui \
+	ui/fingerprintdialog.ui \
 	$(DEPS_res)
 
diff --git a/modules/gui/qt4/adapters/chromaprint.cpp b/modules/gui/qt4/adapters/chromaprint.cpp
new file mode 100644
index 0000000..3b8e5f1
--- /dev/null
+++ b/modules/gui/qt4/adapters/chromaprint.cpp
@@ -0,0 +1,76 @@
+/*****************************************************************************
+ * chromaprint.cpp: Fingerprinter helper class
+ *****************************************************************************
+ * Copyright (C) 2012 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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 "chromaprint.hpp"
+#include <vlc_fingerprinter.h>
+
+Chromaprint::Chromaprint( intf_thread_t *_p_intf ) : p_intf( _p_intf )
+{
+    Q_ASSERT( p_intf );
+    p_fingerprinter = fingerprinter_Create( VLC_OBJECT( p_intf ) );
+    if ( p_fingerprinter )
+        var_AddCallback( p_fingerprinter, "results-available", results_available, this );
+}
+
+int Chromaprint::results_available( vlc_object_t *, const char *, vlc_value_t, vlc_value_t , void *param )
+{
+    Chromaprint *me = (Chromaprint *) param;
+    me->finish();
+    return 0;
+}
+
+fingerprint_request_t * Chromaprint::fetchResults()
+{
+    return p_fingerprinter->pf_getresults( p_fingerprinter );
+}
+
+void Chromaprint::apply( fingerprint_request_t *p_r, int i_id )
+{
+    p_fingerprinter->pf_apply( p_r, i_id );
+}
+
+bool Chromaprint::enqueue( input_item_t *p_item )
+{
+    if ( ! p_fingerprinter ) return false;
+    fingerprint_request_t *p_r = fingerprint_request_New( p_item );
+    if ( ! p_r ) return false;
+    mtime_t t = input_item_GetDuration( p_item );
+    if ( t ) p_r->i_duration = (unsigned int) ( t / 1000000 );
+    p_fingerprinter->pf_enqueue( p_fingerprinter, p_r );
+    return true;
+}
+
+bool Chromaprint::isSupported( QString uri )
+{
+#ifndef HAVE_CHROMAPRINT
+    return false;
+#endif
+    return ( uri.startsWith( "file://" ) || uri.startsWith( "/" ) );
+}
+
+Chromaprint::~Chromaprint()
+{
+    if ( p_fingerprinter )
+        fingerprinter_Destroy( p_fingerprinter );
+}
diff --git a/modules/gui/qt4/adapters/chromaprint.hpp b/modules/gui/qt4/adapters/chromaprint.hpp
new file mode 100644
index 0000000..af159d6
--- /dev/null
+++ b/modules/gui/qt4/adapters/chromaprint.hpp
@@ -0,0 +1,55 @@
+/*****************************************************************************
+ * chromaprint.hpp: Fingerprinter helper class
+ *****************************************************************************
+ * Copyright (C) 2012 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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 CHROMAPRINT_HPP
+#define CHROMAPRINT_HPP
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <QObject>
+#include <QString>
+#include <vlc_fingerprinter.h>
+#include <vlc_interface.h>
+
+class Chromaprint : public QObject
+{
+    Q_OBJECT
+
+public:
+    Chromaprint( intf_thread_t *p_intf = NULL );
+    virtual ~Chromaprint();
+    bool enqueue( input_item_t *p_item );
+    static int results_available( vlc_object_t *p_this, const char *,
+                                  vlc_value_t, vlc_value_t newval, void *param );
+    fingerprint_request_t * fetchResults();
+    void apply( fingerprint_request_t *, int i_id );
+    static bool isSupported( QString uri );
+
+signals:
+    void finished();
+
+private:
+    void finish() { emit finished(); }
+    intf_thread_t *p_intf;
+    fingerprinter_thread_t *p_fingerprinter;
+};
+
+#endif // CHROMAPRINT_HPP
diff --git a/modules/gui/qt4/components/info_panels.cpp b/modules/gui/qt4/components/info_panels.cpp
index 0b051d4..13e8706 100644
--- a/modules/gui/qt4/components/info_panels.cpp
+++ b/modules/gui/qt4/components/info_panels.cpp
@@ -33,6 +33,8 @@
 #include "qt4.hpp"
 #include "components/info_panels.hpp"
 #include "components/interface_widgets.hpp"
+#include "dialogs/fingerprintdialog.hpp"
+#include "adapters/chromaprint.hpp"
 
 #include <assert.h>
 #include <vlc_url.h>
@@ -128,7 +130,15 @@ MetaPanel::MetaPanel( QWidget *parent,
 
     /* Language on the same line */
     ADD_META( VLC_META_LANGUAGE, language_text, 7, -1 ); line++;
-    ADD_META( VLC_META_PUBLISHER, publisher_text, 0, 7 ); line++;
+    ADD_META( VLC_META_PUBLISHER, publisher_text, 0, 7 );
+
+    fingerprintButton = new QPushButton( qtr("&Fingerprint") );
+    fingerprintButton->setToolTip( qtr( "Find meta data using audio fingerprinting" ) );
+    fingerprintButton->setVisible( false );
+    metaLayout->addWidget( fingerprintButton, line, 7 , 3, -1 );
+    CONNECT( fingerprintButton, clicked(), this, fingerprint() );
+
+    line++;
 
     lblURL = new QLabel;
     lblURL->setOpenExternalLinks( true );
@@ -211,7 +221,8 @@ void MetaPanel::update( input_item_t *p_item )
     /* URL / URI */
     psz_meta = input_item_GetURI( p_item );
     if( !EMPTY_STR( psz_meta ) )
-         emit uriSet( qfu( psz_meta ) );
+        emit uriSet( qfu( psz_meta ) );
+    fingerprintButton->setVisible( Chromaprint::isSupported( QString( psz_meta ) ) );
     free( psz_meta );
 
     /* Other classic though */
@@ -336,11 +347,26 @@ void MetaPanel::clear()
     publisher_text->clear();
     encodedby_text->clear();
     art_cover->clear();
+    fingerprintButton->setVisible( false );
 
     setEditMode( false );
     emit uriSet( "" );
 }
 
+void MetaPanel::fingerprint()
+{
+    FingerprintDialog *dialog = new FingerprintDialog( this, p_intf, p_input );
+    CONNECT( dialog, metaApplied( input_item_t * ), this, fingerprintUpdate( input_item_t * ) );
+    dialog->setAttribute( Qt::WA_DeleteOnClose, true );
+    dialog->show();
+}
+
+void MetaPanel::fingerprintUpdate( input_item_t *p_item )
+{
+    update( p_item );
+    setEditMode( true );
+}
+
 /**
  * Second Panel - Shows the extra metadata in a tree, non editable.
  **/
diff --git a/modules/gui/qt4/components/info_panels.hpp b/modules/gui/qt4/components/info_panels.hpp
index ce30edf..3f938e0 100644
--- a/modules/gui/qt4/components/info_panels.hpp
+++ b/modules/gui/qt4/components/info_panels.hpp
@@ -51,6 +51,7 @@ class QLineEdit;
 class CoverArtLabel;
 class QTextEdit;
 class QLabel;
+class QPushButton;
 
 class MetaPanel: public QWidget
 {
@@ -87,9 +88,13 @@ private:
     QLabel   *lblURL;
     QString  currentURL;
 
+    QPushButton *fingerprintButton;
+
 public slots:
     void update( input_item_t * );
     void clear();
+    void fingerprint();
+    void fingerprintUpdate( input_item_t * );
 
 private slots:
     void enterEditMode();
diff --git a/modules/gui/qt4/dialogs/fingerprintdialog.cpp b/modules/gui/qt4/dialogs/fingerprintdialog.cpp
new file mode 100644
index 0000000..23525ee
--- /dev/null
+++ b/modules/gui/qt4/dialogs/fingerprintdialog.cpp
@@ -0,0 +1,115 @@
+/*****************************************************************************
+ * fingerprintdialog.cpp: Fingerprinter Dialog
+ *****************************************************************************
+ * Copyright (C) 2012 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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 "fingerprintdialog.hpp"
+#include "ui/fingerprintdialog.h"
+
+#include "adapters/chromaprint.hpp"
+#include <vlc_url.h>
+
+#include <QLabel>
+#include <QListWidgetItem>
+
+FingerprintDialog::FingerprintDialog(QWidget *parent, intf_thread_t *p_intf,
+                                     input_item_t *p_item ) :
+    QDialog(parent),
+    ui(new Ui::FingerprintDialog), p_r( NULL )
+{
+    ui->setupUi(this);
+
+    ui->stackedWidget->setCurrentWidget( ui->wait );
+
+    ui->buttonBox->addButton( "&Close",
+                              QDialogButtonBox::RejectRole );
+
+    ui->buttonsBox->addButton( "&Apply this identity to the file",
+                                QDialogButtonBox::AcceptRole );
+
+    ui->buttonsBox->addButton( "&Discard all identities",
+                                QDialogButtonBox::RejectRole );
+
+    CONNECT( ui->buttonsBox, accepted(), this, applyIdentity() );
+    CONNECT( ui->buttonBox, rejected(), this, close() );
+    CONNECT( ui->buttonsBox, rejected(), this, close() );
+
+    t = new Chromaprint( p_intf );
+    if ( t )
+    {
+        CONNECT( t, finished(), this, handleResults() );
+        t->enqueue( p_item );
+    }
+}
+
+void FingerprintDialog::applyIdentity()
+{
+    Q_ASSERT( p_r );
+    if ( ui->recordsList->currentIndex().isValid() )
+        t->apply( p_r, ui->recordsList->currentIndex().row() );
+    emit metaApplied( p_r->p_item );
+    close();
+}
+
+void FingerprintDialog::handleResults()
+{
+    p_r = t->fetchResults();
+
+    if ( ! p_r )
+    {
+        ui->stackedWidget->setCurrentWidget( ui->error );
+        return;
+    }
+
+    if ( vlc_array_count( & p_r->results.metas_array ) == 0 )
+    {
+        fingerprint_request_Delete( p_r );
+        ui->stackedWidget->setCurrentWidget( ui->error );
+        return;
+    }
+
+    ui->stackedWidget->setCurrentWidget( ui->results );
+
+    for ( int i=0; i< vlc_array_count( & p_r->results.metas_array ) ; i++ )
+    {
+        vlc_meta_t *p_meta =
+                (vlc_meta_t *) vlc_array_item_at_index( & p_r->results.metas_array, i );
+        QListWidgetItem *item = new QListWidgetItem();
+        ui->recordsList->addItem( item );
+        QString mb_id( vlc_meta_GetExtra( p_meta, "musicbrainz-id" ) );
+        QLabel *label = new QLabel(
+                    QString( "<h3 style=\"margin: 0\"><a style=\"text-decoration:none\" href=\"%1\">%2</a></h3>"
+                             "<span style=\"padding-left:20px\">%3</span>" )
+                    .arg( QString( "http://mb.videolan.org/recording/%1" ).arg( mb_id ) )
+                    .arg( qfu( vlc_meta_Get( p_meta, vlc_meta_Title ) ) )
+                    .arg( qfu( vlc_meta_Get( p_meta, vlc_meta_Artist ) ) )
+        );
+        label->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
+        label->setOpenExternalLinks( true );
+        item->setSizeHint( label->sizeHint() );
+        ui->recordsList->setItemWidget( item, label );
+    }
+    ui->recordsList->setCurrentIndex( ui->recordsList->model()->index( 0, 0 ) );
+}
+
+FingerprintDialog::~FingerprintDialog()
+{
+    if ( t ) delete t;
+    if ( p_r ) fingerprint_request_Delete( p_r );
+    delete ui;
+}
diff --git a/modules/gui/qt4/dialogs/fingerprintdialog.hpp b/modules/gui/qt4/dialogs/fingerprintdialog.hpp
new file mode 100644
index 0000000..d4bd070
--- /dev/null
+++ b/modules/gui/qt4/dialogs/fingerprintdialog.hpp
@@ -0,0 +1,61 @@
+/*****************************************************************************
+ * fingerprintdialog.hpp: Fingerprinter Dialog
+ *****************************************************************************
+ * Copyright (C) 2012 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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 FINGERPRINTDIALOG_HPP
+#define FINGERPRINTDIALOG_HPP
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "qt4.hpp"
+
+#include <QDialog>
+#include <vlc_interface.h>
+#include <vlc_fingerprinter.h>
+
+namespace Ui {
+class FingerprintDialog;
+}
+
+class Chromaprint;
+
+class FingerprintDialog : public QDialog
+{
+    Q_OBJECT
+
+public:
+    FingerprintDialog( QWidget *parent, intf_thread_t *p_intf,
+                                input_item_t *p_item );
+    ~FingerprintDialog();
+
+private:
+    Ui::FingerprintDialog *ui;
+    Chromaprint *t;
+    fingerprint_request_t *p_r;
+
+private slots:
+    void handleResults();
+    void applyIdentity();
+
+signals:
+    void metaApplied( input_item_t * );
+};
+
+#endif // FINGERPRINTDIALOG_HPP
diff --git a/modules/gui/qt4/ui/fingerprintdialog.ui b/modules/gui/qt4/ui/fingerprintdialog.ui
new file mode 100644
index 0000000..acc8269
--- /dev/null
+++ b/modules/gui/qt4/ui/fingerprintdialog.ui
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>FingerprintDialog</class>
+ <widget class="QDialog" name="FingerprintDialog">
+  <property name="windowModality">
+   <enum>Qt::WindowModal</enum>
+  </property>
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>499</width>
+    <height>257</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Audio Fingerprinting</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_3">
+   <item>
+    <widget class="QStackedWidget" name="stackedWidget">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="currentIndex">
+      <number>0</number>
+     </property>
+     <widget class="QWidget" name="results">
+      <layout class="QVBoxLayout" name="verticalLayout_2">
+       <item>
+        <widget class="QLabel" name="label_3">
+         <property name="text">
+          <string>Select a matching identity</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QListWidget" name="recordsList"/>
+       </item>
+       <item>
+        <widget class="QDialogButtonBox" name="buttonsBox">
+         <property name="standardButtons">
+          <set>QDialogButtonBox::NoButton</set>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="error">
+      <layout class="QVBoxLayout" name="verticalLayout_4">
+       <item>
+        <widget class="QLabel" name="label_2">
+         <property name="text">
+          <string>No fingerprint has been found</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QDialogButtonBox" name="buttonBox">
+         <property name="standardButtons">
+          <set>QDialogButtonBox::NoButton</set>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="wait">
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
+      <layout class="QVBoxLayout" name="verticalLayout">
+       <item>
+        <spacer name="verticalSpacer">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <widget class="QProgressBar" name="progressBar">
+         <property name="minimum">
+          <number>0</number>
+         </property>
+         <property name="maximum">
+          <number>0</number>
+         </property>
+         <property name="value">
+          <number>-1</number>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLabel" name="label">
+         <property name="text">
+          <string>Fingerprinting track...</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="verticalSpacer_2">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
-- 
1.7.9




More information about the vlc-devel mailing list