From 6dd69c633b0b1250d705f922e619b1fb2bd9d440 Mon Sep 17 00:00:00 2001
From: Fabio Ritrovato <exsephiroth87@gmail.com>
Date: Sat, 28 Mar 2009 16:52:50 +0100
Subject: [PATCH] GSoC: MTP - Expand Qt4 functionalities

---
 modules/gui/qt4/components/playlist/panels.hpp     |    2 +
 .../gui/qt4/components/playlist/playlist_model.cpp |  132 ++++++++++++++++----
 .../gui/qt4/components/playlist/standardpanel.cpp  |   33 +++++-
 modules/gui/qt4/dialogs_provider.cpp               |   63 +++++++++
 modules/gui/qt4/dialogs_provider.hpp               |    2 +
 5 files changed, 209 insertions(+), 23 deletions(-)

diff --git a/modules/gui/qt4/components/playlist/panels.hpp b/modules/gui/qt4/components/playlist/panels.hpp
index 671b092..dfd738b 100644
--- a/modules/gui/qt4/components/playlist/panels.hpp
+++ b/modules/gui/qt4/components/playlist/panels.hpp
@@ -90,6 +90,8 @@ private slots:
     void setCurrentRootId( int );
     void popupAdd();
     void popupSelectColumn( QPoint );
+    void callSDAppendDialog();
+    void callSDAppendDir();
 };
 
 #endif
diff --git a/modules/gui/qt4/components/playlist/playlist_model.cpp b/modules/gui/qt4/components/playlist/playlist_model.cpp
index 8f6f049..a14d5b8 100644
--- a/modules/gui/qt4/components/playlist/playlist_model.cpp
+++ b/modules/gui/qt4/components/playlist/playlist_model.cpp
@@ -40,6 +40,8 @@
 #include <QMenu>
 #include <QApplication>
 #include <QSettings>
+#include <QFileDialog>
+#include <vlc_services_discovery.h>
 
 #include "sorting.h"
 
