Commit 3651067e authored by Paweł Wegner's avatar Paweł Wegner

cloudbrowser: added ProviderListModel.

parent 46f26058
......@@ -61,15 +61,19 @@ Kirigami.ApplicationWindow {
}
}
Connections {
target: cloud.userProviders
onUpdated: {
root.globalDrawer.actions = root.actions(cloud.userProviders.variant());
}
}
CloudContext {
property var list_request
property var currently_moved
property variant request: []
id: cloud
onUserProvidersChanged: {
root.globalDrawer.actions = root.actions();
}
onErrorOccurred: {
if (operation !== "GetThumbnail") {
var message = "";
......@@ -105,15 +109,15 @@ Kirigami.ApplicationWindow {
return str.substr(0, length) + "...";
}
function actions() {
function actions(userProviders) {
var ret = [settings.createObject(root.globalDrawer)], i;
if (cloud.isFree) {
ret.push(supportAction.createObject(root.globalDrawer));
}
for (i = 0; i < cloud.userProviders.length; i++) {
for (i = 0; i < userProviders.length; i++) {
var props = {
provider: cloud.userProviders[i],
iconName: "qrc:/resources/providers/" + cloud.userProviders[i].type + ".png"
provider: userProviders[i],
iconName: "qrc:/resources/providers/" + userProviders[i].type + ".png"
};
ret.push(providerAction.createObject(root.globalDrawer, props));
}
......@@ -189,7 +193,7 @@ Kirigami.ApplicationWindow {
title: "Cloud Browser"
titleIcon: "qrc:/resources/cloud.png"
drawerOpen: true
actions: root.actions()
actions: root.actions(cloud.userProviders.variant())
height: parent.height - footer_height
handle.anchors.bottomMargin: footer_height
}
......
......@@ -36,6 +36,72 @@ QString sanitize(const QString& name) {
} // namespace
int ProviderListModel::rowCount(const QModelIndex&) const {
return provider_.size();
}
QVariant ProviderListModel::data(const QModelIndex& index, int) const {
return provider_[index.row()].variant();
}
QHash<int, QByteArray> ProviderListModel::roleNames() const {
return {{Qt::DisplayRole, "modelData"}};
}
void ProviderListModel::remove(QVariant provider) {
auto label = provider.toMap()["label"].toString().toStdString();
auto type = provider.toMap()["type"].toString().toStdString();
for (size_t i = 0; i < provider_.size();)
if (provider_[i].label_ == label &&
provider_[i].provider_->name() == type) {
beginRemoveRows(QModelIndex(), i, i);
provider_.erase(provider_.begin() + i);
endRemoveRows();
emit updated();
} else {
i++;
}
}
Provider ProviderListModel::provider(QVariant provider) const {
auto label = provider.toMap()["label"].toString().toStdString();
auto type = provider.toMap()["type"].toString().toStdString();
for (auto&& i : provider_)
if (i.label_ == label && i.provider_->name() == type) return i;
return {};
}
QVariantList ProviderListModel::dump() const {
QVariantList array;
for (auto&& p : provider_) {
QVariantMap dict;
dict["token"] = p.provider_->token().c_str();
dict["access_token"] = p.provider_->hints()["access_token"].c_str();
dict["type"] = p.provider_->name().c_str();
dict["label"] = p.label_.c_str();
array.append(dict);
}
return array;
}
void ProviderListModel::add(const Provider& p) {
std::unordered_set<std::string> names;
for (auto&& i : provider_)
if (i.provider_->name() == p.provider_->name()) names.insert(i.label_);
if (names.find(p.label_) == names.end()) {
beginInsertRows(QModelIndex(), rowCount(), rowCount());
provider_.push_back(p);
endInsertRows();
emit updated();
}
}
QVariantList ProviderListModel::variant() const {
QVariantList result;
for (auto&& p : provider_) result.push_back(p.variant());
return result;
}
CloudContext::CloudContext(QObject* parent)
: QObject(parent),
config_([]() {
......@@ -55,7 +121,7 @@ CloudContext::CloudContext(QObject* parent)
for (auto j : providers) {
auto obj = j.toMap();
auto label = obj["label"].toString().toStdString();
provider_.push_back(
user_provider_model_.add(
{label,
this->provider(obj["type"].toString().toStdString(), label,
Token{obj["token"].toString().toStdString(),
......@@ -129,16 +195,7 @@ void CloudContext::saveCachedDirectories() {
void CloudContext::save() {
std::lock_guard<std::mutex> lock(mutex_);
QSettings settings;
QVariantList array;
for (auto&& p : provider_) {
QVariantMap dict;
dict["token"] = p.provider_->token().c_str();
dict["access_token"] = p.provider_->hints()["access_token"].c_str();
dict["type"] = p.provider_->name().c_str();
dict["label"] = p.label_.c_str();
array.append(dict);
}
settings.setValue("providers", array);
settings.setValue("providers", user_provider_model_.dump());
saveCachedDirectories();
}
......@@ -148,11 +205,8 @@ QStringList CloudContext::providers() const {
return list;
}
QVariantList CloudContext::userProviders() const {
std::lock_guard<std::mutex> lock(mutex_);
QVariantList result;
for (auto&& i : provider_) result.push_back(i.variant());
return result;
ProviderListModel* CloudContext::userProviders() {
return &user_provider_model_;
}
bool CloudContext::includeAds() const {
......@@ -177,28 +231,21 @@ QString CloudContext::authorizationUrl(QString provider) const {
QObject* CloudContext::root(QVariant provider) {
std::lock_guard<std::mutex> lock(mutex_);
auto label = provider.toMap()["label"].toString().toStdString();
auto type = provider.toMap()["type"].toString().toStdString();
for (auto&& i : provider_)
if (i.label_ == label && i.provider_->name() == type) {
auto item = new CloudItem(i, i.provider_->rootDirectory());
QQmlEngine::setObjectOwnership(item, QQmlEngine::JavaScriptOwnership);
return item;
}
return nullptr;
auto p = user_provider_model_.provider(provider);
if (p.provider_) {
auto item = new CloudItem(p, p.provider_->rootDirectory());
QQmlEngine::setObjectOwnership(item, QQmlEngine::JavaScriptOwnership);
return item;
} else {
return nullptr;
}
}
void CloudContext::removeProvider(QVariant provider) {
{
std::lock_guard<std::mutex> lock(mutex_);
auto label = provider.toMap()["label"].toString().toStdString();
auto type = provider.toMap()["type"].toString().toStdString();
std::vector<Provider> r;
for (auto&& i : provider_)
if (i.label_ != label || i.provider_->name() != type) r.push_back(i);
provider_ = r;
user_provider_model_.remove(provider);
}
emit userProvidersChanged();
save();
}
......@@ -342,18 +389,13 @@ void CloudContext::receivedCode(std::string provider, std::string code) {
return emit errorOccurred("GeneralData", provider_variant,
d.left()->code_,
d.left()->description_.c_str());
std::unique_lock<std::mutex> lock(mutex_);
std::unordered_set<std::string> names;
for (auto&& i : provider_)
if (i.provider_->name() == provider) names.insert(i.label_);
if (names.find(d.right()->username_) == names.end()) {
provider_.push_back(
{
std::unique_lock<std::mutex> lock(mutex_);
user_provider_model_.add(
{d.right()->username_,
this->provider(provider, d.right()->username_, *e.right())});
lock.unlock();
save();
emit userProvidersChanged();
}
save();
}));
});
pool_.add(std::move(p), std::move(r));
......@@ -425,13 +467,6 @@ ICloudProvider::Pointer CloudContext::provider(const std::string& name,
return ICloudStorage::create()->provider(name, std::move(data));
}
ICloudProvider* CloudContext::provider(const std::string& label) const {
std::lock_guard<std::mutex> lock(mutex_);
for (auto&& i : provider_)
if (i.label_ == label) return i.provider_.get();
return nullptr;
}
ICloudProvider::InitData CloudContext::init_data(
const std::string& name) const {
ICloudProvider::InitData data;
......
......@@ -4,8 +4,8 @@
#include "CloudItem.h"
#include "HttpServer.h"
#include "ICloudProvider.h"
#include "Request/ListDirectory.h"
#include "Request/CloudRequest.h"
#include "Request/ListDirectory.h"
#include <QAbstractListModel>
#include <QJsonDocument>
......@@ -20,11 +20,33 @@
#include <streambuf>
#include <unordered_set>
class CloudContext;
class ProviderListModel : public QAbstractListModel {
public:
int rowCount(const QModelIndex& = QModelIndex()) const override;
QVariant data(const QModelIndex& index, int role) const override;
QHash<int, QByteArray> roleNames() const override;
void add(const Provider&);
void remove(QVariant provider);
Provider provider(QVariant provider) const;
QVariantList dump() const;
Q_INVOKABLE QVariantList variant() const;
signals:
void updated();
private:
std::vector<Provider> provider_;
Q_OBJECT
};
class CloudContext : public QObject {
public:
Q_PROPERTY(QStringList providers READ providers CONSTANT)
Q_PROPERTY(
QVariantList userProviders READ userProviders NOTIFY userProvidersChanged)
Q_PROPERTY(ProviderListModel* userProviders READ userProviders CONSTANT)
Q_PROPERTY(bool includeAds READ includeAds CONSTANT)
Q_PROPERTY(bool isFree READ isFree CONSTANT)
Q_PROPERTY(qint64 cacheSize READ cacheSize NOTIFY cacheSizeChanged)
......@@ -39,7 +61,7 @@ class CloudContext : public QObject {
void save();
QStringList providers() const;
QVariantList userProviders() const;
ProviderListModel* userProviders();
bool includeAds() const;
bool isFree() const;
bool httpServerAvailable() const;
......@@ -71,7 +93,6 @@ class CloudContext : public QObject {
static QString thumbnail_path(const QString& filename);
signals:
void userProvidersChanged();
void receivedCode(QString provider);
void errorOccurred(QString operation, QVariantMap provider, int code,
QString description);
......@@ -121,7 +142,6 @@ class CloudContext : public QObject {
cloudstorage::ICloudProvider::Pointer provider(
const std::string& name, const std::string& label,
cloudstorage::Token token) const;
cloudstorage::ICloudProvider* provider(const std::string& label) const;
cloudstorage::ICloudProvider::InitData init_data(
const std::string& name) const;
......@@ -133,11 +153,11 @@ class CloudContext : public QObject {
std::shared_ptr<cloudstorage::IHttp> http_;
std::shared_ptr<cloudstorage::IThreadPool> thread_pool_;
RequestPool pool_;
std::vector<Provider> provider_;
std::unordered_map<ListDirectoryCacheKey,
std::vector<cloudstorage::IItem::Pointer>>
list_directory_cache_;
qint64 cache_size_;
ProviderListModel user_provider_model_;
Q_OBJECT
};
......
......@@ -62,6 +62,8 @@ void register_types() {
qRegisterMetaType<cloudstorage::EitherError<std::string>>();
qRegisterMetaType<cloudstorage::EitherError<cloudstorage::IItem>>();
qRegisterMetaType<cloudstorage::EitherError<QVariant>>();
qRegisterMetaType<ProviderListModel*>();
qRegisterMetaType<ListDirectoryModel*>();
qmlRegisterType<CloudContext>("libcloudstorage", 1, 0, "CloudContext");
qmlRegisterType<ListDirectoryRequest>("libcloudstorage", 1, 0,
"ListDirectoryRequest");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment