diff options
author | Hannah von Reth <hannah.vonreth@owncloud.com> | 2022-02-24 16:51:15 +0300 |
---|---|---|
committer | Fabian Müller <80399010+fmoc@users.noreply.github.com> | 2022-04-13 17:21:25 +0300 |
commit | 6c2a0ea867f75dc36a997b829bdf2424bcb101d5 (patch) | |
tree | 372aa7b7f20d483759f2e370b89df22d57a2690a /src/gui/spaces | |
parent | 4033411ffadb7d9491fafe89a2dc72f47173897e (diff) |
Allow to add Folder sync pairs based on spaces
Diffstat (limited to 'src/gui/spaces')
-rw-r--r-- | src/gui/spaces/CMakeLists.txt | 14 | ||||
-rw-r--r-- | src/gui/spaces/spacesbrowser.cpp | 78 | ||||
-rw-r--r-- | src/gui/spaces/spacesbrowser.h | 49 | ||||
-rw-r--r-- | src/gui/spaces/spacesbrowser.ui | 52 | ||||
-rw-r--r-- | src/gui/spaces/spacesmodel.cpp | 147 | ||||
-rw-r--r-- | src/gui/spaces/spacesmodel.h | 55 |
6 files changed, 395 insertions, 0 deletions
diff --git a/src/gui/spaces/CMakeLists.txt b/src/gui/spaces/CMakeLists.txt new file mode 100644 index 000000000..8485e7816 --- /dev/null +++ b/src/gui/spaces/CMakeLists.txt @@ -0,0 +1,14 @@ +add_library(spaces OBJECT + spacesmodel.cpp spacesbrowser.cpp spacesbrowser.ui) +target_link_libraries(spaces PUBLIC Qt5::Widgets libsync) +set_target_properties(spaces PROPERTIES AUTOUIC ON AUTORCC ON) +target_compile_definitions(spaces + PRIVATE QT_NO_CAST_TO_ASCII + QT_NO_CAST_FROM_ASCII + QT_NO_URL_CAST_FROM_STRING + QT_NO_CAST_FROM_BYTEARRAY + QT_USE_QSTRINGBUILDER + QT_MESSAGELOGCONTEXT # enable function name and line number in debug output + QT_DEPRECATED_WARNINGS + QT_NO_FOREACH +) diff --git a/src/gui/spaces/spacesbrowser.cpp b/src/gui/spaces/spacesbrowser.cpp new file mode 100644 index 000000000..a237bed68 --- /dev/null +++ b/src/gui/spaces/spacesbrowser.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) by Hannah von Reth <hannah.vonreth@owncloud.com> + * + * 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. + */ +#include "spacesbrowser.h" +#include "ui_spacesbrowser.h" + +#include "spacesmodel.h" + +#include "graphapi/drives.h" + +#include "gui/models/expandingheaderview.h" + +#include <QCursor> +#include <QMenu> + +using namespace OCC::Spaces; + +SpacesBrowser::SpacesBrowser(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SpacesBrowser) +{ + ui->setupUi(this); + _model = new SpacesModel(this); + ui->tableView->setModel(_model); + + connect(ui->tableView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &SpacesBrowser::selectionChanged); + + ui->tableView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + auto header = new OCC::ExpandingHeaderView(QStringLiteral("SpacesBrowserHeader"), ui->tableView); + ui->tableView->setHorizontalHeader(header); + header->setExpandingColumn(static_cast<int>(SpacesModel::Columns::Name)); + header->hideSection(static_cast<int>(SpacesModel::Columns::WebDavUrl)); + // not used yet + header->hideSection(static_cast<int>(SpacesModel::Columns::WebUrl)); + header->setContextMenuPolicy(Qt::CustomContextMenu); + connect(header, &QHeaderView::customContextMenuRequested, header, [header, this] { + auto menu = new QMenu(this); + menu->setAttribute(Qt::WA_DeleteOnClose); + header->addResetActionToMenu(menu); + menu->popup(QCursor::pos()); + }); +} + +SpacesBrowser::~SpacesBrowser() +{ + delete ui; +} + +void SpacesBrowser::setAccount(OCC::AccountPtr acc) +{ + _acc = acc; + if (acc) { + QTimer::singleShot(0, this, [this] { + auto drive = new OCC::GraphApi::Drives(_acc); + connect(drive, &OCC::GraphApi::Drives::finishedSignal, [drive, this] { + _model->setData(_acc, drive->drives()); + show(); + }); + drive->start(); + }); + } +} + +QModelIndex SpacesBrowser::currentSpace() +{ + const auto spaces = ui->tableView->selectionModel()->selectedRows(); + return spaces.isEmpty() ? QModelIndex {} : spaces.first(); +} diff --git a/src/gui/spaces/spacesbrowser.h b/src/gui/spaces/spacesbrowser.h new file mode 100644 index 000000000..12c950339 --- /dev/null +++ b/src/gui/spaces/spacesbrowser.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) by Hannah von Reth <hannah.vonreth@owncloud.com> + * + * 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. + */ +#pragma once + +#include "account.h" + +#include <QWidget> + +namespace Ui { +class SpacesBrowser; +} + +namespace OCC::Spaces { +class SpacesModel; + +class SpacesBrowser : public QWidget +{ + Q_OBJECT + +public: + explicit SpacesBrowser(QWidget *parent = nullptr); + ~SpacesBrowser(); + + void setAccount(OCC::AccountPtr acc); + + QModelIndex currentSpace(); + +Q_SIGNALS: + void selectionChanged(); + +private: + Ui::SpacesBrowser *ui; + + OCC::AccountPtr _acc; + SpacesModel *_model; +}; + +}
\ No newline at end of file diff --git a/src/gui/spaces/spacesbrowser.ui b/src/gui/spaces/spacesbrowser.ui new file mode 100644 index 000000000..b4c6fe224 --- /dev/null +++ b/src/gui/spaces/spacesbrowser.ui @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>SpacesBrowser</class> + <widget class="QWidget" name="SpacesBrowser"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QTableView" name="tableView"> + <property name="selectionMode"> + <enum>QAbstractItemView::SingleSelection</enum> + </property> + <property name="selectionBehavior"> + <enum>QAbstractItemView::SelectRows</enum> + </property> + <attribute name="horizontalHeaderVisible"> + <bool>true</bool> + </attribute> + <attribute name="verticalHeaderVisible"> + <bool>false</bool> + </attribute> + <attribute name="verticalHeaderHighlightSections"> + <bool>false</bool> + </attribute> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/gui/spaces/spacesmodel.cpp b/src/gui/spaces/spacesmodel.cpp new file mode 100644 index 000000000..924d84384 --- /dev/null +++ b/src/gui/spaces/spacesmodel.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (C) by Hannah von Reth <hannah.vonreth@owncloud.com> + * + * 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. + */ +#include "spacesmodel.h" + +#include "networkjobs.h" + +#include <QPixmap> + +namespace { +constexpr QSize ImageSizeC(128, 128); +} + +using namespace OCC::Spaces; + +SpacesModel::SpacesModel(QObject *parent) + : QAbstractTableModel(parent) +{ +} + +QVariant SpacesModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Horizontal) { + const auto actionRole = static_cast<Columns>(section); + switch (role) { + case Qt::DisplayRole: + switch (actionRole) { + case Columns::Name: + return tr("Name"); + case Columns::Description: + return tr("Description"); + case Columns::WebUrl: + return tr("Web URL"); + case Columns::WebDavUrl: + return tr("Web Dav URL"); + case Columns::Image: + return tr("Image"); + case Columns::ColumnCount: + Q_UNREACHABLE(); + break; + } + } + } + return QAbstractTableModel::headerData(section, orientation, role); +} + +int SpacesModel::rowCount(const QModelIndex &parent) const +{ + Q_ASSERT(checkIndex(parent)); + if (parent.isValid()) + return 0; + return static_cast<int>(_data.size()); +} + +int SpacesModel::columnCount(const QModelIndex &parent) const +{ + Q_ASSERT(checkIndex(parent)); + if (parent.isValid()) { + return 0; + } + return static_cast<int>(Columns::ColumnCount); +} + +QVariant SpacesModel::data(const QModelIndex &index, int role) const +{ + Q_ASSERT(checkIndex(index, QAbstractItemModel::CheckIndexOption::IndexIsValid)); + + const auto column = static_cast<Columns>(index.column()); + const auto &item = _data.at(index.row()); + switch (role) { + case Qt::DisplayRole: + switch (column) { + case Columns::Name: + return item.getName(); + case Columns::Description: + return item.getDescription(); + case Columns::WebUrl: + return item.getWebUrl(); + case Columns::WebDavUrl: + return item.getRoot().getWebDavUrl(); + case Columns::Image: { + const auto &special = item.getSpecial(); + const auto img = std::find_if(special.cbegin(), special.cend(), [](OpenAPI::OAIDriveItem it) { + return it.getSpecialFolder().getName() == QLatin1String("image"); + }); + return img == special.cend() ? QString() : img->getWebDavUrl(); + } + case Columns::ColumnCount: + Q_UNREACHABLE(); + break; + } + break; + case Qt::DecorationRole: + switch (column) { + case Columns::Image: { + auto it = _images.find(item.getId()); + if (it != _images.cend()) { + return QVariant::fromValue(*it); + } + const auto imgUrl = data(index, Qt::DisplayRole); + if (!imgUrl.isValid()) { + return {}; + } + // TODO: placeholder + _images[item.getId()] = QPixmap(); + auto davUrl = QUrl(item.getRoot().getWebDavUrl()); + auto path = imgUrl.toString().remove(item.getRoot().getWebDavUrl()); + auto job = new OCC::SimpleNetworkJob(_acc, davUrl, path, "GET", {}, {}, nullptr); + connect(job, &OCC::SimpleNetworkJob::finishedSignal, this, [job, id = item.getId(), index, this] { + QPixmap img; + qDebug() << img.loadFromData(job->reply()->readAll()); + img = img.scaled(ImageSizeC, Qt::KeepAspectRatio); + _images[id] = img; + Q_EMIT const_cast<SpacesModel *>(this)->dataChanged(index, index, { Qt::DecorationRole }); + }); + job->start(); + return _images[item.getId()]; + } break; + } + case Qt::SizeHintRole: { + switch (column) { + case Columns::Image: { + return ImageSizeC; + } + } + } + } + return {}; +} + +void SpacesModel::setData(OCC::AccountPtr acc, const QList<OpenAPI::OAIDrive> &data) +{ + beginResetModel(); + _acc = acc; + _data = data; + endResetModel(); +} diff --git a/src/gui/spaces/spacesmodel.h b/src/gui/spaces/spacesmodel.h new file mode 100644 index 000000000..8f40cd9e7 --- /dev/null +++ b/src/gui/spaces/spacesmodel.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) by Hannah von Reth <hannah.vonreth@owncloud.com> + * + * 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. + */ +#pragma once + +#include "accountfwd.h" + +#include <graphapi/drives.h> + +#include <QAbstractItemModel> + +namespace OCC::Spaces { +class SpacesModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + enum class Columns { + Image, + Name, + Description, + WebUrl, + WebDavUrl, + + ColumnCount + }; + Q_ENUM(Columns) + explicit SpacesModel(QObject *parent = nullptr); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + void setData(OCC::AccountPtr acc, const QList<OpenAPI::OAIDrive> &data); + +private: + QList<OpenAPI::OAIDrive> _data; + + mutable QMap<QString, QPixmap> _images; + OCC::AccountPtr _acc; +}; +}
\ No newline at end of file |