@@ -174,12 +176,13 @@ bool PLModel::dropMimeData( const QMimeData *data, Qt::DropAction action,
             playlist_item_t *p_target =
                         playlist_ItemGetById( p_playlist, targetItem->i_id );
             playlist_item_t *p_src = playlist_ItemGetById( p_playlist, srcId );
+            PL_UNLOCK;
 
             if( !p_target || !p_src )
-            {
-                PL_UNLOCK;
                 return false;
-            }
+            services_discovery_t *p_sd = playlist_ServiceDiscoveryGetById( THEPL,
+                                                             targetItem->i_id );
+            PL_LOCK;
             if( p_target->i_children == -1 ) /* A leaf */
             {
                 PLItem *parentItem = targetItem->parent();
@@ -200,9 +203,44 @@ bool PLModel::dropMimeData( const QMimeData *data, Qt::DropAction action,
             else
             {
                 /* \todo: if we drop on a top-level node, use copy instead ? */
-                playlist_TreeMove( p_playlist, p_src, p_target, 0 );
-                i = 0;
-                newParentItem = targetItem;
+                if( p_sd == NULL)
+                {
+                    playlist_TreeMove( p_playlist, p_src, p_target, 0 );
+                    i = 0;
+                    newParentItem = targetItem;
+                }
+                else
+                {
+                    /* If we dropped on a service discovery, we send it the
+                     * request to add the item */
+                    if( !p_sd->b_read_only )
+                    {
+                        vlc_event_t event;
+                        event.type = vlc_ServicesDiscoveryItemPut;
+                        event.u.services_discovery_item_put.psz_string = 
+                                                        p_src->p_input->psz_uri;
+                        vlc_event_send( &p_sd->event_manager, &event );
+                    }
+                }
+            }
+            if( p_sd == NULL )
+            {
+                /* Remove from source */
+                PLItem *srcItem = FindById( rootItem, p_src->i_id );
+                // We dropped on the source selector. Ask the dialog to forward
+                // to the main view
+                if( !srcItem )
+                {
+                    emit shouldRemove( p_src->i_id );
+                }
+                else
+                    srcItem->remove( srcItem );
+                /* Display at new destination */
+                PLItem *newItem = new PLItem( p_src, newParentItem, this );
+                newParentItem->insertChild( newItem, i, true );
+                UpdateTreeItem( p_src, newItem, true );
+                if( p_src->i_children != -1 )
+                    UpdateNodeChildren( newItem );
             }
             PL_UNLOCK;
         }
@@ -394,20 +432,18 @@ QStringList PLModel::selectedURIs()
         PL_LOCK;
         PLItem *item = static_cast<PLItem*>
                     (current_selection[i].internalPointer());
-        if( !item )
-            continue;
-
-        input_item_t *p_item = NULL;
-        if( !p_item )
-            continue;
-
-        char *psz = input_item_GetURI( p_item );
-        if( !psz )
-            continue;
-        else
+        if( item )
         {
-            lst.append( QString( psz ) );
-            free( psz );
+            playlist_item_t *p_item = playlist_ItemGetById( p_playlist, item->i_id );
+            if( p_item )
+            {
+                char *psz = input_item_GetURI( p_item->p_input );
+                if( psz )
+                {
+                    lst.append( QString( psz ) );
+                    free( psz );
+                }
+            }
         }
         PL_UNLOCK;
     }
@@ -718,8 +754,19 @@ void PLModel::doDeleteItem( PLItem *item, QModelIndexList *fullList )
 
     PL_LOCK;
     playlist_item_t *p_item = playlist_ItemGetById( p_playlist, item->i_id );
+    PL_UNLOCK;
     if( !p_item )
+        return;
+    services_discovery_t *p_sd = playlist_ServiceDiscoveryGetById( THEPL,
+                                                       p_item->p_parent->i_id );
+    PL_LOCK;
+    if( p_sd != NULL && !p_sd->b_read_only )
     {
+        /* If the item is on a service discovery, we let it do its things first */
+        vlc_event_t event;
+        event.type = vlc_ServicesDiscoveryItemDelete;
+        event.u.services_discovery_item_delete.p_item = p_item->p_input;
+        vlc_event_send( &p_sd->event_manager, &event );
         PL_UNLOCK;
         return;
     }
@@ -901,9 +948,50 @@ void PLModel::popupStream()
 
 void PLModel::popupSave()
 {
-    QStringList mrls = selectedURIs();
-    if( !mrls.isEmpty() )
-        THEDP->streamingDialog( NULL, mrls[0], true );
+    services_discovery_t *p_sd = playlist_ServiceDiscoveryGetById( THEPL,
+                                                               i_popup_parent );
+    if( p_sd != NULL && !p_sd->b_read_only )
+    {
+        /* If the items are in a service discovery, send it a save request
+         * for each one of them */
+        QString dir = QFileDialog::getExistingDirectory( 0, qtr(I_OP_OPDIR) );
+        if( !dir.isEmpty() )
+        {
+            playlist_item_t *p_item;
+            for( int i = current_selection.size() -1; i >= 0; i-- )
+            {
+                QModelIndex index = current_selection[i];
+                if( index.column() != 0 ) continue;
+                PLItem *item = static_cast<PLItem*>(index.internalPointer());
+                assert( item );
+                PL_LOCK;
+                if( ( p_item = playlist_ItemGetById( p_playlist, item->i_id ) )
+                    != NULL )
+                {
+                    vlc_event_t event;
+                    event.type = vlc_ServicesDiscoveryItemGet;
+                    if( !( event.u.services_discovery_item_get.psz_string =
+                                                        strdup( qtu( dir ) ) ) )
+                    {
+                        PL_UNLOCK;
+                        return;
+                    }
+                    event.u.services_discovery_item_get.p_item = p_item->p_input;
+                    vlc_event_send( &p_sd->event_manager, &event );
+                    free( event.u.services_discovery_item_get.psz_string );
+                }
+                else
+                    msg_Err( p_playlist, "Some error occourred with item %d", item->i_id );
+                PL_UNLOCK;
+            }
+        }
+    }
+    else
+    {
+        QStringList mrls = selectedURIs();
+        if( !mrls.isEmpty() )
+            THEDP->streamingDialog( NULL, mrls[0], true );
+    }
 }
 
 #include <QUrl>
diff --git a/modules/gui/qt4/components/playlist/standardpanel.cpp b/modules/gui/qt4/components/playlist/standardpanel.cpp
index 4ecc873..b81a066 100644
--- a/modules/gui/qt4/components/playlist/standardpanel.cpp
+++ b/modules/gui/qt4/components/playlist/standardpanel.cpp
@@ -33,6 +33,8 @@
 #include "util/customwidgets.hpp"
 
 #include <vlc_intf_strings.h>
+#include <vlc_services_discovery.h>
+#include <vlc_events.h>
 
 #include <QTreeView>
 #include <QPushButton>
@@ -232,7 +234,14 @@ void StandardPLPanel::setCurrentRootId( int _new )
         addButton->setToolTip( qtr(I_PL_ADDML) );
     }
     else
-        addButton->setEnabled( false );
+    {
+        services_discovery_t *p_sd = playlist_ServiceDiscoveryGetById( THEPL,
+                                                                currentRootId );
+        if( p_sd != NULL && !p_sd->b_read_only )
+            addButton->setEnabled( true );
+        else
+            addButton->setEnabled( false );
+    }
 }
 
 /* PopupAdd Menu for the Add Menu */
@@ -253,6 +262,16 @@ void StandardPLPanel::popupAdd()
         popup.addAction( qtr(I_PL_ADDF), THEDP, SLOT( MLAppendDialog() ) );
         popup.addAction( qtr(I_PL_ADDDIR), THEDP, SLOT( MLAppendDir() ) );
     }
+    else
+    {
+        services_discovery_t *p_sd = playlist_ServiceDiscoveryGetById( THEPL,
+                                                                currentRootId );
+        if( p_sd != NULL && !p_sd->b_read_only )
+        {
+            popup.addAction( qtr(I_PL_ADDF), this, SLOT( callSDAppendDialog() ) );
+            popup.addAction( qtr(I_PL_ADDDIR), this, SLOT( callSDAppendDir() ) );
+        }
+    }
     popup.exec( QCursor::pos() - addButton->mapFromGlobal( QCursor::pos() )
                         + QPoint( 0, addButton->height() ) );
 }
