summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2014-06-28 17:09:23 +0200
committerPetr Mrázek <peterix@gmail.com>2014-06-28 17:09:23 +0200
commit56d91fda3a7220c6f8d29289998af43b72e3ad5c (patch)
tree9d60848f3619e52a993acfe2c11f6806f16f2695
parente8731c5d013e67ee0153d5a49b38b0e914d14aa0 (diff)
downloadMultiMC-56d91fda3a7220c6f8d29289998af43b72e3ad5c.tar
MultiMC-56d91fda3a7220c6f8d29289998af43b72e3ad5c.tar.gz
MultiMC-56d91fda3a7220c6f8d29289998af43b72e3ad5c.tar.lz
MultiMC-56d91fda3a7220c6f8d29289998af43b72e3ad5c.tar.xz
MultiMC-56d91fda3a7220c6f8d29289998af43b72e3ad5c.zip
Derp!
-rw-r--r--gui/pages/ScreenshotsPage.cpp249
-rw-r--r--gui/pages/ScreenshotsPage.h68
-rw-r--r--gui/pages/ScreenshotsPage.ui103
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>&amp;Upload</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="deleteBtn">
+ <property name="text">
+ <string>&amp;Delete</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="renameBtn">
+ <property name="text">
+ <string>&amp;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>&amp;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>