34 |
34 |
35 ConfigOption (QStringList RecentFiles) |
35 ConfigOption (QStringList RecentFiles) |
36 ConfigOption (bool TryDownloadMissingFiles = false) |
36 ConfigOption (bool TryDownloadMissingFiles = false) |
37 |
37 |
38 static bool g_loadingMainFile = false; |
38 static bool g_loadingMainFile = false; |
39 static const int g_maxRecentFiles = 10; |
39 enum { MAX_RECENT_FILES = 10 }; |
40 static bool g_aborted = false; |
40 static bool g_aborted = false; |
41 static LDDocument* g_logoedStud; |
41 static LDDocument* g_logoedStud; |
42 static LDDocument* g_logoedStud2; |
42 static LDDocument* g_logoedStud2; |
43 static QList<LDDocument*> g_allDocuments; |
|
44 static QList<LDDocument*> g_explicitDocuments; |
|
45 static LDDocument* g_currentDocument; |
|
46 static bool g_loadingLogoedStuds = false; |
43 static bool g_loadingLogoedStuds = false; |
47 |
44 |
48 const QStringList g_specialSubdirectories ({ "s", "48", "8" }); |
45 const QStringList g_specialSubdirectories ({ "s", "48", "8" }); |
49 |
46 |
50 // ============================================================================= |
47 // ============================================================================= |
51 // |
48 // |
52 LDDocument::LDDocument() : |
49 LDDocument::LDDocument (QObject* parent) : |
|
50 QObject (parent), |
|
51 HierarchyElement (parent), |
53 m_history (new History), |
52 m_history (new History), |
54 m_isImplicit (true), |
53 m_isImplicit (true), |
55 m_flags (0), |
54 m_flags (0), |
56 m_verticesOutdated (true), |
55 m_verticesOutdated (true), |
57 m_needVertexMerge (true), |
56 m_needVertexMerge (true), |
59 { |
58 { |
60 setSavePosition (-1); |
59 setSavePosition (-1); |
61 setTabIndex (-1); |
60 setTabIndex (-1); |
62 m_history->setDocument (this); |
61 m_history->setDocument (this); |
63 m_needsReCache = true; |
62 m_needsReCache = true; |
64 g_allDocuments << this; |
|
65 } |
|
66 |
|
67 // ============================================================================= |
|
68 // |
|
69 LDDocument* LDDocument::createNew() |
|
70 { |
|
71 return new LDDocument(); |
|
72 } |
63 } |
73 |
64 |
74 // ============================================================================= |
65 // ============================================================================= |
75 // |
66 // |
76 LDDocument::~LDDocument() |
67 LDDocument::~LDDocument() |
77 { |
68 { |
78 g_allDocuments.removeOne (this); |
|
79 m_flags |= DOCF_IsBeingDestroyed; |
69 m_flags |= DOCF_IsBeingDestroyed; |
80 delete m_history; |
70 delete m_history; |
81 delete m_gldata; |
71 delete m_gldata; |
82 } |
72 } |
83 |
73 |
89 { |
79 { |
90 m_isImplicit = a; |
80 m_isImplicit = a; |
91 |
81 |
92 if (a == false) |
82 if (a == false) |
93 { |
83 { |
94 g_explicitDocuments << this; |
|
95 print ("Opened %1", name()); |
84 print ("Opened %1", name()); |
96 |
85 |
97 // Implicit files are not compiled by the GL renderer. Now that this |
86 // Implicit files are not compiled by the GL renderer. Now that this |
98 // part is no longer implicit, it needs to be compiled. |
87 // part is no longer implicit, it needs to be compiled. |
99 if (g_win != null) |
88 m_window->R()->compiler()->compileDocument (this); |
100 g_win->R()->compiler()->compileDocument (this); |
|
101 } |
89 } |
102 else |
90 else |
103 { |
91 { |
104 g_explicitDocuments.removeOne (this); |
|
105 print ("Closed %1", name()); |
92 print ("Closed %1", name()); |
106 } |
93 } |
107 |
94 |
108 if (g_win != null) |
95 m_window->updateDocumentList(); |
109 g_win->updateDocumentList(); |
96 |
110 |
97 // If the current document just became implicit (i.e. user closed it), we need to get a new one to show. |
111 // If the current document just became implicit (e.g. it was 'closed'), |
98 if (currentDocument() == this and a) |
112 // we need to get a new current document. |
99 m_window->currentDocumentClosed(); |
113 if (current() == this and isImplicit()) |
100 } |
114 { |
|
115 if (explicitDocuments().isEmpty()) |
|
116 newFile(); |
|
117 else |
|
118 setCurrent (explicitDocuments().first()); |
|
119 } |
|
120 } |
|
121 } |
|
122 |
|
123 // ============================================================================= |
|
124 // |
|
125 QList<LDDocument*> const& LDDocument::explicitDocuments() |
|
126 { |
|
127 return g_explicitDocuments; |
|
128 } |
101 } |
129 |
102 |
130 // ============================================================================= |
103 // ============================================================================= |
131 // |
104 // |
132 LDDocument* FindDocument (QString name) |
105 LDDocument* FindDocument (QString name) |
133 { |
106 { |
134 for (LDDocument* file : g_allDocuments) |
107 for (LDDocument* document : g_win->allDocuments()) |
135 { |
108 { |
136 if (file == null) |
109 if (isOneOf (name, document->name(), document->defaultName())) |
137 continue; |
110 return document; |
138 |
|
139 if (isOneOf (name, file->name(), file->defaultName())) |
|
140 return file; |
|
141 } |
111 } |
142 |
112 |
143 return nullptr; |
113 return nullptr; |
144 } |
114 } |
145 |
115 |
176 // |
146 // |
177 static QString FindDocumentPath (QString relpath, bool subdirs) |
147 static QString FindDocumentPath (QString relpath, bool subdirs) |
178 { |
148 { |
179 QString fullPath; |
149 QString fullPath; |
180 |
150 |
181 // LDraw models use Windows-style path separators. If we're not on Windows, |
151 // LDraw models use backslashes as path separators. Replace those into forward slashes for Qt. |
182 // replace the path separator now before opening any files. Qt expects |
|
183 // forward-slashes as directory separators. |
|
184 #ifndef WIN32 |
|
185 relpath.replace ("\\", "/"); |
152 relpath.replace ("\\", "/"); |
186 #endif // WIN32 |
153 |
187 |
154 // Try find it relative to other currently open documents. We want a file in the immediate vicinity of a current |
188 // Try find it relative to other currently open documents. We want a file |
155 // part model to override stock LDraw stuff. |
189 // in the immediate vicinity of a current model to override stock LDraw stuff. |
|
190 QString reltop = Basename (Dirname (relpath)); |
156 QString reltop = Basename (Dirname (relpath)); |
191 |
157 |
192 for (LDDocument* doc : g_allDocuments) |
158 for (LDDocument* doc : g_win->allDocuments()) |
193 { |
159 { |
194 if (doc == null) |
|
195 continue; |
|
196 |
|
197 QString partpath = format ("%1/%2", Dirname (doc->fullPath()), relpath); |
160 QString partpath = format ("%1/%2", Dirname (doc->fullPath()), relpath); |
198 QFile f (partpath); |
161 QFile f (partpath); |
199 |
162 |
200 if (f.exists()) |
163 if (f.exists()) |
201 { |
164 { |
227 if (QFile::exists (fullPath)) |
190 if (QFile::exists (fullPath)) |
228 return fullPath; |
191 return fullPath; |
229 |
192 |
230 if (subdirs) |
193 if (subdirs) |
231 { |
194 { |
232 // Look in sub-directories: parts and p. Also look in net_downloadpath, since that's |
195 // Look in sub-directories: parts and p. Also look in the download path, since that's where we download parts |
233 // where we download parts from the PT to. |
196 // from the PT to. |
234 QStringList dirs = { g_win->configBag()->lDrawPath(), g_win->configBag()->downloadFilePath() }; |
197 QStringList dirs = { g_win->configBag()->lDrawPath(), g_win->configBag()->downloadFilePath() }; |
235 for (const QString& topdir : dirs) |
198 for (const QString& topdir : dirs) |
236 { |
199 { |
237 for (const QString& subdir : QStringList ({ "parts", "p" })) |
200 for (const QString& subdir : QStringList ({ "parts", "p" })) |
238 { |
201 { |
451 } |
414 } |
452 |
415 |
453 if (not fp) |
416 if (not fp) |
454 return nullptr; |
417 return nullptr; |
455 |
418 |
456 LDDocument* load = (fileToOverride != null ? fileToOverride : LDDocument::createNew()); |
419 LDDocument* load = (fileToOverride != null ? fileToOverride : g_win->newDocument (implicit)); |
457 load->setImplicit (implicit); |
|
458 load->setFullPath (fullpath); |
420 load->setFullPath (fullpath); |
459 load->setName (LDDocument::shortenName (load->fullPath())); |
421 load->setName (LDDocument::shortenName (load->fullPath())); |
460 |
422 |
461 // Loading the file shouldn't count as actual edits to the document. |
423 // Loading the file shouldn't count as actual edits to the document. |
462 load->history()->setIgnoring (true); |
424 load->history()->setIgnoring (true); |
475 |
437 |
476 load->addObjects (objs); |
438 load->addObjects (objs); |
477 |
439 |
478 if (g_loadingMainFile) |
440 if (g_loadingMainFile) |
479 { |
441 { |
480 LDDocument::setCurrent (load); |
442 g_win->changeDocument (load); |
481 g_win->R()->setDocument (load); |
443 g_win->R()->setDocument (load); |
482 print (QObject::tr ("File %1 parsed successfully (%2 errors)."), path, numWarnings); |
444 print (QObject::tr ("File %1 parsed successfully (%2 errors)."), path, numWarnings); |
483 } |
445 } |
484 |
446 |
485 load->history()->setIgnoring (false); |
447 load->history()->setIgnoring (false); |
494 setlocale (LC_ALL, "C"); |
456 setlocale (LC_ALL, "C"); |
495 |
457 |
496 // If we have unsaved changes, warn and give the option of saving. |
458 // If we have unsaved changes, warn and give the option of saving. |
497 if (hasUnsavedChanges()) |
459 if (hasUnsavedChanges()) |
498 { |
460 { |
499 QString message = format (QObject::tr ("There are unsaved changes to %1. Should it be saved?"), |
461 QString message = format (tr ("There are unsaved changes to %1. Should it be saved?"), getDisplayName()); |
500 getDisplayName()); |
462 |
501 |
463 int button = msgbox::question (m_window, QObject::tr ("Unsaved Changes"), message, |
502 int button = msgbox::question (g_win, QObject::tr ("Unsaved Changes"), message, |
|
503 (msgbox::Yes | msgbox::No | msgbox::Cancel), msgbox::Cancel); |
464 (msgbox::Yes | msgbox::No | msgbox::Cancel), msgbox::Cancel); |
504 |
465 |
505 switch (button) |
466 switch (button) |
506 { |
467 { |
507 case msgbox::Yes: |
468 case msgbox::Yes: |
508 { |
469 { |
509 // If we don't have a file path yet, we have to ask the user for one. |
470 // If we don't have a file path yet, we have to ask the user for one. |
510 if (name().length() == 0) |
471 if (name().length() == 0) |
511 { |
472 { |
512 QString newpath = QFileDialog::getSaveFileName (g_win, QObject::tr ("Save As"), |
473 QString newpath = QFileDialog::getSaveFileName (m_window, QObject::tr ("Save As"), |
513 CurrentDocument()->name(), QObject::tr ("LDraw files (*.dat *.ldr)")); |
474 name(), QObject::tr ("LDraw files (*.dat *.ldr)")); |
514 |
475 |
515 if (newpath.length() == 0) |
476 if (newpath.length() == 0) |
516 return false; |
477 return false; |
517 |
478 |
518 setName (newpath); |
479 setName (newpath); |
521 if (not save()) |
482 if (not save()) |
522 { |
483 { |
523 message = format (QObject::tr ("Failed to save %1 (%2)\nDo you still want to close?"), |
484 message = format (QObject::tr ("Failed to save %1 (%2)\nDo you still want to close?"), |
524 name(), strerror (errno)); |
485 name(), strerror (errno)); |
525 |
486 |
526 if (msgbox::critical (g_win, QObject::tr ("Save Failure"), message, |
487 if (msgbox::critical (m_window, QObject::tr ("Save Failure"), message, |
527 (msgbox::Yes | msgbox::No), msgbox::No) == msgbox::No) |
488 (msgbox::Yes | msgbox::No), msgbox::No) == msgbox::No) |
528 { |
489 { |
529 return false; |
490 return false; |
530 } |
491 } |
531 } |
492 } |
545 |
506 |
546 // ============================================================================= |
507 // ============================================================================= |
547 // |
508 // |
548 void CloseAllDocuments() |
509 void CloseAllDocuments() |
549 { |
510 { |
550 for (LDDocument* file : g_explicitDocuments) |
511 for (LDDocument* file : g_win->allDocuments()) |
551 file->dismiss(); |
512 file->dismiss(); |
552 } |
|
553 |
|
554 // ============================================================================= |
|
555 // |
|
556 void newFile() |
|
557 { |
|
558 // Create a new anonymous file and set it to our current |
|
559 LDDocument* f = LDDocument::createNew(); |
|
560 f->setName (""); |
|
561 f->setImplicit (false); |
|
562 LDDocument::setCurrent (f); |
|
563 LDDocument::closeInitialFile(); |
|
564 g_win->R()->setDocument (f); |
|
565 g_win->doFullRefresh(); |
|
566 g_win->updateTitle(); |
|
567 g_win->updateActions(); |
|
568 } |
513 } |
569 |
514 |
570 // ============================================================================= |
515 // ============================================================================= |
571 // |
516 // |
572 void AddRecentFile (QString path) |
517 void AddRecentFile (QString path) |
582 |
527 |
583 recentFiles.removeAt (idx); |
528 recentFiles.removeAt (idx); |
584 } |
529 } |
585 |
530 |
586 // If there's too many recent files, drop one out. |
531 // If there's too many recent files, drop one out. |
587 while (recentFiles.size() > (g_maxRecentFiles - 1)) |
532 while (recentFiles.size() > (MAX_RECENT_FILES - 1)) |
588 recentFiles.removeAt (0); |
533 recentFiles.removeAt (0); |
589 |
534 |
590 // Add the file |
535 // Add the file |
591 recentFiles << path; |
536 recentFiles << path; |
592 g_win->configBag()->setRecentFiles (recentFiles); |
537 g_win->configBag()->setRecentFiles (recentFiles); |
602 // If there's already a file with the same name, this file must replace it. |
547 // If there's already a file with the same name, this file must replace it. |
603 LDDocument* documentToReplace = nullptr; |
548 LDDocument* documentToReplace = nullptr; |
604 LDDocument* file = nullptr; |
549 LDDocument* file = nullptr; |
605 QString shortName = LDDocument::shortenName (path); |
550 QString shortName = LDDocument::shortenName (path); |
606 |
551 |
607 for (LDDocument* doc : g_allDocuments) |
552 for (LDDocument* doc : g_win->allDocuments()) |
608 { |
553 { |
609 if (doc != null and doc->name() == shortName) |
554 if (doc->name() == shortName) |
610 { |
555 { |
611 documentToReplace = doc; |
556 documentToReplace = doc; |
612 break; |
557 break; |
613 } |
558 } |
614 } |
559 } |
642 g_loadingMainFile = false; |
587 g_loadingMainFile = false; |
643 return; |
588 return; |
644 } |
589 } |
645 |
590 |
646 file->setImplicit (false); |
591 file->setImplicit (false); |
647 |
592 g_win->closeInitialDocument(); |
648 // If we have an anonymous, unchanged file open as the only open file |
593 g_win->changeDocument (file); |
649 // (aside of the one we just opened), close it now. |
|
650 LDDocument::closeInitialFile(); |
|
651 |
|
652 // Rebuild the object tree view now. |
|
653 LDDocument::setCurrent (file); |
|
654 g_win->doFullRefresh(); |
594 g_win->doFullRefresh(); |
655 |
|
656 // Add it to the recent files list. |
|
657 AddRecentFile (path); |
595 AddRecentFile (path); |
658 g_loadingMainFile = false; |
596 g_loadingMainFile = false; |
659 |
597 |
660 // If there were problems loading subfile references, try see if we can find these |
598 // If there were problems loading subfile references, try see if we can find these |
661 // files on the parts tracker. |
599 // files on the parts tracker. |
738 |
676 |
739 // We have successfully saved, update the save position now. |
677 // We have successfully saved, update the save position now. |
740 setSavePosition (history()->position()); |
678 setSavePosition (history()->position()); |
741 setFullPath (path); |
679 setFullPath (path); |
742 setName (shortenName (path)); |
680 setName (shortenName (path)); |
743 |
681 m_window->updateDocumentListItem (this); |
744 g_win->updateDocumentListItem (this); |
682 m_window->updateTitle(); |
745 g_win->updateTitle(); |
|
746 return true; |
683 return true; |
747 } |
684 } |
748 |
685 |
749 // ============================================================================= |
686 // ============================================================================= |
750 // |
687 // |
1039 obj->replace (ParseLine (static_cast<LDError*> (obj)->contents())); |
976 obj->replace (ParseLine (static_cast<LDError*> (obj)->contents())); |
1040 } |
977 } |
1041 |
978 |
1042 m_needsReCache = true; |
979 m_needsReCache = true; |
1043 |
980 |
1044 if (this == CurrentDocument()) |
981 if (this == m_window->currentDocument()) |
1045 g_win->buildObjList(); |
982 m_window->buildObjList(); |
1046 } |
983 } |
1047 |
984 |
1048 // ============================================================================= |
985 // ============================================================================= |
1049 // |
986 // |
1050 int LDDocument::addObject (LDObject* obj) |
987 int LDDocument::addObject (LDObject* obj) |
1051 { |
988 { |
1052 history()->add (new AddHistory (objects().size(), obj)); |
989 history()->add (new AddHistory (objects().size(), obj)); |
1053 m_objects << obj; |
990 m_objects << obj; |
1054 addKnownVertices (obj); |
991 addKnownVertices (obj); |
1055 obj->setDocument (this); |
992 obj->setDocument (this); |
1056 g_win->R()->compileObject (obj); |
993 m_window->R()->compileObject (obj); |
1057 return getObjectCount() - 1; |
994 return getObjectCount() - 1; |
1058 } |
995 } |
1059 |
996 |
1060 // ============================================================================= |
997 // ============================================================================= |
1061 // |
998 // |
1073 void LDDocument::insertObj (int pos, LDObject* obj) |
1010 void LDDocument::insertObj (int pos, LDObject* obj) |
1074 { |
1011 { |
1075 history()->add (new AddHistory (pos, obj)); |
1012 history()->add (new AddHistory (pos, obj)); |
1076 m_objects.insert (pos, obj); |
1013 m_objects.insert (pos, obj); |
1077 obj->setDocument (this); |
1014 obj->setDocument (this); |
1078 g_win->R()->compileObject (obj); |
1015 m_window->R()->compileObject (obj); |
1079 |
1016 |
1080 |
1017 |
1081 #ifdef DEBUG |
1018 #ifdef DEBUG |
1082 if (not isImplicit()) |
1019 if (not isImplicit()) |
1083 dprint ("Inserted object #%1 (%2) at %3\n", obj->id(), obj->typeName(), pos); |
1020 dprint ("Inserted object #%1 (%2) at %3\n", obj->id(), obj->typeName(), pos); |
1151 m_objectVertices.remove (m_objects[idx]); |
1088 m_objectVertices.remove (m_objects[idx]); |
1152 m_objects[idx]->deselect(); |
1089 m_objects[idx]->deselect(); |
1153 m_objects[idx]->setDocument (nullptr); |
1090 m_objects[idx]->setDocument (nullptr); |
1154 obj->setDocument (this); |
1091 obj->setDocument (this); |
1155 addKnownVertices (obj); |
1092 addKnownVertices (obj); |
1156 g_win->R()->compileObject (obj); |
1093 m_window->R()->compileObject (obj); |
1157 m_objects[idx] = obj; |
1094 m_objects[idx] = obj; |
1158 needVertexMerge(); |
1095 needVertexMerge(); |
1159 } |
1096 } |
1160 |
1097 |
1161 // ============================================================================= |
1098 // ============================================================================= |
1266 LDObjectList LDDocument::inlineContents (bool deep, bool renderinline) |
1203 LDObjectList LDDocument::inlineContents (bool deep, bool renderinline) |
1267 { |
1204 { |
1268 // Possibly substitute with logoed studs: |
1205 // Possibly substitute with logoed studs: |
1269 // stud.dat -> stud-logo.dat |
1206 // stud.dat -> stud-logo.dat |
1270 // stud2.dat -> stud-logo2.dat |
1207 // stud2.dat -> stud-logo2.dat |
1271 if (g_win->configBag()->useLogoStuds() and renderinline) |
1208 if (m_config->useLogoStuds() and renderinline) |
1272 { |
1209 { |
1273 // Ensure logoed studs are loaded first |
1210 // Ensure logoed studs are loaded first |
1274 LoadLogoStuds(); |
1211 LoadLogoStuds(); |
1275 |
1212 |
1276 if (name() == "stud.dat" and g_logoedStud != null) |
1213 if (name() == "stud.dat" and g_logoedStud != null) |
1297 else |
1234 else |
1298 objs << obj->createCopy(); |
1235 objs << obj->createCopy(); |
1299 } |
1236 } |
1300 |
1237 |
1301 return objs; |
1238 return objs; |
1302 } |
|
1303 |
|
1304 // ============================================================================= |
|
1305 // |
|
1306 LDDocument* LDDocument::current() |
|
1307 { |
|
1308 return g_currentDocument; |
|
1309 } |
|
1310 |
|
1311 // ============================================================================= |
|
1312 // Sets the given file as the current one on display. At some point in time this |
|
1313 // was an operation completely unheard of. ;) |
|
1314 // |
|
1315 // TODO: f can be temporarily null. This probably should not be the case. |
|
1316 // ============================================================================= |
|
1317 void LDDocument::setCurrent (LDDocument* f) |
|
1318 { |
|
1319 // Implicit files were loaded for caching purposes and must never be set |
|
1320 // current. |
|
1321 if (f != null and f->isImplicit()) |
|
1322 return; |
|
1323 |
|
1324 g_currentDocument = f; |
|
1325 |
|
1326 if (g_win and f) |
|
1327 { |
|
1328 // A ton of stuff needs to be updated |
|
1329 g_win->updateDocumentListItem (f); |
|
1330 g_win->buildObjList(); |
|
1331 g_win->updateTitle(); |
|
1332 g_win->R()->setDocument (f); |
|
1333 g_win->R()->compiler()->needMerge(); |
|
1334 print ("Changed file to %1", f->getDisplayName()); |
|
1335 } |
|
1336 } |
|
1337 |
|
1338 // ============================================================================= |
|
1339 // |
|
1340 int LDDocument::countExplicitFiles() |
|
1341 { |
|
1342 return g_explicitDocuments.size(); |
|
1343 } |
|
1344 |
|
1345 // ============================================================================= |
|
1346 // This little beauty closes the initial file that was open at first when opening |
|
1347 // a new file over it. |
|
1348 // ============================================================================= |
|
1349 void LDDocument::closeInitialFile() |
|
1350 { |
|
1351 if (g_explicitDocuments.size() == 2 and |
|
1352 g_explicitDocuments[0]->name().isEmpty() and |
|
1353 not g_explicitDocuments[1]->name().isEmpty() and |
|
1354 not g_explicitDocuments[0]->hasUnsavedChanges()) |
|
1355 { |
|
1356 LDDocument* filetoclose = g_explicitDocuments.first(); |
|
1357 filetoclose->dismiss(); |
|
1358 } |
|
1359 } |
1239 } |
1360 |
1240 |
1361 // ============================================================================= |
1241 // ============================================================================= |
1362 // |
1242 // |
1363 void LoadLogoStuds() |
1243 void LoadLogoStuds() |
1377 void LDDocument::addToSelection (LDObject* obj) // [protected] |
1257 void LDDocument::addToSelection (LDObject* obj) // [protected] |
1378 { |
1258 { |
1379 if (not obj->isSelected() and obj->document() == this) |
1259 if (not obj->isSelected() and obj->document() == this) |
1380 { |
1260 { |
1381 m_sel << obj; |
1261 m_sel << obj; |
1382 g_win->R()->compileObject (obj); |
1262 m_window->R()->compileObject (obj); |
1383 obj->setSelected (true); |
1263 obj->setSelected (true); |
1384 } |
1264 } |
1385 } |
1265 } |
1386 |
1266 |
1387 // ============================================================================= |
1267 // ============================================================================= |
1389 void LDDocument::removeFromSelection (LDObject* obj) // [protected] |
1269 void LDDocument::removeFromSelection (LDObject* obj) // [protected] |
1390 { |
1270 { |
1391 if (obj->isSelected() and obj->document() == this) |
1271 if (obj->isSelected() and obj->document() == this) |
1392 { |
1272 { |
1393 m_sel.removeOne (obj); |
1273 m_sel.removeOne (obj); |
1394 g_win->R()->compileObject (obj); |
1274 m_window->R()->compileObject (obj); |
1395 obj->setSelected (false); |
1275 obj->setSelected (false); |
1396 } |
1276 } |
1397 } |
1277 } |
1398 |
1278 |
1399 // ============================================================================= |
1279 // ============================================================================= |
1400 // |
1280 // |
1401 void LDDocument::clearSelection() |
1281 void LDDocument::clearSelection() |
1402 { |
1282 { |
1403 for (LDObject* obj : m_sel) |
1283 for (LDObject* obj : m_sel) |
1404 { |
1284 { |
1405 g_win->R()->compileObject (obj); |
1285 m_window->R()->compileObject (obj); |
1406 obj->setSelected (false); |
1286 obj->setSelected (false); |
1407 } |
1287 } |
1408 |
1288 |
1409 m_sel.clear(); |
1289 m_sel.clear(); |
1410 } |
1290 } |