You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
187 lines
6.4 KiB
187 lines
6.4 KiB
/* |
|
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"
|
|
|