File indexing completed on 2024-04-21 05:50:21

0001 // -*- indent-tabs-mode:nil -*-
0002 // vim: set ts=4 sts=4 sw=4 et:
0003 /* This file is part of the KDE project
0004    Copyright (C) 2000 David Faure <faure@kde.org>
0005    Copyright (C) 2002-2003 Alexander Kellett <lypanov@kde.org>
0006 
0007    This program is free software; you can redistribute it and/or
0008    modify it under the terms of the GNU General Public
0009    License version 2 as published by the Free Software Foundation.
0010 
0011    This program is distributed in the hope that it will be useful,
0012    but WITHOUT ANY WARRANTY; without even the implied warranty of
0013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014    General Public License for more details.
0015 
0016    You should have received a copy of the GNU General Public License
0017    along with this program; see the file COPYING.  If not, write to
0018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0019    Boston, MA 02110-1301, USA.
0020 */
0021 
0022 #include "actionsimpl.h"
0023 #include "globalbookmarkmanager.h"
0024 
0025 #include "bookmarkinfowidget.h"
0026 #include "exporters.h"
0027 #include "favicons.h"
0028 #include "importers.h"
0029 #include "kbookmarkmodel/commandhistory.h"
0030 #include "kbookmarkmodel/commands.h"
0031 #include "kbookmarkmodel/model.h"
0032 #include "testlink.h"
0033 #include "toplevel.h" // for KEBApp
0034 
0035 #include <stdlib.h>
0036 
0037 #include "keditbookmarks_debug.h"
0038 
0039 #include <QApplication>
0040 #include <QClipboard>
0041 #include <QFileDialog>
0042 #include <QMimeData>
0043 
0044 #include <KActionCollection>
0045 #include <KIO/JobUiDelegateFactory>
0046 #include <KIO/OpenUrlJob>
0047 #include <KIconDialog>
0048 #include <KIconLoader>
0049 #include <KLocalizedString>
0050 #include <KStandardAction>
0051 #include <QIcon>
0052 #include <kio_version.h>
0053 
0054 #include <QInputDialog>
0055 
0056 #include "kbookmarkimporter.h"
0057 #include <KBookmark>
0058 #include <KBookmarkManager>
0059 
0060 #include "kbookmarkexporter.h"
0061 #include "kbookmarkimporter_ie.h"
0062 #include "kbookmarkimporter_ns.h"
0063 #include "kbookmarkimporter_opera.h"
0064 
0065 // decoupled from resetActions in toplevel.cpp
0066 // as resetActions simply uses the action groups
0067 // specified in the ui.rc file
0068 void KEBApp::createActions()
0069 {
0070     m_actionsImpl = new ActionsImpl(this, GlobalBookmarkManager::self()->model());
0071 
0072     connect(m_actionsImpl->testLinkHolder(), &BookmarkIteratorHolder::setCancelEnabled, this, &KEBApp::setCancelTestsEnabled);
0073     connect(m_actionsImpl->favIconHolder(), &BookmarkIteratorHolder::setCancelEnabled, this, &KEBApp::setCancelFavIconUpdatesEnabled);
0074 
0075     // save and quit should probably not be in the toplevel???
0076     (void)KStandardAction::quit(this, SLOT(close()), actionCollection());
0077 
0078     KStandardAction::keyBindings(guiFactory(), &KXMLGUIFactory::showConfigureShortcutsDialog, actionCollection());
0079 
0080     (void)KStandardAction::configureToolbars(this, SLOT(slotConfigureToolbars()), actionCollection());
0081 
0082     if (m_browser) {
0083         (void)KStandardAction::open(m_actionsImpl, SLOT(slotLoad()), actionCollection());
0084         (void)KStandardAction::saveAs(m_actionsImpl, SLOT(slotSaveAs()), actionCollection());
0085     }
0086 
0087     (void)KStandardAction::cut(m_actionsImpl, SLOT(slotCut()), actionCollection());
0088     (void)KStandardAction::copy(m_actionsImpl, SLOT(slotCopy()), actionCollection());
0089     (void)KStandardAction::paste(m_actionsImpl, SLOT(slotPaste()), actionCollection());
0090 
0091     // actions
0092     QAction *m_actionsImplDelete = actionCollection()->addAction(QStringLiteral("delete"));
0093     m_actionsImplDelete->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete")));
0094     m_actionsImplDelete->setText(i18n("&Delete"));
0095     actionCollection()->setDefaultShortcut(m_actionsImplDelete, Qt::Key_Delete);
0096     connect(m_actionsImplDelete, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotDelete);
0097 
0098     QAction *m_actionsImplRename = actionCollection()->addAction(QStringLiteral("rename"));
0099     m_actionsImplRename->setIcon(QIcon::fromTheme(QStringLiteral("edit-rename")));
0100     m_actionsImplRename->setText(i18n("Rename"));
0101     actionCollection()->setDefaultShortcut(m_actionsImplRename, Qt::Key_F2);
0102     connect(m_actionsImplRename, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotRename);
0103 
0104     QAction *m_actionsImplChangeURL = actionCollection()->addAction(QStringLiteral("changeurl"));
0105     m_actionsImplChangeURL->setIcon(QIcon::fromTheme(QStringLiteral("edit-rename")));
0106     m_actionsImplChangeURL->setText(i18n("C&hange Location"));
0107     actionCollection()->setDefaultShortcut(m_actionsImplChangeURL, Qt::Key_F3);
0108     connect(m_actionsImplChangeURL, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotChangeURL);
0109 
0110     QAction *m_actionsImplChangeComment = actionCollection()->addAction(QStringLiteral("changecomment"));
0111     m_actionsImplChangeComment->setIcon(QIcon::fromTheme(QStringLiteral("edit-rename")));
0112     m_actionsImplChangeComment->setText(i18n("C&hange Comment"));
0113     actionCollection()->setDefaultShortcut(m_actionsImplChangeComment, Qt::Key_F4);
0114     connect(m_actionsImplChangeComment, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotChangeComment);
0115 
0116     QAction *m_actionsImplChangeIcon = actionCollection()->addAction(QStringLiteral("changeicon"));
0117     m_actionsImplChangeIcon->setIcon(QIcon::fromTheme(QStringLiteral("preferences-desktop-icons")));
0118     m_actionsImplChangeIcon->setText(i18n("Chan&ge Icon..."));
0119     connect(m_actionsImplChangeIcon, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotChangeIcon);
0120 
0121     QAction *m_actionsImplUpdateFavIcon = actionCollection()->addAction(QStringLiteral("updatefavicon"));
0122     m_actionsImplUpdateFavIcon->setText(i18n("Update Favicon"));
0123     connect(m_actionsImplUpdateFavIcon, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotUpdateFavIcon);
0124 
0125     QAction *m_actionsImplRecursiveSort = actionCollection()->addAction(QStringLiteral("recursivesort"));
0126     m_actionsImplRecursiveSort->setText(i18n("Recursive Sort"));
0127     connect(m_actionsImplRecursiveSort, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotRecursiveSort);
0128 
0129     QAction *m_actionsImplNewFolder = actionCollection()->addAction(QStringLiteral("newfolder"));
0130     m_actionsImplNewFolder->setIcon(QIcon::fromTheme(QStringLiteral("folder-new")));
0131     m_actionsImplNewFolder->setText(i18n("&New Folder..."));
0132     actionCollection()->setDefaultShortcut(m_actionsImplNewFolder, Qt::CTRL | Qt::Key_N);
0133     connect(m_actionsImplNewFolder, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotNewFolder);
0134 
0135     QAction *m_actionsImplNewBookmark = actionCollection()->addAction(QStringLiteral("newbookmark"));
0136     m_actionsImplNewBookmark->setIcon(QIcon::fromTheme(QStringLiteral("bookmark-new")));
0137     m_actionsImplNewBookmark->setText(i18n("&New Bookmark"));
0138     connect(m_actionsImplNewBookmark, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotNewBookmark);
0139 
0140     QAction *m_actionsImplInsertSeparator = actionCollection()->addAction(QStringLiteral("insertseparator"));
0141     m_actionsImplInsertSeparator->setText(i18n("&Insert Separator"));
0142     actionCollection()->setDefaultShortcut(m_actionsImplInsertSeparator, Qt::CTRL | Qt::Key_I);
0143     connect(m_actionsImplInsertSeparator, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotInsertSeparator);
0144 
0145     QAction *m_actionsImplSort = actionCollection()->addAction(QStringLiteral("sort"));
0146     m_actionsImplSort->setText(i18n("&Sort Alphabetically"));
0147     connect(m_actionsImplSort, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotSort);
0148 
0149     QAction *m_actionsImplSetAsToolbar = actionCollection()->addAction(QStringLiteral("setastoolbar"));
0150     m_actionsImplSetAsToolbar->setIcon(QIcon::fromTheme(QStringLiteral("bookmark-toolbar")));
0151     m_actionsImplSetAsToolbar->setText(i18n("Set as T&oolbar Folder"));
0152     connect(m_actionsImplSetAsToolbar, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotSetAsToolbar);
0153 
0154     QAction *m_actionsImplExpandAll = actionCollection()->addAction(QStringLiteral("expandall"));
0155     m_actionsImplExpandAll->setText(i18n("&Expand All Folders"));
0156     connect(m_actionsImplExpandAll, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotExpandAll);
0157 
0158     QAction *m_actionsImplCollapseAll = actionCollection()->addAction(QStringLiteral("collapseall"));
0159     m_actionsImplCollapseAll->setText(i18n("Collapse &All Folders"));
0160     connect(m_actionsImplCollapseAll, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotCollapseAll);
0161 
0162     QAction *m_actionsImplOpenLink = actionCollection()->addAction(QStringLiteral("openlink"));
0163     m_actionsImplOpenLink->setIcon(QIcon::fromTheme(QStringLiteral("internet-web-browser")));
0164     m_actionsImplOpenLink->setText(i18n("&Open in Browser"));
0165     connect(m_actionsImplOpenLink, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotOpenLink);
0166 
0167     QAction *m_actionsImplTestSelection = actionCollection()->addAction(QStringLiteral("testlink"));
0168     m_actionsImplTestSelection->setIcon(QIcon::fromTheme(QStringLiteral("bookmarks")));
0169     m_actionsImplTestSelection->setText(i18n("Check &Status"));
0170     connect(m_actionsImplTestSelection, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotTestSelection);
0171 
0172     QAction *m_actionsImplTestAll = actionCollection()->addAction(QStringLiteral("testall"));
0173     m_actionsImplTestAll->setText(i18n("Check Status: &All"));
0174     connect(m_actionsImplTestAll, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotTestAll);
0175 
0176     QAction *m_actionsImplUpdateAllFavIcons = actionCollection()->addAction(QStringLiteral("updateallfavicons"));
0177     m_actionsImplUpdateAllFavIcons->setText(i18n("Update All &Favicons"));
0178     connect(m_actionsImplUpdateAllFavIcons, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotUpdateAllFavIcons);
0179 
0180     QAction *m_actionsImplCancelAllTests = actionCollection()->addAction(QStringLiteral("canceltests"));
0181     m_actionsImplCancelAllTests->setText(i18n("Cancel &Checks"));
0182     connect(m_actionsImplCancelAllTests, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotCancelAllTests);
0183 
0184     QAction *m_actionsImplCancelFavIconUpdates = actionCollection()->addAction(QStringLiteral("cancelfaviconupdates"));
0185     m_actionsImplCancelFavIconUpdates->setText(i18n("Cancel &Favicon Updates"));
0186     connect(m_actionsImplCancelFavIconUpdates, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotCancelFavIconUpdates);
0187 
0188     QAction *m_actionsImplImportNS = actionCollection()->addAction(QStringLiteral("importNS"));
0189     m_actionsImplImportNS->setObjectName(QStringLiteral("NS"));
0190     m_actionsImplImportNS->setIcon(QIcon::fromTheme(QStringLiteral("netscape")));
0191     m_actionsImplImportNS->setText(i18n("Import &Netscape Bookmarks..."));
0192     connect(m_actionsImplImportNS, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotImport);
0193 
0194     QAction *m_actionsImplImportOpera = actionCollection()->addAction(QStringLiteral("importOpera"));
0195     m_actionsImplImportOpera->setObjectName(QStringLiteral("Opera"));
0196     m_actionsImplImportOpera->setIcon(QIcon::fromTheme(QStringLiteral("opera")));
0197     m_actionsImplImportOpera->setText(i18n("Import &Opera Bookmarks..."));
0198     connect(m_actionsImplImportOpera, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotImport);
0199     /*
0200         KAction* m_actionsImplImportCrashes = actionCollection()->addAction("importCrashes");
0201         m_actionsImplImportCrashes->setObjectName( QLatin1String("Crashes" ));
0202         m_actionsImplImportCrashes->setText(i18n("Import All &Crash Sessions as Bookmarks..."));
0203         connect(m_actionsImplImportCrashes, &KAction::triggered, m_actionsImpl, &ActionsImpl::slotImport);
0204     */
0205     QAction *m_actionsImplImportGaleon = actionCollection()->addAction(QStringLiteral("importGaleon"));
0206     m_actionsImplImportGaleon->setObjectName(QStringLiteral("Galeon"));
0207     m_actionsImplImportGaleon->setText(i18n("Import &Galeon Bookmarks..."));
0208     connect(m_actionsImplImportGaleon, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotImport);
0209 
0210     QAction *m_actionsImplImportKDE2 = actionCollection()->addAction(QStringLiteral("importKDE2"));
0211     m_actionsImplImportKDE2->setObjectName(QStringLiteral("KDE2"));
0212     m_actionsImplImportKDE2->setIcon(QIcon::fromTheme(QStringLiteral("kde")));
0213     m_actionsImplImportKDE2->setText(i18n("Import &KDE 2 or KDE 3 Bookmarks..."));
0214 
0215     connect(m_actionsImplImportKDE2, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotImport);
0216 
0217     QAction *m_actionsImplImportIE = actionCollection()->addAction(QStringLiteral("importIE"));
0218     m_actionsImplImportIE->setObjectName(QStringLiteral("IE"));
0219     m_actionsImplImportIE->setText(i18n("Import &Internet Explorer Bookmarks..."));
0220     connect(m_actionsImplImportIE, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotImport);
0221 
0222     QAction *m_actionsImplImportMoz = actionCollection()->addAction(QStringLiteral("importMoz"));
0223     m_actionsImplImportMoz->setObjectName(QStringLiteral("Moz"));
0224     m_actionsImplImportMoz->setIcon(QIcon::fromTheme(QStringLiteral("mozilla")));
0225     m_actionsImplImportMoz->setText(i18n("Import &Mozilla Bookmarks..."));
0226     connect(m_actionsImplImportMoz, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotImport);
0227 
0228     QAction *m_actionsImplExportNS = actionCollection()->addAction(QStringLiteral("exportNS"));
0229     m_actionsImplExportNS->setIcon(QIcon::fromTheme(QStringLiteral("netscape")));
0230     m_actionsImplExportNS->setText(i18n("Export &Netscape Bookmarks"));
0231     connect(m_actionsImplExportNS, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotExportNS);
0232 
0233     QAction *m_actionsImplExportOpera = actionCollection()->addAction(QStringLiteral("exportOpera"));
0234     m_actionsImplExportOpera->setIcon(QIcon::fromTheme(QStringLiteral("opera")));
0235     m_actionsImplExportOpera->setText(i18n("Export &Opera Bookmarks..."));
0236     connect(m_actionsImplExportOpera, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotExportOpera);
0237 
0238     QAction *m_actionsImplExportHTML = actionCollection()->addAction(QStringLiteral("exportHTML"));
0239     m_actionsImplExportHTML->setIcon(QIcon::fromTheme(QStringLiteral("text-html")));
0240     m_actionsImplExportHTML->setText(i18n("Export &HTML Bookmarks..."));
0241     connect(m_actionsImplExportHTML, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotExportHTML);
0242 
0243     QAction *m_actionsImplExportIE = actionCollection()->addAction(QStringLiteral("exportIE"));
0244     m_actionsImplExportIE->setText(i18n("Export &Internet Explorer Bookmarks..."));
0245     connect(m_actionsImplExportIE, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotExportIE);
0246 
0247     QAction *m_actionsImplExportMoz = actionCollection()->addAction(QStringLiteral("exportMoz"));
0248     m_actionsImplExportMoz->setIcon(QIcon::fromTheme(QStringLiteral("mozilla")));
0249     m_actionsImplExportMoz->setText(i18n("Export &Mozilla Bookmarks..."));
0250     connect(m_actionsImplExportMoz, &QAction::triggered, m_actionsImpl, &ActionsImpl::slotExportMoz);
0251 }
0252 
0253 ActionsImpl::ActionsImpl(QObject *parent, KBookmarkModel *model)
0254     : QObject(parent)
0255     , m_model(model)
0256     , m_testLinkHolder(new TestLinkItrHolder(this, model))
0257     , m_favIconHolder(new FavIconsItrHolder(this, model))
0258 {
0259     Q_ASSERT(m_model);
0260 }
0261 
0262 void ActionsImpl::slotLoad()
0263 {
0264     const QString bookmarksFile = QFileDialog::getOpenFileName(KEBApp::self(), QString(), QString(), QStringLiteral("KDE Bookmark Files (*.xml)"));
0265     if (bookmarksFile.isNull())
0266         return;
0267     KEBApp::self()->reset(QString(), bookmarksFile);
0268 }
0269 
0270 void ActionsImpl::slotSaveAs()
0271 {
0272     KEBApp::self()->bkInfo()->commitChanges();
0273     const QString saveFilename = QFileDialog::getSaveFileName(KEBApp::self(), QString(), QString(), QStringLiteral("KDE Bookmark Files (*.xml)"));
0274     if (!saveFilename.isEmpty())
0275         GlobalBookmarkManager::self()->saveAs(saveFilename);
0276 }
0277 
0278 void GlobalBookmarkManager::doExport(ExportType type, const QString &_path)
0279 {
0280     // it can be null when we use command line to export => there is not interface
0281     if (KEBApp::self() && KEBApp::self()->bkInfo())
0282         KEBApp::self()->bkInfo()->commitChanges();
0283     QString path(_path);
0284     // TODO - add a factory and make all this use the base class
0285     if (type == OperaExport) {
0286         if (path.isNull())
0287             path = OperaBookmarkImporterImpl().findDefaultLocation(true);
0288         KOperaBookmarkExporterImpl exporter(path);
0289         exporter.write(mgr()->root());
0290         return;
0291 
0292     } else if (type == HTMLExport) {
0293         if (path.isNull())
0294             path = QFileDialog::getSaveFileName(KEBApp::self(), QString(), QDir::homePath(), i18n("HTML Bookmark Listing (*.html)"));
0295         HTMLExporter exporter;
0296         exporter.write(mgr()->root(), path);
0297         return;
0298 
0299     } else if (type == IEExport) {
0300         if (path.isNull())
0301             path = IEBookmarkImporterImpl().findDefaultLocation(true);
0302         IEBookmarkExporterImpl exporter(path);
0303         exporter.write(mgr()->root());
0304         return;
0305     }
0306 
0307     bool moz = (type == MozillaExport);
0308 
0309     if (path.isNull()) {
0310         if (moz) {
0311             KMozillaBookmarkImporterImpl importer;
0312             path = importer.findDefaultLocation(true);
0313         } else {
0314             NSBookmarkImporterImpl importer;
0315             path = importer.findDefaultLocation(true);
0316         }
0317     }
0318 
0319     if (!path.isEmpty()) {
0320         KNSBookmarkExporterImpl exporter(path);
0321         exporter.write(mgr()->root());
0322     }
0323 }
0324 
0325 void KEBApp::setCancelFavIconUpdatesEnabled(bool enabled)
0326 {
0327     actionCollection()->action(QStringLiteral("cancelfaviconupdates"))->setEnabled(enabled);
0328 }
0329 
0330 void KEBApp::setCancelTestsEnabled(bool enabled)
0331 {
0332     actionCollection()->action(QStringLiteral("canceltests"))->setEnabled(enabled);
0333 }
0334 
0335 void ActionsImpl::slotCut()
0336 {
0337     KEBApp::self()->bkInfo()->commitChanges();
0338     slotCopy();
0339     DeleteManyCommand *mcmd = new DeleteManyCommand(m_model, i18nc("(qtundo-format)", "Cut Items"), KEBApp::self()->selectedBookmarks());
0340     commandHistory()->addCommand(mcmd);
0341 }
0342 
0343 void ActionsImpl::slotCopy()
0344 {
0345     KEBApp::self()->bkInfo()->commitChanges();
0346     // this is not a command, because it can't be undone
0347     KBookmark::List bookmarks = KEBApp::self()->selectedBookmarksExpanded();
0348     QMimeData *mimeData = new QMimeData;
0349     bookmarks.populateMimeData(mimeData);
0350     QApplication::clipboard()->setMimeData(mimeData);
0351 }
0352 
0353 void ActionsImpl::slotPaste()
0354 {
0355     KEBApp::self()->bkInfo()->commitChanges();
0356 
0357     QString addr;
0358     KBookmark bk = KEBApp::self()->firstSelected();
0359     if (bk.isGroup())
0360         addr = bk.address() + QStringLiteral("/0"); // FIXME internal
0361     else
0362         addr = bk.address();
0363 
0364     QUndoCommand *mcmd = CmdGen::insertMimeSource(m_model, i18nc("(qtundo-format)", "Paste"), QApplication::clipboard()->mimeData(), addr);
0365     commandHistory()->addCommand(mcmd);
0366 }
0367 
0368 /* -------------------------------------- */
0369 
0370 void ActionsImpl::slotNewFolder()
0371 {
0372     KEBApp::self()->bkInfo()->commitChanges();
0373     bool ok;
0374     QString str =
0375         QInputDialog::getText(KEBApp::self(), i18n("New folder:"), i18nc("@title:window", "Create New Bookmark Folder"), QLineEdit::Normal, QString(), &ok);
0376     if (!ok)
0377         return;
0378 
0379     CreateCommand *cmd = new CreateCommand(m_model, KEBApp::self()->insertAddress(), str, QStringLiteral("bookmark_folder"), /*open*/ true);
0380     commandHistory()->addCommand(cmd);
0381 }
0382 
0383 void ActionsImpl::slotNewBookmark()
0384 {
0385     KEBApp::self()->bkInfo()->commitChanges();
0386     // TODO - make a setCurrentItem(Command *) which uses finaladdress interface
0387     CreateCommand *cmd = new CreateCommand(m_model, KEBApp::self()->insertAddress(), QString(), QStringLiteral("www"), QUrl(QStringLiteral("http://")));
0388     commandHistory()->addCommand(cmd);
0389 }
0390 
0391 void ActionsImpl::slotInsertSeparator()
0392 {
0393     KEBApp::self()->bkInfo()->commitChanges();
0394     CreateCommand *cmd = new CreateCommand(m_model, KEBApp::self()->insertAddress());
0395     commandHistory()->addCommand(cmd);
0396 }
0397 
0398 void ActionsImpl::slotImport()
0399 {
0400     KEBApp::self()->bkInfo()->commitChanges();
0401     qCDebug(KEDITBOOKMARKS_LOG) << "ActionsImpl::slotImport() where sender()->name() == " << sender()->objectName();
0402     ImportCommand *import = ImportCommand::performImport(m_model, sender()->objectName(), KEBApp::self());
0403     if (!import)
0404         return;
0405     commandHistory()->addCommand(import);
0406     // FIXME select import->groupAddress
0407 }
0408 
0409 // TODO - this is getting ugly and repetitive. cleanup!
0410 
0411 void ActionsImpl::slotExportOpera()
0412 {
0413     KEBApp::self()->bkInfo()->commitChanges();
0414     GlobalBookmarkManager::self()->doExport(GlobalBookmarkManager::OperaExport);
0415 }
0416 void ActionsImpl::slotExportHTML()
0417 {
0418     KEBApp::self()->bkInfo()->commitChanges();
0419     GlobalBookmarkManager::self()->doExport(GlobalBookmarkManager::HTMLExport);
0420 }
0421 void ActionsImpl::slotExportIE()
0422 {
0423     KEBApp::self()->bkInfo()->commitChanges();
0424     GlobalBookmarkManager::self()->doExport(GlobalBookmarkManager::IEExport);
0425 }
0426 void ActionsImpl::slotExportNS()
0427 {
0428     KEBApp::self()->bkInfo()->commitChanges();
0429     GlobalBookmarkManager::self()->doExport(GlobalBookmarkManager::NetscapeExport);
0430 }
0431 void ActionsImpl::slotExportMoz()
0432 {
0433     KEBApp::self()->bkInfo()->commitChanges();
0434     GlobalBookmarkManager::self()->doExport(GlobalBookmarkManager::MozillaExport);
0435 }
0436 
0437 /* -------------------------------------- */
0438 
0439 void ActionsImpl::slotCancelFavIconUpdates()
0440 {
0441     m_favIconHolder->cancelAllItrs();
0442 }
0443 
0444 void ActionsImpl::slotCancelAllTests()
0445 {
0446     m_testLinkHolder->cancelAllItrs();
0447 }
0448 
0449 void ActionsImpl::slotTestAll()
0450 {
0451     m_testLinkHolder->insertIterator(new TestLinkItr(m_testLinkHolder, KEBApp::self()->allBookmarks()));
0452 }
0453 
0454 void ActionsImpl::slotUpdateAllFavIcons()
0455 {
0456     m_favIconHolder->insertIterator(new FavIconsItr(m_favIconHolder, KEBApp::self()->allBookmarks()));
0457 }
0458 
0459 ActionsImpl::~ActionsImpl()
0460 {
0461     delete m_favIconHolder;
0462     delete m_testLinkHolder;
0463 }
0464 
0465 /* -------------------------------------- */
0466 
0467 void ActionsImpl::slotTestSelection()
0468 {
0469     KEBApp::self()->bkInfo()->commitChanges();
0470     m_testLinkHolder->insertIterator(new TestLinkItr(m_testLinkHolder, KEBApp::self()->selectedBookmarksExpanded()));
0471 }
0472 
0473 void ActionsImpl::slotUpdateFavIcon()
0474 {
0475     KEBApp::self()->bkInfo()->commitChanges();
0476     m_favIconHolder->insertIterator(new FavIconsItr(m_favIconHolder, KEBApp::self()->selectedBookmarksExpanded()));
0477 }
0478 
0479 /* -------------------------------------- */
0480 
0481 class KBookmarkGroupList : private KBookmarkGroupTraverser
0482 {
0483 public:
0484     KBookmarkGroupList(KBookmarkManager *);
0485     QList<KBookmark> getList(const KBookmarkGroup &);
0486 
0487 private:
0488     void visit(const KBookmark &) override
0489     {
0490     }
0491     void visitEnter(const KBookmarkGroup &) override;
0492     void visitLeave(const KBookmarkGroup &) override
0493     {
0494     }
0495 
0496 private:
0497     KBookmarkManager *m_manager;
0498     QList<KBookmark> m_list;
0499 };
0500 
0501 KBookmarkGroupList::KBookmarkGroupList(KBookmarkManager *manager)
0502 {
0503     m_manager = manager;
0504 }
0505 
0506 QList<KBookmark> KBookmarkGroupList::getList(const KBookmarkGroup &grp)
0507 {
0508     traverse(grp);
0509     return m_list;
0510 }
0511 
0512 void KBookmarkGroupList::visitEnter(const KBookmarkGroup &grp)
0513 {
0514     m_list << grp;
0515 }
0516 
0517 void ActionsImpl::slotRecursiveSort()
0518 {
0519     KEBApp::self()->bkInfo()->commitChanges();
0520     KBookmark bk = KEBApp::self()->firstSelected();
0521     Q_ASSERT(bk.isGroup());
0522     KEBMacroCommand *mcmd = new KEBMacroCommand(i18nc("(qtundo-format)", "Recursive Sort"));
0523     KBookmarkGroupList lister(GlobalBookmarkManager::self()->mgr());
0524     QList<KBookmark> bookmarks = lister.getList(bk.toGroup());
0525     bookmarks << bk.toGroup();
0526     for (QList<KBookmark>::ConstIterator it = bookmarks.constBegin(); it != bookmarks.constEnd(); ++it) {
0527         new SortCommand(m_model, QLatin1String(""), (*it).address(), mcmd);
0528     }
0529     commandHistory()->addCommand(mcmd);
0530 }
0531 
0532 void ActionsImpl::slotSort()
0533 {
0534     KEBApp::self()->bkInfo()->commitChanges();
0535     KBookmark bk = KEBApp::self()->firstSelected();
0536     Q_ASSERT(bk.isGroup());
0537     SortCommand *cmd = new SortCommand(m_model, i18nc("(qtundo-format)", "Sort Alphabetically"), bk.address());
0538     commandHistory()->addCommand(cmd);
0539 }
0540 
0541 /* -------------------------------------- */
0542 
0543 void ActionsImpl::slotDelete()
0544 {
0545     KEBApp::self()->bkInfo()->commitChanges();
0546     DeleteManyCommand *mcmd = new DeleteManyCommand(m_model, i18nc("(qtundo-format)", "Delete Items"), KEBApp::self()->selectedBookmarks());
0547     commandHistory()->addCommand(mcmd);
0548 }
0549 
0550 void ActionsImpl::slotOpenLink()
0551 {
0552     KEBApp::self()->bkInfo()->commitChanges();
0553     const QList<KBookmark> bookmarks = KEBApp::self()->selectedBookmarksExpanded();
0554     for (auto &bm : bookmarks) {
0555         if (bm.isGroup() || bm.isSeparator()) {
0556             continue;
0557         }
0558 
0559         auto *job = new KIO::OpenUrlJob(bm.url());
0560         job->setUiDelegate(KIO::createDefaultJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, KEBApp::self()));
0561         job->start();
0562     }
0563 }
0564 
0565 /* -------------------------------------- */
0566 
0567 void ActionsImpl::slotRename()
0568 {
0569     KEBApp::self()->bkInfo()->commitChanges();
0570     KEBApp::self()->startEdit(KEBApp::NameColumn);
0571 }
0572 
0573 void ActionsImpl::slotChangeURL()
0574 {
0575     KEBApp::self()->bkInfo()->commitChanges();
0576     KEBApp::self()->startEdit(KEBApp::UrlColumn);
0577 }
0578 
0579 void ActionsImpl::slotChangeComment()
0580 {
0581     KEBApp::self()->bkInfo()->commitChanges();
0582     KEBApp::self()->startEdit(KEBApp::CommentColumn);
0583 }
0584 
0585 void ActionsImpl::slotSetAsToolbar()
0586 {
0587     KEBApp::self()->bkInfo()->commitChanges();
0588     KBookmark bk = KEBApp::self()->firstSelected();
0589     Q_ASSERT(bk.isGroup());
0590     QUndoCommand *mcmd = CmdGen::setAsToolbar(m_model, bk);
0591     commandHistory()->addCommand(mcmd);
0592 }
0593 
0594 void ActionsImpl::slotChangeIcon()
0595 {
0596     KEBApp::self()->bkInfo()->commitChanges();
0597     KBookmark bk = KEBApp::self()->firstSelected();
0598     const QString newIcon = KIconDialog::getIcon(KIconLoader::Small, KIconLoader::Place, false, 0, false, KEBApp::self());
0599     if (newIcon.isEmpty())
0600         return;
0601     EditCommand *cmd = new EditCommand(m_model, bk.address(), -1, newIcon);
0602 
0603     commandHistory()->addCommand(cmd);
0604 }
0605 
0606 void ActionsImpl::slotExpandAll()
0607 {
0608     KEBApp::self()->expandAll();
0609 }
0610 
0611 void ActionsImpl::slotCollapseAll()
0612 {
0613     KEBApp::self()->collapseAll();
0614 }
0615 
0616 CommandHistory *ActionsImpl::commandHistory()
0617 {
0618     return m_model->commandHistory();
0619 }
0620 
0621 #include "moc_actionsimpl.cpp"