Warning, file /utilities/keditbookmarks/src/main.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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 or at your option version 3 as published by
0010    the Free Software Foundation.
0011 
0012    This program is distributed in the hope that it will be useful,
0013    but WITHOUT ANY WARRANTY; without even the implied warranty of
0014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015    General Public License for more details.
0016 
0017    You should have received a copy of the GNU General Public License
0018    along with this program; see the file COPYING.  If not, write to
0019    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0020    Boston, MA 02110-1301, USA.
0021 */
0022 
0023 #include "config-keditbookmarks.h"
0024 #include "globalbookmarkmanager.h"
0025 #include "importers.h"
0026 #include "kbookmarkmodel/commandhistory.h"
0027 #include "keditbookmarks_version.h"
0028 #include "toplevel.h"
0029 
0030 #include "keditbookmarks_debug.h"
0031 #include <QApplication>
0032 #include <QCommandLineOption>
0033 #include <QCommandLineParser>
0034 
0035 #include <KAboutData>
0036 
0037 #include <KMessageBox>
0038 #include <KWindowSystem>
0039 #include <kwindowsystem_version.h>
0040 #if HAVE_X11
0041 #include <KX11Extras>
0042 #endif
0043 #include <KBookmarkManager>
0044 #include <QStandardPaths>
0045 #include <kbookmarkexporter.h>
0046 #include <kwidgetsaddons_version.h>
0047 #include <toplevel_interface.h>
0048 
0049 // TODO - make this register() or something like that and move dialog into main
0050 static bool askUser(const QString &filename, bool &readonly)
0051 {
0052     QString interfaceName = QStringLiteral("org.kde.keditbookmarks");
0053     QString appId = interfaceName + QLatin1Char('-') + QString().setNum(QApplication::applicationPid());
0054 
0055     QDBusConnection dbus = QDBusConnection::sessionBus();
0056     QDBusReply<QStringList> reply = dbus.interface()->registeredServiceNames();
0057     if (!reply.isValid())
0058         return true;
0059     const QStringList allServices = reply;
0060     for (QStringList::const_iterator it = allServices.begin(), end = allServices.end(); it != end; ++it) {
0061         const QString service = *it;
0062         if (service.startsWith(interfaceName) && service != appId) {
0063             org::kde::keditbookmarks keditbookmarks(service, QStringLiteral("/keditbookmarks"), dbus);
0064             QDBusReply<QString> bookmarks = keditbookmarks.bookmarkFilename();
0065             QString name;
0066             if (bookmarks.isValid())
0067                 name = bookmarks;
0068             if (name == filename) {
0069                 int ret = KMessageBox::warningTwoActions(nullptr,
0070                                                          i18n("Another instance of %1 is already running. Do you really "
0071                                                               "want to open another instance or continue work in the same instance?\n"
0072                                                               "Please note that, unfortunately, duplicate views are read-only.",
0073                                                               QGuiApplication::applicationDisplayName()),
0074                                                          i18nc("@title:window", "Warning"),
0075                                                          KGuiItem(i18n("Run Another")), /* yes */
0076                                                          KGuiItem(i18n("Continue in Same")) /*  no */);
0077                 if (ret == KMessageBox::ButtonCode::SecondaryAction) {
0078                     QDBusInterface keditinterface(service, QStringLiteral("/keditbookmarks/MainWindow_1"));
0079                     // TODO fix me
0080                     QDBusReply<qlonglong> value = keditinterface.call(QDBus::NoBlock, QStringLiteral("winId"));
0081                     qlonglong id = 0;
0082                     if (value.isValid())
0083                         id = value;
0084                         ////qCDebug(KEDITBOOKMARKS_LOG)<<" id !!!!!!!!!!!!!!!!!!! :"<<id;
0085 #if HAVE_X11
0086                     KX11Extras::activateWindow((WId)id);
0087 #endif
0088                     return false;
0089                 } else if (ret == KMessageBox::ButtonCode::PrimaryAction) {
0090                     readonly = true;
0091                 }
0092             }
0093         }
0094     }
0095     return true;
0096 }
0097 
0098 int main(int argc, char **argv)
0099 {
0100     QApplication app(argc, argv);
0101 
0102     KLocalizedString::setApplicationDomain(QByteArrayLiteral("keditbookmarks"));
0103 
0104     KAboutData aboutData(QStringLiteral("keditbookmarks"),
0105                          i18n("Bookmark Editor"),
0106                          QStringLiteral(KEDITBOOKMARKS_VERSION_STRING),
0107                          i18n("Bookmark Organizer and Editor"),
0108                          KAboutLicense::GPL,
0109                          i18n("Copyright 2000-2023, KDE developers"));
0110     aboutData.addAuthor(i18n("David Faure"), i18n("Initial author"), QStringLiteral("faure@kde.org"));
0111     aboutData.addAuthor(i18n("Alexander Kellett"), i18n("Author"), QStringLiteral("lypanov@kde.org"));
0112 
0113     aboutData.setDesktopFileName(QStringLiteral("org.kde.keditbookmarks"));
0114     KAboutData::setApplicationData(aboutData);
0115 
0116     app.setWindowIcon(QIcon::fromTheme(QStringLiteral("bookmarks-organize")));
0117 
0118     QCommandLineParser parser;
0119     parser.setApplicationDescription(aboutData.shortDescription());
0120     // clang-format off
0121     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("importmoz"), i18n("Import bookmarks from a file in Mozilla format"), QStringLiteral("filename")));
0122     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("importns"), i18n("Import bookmarks from a file in Netscape (4.x and earlier) format"), QStringLiteral("filename")));
0123     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("importie"), i18n("Import bookmarks from a file in Internet Explorer's Favorites format"), QStringLiteral("filename")));
0124     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("importopera"), i18n("Import bookmarks from a file in Opera format"), QStringLiteral("filename")));
0125     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("importkde3"), i18n("Import bookmarks from a file in KDE2 format"), QStringLiteral("filename")));
0126     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("importgaleon"), i18n("Import bookmarks from a file in Galeon format"), QStringLiteral("filename")));
0127     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("exportmoz"), i18n("Export bookmarks to a file in Mozilla format"), QStringLiteral("filename")));
0128     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("exportns"), i18n("Export bookmarks to a file in Netscape (4.x and earlier) format"), QStringLiteral("filename")));
0129     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("exporthtml"), i18n("Export bookmarks to a file in a printable HTML format"), QStringLiteral("filename")));
0130     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("exportie"), i18n("Export bookmarks to a file in Internet Explorer's Favorites format"), QStringLiteral("filename")));
0131     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("exportopera"), i18n("Export bookmarks to a file in Opera format"), QStringLiteral("filename")));
0132     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("address"), i18n("Open at the given position in the bookmarks file"), QStringLiteral("address")));
0133     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("customcaption"), i18n("Set the user-readable caption, for example \"Konsole\""), QStringLiteral("caption")));
0134     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("nobrowser"), i18n("Hide all browser related functions")));
0135     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("dbusObjectName"), i18n("A unique name that represents this bookmark collection, usually the kinstance name.\n"
0136                                  "This should be \"konqueror\" for the Konqueror bookmarks, \"kfile\" for KFileDialog bookmarks, etc.\n"
0137                                  "The final D-Bus object path is /KBookmarkManager/<dbusObjectName>"), QStringLiteral("name")));
0138     // clang-format on
0139     parser.addPositionalArgument(QStringLiteral("[file]"), i18n("File to edit"));
0140 
0141     aboutData.setupCommandLine(&parser);
0142     parser.process(app);
0143     aboutData.processCommandLine(&parser);
0144 
0145     const bool isGui = !(parser.isSet(QStringLiteral("exportmoz")) || parser.isSet(QStringLiteral("exportns")) || parser.isSet(QStringLiteral("exporthtml")) //
0146                          || parser.isSet(QStringLiteral("exportie")) || parser.isSet(QStringLiteral("exportopera")) //
0147                          || parser.isSet(QStringLiteral("importmoz")) || parser.isSet(QStringLiteral("importns")) //
0148                          || parser.isSet(QStringLiteral("importie")) || parser.isSet(QStringLiteral("importopera")) //
0149                          || parser.isSet(QStringLiteral("importkde3")) || parser.isSet(QStringLiteral("importgaleon")));
0150 
0151     const bool browser = !parser.isSet(QStringLiteral("nobrowser"));
0152     const bool gotFilenameArg = (parser.positionalArguments().count() == 1);
0153 
0154     if (!gotFilenameArg) {
0155         const QString location = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/konqueror/");
0156         QDir().mkpath(location);
0157     }
0158 
0159     QString filename = gotFilenameArg ? parser.positionalArguments().at(0)
0160                                       : QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/konqueror/bookmarks.xml");
0161 
0162     if (!isGui) {
0163         GlobalBookmarkManager::self()->createManager(filename, QString(), new CommandHistory());
0164         GlobalBookmarkManager::ExportType exportType = GlobalBookmarkManager::MozillaExport; // uumm.. can i just set it to -1 ?
0165         int got = 0;
0166         QString arg;
0167         QString arg2;
0168         QString importType;
0169         if (arg = QStringLiteral("exportmoz"), parser.isSet(arg)) {
0170             exportType = GlobalBookmarkManager::MozillaExport;
0171             arg2 = arg;
0172             got++;
0173         }
0174         if (arg = QStringLiteral("exportns"), parser.isSet(arg)) {
0175             exportType = GlobalBookmarkManager::NetscapeExport;
0176             arg2 = arg;
0177             got++;
0178         }
0179         if (arg = QStringLiteral("exporthtml"), parser.isSet(arg)) {
0180             exportType = GlobalBookmarkManager::HTMLExport;
0181             arg2 = arg;
0182             got++;
0183         }
0184         if (arg = QStringLiteral("exportie"), parser.isSet(arg)) {
0185             exportType = GlobalBookmarkManager::IEExport;
0186             arg2 = arg;
0187             got++;
0188         }
0189         if (arg = QStringLiteral("exportopera"), parser.isSet(arg)) {
0190             exportType = GlobalBookmarkManager::OperaExport;
0191             arg2 = arg;
0192             got++;
0193         }
0194         if (arg = QStringLiteral("importmoz"), parser.isSet(arg)) {
0195             importType = QStringLiteral("Moz");
0196             arg2 = arg;
0197             got++;
0198         }
0199         if (arg = QStringLiteral("importns"), parser.isSet(arg)) {
0200             importType = QStringLiteral("NS");
0201             arg2 = arg;
0202             got++;
0203         }
0204         if (arg = QStringLiteral("importie"), parser.isSet(arg)) {
0205             importType = QStringLiteral("IE");
0206             arg2 = arg;
0207             got++;
0208         }
0209         if (arg = QStringLiteral("importopera"), parser.isSet(arg)) {
0210             importType = QStringLiteral("Opera");
0211             arg2 = arg;
0212             got++;
0213         }
0214         if (arg = QStringLiteral("importgaleon"), parser.isSet(arg)) {
0215             importType = QStringLiteral("Galeon");
0216             arg2 = arg;
0217             got++;
0218         }
0219         if (arg = QStringLiteral("importkde3"), parser.isSet(arg)) {
0220             importType = QStringLiteral("KDE2");
0221             arg2 = arg;
0222             got++;
0223         }
0224         if (importType.isEmpty() && !arg2.isEmpty()) {
0225             // TODO - maybe an xbel export???
0226             if (got > 1) { // got == 0 isn't possible as !isGui is dependent on "export.*"
0227                 qCWarning(KEDITBOOKMARKS_LOG) << i18n("You may only specify a single --export option.");
0228                 return 1;
0229             }
0230             QString path = parser.value(arg2);
0231             GlobalBookmarkManager::self()->doExport(exportType, path);
0232         } else if (!importType.isEmpty()) {
0233             if (got > 1) { // got == 0 isn't possible as !isGui is dependent on "import.*"
0234                 qCWarning(KEDITBOOKMARKS_LOG) << i18n("You may only specify a single --import option.");
0235                 return 1;
0236             }
0237             QString path = parser.value(arg2);
0238             KBookmarkModel *model = GlobalBookmarkManager::self()->model();
0239             ImportCommand *importer = ImportCommand::importerFactory(model, importType);
0240             importer->import(path, true);
0241             importer->redo();
0242             GlobalBookmarkManager::self()->managerSave();
0243             GlobalBookmarkManager::self()->notifyManagers();
0244         }
0245         return 0; // error flag on exit?, 1?
0246     }
0247 
0248     QString address = parser.isSet(QStringLiteral("address")) ? parser.value(QStringLiteral("address")) : QStringLiteral("/0");
0249 
0250     QString caption = parser.isSet(QStringLiteral("customcaption")) ? parser.value(QStringLiteral("customcaption")) : QString();
0251 
0252     QString dbusObjectName;
0253     if (parser.isSet(QStringLiteral("dbusObjectName"))) {
0254         dbusObjectName = parser.value(QStringLiteral("dbusObjectName"));
0255     } else {
0256         if (gotFilenameArg)
0257             dbusObjectName = QString();
0258         else
0259             dbusObjectName = QStringLiteral("konqueror");
0260     }
0261 
0262     bool readonly = false; // passed by ref
0263 
0264     if (askUser((gotFilenameArg ? filename : QString()), readonly)) {
0265         KEBApp *toplevel = new KEBApp(filename, readonly, address, browser, caption, dbusObjectName);
0266         toplevel->setAttribute(Qt::WA_DeleteOnClose);
0267         toplevel->show();
0268         return app.exec();
0269     }
0270 
0271     return 0;
0272 }