File indexing completed on 2023-09-24 09:52:44

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