mirror of
https://invent.kde.org/graphics/okular
synced 2024-10-30 10:14:34 +00:00
adc01be263
Just to load an icon, we can use `QIcon::fromTheme` for that.
187 lines
6.4 KiB
C++
187 lines
6.4 KiB
C++
/*
|
|
SPDX-FileCopyrightText: 2021 Jiří Wolker <woljiri@gmail.com>
|
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
*/
|
|
|
|
#include "welcomescreen.h"
|
|
|
|
#include <KConfigGroup>
|
|
#include <KIconLoader>
|
|
#include <KSharedConfig>
|
|
|
|
#include <QAction>
|
|
#include <QClipboard>
|
|
#include <QDesktopServices>
|
|
#include <QDir>
|
|
#include <QGraphicsOpacityEffect>
|
|
#include <QGuiApplication>
|
|
#include <QMenu>
|
|
#include <QResizeEvent>
|
|
#include <QStyledItemDelegate>
|
|
|
|
#include "recentitemsmodel.h"
|
|
|
|
class RecentsListItemDelegate : public QStyledItemDelegate
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
explicit RecentsListItemDelegate(WelcomeScreen *welcomeScreen)
|
|
: m_welcomeScreen(welcomeScreen)
|
|
{
|
|
}
|
|
|
|
WelcomeScreen *welcomeScreen() const
|
|
{
|
|
return m_welcomeScreen;
|
|
}
|
|
|
|
bool editorEvent(QEvent *event, QAbstractItemModel *aModel, const QStyleOptionViewItem &styleOptionViewItem, const QModelIndex &index) override
|
|
{
|
|
const RecentItemsModel *model = static_cast<RecentItemsModel *>(aModel);
|
|
const RecentItemsModel::RecentItem *item = model->getItem(index);
|
|
|
|
bool willOpenMenu = false;
|
|
QPoint menuPosition;
|
|
|
|
if (item != nullptr) {
|
|
if (event->type() == QEvent::ContextMenu) {
|
|
willOpenMenu = true;
|
|
menuPosition = static_cast<QContextMenuEvent *>(event)->globalPos();
|
|
}
|
|
if (event->type() == QEvent::MouseButtonPress) {
|
|
if (static_cast<QMouseEvent *>(event)->button() == Qt::MouseButton::RightButton) {
|
|
willOpenMenu = true;
|
|
menuPosition = static_cast<QMouseEvent *>(event)->globalPos();
|
|
}
|
|
}
|
|
|
|
if (willOpenMenu) {
|
|
event->accept();
|
|
|
|
QMenu menu;
|
|
|
|
QAction *copyPathAction = new QAction(i18n("&Copy Path"));
|
|
copyPathAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy")));
|
|
connect(copyPathAction, &QAction::triggered, this, [item]() {
|
|
QString path;
|
|
if (item->url.isLocalFile()) {
|
|
path = item->url.toLocalFile();
|
|
} else {
|
|
path = item->url.toString();
|
|
}
|
|
QGuiApplication::clipboard()->setText(path);
|
|
});
|
|
menu.addAction(copyPathAction);
|
|
|
|
QAction *showDirectoryAction = new QAction(i18n("&Open Containing Folder"));
|
|
showDirectoryAction->setIcon(QIcon::fromTheme(QStringLiteral("document-open-folder")));
|
|
connect(showDirectoryAction, &QAction::triggered, this, [item]() {
|
|
if (item->url.isLocalFile()) {
|
|
QFileInfo fileInfo(item->url.toLocalFile());
|
|
QDir parentDir = fileInfo.dir();
|
|
QUrl parentDirUrl = QUrl::fromLocalFile(parentDir.absolutePath());
|
|
QDesktopServices::openUrl(parentDirUrl);
|
|
}
|
|
});
|
|
menu.addAction(showDirectoryAction);
|
|
if (!item->url.isLocalFile()) {
|
|
showDirectoryAction->setEnabled(false);
|
|
}
|
|
|
|
QAction *forgetItemAction = new QAction(i18nc("recent items context menu", "&Forget This Item"));
|
|
forgetItemAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-clear-history")));
|
|
connect(forgetItemAction, &QAction::triggered, this, [this, item]() { Q_EMIT welcomeScreen()->forgetRecentItem(item->url); });
|
|
menu.addAction(forgetItemAction);
|
|
|
|
menu.exec(menuPosition);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return QStyledItemDelegate::editorEvent(event, aModel, styleOptionViewItem, index);
|
|
}
|
|
|
|
private:
|
|
WelcomeScreen *m_welcomeScreen;
|
|
};
|
|
|
|
WelcomeScreen::WelcomeScreen(QWidget *parent)
|
|
: QWidget(parent)
|
|
, m_recentsModel(new RecentItemsModel)
|
|
, m_recentsItemDelegate(new RecentsListItemDelegate(this))
|
|
{
|
|
Q_ASSERT(parent);
|
|
|
|
setupUi(this);
|
|
|
|
appIcon->setPixmap(QIcon::fromTheme(QStringLiteral("okular")).pixmap(KIconLoader::SizeEnormous));
|
|
|
|
connect(openButton, &QPushButton::clicked, this, &WelcomeScreen::openClicked);
|
|
connect(closeButton, &QPushButton::clicked, this, &WelcomeScreen::closeClicked);
|
|
|
|
recentsListView->setContextMenuPolicy(Qt::DefaultContextMenu);
|
|
recentsListView->setModel(m_recentsModel);
|
|
recentsListView->setItemDelegate(m_recentsItemDelegate);
|
|
connect(recentsListView, &QListView::activated, this, &WelcomeScreen::recentsItemActivated);
|
|
|
|
connect(m_recentsModel, &RecentItemsModel::layoutChanged, this, &WelcomeScreen::recentListChanged);
|
|
|
|
QVBoxLayout *noRecentsLayout = new QVBoxLayout(recentsListView);
|
|
recentsListView->setLayout(noRecentsLayout);
|
|
m_noRecentsLabel = new QLabel(recentsListView);
|
|
QFont placeholderLabelFont;
|
|
// To match the size of a level 2 Heading/KTitleWidget
|
|
placeholderLabelFont.setPointSize(qRound(placeholderLabelFont.pointSize() * 1.3));
|
|
noRecentsLayout->addWidget(m_noRecentsLabel);
|
|
m_noRecentsLabel->setFont(placeholderLabelFont);
|
|
m_noRecentsLabel->setTextInteractionFlags(Qt::NoTextInteraction);
|
|
m_noRecentsLabel->setWordWrap(true);
|
|
m_noRecentsLabel->setAlignment(Qt::AlignCenter);
|
|
m_noRecentsLabel->setText(i18nc("on welcome screen", "No recent documents"));
|
|
// Match opacity of QML placeholder label component
|
|
auto *effect = new QGraphicsOpacityEffect(m_noRecentsLabel);
|
|
effect->setOpacity(0.5);
|
|
m_noRecentsLabel->setGraphicsEffect(effect);
|
|
|
|
connect(forgetAllButton, &QToolButton::clicked, this, &WelcomeScreen::forgetAllRecents);
|
|
}
|
|
|
|
WelcomeScreen::~WelcomeScreen()
|
|
{
|
|
delete m_recentsModel;
|
|
delete m_recentsItemDelegate;
|
|
}
|
|
|
|
void WelcomeScreen::loadRecents()
|
|
{
|
|
m_recentsModel->loadEntries(KSharedConfig::openConfig()->group("Recent Files"));
|
|
}
|
|
|
|
int WelcomeScreen::recentsCount()
|
|
{
|
|
return m_recentsModel->rowCount();
|
|
}
|
|
|
|
void WelcomeScreen::recentsItemActivated(const QModelIndex &index)
|
|
{
|
|
const RecentItemsModel::RecentItem *item = m_recentsModel->getItem(index);
|
|
if (item != nullptr) {
|
|
Q_EMIT recentItemClicked(item->url);
|
|
}
|
|
}
|
|
|
|
void WelcomeScreen::recentListChanged()
|
|
{
|
|
if (recentsCount() == 0) {
|
|
m_noRecentsLabel->show();
|
|
forgetAllButton->setEnabled(false);
|
|
} else {
|
|
m_noRecentsLabel->hide();
|
|
forgetAllButton->setEnabled(true);
|
|
}
|
|
}
|
|
|
|
#include "welcomescreen.moc"
|