1
2
3 #include "svnrevertdialog.h"
4
5 // Tnz6 includes
6 #include "tapp.h"
7
8 // TnzQt includes
9 #include "toonzqt/gutil.h"
10
11 // TnzLib includes
12 #include "toonz/txshsimplelevel.h"
13
14 // TnzCore includes
15 #include "tfilepath.h"
16 #include "tsystem.h"
17
18 // Qt includes
19 #include <QPushButton>
20 #include <QTreeWidget>
21 #include <QHeaderView>
22 #include <QCheckBox>
23 #include <QMovie>
24 #include <QLabel>
25 #include <QDir>
26 #include <QRegExp>
27 #include <QMainWindow>
28
29 //=============================================================================
30 // SVNRevertDialog
31 //-----------------------------------------------------------------------------
32
SVNRevertDialog(QWidget * parent,const QString & workingDir,const QStringList & files,bool folderOnly,int sceneIconAdded)33 SVNRevertDialog::SVNRevertDialog(QWidget *parent, const QString &workingDir,
34 const QStringList &files, bool folderOnly,
35 int sceneIconAdded)
36 : Dialog(TApp::instance()->getMainWindow(), true, false)
37 , m_workingDir(workingDir)
38 , m_files(files)
39 , m_revertSceneContentsCheckBox(0)
40 , m_folderOnly(folderOnly)
41 , m_sceneIconAdded(sceneIconAdded) {
42 setModal(false);
43 setMinimumSize(300, 150);
44 setAttribute(Qt::WA_DeleteOnClose, true);
45 setWindowTitle(tr("Version Control: Revert changes"));
46
47 QWidget *container = new QWidget;
48
49 QVBoxLayout *mainLayout = new QVBoxLayout;
50 mainLayout->setAlignment(Qt::AlignHCenter);
51 mainLayout->setMargin(0);
52
53 QHBoxLayout *hLayout = new QHBoxLayout;
54
55 m_waitingLabel = new QLabel;
56 QMovie *waitingMove = new QMovie(":Resources/waiting.gif");
57 waitingMove->setParent(this);
58
59 m_waitingLabel->setMovie(waitingMove);
60 waitingMove->setCacheMode(QMovie::CacheAll);
61 waitingMove->start();
62
63 m_textLabel = new QLabel(tr("Getting repository status..."));
64
65 hLayout->addStretch();
66 hLayout->addWidget(m_waitingLabel);
67 hLayout->addWidget(m_textLabel);
68 hLayout->addStretch();
69
70 mainLayout->addLayout(hLayout);
71
72 m_treeWidget = new QTreeWidget;
73 m_treeWidget->setStyleSheet("QTreeWidget { border: 1px solid gray; }");
74 m_treeWidget->header()->hide();
75 m_treeWidget->hide();
76 mainLayout->addWidget(m_treeWidget);
77
78 if (!m_folderOnly) {
79 mainLayout->addSpacing(10);
80 QHBoxLayout *checkBoxLayout = new QHBoxLayout;
81 checkBoxLayout->setMargin(0);
82 m_revertSceneContentsCheckBox = new QCheckBox(this);
83 connect(m_revertSceneContentsCheckBox, SIGNAL(toggled(bool)), this,
84 SLOT(onRevertSceneContentsToggled(bool)));
85 m_revertSceneContentsCheckBox->setChecked(false);
86 m_revertSceneContentsCheckBox->hide();
87 m_revertSceneContentsCheckBox->setText(tr("Revert Scene Contents"));
88 checkBoxLayout->addStretch();
89 checkBoxLayout->addWidget(m_revertSceneContentsCheckBox);
90 checkBoxLayout->addStretch();
91 mainLayout->addLayout(checkBoxLayout);
92 }
93
94 container->setLayout(mainLayout);
95
96 beginHLayout();
97 addWidget(container, false);
98 endHLayout();
99
100 m_revertButton = new QPushButton(tr("Revert"));
101 m_revertButton->setEnabled(false);
102 connect(m_revertButton, SIGNAL(clicked()), this,
103 SLOT(onRevertButtonClicked()));
104
105 m_cancelButton = new QPushButton(tr("Cancel"));
106 connect(m_cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
107
108 addButtonBarWidget(m_revertButton, m_cancelButton);
109
110 // 0. Connect for svn errors (that may occurs everythings)
111 connect(&m_thread, SIGNAL(error(const QString &)), this,
112 SLOT(onError(const QString &)));
113
114 // 1. Getting status
115 connect(&m_thread, SIGNAL(statusRetrieved(const QString &)), this,
116 SLOT(onStatusRetrieved(const QString &)));
117 m_thread.getSVNStatus(m_workingDir);
118 }
119
120 //-----------------------------------------------------------------------------
121
onStatusRetrieved(const QString & xmlResponse)122 void SVNRevertDialog::onStatusRetrieved(const QString &xmlResponse) {
123 SVNStatusReader sr(xmlResponse);
124 m_status = sr.getStatus();
125 int height = 50;
126
127 checkFiles();
128
129 int fileSize = m_filesToRevert.size();
130 for (int i = 0; i < fileSize; i++) {
131 if (m_filesToRevert.at(i).endsWith(".tnz")) {
132 if (m_revertSceneContentsCheckBox) m_revertSceneContentsCheckBox->show();
133 break;
134 }
135 }
136
137 initTreeWidget();
138
139 if (m_filesToRevert.size() == 0) {
140 QString msg = QString(tr("No items to revert."));
141 m_textLabel->setText(msg);
142 switchToCloseButton();
143 } else {
144 if (m_treeWidget->isVisible()) height += (m_filesToRevert.size() * 50);
145
146 setMinimumSize(300, std::min(height, 350));
147
148 QString msg = QString(tr("%1 items to revert."))
149 .arg(m_filesToRevert.size() == 1
150 ? 1
151 : m_filesToRevert.size() - m_sceneIconAdded);
152 m_textLabel->setText(msg);
153
154 m_waitingLabel->hide();
155 m_revertButton->setEnabled(true);
156
157 m_thread.disconnect(SIGNAL(statusRetrieved(const QString &)));
158 }
159 }
160
161 //-----------------------------------------------------------------------------
162
checkFiles()163 void SVNRevertDialog::checkFiles() {
164 int statusCount = m_status.size();
165 for (int i = 0; i < statusCount; i++) {
166 SVNStatus s = m_status.at(i);
167 if (s.m_path == "." || s.m_path == "..") continue;
168 if (s.m_item != "normal" && s.m_item != "unversioned") {
169 if (m_folderOnly || m_files.contains(s.m_path))
170 m_filesToRevert.append(s.m_path);
171 }
172 }
173 }
174
175 //-----------------------------------------------------------------------------
176
initTreeWidget()177 void SVNRevertDialog::initTreeWidget() {
178 int filesSize = m_filesToRevert.size();
179
180 bool itemAdded = false;
181
182 for (int i = 0; i < filesSize; i++) {
183 QString fileName = m_filesToRevert.at(i);
184 TFilePath fp =
185 TFilePath(m_workingDir.toStdWString()) + fileName.toStdWString();
186 TFilePathSet fpset;
187 TXshSimpleLevel::getFiles(fp, fpset);
188
189 QStringList linkedFiles;
190
191 TFilePathSet::iterator it;
192 for (it = fpset.begin(); it != fpset.end(); ++it) {
193 QString fn = toQString((*it).withoutParentDir());
194
195 if (m_filesToRevert.contains(fn)) linkedFiles.append(fn);
196 }
197
198 if (!linkedFiles.isEmpty()) {
199 itemAdded = true;
200 QTreeWidgetItem *twi = new QTreeWidgetItem(m_treeWidget);
201 twi->setText(0, fileName);
202 twi->setFirstColumnSpanned(false);
203 twi->setFlags(Qt::NoItemFlags);
204
205 for (int i = 0; i < linkedFiles.size(); i++) {
206 QTreeWidgetItem *child = new QTreeWidgetItem(twi);
207 child->setText(0, linkedFiles.at(i));
208 child->setFlags(Qt::NoItemFlags);
209 }
210 twi->setExpanded(true);
211 }
212 }
213
214 if (itemAdded) m_treeWidget->show();
215 }
216
217 //-----------------------------------------------------------------------------
218
switchToCloseButton()219 void SVNRevertDialog::switchToCloseButton() {
220 m_waitingLabel->hide();
221 m_treeWidget->hide();
222 m_revertButton->disconnect();
223 m_revertButton->setText("Close");
224 m_revertButton->setEnabled(true);
225 m_cancelButton->hide();
226 connect(m_revertButton, SIGNAL(clicked()), this, SLOT(close()));
227 }
228
229 //-----------------------------------------------------------------------------
230
onRevertButtonClicked()231 void SVNRevertDialog::onRevertButtonClicked() {
232 m_revertButton->setEnabled(false);
233 revertFiles();
234 }
235
236 //-----------------------------------------------------------------------------
237
revertFiles()238 void SVNRevertDialog::revertFiles() {
239 m_treeWidget->hide();
240 if (m_revertSceneContentsCheckBox) m_revertSceneContentsCheckBox->hide();
241 m_waitingLabel->show();
242
243 int fileToRevertSize = m_filesToRevert.size();
244 int sceneResourceToRevertSize = m_sceneResources.size();
245 int totalFilesToRevert = fileToRevertSize + sceneResourceToRevertSize;
246 if (totalFilesToRevert > 0) {
247 m_textLabel->setText(tr("Reverting %1 items...")
248 .arg(totalFilesToRevert == 1
249 ? 1
250 : totalFilesToRevert - m_sceneIconAdded));
251
252 QStringList args;
253 args << "revert";
254
255 for (int i = 0; i < fileToRevertSize; i++) args << m_filesToRevert.at(i);
256
257 for (int i = 0; i < sceneResourceToRevertSize; i++)
258 args << m_sceneResources.at(i);
259
260 connect(&m_thread, SIGNAL(done(const QString &)), SLOT(onRevertDone()));
261 m_thread.executeCommand(m_workingDir, "svn", args);
262 } else
263 onRevertDone();
264 }
265
266 //-----------------------------------------------------------------------------
267
onRevertDone()268 void SVNRevertDialog::onRevertDone() {
269 m_textLabel->setText(tr("Revert done successfully."));
270
271 QStringList files;
272 for (int i = 0; i < m_filesToRevert.size(); i++)
273 files.append(m_filesToRevert.at(i));
274 emit done(files);
275
276 switchToCloseButton();
277 }
278
279 //-----------------------------------------------------------------------------
280
onError(const QString & errorString)281 void SVNRevertDialog::onError(const QString &errorString) {
282 m_textLabel->setText(errorString);
283 switchToCloseButton();
284 update();
285 }
286
287 //-----------------------------------------------------------------------------
288
onRevertSceneContentsToggled(bool checked)289 void SVNRevertDialog::onRevertSceneContentsToggled(bool checked) {
290 if (!checked)
291 m_sceneResources.clear();
292 else {
293 VersionControl *vc = VersionControl::instance();
294
295 int fileSize = m_filesToRevert.count();
296 for (int i = 0; i < fileSize; i++) {
297 QString fileName = m_filesToRevert.at(i);
298 if (fileName.endsWith(".tnz")) {
299 if (m_filesToRevert.contains(fileName))
300 m_sceneResources.append(vc->getSceneContents(m_workingDir, fileName));
301 }
302 }
303 }
304 m_textLabel->setText(
305 tr("%1 items to revert.")
306 .arg(m_filesToRevert.size() + m_sceneResources.size() == 1
307 ? 1
308 : m_filesToRevert.size() + m_sceneResources.size() -
309 m_sceneIconAdded));
310 }
311
312 //=============================================================================
313 // SVNRevertFrameRangeDialog
314 //-----------------------------------------------------------------------------
315
SVNRevertFrameRangeDialog(QWidget * parent,const QString & workingDir,const QString & file,const QString & tempFileName)316 SVNRevertFrameRangeDialog::SVNRevertFrameRangeDialog(
317 QWidget *parent, const QString &workingDir, const QString &file,
318 const QString &tempFileName)
319 : Dialog(TApp::instance()->getMainWindow(), true, false)
320 , m_workingDir(workingDir)
321 , m_file(file)
322 , m_tempFileName(tempFileName) {
323 setModal(false);
324 setMinimumSize(300, 150);
325 setAttribute(Qt::WA_DeleteOnClose, true);
326 setWindowTitle(tr("Version Control: Revert Frame Range changes"));
327
328 beginVLayout();
329
330 m_waitingLabel = new QLabel;
331 QMovie *waitingMove = new QMovie(":Resources/waiting.gif");
332 waitingMove->setParent(this);
333
334 m_waitingLabel->setMovie(waitingMove);
335 waitingMove->setCacheMode(QMovie::CacheAll);
336 waitingMove->start();
337 m_waitingLabel->hide();
338
339 m_textLabel = new QLabel(tr("1 item to revert."));
340
341 addWidgets(m_waitingLabel, m_textLabel);
342
343 endVLayout();
344
345 m_revertButton = new QPushButton(tr("Revert"));
346 connect(m_revertButton, SIGNAL(clicked()), this,
347 SLOT(onRevertButtonClicked()));
348
349 m_cancelButton = new QPushButton(tr("Cancel"));
350 connect(m_cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
351
352 addButtonBarWidget(m_revertButton, m_cancelButton);
353 }
354
355 //-----------------------------------------------------------------------------
356
switchToCloseButton()357 void SVNRevertFrameRangeDialog::switchToCloseButton() {
358 m_waitingLabel->hide();
359 m_revertButton->disconnect();
360 m_revertButton->setText("Close");
361 m_revertButton->setEnabled(true);
362 m_cancelButton->hide();
363 connect(m_revertButton, SIGNAL(clicked()), this, SLOT(close()));
364 }
365
366 //-----------------------------------------------------------------------------
367
onRevertButtonClicked()368 void SVNRevertFrameRangeDialog::onRevertButtonClicked() {
369 m_revertButton->setEnabled(false);
370 revertFiles();
371 }
372
373 //-----------------------------------------------------------------------------
374
revertFiles()375 void SVNRevertFrameRangeDialog::revertFiles() {
376 m_waitingLabel->show();
377 m_textLabel->setText(tr("Reverting 1 item..."));
378
379 try {
380 TFilePath pathToRemove = TFilePath(m_tempFileName.toStdWString());
381 if (TSystem::doesExistFileOrLevel(pathToRemove))
382 TSystem::removeFileOrLevel(TFilePath(m_tempFileName.toStdWString()));
383 if (pathToRemove.getType() == "tlv") {
384 pathToRemove = pathToRemove.withType("tpl");
385 if (TSystem::doesExistFileOrLevel(pathToRemove))
386 TSystem::removeFileOrLevel(pathToRemove);
387 }
388
389 TFilePath hookFilePath =
390 pathToRemove.withName(pathToRemove.getName() + "_hooks")
391 .withType("xml");
392 if (TSystem::doesExistFileOrLevel(hookFilePath))
393 TSystem::removeFileOrLevel(hookFilePath);
394 } catch (...) {
395 m_textLabel->setText(tr("It is not possible to revert the file."));
396 switchToCloseButton();
397 return;
398 }
399
400 TFilePath path =
401 TFilePath(m_workingDir.toStdWString()) + m_file.toStdWString();
402
403 if (path.getDots() == "..") {
404 TFilePath dir = path.getParentDir();
405 QDir qDir(QString::fromStdWString(dir.getWideString()));
406 QString levelName =
407 QRegExp::escape(QString::fromStdWString(path.getWideName()));
408 QString levelType = QString::fromStdString(path.getType());
409 QString exp(levelName + ".[0-9]{1,4}." + levelType);
410 QRegExp regExp(exp);
411 QStringList list = qDir.entryList(QDir::Files);
412 m_files = list.filter(regExp);
413
414 // 0. Connect for svn errors (that may occurs everythings)
415 connect(&m_thread, SIGNAL(error(const QString &)), this,
416 SLOT(onError(const QString &)));
417
418 // 1. Getting status
419 connect(&m_thread, SIGNAL(statusRetrieved(const QString &)), this,
420 SLOT(onStatusRetrieved(const QString &)));
421 m_thread.getSVNStatus(m_workingDir, m_files);
422 } else {
423 m_textLabel->setText(tr("Revert done successfully."));
424
425 QStringList files;
426 files.append(m_file);
427 emit done(files);
428
429 switchToCloseButton();
430 }
431 }
432
433 //-----------------------------------------------------------------------------
434
onStatusRetrieved(const QString & xmlResponse)435 void SVNRevertFrameRangeDialog::onStatusRetrieved(const QString &xmlResponse) {
436 SVNStatusReader sr(xmlResponse);
437 m_status = sr.getStatus();
438
439 checkFiles();
440
441 int fileToRevertCount = m_filesToRevert.size();
442
443 if (fileToRevertCount == 0) {
444 m_textLabel->setText(tr("Revert done successfully."));
445 switchToCloseButton();
446 } else {
447 m_thread.disconnect(SIGNAL(statusRetrieved(const QString &)));
448 m_textLabel->setText(
449 tr("Reverting %1 items...").arg(QString::number(fileToRevertCount)));
450
451 QStringList args;
452 args << "revert";
453 for (int i = 0; i < fileToRevertCount; i++) args << m_filesToRevert.at(i);
454
455 connect(&m_thread, SIGNAL(done(const QString &)), SLOT(onRevertDone()));
456 m_thread.executeCommand(m_workingDir, "svn", args);
457 }
458 }
459
460 //-----------------------------------------------------------------------------
461
onError(const QString & errorString)462 void SVNRevertFrameRangeDialog::onError(const QString &errorString) {
463 m_textLabel->setText(errorString);
464 switchToCloseButton();
465 update();
466 }
467
468 //-----------------------------------------------------------------------------
469
checkFiles()470 void SVNRevertFrameRangeDialog::checkFiles() {
471 int statusCount = m_status.size();
472 for (int i = 0; i < statusCount; i++) {
473 SVNStatus s = m_status.at(i);
474 if (s.m_item != "normal" && s.m_item != "unversioned") {
475 if (m_files.contains(s.m_path)) m_filesToRevert.append(s.m_path);
476 }
477 }
478 }
479
480 //-----------------------------------------------------------------------------
481
onRevertDone()482 void SVNRevertFrameRangeDialog::onRevertDone() {
483 m_textLabel->setText(tr("Revert done successfully."));
484
485 QStringList files;
486 for (int i = 0; i < m_filesToRevert.size(); i++)
487 files.append(m_filesToRevert.at(i));
488 emit done(files);
489
490 switchToCloseButton();
491 }
492