main.cpp 9.78 KB
Newer Older
1
/***************************************************************************
2
 * Copyright (C) 2015-2019 by Savoir-faire Linux                           *
3
 * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>*
4
 * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>          *
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
 *                                                                         *
 * 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 "mainwindow.h"
21

22
#include "accountmigrationdialog.h"
23
#include "globalinstances.h"
24
#include "networkmanager.h"
25 26 27 28 29
#include "lrcinstance.h"
#include "pixbufmanipulator.h"
#include "runguard.h"
#include "utils.h"
#include "splashscreen.h"
30
#include "aboutdialog.h"
31

32 33
#include <QApplication>
#include <QFile>
34
#include <QMessageBox>
35
#include <QFontDatabase>
36 37
#include <QLibraryInfo>
#include <QTranslator>
38

39
#include <ciso646>
40
#include <locale.h>
41

42
#ifdef Q_OS_WIN
43
#include <windows.h>
44
#endif
45

46
#if defined _MSC_VER && !COMPILE_ONLY
47 48 49
#include <gnutls/gnutls.h>
#endif

50
void
51
consoleDebug()
52
{
53
#ifdef Q_OS_WIN
54
    AllocConsole();
55 56
    SetConsoleCP(CP_UTF8);

57 58 59 60 61 62 63 64
    freopen("CONOUT$", "w", stdout);
    freopen("CONOUT$", "w", stderr);

    COORD coordInfo;
    coordInfo.X = 130;
    coordInfo.Y = 9000;

    SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coordInfo);
65
    SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS);
66
#endif
67 68 69 70 71 72 73 74 75 76 77 78 79 80
}

#ifdef _MSC_VER
void
vsConsoleDebug()
{
    // Print debug to output window if using VS
    QObject::connect(
        &LRCInstance::behaviorController(),
        &lrc::api::BehaviorController::debugMessageReceived,
        [](const std::string& message) {
            OutputDebugStringA((message + "\n").c_str());
        });
}
81
#endif
82 83 84 85 86 87 88 89 90 91 92 93 94 95

void
fileDebug(QFile& debugFile)
{
    QObject::connect(
        &LRCInstance::behaviorController(),
        &lrc::api::BehaviorController::debugMessageReceived,
        [&debugFile](const std::string& message) {
            if (debugFile.open(QIODevice::WriteOnly | QIODevice::Append)) {
                auto msg = (message + "\n").c_str();
                debugFile.write(msg, qstrlen(msg));
                debugFile.close();
            }
        });
96 97
}

98 99 100 101 102 103 104
void
exitApp(RunGuard& guard)
{
    GlobalSystemTray::instance().hide();
    guard.release();
}

105
int
106
main(int argc, char* argv[])
107
{
108 109
    setlocale(LC_ALL, "en_US.utf8");

110 111 112 113 114 115 116 117 118
    char ARG_DISABLE_WEB_SECURITY[] = "--disable-web-security";
    int newArgc = argc + 1 + 1;
    char** newArgv = new char*[newArgc];
    for (int i = 0; i < argc; i++) {
        newArgv[i] = argv[i];
    }
    newArgv[argc] = ARG_DISABLE_WEB_SECURITY;
    newArgv[argc + 1] = nullptr;

119
#if defined(Q_OS_WIN) && (PROCESS_DPI_AWARE)
120 121 122
    SetProcessDPIAware();
#endif // Q_OS_WIN

123
    QApplication a(newArgc, newArgv);
124

125 126 127 128 129 130 131 132 133 134 135
    QCoreApplication::setApplicationName("Ring");
    QCoreApplication::setOrganizationDomain("jami.net");

    QCryptographicHash appData(QCryptographicHash::Sha256);
    appData.addData(QApplication::applicationName().toUtf8());
    appData.addData(QApplication::organizationDomain().toUtf8());
    RunGuard guard(appData.result());
    if (!guard.tryToRun()) {
        return 0;
    }

136 137 138 139 140 141
    for (auto string : QCoreApplication::arguments()) {
        if (string == "-d" || string == "--debug") {
            consoleDebug();
        }
    }

142 143
    Utils::removeOldVersions();

144 145 146
    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling, false);
    QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);

147
    auto startMinimized = false;
148
    QString uri = "";
149

150
    auto appDir = qApp->applicationDirPath() + "/";
151 152 153 154 155 156
    const auto locale_name = QLocale::system().name();
    const auto locale_lang = locale_name.split('_')[0];

    QTranslator qtTranslator_lang;
    QTranslator qtTranslator_name;
    if (locale_name != locale_lang) {
157 158
        if (qtTranslator_lang.load("qt_" + locale_lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
            a.installTranslator(&qtTranslator_lang);
159 160 161 162 163 164 165
    }
    qtTranslator_name.load("qt_" + locale_name, QLibraryInfo::location(QLibraryInfo::TranslationsPath));
    a.installTranslator(&qtTranslator_name);

    QTranslator lrcTranslator_lang;
    QTranslator lrcTranslator_name;
    if (locale_name != locale_lang) {
166 167
        if (lrcTranslator_lang.load(appDir + "share/libringclient/translations/lrc_" + locale_lang))
            a.installTranslator(&lrcTranslator_lang);
168
    }
169 170
    if (lrcTranslator_name.load(appDir + "share/libringclient/translations/lrc_" + locale_name))
        a.installTranslator(&lrcTranslator_name);
171 172 173 174

    QTranslator mainTranslator_lang;
    QTranslator mainTranslator_name;
    if (locale_name != locale_lang) {
175 176
        if (mainTranslator_lang.load(appDir + "share/ring/translations/ring_client_windows_" + locale_lang))
            a.installTranslator(&mainTranslator_lang);
177
    }
178 179
    if (mainTranslator_name.load(appDir + "share/ring/translations/ring_client_windows_" + locale_name))
        a.installTranslator(&mainTranslator_name);
180

181 182 183 184
    QFont font;
    font.setFamily("Segoe UI");
    a.setFont(font);

Andreas Traczyk's avatar
Andreas Traczyk committed
185
#ifndef DEBUG_STYLESHEET
186
    QFile file(":/stylesheet.css");
187
    if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
188 189 190
        a.setStyleSheet(file.readAll());
        file.close();
    }
Andreas Traczyk's avatar
Andreas Traczyk committed
191
#endif
192

193 194 195 196 197 198 199
#if defined _MSC_VER && !COMPILE_ONLY
    gnutls_global_init();
#endif

    GlobalInstances::setPixmapManipulator(std::make_unique<PixbufManipulator>());

    SplashScreen* splash = new SplashScreen();
200
    std::atomic_bool isMigrating(false);
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
    LRCInstance::init(
        [&splash, &a, &isMigrating] {
            splash->setupUI(
                QPixmap(":/images/logo-jami-standard-coul.png"),
                QString("Jami - ") + QObject::tr("Migration needed"),
                QObject::tr("Migration in progress... This may take a while."),
                QColor(232, 232, 232)
            );
            splash->show();
            isMigrating = true;
            while (isMigrating) {
                a.processEvents();
            }
        },
        [&splash, &isMigrating] {
            while (!isMigrating) {
                std::this_thread::sleep_for(std::chrono::milliseconds(10));
            }
            isMigrating = false;
        });
    splash->hide();
    LRCInstance::subscribeToDebugReceived();
223
    LRCInstance::getAPI().holdConferences = false;
224

225 226 227 228 229
    QDir logPath(QStandardPaths::writableLocation(
        QStandardPaths::AppLocalDataLocation));
    // since logPath will be .../Ring, we use cdUp to remove it.
    logPath.cdUp();
    QFile debugFile(logPath.absolutePath() + "/jami/jami.log");
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254

    for (auto string : QCoreApplication::arguments()) {
        if (string.startsWith("jami:")) {
            uri = string;
        } else {
            if (string == "-m" || string == "--minimized") {
                startMinimized = true;
            }
            auto dbgFile = string == "-f" || string == "--file";
            auto dbgConsole = string == "-c" || string == "--vsconsole";
            if (dbgFile || dbgConsole) {
                if (dbgFile) {
                    debugFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
                    debugFile.close();
                    fileDebug(debugFile);
                }
#ifdef _MSC_VER
                if (dbgConsole) {
                    vsConsoleDebug();
                }
#endif
            }
        }
    }

255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
    auto accountList = LRCInstance::accountModel().getAccountList();

    for (const std::string& i : accountList) {
        auto accountStatus = LRCInstance::accountModel().getAccountInfo(i).status;
        if (accountStatus == lrc::api::account::Status::ERROR_NEED_MIGRATION) {
            std::unique_ptr<AccountMigrationDialog> dialog = std::make_unique<AccountMigrationDialog>(nullptr, i);
            int status = dialog->exec();

            //migration failed
            if (!status) {
#ifdef Q_OS_WIN
                FreeConsole();
#endif
                exitApp(guard);
                return status;
            }
        }
    }

    splash->finish(&MainWindow::instance());
    splash->deleteLater();

277 278
    QFontDatabase::addApplicationFont(":/images/FontAwesome.otf");

279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
    QSettings settings("jami.net", "Jami");
    if (not startMinimized) {
        if (settings.value(SettingsKey::hasRun) == 0) {
            MainWindow::instance().showMaximized();
            QTimer::singleShot(100,
                [] {
                    QSettings settings("jami.net", "Jami");
                    settings.setValue(SettingsKey::hasRun, 1);
                    auto aboutDialog = std::make_unique<AboutDialog>(&MainWindow::instance());
                    aboutDialog->getContainer()->exec();
                });
        } else {
            MainWindow::instance().showWindow();
        }
    } else {
294
        MainWindow::instance().showMinimized();
295 296
        MainWindow::instance().hide();
    }
297

298
    QObject::connect(&a, &QApplication::aboutToQuit, [&guard] { exitApp(guard); });
299

300 301
    auto ret = a.exec();

302
#ifdef Q_OS_WIN
303
    FreeConsole();
304
#endif
305

306
    return ret;
307
}