1 #include "xdtsimportpopup.h"
2 
3 #include "tapp.h"
4 #include "tsystem.h"
5 #include "toonzqt/filefield.h"
6 #include "toonz/toonzscene.h"
7 
8 #include <QMainWindow>
9 #include <QTableView>
10 #include <QPushButton>
11 #include <QScrollArea>
12 #include <QGridLayout>
13 #include <QLabel>
14 
15 using namespace DVGui;
16 
XDTSImportPopup(QStringList levelNames,ToonzScene * scene,TFilePath scenePath)17 XDTSImportPopup::XDTSImportPopup(QStringList levelNames, ToonzScene* scene,
18                                  TFilePath scenePath)
19     : m_scene(scene)
20     , DVGui::Dialog(TApp::instance()->getMainWindow(), true, false,
21                     "XDTSImport") {
22   setWindowTitle(tr("Importing XDTS file %1")
23                      .arg(QString::fromStdString(scenePath.getLevelName())));
24   QPushButton* loadButton   = new QPushButton(tr("Load"), this);
25   QPushButton* cancelButton = new QPushButton(tr("Cancel"), this);
26 
27   QString description =
28       tr("Please specify the level locations. Suggested paths "
29          "are input in the fields with blue border.");
30 
31   m_topLayout->addWidget(new QLabel(description, this), 0);
32   m_topLayout->addSpacing(15);
33 
34   QScrollArea* fieldsArea = new QScrollArea(this);
35   fieldsArea->setWidgetResizable(true);
36 
37   QWidget* fieldsWidget = new QWidget(this);
38 
39   QGridLayout* fieldsLay = new QGridLayout();
40   fieldsLay->setMargin(0);
41   fieldsLay->setHorizontalSpacing(10);
42   fieldsLay->setVerticalSpacing(10);
43   fieldsLay->addWidget(new QLabel(tr("Level Name"), this), 0, 0,
44                        Qt::AlignLeft | Qt::AlignVCenter);
45   fieldsLay->addWidget(new QLabel(tr("Level Path"), this), 0, 1,
46                        Qt::AlignLeft | Qt::AlignVCenter);
47   for (QString& levelName : levelNames) {
48     int row = fieldsLay->rowCount();
49     fieldsLay->addWidget(new QLabel(levelName, this), row, 0,
50                          Qt::AlignRight | Qt::AlignVCenter);
51     FileField* fileField = new FileField(this);
52     fieldsLay->addWidget(fileField, row, 1);
53     m_fields.insert(levelName, fileField);
54     fileField->setFileMode(QFileDialog::AnyFile);
55     fileField->setObjectName("SuggestiveFileField");
56     connect(fileField, SIGNAL(pathChanged()), this, SLOT(onPathChanged()));
57   }
58   fieldsLay->setColumnStretch(1, 1);
59   fieldsLay->setRowStretch(fieldsLay->rowCount(), 1);
60 
61   fieldsWidget->setLayout(fieldsLay);
62   fieldsArea->setWidget(fieldsWidget);
63   m_topLayout->addWidget(fieldsArea, 1);
64 
65   connect(loadButton, SIGNAL(clicked()), this, SLOT(accept()));
66   connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
67 
68   addButtonBarWidget(loadButton, cancelButton);
69 
70   updateSuggestions(scenePath.getQString());
71 }
72 
73 //-----------------------------------------------------------------------------
74 
onPathChanged()75 void XDTSImportPopup::onPathChanged() {
76   FileField* fileField = dynamic_cast<FileField*>(sender());
77   if (!fileField) return;
78   QString levelName = m_fields.key(fileField);
79   // make the field non-suggestive
80   m_pathSuggestedLevels.removeAll(levelName);
81 
82   // if the path is specified under the sub-folder with the same name as the
83   // level, then try to make suggestions from the parent folder of it
84   TFilePath fp =
85       m_scene->decodeFilePath(TFilePath(fileField->getPath())).getParentDir();
86   if (QDir(fp.getQString()).dirName() == levelName)
87     updateSuggestions(fp.getQString());
88 
89   updateSuggestions(fileField->getPath());
90 }
91 
92 //-----------------------------------------------------------------------------
93 
updateSuggestions(const QString samplePath)94 void XDTSImportPopup::updateSuggestions(const QString samplePath) {
95   TFilePath fp(samplePath);
96   fp = m_scene->decodeFilePath(fp).getParentDir();
97   QDir suggestFolder(fp.getQString());
98   QStringList filters;
99   filters << "*.bmp"
100           << "*.jpg"
101           << "*.nol"
102           << "*.pic"
103           << "*.pict"
104           << "*.pct"
105           << "*.png"
106           << "*.rgb"
107           << "*.sgi"
108           << "*.tga"
109           << "*.tif"
110           << "*.tiff"
111           << "*.tlv"
112           << "*.pli"
113           << "*.psd";
114   suggestFolder.setNameFilters(filters);
115   suggestFolder.setFilter(QDir::Files);
116   TFilePathSet pathSet;
117   try {
118     TSystem::readDirectory(pathSet, suggestFolder, true);
119   } catch (...) {
120     return;
121   }
122 
123   QMap<QString, FileField*>::iterator fieldsItr = m_fields.begin();
124   while (fieldsItr != m_fields.end()) {
125     QString levelName    = fieldsItr.key();
126     FileField* fileField = fieldsItr.value();
127     // check if the field can be filled with suggestion
128     if (fileField->getPath().isEmpty() ||
129         m_pathSuggestedLevels.contains(levelName)) {
130       // input suggestion if there is a file with the same level name
131       bool found = false;
132       for (TFilePath path : pathSet) {
133         if (path.getName() == levelName.toStdString()) {
134           TFilePath codedPath = m_scene->codeFilePath(path);
135           fileField->setPath(codedPath.getQString());
136           if (!m_pathSuggestedLevels.contains(levelName))
137             m_pathSuggestedLevels.append(levelName);
138           found = true;
139           break;
140         }
141       }
142       // Not found in the current folder.
143       // Then check if there is a sub-folder with the same name as the level
144       // (like foo/A/A.tlv), as CSP exports levels like that.
145       if (!found && suggestFolder.cd(levelName)) {
146         TFilePathSet subPathSet;
147         try {
148           TSystem::readDirectory(subPathSet, suggestFolder, true);
149         } catch (...) {
150           return;
151         }
152         for (TFilePath path : subPathSet) {
153           if (path.getName() == levelName.toStdString()) {
154             TFilePath codedPath = m_scene->codeFilePath(path);
155             fileField->setPath(codedPath.getQString());
156             if (!m_pathSuggestedLevels.contains(levelName))
157               m_pathSuggestedLevels.append(levelName);
158             break;
159           }
160         }
161         // back to parent folder
162         suggestFolder.cdUp();
163       }
164     }
165     ++fieldsItr;
166   }
167 
168   // repaint fields
169   fieldsItr = m_fields.begin();
170   while (fieldsItr != m_fields.end()) {
171     if (m_pathSuggestedLevels.contains(fieldsItr.key()))
172       fieldsItr.value()->setStyleSheet(
173           QString("#SuggestiveFileField "
174                   "QLineEdit{border-color:#2255aa;border-width:2px;}"));
175     else
176       fieldsItr.value()->setStyleSheet(QString(""));
177     ++fieldsItr;
178   }
179 }
180 
getLevelPath(QString levelName)181 QString XDTSImportPopup::getLevelPath(QString levelName) {
182   FileField* field = m_fields.value(levelName);
183   if (!field) return QString();
184   return field->getPath();
185 }