File: main.cpp

package info (click to toggle)
mystiq 20.03.23-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,520 kB
  • sloc: cpp: 8,240; xml: 764; sh: 99; makefile: 8
file content (210 lines) | stat: -rw-r--r-- 7,278 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/*  MystiQ - a C++/Qt5 gui frontend for ffmpeg
 *  Copyright (C) 2011-2019 Maikel Llamaret Heredia <llamaret@webmisolutions.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <QApplication>
#include <QDebug>
#include <QLocale>
#include <QTranslator>
#include <QDir>
#include <QSettings>
#include <QMessageBox>
#include "ui/mainwindow.h"
#include "services/paths.h"
#include "converter/ffmpeginterface.h"
#include "converter/mediaprobe.h"
#include "converter/exepath.h"
#include "services/notification.h"
#include "services/constants.h"

/**
 * @brief Find  the absolute path of the translation of the current locale.
 *
 * @return the absolute path of the translation or an empty string if file not found.
 * @note This function must be called after @c Paths has been initialized.
 */
static QString find_translation_file()
{
    QString locale = QLocale::system().name(); // language code + country code (xx_XX)
    QString language = locale.mid(0, 2); // language code (first two chars of locale)
    QString translation_file_basename =
            //QDir(Paths::translationPath()).absoluteFilePath("mystiq_");
            QDir(":/translations/").absoluteFilePath("mystiq_");

    // look for mystiq_xx_XX.qm in the translation directory
    QString translation_language_country = translation_file_basename + locale + ".qm";
    if (QFile(translation_language_country).exists())
        return translation_language_country;

    // look for mystiq_xx.qm in the translation directory
    QString translation_language = translation_file_basename + language + ".qm";
    if (QFile(translation_language).exists())
        return translation_language;

    // translation for current locale not found, return empty string
    return "";
}

/**
 * @brief Load program constants from constants.xml.
 * @return true on success, false on failure
 */
static bool load_constants(QApplication& app)
{
#ifdef DATA_PATH
    QString app_path = QString(DATA_PATH);
    (void)app; // eliminate "variable not used" warning
#else
    QString app_path = app.applicationDirPath();
#endif
    QString constant_xml_filename = ":/other/constants.xml";

    // open constant xml file
    QFile constant_xml(constant_xml_filename);
    constant_xml.open(QIODevice::ReadOnly);
    if (!constant_xml.isOpen()) {
        qCritical() << "Failed to read file: " << constant_xml_filename;
        QMessageBox::critical(nullptr, "MystiQ",
                              QString("Cannot load %1. The program will exit now.")
                              .arg(constant_xml_filename));
        return false;
    }

    qDebug() << "Reading file: " << constant_xml_filename;
    // parse the xml file
    if (!Constants::readFile(constant_xml)) {
        QMessageBox::critical(nullptr, "MystiQ",
                              QString("%1 contains error(s). "
                                      "Reinstall the application may solve the problem.")
                              .arg(constant_xml_filename));
        return false;
    }

    return true;
}

// register an external tool for use
// returns whether the tool can be successfully invoked
static bool register_tool(const char *id, const char *name)
{
    QString exefile = name; // default: use the program in PATH
#ifdef TOOLS_IN_DATA_PATH // Search external tools in <datapath>/tools
#ifdef Q_OS_WIN32 // executable files must end with .exe on MS Windows
    exefile = Paths::dataFileName("tools/%1.exe").arg(name);
#else
    exefile = Paths::dataFileName("tools/%1").arg(name);
#endif // Q_OS_WIN32
#ifdef Q_OS_MACOS // executable files must end without extension on MacOS
    exefile = Paths::dataFileName("tools/%1").arg(name);
#endif // Q_OS_MACOS
#endif // TOOLS_IN_DATA_PATH
    ExePath::setPath(id, exefile);
    if (ExePath::checkProgramAvailability(id))
        return true;
    // failed to invoke the program
    ExePath::setPath(id, ""); // unset the tool
    return false;
}

static bool register_tool(const char *name)
{
    return register_tool(name, name);
}

static void register_external_tools()
{
    // load user settings for the tools
    ExePath::loadSettings();
    // If the setting of ffmpeg is not available, register it again.
    // If "ffmpeg" doesn't exist on the system, try "avconv" instead.
    ExePath::checkProgramAvailability("ffmpeg")
            || register_tool("ffmpeg")
            || register_tool("ffmpeg", "avconv");
    // same as "ffmpeg" (try "avprobe" if "ffprobe" not available)
    ExePath::checkProgramAvailability("ffprobe")
            || register_tool("ffprobe")
            || register_tool("ffprobe", "avprobe");
    // same as above
    // these tools have no alternative names
    register_tool("sox");
}

int main(int argc, char *argv[])
{
    // Create Application.
    QApplication app(argc, argv);

    if (!load_constants(app)) {
        app.exec();
        return EXIT_FAILURE;
    }

    // Register QSettings information.
    app.setOrganizationName("mystiq");
    QSettings::setDefaultFormat(QSettings::IniFormat);
    if (Constants::getBool("Portable")) {
        // Portable App: Save settings in <exepath>/mystiq.ini.
        QSettings::setPath(QSettings::IniFormat, QSettings::UserScope
                           , app.applicationDirPath());
    } else {
        // Save settings to the default Qt location
    }
    qDebug() << "Settings filename: " + QSettings().fileName();

    Paths::setAppPath(app.applicationDirPath());

    register_external_tools();

    // Construct a string list containing all input filenames.
    QStringList inputFiles(app.arguments());
    inputFiles.removeFirst(); // Exclude self executable name.

    // Setup translation
    QTranslator translator;
    QString translation_filename = find_translation_file();
    if (!translation_filename.isEmpty()) {
        qDebug() << "Translation file: " << translation_filename;
        translator.load(translation_filename);
        app.installTranslator(&translator);
    }

    // Load translation for Qt library
    QTranslator translator_qt;
    translator_qt.load("qt_" + QLocale::system().name(), Paths::qtTranslationPath());
    app.installTranslator(&translator_qt);

    // Setup notification
    Notification::init();
    if (!Notification::setType(Notification::TYPE_LIBNOTIFY))
        Notification::setType(Notification::TYPE_NOTIFYSEND);

    // Create main window.
    MainWindow window(nullptr, inputFiles);
    window.show();

    // Execute the main loop
    int status = app.exec();

    // Tear down notification
    Notification::release();

#ifndef TOOLS_IN_DATA_PATH
    // Save path settings
    ExePath::saveSettings();
#endif

    return status;
}