File indexing completed on 2024-04-14 14:18:00

0001 //  -*- c-basic-offset:4; indent-tabs-mode:nil -*-
0002 /*
0003     This file is part of the KDE libraries
0004     SPDX-FileCopyrightText: 2007 Daniel Teske <teske@squorn.de>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-only
0007 */
0008 
0009 #include "kbookmarkdialog.h"
0010 #include "kbookmarkdialog_p.h"
0011 #include "kbookmarkmanager.h"
0012 #include "kbookmarkmenu.h"
0013 #include "kbookmarkmenu_p.h"
0014 
0015 #include <QDialogButtonBox>
0016 #include <QFormLayout>
0017 #include <QHeaderView>
0018 #include <QIcon>
0019 #include <QInputDialog>
0020 #include <QLabel>
0021 #include <QLineEdit>
0022 #include <QPushButton>
0023 #include <QTreeWidget>
0024 
0025 #include <KGuiItem>
0026 
0027 KBookmarkDialogPrivate::KBookmarkDialogPrivate(KBookmarkDialog *qq)
0028     : q(qq)
0029     , folderTree(nullptr)
0030     , layout(false)
0031 {
0032 }
0033 
0034 KBookmarkDialogPrivate::~KBookmarkDialogPrivate()
0035 {
0036 }
0037 
0038 void KBookmarkDialogPrivate::initLayout()
0039 {
0040     QBoxLayout *vbox = new QVBoxLayout(q);
0041 
0042     QFormLayout *form = new QFormLayout();
0043     vbox->addLayout(form);
0044 
0045     form->addRow(titleLabel, title);
0046     form->addRow(urlLabel, url);
0047     form->addRow(commentLabel, comment);
0048 
0049     vbox->addWidget(folderTree);
0050     vbox->addWidget(buttonBox);
0051 }
0052 
0053 void KBookmarkDialogPrivate::initLayoutPrivate()
0054 {
0055     title = new QLineEdit(q);
0056     title->setMinimumWidth(300);
0057     titleLabel = new QLabel(KBookmarkDialog::tr("Name:", "@label:textbox"), q);
0058     titleLabel->setBuddy(title);
0059 
0060     url = new QLineEdit(q);
0061     url->setMinimumWidth(300);
0062     urlLabel = new QLabel(KBookmarkDialog::tr("Location:", "@label:textbox"), q);
0063     urlLabel->setBuddy(url);
0064 
0065     comment = new QLineEdit(q);
0066     comment->setMinimumWidth(300);
0067     commentLabel = new QLabel(KBookmarkDialog::tr("Comment:", "@label:textbox"), q);
0068     commentLabel->setBuddy(comment);
0069 
0070     folderTree = new QTreeWidget(q);
0071     folderTree->setColumnCount(1);
0072     folderTree->header()->hide();
0073     folderTree->setSortingEnabled(false);
0074     folderTree->setSelectionMode(QTreeWidget::SingleSelection);
0075     folderTree->setSelectionBehavior(QTreeWidget::SelectRows);
0076     folderTree->setMinimumSize(60, 100);
0077     QTreeWidgetItem *root = new KBookmarkTreeItem(folderTree);
0078     fillGroup(root, mgr->root());
0079 
0080     buttonBox = new QDialogButtonBox(q);
0081     buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
0082     q->connect(buttonBox, &QDialogButtonBox::accepted, q, &KBookmarkDialog::accept);
0083     q->connect(buttonBox, &QDialogButtonBox::rejected, q, &QDialog::reject);
0084 
0085     initLayout();
0086     layout = true;
0087 }
0088 
0089 void KBookmarkDialogPrivate::fillGroup(QTreeWidgetItem *parentItem, const KBookmarkGroup &group, const KBookmarkGroup &selectGroup)
0090 {
0091     for (KBookmark bk = group.first(); !bk.isNull(); bk = group.next(bk)) {
0092         if (bk.isGroup()) {
0093             const KBookmarkGroup bkGroup = bk.toGroup();
0094             QTreeWidgetItem *item = new KBookmarkTreeItem(parentItem, folderTree, bkGroup);
0095             if (selectGroup == bkGroup) {
0096                 folderTree->setCurrentItem(item);
0097             }
0098             fillGroup(item, bkGroup, selectGroup);
0099         }
0100     }
0101 }
0102 
0103 void KBookmarkDialogPrivate::setParentBookmark(const KBookmark &bm)
0104 {
0105     QString address = bm.address();
0106     KBookmarkTreeItem *item = static_cast<KBookmarkTreeItem *>(folderTree->topLevelItem(0));
0107     while (true) {
0108         if (item->address() == bm.address()) {
0109             folderTree->setCurrentItem(item);
0110             return;
0111         }
0112         for (int i = 0; i < item->childCount(); ++i) {
0113             KBookmarkTreeItem *child = static_cast<KBookmarkTreeItem *>(item->child(i));
0114             if (KBookmark::commonParent(child->address(), address) == child->address()) {
0115                 item = child;
0116                 break;
0117             }
0118         }
0119     }
0120 }
0121 
0122 KBookmarkGroup KBookmarkDialogPrivate::parentBookmark()
0123 {
0124     KBookmarkTreeItem *item = dynamic_cast<KBookmarkTreeItem *>(folderTree->currentItem());
0125     if (!item) {
0126         return mgr->root();
0127     }
0128     const QString &address = item->address();
0129     return mgr->findByAddress(address).toGroup();
0130 }
0131 
0132 void KBookmarkDialog::accept()
0133 {
0134     if (d->mode == KBookmarkDialogPrivate::NewFolder) {
0135         KBookmarkGroup parent = d->parentBookmark();
0136         if (d->title->text().isEmpty()) {
0137             d->title->setText(QStringLiteral("New Folder"));
0138         }
0139         d->bm = parent.createNewFolder(d->title->text());
0140         d->bm.setDescription(d->comment->text());
0141         d->mgr->emitChanged(parent);
0142     } else if (d->mode == KBookmarkDialogPrivate::NewBookmark) {
0143         KBookmarkGroup parent = d->parentBookmark();
0144         if (d->title->text().isEmpty()) {
0145             d->title->setText(QStringLiteral("New Bookmark"));
0146         }
0147         d->bm = parent.addBookmark(d->title->text(), QUrl(d->url->text()), d->icon);
0148         d->bm.setDescription(d->comment->text());
0149         d->mgr->emitChanged(parent);
0150     } else if (d->mode == KBookmarkDialogPrivate::NewMultipleBookmarks) {
0151         KBookmarkGroup parent = d->parentBookmark();
0152         if (d->title->text().isEmpty()) {
0153             d->title->setText(QStringLiteral("New Folder"));
0154         }
0155         d->bm = parent.createNewFolder(d->title->text());
0156         d->bm.setDescription(d->comment->text());
0157         for (const KBookmarkOwner::FutureBookmark &fb : std::as_const(d->list)) {
0158             d->bm.toGroup().addBookmark(fb.title(), fb.url(), fb.icon());
0159         }
0160         d->mgr->emitChanged(parent);
0161     } else if (d->mode == KBookmarkDialogPrivate::EditBookmark) {
0162         d->bm.setFullText(d->title->text());
0163         d->bm.setUrl(QUrl(d->url->text()));
0164         d->bm.setDescription(d->comment->text());
0165         d->mgr->emitChanged(d->bm.parentGroup());
0166     } else if (d->mode == d->SelectFolder) {
0167         d->bm = d->parentBookmark();
0168     }
0169     QDialog::accept();
0170 }
0171 
0172 KBookmark KBookmarkDialog::editBookmark(const KBookmark &bm)
0173 {
0174     if (!d->layout) {
0175         d->initLayoutPrivate();
0176     }
0177 
0178     KGuiItem::assign(d->buttonBox->button(QDialogButtonBox::Ok), KGuiItem(tr("Update", "@action:button")));
0179     setWindowTitle(tr("Bookmark Properties", "@title:window"));
0180     d->url->setVisible(!bm.isGroup());
0181     d->urlLabel->setVisible(!bm.isGroup());
0182     d->bm = bm;
0183     d->title->setText(bm.fullText());
0184     d->url->setText(bm.url().toString());
0185     d->comment->setVisible(true);
0186     d->commentLabel->setVisible(true);
0187     d->comment->setText(bm.description());
0188     d->folderTree->setVisible(false);
0189 
0190     d->mode = KBookmarkDialogPrivate::EditBookmark;
0191 
0192     if (exec() == QDialog::Accepted) {
0193         return d->bm;
0194     } else {
0195         return KBookmark();
0196     }
0197 }
0198 
0199 KBookmark KBookmarkDialog::addBookmark(const QString &title, const QUrl &url, const QString &icon, KBookmark parent)
0200 {
0201     if (!d->layout) {
0202         d->initLayoutPrivate();
0203     }
0204     if (parent.isNull()) {
0205         parent = d->mgr->root();
0206     }
0207 
0208     QPushButton *newButton = new QPushButton;
0209     KGuiItem::assign(newButton, KGuiItem(tr("&New Folder...", "@action:button"), QStringLiteral("folder-new")));
0210     d->buttonBox->addButton(newButton, QDialogButtonBox::ActionRole);
0211     connect(newButton, &QAbstractButton::clicked, this, &KBookmarkDialog::newFolderButton);
0212 
0213     KGuiItem::assign(d->buttonBox->button(QDialogButtonBox::Ok), KGuiItem(tr("Add", "@action:button"), QStringLiteral("bookmark-new")));
0214     setWindowTitle(tr("Add Bookmark", "@title:window"));
0215     d->url->setVisible(true);
0216     d->urlLabel->setVisible(true);
0217     d->title->setText(title);
0218     d->url->setText(url.toString());
0219     d->comment->setText(QString());
0220     d->comment->setVisible(true);
0221     d->commentLabel->setVisible(true);
0222     d->setParentBookmark(parent);
0223     d->folderTree->setVisible(true);
0224     d->icon = icon;
0225 
0226     d->mode = KBookmarkDialogPrivate::NewBookmark;
0227 
0228     if (exec() == QDialog::Accepted) {
0229         return d->bm;
0230     } else {
0231         return KBookmark();
0232     }
0233 }
0234 
0235 KBookmarkGroup KBookmarkDialog::addBookmarks(const QList<KBookmarkOwner::FutureBookmark> &list, const QString &name, KBookmarkGroup parent)
0236 {
0237     if (!d->layout) {
0238         d->initLayoutPrivate();
0239     }
0240     if (parent.isNull()) {
0241         parent = d->mgr->root();
0242     }
0243 
0244     d->list = list;
0245 
0246     QPushButton *newButton = new QPushButton;
0247     KGuiItem::assign(newButton, KGuiItem(tr("&New Folder...", "@action:button"), QStringLiteral("folder-new")));
0248     d->buttonBox->addButton(newButton, QDialogButtonBox::ActionRole);
0249     connect(newButton, &QAbstractButton::clicked, this, &KBookmarkDialog::newFolderButton);
0250 
0251     KGuiItem::assign(d->buttonBox->button(QDialogButtonBox::Ok), KGuiItem(tr("Add", "@action:button"), QStringLiteral("bookmark-new")));
0252     setWindowTitle(tr("Add Bookmarks", "@title:window"));
0253     d->url->setVisible(false);
0254     d->urlLabel->setVisible(false);
0255     d->title->setText(name);
0256     d->comment->setVisible(true);
0257     d->commentLabel->setVisible(true);
0258     d->comment->setText(QString());
0259     d->setParentBookmark(parent);
0260     d->folderTree->setVisible(true);
0261 
0262     d->mode = KBookmarkDialogPrivate::NewMultipleBookmarks;
0263 
0264     if (exec() == QDialog::Accepted) {
0265         return d->bm.toGroup();
0266     } else {
0267         return KBookmarkGroup();
0268     }
0269 }
0270 
0271 KBookmarkGroup KBookmarkDialog::selectFolder(KBookmark parent)
0272 {
0273     if (!d->layout) {
0274         d->initLayoutPrivate();
0275     }
0276     if (parent.isNull()) {
0277         parent = d->mgr->root();
0278     }
0279 
0280     QPushButton *newButton = new QPushButton;
0281     KGuiItem::assign(newButton, KGuiItem(tr("&New Folder...", "@action:button"), QStringLiteral("folder-new")));
0282     d->buttonBox->addButton(newButton, QDialogButtonBox::ActionRole);
0283     connect(newButton, &QAbstractButton::clicked, this, &KBookmarkDialog::newFolderButton);
0284 
0285     setWindowTitle(tr("Select Folder", "@title:window"));
0286     d->url->setVisible(false);
0287     d->urlLabel->setVisible(false);
0288     d->title->setVisible(false);
0289     d->titleLabel->setVisible(false);
0290     d->comment->setVisible(false);
0291     d->commentLabel->setVisible(false);
0292     d->setParentBookmark(parent);
0293     d->folderTree->setVisible(true);
0294 
0295     d->mode = d->SelectFolder;
0296 
0297     if (exec() == QDialog::Accepted) {
0298         return d->bm.toGroup();
0299     } else {
0300         return KBookmarkGroup();
0301     }
0302 }
0303 
0304 KBookmarkGroup KBookmarkDialog::createNewFolder(const QString &name, KBookmark parent)
0305 {
0306     if (!d->layout) {
0307         d->initLayoutPrivate();
0308     }
0309     if (parent.isNull()) {
0310         parent = d->mgr->root();
0311     }
0312 
0313     setWindowTitle(tr("New Folder", "@title:window"));
0314     d->url->setVisible(false);
0315     d->urlLabel->setVisible(false);
0316     d->comment->setVisible(true);
0317     d->commentLabel->setVisible(true);
0318     d->comment->setText(QString());
0319     d->title->setText(name);
0320     d->setParentBookmark(parent);
0321     d->folderTree->setVisible(true);
0322 
0323     d->mode = KBookmarkDialogPrivate::NewFolder;
0324 
0325     if (exec() == QDialog::Accepted) {
0326         return d->bm.toGroup();
0327     } else {
0328         return KBookmarkGroup();
0329     }
0330 }
0331 
0332 KBookmarkDialog::KBookmarkDialog(KBookmarkManager *mgr, QWidget *parent)
0333     : QDialog(parent)
0334     , d(new KBookmarkDialogPrivate(this))
0335 {
0336     d->mgr = mgr;
0337 }
0338 
0339 KBookmarkDialog::~KBookmarkDialog() = default;
0340 
0341 void KBookmarkDialog::newFolderButton()
0342 {
0343     QString caption = d->parentBookmark().fullText().isEmpty() ? tr("Create New Bookmark Folder", "@title:window")
0344                                                                : tr("Create New Bookmark Folder in %1", "@title:window").arg(d->parentBookmark().text());
0345     bool ok;
0346     QString text = QInputDialog::getText(this, caption, tr("New folder:", "@label:textbox"), QLineEdit::Normal, QString(), &ok);
0347     if (!ok) {
0348         return;
0349     }
0350 
0351     KBookmarkGroup group = d->parentBookmark().createNewFolder(text);
0352     if (!group.isNull()) {
0353         KBookmarkGroup parentGroup = group.parentGroup();
0354         d->mgr->emitChanged(parentGroup);
0355         d->folderTree->clear();
0356         QTreeWidgetItem *root = new KBookmarkTreeItem(d->folderTree);
0357         d->fillGroup(root, d->mgr->root(), group);
0358     }
0359 }
0360 
0361 /********************************************************************/
0362 
0363 KBookmarkTreeItem::KBookmarkTreeItem(QTreeWidget *tree)
0364     : QTreeWidgetItem(tree)
0365     , m_address(QLatin1String(""))
0366 {
0367     setText(0, KBookmarkDialog::tr("Bookmarks", "name of the container of all browser bookmarks"));
0368     setIcon(0, QIcon::fromTheme(QStringLiteral("bookmarks")));
0369     tree->expandItem(this);
0370     tree->setCurrentItem(this);
0371     setSelected(true);
0372 }
0373 
0374 KBookmarkTreeItem::KBookmarkTreeItem(QTreeWidgetItem *parent, QTreeWidget *tree, const KBookmarkGroup &bk)
0375     : QTreeWidgetItem(parent)
0376 {
0377     setIcon(0, QIcon::fromTheme(bk.icon()));
0378     setText(0, bk.fullText());
0379     tree->expandItem(this);
0380     m_address = bk.address();
0381 }
0382 
0383 KBookmarkTreeItem::~KBookmarkTreeItem()
0384 {
0385 }
0386 
0387 QString KBookmarkTreeItem::address()
0388 {
0389     return m_address;
0390 }
0391 
0392 #include "moc_kbookmarkdialog.cpp"