tahoma2d/toonz/sources/toonz/main.cpp

826 lines
27 KiB
C++
Raw Normal View History

2020-07-13 17:07:54 +12:00
// Soli Deo gloria
2016-03-19 06:57:51 +13:00
// Tnz6 includes
#include "mainwindow.h"
#include "flipbook.h"
#include "tapp.h"
#include "iocommand.h"
#include "previewfxmanager.h"
2020-05-27 18:38:36 +12:00
#include "cleanupsettingspopup.h"
2016-03-19 06:57:51 +13:00
#include "filebrowsermodel.h"
// TnzTools includes
#include "tools/tool.h"
#include "tools/toolcommandids.h"
// TnzQt includes
#include "toonzqt/dvdialog.h"
#include "toonzqt/menubarcommand.h"
#include "toonzqt/tmessageviewer.h"
#include "toonzqt/icongenerator.h"
#include "toonzqt/gutil.h"
#include "toonzqt/pluginloader.h"
// TnzStdfx includes
#include "stdfx/shaderfx.h"
// TnzLib includes
#include "toonz/preferences.h"
#include "toonz/toonzfolders.h"
#include "toonz/tproject.h"
#include "toonz/studiopalette.h"
#include "toonz/stylemanager.h"
#include "toonz/tscenehandle.h"
#include "toonz/txshsimplelevel.h"
#include "toonz/tproject.h"
#include "toonz/scriptengine.h"
2016-03-19 06:57:51 +13:00
// TnzSound includes
#include "tnzsound.h"
// TnzImage includes
#include "tnzimage.h"
// TnzBase includes
#include "permissionsmanager.h"
#include "tenv.h"
#include "tcli.h"
// TnzCore includes
#include "tsystem.h"
#include "tthread.h"
#include "tthreadmessage.h"
#include "tundo.h"
#include "tconvert.h"
#include "tiio_std.h"
#include "timagecache.h"
#include "tofflinegl.h"
#include "tpluginmanager.h"
#include "tsimplecolorstyles.h"
#include "toonz/imagestyles.h"
#include "tvectorbrushstyle.h"
#include "tfont.h"
2016-03-19 06:57:51 +13:00
#include "kis_tablet_support_win8.h"
2016-03-19 06:57:51 +13:00
#ifdef MACOSX
#include "tipc.h"
#endif
// Qt includes
#include <QApplication>
#include <QAbstractEventDispatcher>
#include <QAbstractNativeEventFilter>
2016-03-19 06:57:51 +13:00
#include <QSplashScreen>
#include <QGLPixelBuffer>
#include <QTranslator>
#include <QFileInfo>
#include <QSettings>
#include <QLibraryInfo>
#include <QHash>
#include <QPainterPath>
2016-03-19 06:57:51 +13:00
2019-10-08 12:01:20 +13:00
#ifdef _WIN32
2017-05-31 07:56:39 +12:00
#ifndef x64
#include <float.h>
#endif
2019-10-08 12:01:20 +13:00
#include <QtPlatformHeaders/QWindowsWindowFunctions>
#endif
2016-03-19 06:57:51 +13:00
using namespace DVGui;
TEnv::IntVar EnvSoftwareCurrentFontSize("SoftwareCurrentFontSize", 12);
const char *rootVarName = "TOONZROOT";
const char *systemVarPrefix = "TOONZ";
2016-03-19 06:57:51 +13:00
#ifdef MACOSX
#include "tthread.h"
2016-06-15 18:43:10 +12:00
void postThreadMsg(TThread::Message *) {}
2016-03-19 06:57:51 +13:00
void qt_mac_set_menubar_merge(bool enable);
#endif
2016-06-15 18:43:10 +12:00
// Modifica per toonz (non servono questo tipo di licenze)
2016-03-19 06:57:51 +13:00
#define NO_LICENSE
//-----------------------------------------------------------------------------
static void fatalError(QString msg) {
2016-06-15 18:43:10 +12:00
DVGui::MsgBoxInPopup(
CRITICAL,
msg + "\n" +
QObject::tr("Installing %1 again could fix the problem.")
.arg(QString::fromStdString(TEnv::getApplicationFullName())));
2016-06-15 18:43:10 +12:00
exit(0);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
static void lastWarningError(QString msg) {
2016-06-15 18:43:10 +12:00
DVGui::error(msg);
// exit(0);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
static void toonzRunOutOfContMemHandler(unsigned long size) {
2016-04-15 17:11:23 +12:00
#ifdef _WIN32
2016-06-15 18:43:10 +12:00
static bool firstTime = true;
if (firstTime) {
2020-10-02 19:20:33 +13:00
MessageBox(NULL, (LPCWSTR)L"Run out of contiguous physical memory: please save all and restart Tahoma2D!",
2016-03-19 06:57:51 +13:00
(LPCWSTR)L"Warning", MB_OK | MB_SYSTEMMODAL);
2016-06-15 18:43:10 +12:00
firstTime = false;
}
2016-03-19 06:57:51 +13:00
#endif
}
//-----------------------------------------------------------------------------
// todo.. da mettere in qualche .h
DV_IMPORT_API void initStdFx();
DV_IMPORT_API void initColorFx();
//-----------------------------------------------------------------------------
//! Inizializzaza l'Environment di Toonz
/*! In particolare imposta la projectRoot e
la stuffDir, controlla se la directory di outputs esiste (e provvede a
crearla in caso contrario) verifica inoltre che stuffDir esista.
*/
static void initToonzEnv(QHash<QString, QString> &argPathValues) {
2016-06-15 18:43:10 +12:00
StudioPalette::enable(true);
TEnv::setRootVarName(rootVarName);
TEnv::setSystemVarPrefix(systemVarPrefix);
QHash<QString, QString>::const_iterator i = argPathValues.constBegin();
while (i != argPathValues.constEnd()) {
if (!TEnv::setArgPathValue(i.key().toStdString(), i.value().toStdString()))
DVGui::error(
QObject::tr("The qualifier %1 is not a valid key name. Skipping.")
.arg(i.key()));
++i;
}
2020-10-02 19:20:33 +13:00
QCoreApplication::setOrganizationName("Tahoma2D");
2016-06-15 18:43:10 +12:00
QCoreApplication::setOrganizationDomain("");
QCoreApplication::setApplicationName(
QString::fromStdString(TEnv::getApplicationName()));
2016-06-15 18:43:10 +12:00
/*-- TOONZROOTのPathの確認 --*/
// controllo se la xxxroot e' definita e corrisponde ad un folder esistente
/*-- ENGLISH: Confirm TOONZROOT Path
Check if the xxxroot is defined and corresponds to an existing folder
--*/
2016-06-15 18:43:10 +12:00
TFilePath stuffDir = TEnv::getStuffDir();
if (stuffDir == TFilePath())
fatalError("Undefined or empty: \"" + toQString(TEnv::getRootVarPath()) +
"\"");
else if (!TFileStatus(stuffDir).isDirectory())
fatalError("Folder \"" + toQString(stuffDir) +
"\" not found or not readable");
2016-06-15 18:43:10 +12:00
Tiio::defineStd();
initImageIo();
initSoundIo();
initStdFx();
initColorFx();
// TPluginManager::instance()->loadStandardPlugins();
TFilePath library = ToonzFolder::getLibraryFolder();
TRasterImagePatternStrokeStyle::setRootDir(library);
TVectorImagePatternStrokeStyle::setRootDir(library);
TVectorBrushStyle::setRootDir(library);
CustomStyleManager::setRootPath(library);
// sembra indispensabile nella lettura dei .tab 2.2:
TPalette::setRootDir(library);
TImageStyle::setLibraryDir(library);
// TProjectManager::instance()->enableTabMode(true);
TProjectManager *projectManager = TProjectManager::instance();
/*--
* TOONZPROJECTSのパスセットを取得するTOONZPROJECTSはセミコロンで区切って複数設定可能
* --*/
// TFilePathSet projectsRoots = ToonzFolder::getProjectsFolders();
// TFilePathSet::iterator it;
// for (it = projectsRoots.begin(); it != projectsRoots.end(); ++it)
// projectManager->addProjectsRoot(*it);
2016-06-15 18:43:10 +12:00
/*-- もしまだ無ければ、TOONZROOT/sandboxにsandboxプロジェクトを作る --*/
projectManager->createSandboxIfNeeded();
/*
TProjectP project = projectManager->getCurrentProject();
Non dovrebbe servire per Tab:
project->setFolder(TProject::Drawings, TFilePath("$scenepath"));
project->setFolder(TProject::Extras, TFilePath("$scenepath"));
project->setUseScenePath(TProject::Drawings, false);
project->setUseScenePath(TProject::Extras, false);
2016-03-19 06:57:51 +13:00
*/
2016-06-15 18:43:10 +12:00
// Imposto la rootDir per ImageCache
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
/*-- TOONZCACHEROOTの設定 --*/
TFilePath cacheDir = ToonzFolder::getCacheRootFolder();
2016-06-15 18:43:10 +12:00
if (cacheDir.isEmpty()) cacheDir = TEnv::getStuffDir() + "cache";
TImageCache::instance()->setRootDir(cacheDir);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
static void script_output(int type, const QString &value) {
2020-01-12 07:21:27 +13:00
if (type == ScriptEngine::ExecutionError ||
type == ScriptEngine::SyntaxError ||
type == ScriptEngine::UndefinedEvaluationResult ||
type == ScriptEngine::Warning)
std::cerr << value.toStdString() << std::endl;
else
std::cout << value.toStdString() << std::endl;
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
int main(int argc, char *argv[]) {
#ifdef Q_OS_WIN
2016-06-15 18:43:10 +12:00
// Enable standard input/output on Windows Platform for debug
BOOL consoleAttached = ::AttachConsole(ATTACH_PARENT_PROCESS);
if (consoleAttached) {
freopen("CON", "r", stdin);
freopen("CON", "w", stdout);
freopen("CON", "w", stderr);
}
2016-03-19 06:57:51 +13:00
#endif
// parsing arguments and qualifiers
TFilePath loadFilePath;
QString argumentLayoutFileName = "";
QHash<QString, QString> argumentPathValues;
2016-06-15 18:43:10 +12:00
if (argc > 1) {
TCli::Usage usage(argv[0]);
TCli::UsageLine usageLine;
2020-01-12 07:21:27 +13:00
TCli::FilePathArgument loadFileArg(
"filePath", "Source scene file to open or script file to run");
TCli::StringQualifier layoutFileQual(
"-layout filename",
"Custom layout file to be used, it should be saved in "
"$TOONZPROFILES\\layouts\\personal\\[CurrentLayoutName].[UserName]\\. "
"layouts.txt is used by default.");
usageLine = usageLine + layoutFileQual;
// system path qualifiers
std::map<QString, std::unique_ptr<TCli::QualifierT<TFilePath>>>
systemPathQualMap;
QString qualKey = QString("%1ROOT").arg(systemVarPrefix);
QString qualName = QString("-%1 folderpath").arg(qualKey);
QString qualHelp =
QString(
"%1 path. It will automatically set other system paths to %1 "
"unless individually specified with other qualifiers.")
.arg(qualKey);
systemPathQualMap[qualKey].reset(new TCli::QualifierT<TFilePath>(
qualName.toStdString(), qualHelp.toStdString()));
usageLine = usageLine + *systemPathQualMap[qualKey];
const std::map<std::string, std::string> &spm = TEnv::getSystemPathMap();
for (auto itr = spm.begin(); itr != spm.end(); ++itr) {
qualKey = QString("%1%2")
.arg(systemVarPrefix)
.arg(QString::fromStdString((*itr).first));
qualName = QString("-%1 folderpath").arg(qualKey);
qualHelp = QString("%1 path.").arg(qualKey);
systemPathQualMap[qualKey].reset(new TCli::QualifierT<TFilePath>(
qualName.toStdString(), qualHelp.toStdString()));
usageLine = usageLine + *systemPathQualMap[qualKey];
}
usage.add(usageLine);
usage.add(usageLine + loadFileArg);
if (!usage.parse(argc, argv)) exit(1);
loadFilePath = loadFileArg.getValue();
if (layoutFileQual.isSelected())
argumentLayoutFileName =
QString::fromStdString(layoutFileQual.getValue());
for (auto q_itr = systemPathQualMap.begin();
q_itr != systemPathQualMap.end(); ++q_itr) {
if (q_itr->second->isSelected())
argumentPathValues.insert(q_itr->first,
q_itr->second->getValue().getQString());
2016-06-15 18:43:10 +12:00
}
argc = 1;
2016-06-15 18:43:10 +12:00
}
2017-04-06 13:58:31 +12:00
// Enables high-DPI scaling. This attribute must be set before QApplication is
// constructed. Available from Qt 5.6.
#if QT_VERSION >= 0x050600
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
2017-04-19 22:31:31 +12:00
2016-06-15 18:43:10 +12:00
QApplication a(argc, argv);
2016-03-19 06:57:51 +13:00
#ifdef MACOSX
// This workaround is to avoid missing left button problem on Qt5.6.0.
// To invalidate m_rightButtonClicked in Qt/qnsview.mm, sending
// NSLeftButtonDown event before NSLeftMouseDragged event propagated to
// QApplication. See more details in ../mousedragfilter/mousedragfilter.mm.
#include "mousedragfilter.h"
class OSXMouseDragFilter final : public QAbstractNativeEventFilter {
bool leftButtonPressed = false;
public:
bool nativeEventFilter(const QByteArray &eventType, void *message,
long *) Q_DECL_OVERRIDE {
if (IsLeftMouseDown(message)) {
leftButtonPressed = true;
}
if (IsLeftMouseUp(message)) {
leftButtonPressed = false;
}
if (eventType == "mac_generic_NSEvent") {
if (IsLeftMouseDragged(message) && !leftButtonPressed) {
std::cout << "force mouse press event" << std::endl;
SendLeftMousePressEvent();
return true;
}
}
return false;
}
};
a.installNativeEventFilter(new OSXMouseDragFilter);
#endif
#ifdef Q_OS_WIN
2020-05-23 16:20:51 +12:00
// Since currently Tahoma does not work with OpenGL of software or
2016-06-20 14:23:05 +12:00
// angle,
2016-06-15 18:43:10 +12:00
// force Qt to use desktop OpenGL
a.setAttribute(Qt::AA_UseDesktopOpenGL, true);
#endif
2016-06-15 18:43:10 +12:00
// Some Qt objects are destroyed badly withouth a living qApp. So, we must
// enforce a way to either
// postpone the application destruction until the very end, OR ensure that
// sensible objects are
// destroyed before.
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Using a static QApplication only worked on Windows, and in any case C++
// respects the statics destruction
// order ONLY within the same library. On MAC, it made the app crash on exit
// o_o. So, nope.
2016-03-19 06:57:51 +13:00
std::unique_ptr<QObject> mainScope(new QObject(
2016-06-15 18:43:10 +12:00
&a)); // A QObject destroyed before the qApp is therefore explicitly
mainScope->setObjectName("mainScope"); // provided. It can be accessed by
// looking in the qApp's children.
2016-03-19 06:57:51 +13:00
2016-04-15 17:11:23 +12:00
#ifdef _WIN32
2016-03-19 06:57:51 +13:00
#ifndef x64
2016-06-15 18:43:10 +12:00
// Store the floating point control word. It will be re-set before Toonz
// initialization
// has ended.
unsigned int fpWord = 0;
_controlfp_s(&fpWord, 0, 0);
2016-03-19 06:57:51 +13:00
#endif
#endif
2016-04-15 17:11:23 +12:00
#ifdef _WIN32
2016-06-15 18:43:10 +12:00
// At least on windows, Qt's 4.5.2 native windows feature tend to create
// weird flickering effects when dragging panel separators.
a.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
2016-03-19 06:57:51 +13:00
#endif
2017-04-19 22:31:31 +12:00
2017-04-17 19:59:25 +12:00
// Enable to render smooth icons on high dpi monitors
a.setAttribute(Qt::AA_UseHighDpiPixmaps);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Set the app's locale for numeric stuff to standard C. This is important for
// atof() and similar
// calls that are locale-dependant.
setlocale(LC_NUMERIC, "C");
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Set current directory to the bundle/application path - this is needed to have
// correct relative paths
2016-03-19 06:57:51 +13:00
#ifdef MACOSX
2016-06-15 18:43:10 +12:00
{
QDir appDir(QApplication::applicationDirPath());
appDir.cdUp(), appDir.cdUp(), appDir.cdUp();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
bool ret = QDir::setCurrent(appDir.absolutePath());
assert(ret);
}
2016-03-19 06:57:51 +13:00
#endif
UI update and Icons from Konero (#126) * add multi arc mockup * implement mutli arc * add join and smooth option * reset multiarc and arc when deactivated * create self loop if the last point is the same as the first * make join option in multiarc consistent with tape tool * fix a bug where thickness don't affect mutliarc in vector level * remove join option in geometric tool * stop mutliarc after closing shape * double click can also end multi arc * fix a bug where multiArc will produce buggy stroke * fix a bug where geometric tools is not deactivated * add multiArc shortcut * rewrite multiArc * revert changes to tvectorimage * add undo data for multiArc * Paste as Copy Command for XSheet * Remove unneeded code * Bug fix * prevent guide lines from jumping around in MultiArc * make stroke color consistent in MultiArc * remove color in MultiArc's undo data * make color consistent in MultiArc with previous version * Fix single image raster levels * fix compilation error * fix a bug where multiArc might generate bugged stroke * Remove ICONV dep (#3304) * fix crash on saving studio palette * Move to Paste Special Menu * Don't Set Fixed Width if Docking a Floating Panel * Update how_to_build_win.md New draft of pr for requested changes to windows build instructions. * fix geometric tool multiarc smooth option * fix level saving failure * fix wrong warning after saving palette * fix a bug where moving a control point while holding alt has unintended result * fix travis-install (#3389) * Fix assert debug crash in flipconsole.cpp Fix crash when using the viewer controls in the console (debug) * Redraw Audio Waveform Fills the waveform rather than outlines it. * Update .gitignore * fix undo data when drawing arc and mutliarc * fix overwriting raster drawing palette (#3387) * mode sensitive fx settings * Create New Style Command Button (#3394) * Create New Style Command Button This PR creates a new button in the pallette editor that creates a new style. Button is large and easy access for a faster and easier workflow. Original code developed by Turtletooth for Tahoma. Given permission to develop within Openoonz. Co-Authored-By: Jeremy Bullock <turtletooth@users.noreply.github.com> * Update paletteviewergui.cpp Made changes to the PR per request by Shun. * Fixed a space within the code that wasn't suppose to be there. Co-authored-by: Jeremy Bullock <turtletooth@users.noreply.github.com> * tahoma license (#3396) * new style button optional * fix loading pegbars (removing updateKeyframes) * periodic random expression * add fx in linear color space this commit is based on source for the ComposeAdd plugin fx by DWANGO Co., Ltd. in dwango_opentoonz_plugins and opentoonz_plugin_utility repositories. * fractal noise iwa fx * skip unnecessary icon invalidation * fix frame range fill with tablet * stop function editor to open by dbl clicking key * Expanding the radius of the rotation handle. This just changes when the cursor transforms into the rotation tool. (cherry picked from commit 7722ae989bbdc6aa5cb48df7a4c08bae1fe6ea39) * fix vector img patern stroke style * Update Stylesheets - Support the new icon sizes - XSheet and Timeline significantly redesigned - Lots of margin fixes and refactoring - Remove deprecated icons, as some icons are moved into binary - New Light theme * New Icons - Redesigns almost every icon as symbolic - Adds icons for most commands * Add Option for Icon Themes - Adds option for icon themes - Removes useless label from Preferences category list * Update Icon Functions - Adds themePath() boolean - Adds function for recoloring black pixels in pixmaps to any color - Rebuilds createQIcon to use fromTheme() and recolorPixmap() - Removes createQIconOnOff as it seemed to be a rarely used duplicate of createQIcon - Removes a grey horizontal line drawn above the console play bar in the viewer * Set Default Icon Theme and Paths - Sets search paths for icons for use with QIcon::fromTheme() - Sets default start icon theme on first install - Sets flag for displaying icons in menus, so we can selectively hide them * Set Icons for Commands - Sets icons for the commands - Hides icons being displayed in menus as most icons are 20x20, they will look blurry when shrunk to 16x16 - Selectively allows icons to display for Tools in menus * Change Icon Sizes, General Fixes and Stylesheet Additions - Change icon sizes to new size - Remove margin around FX Editor window - Remove white line under color sliders in Style Editor - Make keyframe icons uniform and color stylable in the stylesheets - Removes deprecated stylesheet strings - Redesign GUI for palette list view - Make tree list header sort row stylable - Remove black lines from scrollbars in New Project window - Remove margin around combobox in Level Strip - Alter how some lines are drawn in the Timeline to fix some alpha issues - Make conditional fixed onion skin and normal onion skin dots contrast more against a light background area to make sure they have good visibility - Make text always viewable in the FPS field in console bar - Increase size of radio buttons in Cleanup Settings - Increase size of switches in motion path nodes - Remove unessesary "Layer" label in Timeline and other rects - Various colors made stylable in the stylesheets; palette numpad and selection frame, cleanup settings border, scene cast folder path, schematic lines, ruler, xsheet lines, keyframes, cell input box and more - Moves some external stylesheet icons into binary * Make TPanelTitleBar Icon States Stylable - Makes icon states for TPanelTitleBar buttons stylable in stylesheets * Travis Fixes * Swap Startup Popup Logos They were in the wrong folders * Revert "Swap Startup Popup Logos" This reverts commit 815908a9f3e725f48507dab8a2270bdfa045649d. * Fix Startup Popup Logo It wasn't switching * Feedback Changes - Change render visualization to clapboard - Fix text contrast on levels in XSheet * Make Cell Selection More Clear * Darken Light Theme and Tint Empty Cell Selection * Fix missing icons * Fix memo button * Bring back colors * Hide Motion Tab * Fix Play Range Area (Light) Make play range area more visible * Vector Column Color Co-authored-by: pojienie <pojienie@gmail.com> Co-authored-by: rim <11380091+rozhuk-im@users.noreply.github.com> Co-authored-by: shun-iwasawa <shun.iwasawa@ghibli.jp> Co-authored-by: Rodney <rodney.baker@gmail.com> Co-authored-by: DoctorRyan <65507211+DoctorRyan@users.noreply.github.com> Co-authored-by: shun-iwasawa <shun-iwasawa@users.noreply.github.com> Co-authored-by: Kite <konero@users.noreply.github.com> Co-authored-by: Jeremy Bullock <turtletooth@users.noreply.github.com> Co-authored-by: DoctorRyan <doctorryan1969.gmail.com>
2020-09-01 06:51:22 +12:00
// Set icon theme search paths
QStringList themeSearchPathsList = {":/icons"};
QIcon::setThemeSearchPaths(themeSearchPathsList);
// qDebug() << "All icon theme search paths:" << QIcon::themeSearchPaths();
// Set show icons in menus flag (use iconVisibleInMenu to disable selectively)
QApplication::instance()->setAttribute(Qt::AA_DontShowIconsInMenus, false);
2019-06-03 11:21:05 +12:00
TEnv::setApplicationFileName(argv[0]);
2016-06-15 18:43:10 +12:00
// splash screen
2020-07-03 19:28:13 +12:00
QPixmap splashPixmap =
QIcon(":Resources/splash2.svg").pixmap(QSize(344, 344));
2017-06-26 14:43:02 +12:00
splashPixmap.setDevicePixelRatio(QApplication::desktop()->devicePixelRatio());
2020-07-03 19:28:13 +12:00
2017-06-26 14:43:02 +12:00
// QPixmap splashPixmap(":Resources/splash.png");
2016-04-15 17:11:23 +12:00
#ifdef _WIN32
2017-09-13 22:04:05 +12:00
QFont font("Segoe UI", -1);
2016-03-19 06:57:51 +13:00
#else
2017-04-19 23:45:36 +12:00
QFont font("Helvetica", -1);
2016-03-19 06:57:51 +13:00
#endif
2020-07-03 19:28:13 +12:00
font.setPixelSize(10);
2017-09-13 22:04:05 +12:00
font.setWeight(50);
2017-04-19 23:45:36 +12:00
a.setFont(font);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
QString offsetStr("\n\n\n\n\n\n\n\n");
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TSystem::hasMainLoop(true);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TMessageRepository::instance();
2016-03-19 06:57:51 +13:00
2020-01-12 07:21:27 +13:00
bool isRunScript = (loadFilePath.getType() == "toonzscript");
2016-06-15 18:43:10 +12:00
QSplashScreen splash(splashPixmap);
2020-07-03 19:28:13 +12:00
QPainterPath path;
path.addRoundedRect(splash.rect(), 7, 7);
QRegion mask = QRegion(path.toFillPolygon().toPolygon());
splash.setMask(mask);
2020-01-12 07:21:27 +13:00
if (!isRunScript) splash.show();
2016-06-15 18:43:10 +12:00
a.processEvents();
2016-03-19 06:57:51 +13:00
2020-07-03 19:28:13 +12:00
splash.showMessage(offsetStr + "Initializing QGLFormat...",
Qt::AlignRight | Qt::AlignBottom, Qt::black);
2016-06-15 18:43:10 +12:00
a.processEvents();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// OpenGL
QGLFormat fmt;
fmt.setAlpha(true);
fmt.setStencil(true);
QGLFormat::setDefaultFormat(fmt);
2016-03-19 06:57:51 +13:00
2017-06-07 00:19:00 +12:00
// seems this function should be called at all systems
// pheraps in some GLUT-implementations initalization is mere formality
#if defined(LINUX) || (defined(_WIN32) && defined(__GNUC__))
2016-06-15 18:43:10 +12:00
glutInit(&argc, argv);
#endif
2020-07-03 19:28:13 +12:00
splash.showMessage(offsetStr + "Initializing environment...",
Qt::AlignRight | Qt::AlignBottom, Qt::black);
2016-06-15 18:43:10 +12:00
a.processEvents();
// Install run out of contiguous memory callback
TBigMemoryManager::instance()->setRunOutOfContiguousMemoryHandler(
&toonzRunOutOfContMemHandler);
// Toonz environment
initToonzEnv(argumentPathValues);
2016-06-15 18:43:10 +12:00
// Initialize thread components
TThread::init();
TProjectManager *projectManager = TProjectManager::instance();
if (Preferences::instance()->isSVNEnabled()) {
// Read Version Control repositories and add it to project manager as
// "special" svn project root
VersionControl::instance()->init();
QList<SVNRepository> repositories =
VersionControl::instance()->getRepositories();
int count = repositories.size();
for (int i = 0; i < count; i++) {
SVNRepository r = repositories.at(i);
TFilePath localPath(r.m_localPath.toStdWString());
if (!TFileStatus(localPath).doesExist()) {
try {
TSystem::mkDir(localPath);
} catch (TException &e) {
fatalError(QString::fromStdWString(e.getMessage()));
}
}
projectManager->addSVNProjectsRoot(localPath);
}
}
2016-03-19 06:57:51 +13:00
#if defined(MACOSX) && defined(__LP64__)
2016-06-15 18:43:10 +12:00
// Load the shared memory settings
int shmmax = Preferences::instance()->getShmMax();
int shmseg = Preferences::instance()->getShmSeg();
int shmall = Preferences::instance()->getShmAll();
int shmmni = Preferences::instance()->getShmMni();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
if (shmall <
0) // Make sure that at least 100 MB of shared memory are available
shmall = (tipc::shm_maxSharedPages() < (100 << 8)) ? (100 << 8) : -1;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
tipc::shm_set(shmmax, shmseg, shmall, shmmni);
2016-03-19 06:57:51 +13:00
#endif
2016-06-15 18:43:10 +12:00
// DVDirModel must be instantiated after Version Control initialization...
FolderListenerManager::instance()->addListener(DvDirModel::instance());
2016-03-19 06:57:51 +13:00
2020-07-03 19:28:13 +12:00
splash.showMessage(offsetStr + "Loading Translator...",
Qt::AlignRight | Qt::AlignBottom, Qt::black);
2016-06-15 18:43:10 +12:00
a.processEvents();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Carico la traduzione contenuta in toonz.qm (se � presente)
QString languagePathString =
QString::fromStdString(::to_string(TEnv::getConfigDir() + "loc"));
#ifndef WIN32
2016-06-15 18:43:10 +12:00
// the merge of menu on osx can cause problems with different languages with
// the Preferences menu
// qt_mac_set_menubar_merge(false);
languagePathString += "/" + Preferences::instance()->getCurrentLanguage();
2016-03-19 06:57:51 +13:00
#else
2016-06-15 18:43:10 +12:00
languagePathString += "\\" + Preferences::instance()->getCurrentLanguage();
2016-03-19 06:57:51 +13:00
#endif
2016-06-15 18:43:10 +12:00
QTranslator translator;
translator.load("toonz", languagePathString);
2016-06-15 18:43:10 +12:00
// La installo
a.installTranslator(&translator);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Carico la traduzione contenuta in toonzqt.qm (se e' presente)
QTranslator translator2;
translator2.load("toonzqt", languagePathString);
a.installTranslator(&translator2);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Carico la traduzione contenuta in tnzcore.qm (se e' presente)
QTranslator tnzcoreTranslator;
tnzcoreTranslator.load("tnzcore", languagePathString);
qApp->installTranslator(&tnzcoreTranslator);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Carico la traduzione contenuta in toonzlib.qm (se e' presente)
QTranslator toonzlibTranslator;
toonzlibTranslator.load("toonzlib", languagePathString);
qApp->installTranslator(&toonzlibTranslator);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Carico la traduzione contenuta in colorfx.qm (se e' presente)
QTranslator colorfxTranslator;
colorfxTranslator.load("colorfx", languagePathString);
qApp->installTranslator(&colorfxTranslator);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Carico la traduzione contenuta in tools.qm
QTranslator toolTranslator;
toolTranslator.load("tnztools", languagePathString);
qApp->installTranslator(&toolTranslator);
2016-03-19 06:57:51 +13:00
// load translation for file writers properties
QTranslator imageTranslator;
imageTranslator.load("image", languagePathString);
qApp->installTranslator(&imageTranslator);
QTranslator qtTranslator;
qtTranslator.load("qt_" + QLocale::system().name(),
QLibraryInfo::location(QLibraryInfo::TranslationsPath));
a.installTranslator(&qtTranslator);
2016-06-15 18:43:10 +12:00
// Aggiorno la traduzione delle properties di tutti i tools
TTool::updateToolsPropertiesTranslation();
// Apply translation to file writers properties
Tiio::updateFileWritersPropertiesTranslation();
2016-03-19 06:57:51 +13:00
2018-07-10 19:45:56 +12:00
// Force to have left-to-right layout direction in any language environment.
// This function has to be called after installTranslator().
2018-07-10 19:45:56 +12:00
a.setLayoutDirection(Qt::LeftToRight);
2020-07-03 19:28:13 +12:00
splash.showMessage(offsetStr + "Loading styles...",
Qt::AlignRight | Qt::AlignBottom, Qt::black);
2016-06-15 18:43:10 +12:00
a.processEvents();
2016-03-19 06:57:51 +13:00
UI update and Icons from Konero (#126) * add multi arc mockup * implement mutli arc * add join and smooth option * reset multiarc and arc when deactivated * create self loop if the last point is the same as the first * make join option in multiarc consistent with tape tool * fix a bug where thickness don't affect mutliarc in vector level * remove join option in geometric tool * stop mutliarc after closing shape * double click can also end multi arc * fix a bug where multiArc will produce buggy stroke * fix a bug where geometric tools is not deactivated * add multiArc shortcut * rewrite multiArc * revert changes to tvectorimage * add undo data for multiArc * Paste as Copy Command for XSheet * Remove unneeded code * Bug fix * prevent guide lines from jumping around in MultiArc * make stroke color consistent in MultiArc * remove color in MultiArc's undo data * make color consistent in MultiArc with previous version * Fix single image raster levels * fix compilation error * fix a bug where multiArc might generate bugged stroke * Remove ICONV dep (#3304) * fix crash on saving studio palette * Move to Paste Special Menu * Don't Set Fixed Width if Docking a Floating Panel * Update how_to_build_win.md New draft of pr for requested changes to windows build instructions. * fix geometric tool multiarc smooth option * fix level saving failure * fix wrong warning after saving palette * fix a bug where moving a control point while holding alt has unintended result * fix travis-install (#3389) * Fix assert debug crash in flipconsole.cpp Fix crash when using the viewer controls in the console (debug) * Redraw Audio Waveform Fills the waveform rather than outlines it. * Update .gitignore * fix undo data when drawing arc and mutliarc * fix overwriting raster drawing palette (#3387) * mode sensitive fx settings * Create New Style Command Button (#3394) * Create New Style Command Button This PR creates a new button in the pallette editor that creates a new style. Button is large and easy access for a faster and easier workflow. Original code developed by Turtletooth for Tahoma. Given permission to develop within Openoonz. Co-Authored-By: Jeremy Bullock <turtletooth@users.noreply.github.com> * Update paletteviewergui.cpp Made changes to the PR per request by Shun. * Fixed a space within the code that wasn't suppose to be there. Co-authored-by: Jeremy Bullock <turtletooth@users.noreply.github.com> * tahoma license (#3396) * new style button optional * fix loading pegbars (removing updateKeyframes) * periodic random expression * add fx in linear color space this commit is based on source for the ComposeAdd plugin fx by DWANGO Co., Ltd. in dwango_opentoonz_plugins and opentoonz_plugin_utility repositories. * fractal noise iwa fx * skip unnecessary icon invalidation * fix frame range fill with tablet * stop function editor to open by dbl clicking key * Expanding the radius of the rotation handle. This just changes when the cursor transforms into the rotation tool. (cherry picked from commit 7722ae989bbdc6aa5cb48df7a4c08bae1fe6ea39) * fix vector img patern stroke style * Update Stylesheets - Support the new icon sizes - XSheet and Timeline significantly redesigned - Lots of margin fixes and refactoring - Remove deprecated icons, as some icons are moved into binary - New Light theme * New Icons - Redesigns almost every icon as symbolic - Adds icons for most commands * Add Option for Icon Themes - Adds option for icon themes - Removes useless label from Preferences category list * Update Icon Functions - Adds themePath() boolean - Adds function for recoloring black pixels in pixmaps to any color - Rebuilds createQIcon to use fromTheme() and recolorPixmap() - Removes createQIconOnOff as it seemed to be a rarely used duplicate of createQIcon - Removes a grey horizontal line drawn above the console play bar in the viewer * Set Default Icon Theme and Paths - Sets search paths for icons for use with QIcon::fromTheme() - Sets default start icon theme on first install - Sets flag for displaying icons in menus, so we can selectively hide them * Set Icons for Commands - Sets icons for the commands - Hides icons being displayed in menus as most icons are 20x20, they will look blurry when shrunk to 16x16 - Selectively allows icons to display for Tools in menus * Change Icon Sizes, General Fixes and Stylesheet Additions - Change icon sizes to new size - Remove margin around FX Editor window - Remove white line under color sliders in Style Editor - Make keyframe icons uniform and color stylable in the stylesheets - Removes deprecated stylesheet strings - Redesign GUI for palette list view - Make tree list header sort row stylable - Remove black lines from scrollbars in New Project window - Remove margin around combobox in Level Strip - Alter how some lines are drawn in the Timeline to fix some alpha issues - Make conditional fixed onion skin and normal onion skin dots contrast more against a light background area to make sure they have good visibility - Make text always viewable in the FPS field in console bar - Increase size of radio buttons in Cleanup Settings - Increase size of switches in motion path nodes - Remove unessesary "Layer" label in Timeline and other rects - Various colors made stylable in the stylesheets; palette numpad and selection frame, cleanup settings border, scene cast folder path, schematic lines, ruler, xsheet lines, keyframes, cell input box and more - Moves some external stylesheet icons into binary * Make TPanelTitleBar Icon States Stylable - Makes icon states for TPanelTitleBar buttons stylable in stylesheets * Travis Fixes * Swap Startup Popup Logos They were in the wrong folders * Revert "Swap Startup Popup Logos" This reverts commit 815908a9f3e725f48507dab8a2270bdfa045649d. * Fix Startup Popup Logo It wasn't switching * Feedback Changes - Change render visualization to clapboard - Fix text contrast on levels in XSheet * Make Cell Selection More Clear * Darken Light Theme and Tint Empty Cell Selection * Fix missing icons * Fix memo button * Bring back colors * Hide Motion Tab * Fix Play Range Area (Light) Make play range area more visible * Vector Column Color Co-authored-by: pojienie <pojienie@gmail.com> Co-authored-by: rim <11380091+rozhuk-im@users.noreply.github.com> Co-authored-by: shun-iwasawa <shun.iwasawa@ghibli.jp> Co-authored-by: Rodney <rodney.baker@gmail.com> Co-authored-by: DoctorRyan <65507211+DoctorRyan@users.noreply.github.com> Co-authored-by: shun-iwasawa <shun-iwasawa@users.noreply.github.com> Co-authored-by: Kite <konero@users.noreply.github.com> Co-authored-by: Jeremy Bullock <turtletooth@users.noreply.github.com> Co-authored-by: DoctorRyan <doctorryan1969.gmail.com>
2020-09-01 06:51:22 +12:00
// Set default start icon theme
QIcon::setThemeName(Preferences::instance()->getIconTheme() ? "dark"
: "light");
// qDebug() << "Icon theme name:" << QIcon::themeName();
2016-06-15 18:43:10 +12:00
// stile
QApplication::setStyle("windows");
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
IconGenerator::setFilmstripIconSize(Preferences::instance()->getIconSize());
2016-03-19 06:57:51 +13:00
2020-07-03 19:28:13 +12:00
splash.showMessage(offsetStr + "Loading shaders...",
Qt::AlignRight | Qt::AlignBottom, Qt::black);
2016-06-15 18:43:10 +12:00
a.processEvents();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
loadShaderInterfaces(ToonzFolder::getLibraryFolder() + TFilePath("shaders"));
2016-03-19 06:57:51 +13:00
2020-10-02 19:20:33 +13:00
splash.showMessage(offsetStr + "Initializing Tahoma2D...",
2020-07-03 19:28:13 +12:00
Qt::AlignRight | Qt::AlignBottom, Qt::black);
2016-06-15 18:43:10 +12:00
a.processEvents();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TTool::setApplication(TApp::instance());
TApp::instance()->init();
2016-03-19 06:57:51 +13:00
2020-07-03 19:28:13 +12:00
splash.showMessage(offsetStr + "Loading Plugins...",
Qt::AlignRight | Qt::AlignBottom, Qt::black);
2016-06-15 18:43:10 +12:00
a.processEvents();
/* poll the thread ends:
PluginLoader setup
main thread queue blocking
processEvents
*/
while (!PluginLoader::load_entries("")) {
a.processEvents();
}
2016-03-19 06:57:51 +13:00
2020-07-03 19:28:13 +12:00
splash.showMessage(offsetStr + "Creating main window...",
Qt::AlignRight | Qt::AlignBottom, Qt::black);
2016-06-15 18:43:10 +12:00
a.processEvents();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
/*-- Layoutファイル名をMainWindowのctorに渡す --*/
MainWindow w(argumentLayoutFileName);
2020-09-04 16:09:45 +12:00
w.setWindowState(Qt::WindowMaximized);
2016-03-19 06:57:51 +13:00
2020-01-12 07:21:27 +13:00
if (isRunScript) {
// load script
if (TFileStatus(loadFilePath).doesExist()) {
// find project for this script file
TProjectManager *pm = TProjectManager::instance();
TProjectP sceneProject = pm->loadSceneProject(loadFilePath);
TFilePath oldProjectPath;
if (!sceneProject) {
std::cerr << QObject::tr(
"It is not possible to load the scene %1 because it "
"does not "
"belong to any project.")
.arg(loadFilePath.getQString())
.toStdString()
<< std::endl;
return 1;
}
if (sceneProject && !sceneProject->isCurrent()) {
oldProjectPath = pm->getCurrentProjectPath();
pm->setCurrentProjectPath(sceneProject->getProjectPath());
}
ScriptEngine engine;
QObject::connect(&engine, &ScriptEngine::output, script_output);
QString s = QString::fromStdWString(loadFilePath.getWideString())
.replace("\\", "\\\\")
.replace("\"", "\\\"");
QString cmd = QString("run(\"%1\")").arg(s);
engine.evaluate(cmd);
engine.wait();
if (!oldProjectPath.isEmpty()) pm->setCurrentProjectPath(oldProjectPath);
return 1;
} else {
std::cerr << QObject::tr("Script file %1 does not exists.")
.arg(loadFilePath.getQString())
.toStdString()
<< std::endl;
return 1;
}
}
2019-10-09 08:26:26 +13:00
#ifdef _WIN32
// http://doc.qt.io/qt-5/windows-issues.html#fullscreen-opengl-based-windows
2019-10-21 16:21:38 +13:00
if (w.windowHandle())
QWindowsWindowFunctions::setHasBorderInFullScreen(w.windowHandle(), true);
2019-10-09 08:26:26 +13:00
#endif
2020-07-03 19:28:13 +12:00
splash.showMessage(offsetStr + "Loading style sheet...",
Qt::AlignRight | Qt::AlignBottom, Qt::black);
2016-06-15 18:43:10 +12:00
a.processEvents();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Carico lo styleSheet
QString currentStyle = Preferences::instance()->getCurrentStyleSheetPath();
2016-06-15 18:43:10 +12:00
a.setStyleSheet(currentStyle);
2016-03-19 06:57:51 +13:00
w.setWindowTitle(QString::fromStdString(TEnv::getApplicationFullName()));
if (TEnv::getIsPortable()) {
2020-10-02 19:20:33 +13:00
splash.showMessage(offsetStr + "Starting Tahoma2D...",
2020-07-03 19:28:13 +12:00
Qt::AlignRight | Qt::AlignBottom, Qt::black);
} else {
2020-07-03 19:28:13 +12:00
splash.showMessage(offsetStr + "Starting main window...",
Qt::AlignRight | Qt::AlignBottom, Qt::black);
}
2016-06-15 18:43:10 +12:00
a.processEvents();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TFilePath fp = ToonzFolder::getModuleFile("mainwindow.ini");
QSettings settings(toQString(fp), QSettings::IniFormat);
w.restoreGeometry(settings.value("MainWindowGeometry").toByteArray());
2016-03-19 06:57:51 +13:00
#ifndef MACOSX
2016-06-15 18:43:10 +12:00
// Workaround for the maximized window case: Qt delivers two resize events,
// one in the normal geometry, before
// maximizing (why!?), the second afterwards - all inside the following show()
// call. This makes troublesome for
// the docking system to correctly restore the saved geometry. Fortunately,
// MainWindow::showEvent(..) gets called
// just between the two, so we can disable the currentRoom layout right before
// showing and re-enable it after
// the normal resize has happened.
if (w.isMaximized()) w.getCurrentRoom()->layout()->setEnabled(false);
2016-03-19 06:57:51 +13:00
#endif
2016-06-15 18:43:10 +12:00
QRect splashGeometry = splash.geometry();
splash.finish(&w);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
a.setQuitOnLastWindowClosed(false);
// a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
2018-03-14 20:58:55 +13:00
if (Preferences::instance()->isLatestVersionCheckEnabled())
w.checkForUpdates();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
w.show();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Show floating panels only after the main window has been shown
w.startupFloatingPanels();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
CommandManager::instance()->execute(T_Hand);
if (!loadFilePath.isEmpty()) {
2016-06-15 18:43:10 +12:00
splash.showMessage(
QString("Loading file '") + loadFilePath.getQString() + "'...",
2020-07-03 19:28:13 +12:00
Qt::AlignRight | Qt::AlignBottom, Qt::black);
2020-01-12 07:21:27 +13:00
loadFilePath = loadFilePath.withType("tnz");
if (TFileStatus(loadFilePath).doesExist()) IoCmd::loadScene(loadFilePath);
2016-06-15 18:43:10 +12:00
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
QFont *myFont;
QString fontName = Preferences::instance()->getInterfaceFont();
QString fontStyle = Preferences::instance()->getInterfaceFontStyle();
TFontManager *fontMgr = TFontManager::instance();
std::vector<std::wstring> typefaces;
bool isBold = false, isItalic = false, hasKerning = false;
try {
fontMgr->loadFontNames();
fontMgr->setFamily(fontName.toStdWString());
fontMgr->getAllTypefaces(typefaces);
isBold = fontMgr->isBold(fontName, fontStyle);
isItalic = fontMgr->isItalic(fontName, fontStyle);
hasKerning = fontMgr->hasKerning();
} catch (TFontCreationError &) {
// Do nothing. A default font should load
}
myFont = new QFont(fontName);
2016-06-15 18:43:10 +12:00
myFont->setPixelSize(EnvSoftwareCurrentFontSize);
myFont->setBold(isBold);
myFont->setItalic(isItalic);
myFont->setKerning(hasKerning);
2016-06-15 18:43:10 +12:00
a.setFont(*myFont);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
QAction *action = CommandManager::instance()->getAction("MI_OpenTMessage");
if (action)
QObject::connect(TMessageRepository::instance(),
SIGNAL(openMessageCenter()), action, SLOT(trigger()));
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
QObject::connect(TUndoManager::manager(), SIGNAL(somethingChanged()),
TApp::instance()->getCurrentScene(), SLOT(setDirtyFlag()));
2016-03-19 06:57:51 +13:00
2016-04-15 17:11:23 +12:00
#ifdef _WIN32
2016-03-19 06:57:51 +13:00
#ifndef x64
2016-06-15 18:43:10 +12:00
// On 32-bit architecture, there could be cases in which initialization could
// alter the
// FPU floating point control word. I've seen this happen when loading some
// AVI coded (VFAPI),
// where 80-bit internal precision was used instead of the standard 64-bit
// (much faster and
// sufficient - especially considering that x86 truncates to 64-bit
// representation anyway).
// IN ANY CASE, revert to the original control word.
// In the x64 case these precision changes simply should not take place up to
// _controlfp_s
// documentation.
_controlfp_s(0, fpWord, -1);
2016-03-19 06:57:51 +13:00
#endif
#endif
#ifdef _WIN32
if (Preferences::instance()->isWinInkEnabled()) {
KisTabletSupportWin8 *penFilter = new KisTabletSupportWin8();
if (penFilter->init()) {
a.installNativeEventFilter(penFilter);
} else {
delete penFilter;
}
}
#endif
2016-06-15 18:43:10 +12:00
a.installEventFilter(TApp::instance());
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
int ret = a.exec();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TUndoManager::manager()->reset();
PreviewFxManager::instance()->reset();
2016-03-19 06:57:51 +13:00
2016-04-15 17:11:23 +12:00
#ifdef _WIN32
2016-06-15 18:43:10 +12:00
if (consoleAttached) {
::FreeConsole();
}
2016-03-19 06:57:51 +13:00
#endif
2016-06-15 18:43:10 +12:00
return ret;
2016-03-19 06:57:51 +13:00
}