Mon, 02 Jun 2014 12:50:40 +0300
- made LDDocument use shared pointers, this eliminates a lot of document-related crashes
--- a/src/actions.cc Sun Jun 01 03:15:36 2014 +0300 +++ b/src/actions.cc Mon Jun 02 12:50:40 2014 +0300 @@ -149,13 +149,8 @@ // DEFINE_ACTION (SaveAll, CTRL (L)) { - for (LDDocument* file : g_loadedFiles) - { - if (file->isImplicit()) - continue; - + for (LDDocumentPtr file : LDDocument::explicitDocuments()) save (file, false); - } } // ============================================================================= @@ -165,7 +160,7 @@ if (not getCurrentDocument()->isSafeToClose()) return; - delete getCurrentDocument(); + getCurrentDocument()->dismiss(); } // ============================================================================= @@ -626,7 +621,7 @@ // these is an immense pain. DEFINE_ACTION (testpic, "Test picture", "", "", (0)) { - LDDocument* file = getFile ("axle.dat"); + LDDocumentPtr file = getFile ("axle.dat"); setlocale (LC_ALL, "C"); if (not file) @@ -827,7 +822,7 @@ code << obj->asText(); // Create the new subfile document - LDDocument* doc = new LDDocument; + LDDocumentPtr doc = LDDocument::createNew(); doc->setImplicit (false); doc->setFullPath (fullsubname); doc->setName (LDDocument::shortenName (fullsubname)); @@ -862,8 +857,6 @@ for (LDObjectPtr obj : selection()) obj->destroy(); - g_loadedFiles << doc; - // Add a reference to the new subfile to where the selection was LDSubfilePtr ref (spawn<LDSubfile>()); ref->setColor (maincolor); @@ -879,7 +872,7 @@ else { // Failed to save. - delete doc; + doc->dismiss(); } }
--- a/src/addObjectDialog.cc Sun Jun 01 03:15:36 2014 +0300 +++ b/src/addObjectDialog.cc Mon Jun 02 12:50:40 2014 +0300 @@ -410,7 +410,7 @@ if (name.length() == 0) return; // no subfile filename - LDDocument* file = getDocument (name); + LDDocumentPtr file = getDocument (name); if (not file) {
--- a/src/basics.h Sun Jun 01 03:15:36 2014 +0300 +++ b/src/basics.h Mon Jun 02 12:50:40 2014 +0300 @@ -29,6 +29,7 @@ class QFile; class QTextStream; class Matrix; +class LDDocument; using int8 = qint8; using int16 = qint16; @@ -43,6 +44,8 @@ using LDObjectList = QList<LDObjectPtr>; using LDObjectWeakPtr = QWeakPointer<LDObject>; using LDObjectWeakList = QList<LDObjectWeakPtr>; +using LDDocumentPtr = QSharedPointer<LDDocument>; +using LDDocumentWeakPtr = QWeakPointer<LDDocument>; template<typename T, typename R> using Pair = std::pair<T, R>;
--- a/src/editHistory.cc Sun Jun 01 03:15:36 2014 +0300 +++ b/src/editHistory.cc Mon Jun 02 12:50:40 2014 +0300 @@ -130,7 +130,7 @@ // void AddHistory::undo() const { - LDObjectPtr obj = parent()->document()->getObject (index()); + LDObjectPtr obj = parent()->document().toStrongRef()->getObject (index()); obj->destroy(); } @@ -139,7 +139,7 @@ void AddHistory::redo() const { LDObjectPtr obj = parseLine (code()); - parent()->document()->insertObj (index(), obj); + parent()->document().toStrongRef()->insertObj (index(), obj); g_win->R()->compileObject (obj); } @@ -155,7 +155,7 @@ void DelHistory::undo() const { LDObjectPtr obj = parseLine (code()); - parent()->document()->insertObj (index(), obj); + parent()->document().toStrongRef()->insertObj (index(), obj); g_win->R()->compileObject (obj); } @@ -163,7 +163,7 @@ // void DelHistory::redo() const { - LDObjectPtr obj = parent()->document()->getObject (index()); + LDObjectPtr obj = parent()->document().toStrongRef()->getObject (index()); obj->destroy(); }
--- a/src/editHistory.h Sun Jun 01 03:15:36 2014 +0300 +++ b/src/editHistory.h Mon Jun 02 12:50:40 2014 +0300 @@ -40,9 +40,9 @@ // ============================================================================= class History { - PROPERTY (private, int, position, setPosition, STOCK_WRITE) - PROPERTY (public, LDDocument*, document, setDocument, STOCK_WRITE) - PROPERTY (public, bool, isIgnoring, setIgnoring, STOCK_WRITE) + PROPERTY (private, int, position, setPosition, STOCK_WRITE) + PROPERTY (public, LDDocumentWeakPtr, document, setDocument, STOCK_WRITE) + PROPERTY (public, bool, isIgnoring, setIgnoring, STOCK_WRITE) public: typedef QList<AbstractHistoryEntry*> Changeset;
--- a/src/format.h Sun Jun 01 03:15:36 2014 +0300 +++ b/src/format.h Mon Jun 02 12:50:40 2014 +0300 @@ -47,6 +47,18 @@ } template<typename T> + StringFormatArg (QSharedPointer<T> const& a) + { + m_text.sprintf ("%p", a.data()); + } + + template<typename T> + StringFormatArg (QWeakPointer<T> const& a) + { + m_text.sprintf ("%p", a.data()); + } + + template<typename T> StringFormatArg (const QList<T>& a) { m_text = "{";
--- a/src/glCompiler.cc Sun Jun 01 03:15:36 2014 +0300 +++ b/src/glCompiler.cc Mon Jun 02 12:50:40 2014 +0300 @@ -243,7 +243,7 @@ // ============================================================================= // -void GLCompiler::compileDocument (LDDocument* doc) +void GLCompiler::compileDocument (LDDocumentPtr doc) { if (doc == null) return; @@ -278,7 +278,9 @@ for (auto it = m_objectInfo.begin(); it != m_objectInfo.end(); ++it) { - if (it.key()->document() == getCurrentDocument() && not it.key()->isHidden()) + if (it.key() == null) + it = m_objectInfo.erase (it); + elif (it.key().toStrongRef()->document() == getCurrentDocument() && not it.key().toStrongRef()->isHidden()) vbodata += it->data[vbonum]; } @@ -311,7 +313,7 @@ { // print ("Compile %1\n", g_objectOrigins[obj]); - if (obj == null || obj->document() == null || obj->document()->isImplicit()) + if (obj == null || obj->document() == null || obj->document().toStrongRef()->isImplicit()) return; ObjectVBOInfo info;
--- a/src/glCompiler.h Sun Jun 01 03:15:36 2014 +0300 +++ b/src/glCompiler.h Mon Jun 02 12:50:40 2014 +0300 @@ -35,7 +35,7 @@ GLCompiler (GLRenderer* renderer); ~GLCompiler(); - void compileDocument (LDDocument* doc); + void compileDocument (LDDocumentPtr doc); void dropObject (LDObjectPtr obj); void initialize(); QColor getColorForPolygon (LDPolygon& poly, LDObjectPtr topobj, @@ -68,12 +68,12 @@ void compileObject (LDObjectPtr obj); void compilePolygon (LDPolygon& poly, LDObjectPtr topobj, GLCompiler::ObjectVBOInfo* objinfo); - QMap<LDObjectPtr, ObjectVBOInfo> m_objectInfo; - LDObjectWeakList m_staged; // Objects that need to be compiled - GLuint m_vbo[g_numVBOs]; - bool m_vboChanged[g_numVBOs]; - int m_vboSizes[g_numVBOs]; - GLRenderer* const m_renderer; + QMap<LDObjectWeakPtr, ObjectVBOInfo> m_objectInfo; + LDObjectWeakList m_staged; // Objects that need to be compiled + GLuint m_vbo[g_numVBOs]; + bool m_vboChanged[g_numVBOs]; + int m_vboSizes[g_numVBOs]; + GLRenderer* const m_renderer; }; #define checkGLError() { checkGLError_private (__FILE__, __LINE__); }
--- a/src/glRenderer.cc Sun Jun 01 03:15:36 2014 +0300 +++ b/src/glRenderer.cc Mon Jun 02 12:50:40 2014 +0300 @@ -119,7 +119,6 @@ m_rectdraw = false; m_panning = false; m_compiler = new GLCompiler (this); - setDocument (null); setDrawOnly (false); setMessageLog (null); m_width = m_height = -1; @@ -1371,7 +1370,7 @@ // ============================================================================= // -void GLRenderer::setDocument (LDDocument* const& a) +void GLRenderer::setDocument (LDDocumentPtr const& a) { m_document = a; @@ -1500,7 +1499,7 @@ const int segs = g_lores, divs = g_lores; // TODO: make customizable double dist0 = getCircleDrawDist (0), dist1 = getCircleDrawDist (1); - LDDocument* refFile = null; + LDDocumentPtr refFile; Matrix transform; bool circleOrDisc = false;
--- a/src/glRenderer.h Sun Jun 01 03:15:36 2014 +0300 +++ b/src/glRenderer.h Mon Jun 02 12:50:40 2014 +0300 @@ -143,7 +143,7 @@ PROPERTY (public, bool, isDrawOnly, setDrawOnly, STOCK_WRITE) PROPERTY (public, MessageManager*, messageLog, setMessageLog, STOCK_WRITE) PROPERTY (private, bool, isPicking, setPicking, CUSTOM_WRITE) - PROPERTY (public, LDDocument*, document, setDocument, CUSTOM_WRITE) + PROPERTY (public, LDDocumentPtr, document, setDocument, CUSTOM_WRITE) PROPERTY (public, EditMode, editMode, setEditMode, CUSTOM_WRITE) PROPERTY (private, GLCompiler*, compiler, setCompiler, STOCK_WRITE) PROPERTY (public, LDObjectWeakPtr, objectAtCursor, setObjectAtCursor, STOCK_WRITE)
--- a/src/ldDocument.cc Sun Jun 01 03:15:36 2014 +0300 +++ b/src/ldDocument.cc Mon Jun 02 12:50:40 2014 +0300 @@ -41,10 +41,11 @@ static bool g_loadingMainFile = false; static const int g_maxRecentFiles = 10; static bool g_aborted = false; -static LDDocumentPointer g_logoedStud = null; -static LDDocumentPointer g_logoedStud2 = null; - -LDDocument* LDDocument::m_curdoc = null; +static LDDocumentPtr g_logoedStud; +static LDDocumentPtr g_logoedStud2; +static QList<LDDocumentWeakPtr> g_allDocuments; +static QList<LDDocumentPtr> g_explicitDocuments; +static LDDocumentPtr g_currentDocument; const QStringList g_specialSubdirectories ({ "s", "48", "8" }); @@ -123,75 +124,98 @@ // ============================================================================= // -LDDocument::LDDocument() : +LDDocument::LDDocument (LDDocumentPtr* selfptr) : + m_isImplicit (true), m_flags (0), m_gldata (new LDGLData) { - setImplicit (true); + *selfptr = LDDocumentPtr (this); + setSelf (*selfptr); setSavePosition (-1); setTabIndex (-1); setHistory (new History); - history()->setDocument (this); + history()->setDocument (*selfptr); m_needsReCache = true; + g_allDocuments << *selfptr; +} + +// ============================================================================= +// +LDDocumentPtr LDDocument::createNew() +{ + LDDocumentPtr ptr; + new LDDocument (&ptr); + return ptr; } // ============================================================================= // LDDocument::~LDDocument() { - // Remove this file from the list of files. This MUST be done FIRST, otherwise - // a ton of other functions will think this file is still valid when it is not! - g_loadedFiles.removeOne (this); + print ("Deleted %1", getDisplayName()); + g_allDocuments.removeOne (self()); m_flags |= DOCF_IsBeingDestroyed; - m_history->setIgnoring (true); - - // Clear everything from the model - for (LDObjectPtr obj : objects()) - obj->destroy(); - - delete history(); + delete m_history; delete m_gldata; - - // If we just closed the current file, we need to set the current - // file as something else. - if (this == getCurrentDocument()) - { - bool found = false; - - // Try find an explicitly loaded file - if we can't find one, - // we need to create a new file to switch to. - for (LDDocument* file : g_loadedFiles) - { - if (not file->isImplicit()) - { - LDDocument::setCurrent (file); - found = true; - break; - } - } - - if (not found) - newFile(); - } - - if (this == g_logoedStud) - g_logoedStud = null; - elif (this == g_logoedStud2) - g_logoedStud2 = null; - - g_win->updateDocumentList(); - print ("Closed %1", name()); } // ============================================================================= // -LDDocument* findDocument (String name) +extern QMap<long, LDObjectWeakPtr> g_allObjects; +void LDDocument::setImplicit (bool const& a) { - for (LDDocument * file : g_loadedFiles) - if (not file->name().isEmpty() && file->name() == name) + if (m_isImplicit != a) + { + m_isImplicit = a; + + if (a == false) + g_explicitDocuments << self().toStrongRef(); + else + { + g_explicitDocuments.removeOne (self().toStrongRef()); + print ("Closed %1", name()); + int count = 0; + for (LDObjectPtr obj : g_allObjects) + { + LDSubfilePtr ref = obj.dynamicCast<LDSubfile>(); + if (ref && ref->fileInfo() == self()) + count++; + } + } + + if (g_win != null) + g_win->updateDocumentList(); + + // If the current document just became implicit (e.g. it was 'closed'), + // we need to get a new current document. + if (current() == self() && isImplicit()) + { + if (explicitDocuments().isEmpty()) + newFile(); + else + setCurrent (explicitDocuments().first()); + } + } +} + +// ============================================================================= +// +QList<LDDocumentPtr> const& LDDocument::explicitDocuments() +{ + return g_explicitDocuments; +} + +// ============================================================================= +// +LDDocumentPtr findDocument (String name) +{ + for (LDDocumentPtr file : g_allDocuments) + { + if (file->name() == name) return file; + } - return null; + return LDDocumentPtr(); } // ============================================================================= @@ -240,7 +264,7 @@ // in the immediate vicinity of a current model to override stock LDraw stuff. String reltop = basename (dirname (relpath)); - for (LDDocument* doc : g_loadedFiles) + for (LDDocumentPtr doc : g_allDocuments) { if (doc->fullPath().isEmpty()) continue; @@ -298,6 +322,8 @@ return ""; } +// ============================================================================= +// QFile* openLDrawFile (String relpath, bool subdirs, String* pathpointer) { print ("Opening %1...\n", relpath); @@ -467,12 +493,13 @@ *ok = not loader->isAborted(); objs = loader->objects(); + delete loader; return objs; } // ============================================================================= // -LDDocument* openDocument (String path, bool search, bool implicit) +LDDocumentPtr openDocument (String path, bool search, bool implicit, LDDocumentPtr fileToOverride) { // Convert the file name to lowercase since some parts contain uppercase // file names. I'll assume here that the library will always use lowercase @@ -490,21 +517,19 @@ if (not fp->open (QIODevice::ReadOnly)) { delete fp; - return null; + return LDDocumentPtr(); } } if (not fp) - return null; + return LDDocumentPtr(); - LDDocument* load = new LDDocument; + LDDocumentPtr load = (fileToOverride != null ? fileToOverride : LDDocument::createNew()); load->setImplicit (implicit); load->setFullPath (fullpath); load->setName (LDDocument::shortenName (load->fullPath())); - dprint ("name: %1 (%2)", load->name(), load->fullPath()); - g_loadedFiles << load; - // Don't take the file loading as actual edits to the file + // Loading the file shouldn't count as actual edits to the document. load->history()->setIgnoring (true); int numWarnings; @@ -515,9 +540,8 @@ if (not ok) { - g_loadedFiles.removeOne (load); - delete load; - return null; + load->dismiss(); + return LDDocumentPtr(); } load->addObjects (objs); @@ -593,11 +617,8 @@ // void closeAll() { - // Remove all loaded files and the objects they contain - QList<LDDocument*> files = g_loadedFiles; - - for (LDDocument* file : files) - delete file; + for (LDDocumentPtr file : g_explicitDocuments) + file->dismiss(); } // ============================================================================= @@ -605,10 +626,9 @@ void newFile() { // Create a new anonymous file and set it to our current - LDDocument* f = new LDDocument; + LDDocumentPtr f = LDDocument::createNew(); f->setName (""); f->setImplicit (false); - g_loadedFiles << f; LDDocument::setCurrent (f); LDDocument::closeInitialFile(); g_win->R()->setDocument (f); @@ -650,15 +670,14 @@ // ============================================================================= void openMainFile (String path) { - g_loadingMainFile = true; - // If there's already a file with the same name, this file must replace it. - LDDocument* documentToReplace = null; + LDDocumentPtr documentToReplace; + LDDocumentPtr file; String shortName = LDDocument::shortenName (path); - for (LDDocument* doc : g_loadedFiles) + for (LDDocumentWeakPtr doc : g_allDocuments) { - if (doc->name() == shortName) + if (doc.toStrongRef()->name() == shortName) { documentToReplace = doc; break; @@ -668,19 +687,22 @@ // We cannot open this file if the document this would replace is not // safe to close. if (documentToReplace != null && not documentToReplace->isSafeToClose()) + return; + + g_loadingMainFile = true; + + // If we're replacing an existing document, clear the document and + // make it ready for being loaded to. + if (documentToReplace != null) { - g_loadingMainFile = false; - return; + file = documentToReplace; + file->clear(); } - LDDocument* file = openDocument (path, false, false); + file = openDocument (path, false, false, file); - if (not file) + if (file == null) { - // Loading failed, thus drop down to a new file since we - // closed everything prior. - newFile(); - if (not g_aborted) { // Tell the user loading failed. @@ -694,20 +716,6 @@ file->setImplicit (false); - // Replace references to the old file with the new file. - if (documentToReplace != null) - { - for (LDDocumentPointer* ptr : documentToReplace->references()) - { dprint ("ptr: %1 (%2)\n", - ptr, ptr->pointer() ? ptr->pointer()->name() : "<null>"); - - *ptr = file; - } - - assert (documentToReplace->references().isEmpty()); - delete documentToReplace; - } - // If we have an anonymous, unchanged file open as the only open file // (aside of the one we just opened), close it now. LDDocument::closeInitialFile(); @@ -766,13 +774,21 @@ setFullPath (savepath); setName (shortenName (savepath)); - g_win->updateDocumentListItem (this); + g_win->updateDocumentListItem (self().toStrongRef()); g_win->updateTitle(); return true; } // ============================================================================= // +void LDDocument::clear() +{ + for (LDObjectPtr obj : objects()) + forgetObject (obj); +} + +// ============================================================================= +// static void checkTokenCount (const QStringList& tokens, int num) { if (tokens.size() != num) @@ -903,7 +919,7 @@ // not loading the main file now, but the subfile in question. bool tmp = g_loadingMainFile; g_loadingMainFile = false; - LDDocument* load = getDocument (tokens[14]); + LDDocumentPtr load = getDocument (tokens[14]); g_loadingMainFile = tmp; // If we cannot open the file, mark it an error. Note we cannot use LDParseError @@ -994,10 +1010,10 @@ // ============================================================================= // -LDDocument* getDocument (String filename) +LDDocumentPtr getDocument (String filename) { // Try find the file in the list of loaded files - LDDocument* doc = findDocument (filename); + LDDocumentPtr doc = findDocument (filename); // If it's not loaded, try open it if (not doc) @@ -1013,16 +1029,13 @@ if (not getCurrentDocument()) return; - g_loadedFiles.clear(); - g_loadedFiles << getCurrentDocument(); - // Go through all objects in the current file and reload the subfiles for (LDObjectPtr obj : getCurrentDocument()->objects()) { if (obj->type() == LDObject::ESubfile) { LDSubfilePtr ref = obj.staticCast<LDSubfile>(); - LDDocument* fileInfo = getDocument (ref->fileInfo()->name()); + LDDocumentPtr fileInfo = getDocument (ref->fileInfo()->name()); if (fileInfo) ref->setFileInfo (fileInfo); @@ -1143,7 +1156,7 @@ } m_objects.removeAt (idx); - obj->setDocument (null); + obj->setDocument (LDDocumentPtr()); } // ============================================================================= @@ -1188,9 +1201,11 @@ // bool safeToCloseAll() { - for (LDDocument* f : g_loadedFiles) + for (LDDocumentPtr f : LDDocument::explicitDocuments()) + { if (not f->isSafeToClose()) return false; + } return true; } @@ -1211,7 +1226,7 @@ removeKnownVerticesOf (m_objects[idx]); m_objects[idx]->deselect(); - m_objects[idx]->setDocument (null); + m_objects[idx]->setDocument (LDDocumentPtr()); obj->setDocument (this); addKnownVerticesOf (obj); g_win->R()->compileObject (obj); @@ -1222,16 +1237,7 @@ // // Close all documents we don't need anymore // -void LDDocument::closeUnused() -{ - for (int i = 0; i < g_loadedFiles.size(); ++i) - { - LDDocument* file = g_loadedFiles[i]; - - if (file->isImplicit() && file->references().isEmpty()) - delete g_loadedFiles[i--]; - } -} +void LDDocument::closeUnused() {} // ============================================================================= // @@ -1254,7 +1260,7 @@ // bool LDDocument::hasUnsavedChanges() const { - return !isImplicit() && history()->position() != savePosition(); + return not isImplicit() && history()->position() != savePosition(); } // ============================================================================= @@ -1277,10 +1283,9 @@ if (not m_needsReCache) return; - LDObjectList objs = inlineContents (true, true); m_storedVertices.clear(); - for (LDObjectPtr obj : objs) + for (LDObjectPtr obj : inlineContents (true, true)) { assert (obj->type() != LDObject::ESubfile); LDPolygon* data = obj->getPolygon(); @@ -1293,8 +1298,6 @@ for (int i = 0; i < obj->numVertices(); ++i) m_storedVertices << obj->vertex (i); - - obj->destroy(); } removeDuplicates (m_storedVertices); @@ -1339,10 +1342,7 @@ // just add it into the objects normally. Yay, recursion! if (deep == true && obj->type() == LDObject::ESubfile) { - LDSubfilePtr ref = obj.staticCast<LDSubfile>(); - LDObjectList otherobjs = ref->inlineContents (deep, renderinline); - - for (LDObjectPtr otherobj : otherobjs) + for (LDObjectPtr otherobj : obj.staticCast<LDSubfile>()->inlineContents (deep, renderinline)) objs << otherobj; } else @@ -1354,9 +1354,9 @@ // ============================================================================= // -LDDocument* LDDocument::current() +LDDocumentPtr LDDocument::current() { - return m_curdoc; + return g_currentDocument; } // ============================================================================= @@ -1365,14 +1365,14 @@ // // TODO: f can be temporarily null. This probably should not be the case. // ============================================================================= -void LDDocument::setCurrent (LDDocument* f) +void LDDocument::setCurrent (LDDocumentPtr f) { // Implicit files were loaded for caching purposes and must never be set // current. - if (f && f->isImplicit()) + if (f != null && f->isImplicit()) return; - m_curdoc = f; + g_currentDocument = f; if (g_win && f) { @@ -1390,15 +1390,7 @@ // int LDDocument::countExplicitFiles() { - int count = 0; - - for (LDDocument* f : g_loadedFiles) - { - if (not f->isImplicit()) - ++count; - } - - return count; + return g_explicitDocuments.size(); } // ============================================================================= @@ -1407,12 +1399,12 @@ // ============================================================================= void LDDocument::closeInitialFile() { - if (countExplicitFiles() == 2 && - g_loadedFiles[0]->name().isEmpty() && - not g_loadedFiles[1]->name().isEmpty() && - not g_loadedFiles[0]->hasUnsavedChanges()) + if (g_explicitDocuments.size() == 2 && + g_explicitDocuments[0]->name().isEmpty() && + not g_explicitDocuments[1]->name().isEmpty() && + not g_explicitDocuments[0]->hasUnsavedChanges()) { - delete g_loadedFiles[0]; + g_explicitDocuments[0]->dismiss(); } } @@ -1423,9 +1415,6 @@ if (g_logoedStud && g_logoedStud2) return; - delete g_logoedStud; - delete g_logoedStud2; - g_logoedStud = openDocument ("stud-logo.dat", true, true); g_logoedStud2 = openDocument ("stud2-logo.dat", true, true); @@ -1439,7 +1428,7 @@ if (obj->isSelected()) return; - assert (obj->document() == this); + assert (obj->document() == self()); m_sel << obj; g_win->R()->compileObject (obj); obj->setSelected (true); @@ -1452,7 +1441,7 @@ if (not obj->isSelected()) return; - assert (obj->document() == this); + assert (obj->document() == self()); m_sel.removeOne (obj); g_win->R()->compileObject (obj); obj->setSelected (false); @@ -1502,23 +1491,6 @@ // ============================================================================= // -void LDDocument::addReference (LDDocumentPointer* ptr) -{ - m_references << ptr; -} - -// ============================================================================= -// -void LDDocument::removeReference (LDDocumentPointer* ptr) -{ - m_references.removeOne (ptr); - - if (references().isEmpty()) - invokeLater (closeUnused); -} - -// ============================================================================= -// QList<Vertex> LDDocument::inlineVertices() { initializeCachedData();
--- a/src/ldDocument.h Sun Jun 01 03:15:36 2014 +0300 +++ b/src/ldDocument.h Mon Jun 02 12:50:40 2014 +0300 @@ -25,7 +25,6 @@ class History; class OpenProgressDialog; -class LDDocumentPointer; struct LDGLData; class GLCompiler; @@ -51,12 +50,11 @@ Q_DECLARE_FLAGS (LDDocumentFlags, LDDocumentFlag) Q_DECLARE_OPERATORS_FOR_FLAGS (LDDocumentFlags) -// ============================================================================= // // This class stores a document either as a editable file for the user or for -// subfile caching. Its methods handle file input and output. +// subfile caching. // -// A file is implicit when they are opened automatically for caching purposes +// A document is implicit when they are opened automatically for caching purposes // and are hidden from the user. User-opened files are explicit (not implicit). // // The default name is a placeholder, initially suggested name for a file. The @@ -65,26 +63,24 @@ class LDDocument : public QObject { public: - using ReferenceList = QList<LDDocumentPointer*>; using KnownVertexMap = QMap<Vertex, int>; - Q_OBJECT - PROPERTY (public, String, name, setName, STOCK_WRITE) - PROPERTY (private, LDObjectList, objects, setObjects, STOCK_WRITE) - PROPERTY (private, LDObjectList, cache, setCache, STOCK_WRITE) - PROPERTY (private, History*, history, setHistory, STOCK_WRITE) - PROPERTY (private, KnownVertexMap, vertices, setVertices, STOCK_WRITE) - PROPERTY (private, ReferenceList, references, setReferences, STOCK_WRITE) - PROPERTY (public, String, fullPath, setFullPath, STOCK_WRITE) - PROPERTY (public, String, defaultName, setDefaultName, STOCK_WRITE) - PROPERTY (public, bool, isImplicit, setImplicit, STOCK_WRITE) - PROPERTY (public, long, savePosition, setSavePosition, STOCK_WRITE) - PROPERTY (public, int, tabIndex, setTabIndex, STOCK_WRITE) - PROPERTY (public, QList<LDPolygon>, polygonData, setPolygonData, STOCK_WRITE) - PROPERTY (private, LDDocumentFlags, flags, setFlags, STOCK_WRITE) + PROPERTY (public, String, name, setName, STOCK_WRITE) + PROPERTY (private, LDObjectList, objects, setObjects, STOCK_WRITE) + PROPERTY (private, LDObjectList, cache, setCache, STOCK_WRITE) + PROPERTY (private, History*, history, setHistory, STOCK_WRITE) + PROPERTY (private, KnownVertexMap, vertices, setVertices, STOCK_WRITE) + PROPERTY (public, String, fullPath, setFullPath, STOCK_WRITE) + PROPERTY (public, String, defaultName, setDefaultName, STOCK_WRITE) + PROPERTY (public, bool, isImplicit, setImplicit, CUSTOM_WRITE) + PROPERTY (public, long, savePosition, setSavePosition, STOCK_WRITE) + PROPERTY (public, int, tabIndex, setTabIndex, STOCK_WRITE) + PROPERTY (public, QList<LDPolygon>, polygonData, setPolygonData, STOCK_WRITE) + PROPERTY (private, LDDocumentFlags, flags, setFlags, STOCK_WRITE) + PROPERTY (private, LDDocumentWeakPtr, self, setSelf, STOCK_WRITE) public: - LDDocument(); + LDDocument(LDDocumentPtr* selfptr); ~LDDocument(); int addObject (LDObjectPtr obj); // Adds an object to this file at the end of the file. @@ -103,13 +99,12 @@ void swapObjects (LDObjectPtr one, LDObjectPtr other); bool isSafeToClose(); // Perform safety checks. Do this before closing any files! void setObject (int idx, LDObjectPtr obj); - void addReference (LDDocumentPointer* ptr); - void removeReference (LDDocumentPointer* ptr); QList<LDPolygon> inlinePolygons(); void vertexChanged (const Vertex& a, const Vertex& b); void addKnownVerticesOf(LDObjectPtr obj); void removeKnownVerticesOf (LDObjectPtr sub); QList<Vertex> inlineVertices(); + void clear(); inline LDDocument& operator<< (LDObjectPtr obj) { @@ -142,14 +137,21 @@ *history() << entry; } + inline void dismiss() + { + setImplicit (true); + } + static void closeUnused(); - static LDDocument* current(); - static void setCurrent (LDDocument* f); + static LDDocumentPtr current(); + static void setCurrent (LDDocumentPtr f); static void closeInitialFile(); static int countExplicitFiles(); + static LDDocumentPtr createNew(); // Turns a full path into a relative path static String shortenName (String a); + static QList<LDDocumentPtr> const& explicitDocuments(); protected: void addToSelection (LDObjectPtr obj); @@ -172,13 +174,11 @@ // stored polygon data and re-builds it. bool m_needsReCache; - static LDDocument* m_curdoc; - void addKnownVertexReference (const Vertex& a); void removeKnownVertexReference (const Vertex& a); }; -inline LDDocument* getCurrentDocument() +inline LDDocumentPtr getCurrentDocument() { return LDDocument::current(); } @@ -190,11 +190,11 @@ void openMainFile (String path); // Finds an OpenFile by name or null if not open -LDDocument* findDocument (String name); +LDDocumentPtr findDocument (String name); // Opens the given file and parses the LDraw code within. Returns a pointer // to the opened file or null on error. -LDDocument* openDocument (String path, bool search, bool implicit); +LDDocumentPtr openDocument (String path, bool search, bool implicit, LDDocumentPtr fileToOverride = LDDocumentPtr()); // Opens the given file and returns a pointer to it, potentially looking in /parts and /p QFile* openLDrawFile (String relpath, bool subdirs, String* pathpointer = null); @@ -207,7 +207,7 @@ // Retrieves the pointer to the given document by file name. Document is loaded // from file if necessary. Can return null if neither succeeds. -LDDocument* getDocument (String filename); +LDDocumentPtr getDocument (String filename); // Re-caches all subfiles. void reloadAllSubfiles(); @@ -217,8 +217,6 @@ LDObjectList loadFileContents (QFile* f, int* numWarnings, bool* ok = null); -extern QList<LDDocument*> g_loadedFiles; - inline const LDObjectList& selection() { return getCurrentDocument()->getSelection(); @@ -229,8 +227,6 @@ String basename (String path); String dirname (String path); -extern QList<LDDocument*> g_loadedFiles; // Vector of all currently opened files. - // ============================================================================= // // LDFileLoader
--- a/src/ldObject.cc Sun Jun 01 03:15:36 2014 +0300 +++ b/src/ldObject.cc Mon Jun 02 12:50:40 2014 +0300 @@ -32,7 +32,7 @@ CFGENTRY (Int, defaultLicense, 0); // List of all LDObjects -static QMap<long, LDObjectWeakPtr> g_allObjects; +QMap<long, LDObjectWeakPtr> g_allObjects; static int32 g_idcursor = 1; // 0 shalt be null static constexpr int32 g_maxID = (1 << 24); @@ -47,7 +47,6 @@ m_isHidden (false), m_isSelected (false), m_isDestructed (false), - m_document (null), qObjListEntry (null) { *selfptr = LDObjectPtr (this, [](LDObject* obj){ obj->finalDelete(); }); @@ -242,7 +241,7 @@ assert (idx != -1); // Replace the instance of the old object with the new object - document()->setObject (idx, other); + document().toStrongRef()->setObject (idx, other); // Remove the old object destroy(); @@ -253,7 +252,7 @@ void LDObject::swap (LDObjectPtr other) { assert (document() == other->document()); - document()->swapObjects (self(), other); + document().toStrongRef()->swapObjects (self(), other); } // ============================================================================= @@ -302,8 +301,8 @@ deselect(); // If this object was associated to a file, remove it off it now - if (document()) - document()->forgetObject (self()); + if (document() != null) + document().toStrongRef()->forgetObject (self()); // Delete the GL lists g_win->R()->forgetObject (self()); @@ -424,8 +423,8 @@ { assert (document() != null); - for (int i = 0; i < document()->getObjectCount(); ++i) - if (document()->getObject (i) == this) + for (int i = 0; i < document().toStrongRef()->getObjectCount(); ++i) + if (document().toStrongRef()->getObject (i) == this) return i; return -1; @@ -443,7 +442,7 @@ const long end = up ? objs.size() : -1; const long incr = up ? 1 : -1; LDObjectList objsToCompile; - LDDocument* file = objs[0]->document(); + LDDocumentPtr file = objs[0]->document(); for (long i = start; i != end; i += incr) { @@ -539,10 +538,10 @@ long idx = lineNumber(); assert (idx != -1); - if (idx == (long) document()->getObjectCount() - 1) + if (idx == (long) document().toStrongRef()->getObjectCount() - 1) return LDObjectPtr(); - return document()->getObject (idx + 1); + return document().toStrongRef()->getObject (idx + 1); } // ============================================================================= @@ -555,7 +554,7 @@ if (idx == 0) return LDObjectPtr(); - return document()->getObject (idx - 1); + return document().toStrongRef()->getObject (idx - 1); } // ============================================================================= @@ -654,6 +653,9 @@ // void LDSubfile::invert() { + if (document() == null) + return; + // Check whether subfile is flat int axisSet = (1 << X) | (1 << Y) | (1 << Z); LDObjectList objs = inlineContents (true, false); @@ -713,7 +715,7 @@ } // Not inverted, thus prefix it with a new invertnext. - document()->insertObj (idx, spawn<LDBFC> (LDBFC::InvertNext)); + document().toStrongRef()->insertObj (idx, spawn<LDBFC> (LDBFC::InvertNext)); } // ============================================================================= @@ -798,7 +800,7 @@ if (before != after) { - obj->document()->addToHistory (new EditHistory (idx, before, after)); + obj->document().toStrongRef()->addToHistory (new EditHistory (idx, before, after)); g_win->R()->compileObject (obj); } } @@ -825,7 +827,7 @@ void LDObject::setVertex (int i, const Vertex& vert) { if (document() != null) - document()->vertexChanged (*m_coords[i], vert); + document().toStrongRef()->vertexChanged (*m_coords[i], vert); changeProperty (self(), &m_coords[i], LDSharedVertex::getSharedVertex (vert)); } @@ -837,12 +839,12 @@ LDObjectPtr ref = linkPointer().toStrongRef(); if (ref->document() != null) - ref->document()->removeKnownVerticesOf (ref); + ref->document().toStrongRef()->removeKnownVerticesOf (ref); changeProperty (ref, &m_position, LDSharedVertex::getSharedVertex (a)); if (ref->document() != null) - ref->document()->addKnownVerticesOf (ref); + ref->document().toStrongRef()->addKnownVerticesOf (ref); } // ============================================================================= @@ -852,12 +854,12 @@ LDObjectPtr ref = linkPointer().toStrongRef(); if (ref->document() != null) - ref->document()->removeKnownVerticesOf (ref); + ref->document().toStrongRef()->removeKnownVerticesOf (ref); changeProperty (ref, &m_transform, val); if (ref->document() != null) - ref->document()->addKnownVerticesOf (ref); + ref->document().toStrongRef()->addKnownVerticesOf (ref); } // ============================================================================= @@ -903,7 +905,7 @@ void LDObject::select() { assert (document() != null); - document()->addToSelection (self()); + document().toStrongRef()->addToSelection (self()); // If this object is inverted with INVERTNEXT, pick the INVERTNEXT as well. LDBFCPtr invertnext; @@ -917,7 +919,7 @@ void LDObject::deselect() { assert (document() != null); - document()->removeFromSelection (self()); + document().toStrongRef()->removeFromSelection (self()); // If this object is inverted with INVERTNEXT, deselect the INVERTNEXT as well. LDBFCPtr invertnext; @@ -956,10 +958,10 @@ // ============================================================================= // -void LDSubfile::setFileInfo (const LDDocumentPointer& a) +void LDSubfile::setFileInfo (const LDDocumentPtr& a) { if (document() != null) - document()->removeKnownVerticesOf (self()); + document().toStrongRef()->removeKnownVerticesOf (self()); m_fileInfo = a; @@ -974,5 +976,5 @@ } if (document() != null) - document()->addKnownVerticesOf (self()); + document().toStrongRef()->addKnownVerticesOf (self()); };
--- a/src/ldObject.h Sun Jun 01 03:15:36 2014 +0300 +++ b/src/ldObject.h Mon Jun 02 12:50:40 2014 +0300 @@ -73,7 +73,7 @@ PROPERTY (public, bool, isSelected, setSelected, STOCK_WRITE) PROPERTY (public, bool, isDestructed, setDestructed, STOCK_WRITE) PROPERTY (public, LDObjectWeakPtr, parent, setParent, STOCK_WRITE) - PROPERTY (public, LDDocument*, document, setDocument, STOCK_WRITE) + PROPERTY (public, LDDocumentWeakPtr, document, setDocument, STOCK_WRITE) PROPERTY (private, int32, id, setID, STOCK_WRITE) PROPERTY (public, int, color, setColor, CUSTOM_WRITE) PROPERTY (private, QColor, randomColor, setRandomColor, STOCK_WRITE) @@ -447,7 +447,7 @@ LDOBJ_COLORED LDOBJ_SCEMANTIC LDOBJ_HAS_MATRIX - PROPERTY (public, LDDocumentPointer, fileInfo, setFileInfo, CUSTOM_WRITE) + PROPERTY (public, LDDocumentPtr, fileInfo, setFileInfo, CUSTOM_WRITE) public: enum InlineFlag
--- a/src/main.cc Sun Jun 01 03:15:36 2014 +0300 +++ b/src/main.cc Mon Jun 02 12:50:40 2014 +0300 @@ -34,7 +34,6 @@ #include "dialogs.h" #include "crashCatcher.h" -QList<LDDocument*> g_loadedFiles; MainWindow* g_win = null; static String g_versionString, g_fullVersionString; @@ -51,7 +50,6 @@ app.setOrganizationName (APPNAME); app.setApplicationName (APPNAME); initCrashCatcher(); - LDDocument::setCurrent (null); // Load or create the configuration if (not Config::load())
--- a/src/mainWindow.cc Sun Jun 01 03:15:36 2014 +0300 +++ b/src/mainWindow.cc Mon Jun 02 12:50:40 2014 +0300 @@ -724,7 +724,7 @@ // ============================================================================= // -bool MainWindow::save (LDDocument* doc, bool saveAs) +bool MainWindow::save (LDDocumentPtr doc, bool saveAs) { String path = doc->fullPath(); @@ -889,12 +889,8 @@ while (m_tabs->count() > 0) m_tabs->removeTab (0); - for (LDDocument* f : g_loadedFiles) + for (LDDocumentPtr f : LDDocument::explicitDocuments()) { - // Don't list implicit files unless explicitly desired. - if (f->isImplicit() && not cfg::listImplicitFiles) - continue; - // Add an item to the list for this file and store the tab index // in the document so we can find documents by tab index. f->setTabIndex (m_tabs->addTab ("")); @@ -906,7 +902,7 @@ // ============================================================================= // -void MainWindow::updateDocumentListItem (LDDocument* doc) +void MainWindow::updateDocumentListItem (LDDocumentPtr doc) { bool oldUpdatingTabs = m_updatingTabs; m_updatingTabs = true; @@ -941,11 +937,11 @@ if (m_updatingTabs) return; - LDDocument* f = null; + LDDocumentPtr f; int tabIndex = m_tabs->currentIndex(); // Find the file pointer of the item that was selected. - for (LDDocument* it : g_loadedFiles) + for (LDDocumentPtr it : LDDocument::explicitDocuments()) { if (it->tabIndex() == tabIndex) { @@ -968,7 +964,7 @@ { #if 0 ui->objectList->clear(); - LDDocument* f = getCurrentDocument(); + LDDocumentPtr f = getCurrentDocument(); for (LDObjectPtr obj : *f) ui->objectList->addItem (obj->qObjListEntry);
--- a/src/mainWindow.h Sun Jun 01 03:15:36 2014 +0300 +++ b/src/mainWindow.h Mon Jun 02 12:50:40 2014 +0300 @@ -129,7 +129,7 @@ //! Updates the document tab for \c doc. If no such tab exists, the //! document list is rebuilt instead. - void updateDocumentListItem (LDDocument* doc); + void updateDocumentListItem (LDDocumentPtr doc); //! \returns the uniform selected color (i.e. 4 if everything selected is //! red), -1 if there is no such consensus. @@ -158,7 +158,7 @@ //! \param doc the document to save //! \param saveAs if true, always ask for a file path //! \returns whether the save was successful - bool save (LDDocument* doc, bool saveAs); + bool save (LDDocumentPtr doc, bool saveAs); //! Updates various actions, undo/redo are set enabled/disabled where //! appropriate, togglable actions are updated based on configuration,
--- a/src/misc/documentPointer.cc Sun Jun 01 03:15:36 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * LDForge: LDraw parts authoring CAD - * Copyright (C) 2013, 2014 Santeri 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 <http://www.gnu.org/licenses/>. - */ - -#include "documentPointer.h" -#include "../ldDocument.h" -#include "../miscallenous.h" - -LDDocumentPointer::LDDocumentPointer() : m_pointer (null) {} - -// ============================================================================= -// -LDDocumentPointer::LDDocumentPointer (LDDocument* ptr) : - m_pointer (ptr) -{ - addReference (); -} - -// ============================================================================= -// -LDDocumentPointer::LDDocumentPointer (const LDDocumentPointer& other) : - m_pointer (other.pointer()) -{ - addReference (); -} - -// ============================================================================= -// -LDDocumentPointer::~LDDocumentPointer() -{ - removeReference(); -} - -// ============================================================================= -// -void LDDocumentPointer::addReference() -{ - if (pointer() != null) - pointer()->addReference (this); -} - -// ============================================================================= -// -void LDDocumentPointer::removeReference() -{ - if (pointer() != null) - pointer()->removeReference (this); -} - -// ============================================================================= -// -LDDocumentPointer& LDDocumentPointer::operator= (LDDocument* ptr) -{ - if (ptr != pointer()) - { - removeReference(); - setPointer (ptr); - addReference(); - } - - return *this; -} \ No newline at end of file
--- a/src/misc/documentPointer.h Sun Jun 01 03:15:36 2014 +0300 +++ b/src/misc/documentPointer.h Mon Jun 02 12:50:40 2014 +0300 @@ -1,74 +0,0 @@ -/* - * LDForge: LDraw parts authoring CAD - * Copyright (C) 2013, 2014 Santeri 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 <http://www.gnu.org/licenses/>. - */ - -#pragma once - -#include "../main.h" - -class LDSubfile; -class LDDocument; - -//! -//! \brief A reference-counting pointer to LDDocument. -//! -//! The LDDocumentPointer class defines a reference-counting pointer which -//! points to LDDocument. -//! -class LDDocumentPointer -{ - PROPERTY (private, LDDocument*, pointer, setPointer, STOCK_WRITE) - - public: - //! Constructs a null LDDocumentPointer - LDDocumentPointer(); - - //! Constructs a document pointer with the given pointer - LDDocumentPointer (LDDocument* ptr); - - //! Copy-constructs a LDDocumentPointer. - LDDocumentPointer (const LDDocumentPointer& other); - - //! Destructs the pointer. - ~LDDocumentPointer(); - - //! \param ptr the new pointer to change to. - LDDocumentPointer& operator= (LDDocument* ptr); - - //! Copy operator. - //! \param other the pointer whose internal pointer to copy. - inline LDDocumentPointer& operator= (LDDocumentPointer& other) - { - return operator= (other.pointer()); - } - - //! Operator overload for a->b support. - inline LDDocument* operator->() const - { - return pointer(); - } - - //! Cast operator overload - inline operator LDDocument*() const - { - return pointer(); - } - - private: - void addReference(); - void removeReference(); -};
--- a/src/miscallenous.cc Sun Jun 01 03:15:36 2014 +0300 +++ b/src/miscallenous.cc Mon Jun 02 12:50:40 2014 +0300 @@ -25,7 +25,6 @@ #include "dialogs.h" #include "ldDocument.h" #include "ui_rotpoint.h" -#include "misc/documentPointer.cc" #include "misc/ringFinder.cc" #include "misc/invokeLater.cc"
--- a/src/partDownloader.cc Sun Jun 01 03:15:36 2014 +0300 +++ b/src/partDownloader.cc Mon Jun 02 12:50:40 2014 +0300 @@ -213,7 +213,7 @@ elif (btn == getButton (Download)) { QString dest = interface()->fname->text(); - setPrimaryFile (null); + setPrimaryFile (LDDocumentPtr()); setAborted (false); if (getSource() == CustomURL) @@ -446,7 +446,7 @@ } // Try to load this file now. - LDDocument* f = openDocument (filePath(), false, not isPrimary()); + LDDocumentPtr f = openDocument (filePath(), false, not isPrimary()); if (f == null) return;
--- a/src/partDownloader.h Sun Jun 01 03:15:36 2014 +0300 +++ b/src/partDownloader.h Mon Jun 02 12:50:40 2014 +0300 @@ -20,6 +20,7 @@ #include <QDialog> #include "main.h" #include "basics.h" +#include "ldDocument.h" class LDDocument; class QFile; @@ -57,7 +58,7 @@ using RequestList = QList<PartDownloadRequest*>; Q_OBJECT - PROPERTY (public, LDDocument*, primaryFile, setPrimaryFile, STOCK_WRITE) + PROPERTY (public, LDDocumentPtr, primaryFile, setPrimaryFile, STOCK_WRITE) PROPERTY (public, bool, isAborted, setAborted, STOCK_WRITE) PROPERTY (private, Ui_DownloadFrom*, interface, setInterface, STOCK_WRITE) PROPERTY (private, QStringList, filesToDownload, setFilesToDownload, STOCK_WRITE)
--- a/src/primitives.cc Sun Jun 01 03:15:36 2014 +0300 +++ b/src/primitives.cc Mon Jun 02 12:50:40 2014 +0300 @@ -579,7 +579,7 @@ // ============================================================================= // -LDDocument* generatePrimitive (PrimitiveType type, int segs, int divs, int num) +LDDocumentPtr generatePrimitive (PrimitiveType type, int segs, int divs, int num) { // Make the description QString frac = QString::number ((float) segs / divs); @@ -605,7 +605,7 @@ if (divs == g_hires) descr.insert (0, "Hi-Res "); - LDDocument* f = new LDDocument; + LDDocumentPtr f = LDDocument::createNew(); f->setDefaultName (name); QString author = APPNAME; @@ -635,10 +635,10 @@ // ============================================================================= // -LDDocument* getPrimitive (PrimitiveType type, int segs, int divs, int num) +LDDocumentPtr getPrimitive (PrimitiveType type, int segs, int divs, int num) { QString name = radialFileName (type, segs, divs, num); - LDDocument* f = getDocument (name); + LDDocumentPtr f = getDocument (name); if (f != null) return f; @@ -694,8 +694,7 @@ dlg->ui->rb_ndisc->isChecked() ? DiscNeg : dlg->ui->rb_ring->isChecked() ? Ring : Cone; - LDDocument* f = generatePrimitive (type, segs, divs, num); - + LDDocumentPtr f = generatePrimitive (type, segs, divs, num); + f->setImplicit (false); g_win->save (f, false); - delete f; }
--- a/src/primitives.h Sun Jun 01 03:15:36 2014 +0300 +++ b/src/primitives.h Mon Jun 02 12:50:40 2014 +0300 @@ -121,10 +121,10 @@ }; void makeCircle (int segs, int divs, double radius, QList<QLineF>& lines); -LDDocument* generatePrimitive (PrimitiveType type, int segs, int divs, int num); +LDDocumentPtr generatePrimitive (PrimitiveType type, int segs, int divs, int num); // Gets a primitive by the given specs. If the primitive cannot be found, it will // be automatically generated. -LDDocument* getPrimitive (PrimitiveType type, int segs, int divs, int num); +LDDocumentPtr getPrimitive (PrimitiveType type, int segs, int divs, int num); QString radialFileName (PrimitiveType type, int segs, int divs, int num);