Merge tahoma2d master with conflicts resolved

This commit is contained in:
manongjohn 2021-03-01 00:11:49 -05:00
commit ea0358aeea
32 changed files with 583 additions and 254 deletions

View file

@ -10,11 +10,11 @@ I will first review the request, then I'll accept it, add comments for rework, o
### Workflow ### Workflow
0. `fork` Tahoma2D to your GitHub account from `turtletooth/tahoma2d`. 0. `fork` Tahoma2D to your GitHub account from `tahoma2d/tahoma2d`.
- (use the `fork` button at the https://github.com/turtletooth/tahoma2d) - (use the `fork` button at the https://github.com/tahoma2d/tahoma2d)
0. `clone` the repository. 0. `clone` the repository.
- `git clone git@github.com:your-github-account/tahoma2d.git` - `git clone git@github.com:your-github-account/tahoma2d.git`
- `git remote add upstream https://github.com/turtletooth/tahoma2d.git`, additionally. - `git remote add upstream https://github.com/tahoma2d/tahoma2d.git`, additionally.
0. modify the codes. 0. modify the codes.
- `git checkout -b your-branch-name` - `git checkout -b your-branch-name`
- `your-branch-name` is a name of your modifications, for example, - `your-branch-name` is a name of your modifications, for example,
@ -32,7 +32,7 @@ I will first review the request, then I'll accept it, add comments for rework, o
## Bugs ## Bugs
If you find bugs, please report details about them using [issues](https://github.com/turtletooth/tahoma2d/issues). If you find bugs, please report details about them using [issues](https://github.com/tahoma2d/tahoma2d/issues).
Please include information needed to reproduce the bug, including the operating system Please include information needed to reproduce the bug, including the operating system
and information directly relating to the issue. Links to screen captures of what is and information directly relating to the issue. Links to screen captures of what is
observed on screen or video of specific steps to produce the problem are very helpful. observed on screen or video of specific steps to produce the problem are very helpful.

View file

@ -1,7 +1,6 @@
# Tahoma2D # Tahoma2D
[![](https://ci.appveyor.com/api/projects/status/mnc3mepksux9kvap/branch/master?svg=true)](https://ci.appveyor.com/project/turtletooth/tahoma2d) [![](https://ci.appveyor.com/api/projects/status/mnc3mepksux9kvap/branch/master?svg=true)](https://ci.appveyor.com/project/tahoma2d/tahoma2d)
[![](https://travis-ci.com/turtletooth/tahoma2d.svg?branch=master)](https://travis-ci.com/turtletooth/tahoma2d)
## What is Tahoma2D? ## What is Tahoma2D?
@ -16,7 +15,7 @@ Please refer to the Tahoma2D site at <https://tahoma2d.org/download>.
## Installation ## Installation
Please download the latest release at <https://github.com/turtletooth/tahoma2d/releases>. Please download the latest release at <https://github.com/tahoma2d/tahoma2d/releases>.
## How to Build Locally ## How to Build Locally
@ -31,7 +30,7 @@ Can't develop but still want to help? Help us test individual Pull Requests befo
## Community ## Community
- To share tips or to troubleshoot, join the [Google Tahoma2D Users forum](hhttps://groups.google.com/g/tahoma2d) - To share tips or to troubleshoot, join the [Google Tahoma2D Users forum](hhttps://groups.google.com/g/tahoma2d)
- If you found a bug with the software after troubleshooting, or are a developer, search the [Github issues](https://github.com/turtletooth/tahoma2d/issues) and post there. - If you found a bug with the software after troubleshooting, or are a developer, search the [Github issues](https://github.com/tahoma2d/tahoma2d/issues) and post there.
## Licensing ## Licensing

View file

@ -101,7 +101,7 @@ $ cd ..
### Cloning the GIT Tree ### Cloning the GIT Tree
``` ```
$ git clone https://github.com/turtletooth/tahoma2d $ git clone https://github.com/tahoma2d/tahoma2d
``` ```
### Copying the 'stuff' Directory ### Copying the 'stuff' Directory

View file

@ -62,7 +62,7 @@ $ rm /usr/local/lib/cmake/glew
These steps will put the Tahoma2D repository under /Users/yourlogin/Documents. These steps will put the Tahoma2D repository under /Users/yourlogin/Documents.
``` ```
$ cd ~/Documents #or where you want to store the repository# $ cd ~/Documents #or where you want to store the repository#
$ git clone https://github.com/turtletooth/tahoma2d $ git clone https://github.com/tahoma2d/tahoma2d
$ cd tahoma2d $ cd tahoma2d
$ git lfs pull $ git lfs pull
$ cd thirdparty/boost $ cd thirdparty/boost

View file

@ -4,7 +4,7 @@ Tahoma2D does not directly use FFmpeg libraries or code.
As of July 2020, Tahoma2D is shipping with FFmpeg 4.3 LGPL version from https://ffmpeg.zeranoe.com/builds/ As of July 2020, Tahoma2D is shipping with FFmpeg 4.3 LGPL version from https://ffmpeg.zeranoe.com/builds/
FFmpeg source code can be found at: FFmpeg source code can be found at:
https://github.com/turtletooth/FFmpeg https://github.com/tahoma2d/FFmpeg
or or
https://github.com/FFmpeg/FFmpeg https://github.com/FFmpeg/FFmpeg

View file

@ -1,36 +0,0 @@
License Agreement For Tahoma2D
[https://github.com/turtletooth/tahoma2d]
- - - - - - - - - - - - - - - -
Tahoma2D
All contributions by Jeremy Bullock:
Copyright (c) 2016 - 2020, Jeremy Bullock
All rights reserved.
All contributions by DWANGO:
Copyright (c) 2016 - 2020, DWANGO Co., Ltd.
All rights reserved.
All other contributions:
Copyright (c) 2016 - 2020, the respective contributors.
All rights reserved.
Each contributor holds copyright over their respective contributions.
The project versioning (Git) records all such contribution source information.
LICENSE
BSD 3-Clause "New" or "Revised" License
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -11,7 +11,7 @@
<key>CFBundleIconFile</key> <key>CFBundleIconFile</key>
<string>Tahoma2D.icns</string> <string>Tahoma2D.icns</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>io.github.turtletooth.Tahoma2D</string> <string>io.github.tahoma2d.Tahoma2D</string>
<key>NSCameraUsageDescription</key> <key>NSCameraUsageDescription</key>
<string>Tahoma2D needs access to the camera in order to use Camera Capture</string> <string>Tahoma2D needs access to the camera in order to use Camera Capture</string>
<key>NSMicrophoneUsageDescription</key> <key>NSMicrophoneUsageDescription</key>

View file

@ -57,7 +57,7 @@ void TDoubleKeyframe::saveData(TOStream &os) const {
// Dirty resolution. Because the degree sign is converted to unexpected // Dirty resolution. Because the degree sign is converted to unexpected
// string... // string...
if (QString::fromStdWString(L"\u00b0").toStdString() == unitName) if (QString::fromStdWString(L"\u00b0").toStdString() == unitName)
unitName = "\\u00b0"; unitName = "degrees";
switch (m_type) { switch (m_type) {
case Constant: case Constant:
case Exponential: case Exponential:
@ -157,6 +157,9 @@ void TDoubleKeyframe::loadData(TIStream &is) {
break; break;
} }
if (!is.matchEndTag()) throw TException(tagName + " : missing endtag"); if (!is.matchEndTag()) throw TException(tagName + " : missing endtag");
if (m_unitName == "default") m_unitName = ""; if (m_unitName == "default")
m_unitName = "";
else if (m_unitName == "degrees")
m_unitName = "\u00b0";
m_isKeyframe = true; m_isKeyframe = true;
} }

View file

@ -342,6 +342,9 @@ public:
bool useCtrlAltToResizeBrushEnabled() const { bool useCtrlAltToResizeBrushEnabled() const {
return getBoolValue(useCtrlAltToResizeBrush); return getBoolValue(useCtrlAltToResizeBrush);
} }
int getTempToolSwitchtimer() const {
return getIntValue(temptoolswitchtimer);
}
// Xsheet tab // Xsheet tab
QString getXsheetLayoutPreference() const { QString getXsheetLayoutPreference() const {

View file

@ -107,6 +107,7 @@ enum PreferencesItemId {
cursorOutlineEnabled, cursorOutlineEnabled,
levelBasedToolsDisplay, levelBasedToolsDisplay,
useCtrlAltToResizeBrush, useCtrlAltToResizeBrush,
temptoolswitchtimer,
//---------- //----------
// Xsheet // Xsheet

View file

@ -20,6 +20,7 @@ class TPaletteHandle;
class TFxHandle; class TFxHandle;
class PaletteController; class PaletteController;
class TColorStyle; class TColorStyle;
class StatusBar;
//==================================================== //====================================================
@ -51,6 +52,7 @@ public:
virtual int getCurrentLevelStyleIndex() const = 0; virtual int getCurrentLevelStyleIndex() const = 0;
virtual void setCurrentLevelStyleIndex(int index, virtual void setCurrentLevelStyleIndex(int index,
bool forceUpdate = false) = 0; bool forceUpdate = false) = 0;
virtual void refreshStatusBar() = 0;
}; };
#endif // TAPPLICATION_H #endif // TAPPLICATION_H

View file

@ -1172,6 +1172,7 @@ public:
if (typeCode != m_typeCode) { if (typeCode != m_typeCode) {
m_typeCode = typeCode; m_typeCode = typeCode;
changeType(typeCode); changeType(typeCode);
TTool::getApplication()->refreshStatusBar();
} }
} else if (propertyName == m_param.m_edgeCount.getName()) } else if (propertyName == m_param.m_edgeCount.getName())
GeometricEdgeCount = m_param.m_edgeCount.getValue(); GeometricEdgeCount = m_param.m_edgeCount.getValue();

View file

@ -301,7 +301,8 @@ TImage *TTool::touchImage() {
bool animationSheetEnabled = pref->isAnimationSheetEnabled(); bool animationSheetEnabled = pref->isAnimationSheetEnabled();
bool isAutoStretchEnabled = pref->isAutoStretchEnabled(); bool isAutoStretchEnabled = pref->isAutoStretchEnabled();
bool isAutoRenumberEnabled = pref->isAutorenumberEnabled(); bool isAutoRenumberEnabled = pref->isAutorenumberEnabled();
bool isCreateInHoldCellsEnabled = pref->isCreationInHoldCellsEnabled(); bool isCreateInHoldCellsEnabled =
isAutoCreateEnabled && pref->isCreationInHoldCellsEnabled();
TFrameHandle *currentFrame = m_application->getCurrentFrame(); TFrameHandle *currentFrame = m_application->getCurrentFrame();
TXshLevelHandle *currentLevel = m_application->getCurrentLevel(); TXshLevelHandle *currentLevel = m_application->getCurrentLevel();

View file

@ -7,6 +7,7 @@
#include "timage.h" #include "timage.h"
//#include "tapp.h" //#include "tapp.h"
#include "toonzqt/menubarcommand.h" #include "toonzqt/menubarcommand.h"
#include "toonz/preferences.h"
#include <QAction> #include <QAction>
#include <QMap> #include <QMap>
#include <QDebug> #include <QDebug>
@ -72,7 +73,8 @@ void ToolHandle::storeTool() {
void ToolHandle::restoreTool() { void ToolHandle::restoreTool() {
//qDebug() << m_storedToolTime.elapsed(); //qDebug() << m_storedToolTime.elapsed();
if (m_storedToolName != m_toolName && m_storedToolName != "" && if (m_storedToolName != m_toolName && m_storedToolName != "" &&
m_storedToolTime.elapsed() > 500) { m_storedToolTime.elapsed() >
Preferences::instance()->getTempToolSwitchtimer()) {
setTool(m_storedToolName); setTool(m_storedToolName);
} }
} }

View file

@ -459,7 +459,7 @@ if(BUILD_ENV_MSVC)
${GL_LIB} ${GLUT_LIB} ${TURBOJPEG_LIB} ${OpenCV_LIBS} ${EXTRA_LIBS} strmiids ${GL_LIB} ${GLUT_LIB} ${TURBOJPEG_LIB} ${OpenCV_LIBS} ${EXTRA_LIBS} strmiids
tnzcore tnzbase toonzlib colorfx tnzext image sound toonzqt tnztools tnzstdfx tfarm tnzcore tnzbase toonzlib colorfx tnzext image sound toonzqt tnztools tnzstdfx tfarm
) )
elseif(BUILD_ENV_APPLE) elseif(BUILD_ENV_APPLE AND WITH_CANON)
find_library(COCOA_LIB Cocoa) find_library(COCOA_LIB Cocoa)
_find_toonz_library(EXTRA_LIBS "tnzcore;tnzbase;toonzlib;colorfx;tnzext;image;sound;toonzqt;tnztools") _find_toonz_library(EXTRA_LIBS "tnzcore;tnzbase;toonzlib;colorfx;tnzext;image;sound;toonzqt;tnztools")
@ -467,9 +467,22 @@ elseif(BUILD_ENV_APPLE)
# #
set(EXTRA_LIBS ${EXTRA_LIBS} "$<TARGET_FILE:tnzstdfx>" "$<TARGET_FILE:tfarm>") set(EXTRA_LIBS ${EXTRA_LIBS} "$<TARGET_FILE:tnzstdfx>" "$<TARGET_FILE:tfarm>")
if(WITH_CANON) add_dependencies(Tahoma2D tnzcore tnzbase toonzlib colorfx tnzext image sound toonzqt tnztools tnzstdfx tfarm)
set(EXTRA_LIBS ${EXTRA_LIBS} ${CANON_LIB})
endif() target_link_libraries(Tahoma2D
Qt5::Core Qt5::Gui Qt5::Network Qt5::OpenGL Qt5::Svg Qt5::Xml
Qt5::Script Qt5::Widgets Qt5::PrintSupport Qt5::Multimedia Qt5::MultimediaWidgets Qt5::SerialPort
${GL_LIB} ${GLUT_LIB} ${CANON_LIB} ${TURBOJPEG_LIB} ${OpenCV_LIBS}
${COCOA_LIB} ${EXTRA_LIBS} mousedragfilter
)
elseif(BUILD_ENV_APPLE)
find_library(COCOA_LIB Cocoa)
_find_toonz_library(EXTRA_LIBS "tnzcore;tnzbase;toonzlib;colorfx;tnzext;image;sound;toonzqt;tnztools")
#
set(EXTRA_LIBS ${EXTRA_LIBS} "$<TARGET_FILE:tnzstdfx>" "$<TARGET_FILE:tfarm>")
add_dependencies(Tahoma2D tnzcore tnzbase toonzlib colorfx tnzext image sound toonzqt tnztools tnzstdfx tfarm) add_dependencies(Tahoma2D tnzcore tnzbase toonzlib colorfx tnzext image sound toonzqt tnztools tnzstdfx tfarm)

View file

@ -1 +1 @@
Web: https://turtletooth.com/ Web: https://tahoma2d.org

View file

@ -131,6 +131,8 @@ void deleteCellsWithoutUndo(int &r0, int &c0, int &r1, int &c1) {
port->setFx(0); port->setFx(0);
} }
} }
xsh->getStageObjectTree()->removeStageObject(
TStageObjectId::ColumnId(c));
} }
} }
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
@ -156,6 +158,7 @@ void cutCellsWithoutUndo(int &r0, int &c0, int &r1, int &c1) {
TFxPort *port = fx->getOutputConnection(i); TFxPort *port = fx->getOutputConnection(i);
port->setFx(0); port->setFx(0);
} }
xsh->getStageObjectTree()->removeStageObject(TStageObjectId::ColumnId(c));
} }
} }
@ -242,6 +245,8 @@ class DeleteCellsUndo final : public TUndo {
QMimeData *m_data; QMimeData *m_data;
QMap<int, QList<TFxPort *>> m_outputConnections; QMap<int, QList<TFxPort *>> m_outputConnections;
QMap<int, TXshColumn *> m_columns; QMap<int, TXshColumn *> m_columns;
QMap<TStageObjectId, QList<TStageObjectId>> m_columnObjChildren;
QMap<TStageObjectId, TStageObjectId> m_columnObjParents;
public: public:
DeleteCellsUndo(TCellSelection *selection, QMimeData *data) : m_data(data) { DeleteCellsUndo(TCellSelection *selection, QMimeData *data) : m_data(data) {
@ -263,6 +268,26 @@ public:
m_columns[i] = col; m_columns[i] = col;
col->addRef(); col->addRef();
} }
// Store TStageObject children in case column is emptied and we need to
// restore it
int pegbarsCount = xsh->getStageObjectTree()->getStageObjectCount();
TStageObjectId id = TStageObjectId::ColumnId(i);
TStageObject *pegbar = xsh->getStageObject(id);
for (int k = 0; k < pegbarsCount; ++k) {
TStageObject *other = xsh->getStageObjectTree()->getStageObject(k);
if (other == pegbar) continue;
if (other->getParent() == id) {
// other->setParent(pegbar->getParent());
m_columnObjChildren[id].append(other->getId());
}
}
// Store TStageObject parent in case column is emptied and we need to
// restore it
m_columnObjParents[id] = pegbar->getParent();
TFx *fx = col->getFx(); TFx *fx = col->getFx();
if (!fx) continue; if (!fx) continue;
int j; int j;
@ -304,10 +329,35 @@ public:
for (i = 0; i < fxPorts.size(); i++) fxPorts[i]->setFx(col->getFx()); for (i = 0; i < fxPorts.size(); i++) fxPorts[i]->setFx(col->getFx());
} }
// Restore TStageObject parent
QMap<TStageObjectId, TStageObjectId>::const_iterator it2;
for (it2 = m_columnObjParents.begin(); it2 != m_columnObjParents.end();
it2++) { // Parents
TStageObject *obj = xsh->getStageObject(it2.key());
if (obj) {
obj->setParent(it2.value());
}
}
// Restore TStageObject children
QMap<TStageObjectId, QList<TStageObjectId>>::const_iterator it3;
for (it3 = m_columnObjChildren.begin(); it3 != m_columnObjChildren.end();
it3++) { // Children
QList<TStageObjectId> children = it3.value();
int i;
for (i = 0; i < children.size(); i++) {
TStageObject *child = xsh->getStageObject(children[i]);
if (child) {
child->setParent(it3.key());
}
}
}
const TCellData *cellData = dynamic_cast<const TCellData *>(m_data); const TCellData *cellData = dynamic_cast<const TCellData *>(m_data);
pasteCellsWithoutUndo(cellData, r0, c0, r1, c1, false, false); pasteCellsWithoutUndo(cellData, r0, c0, r1, c1, false, false);
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
TApp::instance()->getCurrentObject()->notifyObjectIdSwitched();
} }
void redo() const override { void redo() const override {
@ -330,6 +380,8 @@ class CutCellsUndo final : public TUndo {
TCellSelection *m_selection; TCellSelection *m_selection;
TCellData *m_data; TCellData *m_data;
QMap<int, QList<TFxPort *>> m_outputConnections; QMap<int, QList<TFxPort *>> m_outputConnections;
QMap<TStageObjectId, QList<TStageObjectId>> m_columnObjChildren;
QMap<TStageObjectId, TStageObjectId> m_columnObjParents;
public: public:
CutCellsUndo(TCellSelection *selection) : m_data() { CutCellsUndo(TCellSelection *selection) : m_data() {
@ -344,6 +396,26 @@ public:
for (i = c0; i <= c1; i++) { for (i = c0; i <= c1; i++) {
TXshColumn *col = xsh->getColumn(i); TXshColumn *col = xsh->getColumn(i);
if (!col || col->isEmpty()) continue; if (!col || col->isEmpty()) continue;
// Store TStageObject children in case column is emptied and we need to
// restore it
int pegbarsCount = xsh->getStageObjectTree()->getStageObjectCount();
TStageObjectId id = TStageObjectId::ColumnId(i);
TStageObject *pegbar = xsh->getStageObject(id);
for (int k = 0; k < pegbarsCount; ++k) {
TStageObject *other = xsh->getStageObjectTree()->getStageObject(k);
if (other == pegbar) continue;
if (other->getParent() == id) {
// other->setParent(pegbar->getParent());
m_columnObjChildren[id].append(other->getId());
}
}
// Store TStageObject parent in case column is emptied and we need to
// restore it
m_columnObjParents[id] = pegbar->getParent();
TFx *fx = col->getFx(); TFx *fx = col->getFx();
if (!fx) continue; if (!fx) continue;
int j; int j;
@ -380,8 +452,33 @@ public:
for (i = 0; i < fxPorts.size(); i++) fxPorts[i]->setFx(col->getFx()); for (i = 0; i < fxPorts.size(); i++) fxPorts[i]->setFx(col->getFx());
} }
// Restore TStageObject parent
QMap<TStageObjectId, TStageObjectId>::const_iterator it2;
for (it2 = m_columnObjParents.begin(); it2 != m_columnObjParents.end();
it2++) { // Parents
TStageObject *obj = xsh->getStageObject(it2.key());
if (obj) {
obj->setParent(it2.value());
}
}
// Restore TStageObject children
QMap<TStageObjectId, QList<TStageObjectId>>::const_iterator it3;
for (it3 = m_columnObjChildren.begin(); it3 != m_columnObjChildren.end();
it3++) { // Children
QList<TStageObjectId> children = it3.value();
int i;
for (i = 0; i < children.size(); i++) {
TStageObject *child = xsh->getStageObject(children[i]);
if (child) {
child->setParent(it3.key());
}
}
}
pasteCellsWithoutUndo(m_data, r0, c0, r1, c1, true); pasteCellsWithoutUndo(m_data, r0, c0, r1, c1, true);
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
TApp::instance()->getCurrentObject()->notifyObjectIdSwitched();
} }
void redo() const override { void redo() const override {
@ -2613,6 +2710,8 @@ void TCellSelection::createBlankDrawing(int row, int col, bool multiple) {
ToolHandle *toolHandle = TApp::instance()->getCurrentTool(); ToolHandle *toolHandle = TApp::instance()->getCurrentTool();
//----- Going to cheat a little. Use autocreate rules to help create what we
// need
// If autocreate disabled, let's turn it on temporarily // If autocreate disabled, let's turn it on temporarily
bool isAutoCreateEnabled = Preferences::instance()->isAutoCreateEnabled(); bool isAutoCreateEnabled = Preferences::instance()->isAutoCreateEnabled();
if (!isAutoCreateEnabled) if (!isAutoCreateEnabled)
@ -2622,6 +2721,7 @@ void TCellSelection::createBlankDrawing(int row, int col, bool multiple) {
Preferences::instance()->isCreationInHoldCellsEnabled(); Preferences::instance()->isCreationInHoldCellsEnabled();
if (!isCreationInHoldCellsEnabled) if (!isCreationInHoldCellsEnabled)
Preferences::instance()->setValue(EnableCreationInHoldCells, true, false); Preferences::instance()->setValue(EnableCreationInHoldCells, true, false);
//------------------
TImage *img = toolHandle->getTool()->touchImage(); TImage *img = toolHandle->getTool()->touchImage();
@ -2629,11 +2729,13 @@ void TCellSelection::createBlankDrawing(int row, int col, bool multiple) {
TXshSimpleLevel *sl = cell.getSimpleLevel(); TXshSimpleLevel *sl = cell.getSimpleLevel();
if (!img || !sl) { if (!img || !sl) {
//----- Restore previous states of autocreation
if (!isAutoCreateEnabled) if (!isAutoCreateEnabled)
Preferences::instance()->setValue(EnableAutocreation, false, false); Preferences::instance()->setValue(EnableAutocreation, false, false);
if (!isCreationInHoldCellsEnabled) if (!isCreationInHoldCellsEnabled)
Preferences::instance()->setValue(EnableCreationInHoldCells, false, Preferences::instance()->setValue(EnableCreationInHoldCells, false,
false); false);
//------------------
if (!multiple) if (!multiple)
DVGui::warning(QObject::tr( DVGui::warning(QObject::tr(
"Unable to create a blank drawing on the current column")); "Unable to create a blank drawing on the current column"));
@ -2641,11 +2743,13 @@ void TCellSelection::createBlankDrawing(int row, int col, bool multiple) {
} }
if (!toolHandle->getTool()->m_isFrameCreated) { if (!toolHandle->getTool()->m_isFrameCreated) {
//----- Restore previous states of autocreation
if (!isAutoCreateEnabled) if (!isAutoCreateEnabled)
Preferences::instance()->setValue(EnableAutocreation, false, false); Preferences::instance()->setValue(EnableAutocreation, false, false);
if (!isCreationInHoldCellsEnabled) if (!isCreationInHoldCellsEnabled)
Preferences::instance()->setValue(EnableCreationInHoldCells, false, Preferences::instance()->setValue(EnableCreationInHoldCells, false,
false); false);
//------------------
if (!multiple) if (!multiple)
DVGui::warning(QObject::tr( DVGui::warning(QObject::tr(
"Unable to replace the current drawing with a blank drawing")); "Unable to replace the current drawing with a blank drawing"));
@ -2663,11 +2767,12 @@ void TCellSelection::createBlankDrawing(int row, int col, bool multiple) {
IconGenerator::instance()->invalidate(sl, frame); IconGenerator::instance()->invalidate(sl, frame);
// Reset back to what these were //----- Restore previous states of autocreation
if (!isAutoCreateEnabled) if (!isAutoCreateEnabled)
Preferences::instance()->setValue(EnableAutocreation, false, false); Preferences::instance()->setValue(EnableAutocreation, false, false);
if (!isCreationInHoldCellsEnabled) if (!isCreationInHoldCellsEnabled)
Preferences::instance()->setValue(EnableCreationInHoldCells, false, false); Preferences::instance()->setValue(EnableCreationInHoldCells, false, false);
//------------------
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -2764,6 +2869,8 @@ void TCellSelection::duplicateFrame(int row, int col, bool multiple) {
ToolHandle *toolHandle = TApp::instance()->getCurrentTool(); ToolHandle *toolHandle = TApp::instance()->getCurrentTool();
//----- Going to cheat a little. Use autocreate rules to help create what we
// need
// If autocreate disabled, let's turn it on temporarily // If autocreate disabled, let's turn it on temporarily
bool isAutoCreateEnabled = Preferences::instance()->isAutoCreateEnabled(); bool isAutoCreateEnabled = Preferences::instance()->isAutoCreateEnabled();
if (!isAutoCreateEnabled) if (!isAutoCreateEnabled)
@ -2773,14 +2880,17 @@ void TCellSelection::duplicateFrame(int row, int col, bool multiple) {
Preferences::instance()->isCreationInHoldCellsEnabled(); Preferences::instance()->isCreationInHoldCellsEnabled();
if (!isCreationInHoldCellsEnabled) if (!isCreationInHoldCellsEnabled)
Preferences::instance()->setValue(EnableCreationInHoldCells, true, false); Preferences::instance()->setValue(EnableCreationInHoldCells, true, false);
//------------------
TImage *img = toolHandle->getTool()->touchImage(); TImage *img = toolHandle->getTool()->touchImage();
if (!img) { if (!img) {
//----- Restore previous states of autocreation
if (!isAutoCreateEnabled) if (!isAutoCreateEnabled)
Preferences::instance()->setValue(EnableAutocreation, false, false); Preferences::instance()->setValue(EnableAutocreation, false, false);
if (!isCreationInHoldCellsEnabled) if (!isCreationInHoldCellsEnabled)
Preferences::instance()->setValue(EnableCreationInHoldCells, false, Preferences::instance()->setValue(EnableCreationInHoldCells, false,
false); false);
//------------------
if (!multiple) if (!multiple)
DVGui::warning( DVGui::warning(
QObject::tr("Unable to duplicate a drawing on the current column")); QObject::tr("Unable to duplicate a drawing on the current column"));
@ -2789,11 +2899,13 @@ void TCellSelection::duplicateFrame(int row, int col, bool multiple) {
bool frameCreated = toolHandle->getTool()->m_isFrameCreated; bool frameCreated = toolHandle->getTool()->m_isFrameCreated;
if (!frameCreated) { if (!frameCreated) {
//----- Restore previous states of autocreation
if (!isAutoCreateEnabled) if (!isAutoCreateEnabled)
Preferences::instance()->setValue(EnableAutocreation, false, false); Preferences::instance()->setValue(EnableAutocreation, false, false);
if (!isCreationInHoldCellsEnabled) if (!isCreationInHoldCellsEnabled)
Preferences::instance()->setValue(EnableCreationInHoldCells, false, Preferences::instance()->setValue(EnableCreationInHoldCells, false,
false); false);
//------------------
if (!multiple) if (!multiple)
DVGui::warning( DVGui::warning(
QObject::tr("Unable to replace the current or next drawing with a " QObject::tr("Unable to replace the current or next drawing with a "
@ -2815,10 +2927,12 @@ void TCellSelection::duplicateFrame(int row, int col, bool multiple) {
new DuplicateDrawingUndo(sl, srcFrame, targetFrame); new DuplicateDrawingUndo(sl, srcFrame, targetFrame);
TUndoManager::manager()->add(undo); TUndoManager::manager()->add(undo);
//----- Restore previous states of autocreation
if (!isAutoCreateEnabled) if (!isAutoCreateEnabled)
Preferences::instance()->setValue(EnableAutocreation, false, false); Preferences::instance()->setValue(EnableAutocreation, false, false);
if (!isCreationInHoldCellsEnabled) if (!isCreationInHoldCellsEnabled)
Preferences::instance()->setValue(EnableCreationInHoldCells, false, false); Preferences::instance()->setValue(EnableCreationInHoldCells, false, false);
//------------------
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View file

@ -488,9 +488,8 @@ void FilmstripFrames::hideEvent(QHideEvent *) {
// if the level strip is floating during shutting down Tahoma2D // if the level strip is floating during shutting down Tahoma2D
// it can cause a crash disconnecting from the viewer which was already // it can cause a crash disconnecting from the viewer which was already
// destroyed. Checking the fps is a janky way to ensure the viewer is // destroyed.
// stil relevant. if (m_viewer && m_viewer->isValid()) {
if (m_viewer && m_viewer->getFPS() > -100) {
disconnect(m_viewer, SIGNAL(onZoomChanged()), this, SLOT(update())); disconnect(m_viewer, SIGNAL(onZoomChanged()), this, SLOT(update()));
disconnect(m_viewer, SIGNAL(refreshNavi()), this, SLOT(update())); disconnect(m_viewer, SIGNAL(refreshNavi()), this, SLOT(update()));
m_viewer = nullptr; m_viewer = nullptr;

View file

@ -328,26 +328,6 @@ int main(int argc, char *argv[]) {
argc = 1; argc = 1;
} }
// Toonz environment
initToonzEnv(argumentPathValues);
#ifdef WITH_CRASHRPT
CR_INSTALL_INFO pInfo;
memset(&pInfo, 0, sizeof(CR_INSTALL_INFO));
pInfo.cb = sizeof(CR_INSTALL_INFO);
pInfo.pszAppName = convertToLPCWSTR(TEnv::getApplicationName());
pInfo.pszAppVersion = convertToLPCWSTR(TEnv::getApplicationVersion());
TFilePath crashrptCache =
ToonzFolder::getCacheRootFolder() + TFilePath("crashrpt");
pInfo.pszErrorReportSaveDir =
convertToLPCWSTR(crashrptCache.getQString().toStdString());
// Install all available exception handlers.
// Don't send reports automaticall, store locally
pInfo.dwFlags |= CR_INST_ALL_POSSIBLE_HANDLERS | CR_INST_DONT_SEND_REPORT;
crInstall(&pInfo);
#endif
// Enables high-DPI scaling. This attribute must be set before QApplication is // Enables high-DPI scaling. This attribute must be set before QApplication is
// constructed. Available from Qt 5.6. // constructed. Available from Qt 5.6.
#if QT_VERSION >= 0x050600 #if QT_VERSION >= 0x050600
@ -511,6 +491,26 @@ int main(int argc, char *argv[]) {
TBigMemoryManager::instance()->setRunOutOfContiguousMemoryHandler( TBigMemoryManager::instance()->setRunOutOfContiguousMemoryHandler(
&toonzRunOutOfContMemHandler); &toonzRunOutOfContMemHandler);
// Toonz environment
initToonzEnv(argumentPathValues);
#ifdef WITH_CRASHRPT
CR_INSTALL_INFO pInfo;
memset(&pInfo, 0, sizeof(CR_INSTALL_INFO));
pInfo.cb = sizeof(CR_INSTALL_INFO);
pInfo.pszAppName = convertToLPCWSTR(TEnv::getApplicationName());
pInfo.pszAppVersion = convertToLPCWSTR(TEnv::getApplicationVersion());
TFilePath crashrptCache =
ToonzFolder::getCacheRootFolder() + TFilePath("crashrpt");
pInfo.pszErrorReportSaveDir =
convertToLPCWSTR(crashrptCache.getQString().toStdString());
// Install all available exception handlers.
// Don't send reports automaticall, store locally
pInfo.dwFlags |= CR_INST_ALL_POSSIBLE_HANDLERS | CR_INST_DONT_SEND_REPORT;
crInstall(&pInfo);
#endif
// Initialize thread components // Initialize thread components
TThread::init(); TThread::init();

View file

@ -1195,7 +1195,7 @@ void MainWindow::onOpenReportABug() {
int ret = DVGui::MsgBox(DVGui::INFORMATION, str, buttons, 1); int ret = DVGui::MsgBox(DVGui::INFORMATION, str, buttons, 1);
if (ret == 1) if (ret == 1)
QDesktopServices::openUrl( QDesktopServices::openUrl(
QUrl("https://github.com/turtletooth/tahoma2d/issues")); QUrl("https://github.com/tahoma2d/tahoma2d/issues"));
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1481,7 +1481,7 @@ void MainWindow::onUpdateCheckerDone(bool error) {
if (ret == 1) { if (ret == 1) {
// Write the new last date to file // Write the new last date to file
QDesktopServices::openUrl(QObject::tr( QDesktopServices::openUrl(QObject::tr(
"https://github.com/turtletooth/tahoma2d/releases/latest")); "https://github.com/tahoma2d/tahoma2d/releases/latest"));
} }
} }

View file

@ -1002,7 +1002,9 @@ void OutputSettingsPopup::updateField() {
if (!m_isPreviewSettings) { if (!m_isPreviewSettings) {
TFilePath path = prop->getPath(); TFilePath path = prop->getPath();
QString name = QString::fromStdWString(path.getWideName()); QString name = path.withoutParentDir().getQString();
name = QString::fromStdString(name.toStdString().substr(
0, name.length() - path.getDottedType().length()));
if (name.isEmpty()) if (name.isEmpty())
name = QString::fromStdString(scene->getScenePath().getName()); name = QString::fromStdString(scene->getScenePath().getName());
m_saveInFileFld->setPath(toQString(path.getParentDir())); m_saveInFileFld->setPath(toQString(path.getParentDir()));
@ -1204,7 +1206,7 @@ void OutputSettingsPopup::onNameChanged() {
if (fp.getWideName() == wname) return; // Already had the right name if (fp.getWideName() == wname) return; // Already had the right name
fp = fp.withName(wname); fp = fp.getParentDir() + TFilePath(wname).withType(fp.getType());
prop->setPath(fp); prop->setPath(fp);
TApp::instance()->getCurrentScene()->setDirtyFlag(true); TApp::instance()->getCurrentScene()->setDirtyFlag(true);

View file

@ -1082,6 +1082,8 @@ QString PreferencesPopup::getUIString(PreferencesItemId id) {
{cursorOutlineEnabled, tr("Show Cursor Size Outlines")}, {cursorOutlineEnabled, tr("Show Cursor Size Outlines")},
{levelBasedToolsDisplay, tr("Toolbar Display Behaviour:")}, {levelBasedToolsDisplay, tr("Toolbar Display Behaviour:")},
{useCtrlAltToResizeBrush, tr("Use Ctrl+Alt to Resize Brush")}, {useCtrlAltToResizeBrush, tr("Use Ctrl+Alt to Resize Brush")},
{temptoolswitchtimer,
tr("Temporary Tool Switch Shortcut Hold Time (ms):")},
// Xsheet // Xsheet
{xsheetLayoutPreference, tr("Column Header Layout*:")}, {xsheetLayoutPreference, tr("Column Header Layout*:")},
@ -1656,13 +1658,16 @@ QWidget* PreferencesPopup::createDrawingPage() {
insertUI(newLevelSizeToCameraSizeEnabled, lay); insertUI(newLevelSizeToCameraSizeEnabled, lay);
insertDualUIs(DefLevelWidth, DefLevelHeight, lay); insertDualUIs(DefLevelWidth, DefLevelHeight, lay);
// insertUI(DefLevelDpi, lay); // insertUI(DefLevelDpi, lay);
QGridLayout* creationLay = insertGroupBox(
tr("Frame Creation Options"), lay);
{
insertUI(NumberingSystem, creationLay, getComboItemList(NumberingSystem));
insertUI(EnableAutoStretch, creationLay);
insertUI(EnableAutoRenumber, creationLay);
}
QGridLayout* autoCreationLay = insertGroupBoxUI(EnableAutocreation, lay); QGridLayout* autoCreationLay = insertGroupBoxUI(EnableAutocreation, lay);
{ {
insertUI(NumberingSystem, autoCreationLay,
getComboItemList(NumberingSystem));
insertUI(EnableAutoStretch, autoCreationLay);
insertUI(EnableCreationInHoldCells, autoCreationLay); insertUI(EnableCreationInHoldCells, autoCreationLay);
insertUI(EnableAutoRenumber, autoCreationLay);
} }
insertUI(vectorSnappingTarget, lay, getComboItemList(vectorSnappingTarget)); insertUI(vectorSnappingTarget, lay, getComboItemList(vectorSnappingTarget));
insertUI(saveUnpaintedInCleanup, lay); insertUI(saveUnpaintedInCleanup, lay);
@ -1716,6 +1721,7 @@ QWidget* PreferencesPopup::createToolsPage() {
insertUI(levelBasedToolsDisplay, lay, insertUI(levelBasedToolsDisplay, lay,
getComboItemList(levelBasedToolsDisplay)); getComboItemList(levelBasedToolsDisplay));
// insertUI(useCtrlAltToResizeBrush, lay); // insertUI(useCtrlAltToResizeBrush, lay);
insertUI(temptoolswitchtimer, lay);
lay->setRowStretch(lay->rowCount(), 1); lay->setRowStretch(lay->rowCount(), 1);
widget->setLayout(lay); widget->setLayout(lay);

View file

@ -15,12 +15,14 @@
#include "toonz/tobjecthandle.h" #include "toonz/tobjecthandle.h"
#include "toonzqt/tselectionhandle.h" #include "toonzqt/tselectionhandle.h"
#include "toonzqt/selection.h" #include "toonzqt/selection.h"
#include "toonz/tstageobjecttree.h" #include "toonzqt/gutil.h"
#include "tools/tool.h" #include "tools/tool.h"
#include "tools/toolhandle.h" #include "tools/toolhandle.h"
#include "tproperty.h"
#include <QLayout> #include <QLayout>
#include <QLabel> #include <QLabel>
@ -32,7 +34,7 @@ StatusBar::StatusBar(QWidget* parent) : QStatusBar(parent) {
m_infoLabel = new StatusLabel(tr("Info goes here."), this); m_infoLabel = new StatusLabel(tr("Info goes here."), this);
m_infoLabel->setObjectName("MainWindowPlainLabel"); m_infoLabel->setObjectName("MainWindowPlainLabel");
m_infoLabel->setMinimumWidth(1); m_infoLabel->setMinimumWidth(1);
addWidget(m_infoLabel, 0); addWidget(m_infoLabel, 1);
addPermanentWidget(m_currentFrameLabel, 0); addPermanentWidget(m_currentFrameLabel, 0);
TApp* app = TApp::instance(); TApp* app = TApp::instance();
@ -53,7 +55,8 @@ StatusBar::StatusBar(QWidget* parent) : QStatusBar(parent) {
assert(ret); assert(ret);
makeMap(); m_infoMap = makeMap(tr(" "), tr(" - "), tr(" - "));
m_hintMap = makeMap(tr("\n "), tr("\t- "), tr("\t\t- "));
updateInfoText(); updateInfoText();
} }
@ -99,134 +102,270 @@ void StatusBar::updateInfoText() {
bool isRaster = false; bool isRaster = false;
bool isVector = false; bool isVector = false;
bool isSmartRaster = false; bool isSmartRaster = false;
bool isEmpty = false; std::string nameLevel = "";
std::string namePlus = ""; std::string nameMode = "";
if (type >= 0) { if (type >= 0) {
if (type == TXshLevelType::PLI_XSHLEVEL) { if (type == TXshLevelType::PLI_XSHLEVEL) {
isVector = true; isVector = true;
namePlus = "Vector"; nameLevel = "Vector";
} else if (type == TXshLevelType::TZP_XSHLEVEL) { } else if (type == TXshLevelType::TZP_XSHLEVEL) {
isSmartRaster = true; isSmartRaster = true;
namePlus = "SmartRaster"; nameLevel = "SmartRaster";
} else if (type == TXshLevelType::OVL_XSHLEVEL) { } else if (type == TXshLevelType::OVL_XSHLEVEL) {
isRaster = true; isRaster = true;
namePlus = "Raster"; nameLevel = "Raster";
} else if (type == NO_XSHLEVEL)
isEmpty = true;
} }
QString text = "";
if (m_infoMap.find(name + namePlus) != m_infoMap.end()) {
text += m_infoMap[name + namePlus];
int i = 0;
i++;
} else if (m_infoMap.find(name) != m_infoMap.end()) {
text += m_infoMap[name];
int i = 0;
i++;
} }
if (name == "T_Geometric") {
TPropertyGroup* props = tool->getProperties(0);
nameMode = props->getProperty("Shape:")->getValueAsString();
}
QString text = "";
if (m_infoMap.find(name + nameLevel + nameMode) != m_infoMap.end())
text += m_infoMap[name + nameLevel + nameMode];
else if (m_infoMap.find(name + nameLevel) != m_infoMap.end())
text += m_infoMap[name + nameLevel];
else if (m_infoMap.find(name + nameMode) != m_infoMap.end())
text += m_infoMap[name + nameMode];
else if (m_infoMap.find(name) != m_infoMap.end())
text += m_infoMap[name];
QString hintText = "";
if (m_hintMap.find(name + nameLevel + nameMode) != m_hintMap.end())
hintText += m_hintMap[name + nameLevel + nameMode];
else if (m_hintMap.find(name + nameLevel) != m_hintMap.end())
hintText += m_hintMap[name + nameLevel];
else if (m_hintMap.find(name + nameMode) != m_hintMap.end())
hintText += m_hintMap[name + nameMode];
else if (m_hintMap.find(name) != m_hintMap.end())
hintText += m_hintMap[name];
m_infoLabel->setToolTip(hintText);
m_infoLabel->setText(text); m_infoLabel->setText(text);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
QString trModKey(QString key) {
#ifdef MACOSX
// Convert Windows key modifier to macOS modifier
if (key == "Ctrl") // Command
return QString::fromStdWString(L"\u2318");
else if (key == "Shift")
return QString::fromStdWString(L"\u21e7");
else if (key == "Alt")
return QString::fromStdWString(L"\u2325");
// else if (key == "???") // Control
// return QString::fromStdWString(L"\u2303");
#endif
void StatusBar::makeMap() { return key;
QString spacer = " "; }
// tools
m_infoMap.insert({"T_Hand", "<b>Hand Tool:</b> Pans the workspace"}); std::unordered_map<std::string, QString> StatusBar::makeMap(
m_infoMap.insert( QString spacer, QString cmdTextSeparator, QString cmd2TextSeparator) {
{"T_Selection", std::unordered_map<std::string, QString> lMap;
"Selection Tool: Select parts of your image to transform it."});
m_infoMap.insert({"T_Edit", #ifdef MACOSX
"Animate Tool: Modifies the position, rotation and size of " // on macOS, we display symbols. No need to space differently
"the current column"}); cmd2TextSeparator = cmdTextSeparator;
m_infoMap.insert({"T_Brush", "Brush Tool: Draws in the work area freehand"}); #endif
m_infoMap.insert(
{"T_BrushVector", "Brush Tool: Draws in the work area freehand" + spacer + // tools
"Shift - Straight Lines" + spacer + lMap.insert({"T_Hand", tr("Hand Tool: Pans the workspace")});
#ifdef MACOSX lMap.insert(
"Cmd - Straight Lines Snapped to Angles" + spacer + {"T_Selection",
"Cmd + Opt - Add / Remove Vanishing Point" + tr("Selection Tool: Select parts of your image to transform it") +
spacer + "Opt - Draw to Vanishing Point" + spacer + spacer +
"Hold Cmd + Shift - Toggle Snapping"}); tr("%1%2Scale / Directional scale")
#else .arg(trModKey("Shift"))
"Control - Straight Lines Snapped to Angles" + .arg(cmd2TextSeparator) +
spacer + spacer +
"Ctrl + Alt - Add / Remove Vanishing Point" + tr("%1%2Distort / Shear")
spacer + "Alt - Draw to Vanishing Point" + spacer + .arg(trModKey("Ctrl"))
"Hold Ctrl + Shift - Toggle Snapping"}); .arg(cmd2TextSeparator) +
#endif spacer +
m_infoMap.insert({"T_BrushSmartRaster", tr("%1%2Scale Symmetrically from Center")
"Brush Tool: Draws in the work area freehand" + spacer + .arg(trModKey("Alt"))
"Shift - Straight Lines" + spacer + .arg(cmd2TextSeparator) +
#ifdef MACOSX spacer +
"Cmd - Straight Lines Snapped to Angles" + spacer + tr("%1%2Scale Symmetrically from Center w/ Proportion Lock")
"Cmd + Opt - Add / Remove Vanishing Point" + spacer + .arg(trModKey("Shift") + "+" + trModKey("Alt"))
"Opt - Draw to Vanishing Point"}); .arg(cmdTextSeparator)});
#else lMap.insert({"T_Edit", tr("Animate Tool: Modifies the position, "
"Control - Straight Lines Snapped to Angles" + spacer + "rotation and size of the current column")});
"Ctrl + Alt - Add / Remove Vanishing Point" + spacer + lMap.insert({"T_Brush", tr("Brush Tool: Draws in the work area freehand")});
"Alt - Draw to Vanishing Point"}); lMap.insert({"T_BrushVector",
#endif tr("Brush Tool : Draws in the work area freehand") + spacer +
m_infoMap.insert( tr("%1%2Straight Lines")
{"T_BrushRaster", "Brush Tool: Draws in the work area freehand" + spacer + .arg(trModKey("Shift"))
"Shift - Straight Lines" + spacer + .arg(cmd2TextSeparator) +
#ifdef MACOSX spacer +
"Cmd - Straight Lines Snapped to Angles" + spacer + tr("%1%2Straight Lines Snapped to Angles")
"Cmd + Opt - Add / Remove Vanishing Point" + .arg(trModKey("Ctrl"))
spacer + "Opt - Draw to Vanishing Point"}); .arg(cmd2TextSeparator) +
#else spacer +
"Control - Straight Lines Snapped to Angles" + tr("%1%2Add / Remove Vanishing Point")
spacer + .arg(trModKey("Ctrl") + "+" + trModKey("Alt"))
"Ctrl + Alt - Add / Remove Vanishing Point" + .arg(cmdTextSeparator) +
spacer + "Alt - Draw to Vanishing Point"}); spacer +
#endif tr("%1%2Draw to Vanishing Point")
m_infoMap.insert({"T_Geometric", "Geometry Tool: Draws geometric shapes"}); .arg(trModKey("Alt"))
m_infoMap.insert( .arg(cmd2TextSeparator) +
{"T_GeometricVector", "Geometry Tool: Draws geometric shapes" + spacer + spacer +
#ifdef MACOSX tr("%1%2Allow or Disallow Snapping")
"Hold Cmd + Shift - Toggle Snapping"}); .arg(trModKey("Ctrl") + "+" + trModKey("Shift"))
#else .arg(cmdTextSeparator)});
"Hold Ctrl + Shift - Toggle Snapping"}); lMap.insert({"T_BrushSmartRaster",
#endif tr("Brush Tool : Draws in the work area freehand") + spacer +
m_infoMap.insert({"T_Type", "Type Tool: Adds text"}); tr("%1%2Straight Lines")
m_infoMap.insert( .arg(trModKey("Shift"))
{"T_PaintBrush", .arg(cmd2TextSeparator) +
"Smart Raster Painter: Paints areas in Smart Raster leves"}); spacer +
m_infoMap.insert( tr("%1%2Straight Lines Snapped to Angles")
{"T_Fill", "Fill Tool: Fills drawing areas with the current style"}); .arg(trModKey("Ctrl"))
m_infoMap.insert({"T_Eraser", "Eraser: Erases lines and areas"}); .arg(cmd2TextSeparator) +
m_infoMap.insert( spacer +
{"T_Tape", "Tape Tool: Closes gaps in raster, joins edges in vector"}); tr("%1%2Add / Remove Vanishing Point")
m_infoMap.insert( .arg(trModKey("Ctrl") + "+" + trModKey("Alt"))
{"T_StylePicker", "Style Picker: Selects style on current drawing"}); .arg(cmdTextSeparator) +
m_infoMap.insert( spacer +
{"T_RGBPicker", tr("%1%2Draw to Vanishing Point")
"RGB Picker: Picks color on screen and applies to current style"}); .arg(trModKey("Alt"))
m_infoMap.insert({"T_ControlPointEditor", .arg(cmd2TextSeparator)});
"Control Point Editor: Modifies vector lines by editing " lMap.insert({"T_BrushRaster",
"its control points"}); tr("Brush Tool : Draws in the work area freehand") + spacer +
m_infoMap.insert({"T_Pinch", "Pinch Tool: Pulls vector drawings"}); tr("%1%2Straight Lines")
m_infoMap.insert({"T_Pump", "Pump Tool: Changes vector thickness"}); .arg(trModKey("Shift"))
m_infoMap.insert({"T_Magnet", "Magnet Tool: Deforms vector lines"}); .arg(cmd2TextSeparator) +
m_infoMap.insert( spacer +
{"T_Bender", "Bend Tool: Bends vector shapes around the first click"}); tr("%1%2Straight Lines Snapped to Angles")
m_infoMap.insert({"T_Iron", "Iron Tool: Smooths vector lines"}); .arg(trModKey("Ctrl"))
m_infoMap.insert({"T_Cutter", "Cutter Tool: Splits vector lines"}); .arg(cmd2TextSeparator) +
m_infoMap.insert({"T_Hook", ""}); spacer +
m_infoMap.insert({"T_Skeleton", tr("%1%2Add / Remove Vanishing Point")
"Skeleton Tool: Allows to build a skeleton and animate in " .arg(trModKey("Ctrl") + "+" + trModKey("Alt"))
"a cut-out workflow"}); .arg(cmdTextSeparator) +
m_infoMap.insert( spacer +
{"T_Tracker", tr("%1%2Draw to Vanishing Point")
"Tracker: Tracks specific regions in a sequence of images"}); .arg(trModKey("Alt"))
m_infoMap.insert({"T_Plastic", .arg(cmd2TextSeparator)});
"Plastic Tool: Builds a mesh that allows to deform and " lMap.insert({"T_Geometric", tr("Geometry Tool: Draws geometric shapes")});
"animate a level"}); lMap.insert({"T_GeometricRectangle",
m_infoMap.insert({"T_Zoom", "Zoom Tool: Zooms viewer"}); tr("Geometry Tool: Draws geometric shapes") + spacer +
m_infoMap.insert({"T_Rotate", "Rotate Tool: Rotate the workspace"}); tr("%1%2Proportion Lock")
m_infoMap.insert({"T_Ruler", ""}); .arg(trModKey("Shift"))
m_infoMap.insert( .arg(cmdTextSeparator) +
{"T_Finger", "Finger Tool: Smudges small areas to cover with line"}); spacer +
m_infoMap.insert({"T_Dummy", "This tool doesn't work on this layer type."}); tr("%1%2Create From Center")
.arg(trModKey("Alt"))
.arg(cmdTextSeparator)});
lMap.insert({"T_GeometricEllipse",
tr("Geometry Tool: Draws geometric shapes") + spacer +
tr("%1%2Proportion Lock")
.arg(trModKey("Shift"))
.arg(cmdTextSeparator) +
spacer +
tr("%1%2Create From Center")
.arg(trModKey("Alt"))
.arg(cmdTextSeparator)});
lMap.insert(
{"T_GeometricPolyline",
tr("Geometry Tool: Draws geometric shapes") + spacer +
tr("%1%2Create Curve").arg(tr("Click+Drag")).arg(cmdTextSeparator) +
spacer +
tr("%1%2Return to Straight Line")
.arg(trModKey("Ctrl"))
.arg(cmd2TextSeparator) +
spacer +
tr("%1%2Snap to Angle")
.arg(trModKey("Shift"))
.arg(cmd2TextSeparator)});
lMap.insert({"T_GeometricVector",
tr("Geometry Tool: Draws geometric shapes") + spacer +
tr("%1%2Allow or Disallow Snapping")
.arg(trModKey("Ctrl") + "+" + trModKey("Shift"))
.arg(cmdTextSeparator)});
lMap.insert({"T_GeometricVectorRectangle",
tr("Geometry Tool: Draws geometric shapes") + spacer +
tr("%1%2Proportion Lock")
.arg(trModKey("Shift"))
.arg(cmd2TextSeparator) +
spacer +
tr("%1%2Create From Center")
.arg(trModKey("Alt"))
.arg(cmd2TextSeparator) +
spacer +
tr("%1%2Allow or Disallow Snapping")
.arg(trModKey("Ctrl") + "+" + trModKey("Shift"))
.arg(cmdTextSeparator)});
lMap.insert({"T_GeometricVectorEllipse",
tr("Geometry Tool: Draws geometric shapes") + spacer +
tr("%1%2Proportion Lock")
.arg(trModKey("Shift"))
.arg(cmd2TextSeparator) +
spacer +
tr("%1%2Create From Center")
.arg(trModKey("Alt"))
.arg(cmd2TextSeparator) +
spacer +
tr("%1%2Allow or Disallow Snapping")
.arg(trModKey("Ctrl") + "+" + trModKey("Shift"))
.arg(cmdTextSeparator)});
lMap.insert(
{"T_GeometricVectorPolyline",
tr("Geometry Tool: Draws geometric shapes") + spacer +
tr("%1%2Create Curve").arg(tr("Click+Drag")).arg(cmdTextSeparator) +
spacer +
tr("%1%2Return to Straight Line")
.arg(trModKey("Ctrl"))
.arg(cmd2TextSeparator) +
spacer +
tr("%1%2Snap to Angle")
.arg(trModKey("Shift"))
.arg(cmd2TextSeparator) +
spacer +
tr("%1%2Allow or Disallow Snapping")
.arg(trModKey("Ctrl") + "+" + trModKey("Shift"))
.arg(cmdTextSeparator)});
lMap.insert({"T_Type", tr("Type Tool: Adds text")});
lMap.insert({"T_PaintBrush",
tr("Smart Raster Painter: Paints areas in Smart Raster leves")});
lMap.insert(
{"T_Fill", tr("Fill Tool: Fills drawing areas with the current style")});
lMap.insert({"T_Eraser", tr("Eraser: Erases lines and areas")});
lMap.insert({"T_Tape",
tr("Tape Tool: Closes gaps in raster, joins edges in vector")});
lMap.insert(
{"T_StylePicker", tr("Style Picker: Selects style on current drawing")});
lMap.insert(
{"T_RGBPicker",
tr("RGB Picker: Picks color on screen and applies to current style")});
lMap.insert(
{"T_ControlPointEditor", tr("Control Point Editor: Modifies vector lines "
"by editing its control points")});
lMap.insert({"T_Pinch", tr("Pinch Tool: Pulls vector drawings")});
lMap.insert({"T_Pump", tr("Pump Tool: Changes vector thickness")});
lMap.insert({"T_Magnet", tr("Magnet Tool: Deforms vector lines")});
lMap.insert({"T_Bender",
tr("Bend Tool: Bends vector shapes around the first click")});
lMap.insert({"T_Iron", tr("Iron Tool: Smooths vector lines")});
lMap.insert({"T_Cutter", tr("Cutter Tool: Splits vector lines")});
lMap.insert({"T_Hook", ""});
lMap.insert(
{"T_Skeleton", tr("Skeleton Tool: Allows to build a skeleton and animate "
"in a cut-out workflow")});
lMap.insert({"T_Tracker",
tr("Tracker: Tracks specific regions in a sequence of images")});
lMap.insert({"T_Plastic", tr("Plastic Tool: Builds a mesh that allows "
"to deform and animate a level")});
lMap.insert({"T_Zoom", tr("Zoom Tool: Zooms viewer")});
lMap.insert({"T_Rotate", tr("Rotate Tool: Rotate the workspace")});
lMap.insert({"T_Ruler", tr("Ruler Tool: Measures distances on the canvas")});
lMap.insert(
{"T_Finger", tr("Finger Tool: Smudges small areas to cover with line")});
lMap.insert({"T_Dummy", tr("This tool doesn't work on this layer type.")});
return lMap;
} }

View file

@ -3,7 +3,7 @@
#ifndef STATUSBAR_H #ifndef STATUSBAR_H
#define STATUSBAR_H #define STATUSBAR_H
#include <QStatusBar>; #include <QStatusBar>
#include <unordered_map> #include <unordered_map>
#include <QLabel> #include <QLabel>
@ -32,11 +32,16 @@ public:
void updateFrameText(QString text); void updateFrameText(QString text);
void refreshStatusBar() { updateInfoText(); }
protected: protected:
StatusLabel *m_currentFrameLabel, *m_infoLabel; StatusLabel *m_currentFrameLabel, *m_infoLabel;
std::unordered_map<std::string, QString> m_infoMap; std::unordered_map<std::string, QString> m_infoMap;
std::unordered_map<std::string, QString> m_hintMap;
void showEvent(QShowEvent*) override; void showEvent(QShowEvent*) override;
void makeMap(); std::unordered_map<std::string, QString> makeMap(QString spacer,
QString cmdTextSeparator,
QString cmd2TextSeparator);
protected slots: protected slots:
void updateInfoText(); void updateInfoText();

View file

@ -869,6 +869,12 @@ void TApp::showMessage(QString message) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void TApp::refreshStatusBar() {
if (m_statusBar) m_statusBar->refreshStatusBar();
}
//-----------------------------------------------------------------------------
QString TApp::getCurrentRoomName() const { QString TApp::getCurrentRoomName() const {
Room *currentRoom = dynamic_cast<Room *>(getCurrentRoom()); Room *currentRoom = dynamic_cast<Room *>(getCurrentRoom());
if (!currentRoom) return QString(); if (!currentRoom) return QString();

View file

@ -216,6 +216,8 @@ public:
void setStatusBar(StatusBar *statusBar); void setStatusBar(StatusBar *statusBar);
void setStatusBarFrameInfo(QString text); void setStatusBarFrameInfo(QString text);
void refreshStatusBar() override;
protected: protected:
bool eventFilter(QObject *obj, QEvent *event) override; bool eventFilter(QObject *obj, QEvent *event) override;
bool m_showTitleBars = true; bool m_showTitleBars = true;

View file

@ -4,6 +4,7 @@
#include "menubarcommandids.h" #include "menubarcommandids.h"
#include "tapp.h" #include "tapp.h"
#include "sceneviewer.h" #include "sceneviewer.h"
#include "stopmotion.h"
// TnzQt includes // TnzQt includes
#include "toonzqt/menubarcommand.h" #include "toonzqt/menubarcommand.h"
@ -144,6 +145,10 @@ public:
int stopFrame = std::min(currentFrame, maxFrame); int stopFrame = std::min(currentFrame, maxFrame);
StopMotion *stopMotion = StopMotion::instance();
if (stopMotion->getPlaceOnXSheet() && stopMotion->m_liveViewStatus > 0)
stopFrame = StopMotion::instance()->getXSheetFrameNumber() - 1;
int startFrame = std::max(0, stopFrame - shortPlayFrameCount); int startFrame = std::max(0, stopFrame - shortPlayFrameCount);
TApp::instance()->getCurrentFrame()->setFrame(startFrame); TApp::instance()->getCurrentFrame()->setFrame(startFrame);

View file

@ -76,6 +76,7 @@
#include <QToolTip> #include <QToolTip>
#include <QApplication> #include <QApplication>
#include <QClipboard> #include <QClipboard>
#include <QKeyEvent>
namespace { namespace {
@ -558,7 +559,11 @@ namespace XsheetGUI {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
RenameCellField::RenameCellField(QWidget *parent, XsheetViewer *viewer) RenameCellField::RenameCellField(QWidget *parent, XsheetViewer *viewer)
: QLineEdit(parent), m_viewer(viewer), m_row(-1), m_col(-1) { : QLineEdit(parent)
, m_viewer(viewer)
, m_row(-1)
, m_col(-1)
, m_isRenamingCell(false) {
connect(this, SIGNAL(returnPressed()), SLOT(onReturnPressed())); connect(this, SIGNAL(returnPressed()), SLOT(onReturnPressed()));
setContextMenuPolicy(Qt::PreventContextMenu); setContextMenuPolicy(Qt::PreventContextMenu);
setObjectName("RenameCellField"); setObjectName("RenameCellField");
@ -884,24 +889,39 @@ void RenameCellField::renameCell() {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void RenameCellField::onReturnPressed() { void RenameCellField::moveCellSelection(int direction) {
renameCell();
// move the cell selection // move the cell selection
TCellSelection *cellSelection = dynamic_cast<TCellSelection *>( TCellSelection *cellSelection = dynamic_cast<TCellSelection *>(
TApp::instance()->getCurrentSelection()->getSelection()); TApp::instance()->getCurrentSelection()->getSelection());
if (!cellSelection) return; if (!cellSelection) return;
TCellSelection::Range range = cellSelection->getSelectedCells(); TCellSelection::Range range = cellSelection->getSelectedCells();
int offset = range.m_r1 - range.m_r0 + 1; int offset = range.m_r1 - range.m_r0 + direction;
if ((m_row + offset) < 0) return;
cellSelection->selectCells(range.m_r0 + offset, range.m_c0, cellSelection->selectCells(range.m_r0 + offset, range.m_c0,
range.m_r1 + offset, range.m_c1); range.m_r1 + offset, range.m_c1);
showInRowCol(m_row + offset, m_col, range.getColCount() > 1); showInRowCol(m_row + offset, m_col, range.getColCount() > 1);
m_viewer->updateCells(); m_viewer->updateCells();
m_viewer->setCurrentRow(m_row);
TApp::instance()->getCurrentSelection()->notifySelectionChanged(); TApp::instance()->getCurrentSelection()->notifySelectionChanged();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void RenameCellField::onReturnPressed() {
renameCell();
moveCellSelection(1);
}
//-----------------------------------------------------------------------------
void RenameCellField::onTabPressed() { moveCellSelection(1); }
//-----------------------------------------------------------------------------
void RenameCellField::onBacktabPressed() { moveCellSelection(-1); }
//-----------------------------------------------------------------------------
void RenameCellField::focusOutEvent(QFocusEvent *e) { void RenameCellField::focusOutEvent(QFocusEvent *e) {
hide(); hide();
@ -912,9 +932,34 @@ void RenameCellField::focusOutEvent(QFocusEvent *e) {
// Override shortcut keys for cell selection commands // Override shortcut keys for cell selection commands
bool RenameCellField::eventFilter(QObject *obj, QEvent *e) { bool RenameCellField::eventFilter(QObject *obj, QEvent *e) {
if (e->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(e);
int key = keyEvent->key();
switch (key) {
case Qt::Key_Tab:
onTabPressed();
return true;
break;
case Qt::Key_Backtab:
onBacktabPressed();
return true;
break;
}
}
if (e->type() != QEvent::ShortcutOverride) if (e->type() != QEvent::ShortcutOverride)
return QLineEdit::eventFilter(obj, e); // return false; return QLineEdit::eventFilter(obj, e); // return false;
// If we aren't allowing any shortcuts while renaming, use default editing
// commands.
if (!Preferences::instance()->isShortcutCommandsWhileRenamingCellEnabled())
return QLineEdit::eventFilter(obj, e);
// No shortcuts in Note Levels
TXshColumn *col = m_viewer->getXsheet()->getColumn(m_col);
bool noShortcuts = (col && col->getSoundTextColumn()) ? true : false;
if (noShortcuts) return QLineEdit::eventFilter(obj, e);
TCellSelection *cellSelection = dynamic_cast<TCellSelection *>( TCellSelection *cellSelection = dynamic_cast<TCellSelection *>(
TApp::instance()->getCurrentSelection()->getSelection()); TApp::instance()->getCurrentSelection()->getSelection());
if (!cellSelection) return QLineEdit::eventFilter(obj, e); if (!cellSelection) return QLineEdit::eventFilter(obj, e);
@ -925,19 +970,13 @@ bool RenameCellField::eventFilter(QObject *obj, QEvent *e) {
QAction *action = CommandManager::instance()->getActionFromShortcut(keyStr); QAction *action = CommandManager::instance()->getActionFromShortcut(keyStr);
if (!action) return QLineEdit::eventFilter(obj, e); if (!action) return QLineEdit::eventFilter(obj, e);
std::string actionId = CommandManager::instance()->getIdFromAction(action);
// These are usally standard ctrl/command strokes for text editing. // These are usally standard ctrl/command strokes for text editing.
// Default to standard behavior and don't execute OT's action while renaming // Default to standard behavior and don't execute OT's action while renaming
// cell if users prefer to do so. // cell if users prefer to do so.
// Or, always invoke OT's commands when renaming cell even the standard std::string actionId = CommandManager::instance()->getIdFromAction(action);
// command strokes for text editing. if (actionId == "MI_Undo" || actionId == "MI_Redo" ||
// The latter option is demanded by Japanese animation industry in order to
// gain efficiency for inputting xsheet.
if (!Preferences::instance()->isShortcutCommandsWhileRenamingCellEnabled() &&
(actionId == "MI_Undo" || actionId == "MI_Redo" ||
actionId == "MI_Clear" || actionId == "MI_Copy" || actionId == "MI_Clear" || actionId == "MI_Copy" ||
actionId == "MI_Paste" || actionId == "MI_Cut")) actionId == "MI_Paste" || actionId == "MI_Cut")
return QLineEdit::eventFilter(obj, e); return QLineEdit::eventFilter(obj, e);
return TCellSelection::isEnabledCommand(actionId); return TCellSelection::isEnabledCommand(actionId);
@ -948,6 +987,7 @@ bool RenameCellField::eventFilter(QObject *obj, QEvent *e) {
void RenameCellField::keyPressEvent(QKeyEvent *event) { void RenameCellField::keyPressEvent(QKeyEvent *event) {
if (event->key() == Qt::Key_Escape) { if (event->key() == Qt::Key_Escape) {
clearFocus(); clearFocus();
m_viewer->setFocus();
return; return;
} }
@ -965,7 +1005,8 @@ void RenameCellField::keyPressEvent(QKeyEvent *event) {
stride.setFrame(cellSelection->getSelectedCells().getRowCount()); stride.setFrame(cellSelection->getSelectedCells().getRowCount());
CellPosition offset; CellPosition offset;
switch (int key = event->key()) { int key = event->key();
switch (key) {
case Qt::Key_Up: case Qt::Key_Up:
case Qt::Key_Down: case Qt::Key_Down:
offset = m_viewer->orientation()->arrowShift(key); offset = m_viewer->orientation()->arrowShift(key);
@ -973,11 +1014,17 @@ void RenameCellField::keyPressEvent(QKeyEvent *event) {
case Qt::Key_Left: case Qt::Key_Left:
case Qt::Key_Right: case Qt::Key_Right:
// ctrl+left/right arrow for moving cursor to the end in the field // ctrl+left/right arrow for moving cursor to the end in the field
if (isCtrlPressed && if (!isCtrlPressed ||
!Preferences::instance()->isUseArrowKeyToShiftCellSelectionEnabled()) { !Preferences::instance()->isUseArrowKeyToShiftCellSelectionEnabled()) {
// Allow left/right movement inside field. If you go too far, you will
// shift cells
int curPos = cursorPosition();
if ((key == Qt::Key_Left && curPos > 0) ||
(key == Qt::Key_Right && curPos < text().size())) {
QLineEdit::keyPressEvent(event); QLineEdit::keyPressEvent(event);
return; return;
} }
}
offset = m_viewer->orientation()->arrowShift(key); offset = m_viewer->orientation()->arrowShift(key);
break; break;
default: default:
@ -1019,6 +1066,8 @@ void RenameCellField::showEvent(QShowEvent *) {
bool ret = connect(TApp::instance()->getCurrentXsheet(), bool ret = connect(TApp::instance()->getCurrentXsheet(),
SIGNAL(xsheetChanged()), this, SLOT(onXsheetChanged())); SIGNAL(xsheetChanged()), this, SLOT(onXsheetChanged()));
assert(ret); assert(ret);
m_isRenamingCell = true;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1026,6 +1075,7 @@ void RenameCellField::showEvent(QShowEvent *) {
void RenameCellField::hideEvent(QHideEvent *) { void RenameCellField::hideEvent(QHideEvent *) {
disconnect(TApp::instance()->getCurrentXsheet(), SIGNAL(xsheetChanged()), disconnect(TApp::instance()->getCurrentXsheet(), SIGNAL(xsheetChanged()),
this, SLOT(onXsheetChanged())); this, SLOT(onXsheetChanged()));
m_isRenamingCell = false;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View file

@ -26,6 +26,7 @@ class RenameCellField final : public QLineEdit {
int m_row; int m_row;
int m_col; int m_col;
XsheetViewer *m_viewer; XsheetViewer *m_viewer;
bool m_isRenamingCell;
public: public:
RenameCellField(QWidget *parent, XsheetViewer *viewer); RenameCellField(QWidget *parent, XsheetViewer *viewer);
@ -35,6 +36,8 @@ public:
bool isLocatedAt(int row, int col) { return row == m_row && col == m_col; } bool isLocatedAt(int row, int col) { return row == m_row && col == m_col; }
bool isRenamingCell() { return m_isRenamingCell; }
protected: protected:
void focusOutEvent(QFocusEvent *) override; void focusOutEvent(QFocusEvent *) override;
void keyPressEvent(QKeyEvent *event) override; void keyPressEvent(QKeyEvent *event) override;
@ -46,6 +49,10 @@ protected:
void renameCell(); void renameCell();
void renameSoundTextColumn(TXshSoundTextColumn *sndTextCol, const QString &s); void renameSoundTextColumn(TXshSoundTextColumn *sndTextCol, const QString &s);
void moveCellSelection(int direction);
void onTabPressed();
void onBacktabPressed();
protected slots: protected slots:
void onReturnPressed(); void onReturnPressed();
void onXsheetChanged(); void onXsheetChanged();
@ -134,6 +141,9 @@ public:
m_renameCell->showInRowCol(row, col, multiColumnSelected); m_renameCell->showInRowCol(row, col, multiColumnSelected);
} }
void hideRenameField() { m_renameCell->hide(); } void hideRenameField() { m_renameCell->hide(); }
bool isRenamingCell() {
return m_renameCell && m_renameCell->isRenamingCell();
}
protected: protected:
void paintEvent(QPaintEvent *) override; void paintEvent(QPaintEvent *) override;

View file

@ -1667,8 +1667,8 @@ void XsheetViewer::changeWindowTitle() {
QString sceneName = QString::fromStdWString(scene->getSceneName()); QString sceneName = QString::fromStdWString(scene->getSceneName());
if (sceneName.isEmpty()) sceneName = tr("Untitled"); if (sceneName.isEmpty()) sceneName = tr("Untitled");
if (app->getCurrentScene()->getDirtyFlag()) sceneName += QString("*"); if (app->getCurrentScene()->getDirtyFlag()) sceneName += QString("*");
QString name = tr("Scene: ") + sceneName;
QString separator = " | "; QString separator = " | ";
QString name = tr("Scene: ") + sceneName;
int frameCount = scene->getFrameCount(); int frameCount = scene->getFrameCount();
name = name + separator + tr(std::to_string(frameCount).c_str()) + name = name + separator + tr(std::to_string(frameCount).c_str()) +
(frameCount == 1 ? tr(" Frame") : tr(" Frames")); (frameCount == 1 ? tr(" Frame") : tr(" Frames"));
@ -1695,7 +1695,7 @@ void XsheetViewer::changeWindowTitle() {
QString::number(c1 - c0 + 1) + QString::number(c1 - c0 + 1) +
((c1 - c0 + 1 == 1) ? tr(" column") : tr(" columns")); ((c1 - c0 + 1 == 1) ? tr(" column") : tr(" columns"));
} }
TApp::instance()->setStatusBarFrameInfo(name); TApp::instance()->setStatusBarFrameInfo("| " + name);
parentWidget()->setWindowTitle(name); parentWidget()->setWindowTitle(name);
} }

View file

@ -498,6 +498,8 @@ void Preferences::definePreferenceItems() {
0); // Default 0); // Default
define(useCtrlAltToResizeBrush, "useCtrlAltToResizeBrush", QMetaType::Bool, define(useCtrlAltToResizeBrush, "useCtrlAltToResizeBrush", QMetaType::Bool,
true); true);
define(temptoolswitchtimer, "temptoolswitchtimer", QMetaType::Int, 500, 1,
std::numeric_limits<int>::max());
// Xsheet // Xsheet
define(xsheetLayoutPreference, "xsheetLayoutPreference", QMetaType::QString, define(xsheetLayoutPreference, "xsheetLayoutPreference", QMetaType::QString,

View file

@ -18,7 +18,7 @@
</p> </p>
</description> </description>
<url type="homepage">https://tahoma2d.org</url> <url type="homepage">https://tahoma2d.org</url>
<url type="bugtracker">https://github.com/turtletooth/tahoma2d/issues</url> <url type="bugtracker">https://github.com/tahoma2d/tahoma2d/issues</url>
<screenshots> <screenshots>
<screenshot type="default"> <screenshot type="default">
<image>https://tahoma2d.readthedocs.io/en/latest/_images/interface.png</image> <image>https://tahoma2d.readthedocs.io/en/latest/_images/interface.png</image>