src/Document.cc

changeset 644
93dcd1a0e4bd
parent 642
751a8df42842
child 648
ed6170728ae4
equal deleted inserted replaced
643:a79277000830 644:93dcd1a0e4bd
87 { 87 {
88 pathError = "Not an LDraw directory! Must<br />have LDConfig.ldr, parts/ and p/."; 88 pathError = "Not an LDraw directory! Must<br />have LDConfig.ldr, parts/ and p/.";
89 return false; 89 return false;
90 } 90 }
91 91
92 pathInfo.partsPath = fmt ("%1" DIRSLASH "parts", path); 92 pathInfo.partsPath = format ("%1" DIRSLASH "parts", path);
93 pathInfo.LDConfigPath = fmt ("%1" DIRSLASH "LDConfig.ldr", path); 93 pathInfo.LDConfigPath = format ("%1" DIRSLASH "LDConfig.ldr", path);
94 pathInfo.primsPath = fmt ("%1" DIRSLASH "p", path); 94 pathInfo.primsPath = format ("%1" DIRSLASH "p", path);
95 95
96 return true; 96 return true;
97 } 97 }
98 98
99 // Accessors 99 // Accessors
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", name()); 182 print ("Closed %1", name());
183 } 183 }
184 184
185 // ============================================================================= 185 // =============================================================================
186 // 186 //
187 LDDocument* findDocument (QString name) 187 LDDocument* findDocument (QString name)
242 for (LDDocument* doc : g_loadedFiles) 242 for (LDDocument* doc : g_loadedFiles)
243 { 243 {
244 if (doc->fullPath().isEmpty()) 244 if (doc->fullPath().isEmpty())
245 continue; 245 continue;
246 246
247 QString partpath = fmt ("%1/%2", dirname (doc->fullPath()), relpath); 247 QString partpath = format ("%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
270 270
271 if (QFile::exists (relpath)) 271 if (QFile::exists (relpath))
272 return relpath; 272 return relpath;
273 273
274 // Try with just the LDraw path first 274 // Try with just the LDraw path first
275 fullPath = fmt ("%1" DIRSLASH "%2", io_ldpath, relpath); 275 fullPath = format ("%1" DIRSLASH "%2", io_ldpath, relpath);
276 276
277 if (QFile::exists (fullPath)) 277 if (QFile::exists (fullPath))
278 return fullPath; 278 return fullPath;
279 279
280 if (subdirs) 280 if (subdirs)
283 // where we download parts from the PT to. 283 // where we download parts from the PT to.
284 for (const QString& topdir : initlist<QString> ({ io_ldpath, net_downloadpath })) 284 for (const QString& topdir : initlist<QString> ({ io_ldpath, net_downloadpath }))
285 { 285 {
286 for (const QString& subdir : initlist<QString> ({ "parts", "p" })) 286 for (const QString& subdir : initlist<QString> ({ "parts", "p" }))
287 { 287 {
288 fullPath = fmt ("%1" DIRSLASH "%2" DIRSLASH "%3", topdir, subdir, relpath); 288 fullPath = format ("%1" DIRSLASH "%2" DIRSLASH "%3", topdir, subdir, relpath);
289 289
290 if (QFile::exists (fullPath)) 290 if (QFile::exists (fullPath))
291 return fullPath; 291 return fullPath;
292 } 292 }
293 } 293 }
297 return ""; 297 return "";
298 } 298 }
299 299
300 QFile* openLDrawFile (QString relpath, bool subdirs, QString* pathpointer) 300 QFile* openLDrawFile (QString relpath, bool subdirs, QString* pathpointer)
301 { 301 {
302 log ("Opening %1...\n", relpath); 302 print ("Opening %1...\n", relpath);
303 QString path = findLDrawFilePath (relpath, subdirs); 303 QString path = findLDrawFilePath (relpath, subdirs);
304 304
305 if (pathpointer != null) 305 if (pathpointer != null)
306 *pathpointer = path; 306 *pathpointer = path;
307 307
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", progress() + 1, static_cast<LDError*> (obj)->reason()); 385 print ("Couldn't parse line #%1: %2", progress() + 1, static_cast<LDError*> (obj)->reason());
386 386
387 if (warnings() != null) 387 if (warnings() != null)
388 (*warnings())++; 388 (*warnings())++;
389 } 389 }
390 390
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->fullPath())); 501 load->setName (LDDocument::shortenName (load->fullPath()));
502 dlog ("name: %1 (%2)", load->name(), load->fullPath()); 502 dprint ("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->history()->setIgnoring (true); 506 load->history()->setIgnoring (true);
507 507
522 522
523 if (g_loadingMainFile) 523 if (g_loadingMainFile)
524 { 524 {
525 LDDocument::setCurrent (load); 525 LDDocument::setCurrent (load);
526 g_win->R()->setDocument (load); 526 g_win->R()->setDocument (load);
527 log (QObject::tr ("File %1 parsed successfully (%2 errors)."), path, numWarnings); 527 print (QObject::tr ("File %1 parsed successfully (%2 errors)."), path, numWarnings);
528 } 528 }
529 529
530 load->history()->setIgnoring (false); 530 load->history()->setIgnoring (false);
531 return load; 531 return load;
532 } 532 }
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 = format (tr ("There are unsaved changes to %1. Should it be saved?"),
545 (name().length() > 0) ? name() : 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
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 = format (tr ("Failed to save %1 (%2)\nDo you still want to close?"),
569 name(), 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 {
681 681
682 if (!g_aborted) 682 if (!g_aborted)
683 { 683 {
684 // Tell the user loading failed. 684 // Tell the user loading failed.
685 setlocale (LC_ALL, "C"); 685 setlocale (LC_ALL, "C");
686 critical (fmt (QObject::tr ("Failed to open %1: %2"), path, strerror (errno))); 686 critical (format (QObject::tr ("Failed to open %1: %2"), path, strerror (errno)));
687 } 687 }
688 688
689 g_loadingMainFile = false; 689 g_loadingMainFile = false;
690 return; 690 return;
691 } 691 }
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->references()) 698 for (LDDocumentPointer* ptr : documentToReplace->references())
699 { dlog ("ptr: %1 (%2)\n", 699 { dprint ("ptr: %1 (%2)\n",
700 ptr, ptr->pointer() ? ptr->pointer()->name() : "<null>"); 700 ptr, ptr->pointer() ? ptr->pointer()->name() : "<null>");
701 701
702 *ptr = file; 702 *ptr = file;
703 } 703 }
704 704
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->setText (fmt ("Name: %1", newname)); 745 nameComment->setText (format ("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
786 // ============================================================================= 786 // =============================================================================
787 // 787 //
788 void checkTokenCount (QString line, const QStringList& tokens, int num) 788 void checkTokenCount (QString line, const QStringList& tokens, int num)
789 { 789 {
790 if (tokens.size() != num) 790 if (tokens.size() != num)
791 throw LDParseError (line, fmt ("Bad amount of tokens, expected %1, got %2", num, tokens.size())); 791 throw LDParseError (line, format ("Bad amount of tokens, expected %1, got %2", num, tokens.size()));
792 } 792 }
793 793
794 // ============================================================================= 794 // =============================================================================
795 // 795 //
796 void checkTokenNumbers (QString line, const QStringList& tokens, int min, int max) 796 void checkTokenNumbers (QString line, const QStringList& tokens, int min, int max)
803 for (int i = min; i <= max; ++i) 803 for (int i = min; i <= max; ++i)
804 { 804 {
805 tokens[i].toDouble (&ok); 805 tokens[i].toDouble (&ok);
806 806
807 if (!ok && !scient.exactMatch (tokens[i])) 807 if (!ok && !scient.exactMatch (tokens[i]))
808 throw LDParseError (line, fmt ("Token #%1 was `%2`, expected a number (matched length: %3)", (i + 1), tokens[i], scient.matchedLength())); 808 throw LDParseError (line, format ("Token #%1 was `%2`, expected a number (matched length: %3)", (i + 1), tokens[i], scient.matchedLength()));
809 } 809 }
810 } 810 }
811 811
812 // ============================================================================= 812 // =============================================================================
813 // 813 //
852 852
853 // Handle BFC statements 853 // Handle BFC statements
854 if (tokens.size() > 2 && tokens[1] == "BFC") 854 if (tokens.size() > 2 && tokens[1] == "BFC")
855 { 855 {
856 for (int i = 0; i < LDBFC::NumStatements; ++i) 856 for (int i = 0; i < LDBFC::NumStatements; ++i)
857 if (comm == fmt ("BFC %1", LDBFC::k_statementStrings [i])) 857 if (comm == format ("BFC %1", LDBFC::k_statementStrings [i]))
858 return new LDBFC ( (LDBFC::Statement) i); 858 return new LDBFC ( (LDBFC::Statement) i);
859 859
860 // MLCAD is notorious for stuffing these statements in parts it 860 // MLCAD is notorious for stuffing these statements in parts it
861 // creates. The above block only handles valid statements, so we 861 // creates. The above block only handles valid statements, so we
862 // need to handle MLCAD-style invertnext, clip and noclip separately. 862 // need to handle MLCAD-style invertnext, clip and noclip separately.
929 929
930 // If we cannot open the file, mark it an error. Note we cannot use LDParseError 930 // If we cannot open the file, mark it an error. Note we cannot use LDParseError
931 // here because the error object needs the document reference. 931 // here because the error object needs the document reference.
932 if (!load) 932 if (!load)
933 { 933 {
934 LDError* obj = new LDError (line, fmt ("Could not open %1", tokens[14])); 934 LDError* obj = new LDError (line, format ("Could not open %1", tokens[14]));
935 obj->setFileReferenced (tokens[14]); 935 obj->setFileReferenced (tokens[14]);
936 return obj; 936 return obj;
937 } 937 }
938 938
939 LDSubfile* obj = new LDSubfile; 939 LDSubfile* obj = new LDSubfile;
1045 LDDocument* fileInfo = getDocument (ref->fileInfo()->name()); 1045 LDDocument* fileInfo = getDocument (ref->fileInfo()->name());
1046 1046
1047 if (fileInfo) 1047 if (fileInfo)
1048 ref->setFileInfo (fileInfo); 1048 ref->setFileInfo (fileInfo);
1049 else 1049 else
1050 ref->replace (new LDError (ref->asText(), fmt ("Could not open %1", ref->fileInfo()->name()))); 1050 ref->replace (new LDError (ref->asText(), format ("Could not open %1", ref->fileInfo()->name())));
1051 } 1051 }
1052 1052
1053 // Reparse gibberish files. It could be that they are invalid because 1053 // Reparse gibberish files. It could be that they are invalid because
1054 // of loading errors. Circumstances may be different now. 1054 // of loading errors. Circumstances may be different now.
1055 if (obj->type() == LDObject::EError) 1055 if (obj->type() == LDObject::EError)
1067 if (obj->type() == LDObject::EVertex) 1067 if (obj->type() == LDObject::EVertex)
1068 m_vertices << obj; 1068 m_vertices << obj;
1069 1069
1070 #ifdef DEBUG 1070 #ifdef DEBUG
1071 if (!isImplicit()) 1071 if (!isImplicit())
1072 dlog ("Added object #%1 (%2)\n", obj->id(), obj->typeName()); 1072 dprint ("Added object #%1 (%2)\n", obj->id(), obj->typeName());
1073 #endif 1073 #endif
1074 1074
1075 obj->setDocument (this); 1075 obj->setDocument (this);
1076 return getObjectCount() - 1; 1076 return getObjectCount() - 1;
1077 } 1077 }
1093 m_objects.insert (pos, obj); 1093 m_objects.insert (pos, obj);
1094 obj->setDocument (this); 1094 obj->setDocument (this);
1095 1095
1096 #ifdef DEBUG 1096 #ifdef DEBUG
1097 if (!isImplicit()) 1097 if (!isImplicit())
1098 dlog ("Inserted object #%1 (%2) at %3\n", obj->id(), obj->typeName(), pos); 1098 dprint ("Inserted object #%1 (%2) at %3\n", obj->id(), obj->typeName(), pos);
1099 #endif 1099 #endif
1100 } 1100 }
1101 1101
1102 // ============================================================================= 1102 // =============================================================================
1103 // 1103 //
1303 g_win->updateDocumentListItem (f); 1303 g_win->updateDocumentListItem (f);
1304 g_win->buildObjList(); 1304 g_win->buildObjList();
1305 g_win->updateTitle(); 1305 g_win->updateTitle();
1306 g_win->R()->setDocument (f); 1306 g_win->R()->setDocument (f);
1307 g_win->R()->repaint(); 1307 g_win->R()->repaint();
1308 log ("Changed file to %1", f->getDisplayName()); 1308 print ("Changed file to %1", f->getDisplayName());
1309 } 1309 }
1310 } 1310 }
1311 1311
1312 // ============================================================================= 1312 // =============================================================================
1313 // 1313 //
1348 delete g_logoedStud2; 1348 delete g_logoedStud2;
1349 1349
1350 g_logoedStud = openDocument ("stud-logo.dat", true); 1350 g_logoedStud = openDocument ("stud-logo.dat", true);
1351 g_logoedStud2 = openDocument ("stud2-logo.dat", true); 1351 g_logoedStud2 = openDocument ("stud2-logo.dat", true);
1352 1352
1353 log (LDDocument::tr ("Logoed studs loaded.\n")); 1353 print (LDDocument::tr ("Logoed studs loaded.\n"));
1354 } 1354 }
1355 1355
1356 // ============================================================================= 1356 // =============================================================================
1357 // 1357 //
1358 void LDDocument::addToSelection (LDObject* obj) // [protected] 1358 void LDDocument::addToSelection (LDObject* obj) // [protected]

mercurial