diff options
author | Petr Mrázek <peterix@gmail.com> | 2014-06-28 17:09:23 +0200 |
---|---|---|
committer | Petr Mrázek <peterix@gmail.com> | 2014-06-28 17:09:23 +0200 |
commit | 56d91fda3a7220c6f8d29289998af43b72e3ad5c (patch) | |
tree | 9d60848f3619e52a993acfe2c11f6806f16f2695 | |
parent | e8731c5d013e67ee0153d5a49b38b0e914d14aa0 (diff) | |
download | MultiMC-56d91fda3a7220c6f8d29289998af43b72e3ad5c.tar MultiMC-56d91fda3a7220c6f8d29289998af43b72e3ad5c.tar.gz MultiMC-56d91fda3a7220c6f8d29289998af43b72e3ad5c.tar.lz MultiMC-56d91fda3a7220c6f8d29289998af43b72e3ad5c.tar.xz MultiMC-56d91fda3a7220c6f8d29289998af43b72e3ad5c.zip |
Derp!
-rw-r--r-- | gui/pages/ScreenshotsPage.cpp | 249 | ||||
-rw-r--r-- | gui/pages/ScreenshotsPage.h | 68 | ||||
-rw-r--r-- | gui/pages/ScreenshotsPage.ui | 103 |
3 files changed, 420 insertions, 0 deletions
diff --git a/gui/pages/ScreenshotsPage.cpp b/gui/pages/ScreenshotsPage.cpp new file mode 100644 index 00000000..6c3ca7e3 --- /dev/null +++ b/gui/pages/ScreenshotsPage.cpp @@ -0,0 +1,249 @@ +#include "ScreenshotsPage.h" +#include "ui_ScreenshotsPage.h" + +#include <QModelIndex> +#include <QMutableListIterator> +#include <QFileIconProvider> +#include <QFileSystemModel> +#include <QStyledItemDelegate> +#include <QLineEdit> +#include <QtGui/qevent.h> + +#include <pathutils.h> + +#include "gui/dialogs/ProgressDialog.h" +#include "gui/dialogs/CustomMessageBox.h" +#include "logic/screenshots/ScreenshotList.h" +#include "logic/net/NetJob.h" +#include "logic/screenshots/ImgurUpload.h" +#include "logic/screenshots/ImgurAlbumCreation.h" +#include "logic/tasks/SequentialTask.h" + +class ThumbnailProvider : public QFileIconProvider +{ +public: + virtual ~ThumbnailProvider() {}; + virtual QIcon icon(const QFileInfo &info) const + { + QImage image(info.absoluteFilePath()); + if (image.isNull()) + { + return QFileIconProvider::icon(info); + } + QImage thumbnail = image.scaledToWidth(256, Qt::SmoothTransformation); + return QIcon(QPixmap::fromImage(thumbnail)); + } +}; + +class FilterModel : public QIdentityProxyModel +{ + virtual QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const + { + auto model = sourceModel(); + if(!model) + return QVariant(); + QVariant result = sourceModel()->data(mapToSource(proxyIndex), role); + if(role == Qt::DisplayRole || role == Qt::EditRole) + { + return result.toString().remove(QRegExp("\.png$")); + } + return result; + } + virtual bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole) + { + auto model = sourceModel(); + if(!model) + return false; + if(role != Qt::EditRole) + return false; + // FIXME: this is a workaround for a bug in QFileSystemModel, where it doesn't + // sort after renames + { + ((QFileSystemModel *)model)->setNameFilterDisables(true); + ((QFileSystemModel *)model)->setNameFilterDisables(false); + } + return model->setData(mapToSource(index), value.toString() + ".png", role); + } +}; + +class CenteredEditingDelegate : public QStyledItemDelegate +{ +public: + explicit CenteredEditingDelegate(QObject *parent = 0) + : QStyledItemDelegate(parent) + { + } + virtual ~CenteredEditingDelegate() {} + virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const + { + auto widget = QStyledItemDelegate::createEditor(parent, option, index); + auto foo = dynamic_cast<QLineEdit *> (widget); + if(foo) + { + foo->setAlignment(Qt::AlignHCenter); + foo->setFrame(true); + foo->setMaximumWidth(192); + } + return widget; + } +}; + +QString ScreenshotsPage::displayName() +{ + return tr("Screenshots"); +} + +QIcon ScreenshotsPage::icon() +{ + return QIcon::fromTheme("screenshots"); +} + +QString ScreenshotsPage::id() +{ + return "screenshots"; +} + +ScreenshotsPage::ScreenshotsPage(BaseInstance *instance, QWidget *parent) + : QWidget(parent), ui(new Ui::ScreenshotsPage) +{ + m_model.reset(new QFileSystemModel()); + m_filterModel.reset(new FilterModel()); + m_filterModel->setSourceModel(m_model.get()); + m_model->setFilter(QDir::Files | QDir::Writable | QDir::Readable); + m_model->setIconProvider(new ThumbnailProvider); + m_model->setReadOnly(false); + m_folder = PathCombine(instance->minecraftRoot(), "screenshots"); + m_valid = ensureFolderPathExists(m_folder); + + ui->setupUi(this); + ui->listView->setModel(m_filterModel.get()); + ui->listView->setIconSize(QSize(128, 128)); + ui->listView->setGridSize(QSize(192, 128)); + ui->listView->setSpacing(9); + // ui->listView->setUniformItemSizes(true); + ui->listView->setLayoutMode(QListView::Batched); + ui->listView->setViewMode(QListView::IconMode); + ui->listView->setResizeMode(QListView::Adjust); + ui->listView->installEventFilter(this); + ui->listView->setEditTriggers(0); + ui->listView->setItemDelegate(new CenteredEditingDelegate(this)); + connect(ui->listView, SIGNAL(activated(QModelIndex)), SLOT(onItemActivated(QModelIndex))); +} + +bool ScreenshotsPage::eventFilter(QObject *obj, QEvent *evt) +{ + if (obj != ui->listView) + return QWidget::eventFilter(obj, evt); + if (evt->type() != QEvent::KeyPress) + { + return QWidget::eventFilter(obj, evt); + } + QKeyEvent *keyEvent = static_cast<QKeyEvent *>(evt); + switch (keyEvent->key()) + { + case Qt::Key_Delete: + on_deleteBtn_clicked(); + return true; + case Qt::Key_F2: + on_renameBtn_clicked(); + return true; + default: + break; + } + return QWidget::eventFilter(obj, evt); +} + +ScreenshotsPage::~ScreenshotsPage() +{ + delete ui; +} + +void ScreenshotsPage::onItemActivated(QModelIndex index) +{ + if (!index.isValid()) + return; + auto info = m_model->fileInfo(index); + QString fileName = info.absoluteFilePath(); + openFileInDefaultProgram(info.absoluteFilePath()); +} + +void ScreenshotsPage::on_viewFolderBtn_clicked() +{ + openDirInDefaultProgram(m_folder, true); +} + +void ScreenshotsPage::on_uploadBtn_clicked() +{ + auto selection = ui->listView->selectionModel()->selectedIndexes(); + if (selection.isEmpty()) + return; + + QList<ScreenshotPtr> uploaded; + auto job = std::make_shared<NetJob>("Screenshot Upload"); + for (auto item : selection) + { + auto info = m_model->fileInfo(item); + auto screenshot = std::make_shared<ScreenShot>(info); + uploaded.push_back(screenshot); + job->addNetAction(ImgurUpload::make(screenshot)); + } + SequentialTask task; + auto albumTask = std::make_shared<NetJob>("Imgur Album Creation"); + auto imgurAlbum = ImgurAlbumCreation::make(uploaded); + albumTask->addNetAction(imgurAlbum); + task.addTask(job); + task.addTask(albumTask); + ProgressDialog prog(this); + if (prog.exec(&task) != QDialog::Accepted) + { + CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"), + tr("Unknown error"), QMessageBox::Warning)->exec(); + } + else + { + CustomMessageBox::selectable( + this, tr("Upload finished"), + tr("<a href=\"https://imgur.com/a/%1\">Visit album</a><br/>Delete hash: %2 (save " + "this if you want to be able to edit/delete the album)") + .arg(imgurAlbum->id(), imgurAlbum->deleteHash()), + QMessageBox::Information)->exec(); + } +} + +void ScreenshotsPage::on_deleteBtn_clicked() +{ + auto mbox = CustomMessageBox::selectable( + this, tr("Are you sure?"), tr("This will delete all selected screenshots."), + QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No); + std::unique_ptr<QMessageBox> box(mbox); + + if(box->exec() != QMessageBox::Yes) + return; + + auto selected = ui->listView->selectionModel()->selectedIndexes(); + for(auto item : selected) + { + m_model->remove(item); + } +} + +void ScreenshotsPage::on_renameBtn_clicked() +{ + auto selection = ui->listView->selectionModel()->selectedIndexes(); + if (selection.isEmpty()) + return; + ui->listView->edit(selection[0]); + // TODO: mass renaming +} + +void ScreenshotsPage::opened() +{ + if (m_valid) + { + QString path = QDir(m_folder).absolutePath(); + m_model->setRootPath(path); + ui->listView->setRootIndex(m_filterModel->mapFromSource(m_model->index(path))); + } +} diff --git a/gui/pages/ScreenshotsPage.h b/gui/pages/ScreenshotsPage.h new file mode 100644 index 00000000..4098e5e4 --- /dev/null +++ b/gui/pages/ScreenshotsPage.h @@ -0,0 +1,68 @@ +/* Copyright 2014 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 <QWidget> +#include <logic/OneSixInstance.h> +#include "BasePage.h" +#include <QIcon> +#include <QEvent> + +class QFileSystemModel; +class QIdentityProxyModel; +namespace Ui +{ +class ScreenshotsPage; +} + +class ScreenShot; +class ScreenshotList; +class ImgurAlbumCreation; + +class ScreenshotsPage : public QWidget, public BasePage +{ + Q_OBJECT + +public: + explicit ScreenshotsPage(BaseInstance *instance, QWidget *parent = 0); + virtual ~ScreenshotsPage(); + + virtual void opened() override; + + enum + { + NothingDone = 0x42 + }; + + virtual bool eventFilter(QObject *, QEvent *); + virtual QString displayName() override; + virtual QIcon icon() override; + virtual QString id() override; + virtual QString helpPage() override { return "Screenshots-management"; }; +private +slots: + void on_uploadBtn_clicked(); + void on_deleteBtn_clicked(); + void on_renameBtn_clicked(); + void on_viewFolderBtn_clicked(); + void onItemActivated(QModelIndex); + +private: + Ui::ScreenshotsPage *ui; + std::shared_ptr<QFileSystemModel> m_model; + std::shared_ptr<QIdentityProxyModel> m_filterModel; + QString m_folder; + bool m_valid = false; +}; diff --git a/gui/pages/ScreenshotsPage.ui b/gui/pages/ScreenshotsPage.ui new file mode 100644 index 00000000..5951ab02 --- /dev/null +++ b/gui/pages/ScreenshotsPage.ui @@ -0,0 +1,103 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ScreenshotsPage</class> + <widget class="QWidget" name="ScreenshotsPage"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>723</width> + <height>532</height> + </rect> + </property> + <property name="windowTitle"> + <string>Mods</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <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> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QListView" name="listView"> + <property name="selectionMode"> + <enum>QAbstractItemView::ExtendedSelection</enum> + </property> + <property name="selectionBehavior"> + <enum>QAbstractItemView::SelectItems</enum> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QPushButton" name="uploadBtn"> + <property name="text"> + <string>&Upload</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="deleteBtn"> + <property name="text"> + <string>&Delete</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="renameBtn"> + <property name="text"> + <string>&Rename</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="viewFolderBtn"> + <property name="text"> + <string>&View Folder</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + </layout> + </widget> + <tabstops> + <tabstop>listView</tabstop> + <tabstop>uploadBtn</tabstop> + <tabstop>deleteBtn</tabstop> + <tabstop>renameBtn</tabstop> + <tabstop>viewFolderBtn</tabstop> + </tabstops> + <resources/> + <connections/> +</ui> |