File indexing completed on 2024-10-06 04:35:35

0001 /*
0002  *  Bookmark dialog
0003  *
0004  *  SPDX-FileCopyrightText: 2023 Alexander Reinholdt <alexander.reinholdt@kdemail.net>
0005  *  SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 
0008 // application specific includes
0009 #include "smb4kbookmarkdialog.h"
0010 #include "core/smb4kbookmark.h"
0011 #include "core/smb4kbookmarkhandler.h"
0012 #include "core/smb4ksettings.h"
0013 #include "smb4khomesuserdialog.h"
0014 
0015 // Qt includes
0016 #include <QDialogButtonBox>
0017 #include <QGridLayout>
0018 #include <QLabel>
0019 #include <QMouseEvent>
0020 #include <QVBoxLayout>
0021 #include <QWindow>
0022 
0023 // KDE includes
0024 #include <KConfigGroup>
0025 #include <KIconLoader>
0026 #include <KLocalizedString>
0027 #include <KWindowConfig>
0028 
0029 Smb4KBookmarkDialog::Smb4KBookmarkDialog(QWidget *parent)
0030     : QDialog(parent)
0031 {
0032     setWindowTitle(i18n("Bookmark Shares"));
0033     setAttribute(Qt::WA_DeleteOnClose);
0034 
0035     QVBoxLayout *layout = new QVBoxLayout(this);
0036 
0037     QWidget *descriptionWidget = new QWidget(this);
0038     QHBoxLayout *descriptionWidgetLayout = new QHBoxLayout(descriptionWidget);
0039     descriptionWidgetLayout->setContentsMargins(0, 0, 0, 0);
0040 
0041     QLabel *descriptionPixmap = new QLabel(descriptionWidget);
0042     descriptionPixmap->setPixmap(KDE::icon(QStringLiteral("bookmark-new")).pixmap(KIconLoader::SizeHuge));
0043     descriptionPixmap->setAlignment(Qt::AlignBottom);
0044     descriptionPixmap->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
0045 
0046     descriptionWidgetLayout->addWidget(descriptionPixmap);
0047 
0048     QLabel *descriptionText = new QLabel(this);
0049     descriptionText->setText(i18n("All listed shares will be bookmarked. To add a label or category, double-click the respective bookmark entry."));
0050     descriptionText->setWordWrap(true);
0051     descriptionText->setAlignment(Qt::AlignBottom);
0052     descriptionText->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
0053 
0054     descriptionWidgetLayout->addWidget(descriptionText);
0055 
0056     layout->addWidget(descriptionWidget);
0057     layout->addSpacing(layout->spacing());
0058 
0059     m_listWidget = new QListWidget(this);
0060     m_listWidget->setSelectionMode(QListWidget::SingleSelection);
0061     m_listWidget->viewport()->installEventFilter(this);
0062 
0063     connect(m_listWidget, &QListWidget::itemDoubleClicked, this, &Smb4KBookmarkDialog::slotItemDoubleClicked);
0064     connect(m_listWidget, &QListWidget::itemSelectionChanged, this, &Smb4KBookmarkDialog::slotItemSelectionChanged);
0065 
0066     layout->addWidget(m_listWidget);
0067 
0068     m_editorWidget = new QWidget(this);
0069     m_editorWidget->setVisible(false);
0070 
0071     QGridLayout *editorWidgetLayout = new QGridLayout(m_editorWidget);
0072     editorWidgetLayout->setContentsMargins(0, 0, 0, 0);
0073 
0074     QLabel *labelLabel = new QLabel(i18n("Label:"), m_editorWidget);
0075     m_labelEdit = new KLineEdit(m_editorWidget);
0076     m_labelEdit->setClearButtonEnabled(true);
0077     m_labelEdit->setCompletionMode(KCompletion::CompletionPopupAuto);
0078 
0079     connect(m_labelEdit, &KLineEdit::editingFinished, this, &Smb4KBookmarkDialog::slotLabelEdited);
0080 
0081     QLabel *categoryLabel = new QLabel(i18n("Category:"), m_editorWidget);
0082     m_categoryEdit = new KComboBox(m_editorWidget);
0083     m_categoryEdit->setEditable(true);
0084     m_categoryEdit->lineEdit()->setClearButtonEnabled(true);
0085     m_categoryEdit->setCompletionMode(KCompletion::CompletionPopupAuto);
0086 
0087     QStringList categories = Smb4KBookmarkHandler::self()->categoryList();
0088 
0089     if (!categories.contains(QStringLiteral(""))) {
0090         categories << QStringLiteral("");
0091     }
0092 
0093     m_categoryEdit->addItems(categories);
0094     m_categoryEdit->setCurrentText(QStringLiteral(""));
0095 
0096     connect(m_categoryEdit->lineEdit(), &KLineEdit::editingFinished, this, &Smb4KBookmarkDialog::slotCategoryEdited);
0097 
0098     editorWidgetLayout->addWidget(labelLabel, 0, 0);
0099     editorWidgetLayout->addWidget(m_labelEdit, 0, 1);
0100     editorWidgetLayout->addWidget(categoryLabel, 1, 0);
0101     editorWidgetLayout->addWidget(m_categoryEdit, 1, 1);
0102 
0103     layout->addWidget(m_editorWidget);
0104 
0105     QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
0106     m_saveButton = buttonBox->addButton(QDialogButtonBox::Save);
0107     m_saveButton->setShortcut(QKeySequence::Save);
0108     m_cancelButton = buttonBox->addButton(QDialogButtonBox::Cancel);
0109     m_cancelButton->setShortcut(QKeySequence::Cancel);
0110     m_cancelButton->setDefault(true);
0111 
0112     connect(m_saveButton, &QPushButton::clicked, this, &Smb4KBookmarkDialog::slotSaveBookmarks);
0113     connect(m_cancelButton, &QPushButton::clicked, this, &Smb4KBookmarkDialog::reject);
0114 
0115     layout->addWidget(buttonBox);
0116 
0117     setMinimumWidth(sizeHint().width() > 350 ? sizeHint().width() : 350);
0118 
0119     create();
0120 
0121     KConfigGroup dialogGroup(Smb4KSettings::self()->config(), QStringLiteral("BookmarkDialog"));
0122     QSize dialogSize;
0123 
0124     if (dialogGroup.exists()) {
0125         KWindowConfig::restoreWindowSize(windowHandle(), dialogGroup);
0126         dialogSize = windowHandle()->size();
0127     } else {
0128         dialogSize = sizeHint();
0129     }
0130 
0131     resize(dialogSize); // workaround for QTBUG-40584
0132 
0133     KConfigGroup completionGroup(Smb4KSettings::self()->config(), QStringLiteral("CompletionItems"));
0134 
0135     if (completionGroup.exists()) {
0136         m_labelEdit->completionObject()->setItems(completionGroup.readEntry("LabelCompletion", QStringList()));
0137         m_categoryEdit->completionObject()->setItems(completionGroup.readEntry("CategoryCompletion", Smb4KBookmarkHandler::self()->categoryList()));
0138     }
0139 }
0140 
0141 Smb4KBookmarkDialog::~Smb4KBookmarkDialog()
0142 {
0143 }
0144 
0145 bool Smb4KBookmarkDialog::setShares(const QList<SharePtr> &shares)
0146 {
0147     bool bookmarksSet = false;
0148 
0149     for (const SharePtr &share : qAsConst(shares)) {
0150         if (share->isHomesShare()) {
0151             QPointer<Smb4KHomesUserDialog> homesUserDialog = new Smb4KHomesUserDialog(this);
0152             bool proceed = false;
0153 
0154             if (homesUserDialog->setShare(share)) {
0155                 // We want to get a return value here, so we use exec()
0156                 if (homesUserDialog->exec() == QDialog::Accepted) {
0157                     proceed = true;
0158                 }
0159             }
0160 
0161             delete homesUserDialog;
0162 
0163             if (!proceed) {
0164                 continue;
0165             }
0166         }
0167 
0168         if (Smb4KBookmarkHandler::self()->isBookmarked(share)) {
0169             continue;
0170         }
0171 
0172         Smb4KBookmark bookmark;
0173         bookmark.setShare(share.data());
0174 
0175         QVariant variant = QVariant::fromValue(bookmark);
0176 
0177         QListWidgetItem *bookmarkItem = new QListWidgetItem(m_listWidget);
0178         bookmarkItem->setText(bookmark.displayString());
0179         bookmarkItem->setIcon(bookmark.icon());
0180         bookmarkItem->setData(Qt::UserRole, variant);
0181 
0182         bookmarksSet = true;
0183     }
0184 
0185     return bookmarksSet;
0186 }
0187 
0188 bool Smb4KBookmarkDialog::eventFilter(QObject *object, QEvent *event)
0189 {
0190     if (object == m_listWidget->viewport()) {
0191         if (event->type() == QEvent::MouseButtonPress) {
0192             QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
0193 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
0194             QPointF pos = m_listWidget->viewport()->mapFromGlobal(mouseEvent->globalPosition());
0195             QListWidgetItem *item = m_listWidget->itemAt(pos.toPoint());
0196 #else
0197             QPoint pos = m_listWidget->viewport()->mapFromGlobal(mouseEvent->globalPos());
0198             QListWidgetItem *item = m_listWidget->itemAt(pos);
0199 #endif
0200             if (!item) {
0201                 m_listWidget->clearSelection();
0202             }
0203         }
0204     }
0205 
0206     return QObject::eventFilter(object, event);
0207 }
0208 
0209 void Smb4KBookmarkDialog::slotItemDoubleClicked(QListWidgetItem *item)
0210 {
0211     Q_UNUSED(item);
0212 
0213     Smb4KBookmark bookmark = item->data(Qt::UserRole).value<Smb4KBookmark>();
0214 
0215     m_labelEdit->setText(bookmark.label());
0216     m_categoryEdit->setCurrentText(bookmark.categoryName());
0217 
0218     m_editorWidget->setVisible(true);
0219 }
0220 
0221 void Smb4KBookmarkDialog::slotItemSelectionChanged()
0222 {
0223     if (m_editorWidget->isVisible()) {
0224         m_editorWidget->setVisible(false);
0225         m_labelEdit->clear();
0226         m_categoryEdit->lineEdit()->clear();
0227     }
0228 }
0229 
0230 void Smb4KBookmarkDialog::slotLabelEdited()
0231 {
0232     if (m_listWidget->currentItem() && m_editorWidget->isVisible()) {
0233         Smb4KBookmark bookmark = m_listWidget->currentItem()->data(Qt::UserRole).value<Smb4KBookmark>();
0234         bookmark.setLabel(m_labelEdit->text());
0235 
0236         QVariant variant = QVariant::fromValue(bookmark);
0237         m_listWidget->currentItem()->setData(Qt::UserRole, variant);
0238 
0239         m_labelEdit->completionObject()->addItem(m_labelEdit->text());
0240     }
0241 }
0242 
0243 void Smb4KBookmarkDialog::slotCategoryEdited()
0244 {
0245     if (m_listWidget->currentItem() && m_editorWidget->isVisible()) {
0246         Smb4KBookmark bookmark = m_listWidget->currentItem()->data(Qt::UserRole).value<Smb4KBookmark>();
0247         bookmark.setCategoryName(m_categoryEdit->currentText());
0248 
0249         QVariant variant = QVariant::fromValue(bookmark);
0250         m_listWidget->currentItem()->setData(Qt::UserRole, variant);
0251 
0252         if (!m_categoryEdit->contains(m_categoryEdit->currentText())) {
0253             m_categoryEdit->addItem(m_categoryEdit->currentText());
0254         }
0255 
0256         m_categoryEdit->completionObject()->addItem(m_categoryEdit->currentText());
0257     }
0258 }
0259 
0260 void Smb4KBookmarkDialog::slotSaveBookmarks()
0261 {
0262     if (m_editorWidget->isVisible()) {
0263         Smb4KBookmark bookmark = m_listWidget->currentItem()->data(Qt::UserRole).value<Smb4KBookmark>();
0264 
0265         bookmark.setLabel(m_labelEdit->text());
0266         bookmark.setCategoryName(m_categoryEdit->currentText());
0267     }
0268 
0269     QList<BookmarkPtr> bookmarks;
0270 
0271     for (int i = 0; i < m_listWidget->count(); ++i) {
0272         Smb4KBookmark bookmark = m_listWidget->item(i)->data(Qt::UserRole).value<Smb4KBookmark>();
0273         bookmarks << BookmarkPtr(new Smb4KBookmark(bookmark));
0274     }
0275 
0276     Smb4KBookmarkHandler::self()->addBookmarks(bookmarks);
0277 
0278     KConfigGroup dialogGroup(Smb4KSettings::self()->config(), QStringLiteral("BookmarkEditor"));
0279     KWindowConfig::saveWindowSize(windowHandle(), dialogGroup);
0280 
0281     KConfigGroup completionGroup(Smb4KSettings::self()->config(), QStringLiteral("CompletionItems"));
0282     completionGroup.writeEntry("LabelCompletion", m_labelEdit->completionObject()->items());
0283     completionGroup.writeEntry("CategoryCompletion", m_categoryEdit->completionObject()->items());
0284 
0285     accept();
0286 }