1 #include "loader.hpp"
2 
3 #include <QVBoxLayout>
4 #include <QLabel>
5 #include <QProgressBar>
6 #include <QCursor>
7 #include <QDialogButtonBox>
8 #include <QCloseEvent>
9 #include <QListWidget>
10 
11 #include "../../model/doc/document.hpp"
12 
closeEvent(QCloseEvent * event)13 void CSVDoc::LoadingDocument::closeEvent (QCloseEvent *event)
14 {
15     event->ignore();
16     cancel();
17 }
18 
LoadingDocument(CSMDoc::Document * document)19 CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document)
20 : mDocument (document), mAborted (false), mMessages (nullptr), mTotalRecords (0)
21 {
22     setWindowTitle (QString::fromUtf8((std::string("Opening ") + document->getSavePath().filename().string()).c_str()));
23 
24     setMinimumWidth (400);
25 
26     mLayout = new QVBoxLayout (this);
27 
28     // file progress
29     mFile = new QLabel (this);
30 
31     mLayout->addWidget (mFile);
32 
33     mFileProgress = new QProgressBar (this);
34 
35     mLayout->addWidget (mFileProgress);
36 
37     int size = static_cast<int> (document->getContentFiles().size())+1;
38     if (document->isNew())
39         --size;
40 
41     mFileProgress->setMinimum (0);
42     mFileProgress->setMaximum (size);
43     mFileProgress->setTextVisible (true);
44     mFileProgress->setValue (0);
45 
46     // record progress
47     mLayout->addWidget (mRecords = new QLabel ("Records", this));
48 
49     mRecordProgress = new QProgressBar (this);
50 
51     mLayout->addWidget (mRecordProgress);
52 
53     mRecordProgress->setMinimum (0);
54     mRecordProgress->setTextVisible (true);
55     mRecordProgress->setValue (0);
56 
57     // error message
58     mError = new QLabel (this);
59     mError->setWordWrap (true);
60 
61     mLayout->addWidget (mError);
62 
63     // buttons
64     mButtons = new QDialogButtonBox (QDialogButtonBox::Cancel, Qt::Horizontal, this);
65 
66     mLayout->addWidget (mButtons);
67 
68     setLayout (mLayout);
69 
70     move (QCursor::pos());
71 
72     show();
73 
74     connect (mButtons, SIGNAL (rejected()), this, SLOT (cancel()));
75 }
76 
nextStage(const std::string & name,int totalRecords)77 void CSVDoc::LoadingDocument::nextStage (const std::string& name, int totalRecords)
78 {
79     mFile->setText (QString::fromUtf8 (("Loading: " + name).c_str()));
80 
81     mFileProgress->setValue (mFileProgress->value()+1);
82 
83     mRecordProgress->setValue (0);
84     mRecordProgress->setMaximum (totalRecords>0 ? totalRecords : 1);
85 
86     mTotalRecords = totalRecords;
87 }
88 
nextRecord(int records)89 void CSVDoc::LoadingDocument::nextRecord (int records)
90 {
91     if (records<=mTotalRecords)
92     {
93         mRecordProgress->setValue (records);
94 
95         std::ostringstream stream;
96 
97         stream << "Records: " << records << " of " << mTotalRecords;
98 
99         mRecords->setText (QString::fromUtf8 (stream.str().c_str()));
100     }
101 }
102 
abort(const std::string & error)103 void CSVDoc::LoadingDocument::abort (const std::string& error)
104 {
105     mAborted = true;
106     mError->setText (QString::fromUtf8 (("<font color=red>Loading failed: " + error + "</font>").c_str()));
107     mButtons->setStandardButtons (QDialogButtonBox::Close);
108 }
109 
addMessage(const std::string & message)110 void CSVDoc::LoadingDocument::addMessage (const std::string& message)
111 {
112     if (!mMessages)
113     {
114         mMessages = new QListWidget (this);
115         mLayout->insertWidget (4, mMessages);
116     }
117 
118     new QListWidgetItem (QString::fromUtf8 (message.c_str()), mMessages);
119 }
120 
cancel()121 void CSVDoc::LoadingDocument::cancel()
122 {
123     if (!mAborted)
124         emit cancel (mDocument);
125     else
126     {
127         emit close (mDocument);
128         deleteLater();
129     }
130 }
131 
132 
Loader()133 CSVDoc::Loader::Loader() {}
134 
~Loader()135 CSVDoc::Loader::~Loader()
136 {
137     for (std::map<CSMDoc::Document *, LoadingDocument *>::iterator iter (mDocuments.begin());
138         iter!=mDocuments.end(); ++iter)
139         delete iter->second;
140 }
141 
add(CSMDoc::Document * document)142 void CSVDoc::Loader::add (CSMDoc::Document *document)
143 {
144     LoadingDocument *loading = new LoadingDocument (document);
145     mDocuments.insert (std::make_pair (document, loading));
146 
147     connect (loading, SIGNAL (cancel (CSMDoc::Document *)),
148         this, SIGNAL (cancel (CSMDoc::Document *)));
149     connect (loading, SIGNAL (close (CSMDoc::Document *)),
150         this, SIGNAL (close (CSMDoc::Document *)));
151 }
152 
loadingStopped(CSMDoc::Document * document,bool completed,const std::string & error)153 void CSVDoc::Loader::loadingStopped (CSMDoc::Document *document, bool completed,
154     const std::string& error)
155 {
156     std::map<CSMDoc::Document *, LoadingDocument *>::iterator iter = mDocuments.begin();
157 
158     for (; iter!=mDocuments.end(); ++iter)
159         if (iter->first==document)
160             break;
161 
162     if (iter==mDocuments.end())
163         return;
164 
165     if (completed || error.empty())
166     {
167         delete iter->second;
168         mDocuments.erase (iter);
169     }
170     else
171     {
172         iter->second->abort (error);
173         // Leave the window open for now (wait for the user to close it)
174         mDocuments.erase (iter);
175     }
176 }
177 
nextStage(CSMDoc::Document * document,const std::string & name,int totalRecords)178 void CSVDoc::Loader::nextStage (CSMDoc::Document *document, const std::string& name,
179     int totalRecords)
180 {
181     std::map<CSMDoc::Document *, LoadingDocument *>::iterator iter = mDocuments.find (document);
182 
183     if (iter!=mDocuments.end())
184         iter->second->nextStage (name, totalRecords);
185 }
186 
nextRecord(CSMDoc::Document * document,int records)187 void CSVDoc::Loader::nextRecord (CSMDoc::Document *document, int records)
188 {
189     std::map<CSMDoc::Document *, LoadingDocument *>::iterator iter = mDocuments.find (document);
190 
191     if (iter!=mDocuments.end())
192         iter->second->nextRecord (records);
193 }
194 
loadMessage(CSMDoc::Document * document,const std::string & message)195 void CSVDoc::Loader::loadMessage (CSMDoc::Document *document, const std::string& message)
196 {
197     std::map<CSMDoc::Document *, LoadingDocument *>::iterator iter = mDocuments.find (document);
198 
199     if (iter!=mDocuments.end())
200         iter->second->addMessage (message);
201 }
202