File indexing completed on 2024-04-21 14:53:28

0001 //  -*- c-basic-offset:4; indent-tabs-mode:nil -*-
0002 /*
0003     This file is part of the KDE libraries
0004     SPDX-FileCopyrightText: 2002-2003 Alexander Kellett <lypanov@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-only
0007 */
0008 
0009 #include "kbookmarkimporter_opera.h"
0010 #include "kbookmarkimporter.h"
0011 #include "kbookmarkimporter_opera_p.h"
0012 #include "kbookmarks_debug.h"
0013 
0014 #include <QApplication>
0015 #include <QFileDialog>
0016 
0017 #include <qplatformdefs.h>
0018 
0019 
0020 void KOperaBookmarkImporter::parseOperaBookmarks()
0021 {
0022     QFile file(m_fileName);
0023     if (!file.open(QIODevice::ReadOnly)) {
0024         return;
0025     }
0026 
0027     QString url;
0028     QString name;
0029     QString type;
0030     int lineno = 0;
0031     QTextStream stream(&file);
0032 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0033     stream.setCodec("UTF-8");
0034 #endif
0035     while (!stream.atEnd()) {
0036         lineno++;
0037         QString line = stream.readLine().trimmed();
0038 
0039         // first two headers lines contain details about the format
0040         if (lineno <= 2) {
0041             if (line.startsWith(QLatin1String("options:"), Qt::CaseInsensitive)) {
0042                 const auto lst = line.mid(8).split(QLatin1Char(','));
0043                 for (const QString &ba : lst) {
0044                     const int pos = ba.indexOf(QLatin1Char('='));
0045                     if (pos < 1) {
0046                         continue;
0047                     }
0048                 }
0049             }
0050             continue;
0051         }
0052 
0053         // at least up till version<=3 the following is valid
0054         if (line.isEmpty()) {
0055             // end of data block
0056             if (type.isNull()) {
0057                 continue;
0058             } else if (type == QLatin1String("URL")) {
0059                 Q_EMIT newBookmark(name, url, QLatin1String(""));
0060             } else if (type == QLatin1String("FOLDER")) {
0061                 Q_EMIT newFolder(name, false, QLatin1String(""));
0062             }
0063 
0064             type.clear();
0065             name.clear();
0066             url.clear();
0067         } else if (line == QLatin1String("-")) {
0068             // end of folder
0069             Q_EMIT endFolder();
0070         } else {
0071             // data block line
0072             QString tag;
0073             if (tag = QStringLiteral("#"), line.startsWith(tag)) {
0074                 type = line.remove(0, tag.length());
0075             } else if (tag = QStringLiteral("NAME="), line.startsWith(tag)) {
0076                 name = line.remove(0, tag.length());
0077             } else if (tag = QStringLiteral("URL="), line.startsWith(tag)) {
0078                 url = line.remove(0, tag.length());
0079             }
0080         }
0081     }
0082 }
0083 
0084 QString KOperaBookmarkImporter::operaBookmarksFile()
0085 {
0086     static KOperaBookmarkImporterImpl *p = nullptr;
0087     if (!p) {
0088         p = new KOperaBookmarkImporterImpl;
0089     }
0090     return p->findDefaultLocation();
0091 }
0092 
0093 void KOperaBookmarkImporterImpl::parse()
0094 {
0095     KOperaBookmarkImporter importer(m_fileName);
0096     setupSignalForwards(&importer, this);
0097     importer.parseOperaBookmarks();
0098 }
0099 
0100 QString KOperaBookmarkImporterImpl::findDefaultLocation(bool saving) const
0101 {
0102     const QString operaHomePath = QDir::homePath() + QLatin1String("/.opera");
0103     return saving ? QFileDialog::getSaveFileName(QApplication::activeWindow(), QString(), operaHomePath, tr("Opera Bookmark Files (*.adr)"))
0104                   : QFileDialog::getOpenFileName(QApplication::activeWindow(), QString(), operaHomePath, tr("*.adr|Opera Bookmark Files (*.adr)"));
0105 }
0106 
0107 /////////////////////////////////////////////////
0108 
0109 class OperaExporter : private KBookmarkGroupTraverser
0110 {
0111 public:
0112     OperaExporter();
0113     QString generate(const KBookmarkGroup &grp)
0114     {
0115         traverse(grp);
0116         return m_string;
0117     }
0118 
0119 private:
0120     void visit(const KBookmark &) override;
0121     void visitEnter(const KBookmarkGroup &) override;
0122     void visitLeave(const KBookmarkGroup &) override;
0123 
0124 private:
0125     QString m_string;
0126     QTextStream m_out;
0127 };
0128 
0129 OperaExporter::OperaExporter()
0130     : m_out(&m_string, QIODevice::WriteOnly)
0131 {
0132     m_out << "Opera Hotlist version 2.0\n";
0133     m_out << "Options: encoding = utf8, version=3\n";
0134     m_out.flush();
0135 }
0136 
0137 void OperaExporter::visit(const KBookmark &bk)
0138 {
0139     // qCDebug(KBOOKMARKS_LOG) << "visit(" << bk.text() << ")";
0140     m_out << "#URL\n";
0141     m_out << "\tNAME=" << bk.fullText() << '\n';
0142     m_out << "\tURL=" << bk.url().toString().toUtf8() << '\n';
0143     m_out << '\n';
0144     m_out.flush();
0145 }
0146 
0147 void OperaExporter::visitEnter(const KBookmarkGroup &grp)
0148 {
0149     // qCDebug(KBOOKMARKS_LOG) << "visitEnter(" << grp.text() << ")";
0150     m_out << "#FOLDER\n";
0151     m_out << "\tNAME=" << grp.fullText() << '\n';
0152     m_out << '\n';
0153     m_out.flush();
0154 }
0155 
0156 void OperaExporter::visitLeave(const KBookmarkGroup &)
0157 {
0158     // qCDebug(KBOOKMARKS_LOG) << "visitLeave()";
0159     m_out << "-\n";
0160     m_out << '\n';
0161     m_out.flush();
0162 }
0163 
0164 void KOperaBookmarkExporterImpl::write(const KBookmarkGroup &parent)
0165 {
0166     OperaExporter exporter;
0167     QString content = exporter.generate(parent);
0168     QFile file(m_fileName);
0169     if (!file.open(QIODevice::WriteOnly)) {
0170         qCCritical(KBOOKMARKS_LOG) << "Can't write to file " << m_fileName;
0171         return;
0172     }
0173     QTextStream fstream(&file);
0174 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0175     fstream.setCodec("UTF-8");
0176 #endif
0177     fstream << content;
0178 }
0179 
0180 #include "moc_kbookmarkimporter_opera.cpp"
0181 #include "moc_kbookmarkimporter_opera_p.cpp"