2022-03-21 00:31:08 +05:30
|
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
/*
|
2022-12-14 20:32:04 +05:30
|
|
|
* Prism Launcher - Minecraft Launcher
|
2022-03-21 00:31:08 +05:30
|
|
|
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
2022-06-12 17:20:58 +05:30
|
|
|
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
|
2022-12-14 20:32:04 +05:30
|
|
|
* Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
|
2022-03-21 00:31:08 +05:30
|
|
|
*
|
|
|
|
* 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, version 3.
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
* This file incorporates work covered by the following copyright and
|
|
|
|
* permission notice:
|
|
|
|
*
|
|
|
|
* Copyright 2013-2021 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.
|
|
|
|
*/
|
|
|
|
|
2014-06-28 20:39:23 +05:30
|
|
|
#include "ScreenshotsPage.h"
|
|
|
|
#include "ui_ScreenshotsPage.h"
|
|
|
|
|
|
|
|
#include <QModelIndex>
|
|
|
|
#include <QMutableListIterator>
|
2014-07-05 16:56:37 +05:30
|
|
|
#include <QMap>
|
|
|
|
#include <QSet>
|
2014-06-28 20:39:23 +05:30
|
|
|
#include <QFileIconProvider>
|
|
|
|
#include <QFileSystemModel>
|
|
|
|
#include <QStyledItemDelegate>
|
|
|
|
#include <QLineEdit>
|
2014-07-13 02:32:52 +05:30
|
|
|
#include <QEvent>
|
|
|
|
#include <QPainter>
|
|
|
|
#include <QClipboard>
|
|
|
|
#include <QKeyEvent>
|
2019-07-17 05:31:29 +05:30
|
|
|
#include <QMenu>
|
2022-05-02 23:18:37 +05:30
|
|
|
#include <QRegularExpression>
|
2014-06-28 20:39:23 +05:30
|
|
|
|
2021-11-20 20:52:22 +05:30
|
|
|
#include <Application.h>
|
2014-06-28 20:39:23 +05:30
|
|
|
|
2021-11-22 08:25:16 +05:30
|
|
|
#include "ui/dialogs/ProgressDialog.h"
|
|
|
|
#include "ui/dialogs/CustomMessageBox.h"
|
|
|
|
|
2015-02-09 06:21:14 +05:30
|
|
|
#include "net/NetJob.h"
|
|
|
|
#include "screenshots/ImgurUpload.h"
|
|
|
|
#include "screenshots/ImgurAlbumCreation.h"
|
|
|
|
#include "tasks/SequentialTask.h"
|
2014-06-28 20:39:23 +05:30
|
|
|
|
2015-02-09 06:21:14 +05:30
|
|
|
#include "RWStorage.h"
|
2015-10-05 05:17:27 +05:30
|
|
|
#include <FileSystem.h>
|
2016-01-05 12:02:52 +05:30
|
|
|
#include <DesktopServices.h>
|
2014-07-13 02:32:52 +05:30
|
|
|
|
2014-07-05 16:56:37 +05:30
|
|
|
typedef RWStorage<QString, QIcon> SharedIconCache;
|
|
|
|
typedef std::shared_ptr<SharedIconCache> SharedIconCachePtr;
|
|
|
|
|
|
|
|
class ThumbnailingResult : public QObject
|
|
|
|
{
|
2018-07-15 18:21:05 +05:30
|
|
|
Q_OBJECT
|
2014-07-13 02:32:52 +05:30
|
|
|
public slots:
|
2018-07-15 18:21:05 +05:30
|
|
|
inline void emitResultsReady(const QString &path) { emit resultsReady(path); }
|
|
|
|
inline void emitResultsFailed(const QString &path) { emit resultsFailed(path); }
|
2014-07-13 02:32:52 +05:30
|
|
|
signals:
|
2018-07-15 18:21:05 +05:30
|
|
|
void resultsReady(const QString &path);
|
|
|
|
void resultsFailed(const QString &path);
|
2014-07-05 16:56:37 +05:30
|
|
|
};
|
|
|
|
|
2014-07-13 02:32:52 +05:30
|
|
|
class ThumbnailRunnable : public QRunnable
|
2014-07-05 16:56:37 +05:30
|
|
|
{
|
|
|
|
public:
|
2018-07-15 18:21:05 +05:30
|
|
|
ThumbnailRunnable(QString path, SharedIconCachePtr cache)
|
|
|
|
{
|
|
|
|
m_path = path;
|
|
|
|
m_cache = cache;
|
|
|
|
}
|
|
|
|
void run()
|
|
|
|
{
|
|
|
|
QFileInfo info(m_path);
|
|
|
|
if (info.isDir())
|
|
|
|
return;
|
|
|
|
if ((info.suffix().compare("png", Qt::CaseInsensitive) != 0))
|
|
|
|
return;
|
|
|
|
int tries = 5;
|
|
|
|
while (tries)
|
|
|
|
{
|
|
|
|
if (!m_cache->stale(m_path))
|
|
|
|
return;
|
|
|
|
QImage image(m_path);
|
|
|
|
if (image.isNull())
|
|
|
|
{
|
|
|
|
QThread::msleep(500);
|
|
|
|
tries--;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
QImage small;
|
|
|
|
if (image.width() > image.height())
|
|
|
|
small = image.scaledToWidth(512).scaledToWidth(256, Qt::SmoothTransformation);
|
|
|
|
else
|
|
|
|
small = image.scaledToHeight(512).scaledToHeight(256, Qt::SmoothTransformation);
|
|
|
|
QPoint offset((256 - small.width()) / 2, (256 - small.height()) / 2);
|
|
|
|
QImage square(QSize(256, 256), QImage::Format_ARGB32);
|
|
|
|
square.fill(Qt::transparent);
|
2014-07-13 02:32:52 +05:30
|
|
|
|
2018-07-15 18:21:05 +05:30
|
|
|
QPainter painter(&square);
|
|
|
|
painter.drawImage(offset, small);
|
|
|
|
painter.end();
|
2014-07-13 02:32:52 +05:30
|
|
|
|
2018-07-15 18:21:05 +05:30
|
|
|
QIcon icon(QPixmap::fromImage(square));
|
|
|
|
m_cache->add(m_path, icon);
|
|
|
|
m_resultEmitter.emitResultsReady(m_path);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
m_resultEmitter.emitResultsFailed(m_path);
|
|
|
|
}
|
|
|
|
QString m_path;
|
|
|
|
SharedIconCachePtr m_cache;
|
|
|
|
ThumbnailingResult m_resultEmitter;
|
2014-07-05 16:56:37 +05:30
|
|
|
};
|
|
|
|
|
2014-07-13 02:32:52 +05:30
|
|
|
// this is about as elegant and well written as a bag of bricks with scribbles done by insane
|
|
|
|
// asylum patients.
|
2014-06-28 20:39:23 +05:30
|
|
|
class FilterModel : public QIdentityProxyModel
|
|
|
|
{
|
2018-07-15 18:21:05 +05:30
|
|
|
Q_OBJECT
|
2014-06-30 05:32:57 +05:30
|
|
|
public:
|
2018-07-15 18:21:05 +05:30
|
|
|
explicit FilterModel(QObject *parent = 0) : QIdentityProxyModel(parent)
|
|
|
|
{
|
|
|
|
m_thumbnailingPool.setMaxThreadCount(4);
|
|
|
|
m_thumbnailCache = std::make_shared<SharedIconCache>();
|
2021-11-20 20:52:22 +05:30
|
|
|
m_thumbnailCache->add("placeholder", APPLICATION->getThemedIcon("screenshot-placeholder"));
|
2018-07-15 18:21:05 +05:30
|
|
|
connect(&watcher, SIGNAL(fileChanged(QString)), SLOT(fileChanged(QString)));
|
|
|
|
// FIXME: the watched file set is not updated when files are removed
|
|
|
|
}
|
|
|
|
virtual ~FilterModel() { m_thumbnailingPool.waitForDone(500); }
|
|
|
|
virtual QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const
|
|
|
|
{
|
|
|
|
auto model = sourceModel();
|
|
|
|
if (!model)
|
|
|
|
return QVariant();
|
|
|
|
if (role == Qt::DisplayRole || role == Qt::EditRole)
|
|
|
|
{
|
|
|
|
QVariant result = sourceModel()->data(mapToSource(proxyIndex), role);
|
2022-05-02 23:18:37 +05:30
|
|
|
return result.toString().remove(QRegularExpression("\\.png$"));
|
2018-07-15 18:21:05 +05:30
|
|
|
}
|
|
|
|
if (role == Qt::DecorationRole)
|
|
|
|
{
|
|
|
|
QVariant result =
|
|
|
|
sourceModel()->data(mapToSource(proxyIndex), QFileSystemModel::FilePathRole);
|
|
|
|
QString filePath = result.toString();
|
|
|
|
QIcon temp;
|
|
|
|
if (!watched.contains(filePath))
|
|
|
|
{
|
|
|
|
((QFileSystemWatcher &)watcher).addPath(filePath);
|
|
|
|
((QSet<QString> &)watched).insert(filePath);
|
|
|
|
}
|
|
|
|
if (m_thumbnailCache->get(filePath, temp))
|
|
|
|
{
|
|
|
|
return temp;
|
|
|
|
}
|
|
|
|
if (!m_failed.contains(filePath))
|
|
|
|
{
|
|
|
|
((FilterModel *)this)->thumbnailImage(filePath);
|
|
|
|
}
|
|
|
|
return (m_thumbnailCache->get("placeholder"));
|
|
|
|
}
|
|
|
|
return sourceModel()->data(mapToSource(proxyIndex), role);
|
|
|
|
}
|
|
|
|
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);
|
|
|
|
}
|
2014-07-13 02:32:52 +05:30
|
|
|
|
2014-06-30 05:32:57 +05:30
|
|
|
private:
|
2018-07-15 18:21:05 +05:30
|
|
|
void thumbnailImage(QString path)
|
|
|
|
{
|
|
|
|
auto runnable = new ThumbnailRunnable(path, m_thumbnailCache);
|
|
|
|
connect(&(runnable->m_resultEmitter), SIGNAL(resultsReady(QString)),
|
|
|
|
SLOT(thumbnailReady(QString)));
|
|
|
|
connect(&(runnable->m_resultEmitter), SIGNAL(resultsFailed(QString)),
|
|
|
|
SLOT(thumbnailFailed(QString)));
|
|
|
|
((QThreadPool &)m_thumbnailingPool).start(runnable);
|
|
|
|
}
|
2014-07-13 02:32:52 +05:30
|
|
|
private slots:
|
2018-07-15 18:21:05 +05:30
|
|
|
void thumbnailReady(QString path) { emit layoutChanged(); }
|
|
|
|
void thumbnailFailed(QString path) { m_failed.insert(path); }
|
|
|
|
void fileChanged(QString filepath)
|
|
|
|
{
|
|
|
|
m_thumbnailCache->setStale(filepath);
|
|
|
|
thumbnailImage(filepath);
|
|
|
|
// reinsert the path...
|
|
|
|
watcher.removePath(filepath);
|
|
|
|
watcher.addPath(filepath);
|
|
|
|
}
|
2014-07-05 16:56:37 +05:30
|
|
|
|
|
|
|
private:
|
2018-07-15 18:21:05 +05:30
|
|
|
SharedIconCachePtr m_thumbnailCache;
|
|
|
|
QThreadPool m_thumbnailingPool;
|
|
|
|
QSet<QString> m_failed;
|
|
|
|
QSet<QString> watched;
|
|
|
|
QFileSystemWatcher watcher;
|
2014-06-28 20:39:23 +05:30
|
|
|
};
|
|
|
|
|
|
|
|
class CenteredEditingDelegate : public QStyledItemDelegate
|
|
|
|
{
|
|
|
|
public:
|
2018-07-15 18:21:05 +05:30
|
|
|
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;
|
|
|
|
}
|
2014-06-28 20:39:23 +05:30
|
|
|
};
|
|
|
|
|
2015-01-28 03:01:07 +05:30
|
|
|
ScreenshotsPage::ScreenshotsPage(QString path, QWidget *parent)
|
2019-07-17 05:31:29 +05:30
|
|
|
: QMainWindow(parent), ui(new Ui::ScreenshotsPage)
|
2014-06-28 20:39:23 +05:30
|
|
|
{
|
2018-07-15 18:21:05 +05:30
|
|
|
m_model.reset(new QFileSystemModel());
|
|
|
|
m_filterModel.reset(new FilterModel());
|
|
|
|
m_filterModel->setSourceModel(m_model.get());
|
2022-05-09 10:24:47 +05:30
|
|
|
m_model->setFilter(QDir::Files);
|
2018-07-15 18:21:05 +05:30
|
|
|
m_model->setReadOnly(false);
|
|
|
|
m_model->setNameFilters({"*.png"});
|
|
|
|
m_model->setNameFilterDisables(false);
|
|
|
|
m_folder = path;
|
|
|
|
m_valid = FS::ensureFolderPathExists(m_folder);
|
2014-06-28 20:39:23 +05:30
|
|
|
|
2018-07-15 18:21:05 +05:30
|
|
|
ui->setupUi(this);
|
2019-07-23 04:18:14 +05:30
|
|
|
ui->toolBar->insertSpacer(ui->actionView_Folder);
|
2019-07-17 05:39:54 +05:30
|
|
|
|
2018-07-15 18:21:05 +05:30
|
|
|
ui->listView->setIconSize(QSize(128, 128));
|
|
|
|
ui->listView->setGridSize(QSize(192, 160));
|
|
|
|
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);
|
2022-05-02 22:40:45 +05:30
|
|
|
ui->listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
2018-07-15 18:21:05 +05:30
|
|
|
ui->listView->setItemDelegate(new CenteredEditingDelegate(this));
|
2019-07-25 04:32:30 +05:30
|
|
|
ui->listView->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
|
connect(ui->listView, &QListView::customContextMenuRequested, this, &ScreenshotsPage::ShowContextMenu);
|
2018-07-15 18:21:05 +05:30
|
|
|
connect(ui->listView, SIGNAL(activated(QModelIndex)), SLOT(onItemActivated(QModelIndex)));
|
2014-06-28 20:39:23 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
bool ScreenshotsPage::eventFilter(QObject *obj, QEvent *evt)
|
|
|
|
{
|
2018-07-15 18:21:05 +05:30
|
|
|
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);
|
2021-12-03 07:32:58 +05:30
|
|
|
|
|
|
|
if (keyEvent->matches(QKeySequence::Copy)) {
|
2021-12-03 20:38:11 +05:30
|
|
|
on_actionCopy_File_s_triggered();
|
2021-12-03 07:32:58 +05:30
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-07-15 18:21:05 +05:30
|
|
|
switch (keyEvent->key())
|
|
|
|
{
|
|
|
|
case Qt::Key_Delete:
|
2019-07-17 05:31:29 +05:30
|
|
|
on_actionDelete_triggered();
|
2018-07-15 18:21:05 +05:30
|
|
|
return true;
|
|
|
|
case Qt::Key_F2:
|
2019-07-17 05:31:29 +05:30
|
|
|
on_actionRename_triggered();
|
2018-07-15 18:21:05 +05:30
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return QWidget::eventFilter(obj, evt);
|
2014-06-28 20:39:23 +05:30
|
|
|
}
|
|
|
|
|
2022-02-22 23:53:53 +05:30
|
|
|
void ScreenshotsPage::retranslate()
|
|
|
|
{
|
|
|
|
ui->retranslateUi(this);
|
|
|
|
}
|
|
|
|
|
2014-06-28 20:39:23 +05:30
|
|
|
ScreenshotsPage::~ScreenshotsPage()
|
|
|
|
{
|
2018-07-15 18:21:05 +05:30
|
|
|
delete ui;
|
2014-06-28 20:39:23 +05:30
|
|
|
}
|
|
|
|
|
2019-07-25 04:32:30 +05:30
|
|
|
void ScreenshotsPage::ShowContextMenu(const QPoint& pos)
|
|
|
|
{
|
|
|
|
auto menu = ui->toolBar->createContextMenu(this, tr("Context menu"));
|
2021-12-03 20:59:28 +05:30
|
|
|
|
|
|
|
if (ui->listView->selectionModel()->selectedRows().size() > 1) {
|
|
|
|
menu->removeAction( ui->actionCopy_Image );
|
|
|
|
}
|
|
|
|
|
2019-07-25 04:32:30 +05:30
|
|
|
menu->exec(ui->listView->mapToGlobal(pos));
|
|
|
|
delete menu;
|
|
|
|
}
|
|
|
|
|
2019-07-17 05:31:29 +05:30
|
|
|
QMenu * ScreenshotsPage::createPopupMenu()
|
|
|
|
{
|
|
|
|
QMenu* filteredMenu = QMainWindow::createPopupMenu();
|
|
|
|
filteredMenu->removeAction( ui->toolBar->toggleViewAction() );
|
|
|
|
return filteredMenu;
|
|
|
|
}
|
|
|
|
|
2014-06-28 20:39:23 +05:30
|
|
|
void ScreenshotsPage::onItemActivated(QModelIndex index)
|
|
|
|
{
|
2018-07-15 18:21:05 +05:30
|
|
|
if (!index.isValid())
|
|
|
|
return;
|
|
|
|
auto info = m_model->fileInfo(index);
|
|
|
|
QString fileName = info.absoluteFilePath();
|
|
|
|
DesktopServices::openFile(info.absoluteFilePath());
|
2014-06-28 20:39:23 +05:30
|
|
|
}
|
|
|
|
|
2022-05-09 10:24:47 +05:30
|
|
|
void ScreenshotsPage::onCurrentSelectionChanged(const QItemSelection &selected)
|
|
|
|
{
|
|
|
|
bool allReadable = !selected.isEmpty();
|
|
|
|
bool allWritable = !selected.isEmpty();
|
|
|
|
|
|
|
|
for (auto index : selected.indexes())
|
|
|
|
{
|
|
|
|
if (!index.isValid())
|
|
|
|
break;
|
|
|
|
auto info = m_model->fileInfo(index);
|
|
|
|
if (!info.isReadable())
|
|
|
|
allReadable = false;
|
|
|
|
if (!info.isWritable())
|
|
|
|
allWritable = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
ui->actionUpload->setEnabled(allReadable);
|
|
|
|
ui->actionCopy_Image->setEnabled(allReadable);
|
|
|
|
ui->actionCopy_File_s->setEnabled(allReadable);
|
|
|
|
ui->actionDelete->setEnabled(allWritable);
|
|
|
|
ui->actionRename->setEnabled(allWritable);
|
|
|
|
}
|
|
|
|
|
2019-07-17 05:31:29 +05:30
|
|
|
void ScreenshotsPage::on_actionView_Folder_triggered()
|
2014-06-28 20:39:23 +05:30
|
|
|
{
|
2018-07-15 18:21:05 +05:30
|
|
|
DesktopServices::openDirectory(m_folder, true);
|
2014-06-28 20:39:23 +05:30
|
|
|
}
|
|
|
|
|
2019-07-17 05:31:29 +05:30
|
|
|
void ScreenshotsPage::on_actionUpload_triggered()
|
2014-06-28 20:39:23 +05:30
|
|
|
{
|
2018-07-15 18:21:05 +05:30
|
|
|
auto selection = ui->listView->selectionModel()->selectedRows();
|
|
|
|
if (selection.isEmpty())
|
|
|
|
return;
|
2014-06-28 20:39:23 +05:30
|
|
|
|
2022-12-14 20:32:04 +05:30
|
|
|
|
|
|
|
QString text;
|
|
|
|
if (selection.size() > 1)
|
|
|
|
text = tr("About to upload: %1 screenshots\n\n"
|
|
|
|
"Are you sure?")
|
|
|
|
.arg(selection.size());
|
|
|
|
else
|
|
|
|
text =
|
|
|
|
tr("About to upload the selected screenshot.\n\n"
|
|
|
|
"Are you sure?");
|
|
|
|
|
|
|
|
auto response = CustomMessageBox::selectable(this, "Confirm Upload", text, QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No,
|
|
|
|
QMessageBox::No)
|
|
|
|
->exec();
|
|
|
|
|
|
|
|
if (response != QMessageBox::Yes)
|
|
|
|
return;
|
|
|
|
|
2021-11-22 03:51:12 +05:30
|
|
|
QList<ScreenShot::Ptr> uploaded;
|
2021-12-31 09:57:59 +05:30
|
|
|
auto job = NetJob::Ptr(new NetJob("Screenshot Upload", APPLICATION->network()));
|
2019-06-18 18:11:07 +05:30
|
|
|
if(selection.size() < 2)
|
|
|
|
{
|
|
|
|
auto item = selection.at(0);
|
|
|
|
auto info = m_model->fileInfo(item);
|
|
|
|
auto screenshot = std::make_shared<ScreenShot>(info);
|
|
|
|
job->addNetAction(ImgurUpload::make(screenshot));
|
|
|
|
|
|
|
|
m_uploadActive = true;
|
|
|
|
ProgressDialog dialog(this);
|
2021-12-29 21:38:15 +05:30
|
|
|
|
2019-06-18 18:11:07 +05:30
|
|
|
if(dialog.execWithTask(job.get()) != QDialog::Accepted)
|
|
|
|
{
|
|
|
|
CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"),
|
|
|
|
tr("Unknown error"), QMessageBox::Warning)->exec();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
auto link = screenshot->m_url;
|
|
|
|
QClipboard *clipboard = QApplication::clipboard();
|
|
|
|
clipboard->setText(link);
|
|
|
|
CustomMessageBox::selectable(
|
|
|
|
this,
|
|
|
|
tr("Upload finished"),
|
|
|
|
tr("The <a href=\"%1\">link to the uploaded screenshot</a> has been placed in your clipboard.")
|
|
|
|
.arg(link),
|
|
|
|
QMessageBox::Information
|
|
|
|
)->exec();
|
|
|
|
}
|
|
|
|
|
|
|
|
m_uploadActive = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-07-15 18:21:05 +05:30
|
|
|
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;
|
2021-12-31 09:57:59 +05:30
|
|
|
auto albumTask = NetJob::Ptr(new NetJob("Imgur Album Creation", APPLICATION->network()));
|
2018-07-15 18:21:05 +05:30
|
|
|
auto imgurAlbum = ImgurAlbumCreation::make(uploaded);
|
|
|
|
albumTask->addNetAction(imgurAlbum);
|
2021-11-20 21:38:34 +05:30
|
|
|
task.addTask(job);
|
|
|
|
task.addTask(albumTask);
|
2018-07-15 18:21:05 +05:30
|
|
|
m_uploadActive = true;
|
|
|
|
ProgressDialog prog(this);
|
|
|
|
if (prog.execWithTask(&task) != QDialog::Accepted)
|
|
|
|
{
|
2021-12-31 09:57:59 +05:30
|
|
|
CustomMessageBox::selectable(
|
|
|
|
this,
|
|
|
|
tr("Failed to upload screenshots!"),
|
|
|
|
tr("Unknown error"),
|
|
|
|
QMessageBox::Warning
|
|
|
|
)->exec();
|
2018-07-15 18:21:05 +05:30
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
auto link = QString("https://imgur.com/a/%1").arg(imgurAlbum->id());
|
|
|
|
QClipboard *clipboard = QApplication::clipboard();
|
|
|
|
clipboard->setText(link);
|
|
|
|
CustomMessageBox::selectable(
|
|
|
|
this,
|
|
|
|
tr("Upload finished"),
|
|
|
|
tr("The <a href=\"%1\">link to the uploaded album</a> has been placed in your clipboard.") .arg(link),
|
|
|
|
QMessageBox::Information
|
|
|
|
)->exec();
|
|
|
|
}
|
|
|
|
m_uploadActive = false;
|
2014-06-28 20:39:23 +05:30
|
|
|
}
|
|
|
|
|
2021-12-03 20:38:11 +05:30
|
|
|
void ScreenshotsPage::on_actionCopy_Image_triggered()
|
2021-12-03 07:32:58 +05:30
|
|
|
{
|
|
|
|
auto selection = ui->listView->selectionModel()->selectedRows();
|
|
|
|
if(selection.size() < 1)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// You can only copy one image to the clipboard. In the case of multiple selected files, only the first one gets copied.
|
|
|
|
auto item = selection[0];
|
|
|
|
auto info = m_model->fileInfo(item);
|
|
|
|
QImage image(info.absoluteFilePath());
|
|
|
|
Q_ASSERT(!image.isNull());
|
|
|
|
QApplication::clipboard()->setImage(image, QClipboard::Clipboard);
|
|
|
|
}
|
|
|
|
|
2021-12-03 20:38:11 +05:30
|
|
|
void ScreenshotsPage::on_actionCopy_File_s_triggered()
|
|
|
|
{
|
|
|
|
auto selection = ui->listView->selectionModel()->selectedRows();
|
|
|
|
if(selection.size() < 1)
|
|
|
|
{
|
|
|
|
// Don't do anything so we don't empty the users clipboard
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString buf = "";
|
|
|
|
for (auto item : selection)
|
|
|
|
{
|
|
|
|
auto info = m_model->fileInfo(item);
|
|
|
|
buf += "file:///" + info.absoluteFilePath() + "\r\n";
|
|
|
|
}
|
|
|
|
QMimeData* mimeData = new QMimeData();
|
|
|
|
mimeData->setData("text/uri-list", buf.toLocal8Bit());
|
|
|
|
QApplication::clipboard()->setMimeData(mimeData);
|
|
|
|
}
|
|
|
|
|
2019-07-17 05:31:29 +05:30
|
|
|
void ScreenshotsPage::on_actionDelete_triggered()
|
2014-06-28 20:39:23 +05:30
|
|
|
{
|
2022-12-14 20:32:04 +05:30
|
|
|
auto selected = ui->listView->selectionModel()->selectedIndexes();
|
|
|
|
|
|
|
|
int count = ui->listView->selectionModel()->selectedRows().size();
|
|
|
|
QString text;
|
|
|
|
if (count > 1)
|
|
|
|
text = tr("About to delete: %1 screenshots\n"
|
|
|
|
"This may be permanent and they will be gone from the folder.\n\n"
|
|
|
|
"Are you sure?")
|
|
|
|
.arg(count);
|
|
|
|
else
|
|
|
|
text = tr("About to delete the selected screenshot.\n"
|
|
|
|
"This may be permanent and it will be gone from the folder.\n\n"
|
|
|
|
"Are you sure?")
|
|
|
|
.arg(count);
|
2014-06-28 20:39:23 +05:30
|
|
|
|
2022-12-14 20:32:04 +05:30
|
|
|
auto response =
|
2022-12-17 14:56:06 +05:30
|
|
|
CustomMessageBox::selectable(this, tr("Confirm Deletion"), text, QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No)->exec();
|
2022-12-14 20:32:04 +05:30
|
|
|
|
|
|
|
if (response != QMessageBox::Yes)
|
2018-07-15 18:21:05 +05:30
|
|
|
return;
|
2014-06-28 20:39:23 +05:30
|
|
|
|
2018-07-15 18:21:05 +05:30
|
|
|
for (auto item : selected)
|
|
|
|
{
|
2022-12-14 20:32:04 +05:30
|
|
|
if (FS::trash(m_model->filePath(item)))
|
|
|
|
continue;
|
|
|
|
|
2018-07-15 18:21:05 +05:30
|
|
|
m_model->remove(item);
|
|
|
|
}
|
2014-06-28 20:39:23 +05:30
|
|
|
}
|
|
|
|
|
2019-07-17 05:31:29 +05:30
|
|
|
void ScreenshotsPage::on_actionRename_triggered()
|
2014-06-28 20:39:23 +05:30
|
|
|
{
|
2018-07-15 18:21:05 +05:30
|
|
|
auto selection = ui->listView->selectionModel()->selectedIndexes();
|
|
|
|
if (selection.isEmpty())
|
|
|
|
return;
|
|
|
|
ui->listView->edit(selection[0]);
|
|
|
|
// TODO: mass renaming
|
2014-06-28 20:39:23 +05:30
|
|
|
}
|
|
|
|
|
2018-03-19 07:06:12 +05:30
|
|
|
void ScreenshotsPage::openedImpl()
|
2014-06-28 20:39:23 +05:30
|
|
|
{
|
2018-07-15 18:21:05 +05:30
|
|
|
if(!m_valid)
|
|
|
|
{
|
|
|
|
m_valid = FS::ensureFolderPathExists(m_folder);
|
|
|
|
}
|
|
|
|
if (m_valid)
|
|
|
|
{
|
|
|
|
QString path = QDir(m_folder).absolutePath();
|
|
|
|
auto idx = m_model->setRootPath(path);
|
|
|
|
if(idx.isValid())
|
|
|
|
{
|
|
|
|
ui->listView->setModel(m_filterModel.get());
|
2022-05-09 10:24:47 +05:30
|
|
|
connect(ui->listView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ScreenshotsPage::onCurrentSelectionChanged);
|
|
|
|
onCurrentSelectionChanged(ui->listView->selectionModel()->selection()); // set initial button enable states
|
2018-07-15 18:21:05 +05:30
|
|
|
ui->listView->setRootIndex(m_filterModel->mapFromSource(idx));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ui->listView->setModel(nullptr);
|
|
|
|
}
|
|
|
|
}
|
2022-11-20 01:42:31 +05:30
|
|
|
|
|
|
|
auto const setting_name = QString("WideBarVisibility_%1").arg(id());
|
|
|
|
if (!APPLICATION->settings()->contains(setting_name))
|
|
|
|
m_wide_bar_setting = APPLICATION->settings()->registerSetting(setting_name);
|
|
|
|
else
|
|
|
|
m_wide_bar_setting = APPLICATION->settings()->getSetting(setting_name);
|
|
|
|
|
|
|
|
ui->toolBar->setVisibilityState(m_wide_bar_setting->get().toByteArray());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScreenshotsPage::closedImpl()
|
|
|
|
{
|
|
|
|
m_wide_bar_setting->set(ui->toolBar->getVisibilityState());
|
2014-06-28 20:39:23 +05:30
|
|
|
}
|
2014-07-05 16:56:37 +05:30
|
|
|
|
|
|
|
#include "ScreenshotsPage.moc"
|