diff -r 880d3fe9ac7c -r 4a95c6b06ebe src/documentloader.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/documentloader.cpp Sun Sep 06 01:22:25 2015 +0300
@@ -0,0 +1,160 @@
+/*
+ * LDForge: LDraw parts authoring CAD
+ * Copyright (C) 2013 - 2015 Teemu Piippo
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include "documentloader.h"
+#include "ldDocument.h"
+#include "ldObject.h"
+#include "mainwindow.h"
+#include "dialogs/openprogressdialog.h"
+
+DocumentLoader::DocumentLoader (bool onForeground, QObject *parent) :
+ QObject (parent),
+ m_warningCount (0),
+ m_isDone (false),
+ m_hasAborted (false),
+ m_isOnForeground (onForeground) {}
+
+bool DocumentLoader::hasAborted()
+{
+ return m_hasAborted;
+}
+
+bool DocumentLoader::isDone() const
+{
+ return m_isDone;
+}
+
+int DocumentLoader::progress() const
+{
+ return m_progress;
+}
+
+int DocumentLoader::warningCount() const
+{
+ return m_warningCount;
+}
+
+bool DocumentLoader::isOnForeground() const
+{
+ return m_isOnForeground;
+}
+
+const LDObjectList& DocumentLoader::objects() const
+{
+ return m_objects;
+}
+
+void DocumentLoader::read (QIODevice* fp)
+{
+ if (fp and fp->isOpen())
+ {
+ while (not fp->atEnd())
+ m_lines << QString::fromUtf8 (fp->readLine());
+ }
+}
+
+void DocumentLoader::start()
+{
+ m_isDone = false;
+ m_progress = 0;
+ m_hasAborted = false;
+
+ if (isOnForeground())
+ {
+ // Show a progress dialog if we're loading the main ldDocument.here so we can show progress updates and keep the
+ // WM posted that we're still here.
+ m_progressDialog = new OpenProgressDialog (g_win);
+ m_progressDialog->setNumLines (m_lines.size());
+ m_progressDialog->setModal (true);
+ m_progressDialog->show();
+ connect (this, SIGNAL (workDone()), m_progressDialog, SLOT (accept()));
+ connect (m_progressDialog, SIGNAL (rejected()), this, SLOT (abort()));
+ }
+ else
+ m_progressDialog = null;
+
+ // Begin working
+ work (0);
+}
+
+void DocumentLoader::work (int i)
+{
+ // User wishes to abort, so stop here now.
+ if (hasAborted())
+ {
+ for (LDObject* obj : m_objects)
+ obj->destroy();
+
+ m_objects.clear();
+ m_isDone = true;
+ return;
+ }
+
+ // Parse up to 200 lines per iteration
+ int max = i + 200;
+
+ for (; i < max and i < (int) m_lines.size(); ++i)
+ {
+ QString line = m_lines[i];
+
+ // Trim the trailing newline
+ while (line.endsWith ("\n") or line.endsWith ("\r"))
+ line.chop (1);
+
+ LDObject* obj = ParseLine (line);
+
+ // Check for parse errors and warn about them
+ if (obj->type() == OBJ_Error)
+ {
+ print ("Couldn't parse line #%1: %2", progress() + 1, static_cast (obj)->reason());
+ ++m_warningCount;
+ }
+
+ m_objects << obj;
+ }
+
+ m_progress = i;
+
+ if (m_progressDialog)
+ m_progressDialog->setProgress (i);
+
+ if (i >= m_lines.size() - 1)
+ {
+ emit workDone();
+ m_isDone = true;
+ }
+ else
+ {
+ // If we have a dialog to show progress output to, we cannot just call work() again immediately as the dialog
+ // needs to be updated as well. Thus, we take a detour through the event loop by using the meta-object system.
+ //
+ // This terminates the loop here and control goes back to the function which called the file loader. It will
+ // keep processing the event loop until we're ready (see loadFileContents), thus the event loop will eventually
+ // catch the invokation we throw here and send us back.
+ if (isOnForeground())
+ QMetaObject::invokeMethod (this, "work", Qt::QueuedConnection, Q_ARG (int, i));
+ else
+ work (i);
+ }
+}
+
+void DocumentLoader::abort()
+{
+ m_hasAborted = true;
+}
\ No newline at end of file