File indexing completed on 2024-04-28 15:52:03
0001 /* 0002 SPDX-FileCopyrightText: 2021 Jiří Wolker <woljiri@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "welcomescreen.h" 0008 0009 #include <KConfigGroup> 0010 #include <KIO/OpenFileManagerWindowJob> 0011 #include <KIconLoader> 0012 #include <KSharedConfig> 0013 0014 #include <QAction> 0015 #include <QClipboard> 0016 #include <QGraphicsOpacityEffect> 0017 #include <QGuiApplication> 0018 #include <QMenu> 0019 #include <QResizeEvent> 0020 #include <QStyledItemDelegate> 0021 0022 #include "recentitemsmodel.h" 0023 0024 class RecentsListItemDelegate : public QStyledItemDelegate 0025 { 0026 Q_OBJECT 0027 0028 public: 0029 explicit RecentsListItemDelegate(WelcomeScreen *welcomeScreen) 0030 : m_welcomeScreen(welcomeScreen) 0031 { 0032 } 0033 0034 WelcomeScreen *welcomeScreen() const 0035 { 0036 return m_welcomeScreen; 0037 } 0038 0039 bool editorEvent(QEvent *event, QAbstractItemModel *aModel, const QStyleOptionViewItem &styleOptionViewItem, const QModelIndex &index) override 0040 { 0041 const RecentItemsModel *model = static_cast<RecentItemsModel *>(aModel); 0042 const RecentItemsModel::RecentItem *item = model->getItem(index); 0043 0044 QPoint menuPosition; 0045 0046 if (item != nullptr) { 0047 bool willOpenMenu = false; 0048 if (event->type() == QEvent::ContextMenu) { 0049 willOpenMenu = true; 0050 menuPosition = static_cast<QContextMenuEvent *>(event)->globalPos(); 0051 } 0052 if (event->type() == QEvent::MouseButtonPress) { 0053 if (static_cast<QMouseEvent *>(event)->button() == Qt::MouseButton::RightButton) { 0054 willOpenMenu = true; 0055 menuPosition = static_cast<QMouseEvent *>(event)->globalPosition().toPoint(); 0056 } 0057 } 0058 0059 if (willOpenMenu) { 0060 event->accept(); 0061 0062 QMenu menu; 0063 0064 QAction *copyPathAction = new QAction(i18n("&Copy Path")); 0065 copyPathAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy"))); 0066 connect(copyPathAction, &QAction::triggered, this, [item]() { 0067 QString path; 0068 if (item->url.isLocalFile()) { 0069 path = item->url.toLocalFile(); 0070 } else { 0071 path = item->url.toString(); 0072 } 0073 QGuiApplication::clipboard()->setText(path); 0074 }); 0075 menu.addAction(copyPathAction); 0076 0077 QAction *showDirectoryAction = new QAction(i18n("&Open Containing Folder")); 0078 showDirectoryAction->setIcon(QIcon::fromTheme(QStringLiteral("document-open-folder"))); 0079 connect(showDirectoryAction, &QAction::triggered, this, [item]() { 0080 if (item->url.isLocalFile()) { 0081 KIO::highlightInFileManager({item->url}); 0082 } 0083 }); 0084 menu.addAction(showDirectoryAction); 0085 if (!item->url.isLocalFile()) { 0086 showDirectoryAction->setEnabled(false); 0087 } 0088 0089 QAction *forgetItemAction = new QAction(i18nc("recent items context menu", "&Forget This Item")); 0090 forgetItemAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-clear-history"))); 0091 connect(forgetItemAction, &QAction::triggered, this, [this, item]() { Q_EMIT welcomeScreen()->forgetRecentItem(item->url); }); 0092 menu.addAction(forgetItemAction); 0093 0094 menu.exec(menuPosition); 0095 0096 return true; 0097 } 0098 } 0099 0100 return QStyledItemDelegate::editorEvent(event, aModel, styleOptionViewItem, index); 0101 } 0102 0103 private: 0104 WelcomeScreen *m_welcomeScreen; 0105 }; 0106 0107 WelcomeScreen::WelcomeScreen(QWidget *parent) 0108 : QWidget(parent) 0109 , m_recentsModel(new RecentItemsModel) 0110 , m_recentsItemDelegate(new RecentsListItemDelegate(this)) 0111 { 0112 Q_ASSERT(parent); 0113 0114 setupUi(this); 0115 0116 connect(openButton, &QPushButton::clicked, this, &WelcomeScreen::openClicked); 0117 connect(closeButton, &QPushButton::clicked, this, &WelcomeScreen::closeClicked); 0118 0119 recentsListView->setContextMenuPolicy(Qt::DefaultContextMenu); 0120 recentsListView->setModel(m_recentsModel); 0121 recentsListView->setItemDelegate(m_recentsItemDelegate); 0122 connect(recentsListView, &QListView::activated, this, &WelcomeScreen::recentsItemActivated); 0123 0124 connect(m_recentsModel, &RecentItemsModel::layoutChanged, this, &WelcomeScreen::recentListChanged); 0125 0126 QVBoxLayout *noRecentsLayout = new QVBoxLayout(recentsListView); 0127 recentsListView->setLayout(noRecentsLayout); 0128 m_noRecentsLabel = new QLabel(recentsListView); 0129 QFont placeholderLabelFont; 0130 // To match the size of a level 2 Heading/KTitleWidget 0131 placeholderLabelFont.setPointSize(qRound(placeholderLabelFont.pointSize() * 1.3)); 0132 noRecentsLayout->addWidget(m_noRecentsLabel); 0133 m_noRecentsLabel->setFont(placeholderLabelFont); 0134 m_noRecentsLabel->setTextInteractionFlags(Qt::NoTextInteraction); 0135 m_noRecentsLabel->setWordWrap(true); 0136 m_noRecentsLabel->setAlignment(Qt::AlignCenter); 0137 m_noRecentsLabel->setText(i18nc("on welcome screen", "No recent documents")); 0138 // Match opacity of QML placeholder label component 0139 auto *effect = new QGraphicsOpacityEffect(m_noRecentsLabel); 0140 effect->setOpacity(0.5); 0141 m_noRecentsLabel->setGraphicsEffect(effect); 0142 0143 connect(forgetAllButton, &QToolButton::clicked, this, &WelcomeScreen::forgetAllRecents); 0144 } 0145 0146 WelcomeScreen::~WelcomeScreen() 0147 { 0148 delete m_recentsModel; 0149 delete m_recentsItemDelegate; 0150 } 0151 0152 void WelcomeScreen::showEvent(QShowEvent *e) 0153 { 0154 if (appIcon->pixmap(Qt::ReturnByValue).isNull()) { 0155 appIcon->setPixmap(QIcon::fromTheme(QStringLiteral("okular")).pixmap(KIconLoader::SizeEnormous)); 0156 } 0157 0158 QWidget::showEvent(e); 0159 } 0160 0161 void WelcomeScreen::loadRecents() 0162 { 0163 m_recentsModel->loadEntries(KSharedConfig::openConfig()->group(QStringLiteral("Recent Files"))); 0164 } 0165 0166 int WelcomeScreen::recentsCount() 0167 { 0168 return m_recentsModel->rowCount(); 0169 } 0170 0171 void WelcomeScreen::recentsItemActivated(const QModelIndex &index) 0172 { 0173 const RecentItemsModel::RecentItem *item = m_recentsModel->getItem(index); 0174 if (item != nullptr) { 0175 Q_EMIT recentItemClicked(item->url); 0176 } 0177 } 0178 0179 void WelcomeScreen::recentListChanged() 0180 { 0181 if (recentsCount() == 0) { 0182 m_noRecentsLabel->show(); 0183 forgetAllButton->setEnabled(false); 0184 } else { 0185 m_noRecentsLabel->hide(); 0186 forgetAllButton->setEnabled(true); 0187 } 0188 } 0189 0190 #include "welcomescreen.moc"