File indexing completed on 2024-04-28 05:02:02

0001 /*
0002     The configuration page for bookmarks
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 "smb4kconfigpagebookmarks.h"
0010 #include "core/smb4kbookmarkhandler.h"
0011 
0012 // Qt includes
0013 #include <QDialogButtonBox>
0014 #include <QGridLayout>
0015 #include <QHBoxLayout>
0016 #include <QHostAddress>
0017 #include <QKeyEvent>
0018 #include <QMouseEvent>
0019 #include <QTimer>
0020 #include <QUrl>
0021 #include <QVBoxLayout>
0022 
0023 // KF includes
0024 #include <KIconLoader>
0025 #include <KLocalizedString>
0026 
0027 Smb4KConfigPageBookmarks::Smb4KConfigPageBookmarks(QWidget *parent)
0028     : QWidget(parent)
0029 {
0030     m_bookmarksChanged = false;
0031     m_savingBookmarks = false;
0032 
0033     QHBoxLayout *layout = new QHBoxLayout(this);
0034     QVBoxLayout *leftLayout = new QVBoxLayout();
0035 
0036     m_treeWidget = new QTreeWidget(this);
0037     m_treeWidget->headerItem()->setHidden(true);
0038     m_treeWidget->setColumnCount(1);
0039     m_treeWidget->setRootIsDecorated(false);
0040     m_treeWidget->setSelectionMode(QTreeWidget::SingleSelection);
0041     m_treeWidget->setItemsExpandable(false);
0042     m_treeWidget->setDragEnabled(true);
0043     m_treeWidget->setDragDropMode(QTreeWidget::InternalMove);
0044     m_treeWidget->setDropIndicatorShown(true);
0045     m_treeWidget->installEventFilter(this);
0046     m_treeWidget->viewport()->installEventFilter(this);
0047 
0048     connect(m_treeWidget, &QTreeWidget::currentItemChanged, this, &Smb4KConfigPageBookmarks::slotCurrentItemChanged);
0049     connect(m_treeWidget, &QTreeWidget::itemSelectionChanged, this, &Smb4KConfigPageBookmarks::slotItemSelectionChanged);
0050     connect(m_treeWidget, &QTreeWidget::itemDoubleClicked, this, &Smb4KConfigPageBookmarks::slotItemDoubleClicked);
0051 
0052     m_editorWidget = new QWidget(this);
0053     m_editorWidget->setVisible(false);
0054 
0055     QGridLayout *editorWidgetLayout = new QGridLayout(m_editorWidget);
0056     editorWidgetLayout->setContentsMargins(0, 0, 0, 0);
0057 
0058     m_labelLabel = new QLabel(i18n("Label:"), m_editorWidget);
0059     m_labelEdit = new KLineEdit(m_editorWidget);
0060     m_labelEdit->setClearButtonEnabled(true);
0061     m_labelEdit->setCompletionMode(KCompletion::CompletionNone);
0062 
0063     connect(m_labelEdit, &KLineEdit::textChanged, this, &Smb4KConfigPageBookmarks::slotLabelChanged);
0064     connect(m_labelEdit, &KLineEdit::editingFinished, this, &Smb4KConfigPageBookmarks::slotLabelEdited);
0065 
0066     m_categoryLabel = new QLabel(i18n("Category:"), m_editorWidget);
0067     m_categoryEdit = new KComboBox(m_editorWidget);
0068     m_categoryEdit->setEditable(true);
0069     m_categoryEdit->lineEdit()->setClearButtonEnabled(true);
0070     m_categoryEdit->setCompletionMode(KCompletion::CompletionNone);
0071 
0072     connect(m_categoryEdit->lineEdit(), &KLineEdit::textChanged, this, &Smb4KConfigPageBookmarks::slotCategoryChanged);
0073     connect(m_categoryEdit->lineEdit(), &QLineEdit::editingFinished, this, &Smb4KConfigPageBookmarks::slotCategoryEdited);
0074 
0075     m_userNameLabel = new QLabel(i18n("Username:"), m_editorWidget);
0076     m_userNameEdit = new KLineEdit(m_editorWidget);
0077     m_userNameEdit->setObjectName(QStringLiteral("UserNameEdit"));
0078     m_userNameEdit->setClearButtonEnabled(true);
0079     m_userNameEdit->setCompletionMode(KCompletion::CompletionNone);
0080 
0081     connect(m_userNameEdit, &KLineEdit::textChanged, this, &Smb4KConfigPageBookmarks::slotUserNameChanged);
0082     connect(m_userNameEdit, &KLineEdit::editingFinished, this, &Smb4KConfigPageBookmarks::slotUserNameEdited);
0083 
0084     m_workgroupLabel = new QLabel(i18n("Workgroup:"), m_editorWidget);
0085     m_workgroupEdit = new KLineEdit(m_editorWidget);
0086     m_workgroupEdit->setClearButtonEnabled(true);
0087     m_workgroupEdit->setCompletionMode(KCompletion::CompletionNone);
0088 
0089     connect(m_workgroupEdit, &KLineEdit::textChanged, this, &Smb4KConfigPageBookmarks::slotWorkgroupChanged);
0090     connect(m_workgroupEdit, &KLineEdit::editingFinished, this, &Smb4KConfigPageBookmarks::slotWorkgroupEdited);
0091 
0092     m_ipAddressLabel = new QLabel(i18n("IP Address:"), m_editorWidget);
0093     m_ipAddressEdit = new KLineEdit(m_editorWidget);
0094     m_ipAddressEdit->setClearButtonEnabled(true);
0095     m_ipAddressEdit->setCompletionMode(KCompletion::CompletionNone);
0096     // FIXME: Do we need an input mask?
0097 
0098     connect(m_ipAddressEdit, &KLineEdit::textChanged, this, &Smb4KConfigPageBookmarks::slotIpAddressChanged);
0099     connect(m_ipAddressEdit, &KLineEdit::editingFinished, this, &Smb4KConfigPageBookmarks::slotIpAddressEdited);
0100 
0101     editorWidgetLayout->addWidget(m_labelLabel, 0, 0);
0102     editorWidgetLayout->addWidget(m_labelEdit, 0, 1);
0103     editorWidgetLayout->addWidget(m_categoryLabel, 1, 0);
0104     editorWidgetLayout->addWidget(m_categoryEdit, 1, 1);
0105     editorWidgetLayout->addWidget(m_userNameLabel, 2, 0);
0106     editorWidgetLayout->addWidget(m_userNameEdit, 2, 1);
0107     editorWidgetLayout->addWidget(m_workgroupLabel, 3, 0);
0108     editorWidgetLayout->addWidget(m_workgroupEdit, 3, 1);
0109     editorWidgetLayout->addWidget(m_ipAddressLabel, 4, 0);
0110     editorWidgetLayout->addWidget(m_ipAddressEdit, 4, 1);
0111 
0112     leftLayout->addWidget(m_treeWidget);
0113     leftLayout->addWidget(m_editorWidget);
0114 
0115     layout->addLayout(leftLayout);
0116 
0117     QDialogButtonBox *buttonBox = new QDialogButtonBox(Qt::Vertical, this);
0118 
0119     m_resetButton = buttonBox->addButton(QDialogButtonBox::Reset);
0120     m_resetButton->setEnabled(false);
0121     m_resetButton->setObjectName(QStringLiteral("ResetButton"));
0122 
0123     connect(m_resetButton, &QPushButton::clicked, this, &Smb4KConfigPageBookmarks::slotResetButtonClicked);
0124 
0125     m_editButton = buttonBox->addButton(i18n("Edit"), QDialogButtonBox::ActionRole);
0126     m_editButton->setIcon(KDE::icon(QStringLiteral("bookmark-edit")));
0127     m_editButton->setEnabled(false);
0128 
0129     connect(m_editButton, &QPushButton::clicked, this, &Smb4KConfigPageBookmarks::slotEditButtonClicked);
0130 
0131     m_addCategoryButton = buttonBox->addButton(i18n("Add Category"), QDialogButtonBox::ActionRole);
0132     m_addCategoryButton->setIcon(KDE::icon(QStringLiteral("bookmark-add-folder")));
0133     m_addCategoryButton->setEnabled(!Smb4KBookmarkHandler::self()->bookmarkList().isEmpty());
0134 
0135     connect(m_addCategoryButton, &QPushButton::clicked, this, &Smb4KConfigPageBookmarks::slotAddCategoryButtonClicked);
0136 
0137     m_removeButton = buttonBox->addButton(i18n("Remove"), QDialogButtonBox::ActionRole);
0138     m_removeButton->setIcon(KDE::icon(QStringLiteral("bookmark-remove")));
0139     m_removeButton->setEnabled(false);
0140 
0141     connect(m_removeButton, &QPushButton::clicked, this, &Smb4KConfigPageBookmarks::slotRemoveButtonClicked);
0142 
0143     m_clearButton = buttonBox->addButton(i18n("Clear List"), QDialogButtonBox::ActionRole);
0144     m_clearButton->setIcon(KDE::icon(QStringLiteral("edit-clear")));
0145     m_clearButton->setEnabled(!Smb4KBookmarkHandler::self()->bookmarkList().isEmpty());
0146 
0147     connect(m_clearButton, &QPushButton::clicked, this, &Smb4KConfigPageBookmarks::slotClearButtonClicked);
0148 
0149     layout->addWidget(buttonBox);
0150 
0151     loadBookmarks();
0152 
0153     connect(this, &Smb4KConfigPageBookmarks::bookmarksModified, this, &Smb4KConfigPageBookmarks::slotEnableButtons);
0154     connect(this, &Smb4KConfigPageBookmarks::bookmarksModified, this, &Smb4KConfigPageBookmarks::sortItems);
0155     connect(Smb4KBookmarkHandler::self(), &Smb4KBookmarkHandler::updated, this, &Smb4KConfigPageBookmarks::loadBookmarks);
0156     connect(KIconLoader::global(), &KIconLoader::iconChanged, this, &Smb4KConfigPageBookmarks::slotIconSizeChanged);
0157 }
0158 
0159 Smb4KConfigPageBookmarks::~Smb4KConfigPageBookmarks()
0160 {
0161 }
0162 
0163 void Smb4KConfigPageBookmarks::loadBookmarks()
0164 {
0165     if (m_savingBookmarks) {
0166         return;
0167     }
0168 
0169     if (m_treeWidget->topLevelItemCount() != 0) {
0170         m_treeWidget->clear();
0171     }
0172 
0173     QStringList categories = Smb4KBookmarkHandler::self()->categoryList();
0174     m_categoryEdit->addItems(categories);
0175 
0176     if (!m_categoryEdit->contains(QStringLiteral(""))) {
0177         m_categoryEdit->addItem(QStringLiteral(""));
0178     }
0179 
0180     for (const QString &category : qAsConst(categories)) {
0181         QList<BookmarkPtr> bookmarks = Smb4KBookmarkHandler::self()->bookmarkList(category);
0182         QTreeWidgetItem *categoryItem = nullptr;
0183 
0184         if (!category.isEmpty() && !bookmarks.isEmpty()) {
0185             categoryItem = addCategoryItem(category);
0186         }
0187 
0188         if (!bookmarks.isEmpty()) {
0189             for (const BookmarkPtr &bookmark : qAsConst(bookmarks)) {
0190                 QVariant variant = QVariant::fromValue(*bookmark.data());
0191                 QTreeWidgetItem *bookmarkItem = nullptr;
0192 
0193                 if (categoryItem) {
0194                     bookmarkItem = new QTreeWidgetItem(categoryItem);
0195                 } else {
0196                     bookmarkItem = new QTreeWidgetItem(m_treeWidget);
0197                 }
0198 
0199                 bookmarkItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled);
0200                 bookmarkItem->setText(0, bookmark->displayString());
0201                 bookmarkItem->setIcon(0, bookmark->icon());
0202                 bookmarkItem->setData(0, TypeRole, BookmarkType);
0203                 bookmarkItem->setData(0, DataRole, variant);
0204             }
0205         }
0206     }
0207 
0208     m_bookmarksChanged = false;
0209     Q_EMIT bookmarksModified();
0210 }
0211 
0212 void Smb4KConfigPageBookmarks::saveBookmarks()
0213 {
0214     if (m_bookmarksChanged) {
0215         QTreeWidgetItemIterator it(m_treeWidget, QTreeWidgetItemIterator::NoChildren);
0216         QList<BookmarkPtr> bookmarksList;
0217 
0218         while (*it) {
0219             if ((*it)->data(0, TypeRole).toInt() == BookmarkType) {
0220                 BookmarkPtr bookmarkPtr = BookmarkPtr(new Smb4KBookmark((*it)->data(0, DataRole).value<Smb4KBookmark>()));
0221 
0222                 if (bookmarkPtr) {
0223                     bookmarksList << bookmarkPtr;
0224                 }
0225             }
0226             ++it;
0227         }
0228 
0229         m_savingBookmarks = true;
0230         Smb4KBookmarkHandler::self()->addBookmarks(bookmarksList, true);
0231         m_savingBookmarks = false;
0232 
0233         m_bookmarksChanged = false;
0234         Q_EMIT bookmarksModified();
0235     }
0236 }
0237 
0238 void Smb4KConfigPageBookmarks::setCompletionItems(const QMap<QString, QStringList> &items)
0239 {
0240     m_labelEdit->setCompletionMode(KCompletion::CompletionPopupAuto);
0241     m_labelEdit->completionObject()->setItems(items[QStringLiteral("LabelCompletion")]);
0242 
0243     m_categoryEdit->setCompletionMode(KCompletion::CompletionPopupAuto);
0244     m_categoryEdit->completionObject()->setItems(items[QStringLiteral("CategoryCompletion")]);
0245 
0246     m_userNameEdit->setCompletionMode(KCompletion::CompletionPopupAuto);
0247     m_userNameEdit->completionObject()->setItems(items[QStringLiteral("LoginCompletion")]);
0248 
0249     m_ipAddressEdit->setCompletionMode(KCompletion::CompletionPopupAuto);
0250     m_ipAddressEdit->completionObject()->setItems(items[QStringLiteral("IpAddressCompletion")]);
0251 
0252     m_workgroupEdit->setCompletionMode(KCompletion::CompletionPopupAuto);
0253     m_workgroupEdit->completionObject()->setItems(items[QStringLiteral("WorkgroupCompletion")]);
0254 }
0255 
0256 QMap<QString, QStringList> Smb4KConfigPageBookmarks::completionItems() const
0257 {
0258     QMap<QString, QStringList> items;
0259 
0260     if (m_labelEdit->completionMode() != KCompletion::CompletionNone) {
0261         items[QStringLiteral("LabelCompletion")] = m_labelEdit->completionObject()->items();
0262     }
0263 
0264     if (m_categoryEdit->completionMode() != KCompletion::CompletionNone) {
0265         items[QStringLiteral("CategoryCompletion")] = m_categoryEdit->completionObject()->items();
0266     }
0267 
0268     if (m_userNameEdit->completionMode() != KCompletion::CompletionNone) {
0269         items[QStringLiteral("LoginCompletion")] = m_userNameEdit->completionObject()->items();
0270     }
0271 
0272     if (m_ipAddressEdit->completionMode() != KCompletion::CompletionNone) {
0273         items[QStringLiteral("IpAddressCompletion")] = m_ipAddressEdit->completionObject()->items();
0274     }
0275 
0276     if (m_workgroupEdit->completionMode() != KCompletion::CompletionNone) {
0277         items[QStringLiteral("WorkgroupCompletion")] = m_workgroupEdit->completionObject()->items();
0278     }
0279 
0280     return items;
0281 }
0282 
0283 bool Smb4KConfigPageBookmarks::bookmarksChanged() const
0284 {
0285     return m_bookmarksChanged;
0286 }
0287 
0288 QTreeWidgetItem *Smb4KConfigPageBookmarks::addCategoryItem(const QString &text)
0289 {
0290     QTreeWidgetItem *categoryItem = new QTreeWidgetItem(m_treeWidget, QTreeWidgetItem::UserType);
0291     categoryItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled);
0292     categoryItem->setText(0, text);
0293     categoryItem->setIcon(0, KDE::icon(QStringLiteral("folder-favorites")));
0294     categoryItem->setData(0, TypeRole, CategoryType);
0295     categoryItem->setData(0, DataRole, text);
0296     QFont font = categoryItem->font(0);
0297     font.setBold(true);
0298     categoryItem->setFont(0, font);
0299     categoryItem->setExpanded(true);
0300 
0301     m_bookmarksChanged = true;
0302 
0303     return categoryItem;
0304 }
0305 
0306 void Smb4KConfigPageBookmarks::startEditingCategoryItem(QTreeWidgetItem *item)
0307 {
0308     m_treeWidget->setCurrentItem(item);
0309     m_treeWidget->openPersistentEditor(item, 0);
0310     m_treeWidget->setFocus();
0311 }
0312 
0313 void Smb4KConfigPageBookmarks::endEditingCategoryItem(QTreeWidgetItem *item)
0314 {
0315     if (m_treeWidget->isPersistentEditorOpen(item, 0)) {
0316         m_treeWidget->closePersistentEditor(item, 0);
0317         item->setData(0, DataRole, item->text(0));
0318 
0319         if (item->childCount() != 0) {
0320             for (int i = 0; i < item->childCount(); ++i) {
0321                 Smb4KBookmark bookmark = item->child(i)->data(0, DataRole).value<Smb4KBookmark>();
0322                 bookmark.setCategoryName(item->text(0));
0323 
0324                 QVariant variant = QVariant::fromValue(bookmark);
0325                 item->child(i)->setData(0, DataRole, variant);
0326             }
0327 
0328             m_bookmarksChanged = true;
0329         }
0330 
0331         m_categoryEdit->addItem(item->text(0));
0332         m_categoryEdit->completionObject()->addItem(item->text(0));
0333 
0334         Q_EMIT bookmarksModified();
0335     }
0336 }
0337 
0338 void Smb4KConfigPageBookmarks::checkValues()
0339 {
0340     if (m_treeWidget->currentItem() && m_treeWidget->currentItem()->data(0, TypeRole).toInt() == BookmarkType && m_editorWidget->isVisible()) {
0341         Smb4KBookmark bookmark = m_treeWidget->currentItem()->data(0, DataRole).value<Smb4KBookmark>();
0342 
0343         if (bookmark.label() != m_labelEdit->text()) {
0344             m_bookmarksChanged = true;
0345             Q_EMIT bookmarksModified();
0346             return;
0347         }
0348 
0349         if (bookmark.categoryName() != m_categoryEdit->currentText()) {
0350             m_bookmarksChanged = true;
0351             Q_EMIT bookmarksModified();
0352             return;
0353         }
0354 
0355         if (bookmark.userName() != m_userNameEdit->text()) {
0356             m_bookmarksChanged = true;
0357             Q_EMIT bookmarksModified();
0358             return;
0359         }
0360 
0361         if (bookmark.workgroupName() != m_workgroupEdit->text()) {
0362             m_bookmarksChanged = true;
0363             Q_EMIT bookmarksModified();
0364             return;
0365         }
0366 
0367         if (bookmark.hostIpAddress() != m_ipAddressEdit->text()) {
0368             m_bookmarksChanged = true;
0369             Q_EMIT bookmarksModified();
0370             return;
0371         }
0372 
0373         Q_EMIT bookmarksModified();
0374     }
0375 }
0376 
0377 bool Smb4KConfigPageBookmarks::eventFilter(QObject *obj, QEvent *e)
0378 {
0379     if (obj == m_treeWidget->viewport()) {
0380         if (e->type() == QEvent::MouseButtonPress) {
0381             QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(e);
0382 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
0383             QPointF pos = m_treeWidget->viewport()->mapFromGlobal(mouseEvent->globalPosition());
0384             QTreeWidgetItem *item = m_treeWidget->itemAt(pos.toPoint());
0385 #else
0386             QPoint pos = m_treeWidget->viewport()->mapFromGlobal(mouseEvent->globalPos());
0387             QTreeWidgetItem *item = m_treeWidget->itemAt(pos);
0388 #endif
0389             m_editButton->setEnabled(item != nullptr);
0390             m_removeButton->setEnabled(item != nullptr);
0391 
0392             if (!item) {
0393                 m_treeWidget->clearSelection();
0394             }
0395 
0396             if (m_treeWidget->isPersistentEditorOpen(m_treeWidget->currentItem(), 0)) {
0397                 endEditingCategoryItem(m_treeWidget->currentItem());
0398             }
0399         }
0400     } else if (obj == m_treeWidget) {
0401         if (e->type() == QEvent::KeyPress) {
0402             QKeyEvent *keyEvent = static_cast<QKeyEvent *>(e);
0403 
0404             if (keyEvent->key() == Qt::Key_Return) {
0405                 if (m_treeWidget->isPersistentEditorOpen(m_treeWidget->currentItem(), 0)) {
0406                     endEditingCategoryItem(m_treeWidget->currentItem());
0407                     return true;
0408                 }
0409             }
0410         } else if (e->type() == QEvent::ChildRemoved) {
0411             // NOTE: Occurs after a drop event on the viewport if an item was moved.
0412             // We use it to get the categories right.
0413             QTreeWidgetItemIterator it(m_treeWidget);
0414 
0415             while (*it) {
0416                 if ((*it)->data(0, TypeRole).toInt() == BookmarkType) {
0417                     Smb4KBookmark bookmark = (*it)->data(0, DataRole).value<Smb4KBookmark>();
0418 
0419                     if ((*it)->parent()) {
0420                         bookmark.setCategoryName((*it)->parent()->data(0, DataRole).toString());
0421                     } else {
0422                         bookmark.setCategoryName(QStringLiteral(""));
0423                     }
0424 
0425                     QVariant variant = QVariant::fromValue(bookmark);
0426                     (*it)->setData(0, DataRole, variant);
0427                 }
0428 
0429                 ++it;
0430             }
0431         }
0432     }
0433 
0434     return QObject::eventFilter(obj, e);
0435 }
0436 
0437 void Smb4KConfigPageBookmarks::slotResetButtonClicked(bool checked)
0438 {
0439     Q_UNUSED(checked);
0440     m_treeWidget->clear();
0441     loadBookmarks();
0442 }
0443 
0444 void Smb4KConfigPageBookmarks::slotEditButtonClicked(bool checked)
0445 {
0446     Q_UNUSED(checked);
0447 
0448     if (m_treeWidget->currentItem()) {
0449         slotItemDoubleClicked(m_treeWidget->currentItem(), 0);
0450     }
0451 }
0452 
0453 void Smb4KConfigPageBookmarks::slotAddCategoryButtonClicked(bool checked)
0454 {
0455     Q_UNUSED(checked)
0456     QTreeWidgetItem *categoryItem = addCategoryItem(i18n("New Category"));
0457 
0458     // Move item to the top
0459     int index = m_treeWidget->indexOfTopLevelItem(categoryItem);
0460     m_treeWidget->takeTopLevelItem(index);
0461     m_treeWidget->insertTopLevelItem(0, categoryItem);
0462 
0463     startEditingCategoryItem(categoryItem);
0464 }
0465 
0466 void Smb4KConfigPageBookmarks::slotRemoveButtonClicked(bool checked)
0467 {
0468     Q_UNUSED(checked);
0469 
0470     if (m_treeWidget->currentItem()) {
0471         QTreeWidgetItem *parentItem = nullptr;
0472 
0473         if (m_treeWidget->currentItem()->data(0, TypeRole).toInt() == BookmarkType) {
0474             parentItem = m_treeWidget->currentItem()->parent();
0475         }
0476 
0477         delete m_treeWidget->currentItem();
0478         m_treeWidget->setCurrentItem(nullptr);
0479 
0480         if (parentItem && parentItem->childCount() == 0) {
0481             delete parentItem;
0482         }
0483 
0484         m_bookmarksChanged = true;
0485         Q_EMIT bookmarksModified();
0486     }
0487 }
0488 
0489 void Smb4KConfigPageBookmarks::slotClearButtonClicked(bool checked)
0490 {
0491     Q_UNUSED(checked);
0492     m_treeWidget->clear();
0493     m_bookmarksChanged = true;
0494     Q_EMIT bookmarksModified();
0495 }
0496 
0497 void Smb4KConfigPageBookmarks::slotCurrentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
0498 {
0499     Q_UNUSED(current);
0500 
0501     if (m_treeWidget->isPersistentEditorOpen(previous)) {
0502         endEditingCategoryItem(previous);
0503     }
0504 }
0505 
0506 void Smb4KConfigPageBookmarks::slotItemSelectionChanged()
0507 {
0508     bool enableButtons = !m_treeWidget->selectedItems().isEmpty();
0509 
0510     m_editButton->setEnabled(enableButtons);
0511     m_removeButton->setEnabled(enableButtons);
0512 
0513     if (m_editorWidget->isVisible()) {
0514         m_editorWidget->setVisible(false);
0515         m_labelEdit->clear();
0516         m_categoryEdit->lineEdit()->clear();
0517         m_userNameEdit->clear();
0518         m_workgroupEdit->clear();
0519         m_ipAddressEdit->clear();
0520     }
0521 }
0522 
0523 void Smb4KConfigPageBookmarks::slotItemDoubleClicked(QTreeWidgetItem *item, int column)
0524 {
0525     Q_UNUSED(column);
0526 
0527     if (item->data(0, TypeRole).toInt() == BookmarkType) {
0528         QString label = item->data(0, DataRole).value<Smb4KBookmark>().label();
0529         m_labelEdit->setText(label);
0530 
0531         if (!m_labelEdit->completionObject()->items().contains(label)) {
0532             m_labelEdit->completionObject()->addItem(label);
0533         }
0534 
0535         QString categoryName = item->data(0, DataRole).value<Smb4KBookmark>().categoryName();
0536         m_categoryEdit->setCurrentItem(categoryName, true);
0537 
0538         if (!m_categoryEdit->completionObject()->items().contains(categoryName)) {
0539             m_categoryEdit->completionObject()->addItem(categoryName);
0540         }
0541 
0542         QString userName = item->data(0, DataRole).value<Smb4KBookmark>().userName();
0543         m_userNameEdit->setText(userName);
0544 
0545         if (!m_userNameEdit->completionObject()->items().contains(userName)) {
0546             m_userNameEdit->completionObject()->addItem(userName);
0547         }
0548 
0549         QString workgroupName = item->data(0, DataRole).value<Smb4KBookmark>().workgroupName();
0550         m_workgroupEdit->setText(workgroupName);
0551 
0552         if (!m_workgroupEdit->completionObject()->items().contains(workgroupName)) {
0553             m_workgroupEdit->completionObject()->addItem(workgroupName);
0554         }
0555 
0556         QString hostIpAddress = item->data(0, DataRole).value<Smb4KBookmark>().hostIpAddress();
0557         m_ipAddressEdit->setText(hostIpAddress);
0558 
0559         if (!m_ipAddressEdit->completionObject()->items().contains(hostIpAddress)) {
0560             m_ipAddressEdit->completionObject()->addItem(hostIpAddress);
0561         }
0562 
0563         m_editorWidget->setVisible(true);
0564     } else {
0565         startEditingCategoryItem(item);
0566     }
0567 }
0568 
0569 void Smb4KConfigPageBookmarks::slotLabelChanged(const QString &text)
0570 {
0571     Q_UNUSED(text);
0572     checkValues();
0573 }
0574 
0575 void Smb4KConfigPageBookmarks::slotLabelEdited()
0576 {
0577     if (m_treeWidget->currentItem() && m_editorWidget->isVisible()) {
0578         if (m_treeWidget->currentItem()->data(0, TypeRole).toInt() == BookmarkType) {
0579             Smb4KBookmark bookmark = m_treeWidget->currentItem()->data(0, DataRole).value<Smb4KBookmark>();
0580             bookmark.setLabel(m_labelEdit->text());
0581 
0582             QVariant variant = QVariant::fromValue(bookmark);
0583             m_treeWidget->currentItem()->setData(0, DataRole, variant);
0584 
0585             if (m_labelEdit->completionMode() != KCompletion::CompletionNone) {
0586                 m_labelEdit->completionObject()->addItem(m_labelEdit->text());
0587             }
0588         }
0589     }
0590 }
0591 
0592 void Smb4KConfigPageBookmarks::slotCategoryChanged(const QString &text)
0593 {
0594     Q_UNUSED(text);
0595     checkValues();
0596 }
0597 
0598 void Smb4KConfigPageBookmarks::slotCategoryEdited()
0599 {
0600     if (m_treeWidget->currentItem() && m_editorWidget->isVisible()) {
0601         if (m_treeWidget->currentItem()->data(0, TypeRole).toInt() == BookmarkType) {
0602             Smb4KBookmark bookmark = m_treeWidget->currentItem()->data(0, DataRole).value<Smb4KBookmark>();
0603             bookmark.setCategoryName(m_categoryEdit->currentText());
0604 
0605             QVariant variant = QVariant::fromValue(bookmark);
0606             m_treeWidget->currentItem()->setData(0, DataRole, variant);
0607 
0608             QTreeWidgetItem *categoryItem = nullptr;
0609 
0610             for (int i = 0; i < m_treeWidget->topLevelItemCount(); ++i) {
0611                 QTreeWidgetItem *item = m_treeWidget->topLevelItem(i);
0612 
0613                 if (item->data(0, TypeRole).toInt() == CategoryType) {
0614                     if (item->data(0, DataRole).toString() == bookmark.categoryName()) {
0615                         categoryItem = item;
0616                         break;
0617                     }
0618                 }
0619             }
0620 
0621             if (!categoryItem) {
0622                 categoryItem = addCategoryItem(bookmark.categoryName());
0623             }
0624 
0625             if (categoryItem != m_treeWidget->currentItem()->parent()) {
0626                 QTreeWidgetItem *itemToMove = m_treeWidget->currentItem();
0627                 QTreeWidgetItem *parentItem = nullptr;
0628 
0629                 if (!itemToMove->parent()) {
0630                     parentItem = m_treeWidget->invisibleRootItem();
0631                 } else {
0632                     parentItem = itemToMove->parent();
0633                 }
0634 
0635                 parentItem->removeChild(itemToMove);
0636                 categoryItem->addChild(itemToMove);
0637             }
0638 
0639             if (!m_categoryEdit->contains(m_categoryEdit->currentText())) {
0640                 m_categoryEdit->addItem(m_categoryEdit->currentText());
0641             }
0642 
0643             if (m_categoryEdit->completionMode() != KCompletion::CompletionNone) {
0644                 m_categoryEdit->completionObject()->addItem(m_categoryEdit->currentText());
0645             }
0646 
0647             Q_EMIT bookmarksModified();
0648         }
0649     }
0650 }
0651 
0652 void Smb4KConfigPageBookmarks::slotUserNameChanged(const QString &text)
0653 {
0654     Q_UNUSED(text);
0655     checkValues();
0656 }
0657 
0658 void Smb4KConfigPageBookmarks::slotUserNameEdited()
0659 {
0660     if (m_treeWidget->currentItem() && m_editorWidget->isVisible()) {
0661         if (m_treeWidget->currentItem()->data(0, TypeRole).toInt() == BookmarkType) {
0662             Smb4KBookmark bookmark = m_treeWidget->currentItem()->data(0, DataRole).value<Smb4KBookmark>();
0663             bookmark.setUserName(m_userNameEdit->text());
0664 
0665             QVariant variant = QVariant::fromValue(bookmark);
0666             m_treeWidget->currentItem()->setData(0, DataRole, variant);
0667 
0668             if (m_userNameEdit->completionMode() != KCompletion::CompletionNone) {
0669                 m_userNameEdit->completionObject()->addItem(m_userNameEdit->text());
0670             }
0671         }
0672     }
0673 }
0674 
0675 void Smb4KConfigPageBookmarks::slotWorkgroupChanged(const QString &text)
0676 {
0677     Q_UNUSED(text);
0678     checkValues();
0679 }
0680 
0681 void Smb4KConfigPageBookmarks::slotWorkgroupEdited()
0682 {
0683     if (m_treeWidget->currentItem() && m_editorWidget->isVisible()) {
0684         if (m_treeWidget->currentItem()->data(0, TypeRole).toInt() == BookmarkType) {
0685             Smb4KBookmark bookmark = m_treeWidget->currentItem()->data(0, DataRole).value<Smb4KBookmark>();
0686             bookmark.setWorkgroupName(m_workgroupEdit->text());
0687 
0688             QVariant variant = QVariant::fromValue(bookmark);
0689             m_treeWidget->currentItem()->setData(0, DataRole, variant);
0690 
0691             if (m_workgroupEdit->completionMode() != KCompletion::CompletionNone) {
0692                 m_workgroupEdit->completionObject()->addItem(m_workgroupEdit->text());
0693             }
0694         }
0695     }
0696 }
0697 
0698 void Smb4KConfigPageBookmarks::slotIpAddressChanged(const QString &text)
0699 {
0700     Q_UNUSED(text);
0701     checkValues();
0702 }
0703 
0704 void Smb4KConfigPageBookmarks::slotIpAddressEdited()
0705 {
0706     if (m_treeWidget->currentItem() && m_editorWidget->isVisible()) {
0707         if (m_treeWidget->currentItem()->data(0, TypeRole).toInt() == BookmarkType) {
0708             if (QHostAddress(m_ipAddressEdit->text()).protocol() == QAbstractSocket::UnknownNetworkLayerProtocol) {
0709                 return;
0710             }
0711 
0712             Smb4KBookmark bookmark = m_treeWidget->currentItem()->data(0, DataRole).value<Smb4KBookmark>();
0713             bookmark.setHostIpAddress(m_ipAddressEdit->text());
0714 
0715             QVariant variant = QVariant::fromValue(bookmark);
0716             m_treeWidget->currentItem()->setData(0, DataRole, variant);
0717 
0718             if (m_ipAddressEdit->completionMode() != KCompletion::CompletionNone) {
0719                 m_ipAddressEdit->completionObject()->addItem(m_ipAddressEdit->text());
0720             }
0721 
0722             m_bookmarksChanged = true;
0723             Q_EMIT bookmarksModified();
0724         }
0725     }
0726 }
0727 
0728 void Smb4KConfigPageBookmarks::slotEnableButtons()
0729 {
0730     m_resetButton->setEnabled(m_bookmarksChanged);
0731     m_clearButton->setEnabled(m_treeWidget->topLevelItemCount() != 0);
0732     m_addCategoryButton->setEnabled(m_treeWidget->topLevelItemCount() != 0);
0733 }
0734 
0735 void Smb4KConfigPageBookmarks::slotIconSizeChanged(int group)
0736 {
0737     switch (group) {
0738     case KIconLoader::Small: {
0739         int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small);
0740         m_treeWidget->setIconSize(QSize(iconSize, iconSize));
0741         break;
0742     }
0743     default: {
0744         break;
0745     }
0746     }
0747 }
0748 
0749 void Smb4KConfigPageBookmarks::sortItems()
0750 {
0751     QMap<QString, QTreeWidgetItem *> itemMap;
0752 
0753     while (m_treeWidget->topLevelItemCount() > 0) {
0754         QTreeWidgetItem *item = m_treeWidget->takeTopLevelItem(0);
0755 
0756         if (item->data(0, TypeRole).toInt() == CategoryType) {
0757             item->sortChildren(0, Qt::AscendingOrder);
0758             itemMap[QStringLiteral("00_") + item->data(0, DataRole).toString()] = item;
0759         } else {
0760             itemMap[QStringLiteral("01_") + item->data(0, DataRole).value<Smb4KBookmark>().displayString()] = item;
0761         }
0762     }
0763 
0764     QMapIterator<QString, QTreeWidgetItem *> it(itemMap);
0765 
0766     while (it.hasNext()) {
0767         it.next();
0768         m_treeWidget->addTopLevelItem(it.value());
0769 
0770         if (it.value()->childCount() != 0) {
0771             it.value()->setExpanded(true);
0772         }
0773     }
0774 }