]> git.sven.stormbind.net Git - sven/vym.git/blobdiff - src/imports.cpp
New upstream version 2.9.22
[sven/vym.git] / src / imports.cpp
diff --git a/src/imports.cpp b/src/imports.cpp
new file mode 100644 (file)
index 0000000..6da80ea
--- /dev/null
@@ -0,0 +1,205 @@
+#include "imports.h"
+
+#include "attributeitem.h"
+#include "branchitem.h"
+#include "file.h"
+#include "linkablemapobj.h"
+#include "mainwindow.h"
+#include "misc.h"
+#include "vymmodel.h"
+#include "xsltproc.h"
+
+#include <QMessageBox>
+
+extern Main *mainWindow;
+extern QDir vymBaseDir;
+
+ImportBase::ImportBase()
+{
+    model = NULL;
+    init();
+}
+
+ImportBase::ImportBase(VymModel *m)
+{
+    model = m;
+    init();
+}
+
+ImportBase::~ImportBase()
+{
+    // Remove tmpdir
+    removeDir(tmpDir);
+}
+
+void ImportBase::init() 
+{
+    bool ok;
+    tmpDir.setPath(makeTmpDir(ok, "vym-import"));
+    if (!tmpDir.exists() || !ok)
+        QMessageBox::critical(
+            0, QObject::tr("Error"),
+            QObject::tr("Couldn't access temporary directory\n"));
+}
+
+void ImportBase::setDir(const QString &p) { inputDir = p; }
+
+void ImportBase::setFile(const QString &p) { inputFile = p; }
+
+bool ImportBase::transform() { return true; }
+
+QString ImportBase::getTransformedFile() { return transformedFile; }
+
+/////////////////////////////////////////////////
+ImportFirefoxBookmarks::ImportFirefoxBookmarks(VymModel *m) : ImportBase(m) 
+{
+    totalBookmarks = currentBookmarks = 0;
+}
+
+bool ImportFirefoxBookmarks::transform()
+{
+    QStringList lines;
+    QFile file(inputFile);
+
+    progressDialog.setAutoReset(false);
+    progressDialog.setAutoClose(false);
+    progressDialog.setMinimumWidth(600);
+    progressDialog.setCancelButton(NULL);
+    progressDialog.setWindowTitle(QObject::tr("Import Firefox bookmarks","Import dialog"));
+    progressDialog.setLabelText(
+        QObject::tr("Loading bookmarks:", "Progress dialog while importing bookmarks"));
+
+    if (file.open(QIODevice::ReadOnly)) {
+        QJsonDocument jsdoc = QJsonDocument::fromJson(file.readAll());
+        file.close();
+
+        QJsonObject jsobj = jsdoc.object();
+
+        QJsonArray jsarr = jsobj["children"].toArray();
+        foreach (const QJsonValue &value, jsarr) {
+            parseJson (value, ParseMode::countBookmarks);
+        }
+
+        progressDialog.setRange(0, totalBookmarks);
+        progressDialog.setValue(1);
+        progressDialog.setWindowModality(Qt::WindowModal);
+        progressDialog.show();
+        QApplication::processEvents();
+
+        model->blockReposition();
+
+        parseJson (jsobj, ParseMode::buildMap);
+        
+        model->unblockReposition();
+
+        mainWindow->statusMessage(
+                QObject::tr("Imported %1 bookmarks", "Import dialog").arg(totalBookmarks));
+    }
+
+    return false;
+}
+
+bool ImportFirefoxBookmarks::parseJson(QJsonValue jsval, ParseMode mode, BranchItem *selbi)
+{
+    if (!selbi) {
+        selbi = model->getSelectedBranch();
+        if (!selbi) {
+            qWarning() << "ImportFirefoxBookmarks: No branch selected!";
+            return false;
+        }
+    }
+
+    QJsonObject jsobj = jsval.toObject();
+
+    if (mode == countBookmarks) {
+        // Count bookmarks 
+        if (jsobj.contains("uri") && jsobj["uri"].isString())
+            totalBookmarks++;
+    } else {
+        // Build map
+        selbi = model->addNewBranch(selbi);
+        selbi->setHeadingPlainText(jsobj["title"].toString());
+
+        if (jsobj.contains("uri") && jsobj["uri"].isString()) {
+            currentBookmarks++;
+            progressDialog.setValue(currentBookmarks);
+            selbi->setURL(jsobj["uri"].toString());
+        }
+
+        AttributeItem *ai;
+
+        foreach (QString key, jsobj.keys())
+        {
+            if (key != "children") {
+                ai = new AttributeItem();
+                ai->setKey(key);
+                // Integer types: dateAdded, id, index, lastModified, typeCode
+                // Special: postData
+                if (key == "dateAdded" || key == "lastModified") {
+                    qlonglong l = jsobj[key].toVariant().toLongLong();
+                    QDateTime dt;
+                    dt.setMSecsSinceEpoch(l / 1000);
+                    ai->setValue(dt);
+                    ai->setAttributeType(AttributeItem::DateTime);
+                } else if (key == "id" || key == "index" || 
+                        key == "lastModified" || key == "typeCode" ) {
+                    ai->setValue(jsobj[key].toInt());
+                } else if (key == "postData") 
+                    ai->setValue(QString("null"));
+                else if (jsobj[key].isString()) 
+                    ai->setValue(jsobj[key].toString());
+                else {
+                // Ignore only the "postdata: null" field for now
+                    qWarning() << "Firefox import, unknown key type: " << jsobj[key].type();
+                    qDebug() << "                Firefox bookmark: " << key << jsobj[key].toString();
+                    ai->setValue(QString("unknown type."));
+                }
+
+                model->setAttribute(selbi, ai); // FIXME-3 deep copy?
+            }
+        }
+
+        model->emitDataChanged(selbi); // FIXME-2 required, but can reposition in between be blocked?
+    } // build bookmakrs
+
+    if (jsobj.contains("children") && jsobj["children"].isArray()) {
+
+        QJsonArray jsarr = jsobj["children"].toArray();
+        foreach (const QJsonValue &val, jsarr) {
+            parseJson (val, mode, selbi);
+        }
+
+        if (selbi->depth() > 2) {
+            selbi->scroll();
+            model->emitDataChanged(selbi); // FIXME-2 required, but can reposition in between be blocked?
+        }
+    } 
+
+    return true;
+}
+   
+/////////////////////////////////////////////////
+bool ImportMM::transform()
+{
+    // try to unzip
+    if (File::Success == unzipDir(tmpDir, inputFile)) {
+
+        // Set short name, too. Search from behind:
+        transformedFile = inputFile;
+        int i = transformedFile.lastIndexOf("/");
+        if (i >= 0)
+            transformedFile = transformedFile.remove(0, i + 1);
+        transformedFile.replace(".mmap", ".xml");
+        transformedFile = tmpDir.path() + "/" + transformedFile;
+
+        XSLTProc p;
+        p.setInputFile(tmpDir.path() + "/Document.xml");
+        p.setOutputFile(transformedFile);
+        p.setXSLFile(vymBaseDir.path() + "/styles/mmap2vym.xsl");
+        p.process();
+
+        return true;
+    }
+    else
+        return false;
+}