leocad/qt/qtmain.cpp

231 lines
6.9 KiB
C++
Raw Normal View History

2013-08-09 06:57:18 +02:00
#include "lc_global.h"
#include "lc_application.h"
2013-08-12 02:26:52 +02:00
#include "lc_qupdatedialog.h"
2019-11-28 22:52:06 +01:00
#include "lc_profile.h"
2021-07-06 02:00:41 +02:00
#include "pieceinf.h"
2013-08-09 06:57:18 +02:00
#include <QApplication>
2017-01-24 07:20:43 +01:00
#include <locale.h>
2013-08-09 06:57:18 +02:00
#ifdef Q_OS_WIN
2016-03-06 21:19:02 +01:00
#pragma warning(push)
#pragma warning(disable : 4091)
2013-08-13 06:54:12 +02:00
#include <dbghelp.h>
#include <direct.h>
#include <shlobj.h>
2016-03-06 21:19:02 +01:00
#pragma warning(pop)
2013-08-13 06:54:12 +02:00
#ifdef UNICODE
#ifndef _UNICODE
#define _UNICODE
#endif
#endif
#include <tchar.h>
static TCHAR gMinidumpPath[_MAX_PATH];
2013-08-13 06:54:12 +02:00
static LONG WINAPI lcSehHandler(PEXCEPTION_POINTERS exceptionPointers)
{
if (IsDebuggerPresent())
return EXCEPTION_CONTINUE_SEARCH;
HMODULE dbgHelp = LoadLibrary(TEXT("dbghelp.dll"));
if (dbgHelp == nullptr)
2013-08-13 06:54:12 +02:00
return EXCEPTION_EXECUTE_HANDLER;
HANDLE file = CreateFile(gMinidumpPath, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
2013-08-13 06:54:12 +02:00
if (file == INVALID_HANDLE_VALUE)
return EXCEPTION_EXECUTE_HANDLER;
typedef BOOL (WINAPI *LPMINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE DumpType, CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, CONST PMINIDUMP_USER_STREAM_INFORMATION UserEncoderParam, CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
LPMINIDUMPWRITEDUMP miniDumpWriteDump = (LPMINIDUMPWRITEDUMP)GetProcAddress(dbgHelp, "MiniDumpWriteDump");
if (!miniDumpWriteDump)
return EXCEPTION_EXECUTE_HANDLER;
MINIDUMP_EXCEPTION_INFORMATION mei;
mei.ThreadId = GetCurrentThreadId();
mei.ExceptionPointers = exceptionPointers;
mei.ClientPointers = TRUE;
BOOL writeDump = miniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), file, MiniDumpNormal, exceptionPointers ? &mei : nullptr, nullptr, nullptr);
2013-08-13 06:54:12 +02:00
CloseHandle(file);
FreeLibrary(dbgHelp);
if (writeDump)
{
TCHAR message[_MAX_PATH + 256];
lstrcpy(message, TEXT("LeoCAD just crashed. Crash information was saved to the file '"));
lstrcat(message, gMinidumpPath);
2013-08-13 06:54:12 +02:00
lstrcat(message, TEXT("', please send it to the developers for debugging."));
MessageBox(nullptr, message, TEXT("LeoCAD"), MB_OK);
2013-08-13 06:54:12 +02:00
}
return EXCEPTION_EXECUTE_HANDLER;
}
static void lcSehInit()
{
2019-12-09 20:47:43 +01:00
if (GetTempPath(LC_ARRAY_COUNT(gMinidumpPath), gMinidumpPath))
lstrcat(gMinidumpPath, TEXT("leocad.dmp"));
2013-08-13 06:54:12 +02:00
SetUnhandledExceptionFilter(lcSehHandler);
}
static void lcRegisterShellFileTypes()
{
TCHAR modulePath[_MAX_PATH], longModulePath[_MAX_PATH];
TCHAR temp[2*_MAX_PATH];
GetModuleFileName(nullptr, longModulePath, _MAX_PATH);
if (GetShortPathName(longModulePath, modulePath, _MAX_PATH) == 0)
lstrcpy(modulePath, longModulePath);
if (RegSetValue(HKEY_CLASSES_ROOT, TEXT("LeoCAD.Project"), REG_SZ, TEXT("LeoCAD Project"), lstrlen(TEXT("LeoCAD Project")) * sizeof(TCHAR)) != ERROR_SUCCESS)
return;
lstrcpy(temp, modulePath);
lstrcat(temp, TEXT(",0"));
if (RegSetValue(HKEY_CLASSES_ROOT, TEXT("LeoCAD.Project\\DefaultIcon"), REG_SZ, temp, lstrlen(temp) * sizeof(TCHAR)) != ERROR_SUCCESS)
return;
lstrcpy(temp, modulePath);
lstrcat(temp, TEXT(" \"%1\""));
if (RegSetValue(HKEY_CLASSES_ROOT, TEXT("LeoCAD.Project\\shell\\open\\command"), REG_SZ, temp, lstrlen(temp) * sizeof(TCHAR)) != ERROR_SUCCESS)
return;
LONG size = 2 * _MAX_PATH;
LONG result = RegQueryValue(HKEY_CLASSES_ROOT, TEXT(".lcd"), temp, &size);
if (result != ERROR_SUCCESS || !lstrlen(temp) || lstrcmp(temp, TEXT("LeoCAD.Project")))
{
if (RegSetValue(HKEY_CLASSES_ROOT, TEXT(".lcd"), REG_SZ, TEXT("LeoCAD.Project"), lstrlen(TEXT("LeoCAD.Project")) * sizeof(TCHAR)) != ERROR_SUCCESS)
return;
HKEY key;
DWORD disposition = 0;
if (RegCreateKeyEx(HKEY_CLASSES_ROOT, TEXT(".lcd\\ShellNew"), 0, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_READ, nullptr, &key, &disposition) != ERROR_SUCCESS)
return;
2017-04-03 02:15:09 +02:00
result = RegSetValueEx(key, TEXT("NullFile"), 0, REG_SZ, (CONST BYTE*)TEXT(""), (lstrlen(TEXT("")) + 1) * sizeof(TCHAR));
if (RegCloseKey(key) != ERROR_SUCCESS || result != ERROR_SUCCESS)
return;
}
}
#endif
static void lcInitializeSurfaceFormat(int argc, char* argv[])
{
QCoreApplication Application(argc, argv);
const lcCommandLineOptions Options = lcApplication::ParseCommandLineOptions();
2021-01-11 02:45:28 +01:00
if (Options.ParseOK && Options.AASamples > 1)
{
QSurfaceFormat Format = QSurfaceFormat::defaultFormat();
2021-01-11 02:45:28 +01:00
Format.setSamples(Options.AASamples);
QSurfaceFormat::setDefaultFormat(Format);
}
}
2013-08-09 06:57:18 +02:00
int main(int argc, char *argv[])
{
QCoreApplication::setOrganizationDomain(QLatin1String("leocad.org"));
QCoreApplication::setOrganizationName(QLatin1String("LeoCAD Software"));
QCoreApplication::setApplicationName(QLatin1String("LeoCAD"));
QCoreApplication::setApplicationVersion(QLatin1String(LC_VERSION_TEXT));
lcInitializeSurfaceFormat(argc, argv);
2020-12-27 22:05:55 +01:00
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
lcApplication Application(argc, argv);
2013-08-09 06:57:18 +02:00
2019-11-28 22:52:06 +01:00
QString Language = lcGetProfileString(LC_PROFILE_LANGUAGE);
QLocale Locale;
if (!Language.isEmpty())
Locale = QLocale(Language);
QTranslator QtTranslator;
2019-11-28 22:52:06 +01:00
if (QtTranslator.load(Locale, "qt", "_", QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
Application.installTranslator(&QtTranslator);
#ifdef Q_OS_WIN
2019-11-28 22:52:06 +01:00
else if (QtTranslator.load(Locale, "qt", "_", qApp->applicationDirPath() + "/translations"))
Application.installTranslator(&QtTranslator);
#endif
QTranslator QtBaseTranslator;
2019-11-28 22:52:06 +01:00
if (QtBaseTranslator.load("qtbase_" + Locale.name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
Application.installTranslator(&QtBaseTranslator);
#ifdef Q_OS_WIN
2019-11-28 22:52:06 +01:00
else if (QtBaseTranslator.load("qtbase_" + Locale.name(), qApp->applicationDirPath() + "/translations"))
Application.installTranslator(&QtBaseTranslator);
#endif
2014-09-16 01:41:46 +02:00
QTranslator Translator;
2019-11-28 22:52:06 +01:00
if (Translator.load("leocad_" + Locale.name(), ":/resources"))
Application.installTranslator(&Translator);
2014-09-16 01:41:46 +02:00
2021-07-06 02:00:41 +02:00
qRegisterMetaType<PieceInfo*>("PieceInfo*");
qRegisterMetaType<QList<int> >("QList<int>");
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
2017-02-06 23:20:09 +01:00
qRegisterMetaTypeStreamOperators<QList<int> >("QList<int>");
2021-07-06 02:00:41 +02:00
#endif
qRegisterMetaType<lcVector3>("lcVector3");
QMetaType::registerComparators<lcVector3>();
2017-02-06 23:20:09 +01:00
2017-08-29 04:13:17 +02:00
QList<QPair<QString, bool>> LibraryPaths;
2013-08-09 06:57:18 +02:00
2017-08-29 04:13:17 +02:00
#ifdef Q_OS_WIN
lcRegisterShellFileTypes();
2013-08-13 06:54:12 +02:00
lcSehInit();
2017-08-29 04:13:17 +02:00
LibraryPaths += qMakePair(QDir::cleanPath(QCoreApplication::applicationDirPath() + "/library.bin"), true);
#endif
#ifdef Q_OS_LINUX
LibraryPaths += qMakePair(QDir::cleanPath(QCoreApplication::applicationDirPath() + "/../share/leocad/library.bin"), true);
#endif
#ifdef Q_OS_MAC
LibraryPaths += qMakePair(QDir::cleanPath(QCoreApplication::applicationDirPath() + "/../../Contents/Resources/library.bin"), true);
#endif
#ifdef LC_LDRAW_LIBRARY_PATH
2017-08-29 05:00:48 +02:00
LibraryPaths += qMakePair(QString::fromLatin1(LC_LDRAW_LIBRARY_PATH), false);
2013-08-09 06:57:18 +02:00
#endif
2017-01-24 05:46:52 +01:00
setlocale(LC_NUMERIC, "C");
2013-08-09 06:57:18 +02:00
2020-12-31 03:22:02 +01:00
lcStartupMode StartupMode = Application.Initialize(LibraryPaths);
if (StartupMode == lcStartupMode::Error)
{
Application.Shutdown();
2013-08-09 06:57:18 +02:00
return 1;
}
2013-08-09 06:57:18 +02:00
int ExecReturn = 0;
2020-12-31 03:22:02 +01:00
if (StartupMode == lcStartupMode::ShowWindow)
{
#if !LC_DISABLE_UPDATE_CHECK
lcDoInitialUpdateCheck();
#endif
2013-08-12 02:26:52 +02:00
ExecReturn = Application.exec();
}
2013-08-09 06:57:18 +02:00
2021-01-02 19:23:51 +01:00
Application.Shutdown();
2013-08-09 06:57:18 +02:00
return ExecReturn;
2013-08-09 06:57:18 +02:00
}