diff options
Diffstat (limited to 'api/dead')
| -rw-r--r-- | api/dead/README.md | 3 | ||||
| -rw-r--r-- | api/dead/src/AbstractCommonModel.cpp | 133 | ||||
| -rw-r--r-- | api/dead/src/AbstractCommonModel.h | 462 | ||||
| -rw-r--r-- | api/dead/src/BaseConfigObject.cpp | 103 | ||||
| -rw-r--r-- | api/dead/src/BaseConfigObject.h | 50 | ||||
| -rw-r--r-- | api/dead/src/TypeMagic.h | 37 | ||||
| -rw-r--r-- | api/dead/src/handlers/IconResourceHandler.cpp | 37 | ||||
| -rw-r--r-- | api/dead/src/handlers/IconResourceHandler.h | 23 | ||||
| -rw-r--r-- | api/dead/src/handlers/WebResourceHandler.cpp | 68 | ||||
| -rw-r--r-- | api/dead/src/handlers/WebResourceHandler.h | 23 | ||||
| -rw-r--r-- | api/dead/src/resources/Resource.cpp | 155 | ||||
| -rw-r--r-- | api/dead/src/resources/Resource.h | 132 | ||||
| -rw-r--r-- | api/dead/src/resources/ResourceHandler.cpp | 28 | ||||
| -rw-r--r-- | api/dead/src/resources/ResourceHandler.h | 36 | ||||
| -rw-r--r-- | api/dead/src/resources/ResourceObserver.cpp | 55 | ||||
| -rw-r--r-- | api/dead/src/resources/ResourceObserver.h | 73 | ||||
| -rw-r--r-- | api/dead/src/resources/ResourceProxyModel.cpp | 89 | ||||
| -rw-r--r-- | api/dead/src/resources/ResourceProxyModel.h | 39 | ||||
| -rw-r--r-- | api/dead/test/tst_Resource.cpp | 116 |
19 files changed, 1662 insertions, 0 deletions
diff --git a/api/dead/README.md b/api/dead/README.md new file mode 100644 index 00000000..520b18d3 --- /dev/null +++ b/api/dead/README.md @@ -0,0 +1,3 @@ +This stuff is dead code I collected from the repository that still looks like it might be useful for something. + +Moved on 10. April 2016 - if it hasn't been moved or used in a while, delete this. diff --git a/api/dead/src/AbstractCommonModel.cpp b/api/dead/src/AbstractCommonModel.cpp new file mode 100644 index 00000000..71d75829 --- /dev/null +++ b/api/dead/src/AbstractCommonModel.cpp @@ -0,0 +1,133 @@ +/* Copyright 2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AbstractCommonModel.h" + +BaseAbstractCommonModel::BaseAbstractCommonModel(const Qt::Orientation orientation, QObject *parent) + : QAbstractListModel(parent), m_orientation(orientation) +{ +} + +int BaseAbstractCommonModel::rowCount(const QModelIndex &parent) const +{ + return m_orientation == Qt::Horizontal ? entryCount() : size(); +} +int BaseAbstractCommonModel::columnCount(const QModelIndex &parent) const +{ + return m_orientation == Qt::Horizontal ? size() : entryCount(); +} +QVariant BaseAbstractCommonModel::data(const QModelIndex &index, int role) const +{ + if (!hasIndex(index.row(), index.column(), index.parent())) + { + return QVariant(); + } + const int i = m_orientation == Qt::Horizontal ? index.column() : index.row(); + const int entry = m_orientation == Qt::Horizontal ? index.row() : index.column(); + return formatData(i, role, get(i, entry, role)); +} +QVariant BaseAbstractCommonModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation != m_orientation && role == Qt::DisplayRole) + { + return entryTitle(section); + } + else + { + return QVariant(); + } +} +bool BaseAbstractCommonModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + const int i = m_orientation == Qt::Horizontal ? index.column() : index.row(); + const int entry = m_orientation == Qt::Horizontal ? index.row() : index.column(); + const bool result = set(i, entry, role, sanetizeData(i, role, value)); + if (result) + { + emit dataChanged(index, index, QVector<int>() << role); + } + return result; +} +Qt::ItemFlags BaseAbstractCommonModel::flags(const QModelIndex &index) const +{ + if (!hasIndex(index.row(), index.column(), index.parent())) + { + return Qt::NoItemFlags; + } + + const int entry = m_orientation == Qt::Horizontal ? index.row() : index.column(); + if (canSet(entry)) + { + return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEnabled; + } + else + { + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + } +} + +void BaseAbstractCommonModel::notifyAboutToAddObject(const int at) +{ + if (m_orientation == Qt::Horizontal) + { + beginInsertColumns(QModelIndex(), at, at); + } + else + { + beginInsertRows(QModelIndex(), at, at); + } +} +void BaseAbstractCommonModel::notifyObjectAdded() +{ + if (m_orientation == Qt::Horizontal) + { + endInsertColumns(); + } + else + { + endInsertRows(); + } +} +void BaseAbstractCommonModel::notifyAboutToRemoveObject(const int at) +{ + if (m_orientation == Qt::Horizontal) + { + beginRemoveColumns(QModelIndex(), at, at); + } + else + { + beginRemoveRows(QModelIndex(), at, at); + } +} +void BaseAbstractCommonModel::notifyObjectRemoved() +{ + if (m_orientation == Qt::Horizontal) + { + endRemoveColumns(); + } + else + { + endRemoveRows(); + } +} + +void BaseAbstractCommonModel::notifyBeginReset() +{ + beginResetModel(); +} +void BaseAbstractCommonModel::notifyEndReset() +{ + endResetModel(); +} diff --git a/api/dead/src/AbstractCommonModel.h b/api/dead/src/AbstractCommonModel.h new file mode 100644 index 00000000..31b86a23 --- /dev/null +++ b/api/dead/src/AbstractCommonModel.h @@ -0,0 +1,462 @@ +/* Copyright 2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <QAbstractListModel> +#include <type_traits> +#include <functional> +#include <memory> + +class BaseAbstractCommonModel : public QAbstractListModel +{ + Q_OBJECT +public: + explicit BaseAbstractCommonModel(const Qt::Orientation orientation, QObject *parent = nullptr); + + // begin QAbstractItemModel interface + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role) override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + // end QAbstractItemModel interface + + virtual int size() const = 0; + virtual int entryCount() const = 0; + + virtual QVariant formatData(const int index, int role, const QVariant &data) const { return data; } + virtual QVariant sanetizeData(const int index, int role, const QVariant &data) const { return data; } + +protected: + virtual QVariant get(const int index, const int entry, const int role) const = 0; + virtual bool set(const int index, const int entry, const int role, const QVariant &value) = 0; + virtual bool canSet(const int entry) const = 0; + virtual QString entryTitle(const int entry) const = 0; + + void notifyAboutToAddObject(const int at); + void notifyObjectAdded(); + void notifyAboutToRemoveObject(const int at); + void notifyObjectRemoved(); + void notifyBeginReset(); + void notifyEndReset(); + + const Qt::Orientation m_orientation; +}; + +template<typename Object> +class AbstractCommonModel : public BaseAbstractCommonModel +{ +public: + explicit AbstractCommonModel(const Qt::Orientation orientation) + : BaseAbstractCommonModel(orientation) {} + virtual ~AbstractCommonModel() {} + + int size() const override { return m_objects.size(); } + int entryCount() const override { return m_entries.size(); } + + void append(const Object &object) + { + notifyAboutToAddObject(size()); + m_objects.append(object); + notifyObjectAdded(); + } + void prepend(const Object &object) + { + notifyAboutToAddObject(0); + m_objects.prepend(object); + notifyObjectAdded(); + } + void insert(const Object &object, const int index) + { + if (index >= size()) + { + prepend(object); + } + else if (index <= 0) + { + append(object); + } + else + { + notifyAboutToAddObject(index); + m_objects.insert(index, object); + notifyObjectAdded(); + } + } + void remove(const int index) + { + notifyAboutToRemoveObject(index); + m_objects.removeAt(index); + notifyObjectRemoved(); + } + Object get(const int index) const + { + return m_objects.at(index); + } + +private: + friend class CommonModel; + QVariant get(const int index, const int entry, const int role) const override + { + if (m_entries.size() < entry || !m_entries[entry].second.contains(role)) + { + return QVariant(); + } + return m_entries[entry].second.value(role)->get(m_objects.at(index)); + } + bool set(const int index, const int entry, const int role, const QVariant &value) override + { + if (m_entries.size() < entry || !m_entries[entry].second.contains(role)) + { + return false; + } + IEntry *e = m_entries[entry].second.value(role); + if (!e->canSet()) + { + return false; + } + e->set(m_objects[index], value); + return true; + } + bool canSet(const int entry) const override + { + if (m_entries.size() < entry || !m_entries[entry].second.contains(Qt::EditRole)) + { + return false; + } + IEntry *e = m_entries[entry].second.value(Qt::EditRole); + return e->canSet(); + } + + QString entryTitle(const int entry) const override + { + return m_entries.at(entry).first; + } + +private: + struct IEntry + { + virtual ~IEntry() {} + virtual void set(Object &object, const QVariant &value) = 0; + virtual QVariant get(const Object &object) const = 0; + virtual bool canSet() const = 0; + }; + template<typename T> + struct VariableEntry : public IEntry + { + typedef T (Object::*Member); + + explicit VariableEntry(Member member) + : m_member(member) {} + + void set(Object &object, const QVariant &value) override + { + object.*m_member = value.value<T>(); + } + QVariant get(const Object &object) const override + { + return QVariant::fromValue<T>(object.*m_member); + } + bool canSet() const override { return true; } + + private: + Member m_member; + }; + template<typename T> + struct FunctionEntry : public IEntry + { + typedef T (Object::*Getter)() const; + typedef void (Object::*Setter)(T); + + explicit FunctionEntry(Getter getter, Setter setter) + : m_getter(m_getter), m_setter(m_setter) {} + + void set(Object &object, const QVariant &value) override + { + object.*m_setter(value.value<T>()); + } + QVariant get(const Object &object) const override + { + return QVariant::fromValue<T>(object.*m_getter()); + } + bool canSet() const override { return !!m_setter; } + + private: + Getter m_getter; + Setter m_setter; + }; + + QList<Object> m_objects; + QVector<QPair<QString, QMap<int, IEntry *>>> m_entries; + + void addEntryInternal(IEntry *e, const int entry, const int role) + { + if (m_entries.size() <= entry) + { + m_entries.resize(entry + 1); + } + m_entries[entry].second.insert(role, e); + } + +protected: + template<typename Getter, typename Setter> + typename std::enable_if<std::is_member_function_pointer<Getter>::value && std::is_member_function_pointer<Getter>::value, void>::type + addEntry(Getter getter, Setter setter, const int entry, const int role) + { + addEntryInternal(new FunctionEntry<typename std::result_of<Getter>::type>(getter, setter), entry, role); + } + template<typename Getter> + typename std::enable_if<std::is_member_function_pointer<Getter>::value, void>::type + addEntry(Getter getter, const int entry, const int role) + { + addEntryInternal(new FunctionEntry<typename std::result_of<Getter>::type>(getter, nullptr), entry, role); + } + template<typename T> + typename std::enable_if<!std::is_member_function_pointer<T (Object::*)>::value, void>::type + addEntry(T (Object::*member), const int entry, const int role) + { + addEntryInternal(new VariableEntry<T>(member), entry, role); + } + + void setEntryTitle(const int entry, const QString &title) + { + m_entries[entry].first = title; + } +}; +template<typename Object> +class AbstractCommonModel<Object *> : public BaseAbstractCommonModel +{ +public: + explicit AbstractCommonModel(const Qt::Orientation orientation) + : BaseAbstractCommonModel(orientation) {} + virtual ~AbstractCommonModel() + { + qDeleteAll(m_objects); + } + + int size() const override { return m_objects.size(); } + int entryCount() const override { return m_entries.size(); } + + void append(Object *object) + { + notifyAboutToAddObject(size()); + m_objects.append(object); + notifyObjectAdded(); + } + void prepend(Object *object) + { + notifyAboutToAddObject(0); + m_objects.prepend(object); + notifyObjectAdded(); + } + void insert(Object *object, const int index) + { + if (index >= size()) + { + prepend(object); + } + else if (index <= 0) + { + append(object); + } + else + { + notifyAboutToAddObject(index); + m_objects.insert(index, object); + notifyObjectAdded(); + } + } + void remove(const int index) + { + notifyAboutToRemoveObject(index); + m_objects.removeAt(index); + notifyObjectRemoved(); + } + Object *get(const int index) const + { + return m_objects.at(index); + } + int find(Object * const obj) const + { + return m_objects.indexOf(obj); + } + + QList<Object *> getAll() const + { + return m_objects; + } + +private: + friend class CommonModel; + QVariant get(const int index, const int entry, const int role) const override + { + if (m_entries.size() < entry || !m_entries[entry].second.contains(role)) + { + return QVariant(); + } + return m_entries[entry].second.value(role)->get(m_objects.at(index)); + } + bool set(const int index, const int entry, const int role, const QVariant &value) override + { + if (m_entries.size() < entry || !m_entries[entry].second.contains(role)) + { + return false; + } + IEntry *e = m_entries[entry].second.value(role); + if (!e->canSet()) + { + return false; + } + e->set(m_objects[index], value); + return true; + } + bool canSet(const int entry) const override + { + if (m_entries.size() < entry || !m_entries[entry].second.contains(Qt::EditRole)) + { + return false; + } + IEntry *e = m_entries[entry].second.value(Qt::EditRole); + return e->canSet(); + } + + QString entryTitle(const int entry) const override + { + return m_entries.at(entry).first; + } + +private: + struct IEntry + { + virtual ~IEntry() {} + virtual void set(Object *object, const QVariant &value) = 0; + virtual QVariant get(Object *object) const = 0; + virtual bool canSet() const = 0; + }; + template<typename T> + struct VariableEntry : public IEntry + { + typedef T (Object::*Member); + + explicit VariableEntry(Member member) + : m_member(member) {} + + void set(Object *object, const QVariant &value) override + { + object->*m_member = value.value<T>(); + } + QVariant get(Object *object) const override + { + return QVariant::fromValue<T>(object->*m_member); + } + bool canSet() const override { return true; } + + private: + Member m_member; + }; + template<typename T> + struct FunctionEntry : public IEntry + { + typedef T (Object::*Getter)() const; + typedef void (Object::*Setter)(T); + + explicit FunctionEntry(Getter getter, Setter setter) + : m_getter(getter), m_setter(setter) {} + + void set(Object *object, const QVariant &value) override + { + (object->*m_setter)(value.value<T>()); + } + QVariant get(Object *object) const override + { + return QVariant::fromValue<T>((object->*m_getter)()); + } + bool canSet() const override { return !!m_setter; } + + private: + Getter m_getter; + Setter m_setter; + }; + template<typename T> + struct LambdaEntry : public IEntry + { + using Getter = std::function<T(Object *)>; + + explicit LambdaEntry(Getter getter) + : m_getter(getter) {} + + void set(Object *object, const QVariant &value) override {} + QVariant get(Object *object) const override + { + return QVariant::fromValue<T>(m_getter(object)); + } + bool canSet() const override { return false; } + + private: + Getter m_getter; + }; + + QList<Object *> m_objects; + QVector<QPair<QString, QMap<int, IEntry *>>> m_entries; + + void addEntryInternal(IEntry *e, const int entry, const int role) + { + if (m_entries.size() <= entry) + { + m_entries.resize(entry + 1); + } + m_entries[entry].second.insert(role, e); + } + +protected: + template<typename Getter, typename Setter> + typename std::enable_if<std::is_member_function_pointer<Getter>::value && std::is_member_function_pointer<Getter>::value, void>::type + addEntry(const int entry, const int role, Getter getter, Setter setter) + { + addEntryInternal(new FunctionEntry<typename std::result_of<Getter>::type>(getter, setter), entry, role); + } + template<typename T> + typename std::enable_if<std::is_member_function_pointer<typename FunctionEntry<T>::Getter>::value, void>::type + addEntry(const int entry, const int role, typename FunctionEntry<T>::Getter getter) + { + addEntryInternal(new FunctionEntry<T>(getter, nullptr), entry, role); + } + template<typename T> + typename std::enable_if<!std::is_member_function_pointer<T (Object::*)>::value, void>::type + addEntry(const int entry, const int role, T (Object::*member)) + { + addEntryInternal(new VariableEntry<T>(member), entry, role); + } + template<typename T> + void addEntry(const int entry, const int role, typename LambdaEntry<T>::Getter lambda) + { + addEntryInternal(new LambdaEntry<T>(lambda), entry, role); + } + + void setEntryTitle(const int entry, const QString &title) + { + m_entries[entry].first = title; + } + + void setAll(const QList<Object *> objects) + { + notifyBeginReset(); + qDeleteAll(m_objects); + m_objects = objects; + notifyEndReset(); + } +}; diff --git a/api/dead/src/BaseConfigObject.cpp b/api/dead/src/BaseConfigObject.cpp new file mode 100644 index 00000000..3040ac2e --- /dev/null +++ b/api/dead/src/BaseConfigObject.cpp @@ -0,0 +1,103 @@ +/* Copyright 2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BaseConfigObject.h" + +#include <QTimer> +#include <QFile> +#include <QCoreApplication> +#include <QDebug> + +#include "Exception.h" +#include "FileSystem.h" + +BaseConfigObject::BaseConfigObject(const QString &filename) + : m_filename(filename) +{ + m_saveTimer = new QTimer; + m_saveTimer->setSingleShot(true); + // cppcheck-suppress pureVirtualCall + QObject::connect(m_saveTimer, &QTimer::timeout, [this](){saveNow();}); + setSaveTimeout(250); + + m_initialReadTimer = new QTimer; + m_initialReadTimer->setSingleShot(true); + QObject::connect(m_initialReadTimer, &QTimer::timeout, [this]() + { + loadNow(); + m_initialReadTimer->deleteLater(); + m_initialReadTimer = 0; + }); + m_initialReadTimer->start(0); + + // cppcheck-suppress pureVirtualCall + m_appQuitConnection = QObject::connect(qApp, &QCoreApplication::aboutToQuit, [this](){saveNow();}); +} +BaseConfigObject::~BaseConfigObject() +{ + delete m_saveTimer; + if (m_initialReadTimer) + { + delete m_initialReadTimer; + } + QObject::disconnect(m_appQuitConnection); +} + +void BaseConfigObject::setSaveTimeout(int msec) +{ + m_saveTimer->setInterval(msec); +} + +void BaseConfigObject::scheduleSave() +{ + m_saveTimer->stop(); + m_saveTimer->start(); +} +void BaseConfigObject::saveNow() +{ + if (m_saveTimer->isActive()) + { + m_saveTimer->stop(); + } + if (m_disableSaving) + { + return; + } + + try + { + FS::write(m_filename, doSave()); + } + catch (Exception & e) + { + qCritical() << e.cause(); + } +} +void BaseConfigObject::loadNow() +{ + if (m_saveTimer->isActive()) + { + saveNow(); + } + + try + { + doLoad(FS::read(m_filename)); + } + catch (Exception & e) + { + qWarning() << "Error loading" << m_filename << ":" << e.cause(); + } +} diff --git a/api/dead/src/BaseConfigObject.h b/api/dead/src/BaseConfigObject.h new file mode 100644 index 00000000..1c96b3d1 --- /dev/null +++ b/api/dead/src/BaseConfigObject.h @@ -0,0 +1,50 @@ +/* Copyright 2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <QObject> + +class QTimer; + +class BaseConfigObject +{ +public: + void setSaveTimeout(int msec); + +protected: + explicit BaseConfigObject(const QString &filename); + virtual ~BaseConfigObject(); + + // cppcheck-suppress pureVirtualCall + virtual QByteArray doSave() const = 0; + virtual void doLoad(const QByteArray &data) = 0; + + void setSavingDisabled(bool savingDisabled) { m_disableSaving = savingDisabled; } + + QString fileName() const { return m_filename; } + +public: + void scheduleSave(); + void saveNow(); + void loadNow(); + +private: + QTimer *m_saveTimer; + QTimer *m_initialReadTimer; + QString m_filename; + QMetaObject::Connection m_appQuitConnection; + bool m_disableSaving = false; +}; diff --git a/api/dead/src/TypeMagic.h b/api/dead/src/TypeMagic.h new file mode 100644 index 00000000..fa9d12a9 --- /dev/null +++ b/api/dead/src/TypeMagic.h @@ -0,0 +1,37 @@ +#pragma once + +namespace TypeMagic +{ +/** "Cleans" the given type T by stripping references (&) and cv-qualifiers (const, volatile) from it + * const int => int + * QString & => QString + * const unsigned long long & => unsigned long long + * + * Usage: + * using Cleaned = Detail::CleanType<const int>; + * static_assert(std::is_same<Cleaned, int>, "Cleaned == int"); + */ +// the order of remove_cv and remove_reference matters! +template <typename T> +using CleanType = typename std::remove_cv<typename std::remove_reference<T>::type>::type; + +/// For functors (structs with operator()), including lambdas, which in **most** cases are functors +/// "Calls" Function<Ret(*)(Arg)> or Function<Ret(C::*)(Arg)> +template <typename T> struct Function : public Function<decltype(&T::operator())> {}; +/// For function pointers (&function), including static members (&Class::member) +template <typename Ret, typename Arg> struct Function<Ret(*)(Arg)> : public Function<Ret(Arg)> {}; +/// Default specialization used by others. +template <typename Ret, typename Arg> struct Function<Ret(Arg)> +{ + using ReturnType = Ret; + using Argument = Arg; +}; +/// For member functions. Also used by the lambda overload if the lambda captures [this] +template <class C, typename Ret, typename Arg> struct Function<Ret(C::*)(Arg)> : public Function<Ret(Arg)> {}; +template <class C, typename Ret, typename Arg> struct Function<Ret(C::*)(Arg) const> : public Function<Ret(Arg)> {}; +/// Overload for references +template <typename F> struct Function<F&> : public Function<F> {}; +/// Overload for rvalues +template <typename F> struct Function<F&&> : public Function<F> {}; +// for more info: https://functionalcpp.wordpress.com/2013/08/05/function-traits/ +} diff --git a/api/dead/src/handlers/IconResourceHandler.cpp b/api/dead/src/handlers/IconResourceHandler.cpp new file mode 100644 index 00000000..b03553fd --- /dev/null +++ b/api/dead/src/handlers/IconResourceHandler.cpp @@ -0,0 +1,37 @@ +#include "IconResourceHandler.h" +#include <xdgicon.h> + +#include <QDir> +#include <QDebug> + +QList<std::weak_ptr<IconResourceHandler>> IconResourceHandler::m_iconHandlers; + +IconResourceHandler::IconResourceHandler(const QString &key) + : m_key(key) +{ +} + +void IconResourceHandler::setTheme(const QString &theme) +{ + // notify everyone + for (auto handler : m_iconHandlers) + { + std::shared_ptr<IconResourceHandler> ptr = handler.lock(); + if (ptr) + { + ptr->setResult(ptr->get()); + } + } +} + +void IconResourceHandler::init(std::shared_ptr<ResourceHandler> &ptr) +{ + m_iconHandlers.append(std::dynamic_pointer_cast<IconResourceHandler>(ptr)); + // we always have a result, so lets report it now! + setResult(get()); +} + +QVariant IconResourceHandler::get() const +{ + return XdgIcon::fromTheme(m_key); +} diff --git a/api/dead/src/handlers/IconResourceHandler.h b/api/dead/src/handlers/IconResourceHandler.h new file mode 100644 index 00000000..0cc4de4f --- /dev/null +++ b/api/dead/src/handlers/IconResourceHandler.h @@ -0,0 +1,23 @@ +#pragma once + +#include <memory> +#include <resources/ResourceHandler.h> + +class IconResourceHandler : public ResourceHandler +{ +public: + explicit IconResourceHandler(const QString &key); + + /// Sets the current theme and notifies all IconResourceHandlers of the change + static void setTheme(const QString &theme); + +private: + // we need to keep track of all IconResourceHandlers so that we can update them if the theme changes + void init(std::shared_ptr<ResourceHandler> &ptr) override; + static QList<std::weak_ptr<IconResourceHandler>> m_iconHandlers; + + QString m_key; + + // the workhorse, returns QVariantMap (filename => size) for m_key/m_theme + QVariant get() const; +}; diff --git a/api/dead/src/handlers/WebResourceHandler.cpp b/api/dead/src/handlers/WebResourceHandler.cpp new file mode 100644 index 00000000..757b870a --- /dev/null +++ b/api/dead/src/handlers/WebResourceHandler.cpp @@ -0,0 +1,68 @@ +#include "WebResourceHandler.h" + +#include "net/CacheDownload.h" +#include "net/HttpMetaCache.h" +#include "net/NetJob.h" +#include "FileSystem.h" +#include "Env.h" + +//FIXME: wrong. needs to be done elsewhere. +QMap<QString, NetJob *> WebResourceHandler::m_activeDownloads; + +WebResourceHandler::WebResourceHandler(const QString &url) + : QObject(), m_url(url) +{ + MetaEntryPtr entry = ENV.metacache()->resolveEntry("icons", url); + if (!entry->isStale()) + { + setResultFromFile(entry->getFullPath()); + } + else if (m_activeDownloads.contains(url)) + { + NetJob *job = m_activeDownloads.value(url); + connect(job, &NetJob::succeeded, this, &WebResourceHandler::succeeded); + connect(job, &NetJob::failed, this, [job, this]() {setFailure(job->failReason());}); + connect(job, &NetJob::progress, this, &WebResourceHandler::progress); + } + else + { + NetJob *job = new NetJob("Icon download"); + job->addNetAction(CacheDownload::make(QUrl(url), entry)); + connect(job, &NetJob::succeeded, this, &WebResourceHandler::succeeded); + connect(job, &NetJob::failed, this, [job, this]() {setFailure(job->failReason());}); + connect(job, &NetJob::progress, this, &WebResourceHandler::progress); + connect(job, &NetJob::finished, job, [job](){m_activeDownloads.remove(m_activeDownloads.key(job));job->deleteLater();}); + m_activeDownloads.insert(url, job); + job->start(); + } +} + +void WebResourceHandler::succeeded() +{ + MetaEntryPtr entry = ENV.metacache()->resolveEntry("icons", m_url); + setResultFromFile(entry->getFullPath()); + m_activeDownloads.remove(m_activeDownloads.key(qobject_cast<NetJob *>(sender()))); +} +void WebResourceHandler::progress(qint64 current, qint64 total) +{ + if (total == 0) + { + setProgress(101); + } + else + { + setProgress(current / total); + } +} + +void WebResourceHandler::setResultFromFile(const QString &file) +{ + try + { + setResult(FS::read(file)); + } + catch (Exception &e) + { + setFailure(e.cause()); + } +} diff --git a/api/dead/src/handlers/WebResourceHandler.h b/api/dead/src/handlers/WebResourceHandler.h new file mode 100644 index 00000000..54bef6a1 --- /dev/null +++ b/api/dead/src/handlers/WebResourceHandler.h @@ -0,0 +1,23 @@ +#pragma once + +#include <QObject> +#include <resources/ResourceHandler.h> + +class NetJob; + +class WebResourceHandler : public QObject, public ResourceHandler +{ +public: + explicit WebResourceHandler(const QString &url); + +private slots: + void succeeded(); + void progress(qint64 current, qint64 total); + +private: + static QMap<QString, NetJob *> m_activeDownloads; + + QString m_url; + + void setResultFromFile(const QString &file); +}; diff --git a/api/dead/src/resources/Resource.cpp b/api/dead/src/resources/Resource.cpp new file mode 100644 index 00000000..e95675d7 --- /dev/null +++ b/api/dead/src/resources/Resource.cpp @@ -0,0 +1,155 @@ +#include "Resource.h" + +#include <QDebug> + +#include "ResourceObserver.h" +#include "ResourceHandler.h" + |
