All Classes Namespaces Functions Variables Enumerations Properties Pages
filedialog.cpp
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 
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 
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 
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 
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 
105 {
106  QSettings setting(PENCIL2D, PENCIL2D);
107  setting.beginGroup("LastOpenPath");
108 
109  return setting.value(toSettingKey(fileType), QDir::homePath()).toString();
110 }
111 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 }
static QString getLastSavePath(FileType fileType)
Retrieves the last used save path for a given file type.
Definition: filedialog.cpp:120
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
static void setLastSavePath(FileType fileType, const QString &savePath)
Saves the last used save path for a given file type.
Definition: filedialog.cpp:129
QString & remove(int position, int n)
QString homePath()
QString tr(const char *sourceText, const char *disambiguation, int n)
int lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const const
bool isNull() const const
void setValue(const QString &key, const QVariant &value)
static QStringList getOpenFileNames(QWidget *parent, FileType fileType, const QString &caption=QString())
Shows a file dialog which allows the user to select multiple files to open.
Definition: filedialog.cpp:46
bool isEmpty() const const
bool isEmpty() const const
QStringList split(const QString &sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
T & first()
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
static QString getLastOpenPath(FileType fileType)
Retrieves the last opened file of a given type.
Definition: filedialog.cpp:104
static QString getOpenFileName(QWidget *parent, FileType fileType, const QString &caption=QString())
Shows a file dialog which allows the user to select a file to open.
Definition: filedialog.cpp:27
QVariant value(const QString &key, const QVariant &defaultValue) const const
QString suffix() const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
static void setLastOpenPath(FileType fileType, const QString &openPath)
Saves the last opened file of a given type.
Definition: filedialog.cpp:112
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
static QString getSaveFileName(QWidget *parent, FileType fileType, const QString &caption=QString())
Shows a file dialog which allows the user to select a file save path.
Definition: filedialog.cpp:65
QString toString() const const
void beginGroup(const QString &prefix)
QStringList getOpenFileNames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)