File indexing completed on 2024-05-19 03:55:15

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