@@ -332,6 +351,18 @@ void StandardPLPanel::deleteSelection()
     model->doDelete( list );
 }
 
+/* Call the appropriate append dialog, passing the id of the currently
+ * selected service discovery */
+void StandardPLPanel::callSDAppendDialog()
+{
+    THEDP->simpleSDAppendDialog( currentRootId );
+}
+
+void StandardPLPanel::callSDAppendDir()
+{
+    THEDP->SDAppendDir( currentRootId );
+}
+
 StandardPLPanel::~StandardPLPanel()
 {
     getSettings()->beginGroup("Playlist");
diff --git a/modules/gui/qt4/dialogs_provider.cpp b/modules/gui/qt4/dialogs_provider.cpp
index d7aec12..e8df002 100644
--- a/modules/gui/qt4/dialogs_provider.cpp
+++ b/modules/gui/qt4/dialogs_provider.cpp
@@ -27,6 +27,7 @@
 #endif
 
 #include <vlc_intf_strings.h>
+#include <vlc_services_discovery.h>
 
 #include "qt4.hpp"
 #include "dialogs_provider.hpp"
@@ -427,6 +428,34 @@ void DialogsProvider::simpleMLAppendDialog()
     addFromSimple( false, false );
 }
 
+/**
+ * Open a file with the SimpleOpen dialog,
+ * and ask the service discovery to add it
+ * id is the id of the service discovery 
+ **/ 
+void DialogsProvider::simpleSDAppendDialog( int id )
+{
+    services_discovery_t *p_sd = playlist_ServiceDiscoveryGetById( THEPL, id );
+    if( p_sd != NULL && !p_sd->b_read_only )
+    {
+        QStringList files = DialogsProvider::showSimpleOpen( NULL,
+                                                             EXT_FILTER_MEDIA );
+        foreach( QString file, files )
+        {
+            vlc_event_t event;
+            event.type = vlc_ServicesDiscoveryItemPut;
+            if( !( event.u.services_discovery_item_put.psz_string =
+                                                       strdup( qtu( file ) ) ) )
+                return;
+            vlc_event_send( &p_sd->event_manager, &event );
+            free( event.u.services_discovery_item_put.psz_string );
+        }
+    }
+    else
+        msg_Err( THEPL,
+          "The selected service discovery does not support the add operation" );
+}
+
 /* Url & Clipboard */
 /**
  * Open a MRL.
@@ -493,6 +522,40 @@ void DialogsProvider::MLAppendDir()
     openDirectory( p_intf, false , false );
 }
 
+/**
+ * Open a directory, and for each file in it,
+ * ask the service discovery to add it
+ * id is the id of the service discovery 
+ **/
+void DialogsProvider::SDAppendDir( int id )
+{
+    services_discovery_t *p_sd = playlist_ServiceDiscoveryGetById( THEPL, id );
+    if( p_sd != NULL && !p_sd->b_read_only )
+    {
+        QString dir_path = QFileDialog::getExistingDirectory( NULL, qtr("Open Directory") );
+        if (!dir_path.isEmpty())
+        {
+            QDir dir( dir_path );
+            dir.setFilter( QDir::Files | QDir::NoSymLinks );
+            QFileInfoList list = dir.entryInfoList();
+            for( int i = 0; i < list.size(); i++ )
+            {
+                QFileInfo fileInfo = list.at(i);
+                vlc_event_t event;
+                event.type = vlc_ServicesDiscoveryItemPut;
+                if( !( event.u.services_discovery_item_put.psz_string =
+                                strdup( qtu( fileInfo.absoluteFilePath() ) ) ) )
+                    return;
+                vlc_event_send( &p_sd->event_manager, &event );
+                free( event.u.services_discovery_item_put.psz_string );
+            }
+        }
+    }
+    else
+        msg_Err( THEPL,
+          "The selected service discovery does not support the add operation" );
+}
+
 /****************
  * Playlist     *
  ****************/
diff --git a/modules/gui/qt4/dialogs_provider.hpp b/modules/gui/qt4/dialogs_provider.hpp
index a7214ae..13b61c3 100644
--- a/modules/gui/qt4/dialogs_provider.hpp
+++ b/modules/gui/qt4/dialogs_provider.hpp
@@ -161,6 +161,7 @@ public slots:
     void simpleOpenDialog();
     void simplePLAppendDialog();
     void simpleMLAppendDialog();
+    void simpleSDAppendDialog( int );
 
     void openDialog();
     void openDiscDialog();
@@ -175,6 +176,7 @@ public slots:
     void PLOpenDir();
     void PLAppendDir();
     void MLAppendDir();
+    void SDAppendDir( int );
 
     void streamingDialog( QWidget *parent, QString mrl = "",
             bool b_stream = true );
-- 
1.5.4.3

