/****************************************************************************** * The MIT License (MIT) * * Copyright (c) 2016 Baldur Karlsson * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. ******************************************************************************/ #pragma once #include #include #include #include bool SaveToJSON(QVariantMap &data, QIODevice &f, const char *magicIdentifier, uint32_t magicVersion); bool LoadFromJSON(QVariantMap &data, QIODevice &f, const char *magicIdentifier, uint32_t magicVersion); // implementation of QOverload, to avoid depending on 5.7. // From: http://stackoverflow.com/a/16795664/4070143 template struct OverloadedSlot { template static constexpr auto of(R (C::*pmf)(Args...)) -> decltype(pmf) { return pmf; } }; // Utility class for invoking a lambda on the GUI thread. // This is supported by QTimer::singleShot on Qt 5.4 but it's probably // wise not to require a higher version that necessary. #include class GUIInvoke : public QObject { private: Q_OBJECT GUIInvoke(const std::function &f) : func(f) {} std::function func; public: static void call(const std::function &f); static void blockcall(const std::function &f); protected slots: void doInvoke() { func(); deleteLater(); } }; // Utility class for calling a lambda on a new thread. #include class LambdaThread : public QObject { private: Q_OBJECT std::function m_func; QThread *m_Thread; QSemaphore completed; bool m_SelfDelete = false; public slots: void process() { m_func(); m_Thread->quit(); m_Thread->deleteLater(); m_Thread = NULL; if(m_SelfDelete) deleteLater(); completed.acquire(); } void selfDelete(bool d) { m_SelfDelete = d; } public: explicit LambdaThread(std::function f) { completed.release(); m_Thread = new QThread(); m_func = f; moveToThread(m_Thread); QObject::connect(m_Thread, &QThread::started, this, &LambdaThread::process); } void start(QThread::Priority prio = QThread::InheritPriority) { m_Thread->start(prio); } bool isRunning() { return completed.available(); } bool wait(unsigned long time = ULONG_MAX) { if(m_Thread) return m_Thread->wait(time); return true; } }; class QMenu; // helper for doing a manual blocking invoke of a dialog struct RDDialog { static void show(QMenu *menu, QPoint pos); static int show(QDialog *dialog); static QMessageBox::StandardButton messageBox( QMessageBox::Icon, QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButton defaultButton = QMessageBox::NoButton); static QMessageBox::StandardButton information( QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButton defaultButton = QMessageBox::NoButton) { return messageBox(QMessageBox::Information, parent, title, text, buttons, defaultButton); } static QMessageBox::StandardButton question( QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No), QMessageBox::StandardButton defaultButton = QMessageBox::NoButton) { return messageBox(QMessageBox::Question, parent, title, text, buttons, defaultButton); } static QMessageBox::StandardButton warning( QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButton defaultButton = QMessageBox::NoButton) { return messageBox(QMessageBox::Warning, parent, title, text, buttons, defaultButton); } static QMessageBox::StandardButton critical( QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButton defaultButton = QMessageBox::NoButton) { return messageBox(QMessageBox::Critical, parent, title, text, buttons, defaultButton); } static QString getExistingDirectory(QWidget *parent = NULL, const QString &caption = QString(), const QString &dir = QString(), QFileDialog::Options options = QFileDialog::ShowDirsOnly); static QString getOpenFileName(QWidget *parent = NULL, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = NULL, QFileDialog::Options options = QFileDialog::Options()); static QString getSaveFileName(QWidget *parent = NULL, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = NULL, QFileDialog::Options options = QFileDialog::Options()); }; // useful delegate for enforcing a given size #include class SizeDelegate : public QItemDelegate { private: Q_OBJECT QSize m_Size; public: SizeDelegate(QSize size) : m_Size(size) {} QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { return m_Size; } };