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 }