[vlc-devel] [PATCH 3/4] Qt GUI: implemented cloud tab.
Paweł Wegner
pawel.wegner95 at gmail.com
Thu Oct 20 07:59:27 CEST 2016
---
modules/gui/qt/components/open_panels.cpp | 183 ++++++++++++++++++++++++++++++
modules/gui/qt/components/open_panels.hpp | 43 +++++++
modules/gui/qt/dialogs/open.cpp | 12 ++
modules/gui/qt/dialogs/open.hpp | 2 +
modules/gui/qt/menus.cpp | 2 +
modules/gui/qt/ui/open_cloud.ui | 39 -------
6 files changed, 242 insertions(+), 39 deletions(-)
diff --git a/modules/gui/qt/components/open_panels.cpp b/modules/gui/qt/components/open_panels.cpp
index 3d0f6d9..2232dbe 100644
--- a/modules/gui/qt/components/open_panels.cpp
+++ b/modules/gui/qt/components/open_panels.cpp
@@ -53,6 +53,7 @@
#include <QUrl>
#include <QMimeData>
#include <QDropEvent>
+#include <QDesktopServices>
#define I_DEVICE_TOOLTIP \
I_DIR_OR_FOLDER( N_("Select a device or a VIDEO_TS directory"), \
@@ -1403,17 +1404,199 @@ void CaptureOpenPanel::advancedDialog()
module_config_free( p_config );
}
+#ifdef WITH_LIBCLOUDSTORAGE
+
+using cloudstorage::IItem;
+using cloudstorage::ICloudProvider;
+
+namespace
+{
+class CloudCallback : public cloudstorage::ICloudProvider::ICallback
+{
+public:
+ Status userConsentRequired(const ICloudProvider& provider) override
+ {
+ QDesktopServices::openUrl(QUrl(provider.authorizeLibraryUrl().c_str()));
+ return Status::WaitForAuthorizationCode;
+ }
+
+ void accepted(const ICloudProvider&) override
+ {
+ }
+
+ void declined(const ICloudProvider&) override
+ {
+ }
+
+ void error(const ICloudProvider&,
+ const std::string&) override
+ {
+ }
+};
+} // namespace
CloudOpenPanel::CloudOpenPanel( QWidget *parent, intf_thread_t *t ) :
OpenPanel( parent, t )
{
+ cloudStorage = cloudstorage::ICloudStorage::create();
+ QWidget* selectProvider = new QWidget(this);
+ QVBoxLayout* selectProviderLayout = new QVBoxLayout;
+ for (auto t : cloudStorage->providers())
+ {
+ QSettings settings;
+ std::string token = settings.value(t->name().c_str()).toString().toStdString();
+ t->initialize({token, std::unique_ptr<CloudCallback>(new CloudCallback),
+ nullptr, nullptr, nullptr, {}});
+ QPushButton* button = new QPushButton(t->name().c_str());
+ selectProviderLayout->addWidget(button);
+ connect(button, &QPushButton::pressed, this, &CloudOpenPanel::buttonClicked);
+ }
+ selectProvider->setLayout(selectProviderLayout);
+ QListView* selectFile = new QListView(this);
+ selectFile->setModel(&directoryModel);
+ connect(selectFile, &QListView::doubleClicked, this, &CloudOpenPanel::itemClicked);
+ QHBoxLayout* mainLayout = new QHBoxLayout(this);
+ mainLayout->addWidget(selectProvider);
+ mainLayout->addWidget(selectFile);
+ setLayout(mainLayout);
ui.setupUi(this);
}
+CloudOpenPanel::~CloudOpenPanel()
+{
+ save();
+}
+
+void CloudOpenPanel::save()
+{
+ if (currentProvider)
+ {
+ QSettings settings;
+ settings.setValue(currentProvider->name().c_str(), currentProvider->token().c_str());
+ }
+}
+
void CloudOpenPanel::clear()
{
}
+void CloudOpenPanel::keyPressEvent(QKeyEvent *e)
+{
+ OpenPanel::keyPressEvent(e);
+ if (!e->isAccepted() && e->key() == Qt::Key_Backspace)
+ {
+ if (!directoryStack.empty())
+ {
+ currentDirectory = directoryStack.back();
+ directoryStack.pop_back();
+ listDirectory();
+ }
+ else
+ {
+ directoryModel.clear();
+ currentDirectory = nullptr;
+ currentProvider = nullptr;
+ }
+ e->accept();
+ }
+}
+
+void CloudOpenPanel::buttonClicked()
+{
+ save();
+ directoryStack.clear();
+ QPushButton* button = static_cast<QPushButton*>(sender());
+ currentProvider = cloudStorage->provider(button->text().toStdString());
+ currentDirectory = currentProvider->rootDirectory();
+ listDirectory();
+}
+
+void CloudOpenPanel::itemClicked(const QModelIndex& index)
+{
+ auto item = directoryModel.get(index.row());
+ if (item->type() == cloudstorage::IItem::FileType::Directory)
+ {
+ directoryStack.push_back(currentDirectory);
+ currentDirectory = item;
+ listDirectory();
+ }
+ else
+ {
+ itemDataRequest = currentProvider->getItemDataAsync(item->id(), [this](IItem::Pointer i) {
+ if (!i) return;
+ QStringList list;
+ list << i->url().c_str();
+ emit methodChanged( qfu( "network-caching" ) );
+ emit mrlUpdated(list, "");
+ });
+ }
+}
+
+void CloudOpenPanel::listDirectory()
+{
+ directoryModel.clear();
+ listDirectoryRequest = currentProvider->listDirectoryAsync(currentDirectory,
+ [this](const std::vector<cloudstorage::IItem::Pointer>& d) {
+ for (auto i : d)
+ directoryModel.addItem(i);
+ });
+}
+
void CloudOpenPanel::updateMRL()
{
}
+
+void DirectoryModel::addItem(IItem::Pointer item) {
+ beginInsertRows(QModelIndex(), rowCount(), rowCount());
+ {
+ QMutexLocker lock(&mutex);
+ list.push_back(item);
+ }
+ endInsertRows();
+}
+
+IItem::Pointer DirectoryModel::get(int idx) const
+{
+ QMutexLocker lock(&mutex);
+ return list[idx];
+}
+
+QVariant DirectoryModel::getName(int idx) const
+{
+ QMutexLocker lock(&mutex);
+ return QString::fromStdString(list[idx]->filename());
+}
+
+QVariant DirectoryModel::getIcon(int idx) const
+{
+ QMutexLocker lock(&mutex);
+ auto item = list[idx];
+ if (item->type() == IItem::FileType::Directory)
+ return QFileIconProvider().icon(QFileIconProvider::Folder);
+ else
+ return QFileIconProvider().icon(QFileIconProvider::File);
+}
+
+void DirectoryModel::clear()
+{
+ beginRemoveRows(QModelIndex(), 0, rowCount() - 1);
+ list.clear();
+ endRemoveRows();
+}
+
+int DirectoryModel::rowCount(const QModelIndex &) const
+{
+ QMutexLocker lock(&mutex);
+ return list.size();
+}
+
+QVariant DirectoryModel::data(const QModelIndex &index, int role) const
+{
+ if (role == Qt::DisplayRole)
+ return getName(index.row());
+ else if (role == Qt::DecorationRole)
+ return getIcon(index.row());
+ return QVariant();
+}
+
+#endif
diff --git a/modules/gui/qt/components/open_panels.hpp b/modules/gui/qt/components/open_panels.hpp
index af61c6b..6bd55a7 100644
--- a/modules/gui/qt/components/open_panels.hpp
+++ b/modules/gui/qt/components/open_panels.hpp
@@ -41,9 +41,17 @@
#include "ui/open_cloud.h"
#include <QFileDialog>
+#include <QMutex>
#include <limits.h>
+#ifdef WITH_LIBCLOUDSTORAGE
+ #include <ICloudStorage.h>
+ #include <ICloudProvider.h>
+ #include <IRequest.h>
+ #include <IItem.h>
+#endif
+
#define setSpinBoxFreq( spinbox ){ spinbox->setRange ( 0, INT_MAX ); \
spinbox->setAccelerated( true ); }
@@ -231,17 +239,52 @@ private slots:
void advancedDialog();
};
+class DirectoryModel : public QAbstractListModel {
+public:
+ int rowCount(const QModelIndex& parent = QModelIndex()) const override;
+ QVariant data(const QModelIndex& index, int) const override;
+ void addItem(cloudstorage::IItem::Pointer item);
+ cloudstorage::IItem::Pointer get(int) const;
+ QVariant getName(int) const;
+ QVariant getIcon(int) const;
+ void clear();
+
+private:
+ mutable QMutex mutex;
+ std::vector<cloudstorage::IItem::Pointer> list;
+};
+
+#ifdef WITH_LIBCLOUDSTORAGE
class CloudOpenPanel : public OpenPanel
{
Q_OBJECT
public:
CloudOpenPanel( QWidget *, intf_thread_t * );
+ ~CloudOpenPanel();
+
+ void save();
void clear();
+
+protected:
+ void keyPressEvent(QKeyEvent*) override;
+
private:
Ui::OpenCloud ui;
+ DirectoryModel directoryModel;
+ cloudstorage::ICloudStorage::Pointer cloudStorage;
+ cloudstorage::ICloudProvider::Pointer currentProvider;
+ cloudstorage::IItem::Pointer currentDirectory;
+ cloudstorage::ICloudProvider::ListDirectoryRequest::Pointer listDirectoryRequest;
+ cloudstorage::ICloudProvider::GetItemDataRequest::Pointer itemDataRequest;
+ std::vector<cloudstorage::IItem::Pointer> directoryStack;
+
+ void buttonClicked();
+ void itemClicked(const QModelIndex&);
+ void listDirectory();
public slots:
void updateMRL();
};
+#endif
#endif
diff --git a/modules/gui/qt/dialogs/open.cpp b/modules/gui/qt/dialogs/open.cpp
index 3856099..2625393 100644
--- a/modules/gui/qt/dialogs/open.cpp
+++ b/modules/gui/qt/dialogs/open.cpp
@@ -84,7 +84,9 @@ OpenDialog::OpenDialog( QWidget *parent,
discOpenPanel = new DiscOpenPanel( this, p_intf );
netOpenPanel = new NetOpenPanel( this, p_intf );
captureOpenPanel = new CaptureOpenPanel( this, p_intf );
+#ifdef WITH_LIBCLOUDSTORAGE
cloudOpenPanel = new CloudOpenPanel( this, p_intf );
+#endif
/* Insert the tabs */
ui.Tab->insertTab( OPEN_FILE_TAB, fileOpenPanel, QIcon( ":/type/file-asym" ),
@@ -95,8 +97,10 @@ OpenDialog::OpenDialog( QWidget *parent,
qtr( "&Network" ) );
ui.Tab->insertTab( OPEN_CAPTURE_TAB, captureOpenPanel,
QIcon( ":/type/capture-card" ), qtr( "Capture &Device" ) );
+#ifdef WITH_LIBCLOUDSTORAGE
ui.Tab->insertTab( OPEN_CLOUD_TAB, cloudOpenPanel, QIcon( ":/type/cloud" ),
qtr( "&Cloud" ) );
+#endif
/* Hide the Slave input widgets */
ui.slaveLabel->hide();
@@ -144,6 +148,10 @@ OpenDialog::OpenDialog( QWidget *parent,
this, updateMRL( const QStringList&, const QString& ) );
CONNECT( captureOpenPanel, mrlUpdated( const QStringList&, const QString& ),
this, updateMRL( const QStringList&, const QString& ) );
+#ifdef WITH_LIBCLOUDSTORAGE
+ CONNECT( cloudOpenPanel, mrlUpdated( const QStringList&, const QString& ),
+ this, updateMRL( const QStringList&, const QString& ) );
+#endif
CONNECT( fileOpenPanel, methodChanged( const QString& ),
this, newCachingMethod( const QString& ) );
@@ -153,6 +161,10 @@ OpenDialog::OpenDialog( QWidget *parent,
this, newCachingMethod( const QString& ) );
CONNECT( captureOpenPanel, methodChanged( const QString& ),
this, newCachingMethod( const QString& ) );
+#ifdef WITH_LIBCLOUDSTORAGE
+ CONNECT( cloudOpenPanel, methodChanged( const QString& ),
+ this, newCachingMethod( const QString& ) );
+#endif
/* Advanced frame Connects */
CONNECT( ui.slaveCheckbox, toggled( bool ), this, updateMRL() );
diff --git a/modules/gui/qt/dialogs/open.hpp b/modules/gui/qt/dialogs/open.hpp
index 6932851..f292760 100644
--- a/modules/gui/qt/dialogs/open.hpp
+++ b/modules/gui/qt/dialogs/open.hpp
@@ -99,7 +99,9 @@ private:
NetOpenPanel *netOpenPanel;
DiscOpenPanel *discOpenPanel;
CaptureOpenPanel *captureOpenPanel;
+#ifdef WITH_LIBCLOUDSTORAGE
CloudOpenPanel *cloudOpenPanel;
+#endif
int i_action_flag;
bool b_pl;
diff --git a/modules/gui/qt/menus.cpp b/modules/gui/qt/menus.cpp
index c70a315..78563ff 100644
--- a/modules/gui/qt/menus.cpp
+++ b/modules/gui/qt/menus.cpp
@@ -370,8 +370,10 @@ QMenu *VLCMenuBar::FileMenu( intf_thread_t *p_intf, QWidget *parent, MainInterfa
":/type/network", SLOT( openNetDialog() ), "Ctrl+N" );
addDPStaticEntry( menu, qtr( "Open &Capture Device..." ),
":/type/capture-card", SLOT( openCaptureDialog() ), "Ctrl+C" );
+#ifdef WITH_LIBCLOUDSTORAGE
addDPStaticEntry( menu, qtr( "Open Cloud File..."),
":/type/cloud", SLOT( openCloudDialog() ) );
+#endif
addDPStaticEntry( menu, qtr( "Open &Location from clipboard" ),
NULL, SLOT( openUrlDialog() ), "Ctrl+V" );
diff --git a/modules/gui/qt/ui/open_cloud.ui b/modules/gui/qt/ui/open_cloud.ui
index 1401402..9844411 100644
--- a/modules/gui/qt/ui/open_cloud.ui
+++ b/modules/gui/qt/ui/open_cloud.ui
@@ -13,45 +13,6 @@
<property name="windowTitle">
<string>Form</string>
</property>
- <widget class="QPushButton" name="pushButton">
- <property name="geometry">
- <rect>
- <x>20</x>
- <y>20</y>
- <width>99</width>
- <height>27</height>
- </rect>
- </property>
- <property name="text">
- <string>GoogleDrive</string>
- </property>
- </widget>
- <widget class="QPushButton" name="pushButton_2">
- <property name="geometry">
- <rect>
- <x>20</x>
- <y>50</y>
- <width>99</width>
- <height>27</height>
- </rect>
- </property>
- <property name="text">
- <string>OneDrive</string>
- </property>
- </widget>
- <widget class="QPushButton" name="pushButton_3">
- <property name="geometry">
- <rect>
- <x>20</x>
- <y>80</y>
- <width>99</width>
- <height>27</height>
- </rect>
- </property>
- <property name="text">
- <string>Dropbox</string>
- </property>
- </widget>
</widget>
<resources/>
<connections/>
--
2.9.3
More information about the vlc-devel
mailing list