46 static LDFile* g_logoedStud = null; |
46 static LDFile* g_logoedStud = null; |
47 static LDFile* g_logoedStud2 = null; |
47 static LDFile* g_logoedStud2 = null; |
48 |
48 |
49 LDFile* LDFile::m_curfile = null; |
49 LDFile* LDFile::m_curfile = null; |
50 |
50 |
51 DEFINE_PROPERTY (QListWidgetItem*, LDFile, listItem, setListItem) |
|
52 |
|
53 // ============================================================================= |
51 // ============================================================================= |
54 // ----------------------------------------------------------------------------- |
52 // ----------------------------------------------------------------------------- |
55 namespace LDPaths |
53 namespace LDPaths |
56 { static str pathError; |
54 { static str pathError; |
57 |
55 |
114 |
112 |
115 // ============================================================================= |
113 // ============================================================================= |
116 // ----------------------------------------------------------------------------- |
114 // ----------------------------------------------------------------------------- |
117 LDFile::LDFile() |
115 LDFile::LDFile() |
118 { setImplicit (true); |
116 { setImplicit (true); |
119 setSavePos (-1); |
117 setSavePosition (-1); |
120 setListItem (null); |
118 setListItem (null); |
121 m_history.setFile (this); |
119 setHistory (new History); |
|
120 m_History->setFile (this); |
122 } |
121 } |
123 |
122 |
124 // ============================================================================= |
123 // ============================================================================= |
125 // ----------------------------------------------------------------------------- |
124 // ----------------------------------------------------------------------------- |
126 LDFile::~LDFile() |
125 LDFile::~LDFile() |
127 { // Clear everything from the model |
126 { // Clear everything from the model |
128 for (LDObject* obj : objects()) |
127 for (LDObject* obj : getObjects()) |
129 delete obj; |
128 delete obj; |
130 |
129 |
131 // Clear the cache as well |
130 // Clear the cache as well |
132 for (LDObject* obj : cache()) |
131 for (LDObject* obj : getCache()) |
133 delete obj; |
132 delete obj; |
|
133 |
|
134 delete m_History; |
134 |
135 |
135 // Remove this file from the list of files |
136 // Remove this file from the list of files |
136 g_loadedFiles.removeOne (this); |
137 g_loadedFiles.removeOne (this); |
137 |
138 |
138 // If we just closed the current file, we need to set the current |
139 // If we just closed the current file, we need to set the current |
141 { bool found = false; |
142 { bool found = false; |
142 |
143 |
143 // Try find an explicitly loaded file - if we can't find one, |
144 // Try find an explicitly loaded file - if we can't find one, |
144 // we need to create a new file to switch to. |
145 // we need to create a new file to switch to. |
145 for (LDFile* file : g_loadedFiles) |
146 for (LDFile* file : g_loadedFiles) |
146 { if (!file->implicit()) |
147 { if (!file->isImplicit()) |
147 { LDFile::setCurrent (file); |
148 { LDFile::setCurrent (file); |
148 found = true; |
149 found = true; |
149 break; |
150 break; |
150 } |
151 } |
151 } |
152 } |
210 #endif // WIN32 |
211 #endif // WIN32 |
211 |
212 |
212 if (LDFile::current()) |
213 if (LDFile::current()) |
213 { // First, try find the file in the current model's file path. We want a file |
214 { // First, try find the file in the current model's file path. We want a file |
214 // in the immediate vicinity of the current model to override stock LDraw stuff. |
215 // in the immediate vicinity of the current model to override stock LDraw stuff. |
215 str partpath = fmt ("%1" DIRSLASH "%2", dirname (LDFile::current()->name()), relpath); |
216 str partpath = fmt ("%1" DIRSLASH "%2", dirname (LDFile::current()->getName()), relpath); |
216 |
217 |
217 if (f->open (partpath, File::Read)) |
218 if (f->open (partpath, File::Read)) |
218 return f; |
219 return f; |
219 } |
220 } |
220 |
221 |
251 void FileLoader::start() |
252 void FileLoader::start() |
252 { setDone (false); |
253 { setDone (false); |
253 setProgress (0); |
254 setProgress (0); |
254 setAborted (false); |
255 setAborted (false); |
255 |
256 |
256 if (concurrent()) |
257 if (isOnForeground()) |
257 { g_aborted = false; |
258 { g_aborted = false; |
258 |
259 |
259 // Show a progress dialog if we're loading the main file here so we can |
260 // Show a progress dialog if we're loading the main file here so we can |
260 // show progress updates and keep the WM posted that we're still here. |
261 // show progress updates and keep the WM posted that we're still here. |
261 // Of course we cannot exec() the dialog because then the dialog would |
262 // Of course we cannot exec() the dialog because then the dialog would |
262 // block. |
263 // block. |
263 dlg = new OpenProgressDialog (g_win); |
264 dlg = new OpenProgressDialog (g_win); |
264 dlg->setNumLines (lines().size()); |
265 dlg->setNumLines (getLines().size()); |
265 dlg->setModal (true); |
266 dlg->setModal (true); |
266 dlg->show(); |
267 dlg->show(); |
267 |
268 |
268 // Connect the loader in so we can show updates |
269 // Connect the loader in so we can show updates |
269 connect (this, SIGNAL (workDone()), dlg, SLOT (accept())); |
270 connect (this, SIGNAL (workDone()), dlg, SLOT (accept())); |
278 |
279 |
279 // ============================================================================= |
280 // ============================================================================= |
280 // ----------------------------------------------------------------------------- |
281 // ----------------------------------------------------------------------------- |
281 void FileLoader::work (int i) |
282 void FileLoader::work (int i) |
282 { // User wishes to abort, so stop here now. |
283 { // User wishes to abort, so stop here now. |
283 if (aborted()) |
284 if (isAborted()) |
284 { for (LDObject* obj : m_objs) |
285 { for (LDObject* obj : m_Objects) |
285 delete obj; |
286 delete obj; |
286 |
287 |
287 m_objs.clear(); |
288 m_Objects.clear(); |
288 setDone (true); |
289 setDone (true); |
289 return; |
290 return; |
290 } |
291 } |
291 |
292 |
292 // Parse up to 300 lines per iteration |
293 // Parse up to 300 lines per iteration |
293 int max = i + 300; |
294 int max = i + 300; |
294 |
295 |
295 for (; i < max && i < (int) lines().size(); ++i) |
296 for (; i < max && i < (int) getLines().size(); ++i) |
296 { str line = lines() [i]; |
297 { str line = getLines()[i]; |
297 |
298 |
298 // Trim the trailing newline |
299 // Trim the trailing newline |
299 QChar c; |
300 QChar c; |
300 |
301 |
301 while (!line.isEmpty() && ((c = line[line.length() - 1]) == '\n' || c == '\r')) |
302 while (!line.isEmpty() && ((c = line[line.length() - 1]) == '\n' || c == '\r')) |
303 |
304 |
304 LDObject* obj = parseLine (line); |
305 LDObject* obj = parseLine (line); |
305 |
306 |
306 // Check for parse errors and warn about tthem |
307 // Check for parse errors and warn about tthem |
307 if (obj->getType() == LDObject::Error) |
308 if (obj->getType() == LDObject::Error) |
308 { log ("Couldn't parse line #%1: %2", m_progress + 1, static_cast<LDError*> (obj)->reason); |
309 { log ("Couldn't parse line #%1: %2", getProgress() + 1, static_cast<LDError*> (obj)->reason); |
309 |
310 |
310 if (m_warningsPointer) |
311 if (getWarnings() != null) |
311 (*m_warningsPointer)++; |
312 (*getWarnings())++; |
312 } |
313 } |
313 |
314 |
314 m_objs << obj; |
315 m_Objects << obj; |
315 setProgress (i); |
316 setProgress (i); |
316 |
317 |
317 // If we have a dialog pointer, update the progress now |
318 // If we have a dialog pointer, update the progress now |
318 if (concurrent()) |
319 if (isOnForeground()) |
319 dlg->updateProgress (i); |
320 dlg->updateProgress (i); |
320 } |
321 } |
321 |
322 |
322 // If we're done now, tell the environment we're done and stop. |
323 // If we're done now, tell the environment we're done and stop. |
323 if (i >= ((int) lines().size()) - 1) |
324 if (i >= ((int) getLines().size()) - 1) |
324 { emit workDone(); |
325 { emit workDone(); |
325 setDone (true); |
326 setDone (true); |
326 return; |
327 return; |
327 } |
328 } |
328 |
329 |
329 // Otherwise, continue, by recursing back. |
330 // Otherwise, continue, by recursing back. |
330 if (!done()) |
331 if (!isDone()) |
331 { // If we have a dialog to show progress output to, we cannot just call |
332 { // If we have a dialog to show progress output to, we cannot just call |
332 // work() again immediately as the dialog needs some processor cycles as |
333 // work() again immediately as the dialog needs some processor cycles as |
333 // well. Thus, take a detour through the event loop by using the |
334 // well. Thus, take a detour through the event loop by using the |
334 // meta-object system. |
335 // meta-object system. |
335 // |
336 // |
336 // This terminates the loop here and control goes back to the function |
337 // This terminates the loop here and control goes back to the function |
337 // which called the file loader. It will keep processing the event loop |
338 // which called the file loader. It will keep processing the event loop |
338 // until we're ready (see loadFileContents), thus the event loop will |
339 // until we're ready (see loadFileContents), thus the event loop will |
339 // eventually catch the invokation we throw here and send us back. Though |
340 // eventually catch the invokation we throw here and send us back. Though |
340 // it's not technically recursion anymore, more like a for loop. :P |
341 // it's not technically recursion anymore, more like a for loop. :P |
341 if (concurrent()) |
342 if (isOnForeground()) |
342 QMetaObject::invokeMethod (this, "work", Qt::QueuedConnection, Q_ARG (int, i)); |
343 QMetaObject::invokeMethod (this, "work", Qt::QueuedConnection, Q_ARG (int, i)); |
343 else |
344 else |
344 work (i + 1); |
345 work (i + 1); |
345 } |
346 } |
346 } |
347 } |
348 // ============================================================================= |
349 // ============================================================================= |
349 // ----------------------------------------------------------------------------- |
350 // ----------------------------------------------------------------------------- |
350 void FileLoader::abort() |
351 void FileLoader::abort() |
351 { setAborted (true); |
352 { setAborted (true); |
352 |
353 |
353 if (concurrent()) |
354 if (isOnForeground()) |
354 g_aborted = true; |
355 g_aborted = true; |
355 } |
356 } |
356 |
357 |
357 // ============================================================================= |
358 // ============================================================================= |
358 // ----------------------------------------------------------------------------- |
359 // ----------------------------------------------------------------------------- |
368 lines << line; |
369 lines << line; |
369 |
370 |
370 f->rewind(); |
371 f->rewind(); |
371 |
372 |
372 FileLoader* loader = new FileLoader; |
373 FileLoader* loader = new FileLoader; |
373 loader->setWarningsPointer (numWarnings); |
374 loader->setWarnings (numWarnings); |
374 loader->setLines (lines); |
375 loader->setLines (lines); |
375 loader->setConcurrent (g_loadingMainFile); |
376 loader->setOnForeground (g_loadingMainFile); |
376 loader->start(); |
377 loader->start(); |
377 |
378 |
378 // After start() returns, if the loader isn't done yet, it's delaying |
379 // After start() returns, if the loader isn't done yet, it's delaying |
379 // its next iteration through the event loop. We need to catch this here |
380 // its next iteration through the event loop. We need to catch this here |
380 // by telling the event loop to tick, which will tick the file loader again. |
381 // by telling the event loop to tick, which will tick the file loader again. |
381 // We keep doing this until the file loader is ready. |
382 // We keep doing this until the file loader is ready. |
382 while (loader->done() == false) |
383 while (loader->isDone() == false) |
383 qApp->processEvents(); |
384 qApp->processEvents(); |
384 |
385 |
385 // If we wanted the success value, supply that now |
386 // If we wanted the success value, supply that now |
386 if (ok) |
387 if (ok) |
387 *ok = !loader->aborted(); |
388 *ok = !loader->isAborted(); |
388 |
389 |
389 objs = loader->objs(); |
390 objs = loader->getObjects(); |
390 return objs; |
391 return objs; |
391 } |
392 } |
392 |
393 |
393 // ============================================================================= |
394 // ============================================================================= |
394 // ----------------------------------------------------------------------------- |
395 // ----------------------------------------------------------------------------- |
444 setlocale (LC_ALL, "C"); |
445 setlocale (LC_ALL, "C"); |
445 |
446 |
446 // If we have unsaved changes, warn and give the option of saving. |
447 // If we have unsaved changes, warn and give the option of saving. |
447 if (hasUnsavedChanges()) |
448 if (hasUnsavedChanges()) |
448 { str message = fmt ("There are unsaved changes to %1. Should it be saved?", |
449 { str message = fmt ("There are unsaved changes to %1. Should it be saved?", |
449 (name().length() > 0) ? name() : "<anonymous>"); |
450 (getName().length() > 0) ? getName() : "<anonymous>"); |
450 |
451 |
451 int button = msgbox::question (g_win, "Unsaved Changes", message, |
452 int button = msgbox::question (g_win, "Unsaved Changes", message, |
452 (msgbox::Yes | msgbox::No | msgbox::Cancel), msgbox::Cancel); |
453 (msgbox::Yes | msgbox::No | msgbox::Cancel), msgbox::Cancel); |
453 |
454 |
454 switch (button) |
455 switch (button) |
455 { case msgbox::Yes: |
456 { case msgbox::Yes: |
456 |
457 |
457 // If we don't have a file path yet, we have to ask the user for one. |
458 // If we don't have a file path yet, we have to ask the user for one. |
458 if (name().length() == 0) |
459 if (getName().length() == 0) |
459 { str newpath = QFileDialog::getSaveFileName (g_win, "Save As", |
460 { str newpath = QFileDialog::getSaveFileName (g_win, "Save As", |
460 LDFile::current()->name(), "LDraw files (*.dat *.ldr)"); |
461 LDFile::current()->getName(), "LDraw files (*.dat *.ldr)"); |
461 |
462 |
462 if (newpath.length() == 0) |
463 if (newpath.length() == 0) |
463 return false; |
464 return false; |
464 |
465 |
465 setName (newpath); |
466 setName (newpath); |
466 } |
467 } |
467 |
468 |
468 if (!save()) |
469 if (!save()) |
469 { message = fmt (QObject::tr ("Failed to save %1: %2\nDo you still want to close?"), |
470 { message = fmt (QObject::tr ("Failed to save %1: %2\nDo you still want to close?"), |
470 name(), strerror (errno)); |
471 getName(), strerror (errno)); |
471 |
472 |
472 if (msgbox::critical (g_win, "Save Failure", message, |
473 if (msgbox::critical (g_win, "Save Failure", message, |
473 (msgbox::Yes | msgbox::No), msgbox::No) == msgbox::No) |
474 (msgbox::Yes | msgbox::No), msgbox::No) == msgbox::No) |
474 { return false; |
475 { return false; |
475 } |
476 } |
511 LDFile::closeInitialFile(); |
512 LDFile::closeInitialFile(); |
512 |
513 |
513 g_win->R()->setFile (f); |
514 g_win->R()->setFile (f); |
514 g_win->doFullRefresh(); |
515 g_win->doFullRefresh(); |
515 g_win->updateTitle(); |
516 g_win->updateTitle(); |
516 f->history().updateActions(); |
517 f->getHistory()->updateActions(); |
517 } |
518 } |
518 |
519 |
519 // ============================================================================= |
520 // ============================================================================= |
520 // ----------------------------------------------------------------------------- |
521 // ----------------------------------------------------------------------------- |
521 void addRecentFile (str path) |
522 void addRecentFile (str path) |
581 |
582 |
582 // ============================================================================= |
583 // ============================================================================= |
583 // ----------------------------------------------------------------------------- |
584 // ----------------------------------------------------------------------------- |
584 bool LDFile::save (str savepath) |
585 bool LDFile::save (str savepath) |
585 { if (!savepath.length()) |
586 { if (!savepath.length()) |
586 savepath = name(); |
587 savepath = getName(); |
587 |
588 |
588 File f (savepath, File::Write); |
589 File f (savepath, File::Write); |
589 |
590 |
590 if (!f) |
591 if (!f) |
591 return false; |
592 return false; |
594 // Only do this if the file is explicitly open. If it's saved into a directory |
595 // Only do this if the file is explicitly open. If it's saved into a directory |
595 // called "s" or "48", prepend that into the name. |
596 // called "s" or "48", prepend that into the name. |
596 LDComment* fpathComment = null; |
597 LDComment* fpathComment = null; |
597 LDObject* first = getObject (1); |
598 LDObject* first = getObject (1); |
598 |
599 |
599 if (!implicit() && first != null && first->getType() == LDObject::Comment) |
600 if (!isImplicit() && first != null && first->getType() == LDObject::Comment) |
600 { fpathComment = static_cast<LDComment*> (first); |
601 { fpathComment = static_cast<LDComment*> (first); |
601 |
602 |
602 if (fpathComment->text.left (6) == "Name: ") |
603 if (fpathComment->text.left (6) == "Name: ") |
603 { str newname; |
604 { str newname; |
604 str dir = basename (dirname (savepath)); |
605 str dir = basename (dirname (savepath)); |
612 } |
613 } |
613 } |
614 } |
614 |
615 |
615 // File is open, now save the model to it. Note that LDraw requires files to |
616 // File is open, now save the model to it. Note that LDraw requires files to |
616 // have DOS line endings, so we terminate the lines with \r\n. |
617 // have DOS line endings, so we terminate the lines with \r\n. |
617 for (LDObject* obj : objects()) |
618 for (LDObject* obj : getObjects()) |
618 f.write (obj->raw() + "\r\n"); |
619 f.write (obj->raw() + "\r\n"); |
619 |
620 |
620 // File is saved, now clean up. |
621 // File is saved, now clean up. |
621 f.close(); |
622 f.close(); |
622 |
623 |
623 // We have successfully saved, update the save position now. |
624 // We have successfully saved, update the save position now. |
624 setSavePos (history().pos()); |
625 setSavePosition (getHistory()->getPosition()); |
625 setName (savepath); |
626 setName (savepath); |
626 |
627 |
627 g_win->updateFileListItem (this); |
628 g_win->updateFileListItem (this); |
628 g_win->updateTitle(); |
629 g_win->updateTitle(); |
629 return true; |
630 return true; |
719 |
720 |
720 { CHECK_TOKEN_COUNT (9); |
721 { CHECK_TOKEN_COUNT (9); |
721 CHECK_TOKEN_NUMBERS (5, 8) |
722 CHECK_TOKEN_NUMBERS (5, 8) |
722 |
723 |
723 LDOverlay* obj = new LDOverlay; |
724 LDOverlay* obj = new LDOverlay; |
724 obj->setFilename (tokens[3]); |
725 obj->setFileName (tokens[3]); |
725 obj->setCamera (tokens[4].toLong()); |
726 obj->setCamera (tokens[4].toLong()); |
726 obj->setX (tokens[5].toLong()); |
727 obj->setX (tokens[5].toLong()); |
727 obj->setY (tokens[6].toLong()); |
728 obj->setY (tokens[6].toLong()); |
728 obj->setWidth (tokens[7].toLong()); |
729 obj->setWidth (tokens[7].toLong()); |
729 obj->setHeight (tokens[8].toLong()); |
730 obj->setHeight (tokens[8].toLong()); |
750 g_loadingMainFile = tmp; |
751 g_loadingMainFile = tmp; |
751 |
752 |
752 // If we cannot open the file, mark it an error |
753 // If we cannot open the file, mark it an error |
753 if (!load) |
754 if (!load) |
754 { LDError* obj = new LDError (line, fmt ("Could not open %1", tokens[14])); |
755 { LDError* obj = new LDError (line, fmt ("Could not open %1", tokens[14])); |
755 obj->setFileRef (tokens[14]); |
756 obj->setFileReferenced (tokens[14]); |
756 return obj; |
757 return obj; |
757 } |
758 } |
758 |
759 |
759 LDSubfile* obj = new LDSubfile; |
760 LDSubfile* obj = new LDSubfile; |
760 obj->setColor (tokens[1].toLong()); |
761 obj->setColor (tokens[1].toLong()); |
845 |
846 |
846 g_loadedFiles.clear(); |
847 g_loadedFiles.clear(); |
847 g_loadedFiles << LDFile::current(); |
848 g_loadedFiles << LDFile::current(); |
848 |
849 |
849 // Go through all objects in the current file and reload the subfiles |
850 // Go through all objects in the current file and reload the subfiles |
850 for (LDObject * obj : LDFile::current()->objects()) |
851 for (LDObject* obj : LDFile::current()->getObjects()) |
851 { if (obj->getType() == LDObject::Subfile) |
852 { if (obj->getType() == LDObject::Subfile) |
852 { LDSubfile* ref = static_cast<LDSubfile*> (obj); |
853 { LDSubfile* ref = static_cast<LDSubfile*> (obj); |
853 LDFile* fileInfo = getFile (ref->fileInfo()->name()); |
854 LDFile* fileInfo = getFile (ref->getFileInfo()->getName()); |
854 |
855 |
855 if (fileInfo) |
856 if (fileInfo) |
856 ref->setFileInfo (fileInfo); |
857 ref->setFileInfo (fileInfo); |
857 else |
858 else |
858 ref->replace (new LDError (ref->raw(), "Could not open referred file")); |
859 ref->replace (new LDError (ref->raw(), "Could not open referred file")); |
869 } |
870 } |
870 |
871 |
871 // ============================================================================= |
872 // ============================================================================= |
872 // ----------------------------------------------------------------------------- |
873 // ----------------------------------------------------------------------------- |
873 int LDFile::addObject (LDObject* obj) |
874 int LDFile::addObject (LDObject* obj) |
874 { m_history.add (new AddHistory (objects().size(), obj)); |
875 { getHistory()->add (new AddHistory (getObjects().size(), obj)); |
875 m_objects << obj; |
876 m_Objects << obj; |
876 |
877 |
877 if (obj->getType() == LDObject::Vertex) |
878 if (obj->getType() == LDObject::Vertex) |
878 m_vertices << obj; |
879 m_Vertices << obj; |
879 |
880 |
880 obj->setFile (this); |
881 obj->setFile (this); |
881 return getObjectCount() - 1; |
882 return getObjectCount() - 1; |
882 } |
883 } |
883 |
884 |
890 } |
891 } |
891 |
892 |
892 // ============================================================================= |
893 // ============================================================================= |
893 // ----------------------------------------------------------------------------- |
894 // ----------------------------------------------------------------------------- |
894 void LDFile::insertObj (int pos, LDObject* obj) |
895 void LDFile::insertObj (int pos, LDObject* obj) |
895 { m_history.add (new AddHistory (pos, obj)); |
896 { getHistory()->add (new AddHistory (pos, obj)); |
896 m_objects.insert (pos, obj); |
897 m_Objects.insert (pos, obj); |
897 obj->setFile (this); |
898 obj->setFile (this); |
898 } |
899 } |
899 |
900 |
900 // ============================================================================= |
901 // ============================================================================= |
901 // ----------------------------------------------------------------------------- |
902 // ----------------------------------------------------------------------------- |
902 void LDFile::forgetObject (LDObject* obj) |
903 void LDFile::forgetObject (LDObject* obj) |
903 { int idx = obj->getIndex(); |
904 { int idx = obj->getIndex(); |
904 m_history.add (new DelHistory (idx, obj)); |
905 getHistory()->add (new DelHistory (idx, obj)); |
905 m_objects.removeAt (idx); |
906 m_Objects.removeAt (idx); |
906 obj->setFile (null); |
907 obj->setFile (null); |
907 } |
908 } |
908 |
909 |
909 // ============================================================================= |
910 // ============================================================================= |
910 // ----------------------------------------------------------------------------- |
911 // ----------------------------------------------------------------------------- |
917 } |
918 } |
918 |
919 |
919 // ============================================================================= |
920 // ============================================================================= |
920 // ----------------------------------------------------------------------------- |
921 // ----------------------------------------------------------------------------- |
921 void LDFile::setObject (int idx, LDObject* obj) |
922 void LDFile::setObject (int idx, LDObject* obj) |
922 { assert (idx < m_objects.size()); |
923 { assert (idx < m_Objects.size()); |
923 |
924 |
924 // Mark this change to history |
925 // Mark this change to history |
925 str oldcode = getObject (idx)->raw(); |
926 str oldcode = getObject (idx)->raw(); |
926 str newcode = obj->raw(); |
927 str newcode = obj->raw(); |
927 m_history << new EditHistory (idx, oldcode, newcode); |
928 *m_History << new EditHistory (idx, oldcode, newcode); |
928 |
929 |
929 obj->setFile (this); |
930 obj->setFile (this); |
930 m_objects[idx] = obj; |
931 m_Objects[idx] = obj; |
931 } |
932 } |
932 |
933 |
933 // ============================================================================= |
934 // ============================================================================= |
934 // ----------------------------------------------------------------------------- |
935 // ----------------------------------------------------------------------------- |
935 static QList<LDFile*> getFilesUsed (LDFile* node) |
936 static QList<LDFile*> getFilesUsed (LDFile* node) |
936 { QList<LDFile*> filesUsed; |
937 { QList<LDFile*> filesUsed; |
937 |
938 |
938 for (LDObject* obj : node->objects()) |
939 for (LDObject* obj : node->getObjects()) |
939 { if (obj->getType() != LDObject::Subfile) |
940 { if (obj->getType() != LDObject::Subfile) |
940 continue; |
941 continue; |
941 |
942 |
942 LDSubfile* ref = static_cast<LDSubfile*> (obj); |
943 LDSubfile* ref = static_cast<LDSubfile*> (obj); |
943 filesUsed << ref->fileInfo(); |
944 filesUsed << ref->getFileInfo(); |
944 filesUsed << getFilesUsed (ref->fileInfo()); |
945 filesUsed << getFilesUsed (ref->getFileInfo()); |
945 } |
946 } |
946 |
947 |
947 return filesUsed; |
948 return filesUsed; |
948 } |
949 } |
949 |
950 |
953 void LDFile::closeUnused() |
954 void LDFile::closeUnused() |
954 { QList<LDFile*> filesUsed = getFilesUsed (LDFile::current()); |
955 { QList<LDFile*> filesUsed = getFilesUsed (LDFile::current()); |
955 |
956 |
956 // Anything that's explicitly opened must not be closed |
957 // Anything that's explicitly opened must not be closed |
957 for (LDFile* file : g_loadedFiles) |
958 for (LDFile* file : g_loadedFiles) |
958 if (!file->implicit()) |
959 if (!file->isImplicit()) |
959 filesUsed << file; |
960 filesUsed << file; |
960 |
961 |
961 // Remove duplicated entries |
962 // Remove duplicated entries |
962 removeDuplicates (filesUsed); |
963 removeDuplicates (filesUsed); |
963 |
964 |
981 } |
982 } |
982 |
983 |
983 // ============================================================================= |
984 // ============================================================================= |
984 // ----------------------------------------------------------------------------- |
985 // ----------------------------------------------------------------------------- |
985 LDObject* LDFile::getObject (int pos) const |
986 LDObject* LDFile::getObject (int pos) const |
986 { if (m_objects.size() <= pos) |
987 { if (m_Objects.size() <= pos) |
987 return null; |
988 return null; |
988 |
989 |
989 return m_objects[pos]; |
990 return m_Objects[pos]; |
990 } |
991 } |
991 |
992 |
992 // ============================================================================= |
993 // ============================================================================= |
993 // ----------------------------------------------------------------------------- |
994 // ----------------------------------------------------------------------------- |
994 int LDFile::getObjectCount() const |
995 int LDFile::getObjectCount() const |
995 { return objects().size(); |
996 { return getObjects().size(); |
996 } |
997 } |
997 |
998 |
998 // ============================================================================= |
999 // ============================================================================= |
999 // ----------------------------------------------------------------------------- |
1000 // ----------------------------------------------------------------------------- |
1000 bool LDFile::hasUnsavedChanges() const |
1001 bool LDFile::hasUnsavedChanges() const |
1001 { return !implicit() && history().pos() != savePos(); |
1002 { return !isImplicit() && getHistory()->getPosition() != getSavePosition(); |
1002 } |
1003 } |
1003 |
1004 |
1004 // ============================================================================= |
1005 // ============================================================================= |
1005 // ----------------------------------------------------------------------------- |
1006 // ----------------------------------------------------------------------------- |
1006 str LDFile::getShortName() |
1007 str LDFile::getShortName() |
1007 { if (!name().isEmpty()) |
1008 { if (!getName().isEmpty()) |
1008 return basename (name()); |
1009 return basename (getName()); |
1009 |
1010 |
1010 if (!defaultName().isEmpty()) |
1011 if (!getDefaultName().isEmpty()) |
1011 return defaultName(); |
1012 return getDefaultName(); |
1012 |
1013 |
1013 return tr ("<anonymous>"); |
1014 return tr ("<anonymous>"); |
1014 } |
1015 } |
1015 |
1016 |
1016 // ============================================================================= |
1017 // ============================================================================= |
1018 QList<LDObject*> LDFile::inlineContents (LDSubfile::InlineFlags flags) |
1019 QList<LDObject*> LDFile::inlineContents (LDSubfile::InlineFlags flags) |
1019 { // Possibly substitute with logoed studs: |
1020 { // Possibly substitute with logoed studs: |
1020 // stud.dat -> stud-logo.dat |
1021 // stud.dat -> stud-logo.dat |
1021 // stud2.dat -> stud-logo2.dat |
1022 // stud2.dat -> stud-logo2.dat |
1022 if (gl_logostuds && (flags & LDSubfile::RendererInline)) |
1023 if (gl_logostuds && (flags & LDSubfile::RendererInline)) |
1023 { if (name() == "stud.dat" && g_logoedStud) |
1024 { if (getName() == "stud.dat" && g_logoedStud) |
1024 return g_logoedStud->inlineContents (flags); |
1025 return g_logoedStud->inlineContents (flags); |
1025 |
1026 |
1026 elif (name() == "stud2.dat" && g_logoedStud2) |
1027 elif (getName() == "stud2.dat" && g_logoedStud2) |
1027 return g_logoedStud2->inlineContents (flags); |
1028 return g_logoedStud2->inlineContents (flags); |
1028 } |
1029 } |
1029 |
1030 |
1030 QList<LDObject*> objs, objcache; |
1031 QList<LDObject*> objs, objcache; |
1031 |
1032 |
1032 bool deep = flags & LDSubfile::DeepInline, |
1033 bool deep = flags & LDSubfile::DeepInline, |
1033 doCache = flags & LDSubfile::CacheInline; |
1034 doCache = flags & LDSubfile::CacheInline; |
1034 |
1035 |
1035 // If we have this cached, just clone that |
1036 // If we have this cached, just clone that |
1036 if (deep && cache().size()) |
1037 if (deep && getCache().size()) |
1037 { for (LDObject * obj : cache()) |
1038 { for (LDObject* obj : getCache()) |
1038 objs << obj->clone(); |
1039 objs << obj->clone(); |
1039 } |
1040 } |
1040 else |
1041 else |
1041 { if (!deep) |
1042 { if (!deep) |
1042 doCache = false; |
1043 doCache = false; |
1043 |
1044 |
1044 for (LDObject * obj : objects()) |
1045 for (LDObject* obj : getObjects()) |
1045 { // Skip those without scemantic meaning |
1046 { // Skip those without scemantic meaning |
1046 if (!obj->isScemantic()) |
1047 if (!obj->isScemantic()) |
1047 continue; |
1048 continue; |
1048 |
1049 |
1049 // Got another sub-file reference, inline it if we're deep-inlining. If not, |
1050 // Got another sub-file reference, inline it if we're deep-inlining. If not, |
1129 // a new file over it. |
1130 // a new file over it. |
1130 // ----------------------------------------------------------------------------- |
1131 // ----------------------------------------------------------------------------- |
1131 void LDFile::closeInitialFile() |
1132 void LDFile::closeInitialFile() |
1132 { if ( |
1133 { if ( |
1133 countExplicitFiles() == 2 && |
1134 countExplicitFiles() == 2 && |
1134 g_loadedFiles[0]->name() == "" && |
1135 g_loadedFiles[0]->getName() == "" && |
1135 !g_loadedFiles[0]->hasUnsavedChanges() |
1136 !g_loadedFiles[0]->hasUnsavedChanges() |
1136 ) |
1137 ) |
1137 delete g_loadedFiles[0]; |
1138 delete g_loadedFiles[0]; |
1138 } |
1139 } |
1139 |
1140 |
1150 } |
1151 } |
1151 |
1152 |
1152 // ============================================================================= |
1153 // ============================================================================= |
1153 // ----------------------------------------------------------------------------- |
1154 // ----------------------------------------------------------------------------- |
1154 void LDFile::addToSelection (LDObject* obj) // [protected] |
1155 void LDFile::addToSelection (LDObject* obj) // [protected] |
1155 { if (obj->selected()) |
1156 { if (obj->isSelected()) |
1156 return; |
1157 return; |
1157 |
1158 |
1158 assert (obj->file() == this); |
1159 assert (obj->getFile() == this); |
1159 m_sel << obj; |
1160 m_sel << obj; |
1160 obj->setSelected (true); |
1161 obj->setSelected (true); |
1161 } |
1162 } |
1162 |
1163 |
1163 // ============================================================================= |
1164 // ============================================================================= |
1164 // ----------------------------------------------------------------------------- |
1165 // ----------------------------------------------------------------------------- |
1165 void LDFile::removeFromSelection (LDObject* obj) // [protected] |
1166 void LDFile::removeFromSelection (LDObject* obj) // [protected] |
1166 { if (!obj->selected()) |
1167 { if (!obj->isSelected()) |
1167 return; |
1168 return; |
1168 |
1169 |
1169 assert (obj->file() == this); |
1170 assert (obj->getFile() == this); |
1170 m_sel.removeOne (obj); |
1171 m_sel.removeOne (obj); |
1171 obj->setSelected (false); |
1172 obj->setSelected (false); |
1172 } |
1173 } |
1173 |
1174 |
1174 // ============================================================================= |
1175 // ============================================================================= |