src/documentmanager.cpp

changeset 1288
d1e45f90654b
parent 1264
5f00dfde4901
child 1291
9c570a30c98a
equal deleted inserted replaced
1287:f1da43b7f5c6 1288:d1e45f90654b
21 #include <QMessageBox> 21 #include <QMessageBox>
22 #include "documentmanager.h" 22 #include "documentmanager.h"
23 #include "lddocument.h" 23 #include "lddocument.h"
24 #include "mainwindow.h" 24 #include "mainwindow.h"
25 #include "partdownloader.h" 25 #include "partdownloader.h"
26 #include "documentloader.h" 26 #include "parser.h"
27 #include "glrenderer.h" 27 #include "glrenderer.h"
28 28
29 const QStringList DocumentManager::specialSubdirectories {"s", "48", "8"}; 29 const QStringList DocumentManager::specialSubdirectories {"s", "48", "8"};
30 30
31 enum 31 enum
101 { 101 {
102 file = documentToReplace; 102 file = documentToReplace;
103 file->clear(); 103 file->clear();
104 } 104 }
105 105
106 bool aborted; 106 file = openDocument (path, false, false, file);
107 file = openDocument (path, false, false, file, &aborted);
108 107
109 if (file == nullptr) 108 if (file == nullptr)
110 { 109 {
111 if (not aborted) 110 // Tell the user loading failed.
112 { 111 setlocale (LC_ALL, "C");
113 // Tell the user loading failed. 112 QMessageBox::critical(m_window, tr("Error"), format(tr("Failed to open %1: %2"), path, strerror (errno)));
114 setlocale (LC_ALL, "C");
115 QMessageBox::critical(m_window, tr("Error"), format(tr("Failed to open %1: %2"), path, strerror (errno)));
116 }
117
118 m_loadingMainFile = false; 113 m_loadingMainFile = false;
119 return; 114 return;
120 } 115 }
121 116
122 m_window->openDocumentForEditing(file); 117 m_window->openDocumentForEditing(file);
271 266
272 fp->deleteLater(); 267 fp->deleteLater();
273 return nullptr; 268 return nullptr;
274 } 269 }
275 270
276 void DocumentManager::loadFileContents(QIODevice* input, Model& model, int* numWarnings, bool* ok)
277 {
278 if (numWarnings)
279 *numWarnings = 0;
280
281 DocumentLoader* loader = new DocumentLoader {&model, m_loadingMainFile};
282 connect(loader, SIGNAL(parseErrorMessage(QString)), this, SLOT(printParseErrorMessage(QString)));
283 loader->read(input);
284 loader->start();
285
286 // After start() returns, if the loader isn't done yet, it's delaying
287 // its next iteration through the event loop. We need to catch this here
288 // by telling the event loop to tick, which will tick the file loader again.
289 // We keep doing this until the file loader is ready.
290 while (not loader->isDone())
291 qApp->processEvents();
292
293 // If we wanted the success value, supply that now
294 if (ok)
295 *ok = not loader->hasAborted();
296 }
297
298 void DocumentManager::printParseErrorMessage(QString message) 271 void DocumentManager::printParseErrorMessage(QString message)
299 { 272 {
300 print(message); 273 print(message);
301 } 274 }
302 275
303 LDDocument* DocumentManager::openDocument (QString path, bool search, bool implicit, LDDocument* fileToOverride, 276 LDDocument* DocumentManager::openDocument (QString path, bool search, bool implicit, LDDocument* fileToOverride)
304 bool* aborted)
305 { 277 {
306 // Convert the file name to lowercase when searching because some parts contain subfile 278 // Convert the file name to lowercase when searching because some parts contain subfile
307 // subfile references with uppercase file names. I'll assume here that the library will always 279 // subfile references with uppercase file names. I'll assume here that the library will always
308 // use lowercase file names for the part files. 280 // use lowercase file names for the part files.
309 QFile* fp; 281 QFile* fp;
334 306
335 // Loading the file shouldn't count as actual edits to the document. 307 // Loading the file shouldn't count as actual edits to the document.
336 load->history()->setIgnoring (true); 308 load->history()->setIgnoring (true);
337 309
338 int numWarnings; 310 int numWarnings;
339 bool ok; 311 Parser parser {*fp};
340 Model model {this}; 312 load->setHeader(parser.parseHeader());
341 loadFileContents(fp, model, &numWarnings, &ok); 313 parser.parseBody(*load);
342 load->merge(model);
343 fp->close(); 314 fp->close();
344 fp->deleteLater(); 315 fp->deleteLater();
345 316
346 if (aborted)
347 *aborted = ok == false;
348
349 if (not ok)
350 {
351 load->close();
352 return nullptr;
353 }
354
355 if (m_loadingMainFile) 317 if (m_loadingMainFile)
356 { 318 {
319 int numWarnings = 0;
320
321 for (LDObject* object : load->objects())
322 {
323 if (object->type() == LDObjectType::Error)
324 numWarnings += 1;
325 }
326
357 m_window->changeDocument (load); 327 m_window->changeDocument (load);
358 print (tr ("File %1 parsed successfully (%2 errors)."), path, numWarnings); 328 print (tr ("File %1 parsed successfully (%2 errors)."), path, numWarnings);
359 } 329 }
360 330
361 load->history()->setIgnoring (false); 331 load->history()->setIgnoring (false);

mercurial