641:425b169a82aa | 642:751a8df42842 |
---|---|
44 LDDocument* LDDocument::m_curdoc = null; | 44 LDDocument* LDDocument::m_curdoc = null; |
45 | 45 |
46 const QStringList g_specialSubdirectories ({ "s", "48", "8" }); | 46 const QStringList g_specialSubdirectories ({ "s", "48", "8" }); |
47 | 47 |
48 // ============================================================================= | 48 // ============================================================================= |
49 // ============================================================================= | 49 // |
50 namespace LDPaths | 50 namespace LDPaths |
51 { | 51 { |
52 static QString pathError; | 52 static QString pathError; |
53 | 53 |
54 struct | 54 struct |
117 return pathInfo.partsPath; | 117 return pathInfo.partsPath; |
118 } | 118 } |
119 } | 119 } |
120 | 120 |
121 // ============================================================================= | 121 // ============================================================================= |
122 // ============================================================================= | 122 // |
123 LDDocument::LDDocument() : | 123 LDDocument::LDDocument() : |
124 m_gldata (new LDGLData) | 124 m_gldata (new LDGLData) |
125 { | 125 { |
126 setImplicit (true); | 126 setImplicit (true); |
127 setSavePosition (-1); | 127 setSavePosition (-1); |
128 setTabIndex (-1); | 128 setTabIndex (-1); |
129 setHistory (new History); | 129 setHistory (new History); |
130 m_History->setDocument (this); | 130 history()->setDocument (this); |
131 } | 131 } |
132 | 132 |
133 // ============================================================================= | 133 // ============================================================================= |
134 // ============================================================================= | 134 // |
135 LDDocument::~LDDocument() | 135 LDDocument::~LDDocument() |
136 { | 136 { |
137 // Remove this file from the list of files. This MUST be done FIRST, otherwise | 137 // Remove this file from the list of files. This MUST be done FIRST, otherwise |
138 // a ton of other functions will think this file is still valid when it is not! | 138 // a ton of other functions will think this file is still valid when it is not! |
139 g_loadedFiles.removeOne (this); | 139 g_loadedFiles.removeOne (this); |
140 | 140 |
141 m_History->setIgnoring (true); | 141 m_history->setIgnoring (true); |
142 | 142 |
143 // Clear everything from the model | 143 // Clear everything from the model |
144 for (LDObject* obj : getObjects()) | 144 for (LDObject* obj : objects()) |
145 obj->destroy(); | 145 obj->destroy(); |
146 | 146 |
147 // Clear the cache as well | 147 // Clear the cache as well |
148 for (LDObject* obj : getCache()) | 148 for (LDObject* obj : cache()) |
149 obj->destroy(); | 149 obj->destroy(); |
150 | 150 |
151 delete m_History; | 151 delete m_history; |
152 delete m_gldata; | 152 delete m_gldata; |
153 | 153 |
154 // If we just closed the current file, we need to set the current | 154 // If we just closed the current file, we need to set the current |
155 // file as something else. | 155 // file as something else. |
156 if (this == getCurrentDocument()) | 156 if (this == getCurrentDocument()) |
177 g_logoedStud = null; | 177 g_logoedStud = null; |
178 elif (this == g_logoedStud2) | 178 elif (this == g_logoedStud2) |
179 g_logoedStud2 = null; | 179 g_logoedStud2 = null; |
180 | 180 |
181 g_win->updateDocumentList(); | 181 g_win->updateDocumentList(); |
182 log ("Closed %1", getName()); | 182 log ("Closed %1", name()); |
183 } | 183 } |
184 | 184 |
185 // ============================================================================= | 185 // ============================================================================= |
186 // ============================================================================= | 186 // |
187 LDDocument* findDocument (QString name) | 187 LDDocument* findDocument (QString name) |
188 { | 188 { |
189 for (LDDocument * file : g_loadedFiles) | 189 for (LDDocument * file : g_loadedFiles) |
190 if (!file->getName().isEmpty() && file->getName() == name) | 190 if (!file->name().isEmpty() && file->name() == name) |
191 return file; | 191 return file; |
192 | 192 |
193 return null; | 193 return null; |
194 } | 194 } |
195 | 195 |
196 // ============================================================================= | 196 // ============================================================================= |
197 // ============================================================================= | 197 // |
198 QString dirname (QString path) | 198 QString dirname (QString path) |
199 { | 199 { |
200 long lastpos = path.lastIndexOf (DIRSLASH); | 200 long lastpos = path.lastIndexOf (DIRSLASH); |
201 | 201 |
202 if (lastpos > 0) | 202 if (lastpos > 0) |
209 | 209 |
210 return ""; | 210 return ""; |
211 } | 211 } |
212 | 212 |
213 // ============================================================================= | 213 // ============================================================================= |
214 // ============================================================================= | 214 // |
215 QString basename (QString path) | 215 QString basename (QString path) |
216 { | 216 { |
217 long lastpos = path.lastIndexOf (DIRSLASH); | 217 long lastpos = path.lastIndexOf (DIRSLASH); |
218 | 218 |
219 if (lastpos != -1) | 219 if (lastpos != -1) |
221 | 221 |
222 return path; | 222 return path; |
223 } | 223 } |
224 | 224 |
225 // ============================================================================= | 225 // ============================================================================= |
226 // ============================================================================= | 226 // |
227 static QString findLDrawFilePath (QString relpath, bool subdirs) | 227 static QString findLDrawFilePath (QString relpath, bool subdirs) |
228 { | 228 { |
229 QString fullPath; | 229 QString fullPath; |
230 | 230 |
231 // LDraw models use Windows-style path separators. If we're not on Windows, | 231 // LDraw models use Windows-style path separators. If we're not on Windows, |
239 // in the immediate vicinity of a current model to override stock LDraw stuff. | 239 // in the immediate vicinity of a current model to override stock LDraw stuff. |
240 QString reltop = basename (dirname (relpath)); | 240 QString reltop = basename (dirname (relpath)); |
241 | 241 |
242 for (LDDocument* doc : g_loadedFiles) | 242 for (LDDocument* doc : g_loadedFiles) |
243 { | 243 { |
244 if (doc->getFullPath().isEmpty()) | 244 if (doc->fullPath().isEmpty()) |
245 continue; | 245 continue; |
246 | 246 |
247 QString partpath = fmt ("%1/%2", dirname (doc->getFullPath()), relpath); | 247 QString partpath = fmt ("%1/%2", dirname (doc->fullPath()), relpath); |
248 QFile f (partpath); | 248 QFile f (partpath); |
249 | 249 |
250 if (f.exists()) | 250 if (f.exists()) |
251 { | 251 { |
252 // ensure we don't mix subfiles and 48-primitives with non-subfiles and non-48 | 252 // ensure we don't mix subfiles and 48-primitives with non-subfiles and non-48 |
316 fp->deleteLater(); | 316 fp->deleteLater(); |
317 return null; | 317 return null; |
318 } | 318 } |
319 | 319 |
320 // ============================================================================= | 320 // ============================================================================= |
321 // ============================================================================= | 321 // |
322 void LDFileLoader::start() | 322 void LDFileLoader::start() |
323 { | 323 { |
324 setDone (false); | 324 setDone (false); |
325 setProgress (0); | 325 setProgress (0); |
326 setAborted (false); | 326 setAborted (false); |
332 // Show a progress dialog if we're loading the main Document.here so we can | 332 // Show a progress dialog if we're loading the main Document.here so we can |
333 // show progress updates and keep the WM posted that we're still here. | 333 // show progress updates and keep the WM posted that we're still here. |
334 // Of course we cannot exec() the dialog because then the dialog would | 334 // Of course we cannot exec() the dialog because then the dialog would |
335 // block. | 335 // block. |
336 dlg = new OpenProgressDialog (g_win); | 336 dlg = new OpenProgressDialog (g_win); |
337 dlg->setNumLines (getLines().size()); | 337 dlg->setNumLines (lines().size()); |
338 dlg->setModal (true); | 338 dlg->setModal (true); |
339 dlg->show(); | 339 dlg->show(); |
340 | 340 |
341 // Connect the loader in so we can show updates | 341 // Connect the loader in so we can show updates |
342 connect (this, SIGNAL (workDone()), dlg, SLOT (accept())); | 342 connect (this, SIGNAL (workDone()), dlg, SLOT (accept())); |
348 // Begin working | 348 // Begin working |
349 work (0); | 349 work (0); |
350 } | 350 } |
351 | 351 |
352 // ============================================================================= | 352 // ============================================================================= |
353 // ============================================================================= | 353 // |
354 void LDFileLoader::work (int i) | 354 void LDFileLoader::work (int i) |
355 { | 355 { |
356 // User wishes to abort, so stop here now. | 356 // User wishes to abort, so stop here now. |
357 if (isAborted()) | 357 if (isAborted()) |
358 { | 358 { |
359 for (LDObject* obj : m_Objects) | 359 for (LDObject* obj : m_objects) |
360 obj->destroy(); | 360 obj->destroy(); |
361 | 361 |
362 m_Objects.clear(); | 362 m_objects.clear(); |
363 setDone (true); | 363 setDone (true); |
364 return; | 364 return; |
365 } | 365 } |
366 | 366 |
367 // Parse up to 300 lines per iteration | 367 // Parse up to 300 lines per iteration |
368 int max = i + 300; | 368 int max = i + 300; |
369 | 369 |
370 for (; i < max && i < (int) getLines().size(); ++i) | 370 for (; i < max && i < (int) lines().size(); ++i) |
371 { | 371 { |
372 QString line = getLines()[i]; | 372 QString line = lines()[i]; |
373 | 373 |
374 // Trim the trailing newline | 374 // Trim the trailing newline |
375 QChar c; | 375 QChar c; |
376 | 376 |
377 while (line.endsWith ("\n") || line.endsWith ("\r")) | 377 while (line.endsWith ("\n") || line.endsWith ("\r")) |
380 LDObject* obj = parseLine (line); | 380 LDObject* obj = parseLine (line); |
381 | 381 |
382 // Check for parse errors and warn about tthem | 382 // Check for parse errors and warn about tthem |
383 if (obj->type() == LDObject::EError) | 383 if (obj->type() == LDObject::EError) |
384 { | 384 { |
385 log ("Couldn't parse line #%1: %2", getProgress() + 1, static_cast<LDError*> (obj)->reason); | 385 log ("Couldn't parse line #%1: %2", progress() + 1, static_cast<LDError*> (obj)->reason()); |
386 | 386 |
387 if (getWarnings() != null) | 387 if (warnings() != null) |
388 (*getWarnings())++; | 388 (*warnings())++; |
389 } | 389 } |
390 | 390 |
391 m_Objects << obj; | 391 m_objects << obj; |
392 setProgress (i); | 392 setProgress (i); |
393 | 393 |
394 // If we have a dialog pointer, update the progress now | 394 // If we have a dialog pointer, update the progress now |
395 if (isOnForeground()) | 395 if (isOnForeground()) |
396 dlg->updateProgress (i); | 396 dlg->updateProgress (i); |
397 } | 397 } |
398 | 398 |
399 // If we're done now, tell the environment we're done and stop. | 399 // If we're done now, tell the environment we're done and stop. |
400 if (i >= ((int) getLines().size()) - 1) | 400 if (i >= ((int) lines().size()) - 1) |
401 { | 401 { |
402 emit workDone(); | 402 emit workDone(); |
403 setDone (true); | 403 setDone (true); |
404 return; | 404 return; |
405 } | 405 } |
423 work (i); | 423 work (i); |
424 } | 424 } |
425 } | 425 } |
426 | 426 |
427 // ============================================================================= | 427 // ============================================================================= |
428 // ============================================================================= | 428 // |
429 void LDFileLoader::abort() | 429 void LDFileLoader::abort() |
430 { | 430 { |
431 setAborted (true); | 431 setAborted (true); |
432 | 432 |
433 if (isOnForeground()) | 433 if (isOnForeground()) |
434 g_aborted = true; | 434 g_aborted = true; |
435 } | 435 } |
436 | 436 |
437 // ============================================================================= | 437 // ============================================================================= |
438 // ============================================================================= | 438 // |
439 LDObjectList loadFileContents (QFile* fp, int* numWarnings, bool* ok) | 439 LDObjectList loadFileContents (QFile* fp, int* numWarnings, bool* ok) |
440 { | 440 { |
441 QStringList lines; | 441 QStringList lines; |
442 LDObjectList objs; | 442 LDObjectList objs; |
443 | 443 |
463 | 463 |
464 // If we wanted the success value, supply that now | 464 // If we wanted the success value, supply that now |
465 if (ok) | 465 if (ok) |
466 *ok = !loader->isAborted(); | 466 *ok = !loader->isAborted(); |
467 | 467 |
468 objs = loader->getObjects(); | 468 objs = loader->objects(); |
469 return objs; | 469 return objs; |
470 } | 470 } |
471 | 471 |
472 // ============================================================================= | 472 // ============================================================================= |
473 // ============================================================================= | 473 // |
474 LDDocument* openDocument (QString path, bool search) | 474 LDDocument* openDocument (QString path, bool search) |
475 { | 475 { |
476 // Convert the file name to lowercase since some parts contain uppercase | 476 // Convert the file name to lowercase since some parts contain uppercase |
477 // file names. I'll assume here that the library will always use lowercase | 477 // file names. I'll assume here that the library will always use lowercase |
478 // file names for the actual parts.. | 478 // file names for the actual parts.. |
496 if (!fp) | 496 if (!fp) |
497 return null; | 497 return null; |
498 | 498 |
499 LDDocument* load = new LDDocument; | 499 LDDocument* load = new LDDocument; |
500 load->setFullPath (fullpath); | 500 load->setFullPath (fullpath); |
501 load->setName (LDDocument::shortenName (load->getFullPath())); | 501 load->setName (LDDocument::shortenName (load->fullPath())); |
502 dlog ("name: %1 (%2)", load->getName(), load->getFullPath()); | 502 dlog ("name: %1 (%2)", load->name(), load->fullPath()); |
503 g_loadedFiles << load; | 503 g_loadedFiles << load; |
504 | 504 |
505 // Don't take the file loading as actual edits to the file | 505 // Don't take the file loading as actual edits to the file |
506 load->getHistory()->setIgnoring (true); | 506 load->history()->setIgnoring (true); |
507 | 507 |
508 int numWarnings; | 508 int numWarnings; |
509 bool ok; | 509 bool ok; |
510 LDObjectList objs = loadFileContents (fp, &numWarnings, &ok); | 510 LDObjectList objs = loadFileContents (fp, &numWarnings, &ok); |
511 fp->close(); | 511 fp->close(); |
521 load->addObjects (objs); | 521 load->addObjects (objs); |
522 | 522 |
523 if (g_loadingMainFile) | 523 if (g_loadingMainFile) |
524 { | 524 { |
525 LDDocument::setCurrent (load); | 525 LDDocument::setCurrent (load); |
526 g_win->R()->setFile (load); | 526 g_win->R()->setDocument (load); |
527 log (QObject::tr ("File %1 parsed successfully (%2 errors)."), path, numWarnings); | 527 log (QObject::tr ("File %1 parsed successfully (%2 errors)."), path, numWarnings); |
528 } | 528 } |
529 | 529 |
530 load->getHistory()->setIgnoring (false); | 530 load->history()->setIgnoring (false); |
531 return load; | 531 return load; |
532 } | 532 } |
533 | 533 |
534 // ============================================================================= | 534 // ============================================================================= |
535 // ============================================================================= | 535 // |
536 bool LDDocument::isSafeToClose() | 536 bool LDDocument::isSafeToClose() |
537 { | 537 { |
538 typedef QMessageBox msgbox; | 538 typedef QMessageBox msgbox; |
539 setlocale (LC_ALL, "C"); | 539 setlocale (LC_ALL, "C"); |
540 | 540 |
541 // If we have unsaved changes, warn and give the option of saving. | 541 // If we have unsaved changes, warn and give the option of saving. |
542 if (hasUnsavedChanges()) | 542 if (hasUnsavedChanges()) |
543 { | 543 { |
544 QString message = fmt (tr ("There are unsaved changes to %1. Should it be saved?"), | 544 QString message = fmt (tr ("There are unsaved changes to %1. Should it be saved?"), |
545 (getName().length() > 0) ? getName() : tr ("<anonymous>")); | 545 (name().length() > 0) ? name() : tr ("<anonymous>")); |
546 | 546 |
547 int button = msgbox::question (g_win, tr ("Unsaved Changes"), message, | 547 int button = msgbox::question (g_win, tr ("Unsaved Changes"), message, |
548 (msgbox::Yes | msgbox::No | msgbox::Cancel), msgbox::Cancel); | 548 (msgbox::Yes | msgbox::No | msgbox::Cancel), msgbox::Cancel); |
549 | 549 |
550 switch (button) | 550 switch (button) |
551 { | 551 { |
552 case msgbox::Yes: | 552 case msgbox::Yes: |
553 { | 553 { |
554 // If we don't have a file path yet, we have to ask the user for one. | 554 // If we don't have a file path yet, we have to ask the user for one. |
555 if (getName().length() == 0) | 555 if (name().length() == 0) |
556 { | 556 { |
557 QString newpath = QFileDialog::getSaveFileName (g_win, tr ("Save As"), | 557 QString newpath = QFileDialog::getSaveFileName (g_win, tr ("Save As"), |
558 getCurrentDocument()->getName(), tr ("LDraw files (*.dat *.ldr)")); | 558 getCurrentDocument()->name(), tr ("LDraw files (*.dat *.ldr)")); |
559 | 559 |
560 if (newpath.length() == 0) | 560 if (newpath.length() == 0) |
561 return false; | 561 return false; |
562 | 562 |
563 setName (newpath); | 563 setName (newpath); |
564 } | 564 } |
565 | 565 |
566 if (!save()) | 566 if (!save()) |
567 { | 567 { |
568 message = fmt (tr ("Failed to save %1 (%2)\nDo you still want to close?"), | 568 message = fmt (tr ("Failed to save %1 (%2)\nDo you still want to close?"), |
569 getName(), strerror (errno)); | 569 name(), strerror (errno)); |
570 | 570 |
571 if (msgbox::critical (g_win, tr ("Save Failure"), message, | 571 if (msgbox::critical (g_win, tr ("Save Failure"), message, |
572 (msgbox::Yes | msgbox::No), msgbox::No) == msgbox::No) | 572 (msgbox::Yes | msgbox::No), msgbox::No) == msgbox::No) |
573 { | 573 { |
574 return false; | 574 return false; |
586 | 586 |
587 return true; | 587 return true; |
588 } | 588 } |
589 | 589 |
590 // ============================================================================= | 590 // ============================================================================= |
591 // ============================================================================= | 591 // |
592 void closeAll() | 592 void closeAll() |
593 { | 593 { |
594 // Remove all loaded files and the objects they contain | 594 // Remove all loaded files and the objects they contain |
595 QList<LDDocument*> files = g_loadedFiles; | 595 QList<LDDocument*> files = g_loadedFiles; |
596 | 596 |
597 for (LDDocument* file : files) | 597 for (LDDocument* file : files) |
598 delete file; | 598 delete file; |
599 } | 599 } |
600 | 600 |
601 // ============================================================================= | 601 // ============================================================================= |
602 // ============================================================================= | 602 // |
603 void newFile() | 603 void newFile() |
604 { | 604 { |
605 // Create a new anonymous file and set it to our current | 605 // Create a new anonymous file and set it to our current |
606 LDDocument* f = new LDDocument; | 606 LDDocument* f = new LDDocument; |
607 f->setName (""); | 607 f->setName (""); |
608 f->setImplicit (false); | 608 f->setImplicit (false); |
609 g_loadedFiles << f; | 609 g_loadedFiles << f; |
610 LDDocument::setCurrent (f); | 610 LDDocument::setCurrent (f); |
611 LDDocument::closeInitialFile(); | 611 LDDocument::closeInitialFile(); |
612 g_win->R()->setFile (f); | 612 g_win->R()->setDocument (f); |
613 g_win->doFullRefresh(); | 613 g_win->doFullRefresh(); |
614 g_win->updateTitle(); | 614 g_win->updateTitle(); |
615 g_win->updateActions(); | 615 g_win->updateActions(); |
616 } | 616 } |
617 | 617 |
618 // ============================================================================= | 618 // ============================================================================= |
619 // ============================================================================= | 619 // |
620 void addRecentFile (QString path) | 620 void addRecentFile (QString path) |
621 { | 621 { |
622 auto& rfiles = io_recentfiles; | 622 auto& rfiles = io_recentfiles; |
623 int idx = rfiles.indexOf (path); | 623 int idx = rfiles.indexOf (path); |
624 | 624 |
654 LDDocument* documentToReplace = null; | 654 LDDocument* documentToReplace = null; |
655 QString shortName = LDDocument::shortenName (path); | 655 QString shortName = LDDocument::shortenName (path); |
656 | 656 |
657 for (LDDocument* doc : g_loadedFiles) | 657 for (LDDocument* doc : g_loadedFiles) |
658 { | 658 { |
659 if (doc->getName() == shortName) | 659 if (doc->name() == shortName) |
660 { | 660 { |
661 documentToReplace = doc; | 661 documentToReplace = doc; |
662 break; | 662 break; |
663 } | 663 } |
664 } | 664 } |
693 file->setImplicit (false); | 693 file->setImplicit (false); |
694 | 694 |
695 // Replace references to the old file with the new file. | 695 // Replace references to the old file with the new file. |
696 if (documentToReplace != null) | 696 if (documentToReplace != null) |
697 { | 697 { |
698 for (LDDocumentPointer* ptr : documentToReplace->getReferences()) | 698 for (LDDocumentPointer* ptr : documentToReplace->references()) |
699 { dlog ("ptr: %1 (%2)\n", | 699 { dlog ("ptr: %1 (%2)\n", |
700 ptr, ptr->getPointer() ? ptr->getPointer()->getName() : "<null>"); | 700 ptr, ptr->pointer() ? ptr->pointer()->name() : "<null>"); |
701 | 701 |
702 ptr->operator= (file); | 702 *ptr = file; |
703 } | 703 } |
704 | 704 |
705 assert (documentToReplace->countReferences() == 0); | 705 assert (documentToReplace->references().isEmpty()); |
706 delete documentToReplace; | 706 delete documentToReplace; |
707 } | 707 } |
708 | 708 |
709 // If we have an anonymous, unchanged file open as the only open file | 709 // If we have an anonymous, unchanged file open as the only open file |
710 // (aside of the one we just opened), close it now. | 710 // (aside of the one we just opened), close it now. |
718 addRecentFile (path); | 718 addRecentFile (path); |
719 g_loadingMainFile = false; | 719 g_loadingMainFile = false; |
720 } | 720 } |
721 | 721 |
722 // ============================================================================= | 722 // ============================================================================= |
723 // ============================================================================= | 723 // |
724 bool LDDocument::save (QString savepath) | 724 bool LDDocument::save (QString savepath) |
725 { | 725 { |
726 if (!savepath.length()) | 726 if (!savepath.length()) |
727 savepath = getFullPath(); | 727 savepath = fullPath(); |
728 | 728 |
729 QFile f (savepath); | 729 QFile f (savepath); |
730 | 730 |
731 if (!f.open (QIODevice::WriteOnly)) | 731 if (!f.open (QIODevice::WriteOnly)) |
732 return false; | 732 return false; |
737 | 737 |
738 if (!isImplicit() && nameObject != null && nameObject->type() == LDObject::EComment) | 738 if (!isImplicit() && nameObject != null && nameObject->type() == LDObject::EComment) |
739 { | 739 { |
740 LDComment* nameComment = static_cast<LDComment*> (nameObject); | 740 LDComment* nameComment = static_cast<LDComment*> (nameObject); |
741 | 741 |
742 if (nameComment->text.left (6) == "Name: ") | 742 if (nameComment->text().left (6) == "Name: ") |
743 { | 743 { |
744 QString newname = shortenName (savepath); | 744 QString newname = shortenName (savepath); |
745 nameComment->text = fmt ("Name: %1", newname); | 745 nameComment->setText (fmt ("Name: %1", newname)); |
746 g_win->buildObjList(); | 746 g_win->buildObjList(); |
747 } | 747 } |
748 } | 748 } |
749 | 749 |
750 // File is open, now save the model to it. Note that LDraw requires files to | 750 // File is open, now save the model to it. Note that LDraw requires files to |
751 // have DOS line endings, so we terminate the lines with \r\n. | 751 // have DOS line endings, so we terminate the lines with \r\n. |
752 for (LDObject* obj : getObjects()) | 752 for (LDObject* obj : objects()) |
753 f.write ((obj->asText() + "\r\n").toUtf8()); | 753 f.write ((obj->asText() + "\r\n").toUtf8()); |
754 | 754 |
755 // File is saved, now clean up. | 755 // File is saved, now clean up. |
756 f.close(); | 756 f.close(); |
757 | 757 |
758 // We have successfully saved, update the save position now. | 758 // We have successfully saved, update the save position now. |
759 setSavePosition (getHistory()->getPosition()); | 759 setSavePosition (history()->position()); |
760 setFullPath (savepath); | 760 setFullPath (savepath); |
761 setName (shortenName (savepath)); | 761 setName (shortenName (savepath)); |
762 | 762 |
763 g_win->updateDocumentListItem (this); | 763 g_win->updateDocumentListItem (this); |
764 g_win->updateTitle(); | 764 g_win->updateTitle(); |
765 return true; | 765 return true; |
766 } | 766 } |
767 | 767 |
768 // ============================================================================= | 768 // ============================================================================= |
769 // ============================================================================= | 769 // |
770 class LDParseError : public std::exception | 770 class LDParseError : public std::exception |
771 { | 771 { |
772 PROPERTY (private, QString, Error, STR_OPS, STOCK_WRITE) | 772 PROPERTY (private, QString, error, setError, STOCK_WRITE) |
773 PROPERTY (private, QString, Line, STR_OPS, STOCK_WRITE) | 773 PROPERTY (private, QString, line, setLine, STOCK_WRITE) |
774 | 774 |
775 public: | 775 public: |
776 LDParseError (QString line, QString a) : m_Error (a), m_Line (line) {} | 776 LDParseError (QString line, QString a) : |
777 m_error (a), | |
778 m_line (line) {} | |
777 | 779 |
778 const char* what() const throw() | 780 const char* what() const throw() |
779 { | 781 { |
780 return getError().toLocal8Bit().constData(); | 782 return qPrintable (error()); |
781 } | 783 } |
782 }; | 784 }; |
783 | 785 |
784 // ============================================================================= | 786 // ============================================================================= |
785 // ============================================================================= | 787 // |
786 void checkTokenCount (QString line, const QStringList& tokens, int num) | 788 void checkTokenCount (QString line, const QStringList& tokens, int num) |
787 { | 789 { |
788 if (tokens.size() != num) | 790 if (tokens.size() != num) |
789 throw LDParseError (line, fmt ("Bad amount of tokens, expected %1, got %2", num, tokens.size())); | 791 throw LDParseError (line, fmt ("Bad amount of tokens, expected %1, got %2", num, tokens.size())); |
790 } | 792 } |
791 | 793 |
792 // ============================================================================= | 794 // ============================================================================= |
793 // ============================================================================= | 795 // |
794 void checkTokenNumbers (QString line, const QStringList& tokens, int min, int max) | 796 void checkTokenNumbers (QString line, const QStringList& tokens, int min, int max) |
795 { | 797 { |
796 bool ok; | 798 bool ok; |
797 | 799 |
798 // Check scientific notation, e.g. 7.99361e-15 | 800 // Check scientific notation, e.g. 7.99361e-15 |
806 throw LDParseError (line, fmt ("Token #%1 was `%2`, expected a number (matched length: %3)", (i + 1), tokens[i], scient.matchedLength())); | 808 throw LDParseError (line, fmt ("Token #%1 was `%2`, expected a number (matched length: %3)", (i + 1), tokens[i], scient.matchedLength())); |
807 } | 809 } |
808 } | 810 } |
809 | 811 |
810 // ============================================================================= | 812 // ============================================================================= |
811 // ============================================================================= | 813 // |
812 static Vertex parseVertex (QStringList& s, const int n) | 814 static Vertex parseVertex (QStringList& s, const int n) |
813 { | 815 { |
814 Vertex v; | 816 Vertex v; |
815 | 817 |
816 for_axes (ax) | 818 for_axes (ax) |
906 } | 908 } |
907 } | 909 } |
908 | 910 |
909 // Just a regular comment: | 911 // Just a regular comment: |
910 LDComment* obj = new LDComment; | 912 LDComment* obj = new LDComment; |
911 obj->text = comm; | 913 obj->setText (comm); |
912 return obj; | 914 return obj; |
913 } | 915 } |
914 | 916 |
915 case 1: | 917 case 1: |
916 { | 918 { |
1004 throw LDError (line, "Unknown line code number"); | 1006 throw LDError (line, "Unknown line code number"); |
1005 } | 1007 } |
1006 } | 1008 } |
1007 catch (LDParseError& e) | 1009 catch (LDParseError& e) |
1008 { | 1010 { |
1009 return new LDError (e.getLine(), e.getError()); | 1011 return new LDError (e.line(), e.error()); |
1010 } | 1012 } |
1011 } | 1013 } |
1012 | 1014 |
1013 // ============================================================================= | 1015 // ============================================================================= |
1014 // ============================================================================= | 1016 // |
1015 LDDocument* getDocument (QString filename) | 1017 LDDocument* getDocument (QString filename) |
1016 { | 1018 { |
1017 // Try find the file in the list of loaded files | 1019 // Try find the file in the list of loaded files |
1018 LDDocument* doc = findDocument (filename); | 1020 LDDocument* doc = findDocument (filename); |
1019 | 1021 |
1023 | 1025 |
1024 return doc; | 1026 return doc; |
1025 } | 1027 } |
1026 | 1028 |
1027 // ============================================================================= | 1029 // ============================================================================= |
1028 // ============================================================================= | 1030 // |
1029 void reloadAllSubfiles() | 1031 void reloadAllSubfiles() |
1030 { | 1032 { |
1031 if (!getCurrentDocument()) | 1033 if (!getCurrentDocument()) |
1032 return; | 1034 return; |
1033 | 1035 |
1034 g_loadedFiles.clear(); | 1036 g_loadedFiles.clear(); |
1035 g_loadedFiles << getCurrentDocument(); | 1037 g_loadedFiles << getCurrentDocument(); |
1036 | 1038 |
1037 // Go through all objects in the current file and reload the subfiles | 1039 // Go through all objects in the current file and reload the subfiles |
1038 for (LDObject* obj : getCurrentDocument()->getObjects()) | 1040 for (LDObject* obj : getCurrentDocument()->objects()) |
1039 { | 1041 { |
1040 if (obj->type() == LDObject::ESubfile) | 1042 if (obj->type() == LDObject::ESubfile) |
1041 { | 1043 { |
1042 LDSubfile* ref = static_cast<LDSubfile*> (obj); | 1044 LDSubfile* ref = static_cast<LDSubfile*> (obj); |
1043 LDDocument* fileInfo = getDocument (ref->getFileInfo()->getName()); | 1045 LDDocument* fileInfo = getDocument (ref->fileInfo()->name()); |
1044 | 1046 |
1045 if (fileInfo) | 1047 if (fileInfo) |
1046 ref->setFileInfo (fileInfo); | 1048 ref->setFileInfo (fileInfo); |
1047 else | 1049 else |
1048 ref->replace (new LDError (ref->asText(), fmt ("Could not open %1", ref->getFileInfo()->getName()))); | 1050 ref->replace (new LDError (ref->asText(), fmt ("Could not open %1", ref->fileInfo()->name()))); |
1049 } | 1051 } |
1050 | 1052 |
1051 // Reparse gibberish files. It could be that they are invalid because | 1053 // Reparse gibberish files. It could be that they are invalid because |
1052 // of loading errors. Circumstances may be different now. | 1054 // of loading errors. Circumstances may be different now. |
1053 if (obj->type() == LDObject::EError) | 1055 if (obj->type() == LDObject::EError) |
1054 obj->replace (parseLine (static_cast<LDError*> (obj)->contents)); | 1056 obj->replace (parseLine (static_cast<LDError*> (obj)->contents())); |
1055 } | 1057 } |
1056 } | 1058 } |
1057 | 1059 |
1058 // ============================================================================= | 1060 // ============================================================================= |
1059 // ============================================================================= | 1061 // |
1060 int LDDocument::addObject (LDObject* obj) | 1062 int LDDocument::addObject (LDObject* obj) |
1061 { | 1063 { |
1062 getHistory()->add (new AddHistory (getObjects().size(), obj)); | 1064 history()->add (new AddHistory (objects().size(), obj)); |
1063 m_Objects << obj; | 1065 m_objects << obj; |
1064 | 1066 |
1065 if (obj->type() == LDObject::EVertex) | 1067 if (obj->type() == LDObject::EVertex) |
1066 m_Vertices << obj; | 1068 m_vertices << obj; |
1067 | 1069 |
1068 #ifdef DEBUG | 1070 #ifdef DEBUG |
1069 if (!isImplicit()) | 1071 if (!isImplicit()) |
1070 dlog ("Added object #%1 (%2)\n", obj->getID(), obj->typeName()); | 1072 dlog ("Added object #%1 (%2)\n", obj->id(), obj->typeName()); |
1071 #endif | 1073 #endif |
1072 | 1074 |
1073 obj->setFile (this); | 1075 obj->setDocument (this); |
1074 return getObjectCount() - 1; | 1076 return getObjectCount() - 1; |
1075 } | 1077 } |
1076 | 1078 |
1077 // ============================================================================= | 1079 // ============================================================================= |
1078 // ============================================================================= | 1080 // |
1079 void LDDocument::addObjects (const LDObjectList objs) | 1081 void LDDocument::addObjects (const LDObjectList objs) |
1080 { | 1082 { |
1081 for (LDObject* obj : objs) | 1083 for (LDObject* obj : objs) |
1082 if (obj) | 1084 if (obj) |
1083 addObject (obj); | 1085 addObject (obj); |
1084 } | 1086 } |
1085 | 1087 |
1086 // ============================================================================= | 1088 // ============================================================================= |
1087 // ============================================================================= | 1089 // |
1088 void LDDocument::insertObj (int pos, LDObject* obj) | 1090 void LDDocument::insertObj (int pos, LDObject* obj) |
1089 { | 1091 { |
1090 getHistory()->add (new AddHistory (pos, obj)); | 1092 history()->add (new AddHistory (pos, obj)); |
1091 m_Objects.insert (pos, obj); | 1093 m_objects.insert (pos, obj); |
1092 obj->setFile (this); | 1094 obj->setDocument (this); |
1093 | 1095 |
1094 #ifdef DEBUG | 1096 #ifdef DEBUG |
1095 if (!isImplicit()) | 1097 if (!isImplicit()) |
1096 dlog ("Inserted object #%1 (%2) at %3\n", obj->getID(), obj->typeName(), pos); | 1098 dlog ("Inserted object #%1 (%2) at %3\n", obj->id(), obj->typeName(), pos); |
1097 #endif | 1099 #endif |
1098 } | 1100 } |
1099 | 1101 |
1100 // ============================================================================= | 1102 // ============================================================================= |
1101 // ============================================================================= | 1103 // |
1102 void LDDocument::forgetObject (LDObject* obj) | 1104 void LDDocument::forgetObject (LDObject* obj) |
1103 { | 1105 { |
1104 int idx = obj->lineNumber(); | 1106 int idx = obj->lineNumber(); |
1105 obj->unselect(); | 1107 obj->unselect(); |
1106 assert (m_Objects[idx] == obj); | 1108 assert (m_objects[idx] == obj); |
1107 | 1109 |
1108 if (!getHistory()->isIgnoring()) | 1110 if (!history()->isIgnoring()) |
1109 getHistory()->add (new DelHistory (idx, obj)); | 1111 history()->add (new DelHistory (idx, obj)); |
1110 | 1112 |
1111 m_Objects.removeAt (idx); | 1113 m_objects.removeAt (idx); |
1112 obj->setFile (null); | 1114 obj->setDocument (null); |
1113 } | 1115 } |
1114 | 1116 |
1115 // ============================================================================= | 1117 // ============================================================================= |
1116 // ============================================================================= | 1118 // |
1117 bool safeToCloseAll() | 1119 bool safeToCloseAll() |
1118 { | 1120 { |
1119 for (LDDocument* f : g_loadedFiles) | 1121 for (LDDocument* f : g_loadedFiles) |
1120 if (!f->isSafeToClose()) | 1122 if (!f->isSafeToClose()) |
1121 return false; | 1123 return false; |
1122 | 1124 |
1123 return true; | 1125 return true; |
1124 } | 1126 } |
1125 | 1127 |
1126 // ============================================================================= | 1128 // ============================================================================= |
1127 // ============================================================================= | 1129 // |
1128 void LDDocument::setObject (int idx, LDObject* obj) | 1130 void LDDocument::setObject (int idx, LDObject* obj) |
1129 { | 1131 { |
1130 assert (idx >= 0 && idx < m_Objects.size()); | 1132 assert (idx >= 0 && idx < m_objects.size()); |
1131 | 1133 |
1132 // Mark this change to history | 1134 // Mark this change to history |
1133 if (!m_History->isIgnoring()) | 1135 if (!m_history->isIgnoring()) |
1134 { | 1136 { |
1135 QString oldcode = getObject (idx)->asText(); | 1137 QString oldcode = getObject (idx)->asText(); |
1136 QString newcode = obj->asText(); | 1138 QString newcode = obj->asText(); |
1137 *m_History << new EditHistory (idx, oldcode, newcode); | 1139 *m_history << new EditHistory (idx, oldcode, newcode); |
1138 } | 1140 } |
1139 | 1141 |
1140 m_Objects[idx]->unselect(); | 1142 m_objects[idx]->unselect(); |
1141 m_Objects[idx]->setFile (null); | 1143 m_objects[idx]->setDocument (null); |
1142 obj->setFile (this); | 1144 obj->setDocument (this); |
1143 m_Objects[idx] = obj; | 1145 m_objects[idx] = obj; |
1144 } | 1146 } |
1145 | 1147 |
1146 // ============================================================================= | 1148 // ============================================================================= |
1147 // Close all implicit files with no references | 1149 // |
1148 // ============================================================================= | 1150 // Close all documents we don't need anymore |
1151 // | |
1149 void LDDocument::closeUnused() | 1152 void LDDocument::closeUnused() |
1150 { | 1153 { |
1151 for (LDDocument* file : g_loadedFiles) | 1154 for (LDDocument* file : g_loadedFiles) |
1152 if (file->isImplicit() && file->countReferences() == 0) | 1155 if (file->isImplicit() && file->references().isEmpty()) |
1153 delete file; | 1156 delete file; |
1154 } | 1157 } |
1155 | 1158 |
1156 // ============================================================================= | 1159 // ============================================================================= |
1157 // ============================================================================= | 1160 // |
1158 LDObject* LDDocument::getObject (int pos) const | 1161 LDObject* LDDocument::getObject (int pos) const |
1159 { | 1162 { |
1160 if (m_Objects.size() <= pos) | 1163 if (m_objects.size() <= pos) |
1161 return null; | 1164 return null; |
1162 | 1165 |
1163 return m_Objects[pos]; | 1166 return m_objects[pos]; |
1164 } | 1167 } |
1165 | 1168 |
1166 // ============================================================================= | 1169 // ============================================================================= |
1167 // ============================================================================= | 1170 // |
1168 int LDDocument::getObjectCount() const | 1171 int LDDocument::getObjectCount() const |
1169 { | 1172 { |
1170 return getObjects().size(); | 1173 return objects().size(); |
1171 } | 1174 } |
1172 | 1175 |
1173 // ============================================================================= | 1176 // ============================================================================= |
1174 // ============================================================================= | 1177 // |
1175 bool LDDocument::hasUnsavedChanges() const | 1178 bool LDDocument::hasUnsavedChanges() const |
1176 { | 1179 { |
1177 return !isImplicit() && getHistory()->getPosition() != getSavePosition(); | 1180 return !isImplicit() && history()->position() != savePosition(); |
1178 } | 1181 } |
1179 | 1182 |
1180 // ============================================================================= | 1183 // ============================================================================= |
1181 // ============================================================================= | 1184 // |
1182 QString LDDocument::getDisplayName() | 1185 QString LDDocument::getDisplayName() |
1183 { | 1186 { |
1184 if (!getName().isEmpty()) | 1187 if (!name().isEmpty()) |
1185 return getName(); | 1188 return name(); |
1186 | 1189 |
1187 if (!getDefaultName().isEmpty()) | 1190 if (!defaultName().isEmpty()) |
1188 return "[" + getDefaultName() + "]"; | 1191 return "[" + defaultName() + "]"; |
1189 | 1192 |
1190 return tr ("<anonymous>"); | 1193 return tr ("<anonymous>"); |
1191 } | 1194 } |
1192 | 1195 |
1193 // ============================================================================= | 1196 // ============================================================================= |
1194 // ============================================================================= | 1197 // |
1195 LDObjectList LDDocument::inlineContents (LDSubfile::InlineFlags flags) | 1198 LDObjectList LDDocument::inlineContents (LDSubfile::InlineFlags flags) |
1196 { | 1199 { |
1197 // Possibly substitute with logoed studs: | 1200 // Possibly substitute with logoed studs: |
1198 // stud.dat -> stud-logo.dat | 1201 // stud.dat -> stud-logo.dat |
1199 // stud2.dat -> stud-logo2.dat | 1202 // stud2.dat -> stud-logo2.dat |
1200 if (gl_logostuds && (flags & LDSubfile::RendererInline)) | 1203 if (gl_logostuds && (flags & LDSubfile::RendererInline)) |
1201 { | 1204 { |
1202 // Ensure logoed studs are loaded first | 1205 // Ensure logoed studs are loaded first |
1203 loadLogoedStuds(); | 1206 loadLogoedStuds(); |
1204 | 1207 |
1205 if (getName() == "stud.dat" && g_logoedStud) | 1208 if (name() == "stud.dat" && g_logoedStud) |
1206 return g_logoedStud->inlineContents (flags); | 1209 return g_logoedStud->inlineContents (flags); |
1207 elif (getName() == "stud2.dat" && g_logoedStud2) | 1210 elif (name() == "stud2.dat" && g_logoedStud2) |
1208 return g_logoedStud2->inlineContents (flags); | 1211 return g_logoedStud2->inlineContents (flags); |
1209 } | 1212 } |
1210 | 1213 |
1211 LDObjectList objs, objcache; | 1214 LDObjectList objs, objcache; |
1212 | 1215 |
1213 bool deep = flags & LDSubfile::DeepInline, | 1216 bool deep = flags & LDSubfile::DeepInline, |
1214 doCache = flags & LDSubfile::CacheInline; | 1217 doCache = flags & LDSubfile::CacheInline; |
1215 | 1218 |
1216 if (m_needsCache) | 1219 if (m_needsCache) |
1217 { | 1220 { |
1218 clearCache(); | 1221 m_cache.clear(); |
1219 doCache = true; | 1222 doCache = true; |
1220 } | 1223 } |
1221 | 1224 |
1222 // If we have this cached, just create a copy of that | 1225 // If we have this cached, just create a copy of that |
1223 if (deep && getCache().isEmpty() == false) | 1226 if (deep && cache().isEmpty() == false) |
1224 { | 1227 { |
1225 for (LDObject* obj : getCache()) | 1228 for (LDObject* obj : cache()) |
1226 objs << obj->createCopy(); | 1229 objs << obj->createCopy(); |
1227 } | 1230 } |
1228 else | 1231 else |
1229 { | 1232 { |
1230 if (!deep) | 1233 if (!deep) |
1231 doCache = false; | 1234 doCache = false; |
1232 | 1235 |
1233 for (LDObject* obj : getObjects()) | 1236 for (LDObject* obj : objects()) |
1234 { | 1237 { |
1235 // Skip those without scemantic meaning | 1238 // Skip those without scemantic meaning |
1236 if (!obj->isScemantic()) | 1239 if (!obj->isScemantic()) |
1237 continue; | 1240 continue; |
1238 | 1241 |
1271 | 1274 |
1272 return objs; | 1275 return objs; |
1273 } | 1276 } |
1274 | 1277 |
1275 // ============================================================================= | 1278 // ============================================================================= |
1276 // ============================================================================= | 1279 // |
1277 LDDocument* LDDocument::current() | 1280 LDDocument* LDDocument::current() |
1278 { | 1281 { |
1279 return m_curdoc; | 1282 return m_curdoc; |
1280 } | 1283 } |
1281 | 1284 |
1298 { | 1301 { |
1299 // A ton of stuff needs to be updated | 1302 // A ton of stuff needs to be updated |
1300 g_win->updateDocumentListItem (f); | 1303 g_win->updateDocumentListItem (f); |
1301 g_win->buildObjList(); | 1304 g_win->buildObjList(); |
1302 g_win->updateTitle(); | 1305 g_win->updateTitle(); |
1303 g_win->R()->setFile (f); | 1306 g_win->R()->setDocument (f); |
1304 g_win->R()->repaint(); | 1307 g_win->R()->repaint(); |
1305 log ("Changed file to %1", f->getDisplayName()); | 1308 log ("Changed file to %1", f->getDisplayName()); |
1306 } | 1309 } |
1307 } | 1310 } |
1308 | 1311 |
1309 // ============================================================================= | 1312 // ============================================================================= |
1310 // ============================================================================= | 1313 // |
1311 int LDDocument::countExplicitFiles() | 1314 int LDDocument::countExplicitFiles() |
1312 { | 1315 { |
1313 int count = 0; | 1316 int count = 0; |
1314 | 1317 |
1315 for (LDDocument* f : g_loadedFiles) | 1318 for (LDDocument* f : g_loadedFiles) |
1325 // ============================================================================= | 1328 // ============================================================================= |
1326 void LDDocument::closeInitialFile() | 1329 void LDDocument::closeInitialFile() |
1327 { | 1330 { |
1328 if ( | 1331 if ( |
1329 countExplicitFiles() == 2 && | 1332 countExplicitFiles() == 2 && |
1330 g_loadedFiles[0]->getName().isEmpty() && | 1333 g_loadedFiles[0]->name().isEmpty() && |
1331 g_loadedFiles[1]->getName().isEmpty() == false && | 1334 g_loadedFiles[1]->name().isEmpty() == false && |
1332 !g_loadedFiles[0]->hasUnsavedChanges() | 1335 !g_loadedFiles[0]->hasUnsavedChanges() |
1333 ) | 1336 ) |
1334 delete g_loadedFiles[0]; | 1337 delete g_loadedFiles[0]; |
1335 } | 1338 } |
1336 | 1339 |
1337 // ============================================================================= | 1340 // ============================================================================= |
1338 // ============================================================================= | 1341 // |
1339 void loadLogoedStuds() | 1342 void loadLogoedStuds() |
1340 { | 1343 { |
1341 if (g_logoedStud && g_logoedStud2) | 1344 if (g_logoedStud && g_logoedStud2) |
1342 return; | 1345 return; |
1343 | 1346 |
1349 | 1352 |
1350 log (LDDocument::tr ("Logoed studs loaded.\n")); | 1353 log (LDDocument::tr ("Logoed studs loaded.\n")); |
1351 } | 1354 } |
1352 | 1355 |
1353 // ============================================================================= | 1356 // ============================================================================= |
1354 // ============================================================================= | 1357 // |
1355 void LDDocument::addToSelection (LDObject* obj) // [protected] | 1358 void LDDocument::addToSelection (LDObject* obj) // [protected] |
1356 { | 1359 { |
1357 if (obj->isSelected()) | 1360 if (obj->isSelected()) |
1358 return; | 1361 return; |
1359 | 1362 |
1360 assert (obj->getFile() == this); | 1363 assert (obj->document() == this); |
1361 m_sel << obj; | 1364 m_sel << obj; |
1362 obj->setSelected (true); | 1365 obj->setSelected (true); |
1363 } | 1366 } |
1364 | 1367 |
1365 // ============================================================================= | 1368 // ============================================================================= |
1366 // ============================================================================= | 1369 // |
1367 void LDDocument::removeFromSelection (LDObject* obj) // [protected] | 1370 void LDDocument::removeFromSelection (LDObject* obj) // [protected] |
1368 { | 1371 { |
1369 if (!obj->isSelected()) | 1372 if (!obj->isSelected()) |
1370 return; | 1373 return; |
1371 | 1374 |
1372 assert (obj->getFile() == this); | 1375 assert (obj->document() == this); |
1373 m_sel.removeOne (obj); | 1376 m_sel.removeOne (obj); |
1374 obj->setSelected (false); | 1377 obj->setSelected (false); |
1375 } | 1378 } |
1376 | 1379 |
1377 // ============================================================================= | 1380 // ============================================================================= |
1378 // ============================================================================= | 1381 // |
1379 void LDDocument::clearSelection() | 1382 void LDDocument::clearSelection() |
1380 { | 1383 { |
1381 for (LDObject* obj : m_sel) | 1384 for (LDObject* obj : m_sel) |
1382 removeFromSelection (obj); | 1385 removeFromSelection (obj); |
1383 | 1386 |
1384 assert (m_sel.isEmpty()); | 1387 assert (m_sel.isEmpty()); |
1385 } | 1388 } |
1386 | 1389 |
1387 // ============================================================================= | 1390 // ============================================================================= |
1388 // ============================================================================= | 1391 // |
1389 const LDObjectList& LDDocument::getSelection() const | 1392 const LDObjectList& LDDocument::getSelection() const |
1390 { | 1393 { |
1391 return m_sel; | 1394 return m_sel; |
1392 } | 1395 } |
1393 | 1396 |
1394 // ============================================================================= | 1397 // ============================================================================= |
1395 // ============================================================================= | 1398 // |
1396 void LDDocument::swapObjects (LDObject* one, LDObject* other) | 1399 void LDDocument::swapObjects (LDObject* one, LDObject* other) |
1397 { | 1400 { |
1398 int a = m_Objects.indexOf (one); | 1401 int a = m_objects.indexOf (one); |
1399 int b = m_Objects.indexOf (other); | 1402 int b = m_objects.indexOf (other); |
1400 assert (a != b && a != -1 && b != -1); | 1403 assert (a != b && a != -1 && b != -1); |
1401 m_Objects[b] = one; | 1404 m_objects[b] = one; |
1402 m_Objects[a] = other; | 1405 m_objects[a] = other; |
1403 addToHistory (new SwapHistory (one->getID(), other->getID())); | 1406 addToHistory (new SwapHistory (one->id(), other->id())); |
1404 } | 1407 } |
1405 | 1408 |
1406 // ============================================================================= | 1409 // ============================================================================= |
1407 // ============================================================================= | 1410 // |
1408 QString LDDocument::shortenName (QString a) // [static] | 1411 QString LDDocument::shortenName (QString a) // [static] |
1409 { | 1412 { |
1410 QString shortname = basename (a); | 1413 QString shortname = basename (a); |
1411 QString topdirname = basename (dirname (a)); | 1414 QString topdirname = basename (dirname (a)); |
1412 | 1415 |
1415 | 1418 |
1416 return shortname; | 1419 return shortname; |
1417 } | 1420 } |
1418 | 1421 |
1419 // ============================================================================= | 1422 // ============================================================================= |
1420 // ============================================================================= | 1423 // |
1421 void LDDocument::addReference (LDDocumentPointer* ptr) | 1424 void LDDocument::addReference (LDDocumentPointer* ptr) |
1422 { | 1425 { |
1423 pushToReferences (ptr); | 1426 m_references << ptr; |
1424 } | 1427 } |
1425 | 1428 |
1426 // ============================================================================= | 1429 // ============================================================================= |
1427 // ============================================================================= | 1430 // |
1428 void LDDocument::removeReference (LDDocumentPointer* ptr) | 1431 void LDDocument::removeReference (LDDocumentPointer* ptr) |
1429 { | 1432 { |
1430 removeFromReferences (ptr); | 1433 m_references.removeOne (ptr); |
1431 | 1434 |
1432 if (getReferences().size() == 0) | 1435 if (references().isEmpty()) |
1433 invokeLater (closeUnused); | 1436 invokeLater (closeUnused); |
1434 } | 1437 } |