1 /*
2
3 Pencil2D - Traditional Animation Software
4 Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon
5 Copyright (C) 2012-2020 Matthew Chiawen Chang
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; version 2 of the License.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 */
17
18 #include "filedialog.h"
19
20 #include <QSettings>
21 #include <QFileInfo>
22 #include <QFileDialog>
23
24 #include "fileformat.h"
25 #include "pencildef.h"
26
getOpenFileName(QWidget * parent,FileType fileType,const QString & caption)27 QString FileDialog::getOpenFileName(QWidget* parent, FileType fileType, const QString& caption)
28 {
29 QString strInitialFilePath = getLastOpenPath(fileType);
30 QString strFilter = openFileFilters(fileType);
31 QString strSelectedFilter = getFilterForFile(strFilter, strInitialFilePath);
32
33 QString filePath = QFileDialog::getOpenFileName(parent,
34 caption.isEmpty() ? openDialogCaption(fileType) : caption,
35 strInitialFilePath,
36 strFilter,
37 strSelectedFilter.isNull() ? nullptr : &strSelectedFilter);
38 if (!filePath.isEmpty())
39 {
40 setLastOpenPath(fileType, filePath);
41 }
42
43 return filePath;
44 }
45
getOpenFileNames(QWidget * parent,FileType fileType,const QString & caption)46 QStringList FileDialog::getOpenFileNames(QWidget* parent, FileType fileType, const QString& caption)
47 {
48 QString strInitialFilePath = getLastOpenPath(fileType);
49 QString strFilter = openFileFilters(fileType);
50 QString strSelectedFilter = getFilterForFile(strFilter, strInitialFilePath);
51
52 QStringList filePaths = QFileDialog::getOpenFileNames(parent,
53 caption.isEmpty() ? openDialogCaption(fileType) : caption,
54 strInitialFilePath,
55 strFilter,
56 strSelectedFilter.isNull() ? nullptr : &strSelectedFilter);
57 if (!filePaths.isEmpty() && !filePaths.first().isEmpty())
58 {
59 setLastOpenPath(fileType, filePaths.first());
60 }
61
62 return filePaths;
63 }
64
getSaveFileName(QWidget * parent,FileType fileType,const QString & caption)65 QString FileDialog::getSaveFileName(QWidget* parent, FileType fileType, const QString& caption)
66 {
67 QString strInitialFilePath = getLastSavePath(fileType);
68 QString strFilter = saveFileFilters(fileType);
69 QString strSelectedFilter = getFilterForFile(strFilter, strInitialFilePath);
70
71 QString filePath = QFileDialog::getSaveFileName(parent,
72 caption.isEmpty() ? saveDialogCaption(fileType) : caption,
73 strInitialFilePath,
74 strFilter,
75 strSelectedFilter.isNull() ? nullptr : &strSelectedFilter);
76
77 if (filePath.isEmpty()) { return QString(); }
78
79 setLastSavePath(fileType, filePath);
80
81 QFileInfo info(filePath);
82 if (info.suffix().isEmpty() && strSelectedFilter.isEmpty())
83 {
84 filePath += addDefaultExtensionSuffix(fileType);
85 }
86
87 return filePath;
88 }
89
addDefaultExtensionSuffix(const FileType fileType)90 QString FileDialog::addDefaultExtensionSuffix(const FileType fileType)
91 {
92 switch (fileType)
93 {
94 case FileType::ANIMATION: return PFF_DEFAULT_PROJECT_EXT;
95 case FileType::IMAGE: return PFF_DEFAULT_IMAGE_EXT;
96 case FileType::IMAGE_SEQUENCE: return PFF_DEFAULT_IMAGE_SEQ_EXT;
97 case FileType::GIF: return PFF_DEFAULT_ANIMATED_EXT;
98 case FileType::PALETTE: return PFF_DEFAULT_PALETTE_EXT;
99 default:
100 return "";
101 }
102 }
103
getLastOpenPath(FileType fileType)104 QString FileDialog::getLastOpenPath(FileType fileType)
105 {
106 QSettings setting(PENCIL2D, PENCIL2D);
107 setting.beginGroup("LastOpenPath");
108
109 return setting.value(toSettingKey(fileType), QDir::homePath()).toString();
110 }
111
setLastOpenPath(FileType fileType,const QString & openPath)112 void FileDialog::setLastOpenPath(FileType fileType, const QString& openPath)
113 {
114 QSettings setting(PENCIL2D, PENCIL2D);
115 setting.beginGroup("LastOpenPath");
116
117 setting.setValue(toSettingKey(fileType), QFileInfo(openPath).absolutePath());
118 }
119
getLastSavePath(FileType fileType)120 QString FileDialog::getLastSavePath(FileType fileType)
121 {
122 QSettings setting(PENCIL2D, PENCIL2D);
123 setting.beginGroup("LastSavePath");
124
125 return setting.value(toSettingKey(fileType),
126 QDir::homePath() + "/" + defaultFileName(fileType)).toString();
127 }
128
setLastSavePath(FileType fileType,const QString & savePath)129 void FileDialog::setLastSavePath(FileType fileType, const QString& savePath)
130 {
131 QSettings setting(PENCIL2D, PENCIL2D);
132 setting.beginGroup("LastSavePath");
133
134 setting.setValue(toSettingKey(fileType), savePath);
135 }
136
openDialogCaption(FileType fileType)137 QString FileDialog::openDialogCaption(FileType fileType)
138 {
139 switch (fileType)
140 {
141 case FileType::ANIMATION: return tr("Open animation");
142 case FileType::IMAGE: return tr("Import image");
143 case FileType::IMAGE_SEQUENCE: return tr("Import image sequence");
144 case FileType::GIF: return tr("Import Animated GIF");
145 case FileType::MOVIE: return tr("Import movie");
146 case FileType::SOUND: return tr("Import sound");
147 case FileType::PALETTE: return tr("Open palette");
148 }
149 return "";
150 }
151
saveDialogCaption(FileType fileType)152 QString FileDialog::saveDialogCaption(FileType fileType)
153 {
154 switch (fileType)
155 {
156 case FileType::ANIMATION: return tr("Save animation");
157 case FileType::IMAGE: return tr("Export image");
158 case FileType::IMAGE_SEQUENCE: return tr("Export image sequence");
159 case FileType::GIF: return tr("Export Animated GIF");
160 case FileType::MOVIE: return tr("Export movie");
161 case FileType::SOUND: return tr("Export sound");
162 case FileType::PALETTE: return tr("Export palette");
163 }
164 return "";
165 }
166
openFileFilters(FileType fileType)167 QString FileDialog::openFileFilters(FileType fileType)
168 {
169 switch (fileType)
170 {
171 case FileType::ANIMATION: return PFF_OPEN_PROJECT_EXT_FILTER;
172 case FileType::IMAGE: return PFF_IMAGE_FILTER;
173 case FileType::IMAGE_SEQUENCE: return PFF_IMAGE_SEQ_FILTER;
174 case FileType::GIF: return PFF_GIF_EXT_FILTER;
175 case FileType::MOVIE: return PFF_MOVIE_EXT;
176 case FileType::SOUND: return PFF_SOUND_EXT_FILTER;
177 case FileType::PALETTE: return PFF_PALETTE_EXT_FILTER;
178 }
179 return "";
180 }
181
saveFileFilters(FileType fileType)182 QString FileDialog::saveFileFilters(FileType fileType)
183 {
184 switch (fileType)
185 {
186 case FileType::ANIMATION: return PFF_SAVE_PROJECT_EXT_FILTER;
187 case FileType::IMAGE: return "";
188 case FileType::IMAGE_SEQUENCE: return "";
189 case FileType::GIF: return QString("%1 (*.gif)").arg(tr("Animated GIF"));
190 case FileType::MOVIE: return "MP4 (*.mp4);; AVI (*.avi);; WebM (*.webm);; APNG (*.apng)";
191 case FileType::SOUND: return "";
192 case FileType::PALETTE: return PFF_PALETTE_EXT_FILTER;
193 }
194 return "";
195 }
196
getFilterForFile(const QString & filters,QString filePath)197 QString FileDialog::getFilterForFile(const QString& filters, QString filePath)
198 {
199 if (!filePath.contains("."))
200 {
201 return QString();
202 }
203 QString fileExt = filePath.remove(0, filePath.lastIndexOf(".")).prepend("*");
204
205 QStringList filtersSplit = filters.split(";;");
206 for (const QString& filter : filtersSplit)
207 {
208 int start = filter.indexOf("(");
209 int end = filter.indexOf(")");
210 if (start < 0 || end < 0)
211 {
212 continue;
213 }
214 start++;
215 QStringList filterExts = filter.mid(start, end - start).split(" ");
216 if (filterExts.contains(fileExt))
217 {
218 return filter.trimmed();
219 }
220 }
221
222 return QString();
223 }
224
defaultFileName(FileType fileType)225 QString FileDialog::defaultFileName(FileType fileType)
226 {
227 switch (fileType)
228 {
229 case FileType::ANIMATION: return tr("MyAnimation.pclx");
230 case FileType::IMAGE:
231 case FileType::IMAGE_SEQUENCE: return tr("untitled.png");
232 case FileType::GIF: return tr("untitled.gif");
233 case FileType::MOVIE: return tr("untitled.mp4");
234 case FileType::SOUND: return tr("untitled.wav");
235 case FileType::PALETTE: return tr("untitled.xml");
236 }
237 return "";
238 }
239
toSettingKey(FileType fileType)240 QString FileDialog::toSettingKey(FileType fileType)
241 {
242 switch (fileType)
243 {
244 case FileType::ANIMATION: return "Animation";
245 case FileType::IMAGE: return "Image";
246 case FileType::IMAGE_SEQUENCE: return "ImageSequence";
247 case FileType::GIF: return "Animated GIF";
248 case FileType::MOVIE: return "Movie";
249 case FileType::SOUND: return "Sound";
250 case FileType::PALETTE: return "Palette";
251 }
252 return "";
253 }
254