All Classes Namespaces Functions Variables Enumerations Properties Pages
pencil2d.cpp
1 
2 /*
3 
4 Pencil2D - Traditional Animation Software
5 Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon
6 Copyright (C) 2012-2020 Matthew Chiawen Chang
7 
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; version 2 of the License.
11 
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 
17 */
18 #include "pencil2d.h"
19 
20 #include <memory>
21 
22 #include <QDebug>
23 #include <QFileOpenEvent>
24 #include <QIcon>
25 #include <QLibraryInfo>
26 #include <QSettings>
27 #include <QTranslator>
28 #include <QLockFile>
29 #include <QStandardPaths>
30 #include <QDir>
31 #include <QMessageBox>
32 
33 #include "commandlineexporter.h"
34 #include "commandlineparser.h"
35 #include "mainwindow2.h"
36 #include "pencildef.h"
37 #include "platformhandler.h"
38 
39 
40 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
41 #include <clocale>
42 #endif
43 
44 Pencil2D::Pencil2D(int& argc, char** argv) :
45  QApplication(argc, argv)
46 {
47  // Set organization and application name
48  setOrganizationName("Pencil2D");
49  setOrganizationDomain("pencil2d.org");
50  setApplicationName("Pencil2D");
51  setApplicationDisplayName("Pencil2D");
52 
53  // Set application version
54  setApplicationVersion(APP_VERSION);
55 
56  // Set application icon
57  setWindowIcon(QIcon(":/icons/icon.png"));
58 
59 #if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
60  // Associate the application with our desktop entry
61  setDesktopFileName("org.pencil2d.Pencil2D.desktop");
62 #endif
64 }
65 
66 Pencil2D::~Pencil2D()
67 {
68  // with a std::unique_ptr member variable,
69  // you need a non-default destructor to avoid compilation error.
70 }
71 
73 {
74  CommandLineParser parser;
75  parser.process(arguments());
76 
77 #ifndef QT_DEBUG
78  if (isInstanceOpen()) {
79  return Status::SAFE;
80  }
81 #endif
82 
83  QString inputPath = parser.inputPath();
84  QStringList outputPaths = parser.outputPaths();
85 
86  if (outputPaths.isEmpty())
87  {
88  prepareGuiStartup(inputPath);
89  return Status::OK;
90  }
91 
92  // Can't construct the editor directly, need to make a main window instead because... reasons
93  mainWindow.reset(new MainWindow2);
94  CommandLineExporter exporter(mainWindow->mEditor);
95  if (exporter.process(inputPath,
96  outputPaths,
97  parser.camera(),
98  parser.width(),
99  parser.height(),
100  parser.startFrame(),
101  parser.endFrame(),
102  parser.transparency()))
103  {
104  return Status::SAFE;
105  }
106  return Status::FAIL;
107 }
108 
110 {
112  appDir.mkpath(".");
113  mProcessLock.reset(new QLockFile(appDir.absoluteFilePath("pencil2d-process.lock")));
114  if (!mProcessLock->tryLock(10))
115  {
116  QMessageBox::StandardButton clickedButton = QMessageBox::warning(nullptr, tr("Warning"), tr("An instance of Pencil2D is already open. Running multiple instances of Pencil2D simultaneously is not recommended and could potentially result in data loss and other unexpected behavior."), QMessageBox::Close | QMessageBox::Open, QMessageBox::Close);
117  if (clickedButton != QMessageBox::Open)
118  {
119  return true;
120  }
121  }
122  return false;
123 }
124 
125 bool Pencil2D::event(QEvent* event)
126 {
127  if (event->type() == QEvent::FileOpen)
128  {
129  auto fileOpenEvent = dynamic_cast<QFileOpenEvent*>(event);
130  Q_ASSERT(fileOpenEvent);
131  emit openFileRequested(fileOpenEvent->file());
132  return true;
133  }
134  return QApplication::event(event);
135 }
136 
138 {
139  QSettings setting(PENCIL2D, PENCIL2D);
140  QString userLocale = setting.value(SETTING_LANGUAGE).toString();
141  QLocale locale = userLocale.isEmpty() ? QLocale::system() : QLocale(userLocale);
142  QLocale::setDefault(locale);
143 
144 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
145  // In versions prior to 5.14, Qt's DOM implementation erroneously used
146  // locale-dependent string conversion for double attributes (QTBUG-80068).
147  // To work around this, we override the numeric locale category to use the
148  // C locale.
149  std::setlocale(LC_NUMERIC, "C");
150 #endif
151 
152  std::unique_ptr<QTranslator> qtTranslator(new QTranslator(this));
153  if (qtTranslator->load(locale, "qt", "_", QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
154  {
155  installTranslator(qtTranslator.release());
156  }
157 
158  std::unique_ptr<QTranslator> pencil2DTranslator(new QTranslator(this));
159  if (pencil2DTranslator->load(locale, "pencil", "_", ":/i18n/"))
160  {
161  installTranslator(pencil2DTranslator.release());
162  }
163 }
164 
165 void Pencil2D::prepareGuiStartup(const QString& inputPath)
166 {
167  PlatformHandler::configurePlatformSpecificSettings();
168 
169  mainWindow.reset(new MainWindow2);
170  connect(this, &Pencil2D::openFileRequested, mainWindow.get(), &MainWindow2::openFile);
171  mainWindow->show();
172 
173  mainWindow->openStartupFile(inputPath);
174 }
Status handleCommandLineOptions()
Parses supplied command line arguments and performs the appropriate actions, such as running the comm...
Definition: pencil2d.cpp:72
QEvent::Type type() const const
QString writableLocation(QStandardPaths::StandardLocation type)
Pencil2D(int &argc, char **argv)
Initializes the application with the given command line arguments.
Definition: pencil2d.cpp:44
void openFileRequested(QString filename)
Emitted when the operating system requests that a file should be opened.
Handles command line export jobs.
QString filePath(const QString &fileName) const const
void setOrganizationDomain(const QString &orgDomain)
QString tr(const char *sourceText, const char *disambiguation, int n)
QLocale system()
void setDesktopFileName(const QString &name)
void setApplicationVersion(const QString &version)
void setDefault(const QLocale &locale)
bool isEmpty() const const
bool isEmpty() const const
void prepareGuiStartup(const QString &inputPath)
Readies the graphical UI for entering the main loop.
Definition: pencil2d.cpp:165
bool installTranslator(QTranslator *translationFile)
QVariant value(const QString &key, const QVariant &defaultValue) const const
void installTranslators()
Sets up translators for the application locale configured by the user or the system locale...
Definition: pencil2d.cpp:137
virtual bool event(QEvent *e) override
void setWindowIcon(const QIcon &icon)
bool process(const QString &inputPath, const QStringList &outputPaths, const QString &camera, int width, int height, int startFrame, int endFrame, bool transparency)
Exports a Pencil2D file according to the specified options.
QString absoluteFilePath(const QString &fileName) const const
bool isInstanceOpen()
Checks if multiple instances of Pencil2D are open.
Definition: pencil2d.cpp:109
QMessageBox::StandardButton warning(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
QStringList arguments()
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QString location(QLibraryInfo::LibraryLocation loc)
void setOrganizationName(const QString &orgName)
QString toString() const const
void setApplicationDisplayName(const QString &name)
bool mkpath(const QString &dirPath) const const
void setApplicationName(const QString &application)