diff --git a/doc/how_to_build_linux.md b/doc/how_to_build_linux.md
index c3db2b2..e353f9a 100644
--- a/doc/how_to_build_linux.md
+++ b/doc/how_to_build_linux.md
@@ -33,7 +33,7 @@ $ rpm ...
(it may include some useless packages)
```
-dnf install gcc gcc-c++ automake git cmake boost boost-devel SuperLU SuperLU-devel lz4-devel libusb-devel lzo-devel libjpeg-turbo-devel GLEW libGLEW freeglut-devel freeglut SDL2 SDL2-devel freetype-devel libpng-devel qt5-base qt5-qtbase-devel qt5-qtsvg qt5-qtsvg-devel qt5-qtscript qt5-qtscript-devel qt5-qttools qt5-qttools-devel blas blas-devel
+dnf install gcc gcc-c++ automake git cmake boost boost-devel SuperLU SuperLU-devel lz4-devel lzma libusb-devel lzo-devel libjpeg-turbo-devel libGLEW glew-devel freeglut-devel freeglut SDL2 SDL2-devel freetype-devel libpng-devel qt5-qtbase-devel qt5-qtsvg qt5-qtsvg-devel qt5-qtscript qt5-qtscript-devel qt5-qttools qt5-qttools-devel qt5-qtmultimedia-devel blas blas-devel
```
### Installing required packages on ArchLinux
@@ -53,7 +53,7 @@ Notes:
### Installing required packages on openSUSE
```
-zypper in boost-devel git cmake gcc-c++ freeglut-devel freetype2-devel glew-devel libjpeg-devel liblz4-devel libqt5-linguist-devel libQt5OpenGL5 libqt5-qtbase-devel libqt5-qtscript-devel libqt5-qtsvg-devel lzo-devel libusb-devel openblas-devel SDL2-devel superlu-devel zlib-devel
+zypper in boost-devel cmake freeglut-devel freetype2-devel gcc-c++ glew-devel libQt5OpenGL-devel libSDL2-devel libjpeg-devel liblz4-devel libpng16-compat-devel libqt5-linguist-devel libqt5-qtbase-devel libqt5-qtmultimedia-devel libqt5-qtscript-devel libqt5-qtsvg-devel libtiff-devel libusb-devel lzo-devel openblas-devel pkgconfig sed superlu-devel zlib-devel
```
## Build instructions
@@ -158,3 +158,15 @@ Then you can launch OpenToonz by running `/opt/opentoonz/bin/opentoonz`.
You can change the installation path by modifying the `CMAKE_INSTALL_PREFIX` CMake variable.
+----
+
+# Linux Package Definitions
+
+It may be helpful to use existing packages as a reference when creating a package for your own distribution.
+
+- ArchLinux (AUR):
+ https://aur.archlinux.org/packages/opentoonz-git/
+
+- App-Image (Portable):
+ https://github.com/morevnaproject/morevna-builds
+
diff --git a/doc/how_to_build_win.md b/doc/how_to_build_win.md
index 94eaf9e..376e47e 100644
--- a/doc/how_to_build_win.md
+++ b/doc/how_to_build_win.md
@@ -63,13 +63,6 @@ Rename the following files:
- `$opentoonz/thirdparty/libpng-1.6.21/scripts/pnglibconf.h.prebuilt` to `$opentoonz/thirdparty/libpng-1.6.21/pnglibconf.h`
- Note that the destination is a different folder for the last file.
-Add a guard for snprintf at tif_config.h(50):
-```
-+#if _MSC_VER < 1900
-#define snprintf _snprintf
-+#endif
-```
-
## Building
1. Open `$opentoonz/toonz/build/OpenToonz.sln` and change to `Release`
2. The output will be in `$opentoonz/toonz/build/Release`
diff --git a/doc/how_to_build_win_ja.md b/doc/how_to_build_win_ja.md
index 493e1f4..5bd2847 100644
--- a/doc/how_to_build_win_ja.md
+++ b/doc/how_to_build_win_ja.md
@@ -57,13 +57,6 @@ Visual Studio 2015 と Qt 5.6 でビルドできることを確認していま�
- `$opentoonz/thirdparty/tiff-4.0.3/libtiff/tiffconf.vc.h` → `$opentoonz/thirdparty/tiff-4.0.3/libtiff/tiffconf.h`
- `$opentoonz/thirdparty/libpng-1.6.21/scripts/pnglibconf.h.prebuilt` → `$opentoonz/thirdparty/libpng-1.6.21/pnglibconf.h`
-`tif_config.h` の 50 行目あたりに下記の修正を加えます:
-```
-+#if _MSC_VER < 1900
-#define snprintf _snprintf
-+#endif
-```
-
## ビルド
1. `$opentoonz/toonz/build/OpenToonz.sln` を開いて Release 構成を選択してビルドします
2. `$opentoonz/toonz/build/Release` にファイルが生成されます
diff --git a/stuff/config/qss/gray_048/gray_048.less b/stuff/config/qss/gray_048/gray_048.less
index 0590e85..c170ed2 100644
--- a/stuff/config/qss/gray_048/gray_048.less
+++ b/stuff/config/qss/gray_048/gray_048.less
@@ -748,7 +748,7 @@ DvDirTreeView {
/*---------------------------------------------------------------------------*/
#CleanupSettingsFrame,
#LoadLevelFrame,
-#SolidLineFrame{
+#SolidLineFrame {
border: 1px solid @m_baseTxtColor;
}
@@ -1365,4 +1365,15 @@ QDialog #dialogButtonFrame {
#LargeSizedText {
font-size: 17px;
+}
+
+#GearButton {
+ qproperty-icon: url("@{image_url}/gear.png");
+}
+
+#StartupLabel {
+ padding: 3px;
+ &:hover {
+ .baseBG(light, 10%);
+ }
}
\ No newline at end of file
diff --git a/stuff/config/qss/gray_048/gray_048.qss b/stuff/config/qss/gray_048/gray_048.qss
index 6936166..0c17daf 100644
--- a/stuff/config/qss/gray_048/gray_048.qss
+++ b/stuff/config/qss/gray_048/gray_048.qss
@@ -1369,5 +1369,14 @@ QDialog #dialogButtonFrame {
#LargeSizedText {
font-size: 17px;
}
+#GearButton {
+ qproperty-icon: url("../gray_072/imgs/gear.png");
+}
+#StartupLabel {
+ padding: 3px;
+}
+#StartupLabel:hover {
+ background-color: #4a4a4a;
+}
//# sourceMappingURL=gray_048.qss.map
\ No newline at end of file
diff --git a/stuff/config/qss/gray_048/gray_048_mac.qss b/stuff/config/qss/gray_048/gray_048_mac.qss
index 7c6a503..1217245 100644
--- a/stuff/config/qss/gray_048/gray_048_mac.qss
+++ b/stuff/config/qss/gray_048/gray_048_mac.qss
@@ -1369,5 +1369,14 @@ QDialog #dialogButtonFrame {
#LargeSizedText {
font-size: 17px;
}
+#GearButton {
+ qproperty-icon: url("../gray_072/imgs/gear.png");
+}
+#StartupLabel {
+ padding: 3px;
+}
+#StartupLabel:hover {
+ background-color: #4a4a4a;
+}
//# sourceMappingURL=gray_048_mac.qss.map
\ No newline at end of file
diff --git a/stuff/config/qss/gray_072/gray_072.less b/stuff/config/qss/gray_072/gray_072.less
index c918bcf..60044ee 100644
--- a/stuff/config/qss/gray_072/gray_072.less
+++ b/stuff/config/qss/gray_072/gray_072.less
@@ -747,7 +747,7 @@ DvDirTreeView {
/*---------------------------------------------------------------------------*/
#CleanupSettingsFrame,
#LoadLevelFrame,
-#SolidLineFrame{
+#SolidLineFrame {
border: 1px solid @m_baseTxtColor;
}
@@ -1365,4 +1365,15 @@ QDialog #dialogButtonFrame {
#LargeSizedText {
font-size: 17px;
+}
+
+#GearButton {
+ qproperty-icon: url("@{image_url}/gear.png");
+}
+
+#StartupLabel {
+ padding: 3px;
+ &:hover {
+ .baseBG(light, 10%);
+ }
}
\ No newline at end of file
diff --git a/stuff/config/qss/gray_072/gray_072.qss b/stuff/config/qss/gray_072/gray_072.qss
index 69c5a4d..824600c 100644
--- a/stuff/config/qss/gray_072/gray_072.qss
+++ b/stuff/config/qss/gray_072/gray_072.qss
@@ -1369,5 +1369,14 @@ QDialog #dialogButtonFrame {
#LargeSizedText {
font-size: 17px;
}
+#GearButton {
+ qproperty-icon: url("imgs/gear.png");
+}
+#StartupLabel {
+ padding: 3px;
+}
+#StartupLabel:hover {
+ background-color: #626262;
+}
//# sourceMappingURL=gray_072.qss.map
\ No newline at end of file
diff --git a/stuff/config/qss/gray_072/gray_072_mac.qss b/stuff/config/qss/gray_072/gray_072_mac.qss
index 182e253..3c89f26 100644
--- a/stuff/config/qss/gray_072/gray_072_mac.qss
+++ b/stuff/config/qss/gray_072/gray_072_mac.qss
@@ -1369,5 +1369,14 @@ QDialog #dialogButtonFrame {
#LargeSizedText {
font-size: 17px;
}
+#GearButton {
+ qproperty-icon: url("imgs/gear.png");
+}
+#StartupLabel {
+ padding: 3px;
+}
+#StartupLabel:hover {
+ background-color: #626262;
+}
//# sourceMappingURL=gray_072_mac.qss.map
\ No newline at end of file
diff --git a/stuff/config/qss/gray_072/imgs/gear.png b/stuff/config/qss/gray_072/imgs/gear.png
new file mode 100644
index 0000000..7e07631
Binary files /dev/null and b/stuff/config/qss/gray_072/imgs/gear.png differ
diff --git a/stuff/config/qss/gray_128/gray_128.less b/stuff/config/qss/gray_128/gray_128.less
index 2c13e25..168a281 100644
--- a/stuff/config/qss/gray_128/gray_128.less
+++ b/stuff/config/qss/gray_128/gray_128.less
@@ -595,7 +595,7 @@ DvDirTreeView {
/*---------------------------------------------------------------------------*/
#CleanupSettingsFrame,
#LoadLevelFrame,
-#SolidLineFrame{
+#SolidLineFrame {
border: 1px solid rgb(20,20,20);
}
@@ -1190,4 +1190,15 @@ QDialog #dialogButtonFrame {
#LargeSizedText {
font-size: 17px;
+}
+
+#GearButton {
+ qproperty-icon: url("@{image_url}/gear.png");
+}
+
+#StartupLabel {
+ padding: 3px;
+ &:hover {
+ .baseBG(light, 10%);
+ }
}
\ No newline at end of file
diff --git a/stuff/config/qss/gray_128/gray_128.qss b/stuff/config/qss/gray_128/gray_128.qss
index 1f3a66e..ee88456 100644
--- a/stuff/config/qss/gray_128/gray_128.qss
+++ b/stuff/config/qss/gray_128/gray_128.qss
@@ -1108,5 +1108,14 @@ QDialog #dialogButtonFrame {
#LargeSizedText {
font-size: 17px;
}
+#GearButton {
+ qproperty-icon: url("imgs/gear.png");
+}
+#StartupLabel {
+ padding: 3px;
+}
+#StartupLabel:hover {
+ background-color: #9a9a9a;
+}
//# sourceMappingURL=gray_128.qss.map
\ No newline at end of file
diff --git a/stuff/config/qss/gray_128/gray_128_mac.qss b/stuff/config/qss/gray_128/gray_128_mac.qss
index f66c40d..a7b90c2 100644
--- a/stuff/config/qss/gray_128/gray_128_mac.qss
+++ b/stuff/config/qss/gray_128/gray_128_mac.qss
@@ -1108,5 +1108,14 @@ QDialog #dialogButtonFrame {
#LargeSizedText {
font-size: 17px;
}
+#GearButton {
+ qproperty-icon: url("imgs/gear.png");
+}
+#StartupLabel {
+ padding: 3px;
+}
+#StartupLabel:hover {
+ background-color: #9a9a9a;
+}
//# sourceMappingURL=gray_128_mac.qss.map
\ No newline at end of file
diff --git a/stuff/config/qss/gray_128/imgs/gear.png b/stuff/config/qss/gray_128/imgs/gear.png
new file mode 100644
index 0000000..36477dd
Binary files /dev/null and b/stuff/config/qss/gray_128/imgs/gear.png differ
diff --git a/stuff/profiles/layouts/rooms/Default/menubar_template.xml b/stuff/profiles/layouts/rooms/Default/menubar_template.xml
index 5df924e..6c9f3b8 100644
--- a/stuff/profiles/layouts/rooms/Default/menubar_template.xml
+++ b/stuff/profiles/layouts/rooms/Default/menubar_template.xml
@@ -2,9 +2,9 @@
\ No newline at end of file
diff --git a/stuff/profiles/layouts/rooms/StudioGhibli/menubar_template.xml b/stuff/profiles/layouts/rooms/StudioGhibli/menubar_template.xml
index eee1faf..b78b58c 100644
--- a/stuff/profiles/layouts/rooms/StudioGhibli/menubar_template.xml
+++ b/stuff/profiles/layouts/rooms/StudioGhibli/menubar_template.xml
@@ -13,6 +13,7 @@
MI_NewLevel
MI_LoadLevel
+ MI_SaveAllLevels
MI_SaveLevel
MI_SaveLevelAs
MI_ExportLevel
diff --git a/stuff/profiles/layouts/shortcuts/defopentoonz.ini b/stuff/profiles/layouts/shortcuts/defopentoonz.ini
new file mode 100644
index 0000000..ebb88c6
--- /dev/null
+++ b/stuff/profiles/layouts/shortcuts/defopentoonz.ini
@@ -0,0 +1,366 @@
+[shortcuts]
+MI_Clear=Del
+MI_OnionSkin=/
+A_DecreaseBrushHardness=
+A_DecreaseMaxBrushThickness=U
+A_DecreaseMinBrushThickness=H
+A_FxSchematicToggle=
+A_IncreaseBrushHardness=
+A_IncreaseMaxBrushThickness=I
+A_IncreaseMinBrushThickness=J
+A_ToolOption_AutoGroup=
+A_ToolOption_AutoSelect%3AColumn=
+A_ToolOption_AutoSelect%3ANone=
+A_ToolOption_AutoSelect%3APegbar=
+A_ToolOption_AutoSelectDrawing=
+A_ToolOption_Autofill=
+A_ToolOption_BreakSharpAngles=
+A_ToolOption_BrushPreset=
+A_ToolOption_EditToolActiveAxis=
+A_ToolOption_EditToolActiveAxis%3ACenter=
+A_ToolOption_EditToolActiveAxis%3APosition=
+A_ToolOption_EditToolActiveAxis%3ARotation=
+A_ToolOption_EditToolActiveAxis%3AScale=
+A_ToolOption_EditToolActiveAxis%3AShear=
+A_ToolOption_FrameRange=F6
+A_ToolOption_GeometricEdge=
+A_ToolOption_GeometricShape=
+A_ToolOption_GlobalKey=
+A_ToolOption_IK=
+A_ToolOption_Invert=
+A_ToolOption_JoinVectors=
+A_ToolOption_Manual=
+A_ToolOption_Meshify=
+A_ToolOption_Mode=
+A_ToolOption_Mode%3AAreas=
+A_ToolOption_Mode%3ALines=
+A_ToolOption_Mode%3ALines%20%26%20Areas=
+A_ToolOption_OnionSkin=
+A_ToolOption_Orientation=
+A_ToolOption_PencilMode=
+A_ToolOption_PickScreen=
+A_ToolOption_PreserveThickness=
+A_ToolOption_PressureSensitivity=Shift+P
+A_ToolOption_SegmentInk=F8
+A_ToolOption_Selective=F7
+A_ToolOption_ShowOnlyActiveSkeleton=
+A_ToolOption_SkeletonMode%3AAnimate=
+A_ToolOption_SkeletonMode%3ABuild%20Skeleton=
+A_ToolOption_SkeletonMode%3AInverse%20Kinematics=
+A_ToolOption_Smooth=
+A_ToolOption_Snap=
+A_ToolOption_Type=
+A_ToolOption_Type%3AFreehand=
+A_ToolOption_Type%3ANormal=
+A_ToolOption_Type%3APolyline=
+A_ToolOption_Type%3ARectangular=F5
+A_ToolOption_TypeFont=
+A_ToolOption_TypeSize=
+A_ToolOption_TypeStyle=
+MI_ACheck=
+MI_About=
+MI_ActivateAllColumns=
+MI_ActivateSelectedColumns=
+MI_ActivateThisColumnOnly=
+MI_AddFrames=
+MI_AddToBatchCleanupList=
+MI_AddToBatchRenderList=
+MI_AdjustLevels=
+MI_AdjustThickness=
+MI_Antialias=
+MI_ApplyMatchLines=
+MI_AutoFillToggle=Shift+A
+MI_Autocenter=
+MI_Autorenumber=
+MI_BCheck=
+MI_Binarize=
+MI_BlendColors=
+MI_BlueChannel=
+MI_BlueChannelGreyscale=
+MI_BrightnessAndContrast=
+MI_BringForward=]
+MI_BringToFront=Ctrl+]
+MI_CameraSettings=
+MI_CameraStage=
+MI_CameraTest=
+MI_CanvasSize=
+MI_Cleanup=
+MI_CleanupPreview=
+MI_CleanupSettings=
+MI_ClearRecentImage=
+MI_ClearRecentLevel=
+MI_ClearRecentScene=
+MI_CloneChild=
+MI_CloneLevel=
+MI_ClonePreview=
+MI_CloseChild=
+MI_Collapse=
+MI_CollectAssets=
+MI_CompareToSnapshot=
+MI_ConvertFileWithInput=
+MI_ConvertFiles=
+MI_ConvertToVectors=
+MI_Copy=Ctrl+C
+MI_Cut=Ctrl+X
+MI_DeactivateAllColumns=
+MI_DeactivateSelectedColumns=
+MI_DeactivateUpperColumns=
+MI_DecreaseStep=";"
+MI_DefineScanner=
+MI_DeleteInk=
+MI_DeleteMatchLines=
+MI_DisableAllColumns=
+MI_DisableSelectedColumns=
+MI_DockingCheck=
+MI_DrawingSubBackward=Q
+MI_DrawingSubForward=W
+MI_DrawingSubGroupBackward=Alt+Q
+MI_DrawingSubGroupForward=Alt+W
+MI_Dup=
+MI_Duplicate=D
+MI_DuplicateFile=
+MI_Each2=
+MI_Each3=
+MI_Each4=
+MI_EditLevel=
+MI_EditShift=
+MI_EnableAllColumns=
+MI_EnableSelectedColumns=
+MI_EnableThisColumnOnly=
+MI_EnterGroup=
+MI_EraseUnusedStyles=
+MI_ExitGroup=
+MI_ExplodeChild=
+MI_ExportLevel=
+MI_ExportScenes=
+MI_ExposeResource=
+MI_FieldGuide=Shift+G
+MI_FileInfo=
+MI_FillAreas=
+MI_FillLines=
+MI_FirstFrame="Alt+,"
+MI_FoldColumns=
+MI_FrezzePreview=
+MI_FullScreenWindow=Ctrl+`
+MI_FxParamEditor=Ctrl+K
+MI_GCheck=
+MI_GetColorFromStudioPalette=
+MI_GreenChannel=
+MI_GreenChannelGreyscale=
+MI_Group=Ctrl+G
+MI_Histogram=
+MI_ICheck=
+MI_IOnly=
+MI_ImportMagpieFile=
+MI_ImportScenes=
+MI_IncreaseStep="'"
+MI_Increment=
+MI_Ink1Check=
+MI_Insert=Ins
+MI_InsertFx=Ctrl+F
+MI_InsertGlobalKeyframe=
+MI_InsertSceneFrame=
+MI_InvertKeyframeSelection=
+MI_InvertSelection=
+MI_LastFrame=Alt+.
+MI_LevelSettings=
+MI_LinesFade=
+MI_Link=
+MI_LoadColorModel=
+MI_LoadFolder=
+MI_LoadLevel=
+MI_LoadScene=Ctrl+L
+MI_LoadSubSceneFile=
+MI_LockAllColumns=Ctrl+Alt+Shift+L
+MI_LockSelectedColumns=Ctrl+Shift+L
+MI_LockThisColumnOnly=Shift+L
+MI_Loop=L
+MI_MatteChannel=
+MI_MaximizePanel=`
+MI_MergeCmapped=
+MI_MergeColumns=
+MI_MergeFrames=
+MI_NewLevel=Alt+N
+MI_NewOutputFx=
+MI_NewProject=
+MI_NewScene=Ctrl+N
+MI_NextDrawing=.
+MI_NextFrame=Shift+.
+MI_NextStep=
+MI_NoShift=
+MI_OpacityCheck=1
+MI_OpenBatchServers=
+MI_OpenChild=
+MI_OpenCleanupSettings=
+MI_OpenColorModel=
+MI_OpenComboViewer=
+MI_OpenFileBrowser=
+MI_OpenFileBrowser2=
+MI_OpenFileViewer=
+MI_OpenFilmStrip=
+MI_OpenFunctionEditor=
+MI_OpenHistoryPanel=Ctrl+H
+MI_OpenLevelView=
+MI_OpenPalette=
+MI_OpenPltGizmo=
+MI_OpenRecentLevel=
+MI_OpenRecentScene=
+MI_OpenSchematic=
+MI_OpenScriptConsole=
+MI_OpenStudioPalette=
+MI_OpenStyleControl=
+MI_OpenTMessage=
+MI_OpenTasks=
+MI_OpenToolOptionBar=
+MI_OpenToolbar=
+MI_OpenXshView=
+MI_OutputSettings=Ctrl+O
+MI_OverwritePalette=
+MI_PCheck=
+MI_Paste=Ctrl+V
+MI_PasteColors=
+MI_PasteInto=
+MI_PasteNames=
+MI_PasteValues=
+MI_Pause=
+MI_PencilTest=
+MI_PickStyleAreas=
+MI_PickStyleLines=
+MI_Play=P
+MI_Preferences=Ctrl+U
+MI_PrevDrawing=","
+MI_PrevFrame="Shift+,"
+MI_PrevStep=
+MI_Preview=Ctrl+R
+MI_PreviewFx=
+MI_PreviewSettings=
+MI_Print=Ctrl+P
+MI_PrintXsheet=
+MI_ProjectSettings=
+MI_Quit=Ctrl+Q
+MI_Random=
+MI_RasterizePli=
+MI_RedChannel=
+MI_RedChannelGreyscale=
+MI_Redo=Ctrl+Y
+MI_Reframe1=
+MI_Reframe2=
+MI_Reframe3=
+MI_Reframe4=
+MI_RefreshTree=
+MI_RegenerateFramePr=
+MI_RegeneratePreview=
+MI_ReloadStyle=
+MI_RemoveEndpoints=
+MI_RemoveGlobalKeyframe=
+MI_RemoveLevel=
+MI_RemoveSceneFrame=
+MI_RemoveUnused=
+MI_Render=Ctrl+Shift+R
+MI_Renumber=
+MI_ReplaceLevel=
+MI_ReplaceParentDirectory=
+MI_Resequence=
+MI_ResetInterpolation=
+MI_ResetRoomLayout=
+MI_ResetScanCropbox=
+MI_ResetShift=
+MI_ResetStep=
+MI_Reverse=
+MI_RevertScene=
+MI_RevertToCleanedUp=
+MI_RevertToLastSaved=
+MI_Rolldown=
+MI_Rollup=
+MI_RunScript=
+MI_SafeArea=
+MI_SaveAll=Ctrl+S
+MI_SaveDefaultSettings=
+MI_SaveLevel=
+MI_SaveLevelAs=
+MI_SavePaletteAs=
+MI_SavePreset=
+MI_SavePreviewedFrames=
+MI_SaveScene=Ctrl+Shift+S
+MI_SaveSceneAs=
+MI_SaveSubxsheetAs=
+MI_Scan=
+MI_ScanSettings=
+MI_SceneSettings=
+MI_SelectAll=Ctrl+A
+MI_SelectAllKeyframes=
+MI_SelectAllKeyframesNotAfter=
+MI_SelectAllKeyframesNotBefore=
+MI_SelectColumnKeyframes=
+MI_SelectFollowingKeysInColumn=
+MI_SelectFollowingKeysInRow=
+MI_SelectPreviousKeysInColumn=
+MI_SelectPreviousKeysInRow=
+MI_SelectRowKeyframes=
+MI_SendBack=Ctrl+[
+MI_SendBackward=[
+MI_SetAcceleration=
+MI_SetConstantSpeed=
+MI_SetDeceleration=
+MI_SetKeyframes=Z
+MI_SetScanCropbox=
+MI_ShiftTrace=
+MI_ShortcutPopup=
+MI_ShowFolderContents=
+MI_Step2=
+MI_Step3=
+MI_Step4=
+MI_SwapEnabledColumns=
+MI_Swing=
+MI_TCheck=
+MI_TimeStretch=
+MI_ToggleColumnLocks=
+MI_ToggleColumnsActivation=
+MI_ToggleEditInPlace=
+MI_Tracking=
+MI_Undo=Ctrl+Z
+MI_Ungroup=Ctrl+Shift+G
+MI_UnlockAllColumns=Ctrl+Alt+Shift+U
+MI_UnlockSelectedColumns=Ctrl+Shift+U
+MI_ViewBBox=
+MI_ViewCamera=
+MI_ViewColorcard=
+MI_ViewFile=
+MI_ViewGuide=
+MI_ViewRuler=
+MI_ViewTable=
+MI_ZeroThick=Shift+/
+T_ActualPixelSize=N
+T_Bender=
+T_Brush=B
+T_ControlPointEditor=C
+T_Cutter=
+T_Edit=E
+T_Eraser=A
+T_Fill=F
+T_Finger=
+T_Geometric=G
+T_Hand=Space
+T_Hook=O
+T_Iron=
+T_Magnet=
+T_PaintBrush=
+T_Pinch=M
+T_Plastic=X
+T_Pump=
+T_RGBPicker=R
+T_Rotate=Ctrl+Space
+T_Ruler=
+T_Selection=S
+T_ShowHideFullScreen=Alt+F
+T_Skeleton=V
+T_StylePicker=K
+T_Tape=T
+T_Tracker=
+T_Type=Y
+T_Zoom=Shift+Space
+T_ZoomFit=9
+T_ZoomReset=0
+T_Zoomin=+
+T_Zoomout=-
+MI_LoadRecentImage=
diff --git a/stuff/profiles/layouts/shortcuts/otadobe.ini b/stuff/profiles/layouts/shortcuts/otadobe.ini
new file mode 100644
index 0000000..7a1b172
--- /dev/null
+++ b/stuff/profiles/layouts/shortcuts/otadobe.ini
@@ -0,0 +1,366 @@
+[shortcuts]
+MI_LoadRecentImage=
+A_ToolOption_FrameRange=
+A_ToolOption_SegmentInk=
+A_ToolOption_Selective=
+A_ToolOption_Type%3ARectangular=
+MI_BringForward=Ctrl+Up
+MI_BringToFront=Ctrl+Shift+Up
+MI_Clear=Delete
+MI_Copy=Ctrl+C
+MI_Cut=Ctrl+X
+MI_DrawingSubBackward=[
+MI_DrawingSubForward=]
+MI_DrawingSubGroupBackward=Ctrl+[
+MI_DrawingSubGroupForward=Ctrl+]
+MI_Duplicate=
+MI_FullScreenWindow=Ctrl+F
+MI_FxParamEditor=
+MI_Group=Ctrl+G
+MI_Insert=Ins
+MI_InsertFx=
+MI_LoadScene=Ctrl+O
+MI_MaximizePanel=
+MI_NewScene=Ctrl+N
+MI_NextDrawing=G
+MI_NextFrame=.
+MI_OpacityCheck=
+MI_Paste=Ctrl+V
+MI_PrevDrawing=F
+MI_PrevFrame=","
+MI_Preview=Alt+P
+MI_Quit=Ctrl+Q
+MI_Redo=Ctrl+Y
+MI_SaveScene=Ctrl+Shift+S
+MI_SaveSceneAs=Ctrl+Alt+Shift+S
+MI_SelectAll=Shift+A
+MI_SendBack=Ctrl+Shift+Down
+MI_SendBackward=Ctrl+Down
+MI_Undo=Ctrl+Z
+MI_ZeroThick=D
+T_ActualPixelSize=
+T_Brush=Alt+B
+T_ControlPointEditor=Alt+A
+T_Edit=Alt+Q
+T_Eraser=Alt+E
+T_Fill=Alt+K
+T_Geometric=Atl+R
+T_Hand=
+T_Pinch=
+T_Rotate=
+T_Selection=Alt+V
+T_StylePicker=Alt+I
+T_Tape=Alt+C
+T_Type=
+T_Zoom=Alt+Z
+T_ZoomReset=Shift+Z
+T_Zoomin=Ctrl+=
+T_Zoomout=Ctrl+-
+A_DecreaseBrushHardness=
+A_DecreaseMaxBrushThickness=
+A_DecreaseMinBrushThickness=
+A_FxSchematicToggle=
+A_IncreaseBrushHardness=
+A_IncreaseMaxBrushThickness=
+A_IncreaseMinBrushThickness=
+A_ToolOption_AutoGroup=
+A_ToolOption_AutoSelect%3AColumn=
+A_ToolOption_AutoSelect%3ANone=
+A_ToolOption_AutoSelect%3APegbar=
+A_ToolOption_AutoSelectDrawing=
+A_ToolOption_Autofill=
+A_ToolOption_BreakSharpAngles=
+A_ToolOption_BrushPreset=
+A_ToolOption_EditToolActiveAxis=
+A_ToolOption_EditToolActiveAxis%3ACenter=
+A_ToolOption_EditToolActiveAxis%3APosition=
+A_ToolOption_EditToolActiveAxis%3ARotation=
+A_ToolOption_EditToolActiveAxis%3AScale=
+A_ToolOption_EditToolActiveAxis%3AShear=
+A_ToolOption_GeometricEdge=
+A_ToolOption_GeometricShape=
+A_ToolOption_GlobalKey=
+A_ToolOption_IK=Alt+8
+A_ToolOption_Invert=
+A_ToolOption_JoinVectors=
+A_ToolOption_Manual=
+A_ToolOption_Meshify=
+A_ToolOption_Mode=
+A_ToolOption_Mode%3AAreas=
+A_ToolOption_Mode%3ALines=
+A_ToolOption_Mode%3ALines%20%26%20Areas=
+A_ToolOption_OnionSkin=
+A_ToolOption_Orientation=
+A_ToolOption_PencilMode=
+A_ToolOption_PickScreen=
+A_ToolOption_PreserveThickness=
+A_ToolOption_PressureSensitivity=
+A_ToolOption_ShowOnlyActiveSkeleton=
+A_ToolOption_SkeletonMode%3AAnimate=
+A_ToolOption_SkeletonMode%3ABuild%20Skeleton=
+A_ToolOption_SkeletonMode%3AInverse%20Kinematics=
+A_ToolOption_Smooth=
+A_ToolOption_Snap=
+A_ToolOption_Type=
+A_ToolOption_Type%3AFreehand=
+A_ToolOption_Type%3ANormal=
+A_ToolOption_Type%3APolyline=
+A_ToolOption_TypeFont=
+A_ToolOption_TypeSize=
+A_ToolOption_TypeStyle=
+MI_ACheck=
+MI_About=
+MI_ActivateAllColumns=
+MI_ActivateSelectedColumns=
+MI_ActivateThisColumnOnly=
+MI_AddFrames=Ctrl+H
+MI_AddToBatchCleanupList=
+MI_AddToBatchRenderList=
+MI_AdjustLevels=
+MI_AdjustThickness=
+MI_Antialias=
+MI_ApplyMatchLines=
+MI_AutoFillToggle=
+MI_Autocenter=
+MI_Autorenumber=
+MI_BCheck=
+MI_Binarize=
+MI_BlendColors=
+MI_BlueChannel=
+MI_BlueChannelGreyscale=
+MI_BrightnessAndContrast=
+MI_CameraSettings=
+MI_CameraStage=
+MI_CameraTest=
+MI_CanvasSize=
+MI_Cleanup=
+MI_CleanupPreview=
+MI_CleanupSettings=
+MI_ClearRecentImage=
+MI_ClearRecentLevel=
+MI_ClearRecentScene=
+MI_CloneChild=
+MI_CloneLevel=
+MI_ClonePreview=
+MI_CloseChild=
+MI_Collapse=
+MI_CollectAssets=
+MI_CompareToSnapshot=
+MI_ConvertFileWithInput=
+MI_ConvertFiles=
+MI_ConvertToVectors=
+MI_DeactivateAllColumns=
+MI_DeactivateSelectedColumns=Alt+H
+MI_DeactivateUpperColumns=
+MI_DecreaseStep=
+MI_DefineScanner=
+MI_DeleteInk=
+MI_DeleteMatchLines=
+MI_DisableAllColumns=
+MI_DisableSelectedColumns=
+MI_DockingCheck=
+MI_Dup=
+MI_DuplicateFile=
+MI_Each2=
+MI_Each3=
+MI_Each4=
+MI_EditLevel=
+MI_EditShift=
+MI_EnableAllColumns=Alt+Shift+H
+MI_EnableSelectedColumns=
+MI_EnableThisColumnOnly=
+MI_EnterGroup=Ctrl+Return
+MI_EraseUnusedStyles=
+MI_ExitGroup=Backspace
+MI_ExplodeChild=Ctrl+B
+MI_ExportLevel=
+MI_ExportScenes=
+MI_ExposeResource=
+MI_FieldGuide="Ctrl+'"
+MI_FileInfo=
+MI_FillAreas=
+MI_FillLines=
+MI_FirstFrame=Home
+MI_FoldColumns=
+MI_FrezzePreview=
+MI_GCheck=
+MI_GetColorFromStudioPalette=
+MI_GreenChannel=
+MI_GreenChannelGreyscale=
+MI_Histogram=
+MI_ICheck=
+MI_IOnly=
+MI_ImportMagpieFile=
+MI_ImportScenes=
+MI_IncreaseStep="+"
+MI_Increment=
+MI_Ink1Check=
+MI_InsertGlobalKeyframe=
+MI_InsertSceneFrame=
+MI_InvertKeyframeSelection=
+MI_InvertSelection=
+MI_LastFrame=End
+MI_LevelSettings=
+MI_LinesFade=
+MI_Link=
+MI_LoadColorModel=
+MI_LoadFolder=
+MI_LoadLevel=
+MI_LoadSubSceneFile=
+MI_LockAllColumns=
+MI_LockSelectedColumns=
+MI_LockThisColumnOnly=
+MI_Loop=
+MI_MatteChannel=
+MI_MergeCmapped=
+MI_MergeColumns=
+MI_MergeFrames=
+MI_NewLevel=
+MI_NewOutputFx=
+MI_NewProject=
+MI_NextStep=
+MI_NoShift=
+MI_OnionSkin=Ctrl+Alt+O
+MI_OpenBatchServers=
+MI_OpenChild=
+MI_OpenCleanupSettings=
+MI_OpenColorModel=
+MI_OpenComboViewer=
+MI_OpenFileBrowser=
+MI_OpenFileBrowser2=
+MI_OpenFileViewer=
+MI_OpenFilmStrip=
+MI_OpenFunctionEditor=Alt+F
+MI_OpenHistoryPanel=
+MI_OpenLevelView=
+MI_OpenPalette=
+MI_OpenPltGizmo=
+MI_OpenRecentScene=
+MI_OpenSchematic=
+MI_OpenScriptConsole=
+MI_OpenStudioPalette=
+MI_OpenStyleControl=
+MI_OpenTMessage=
+MI_OpenTasks=
+MI_OpenToolOptionBar=
+MI_OpenToolbar=
+MI_OpenXshView=
+MI_OutputSettings=
+MI_OverwritePalette=
+MI_PCheck=
+MI_PasteColors=
+MI_PasteInto=
+MI_PasteNames=
+MI_PasteValues=
+MI_Pause=
+MI_PencilTest=
+MI_PickStyleAreas=
+MI_PickStyleLines=
+MI_Play=Return
+MI_Preferences=Ctrl+U
+MI_PrevStep=
+MI_PreviewFx=
+MI_PreviewSettings=
+MI_Print=
+MI_PrintXsheet=
+MI_ProjectSettings=
+MI_Random=
+MI_RasterizePli=
+MI_RedChannel=
+MI_RedChannelGreyscale=
+MI_Reframe1=
+MI_Reframe2=
+MI_Reframe3=
+MI_Reframe4=
+MI_RefreshTree=
+MI_RegenerateFramePr=
+MI_RegeneratePreview=
+MI_ReloadStyle=
+MI_RemoveEndpoints=
+MI_RemoveGlobalKeyframe=
+MI_RemoveLevel=
+MI_RemoveSceneFrame=
+MI_RemoveUnused=
+MI_Render=Ctrl+Alt+Shift+S
+MI_Renumber=
+MI_ReplaceLevel=
+MI_ReplaceParentDirectory=
+MI_Resequence=
+MI_ResetInterpolation=
+MI_ResetRoomLayout=
+MI_ResetScanCropbox=
+MI_ResetShift=
+MI_ResetStep=
+MI_Reverse=
+MI_RevertScene=
+MI_RevertToCleanedUp=
+MI_RevertToLastSaved=
+MI_Rolldown=
+MI_Rollup=
+MI_RunScript=
+MI_SafeArea=
+MI_SaveAll=Ctrl+S
+MI_SaveDefaultSettings=
+MI_SaveLevel=
+MI_SaveLevelAs=
+MI_SavePaletteAs=
+MI_SavePreset=
+MI_SavePreviewedFrames=
+MI_SaveSubxsheetAs=
+MI_Scan=
+MI_ScanSettings=
+MI_SceneSettings=Ctrl+F3
+MI_SelectAllKeyframes=
+MI_SelectAllKeyframesNotAfter=
+MI_SelectAllKeyframesNotBefore=
+MI_SelectColumnKeyframes=
+MI_SelectFollowingKeysInColumn=
+MI_SelectFollowingKeysInRow=
+MI_SelectPreviousKeysInColumn=
+MI_SelectPreviousKeysInRow=
+MI_SelectRowKeyframes=
+MI_SetAcceleration=
+MI_SetConstantSpeed=
+MI_SetDeceleration=
+MI_SetKeyframes=Ctrl+F6
+MI_SetScanCropbox=
+MI_ShiftTrace=
+MI_ShortcutPopup=
+MI_ShowFolderContents=
+MI_Step2=
+MI_Step3=
+MI_Step4=
+MI_SwapEnabledColumns=
+MI_Swing=
+MI_TCheck=
+MI_TimeStretch=
+MI_ToggleColumnLocks=
+MI_ToggleColumnsActivation=
+MI_ToggleEditInPlace=
+MI_Tracking=
+MI_Ungroup=Ctrl+Shift+G
+MI_UnlockAllColumns=Ctrl+Alt+Shift+L
+MI_UnlockSelectedColumns=Ctrl+Shift+K
+MI_ViewBBox=
+MI_ViewCamera=
+MI_ViewColorcard=
+MI_ViewFile=
+MI_ViewGuide=
+MI_ViewRuler=Ctrl+Alt+Shift+R
+MI_ViewTable=
+T_Bender=
+T_Cutter=Alt+T
+T_Finger=
+T_Hook=
+T_Iron=
+T_Magnet=
+T_PaintBrush=
+T_Plastic=
+T_Pump=
+T_RGBPicker=
+T_Ruler=
+T_ShowHideFullScreen=F4
+T_Skeleton=
+T_Tracker=
+T_ZoomFit=
+MI_OpenRecentLevel=
diff --git a/stuff/profiles/layouts/shortcuts/otharmony.ini b/stuff/profiles/layouts/shortcuts/otharmony.ini
new file mode 100644
index 0000000..8464172
--- /dev/null
+++ b/stuff/profiles/layouts/shortcuts/otharmony.ini
@@ -0,0 +1,366 @@
+[shortcuts]
+MI_LoadRecentImage=
+A_ToolOption_FrameRange=
+A_ToolOption_SegmentInk=
+A_ToolOption_Selective=
+A_ToolOption_Type%3ARectangular=
+MI_BringForward=Ctrl+PgUp
+MI_BringToFront=Ctrl+Shift+PgUp
+MI_Clear=Delete
+MI_Copy=Ctrl+C
+MI_Cut=Ctrl+X
+MI_DrawingSubBackward=[
+MI_DrawingSubForward=]
+MI_DrawingSubGroupBackward=Ctrl+[
+MI_DrawingSubGroupForward=Ctrl+]
+MI_Duplicate=
+MI_FullScreenWindow=Ctrl+F
+MI_FxParamEditor=
+MI_Group=Ctrl+G
+MI_Insert=Ins
+MI_InsertFx=
+MI_LoadScene=Ctrl+O
+MI_MaximizePanel=`
+MI_NewScene=Ctrl+N
+MI_NextDrawing=G
+MI_NextFrame=.
+MI_OpacityCheck=
+MI_Paste=Ctrl+V
+MI_PrevDrawing=F
+MI_PrevFrame=","
+MI_Preview=
+MI_Quit=Ctrl+Q
+MI_Redo=Ctrl+Shift+Z
+MI_SaveScene=Ctrl+Shift+S
+MI_SaveSceneAs=Ctrl+Shift+Alt+S
+MI_SelectAll=Ctrl+A
+MI_SendBack=Ctrl+PgDown
+MI_SendBackward=Ctrl+Shift+PgDown
+MI_Undo=Ctrl+Z
+MI_ZeroThick=
+T_ActualPixelSize=
+T_Brush=Alt+B
+T_ControlPointEditor=Alt+Q
+T_Edit=Shift+T
+T_Eraser=Alt+E
+T_Fill=Alt+I
+T_Geometric=Alt+7
+T_Hand=
+T_Pinch=
+T_Rotate=
+T_Selection=Alt+S
+T_StylePicker=Alt+D
+T_Tape=Alt+C
+T_Type=Alt+9
+T_Zoom=Alt+Z
+T_ZoomReset=
+T_Zoomin=2
+T_Zoomout=1
+A_DecreaseBrushHardness=
+A_DecreaseMaxBrushThickness=
+A_DecreaseMinBrushThickness=
+A_FxSchematicToggle=
+A_IncreaseBrushHardness=
+A_IncreaseMaxBrushThickness=
+A_IncreaseMinBrushThickness=
+A_ToolOption_AutoGroup=
+A_ToolOption_AutoSelect%3AColumn=
+A_ToolOption_AutoSelect%3ANone=
+A_ToolOption_AutoSelect%3APegbar=
+A_ToolOption_AutoSelectDrawing=
+A_ToolOption_Autofill=
+A_ToolOption_BreakSharpAngles=
+A_ToolOption_BrushPreset=
+A_ToolOption_EditToolActiveAxis=
+A_ToolOption_EditToolActiveAxis%3ACenter=
+A_ToolOption_EditToolActiveAxis%3APosition=Alt+2
+A_ToolOption_EditToolActiveAxis%3ARotation=Alt+3
+A_ToolOption_EditToolActiveAxis%3AScale=Alt+4
+A_ToolOption_EditToolActiveAxis%3AShear=Alt+5
+A_ToolOption_GeometricEdge=
+A_ToolOption_GeometricShape=
+A_ToolOption_GlobalKey=
+A_ToolOption_IK=
+A_ToolOption_Invert=
+A_ToolOption_JoinVectors=
+A_ToolOption_Manual=
+A_ToolOption_Meshify=
+A_ToolOption_Mode=
+A_ToolOption_Mode%3AAreas=
+A_ToolOption_Mode%3ALines=
+A_ToolOption_Mode%3ALines%20%26%20Areas=
+A_ToolOption_OnionSkin=
+A_ToolOption_Orientation=
+A_ToolOption_PencilMode=
+A_ToolOption_PickScreen=
+A_ToolOption_PreserveThickness=
+A_ToolOption_PressureSensitivity=
+A_ToolOption_ShowOnlyActiveSkeleton=
+A_ToolOption_SkeletonMode%3AAnimate=
+A_ToolOption_SkeletonMode%3ABuild%20Skeleton=
+A_ToolOption_SkeletonMode%3AInverse%20Kinematics=
+A_ToolOption_Smooth=
+A_ToolOption_Snap=
+A_ToolOption_Type=
+A_ToolOption_Type%3AFreehand=
+A_ToolOption_Type%3ANormal=
+A_ToolOption_Type%3APolyline=
+A_ToolOption_TypeFont=
+A_ToolOption_TypeSize=
+A_ToolOption_TypeStyle=
+MI_ACheck=
+MI_About=
+MI_ActivateAllColumns=
+MI_ActivateSelectedColumns=
+MI_ActivateThisColumnOnly=
+MI_AddFrames=
+MI_AddToBatchCleanupList=
+MI_AddToBatchRenderList=
+MI_AdjustLevels=
+MI_AdjustThickness=
+MI_Antialias=
+MI_ApplyMatchLines=
+MI_AutoFillToggle=
+MI_Autocenter=
+MI_Autorenumber=
+MI_BCheck=
+MI_Binarize=
+MI_BlendColors=
+MI_BlueChannel=
+MI_BlueChannelGreyscale=
+MI_BrightnessAndContrast=
+MI_CameraSettings=
+MI_CameraStage=
+MI_CameraTest=
+MI_CanvasSize=
+MI_Cleanup=
+MI_CleanupPreview=
+MI_CleanupSettings=
+MI_ClearRecentImage=
+MI_ClearRecentLevel=
+MI_ClearRecentScene=
+MI_CloneChild=
+MI_CloneLevel=
+MI_ClonePreview=
+MI_CloseChild=
+MI_Collapse=0
+MI_CollectAssets=
+MI_CompareToSnapshot=
+MI_ConvertFileWithInput=
+MI_ConvertFiles=
+MI_ConvertToVectors=
+MI_DeactivateAllColumns=
+MI_DeactivateSelectedColumns=
+MI_DeactivateUpperColumns=
+MI_DecreaseStep=-
+MI_DefineScanner=
+MI_DeleteInk=
+MI_DeleteMatchLines=
+MI_DisableAllColumns=
+MI_DisableSelectedColumns=Alt+H
+MI_DockingCheck=
+MI_Dup=
+MI_DuplicateFile=
+MI_Each2=
+MI_Each3=
+MI_Each4=
+MI_EditLevel=
+MI_EditShift=
+MI_EnableAllColumns=Alt+Shift+H
+MI_EnableSelectedColumns=
+MI_EnableThisColumnOnly=
+MI_EnterGroup=Ctrl+Return
+MI_EraseUnusedStyles=
+MI_ExitGroup=Backspace
+MI_ExplodeChild=Ctrl+B
+MI_ExportLevel=
+MI_ExportScenes=
+MI_ExposeResource=
+MI_FieldGuide="Ctrl+'"
+MI_FileInfo=
+MI_FillAreas=
+MI_FillLines=
+MI_FirstFrame="Shift+<"
+MI_FoldColumns=
+MI_FrezzePreview=
+MI_GCheck=
+MI_GetColorFromStudioPalette=
+MI_GreenChannel=
+MI_GreenChannelGreyscale=
+MI_Histogram=
+MI_ICheck=
+MI_IOnly=
+MI_ImportMagpieFile=
+MI_ImportScenes=
+MI_IncreaseStep="+"
+MI_Increment=
+MI_Ink1Check=
+MI_InsertGlobalKeyframe=
+MI_InsertSceneFrame=
+MI_InvertKeyframeSelection=
+MI_InvertSelection=
+MI_LastFrame="Shift+>"
+MI_LevelSettings=
+MI_LinesFade=
+MI_Link=
+MI_LoadColorModel=
+MI_LoadFolder=
+MI_LoadLevel=
+MI_LoadSubSceneFile=
+MI_LockAllColumns=Ctrl+Shift+L
+MI_LockSelectedColumns=Ctrl+Alt+L
+MI_LockThisColumnOnly=
+MI_Loop=
+MI_MatteChannel=
+MI_MergeCmapped=
+MI_MergeColumns=
+MI_MergeFrames=
+MI_NewLevel=
+MI_NewOutputFx=
+MI_NewProject=
+MI_NextStep=
+MI_NoShift=
+MI_OnionSkin=Alt+O
+MI_OpenBatchServers=
+MI_OpenChild=
+MI_OpenCleanupSettings=
+MI_OpenColorModel=
+MI_OpenComboViewer=
+MI_OpenFileBrowser=
+MI_OpenFileBrowser2=
+MI_OpenFileViewer=
+MI_OpenFilmStrip=
+MI_OpenFunctionEditor=Alt+F
+MI_OpenHistoryPanel=
+MI_OpenLevelView=
+MI_OpenPalette=
+MI_OpenPltGizmo=
+MI_OpenRecentScene=
+MI_OpenSchematic=
+MI_OpenScriptConsole=
+MI_OpenStudioPalette=
+MI_OpenStyleControl=
+MI_OpenTMessage=
+MI_OpenTasks=
+MI_OpenToolOptionBar=
+MI_OpenToolbar=
+MI_OpenXshView=
+MI_OutputSettings=
+MI_OverwritePalette=
+MI_PCheck=
+MI_PasteColors=
+MI_PasteInto=
+MI_PasteNames=
+MI_PasteValues=
+MI_Pause=
+MI_PencilTest=
+MI_PickStyleAreas=
+MI_PickStyleLines=
+MI_Play=Ctrl+Return
+MI_Preferences=Ctrl+U
+MI_PrevStep=
+MI_PreviewFx=
+MI_PreviewSettings=
+MI_Print=
+MI_PrintXsheet=
+MI_ProjectSettings=
+MI_Random=
+MI_RasterizePli=
+MI_RedChannel=
+MI_RedChannelGreyscale=
+MI_Reframe1=
+MI_Reframe2=
+MI_Reframe3=
+MI_Reframe4=
+MI_RefreshTree=
+MI_RegenerateFramePr=
+MI_RegeneratePreview=
+MI_ReloadStyle=
+MI_RemoveEndpoints=
+MI_RemoveGlobalKeyframe=
+MI_RemoveLevel=
+MI_RemoveSceneFrame=
+MI_RemoveUnused=
+MI_Render=
+MI_Renumber=
+MI_ReplaceLevel=
+MI_ReplaceParentDirectory=
+MI_Resequence=
+MI_ResetInterpolation=
+MI_ResetRoomLayout=
+MI_ResetScanCropbox=
+MI_ResetShift=
+MI_ResetStep=
+MI_Reverse=
+MI_RevertScene=
+MI_RevertToCleanedUp=
+MI_RevertToLastSaved=
+MI_Rolldown=
+MI_Rollup=
+MI_RunScript=
+MI_SafeArea=
+MI_SaveAll=Ctrl+S
+MI_SaveDefaultSettings=
+MI_SaveLevel=
+MI_SaveLevelAs=
+MI_SavePaletteAs=
+MI_SavePreset=
+MI_SavePreviewedFrames=
+MI_SaveSubxsheetAs=
+MI_Scan=Ctrl+Shift+S
+MI_ScanSettings=
+MI_SceneSettings=
+MI_SelectAllKeyframes=
+MI_SelectAllKeyframesNotAfter=
+MI_SelectAllKeyframesNotBefore=
+MI_SelectColumnKeyframes=
+MI_SelectFollowingKeysInColumn=
+MI_SelectFollowingKeysInRow=
+MI_SelectPreviousKeysInColumn=
+MI_SelectPreviousKeysInRow=
+MI_SelectRowKeyframes=
+MI_SetAcceleration=
+MI_SetConstantSpeed=
+MI_SetDeceleration=
+MI_SetKeyframes=F6
+MI_SetScanCropbox=
+MI_ShiftTrace=
+MI_ShortcutPopup=
+MI_ShowFolderContents=
+MI_Step2=
+MI_Step3=
+MI_Step4=
+MI_SwapEnabledColumns=
+MI_Swing=
+MI_TCheck=
+MI_TimeStretch=
+MI_ToggleColumnLocks=
+MI_ToggleColumnsActivation=
+MI_ToggleEditInPlace=
+MI_Tracking=
+MI_Ungroup=Ctrl+Shift+G
+MI_UnlockAllColumns=Ctrl+Alt+Shift+K
+MI_UnlockSelectedColumns=Ctrl+Shift+K
+MI_ViewBBox=
+MI_ViewCamera=
+MI_ViewColorcard=
+MI_ViewFile=
+MI_ViewGuide="Ctrl+'"
+MI_ViewRuler=
+MI_ViewTable=
+T_Bender=
+T_Cutter=Alt+T
+T_Finger=
+T_Hook=
+T_Iron=
+T_Magnet=
+T_PaintBrush=
+T_Plastic=
+T_Pump=
+T_RGBPicker=
+T_Ruler=
+T_ShowHideFullScreen=
+T_Skeleton=
+T_Tracker=
+T_ZoomFit=
+MI_OpenRecentLevel=
diff --git a/stuff/profiles/layouts/shortcuts/otretas.ini b/stuff/profiles/layouts/shortcuts/otretas.ini
new file mode 100644
index 0000000..7a1b172
--- /dev/null
+++ b/stuff/profiles/layouts/shortcuts/otretas.ini
@@ -0,0 +1,366 @@
+[shortcuts]
+MI_LoadRecentImage=
+A_ToolOption_FrameRange=
+A_ToolOption_SegmentInk=
+A_ToolOption_Selective=
+A_ToolOption_Type%3ARectangular=
+MI_BringForward=Ctrl+Up
+MI_BringToFront=Ctrl+Shift+Up
+MI_Clear=Delete
+MI_Copy=Ctrl+C
+MI_Cut=Ctrl+X
+MI_DrawingSubBackward=[
+MI_DrawingSubForward=]
+MI_DrawingSubGroupBackward=Ctrl+[
+MI_DrawingSubGroupForward=Ctrl+]
+MI_Duplicate=
+MI_FullScreenWindow=Ctrl+F
+MI_FxParamEditor=
+MI_Group=Ctrl+G
+MI_Insert=Ins
+MI_InsertFx=
+MI_LoadScene=Ctrl+O
+MI_MaximizePanel=
+MI_NewScene=Ctrl+N
+MI_NextDrawing=G
+MI_NextFrame=.
+MI_OpacityCheck=
+MI_Paste=Ctrl+V
+MI_PrevDrawing=F
+MI_PrevFrame=","
+MI_Preview=Alt+P
+MI_Quit=Ctrl+Q
+MI_Redo=Ctrl+Y
+MI_SaveScene=Ctrl+Shift+S
+MI_SaveSceneAs=Ctrl+Alt+Shift+S
+MI_SelectAll=Shift+A
+MI_SendBack=Ctrl+Shift+Down
+MI_SendBackward=Ctrl+Down
+MI_Undo=Ctrl+Z
+MI_ZeroThick=D
+T_ActualPixelSize=
+T_Brush=Alt+B
+T_ControlPointEditor=Alt+A
+T_Edit=Alt+Q
+T_Eraser=Alt+E
+T_Fill=Alt+K
+T_Geometric=Atl+R
+T_Hand=
+T_Pinch=
+T_Rotate=
+T_Selection=Alt+V
+T_StylePicker=Alt+I
+T_Tape=Alt+C
+T_Type=
+T_Zoom=Alt+Z
+T_ZoomReset=Shift+Z
+T_Zoomin=Ctrl+=
+T_Zoomout=Ctrl+-
+A_DecreaseBrushHardness=
+A_DecreaseMaxBrushThickness=
+A_DecreaseMinBrushThickness=
+A_FxSchematicToggle=
+A_IncreaseBrushHardness=
+A_IncreaseMaxBrushThickness=
+A_IncreaseMinBrushThickness=
+A_ToolOption_AutoGroup=
+A_ToolOption_AutoSelect%3AColumn=
+A_ToolOption_AutoSelect%3ANone=
+A_ToolOption_AutoSelect%3APegbar=
+A_ToolOption_AutoSelectDrawing=
+A_ToolOption_Autofill=
+A_ToolOption_BreakSharpAngles=
+A_ToolOption_BrushPreset=
+A_ToolOption_EditToolActiveAxis=
+A_ToolOption_EditToolActiveAxis%3ACenter=
+A_ToolOption_EditToolActiveAxis%3APosition=
+A_ToolOption_EditToolActiveAxis%3ARotation=
+A_ToolOption_EditToolActiveAxis%3AScale=
+A_ToolOption_EditToolActiveAxis%3AShear=
+A_ToolOption_GeometricEdge=
+A_ToolOption_GeometricShape=
+A_ToolOption_GlobalKey=
+A_ToolOption_IK=Alt+8
+A_ToolOption_Invert=
+A_ToolOption_JoinVectors=
+A_ToolOption_Manual=
+A_ToolOption_Meshify=
+A_ToolOption_Mode=
+A_ToolOption_Mode%3AAreas=
+A_ToolOption_Mode%3ALines=
+A_ToolOption_Mode%3ALines%20%26%20Areas=
+A_ToolOption_OnionSkin=
+A_ToolOption_Orientation=
+A_ToolOption_PencilMode=
+A_ToolOption_PickScreen=
+A_ToolOption_PreserveThickness=
+A_ToolOption_PressureSensitivity=
+A_ToolOption_ShowOnlyActiveSkeleton=
+A_ToolOption_SkeletonMode%3AAnimate=
+A_ToolOption_SkeletonMode%3ABuild%20Skeleton=
+A_ToolOption_SkeletonMode%3AInverse%20Kinematics=
+A_ToolOption_Smooth=
+A_ToolOption_Snap=
+A_ToolOption_Type=
+A_ToolOption_Type%3AFreehand=
+A_ToolOption_Type%3ANormal=
+A_ToolOption_Type%3APolyline=
+A_ToolOption_TypeFont=
+A_ToolOption_TypeSize=
+A_ToolOption_TypeStyle=
+MI_ACheck=
+MI_About=
+MI_ActivateAllColumns=
+MI_ActivateSelectedColumns=
+MI_ActivateThisColumnOnly=
+MI_AddFrames=Ctrl+H
+MI_AddToBatchCleanupList=
+MI_AddToBatchRenderList=
+MI_AdjustLevels=
+MI_AdjustThickness=
+MI_Antialias=
+MI_ApplyMatchLines=
+MI_AutoFillToggle=
+MI_Autocenter=
+MI_Autorenumber=
+MI_BCheck=
+MI_Binarize=
+MI_BlendColors=
+MI_BlueChannel=
+MI_BlueChannelGreyscale=
+MI_BrightnessAndContrast=
+MI_CameraSettings=
+MI_CameraStage=
+MI_CameraTest=
+MI_CanvasSize=
+MI_Cleanup=
+MI_CleanupPreview=
+MI_CleanupSettings=
+MI_ClearRecentImage=
+MI_ClearRecentLevel=
+MI_ClearRecentScene=
+MI_CloneChild=
+MI_CloneLevel=
+MI_ClonePreview=
+MI_CloseChild=
+MI_Collapse=
+MI_CollectAssets=
+MI_CompareToSnapshot=
+MI_ConvertFileWithInput=
+MI_ConvertFiles=
+MI_ConvertToVectors=
+MI_DeactivateAllColumns=
+MI_DeactivateSelectedColumns=Alt+H
+MI_DeactivateUpperColumns=
+MI_DecreaseStep=
+MI_DefineScanner=
+MI_DeleteInk=
+MI_DeleteMatchLines=
+MI_DisableAllColumns=
+MI_DisableSelectedColumns=
+MI_DockingCheck=
+MI_Dup=
+MI_DuplicateFile=
+MI_Each2=
+MI_Each3=
+MI_Each4=
+MI_EditLevel=
+MI_EditShift=
+MI_EnableAllColumns=Alt+Shift+H
+MI_EnableSelectedColumns=
+MI_EnableThisColumnOnly=
+MI_EnterGroup=Ctrl+Return
+MI_EraseUnusedStyles=
+MI_ExitGroup=Backspace
+MI_ExplodeChild=Ctrl+B
+MI_ExportLevel=
+MI_ExportScenes=
+MI_ExposeResource=
+MI_FieldGuide="Ctrl+'"
+MI_FileInfo=
+MI_FillAreas=
+MI_FillLines=
+MI_FirstFrame=Home
+MI_FoldColumns=
+MI_FrezzePreview=
+MI_GCheck=
+MI_GetColorFromStudioPalette=
+MI_GreenChannel=
+MI_GreenChannelGreyscale=
+MI_Histogram=
+MI_ICheck=
+MI_IOnly=
+MI_ImportMagpieFile=
+MI_ImportScenes=
+MI_IncreaseStep="+"
+MI_Increment=
+MI_Ink1Check=
+MI_InsertGlobalKeyframe=
+MI_InsertSceneFrame=
+MI_InvertKeyframeSelection=
+MI_InvertSelection=
+MI_LastFrame=End
+MI_LevelSettings=
+MI_LinesFade=
+MI_Link=
+MI_LoadColorModel=
+MI_LoadFolder=
+MI_LoadLevel=
+MI_LoadSubSceneFile=
+MI_LockAllColumns=
+MI_LockSelectedColumns=
+MI_LockThisColumnOnly=
+MI_Loop=
+MI_MatteChannel=
+MI_MergeCmapped=
+MI_MergeColumns=
+MI_MergeFrames=
+MI_NewLevel=
+MI_NewOutputFx=
+MI_NewProject=
+MI_NextStep=
+MI_NoShift=
+MI_OnionSkin=Ctrl+Alt+O
+MI_OpenBatchServers=
+MI_OpenChild=
+MI_OpenCleanupSettings=
+MI_OpenColorModel=
+MI_OpenComboViewer=
+MI_OpenFileBrowser=
+MI_OpenFileBrowser2=
+MI_OpenFileViewer=
+MI_OpenFilmStrip=
+MI_OpenFunctionEditor=Alt+F
+MI_OpenHistoryPanel=
+MI_OpenLevelView=
+MI_OpenPalette=
+MI_OpenPltGizmo=
+MI_OpenRecentScene=
+MI_OpenSchematic=
+MI_OpenScriptConsole=
+MI_OpenStudioPalette=
+MI_OpenStyleControl=
+MI_OpenTMessage=
+MI_OpenTasks=
+MI_OpenToolOptionBar=
+MI_OpenToolbar=
+MI_OpenXshView=
+MI_OutputSettings=
+MI_OverwritePalette=
+MI_PCheck=
+MI_PasteColors=
+MI_PasteInto=
+MI_PasteNames=
+MI_PasteValues=
+MI_Pause=
+MI_PencilTest=
+MI_PickStyleAreas=
+MI_PickStyleLines=
+MI_Play=Return
+MI_Preferences=Ctrl+U
+MI_PrevStep=
+MI_PreviewFx=
+MI_PreviewSettings=
+MI_Print=
+MI_PrintXsheet=
+MI_ProjectSettings=
+MI_Random=
+MI_RasterizePli=
+MI_RedChannel=
+MI_RedChannelGreyscale=
+MI_Reframe1=
+MI_Reframe2=
+MI_Reframe3=
+MI_Reframe4=
+MI_RefreshTree=
+MI_RegenerateFramePr=
+MI_RegeneratePreview=
+MI_ReloadStyle=
+MI_RemoveEndpoints=
+MI_RemoveGlobalKeyframe=
+MI_RemoveLevel=
+MI_RemoveSceneFrame=
+MI_RemoveUnused=
+MI_Render=Ctrl+Alt+Shift+S
+MI_Renumber=
+MI_ReplaceLevel=
+MI_ReplaceParentDirectory=
+MI_Resequence=
+MI_ResetInterpolation=
+MI_ResetRoomLayout=
+MI_ResetScanCropbox=
+MI_ResetShift=
+MI_ResetStep=
+MI_Reverse=
+MI_RevertScene=
+MI_RevertToCleanedUp=
+MI_RevertToLastSaved=
+MI_Rolldown=
+MI_Rollup=
+MI_RunScript=
+MI_SafeArea=
+MI_SaveAll=Ctrl+S
+MI_SaveDefaultSettings=
+MI_SaveLevel=
+MI_SaveLevelAs=
+MI_SavePaletteAs=
+MI_SavePreset=
+MI_SavePreviewedFrames=
+MI_SaveSubxsheetAs=
+MI_Scan=
+MI_ScanSettings=
+MI_SceneSettings=Ctrl+F3
+MI_SelectAllKeyframes=
+MI_SelectAllKeyframesNotAfter=
+MI_SelectAllKeyframesNotBefore=
+MI_SelectColumnKeyframes=
+MI_SelectFollowingKeysInColumn=
+MI_SelectFollowingKeysInRow=
+MI_SelectPreviousKeysInColumn=
+MI_SelectPreviousKeysInRow=
+MI_SelectRowKeyframes=
+MI_SetAcceleration=
+MI_SetConstantSpeed=
+MI_SetDeceleration=
+MI_SetKeyframes=Ctrl+F6
+MI_SetScanCropbox=
+MI_ShiftTrace=
+MI_ShortcutPopup=
+MI_ShowFolderContents=
+MI_Step2=
+MI_Step3=
+MI_Step4=
+MI_SwapEnabledColumns=
+MI_Swing=
+MI_TCheck=
+MI_TimeStretch=
+MI_ToggleColumnLocks=
+MI_ToggleColumnsActivation=
+MI_ToggleEditInPlace=
+MI_Tracking=
+MI_Ungroup=Ctrl+Shift+G
+MI_UnlockAllColumns=Ctrl+Alt+Shift+L
+MI_UnlockSelectedColumns=Ctrl+Shift+K
+MI_ViewBBox=
+MI_ViewCamera=
+MI_ViewColorcard=
+MI_ViewFile=
+MI_ViewGuide=
+MI_ViewRuler=Ctrl+Alt+Shift+R
+MI_ViewTable=
+T_Bender=
+T_Cutter=Alt+T
+T_Finger=
+T_Hook=
+T_Iron=
+T_Magnet=
+T_PaintBrush=
+T_Plastic=
+T_Pump=
+T_RGBPicker=
+T_Ruler=
+T_ShowHideFullScreen=F4
+T_Skeleton=
+T_Tracker=
+T_ZoomFit=
+MI_OpenRecentLevel=
diff --git a/thirdparty/libpng-1.6.21/lib/libpng16_2015.lib b/thirdparty/libpng-1.6.21/lib/libpng16_2015.lib
index ca4827f..1e7bbcf 100644
--- a/thirdparty/libpng-1.6.21/lib/libpng16_2015.lib
+++ b/thirdparty/libpng-1.6.21/lib/libpng16_2015.lib
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:1d6be973caafd36b6dcf9b8fcb2d030ad2e0c3c523527fad7bbf7da9f9ba5b6e
-size 56118
+oid sha256:e005a1c28ab5a1f8ed57793a79c883f0b44cd5d2b25152544e3dca5fbdd616bc
+size 374568
diff --git a/thirdparty/libpng-1.6.21/lib/libpng16_2015d.lib b/thirdparty/libpng-1.6.21/lib/libpng16_2015d.lib
index a94d492..1859771 100644
--- a/thirdparty/libpng-1.6.21/lib/libpng16_2015d.lib
+++ b/thirdparty/libpng-1.6.21/lib/libpng16_2015d.lib
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:be7784d0f86cf87b9dd965a32707e1a999b059d57fbeddb4066a033200e0fbc9
-size 56118
+oid sha256:f61acffbae2925d60a61bd11b6d5b09502843c89c8b3f20b89f240e050a1e916
+size 858596
diff --git a/thirdparty/tiff-4.0.3/libtiff/tif_config.vc.h b/thirdparty/tiff-4.0.3/libtiff/tif_config.vc.h
index c297cf3..859a606 100644
--- a/thirdparty/tiff-4.0.3/libtiff/tif_config.vc.h
+++ b/thirdparty/tiff-4.0.3/libtiff/tif_config.vc.h
@@ -47,7 +47,9 @@
/* Set the native cpu bit order */
#define HOST_FILLORDER FILLORDER_LSB2MSB
+#if defined(_MSC_VER) && (_MSC_VER < 1900)
#define snprintf _snprintf
+#endif
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
diff --git a/toonz/sources/common/tapptools/tcolorutils.cpp b/toonz/sources/common/tapptools/tcolorutils.cpp
index 8203a5c..2a620a1 100644
--- a/toonz/sources/common/tapptools/tcolorutils.cpp
+++ b/toonz/sources/common/tapptools/tcolorutils.cpp
@@ -182,7 +182,8 @@ void chooseLeafToClusterize(ClusterContainer::iterator &itRet,
const KEYER_FLOAT *clusterCovariance = cluster->statistic.covariance;
assert(!ISNAN(clusterCovariance[0]));
- // Calculate the eigenvalues of the covariance matrix of the cluster statistics
+ // Calculate the eigenvalues of the covariance matrix of the cluster
+ // statistics
// (because the array is symmetrical the eigenvalues are all real)
KEYER_FLOAT eigenValues[3];
tmpMulteplicity = calcCovarianceEigenValues(clusterCovariance, eigenValues);
diff --git a/toonz/sources/common/tgeometry/tcurveutil.cpp b/toonz/sources/common/tgeometry/tcurveutil.cpp
index 87140c3..ff0c3b4 100644
--- a/toonz/sources/common/tgeometry/tcurveutil.cpp
+++ b/toonz/sources/common/tgeometry/tcurveutil.cpp
@@ -284,7 +284,8 @@ int intersect(const TQuadratic &c0, const TQuadratic &c1,
// This function checks whether the control point
// p1 is very close to p0 or p2.
// In this case, we are approximated to the quadratic p0-p2 segment.
-// If p1 is near p0, the relationship between the original and the quadratic segment:
+// If p1 is near p0, the relationship between the original and the quadratic
+// segment:
// tq = sqrt(ts),
// If p1 is near p2, instead it's:
// tq = 1-sqrt(1-ts).
diff --git a/toonz/sources/common/tsystem/tfilepath.cpp b/toonz/sources/common/tsystem/tfilepath.cpp
index 215a042..d16a1a3 100644
--- a/toonz/sources/common/tsystem/tfilepath.cpp
+++ b/toonz/sources/common/tsystem/tfilepath.cpp
@@ -480,6 +480,7 @@ bool TFilePath::isRoot() const {
// ritorna ""(niente tipo, niente punto), "." (file con tipo) o ".." (file con
// tipo e frame)
std::string TFilePath::getDots() const {
+ if (isFfmpegType()) return ".";
int i = getLastSlash(m_path);
std::wstring str = m_path.substr(i + 1);
// potrei anche avere a.b.c.d dove d e' l'estensione
@@ -561,7 +562,7 @@ std::string TFilePath::getLevelName() const {
std::wstring TFilePath::getLevelNameW() const {
int i = getLastSlash(m_path); // cerco l'ultimo slash
std::wstring str = m_path.substr(i + 1); // str e' m_path senza directory
-
+ if (isFfmpegType()) return str;
int j = str.rfind(L"."); // str[j..] = ".type"
if (j == (int)std::wstring::npos) return str; // no frame; no type
i = str.substr(0, j).rfind(L'.');
@@ -597,6 +598,7 @@ TFilePath TFilePath::getParentDir() const // noSlash!
//-----------------------------------------------------------------------------
bool TFilePath::isLevelName() const {
+ if (isFfmpegType()) return false;
try {
return getFrame() == TFrameId(TFrameId::EMPTY_FRAME);
}
@@ -638,6 +640,15 @@ TFrameId TFilePath::getFrame() const {
//-----------------------------------------------------------------------------
+bool TFilePath::isFfmpegType() const {
+ QString type = QString::fromStdString(getType()).toLower();
+ if (type == "gif" || type == "mp4" || type == "webm")
+ return true;
+ else
+ return false;
+}
+
+//-----------------------------------------------------------------------------
TFilePath TFilePath::withType(const std::string &type) const {
assert(type.length() < 2 || type.substr(0, 2) != "..");
int i = getLastSlash(m_path); // cerco l'ultimo slash
diff --git a/toonz/sources/common/tvrender/tcolorstyles.cpp b/toonz/sources/common/tvrender/tcolorstyles.cpp
index 3b18ce5..a67f8f1 100644
--- a/toonz/sources/common/tvrender/tcolorstyles.cpp
+++ b/toonz/sources/common/tvrender/tcolorstyles.cpp
@@ -50,7 +50,8 @@ TColorStyle::TColorStyle()
, m_enabled(true)
, m_icon(0)
, m_validIcon(false)
- , m_isEditedFromOriginal(false) {}
+ , m_isEditedFromOriginal(false)
+ , m_pickedPosition() {}
//-------------------------------------------------------------------
@@ -66,7 +67,8 @@ TColorStyle::TColorStyle(const TColorStyle &other)
, m_flags(other.m_flags)
, m_enabled(other.m_enabled)
, m_validIcon(false)
- , m_isEditedFromOriginal(other.m_isEditedFromOriginal) {}
+ , m_isEditedFromOriginal(other.m_isEditedFromOriginal)
+ , m_pickedPosition(other.m_pickedPosition) {}
//-------------------------------------------------------------------
@@ -79,6 +81,7 @@ TColorStyle &TColorStyle::operator=(const TColorStyle &other) {
m_enabled = other.m_enabled;
m_validIcon = false;
m_isEditedFromOriginal = other.m_isEditedFromOriginal;
+ m_pickedPosition = other.m_pickedPosition;
return *this;
}
@@ -100,6 +103,7 @@ bool TColorStyle::operator==(const TColorStyle &cs) const {
if (m_originalName != cs.getOriginalName()) return false;
if (m_globalName != cs.getGlobalName()) return false;
if (m_isEditedFromOriginal != cs.getIsEditedFlag()) return false;
+ if (m_pickedPosition != cs.getPickedPosition()) return false;
for (int p = 0; p < colorParamCount; ++p)
if (getColorParamValue(p) != cs.getColorParamValue(p)) return false;
diff --git a/toonz/sources/common/tvrender/tpalette.cpp b/toonz/sources/common/tvrender/tpalette.cpp
index f3e229e..ad236ef 100644
--- a/toonz/sources/common/tvrender/tpalette.cpp
+++ b/toonz/sources/common/tvrender/tpalette.cpp
@@ -15,6 +15,7 @@
#include "tpalette.h"
#include
+#include
PERSIST_IDENTIFIER(TPalette, "palette")
@@ -30,6 +31,21 @@ namespace {
const int maxStyleIndex = 32765;
+const std::string pointToString(const TPoint &point) {
+ return std::to_string(point.x) + "," + std::to_string(point.y);
+}
+
+// splitting string with ','
+const TPoint stringToPoint(const std::string &string) {
+ std::string buffer;
+ std::stringstream ss(string);
+ std::getline(ss, buffer, ','); // getting the first part of string
+ int x = std::stoi(buffer);
+ std::getline(ss, buffer); // getting the second part of string
+ int y = std::stoi(buffer);
+ return TPoint(x, y);
+}
+
} // namespace
//===================================================================
@@ -564,10 +580,17 @@ void TPalette::saveData(TOStream &os) {
os.openChild("styles");
{
for (int i = 0; i < getStyleCount(); ++i) {
- os.openChild("style");
+ TColorStyleP style = m_styles[i].second;
+ if (style->getPickedPosition() == TPoint())
+ os.openChild("style");
+ else {
+ std::map attr;
+ attr["pickedpos"] = pointToString(style->getPickedPosition());
+ os.openChild("style", attr);
+ }
{
StyleWriter w(os, i);
- m_styles[i].second->save(w);
+ style->save(w);
}
os.closeChild();
}
@@ -681,6 +704,10 @@ void TPalette::loadData(TIStream &is) {
StyleReader r(is, version);
TColorStyle *cs = TColorStyle::load(r);
+ std::string pickedPosStr;
+ if (is.getTagParam("pickedpos", pickedPosStr))
+ cs->setPickedPosition(stringToPoint(pickedPosStr));
+
addStyle(cs);
}
@@ -1096,6 +1123,18 @@ void TPalette::setShortcutValue(int key, int styleId) {
}
//-------------------------------------------------------------------
+// Returns true if there is at least one style with picked pos value
+//-------------------------------------------------------------------
+
+bool TPalette::hasPickedPosStyle() {
+ for (int i = 0; i < getStyleCount(); ++i) {
+ TColorStyleP style = m_styles[i].second;
+ if (style->getPickedPosition() != TPoint()) return true;
+ }
+ return false;
+}
+
+//-------------------------------------------------------------------
void TPalette::nextShortcutScope(bool invert) {
if (invert) {
diff --git a/toonz/sources/image/CMakeLists.txt b/toonz/sources/image/CMakeLists.txt
index d0a19c2..b610a1d 100644
--- a/toonz/sources/image/CMakeLists.txt
+++ b/toonz/sources/image/CMakeLists.txt
@@ -69,7 +69,7 @@ if(WIN32)
mov/tiio_movW.cpp
3gp/tiio_3gpW.cpp
)
-else()
+elseif(APPLE)
set(HEADERS ${HEADERS}
mov/tiio_movM.h
3gp/tiio_3gpM.h
diff --git a/toonz/sources/image/ffmpeg/tiio_ffmpeg.cpp b/toonz/sources/image/ffmpeg/tiio_ffmpeg.cpp
index 3f35abe..9dd86a1 100644
--- a/toonz/sources/image/ffmpeg/tiio_ffmpeg.cpp
+++ b/toonz/sources/image/ffmpeg/tiio_ffmpeg.cpp
@@ -6,6 +6,7 @@
#include
#include
#include
+#include
#include "toonz/preferences.h"
#include "toonz/toonzfolders.h"
@@ -98,8 +99,9 @@ void Ffmpeg::setFrameRate(double fps) { m_frameRate = fps; }
void Ffmpeg::setPath(TFilePath path) { m_path = path; }
void Ffmpeg::createIntermediateImage(const TImageP &img, int frameIndex) {
+ m_frameCount++;
QString tempPath = m_path.getQString() + "tempOut" +
- QString::number(frameIndex) + "." + m_intermediateFormat;
+ QString::number(m_frameCount) + "." + m_intermediateFormat;
std::string saveStatus = "";
TRasterImageP tempImage(img);
TRasterImage *image = (TRasterImage *)tempImage->cloneImage();
@@ -127,7 +129,7 @@ void Ffmpeg::createIntermediateImage(const TImageP &img, int frameIndex) {
qi->save(tempPath, format, -1);
free(buffer);
m_cleanUpList.push_back(tempPath);
- m_frameCount++;
+
delete qi;
delete image;
}
@@ -217,9 +219,9 @@ void Ffmpeg::saveSoundTrack(TSoundTrack *st) {
bool Ffmpeg::checkFilesExist() {
QString ffmpegCachePath = getFfmpegCache().getQString();
QString tempPath = ffmpegCachePath + "//" +
- QString::fromStdString(m_path.getName()) +
- QString::fromStdString(m_path.getType()) + "In0001." +
- m_intermediateFormat;
+ m_path.getQString().remove(QRegExp(QString::fromUtf8(
+ "[-`~!@#$%^&*()_�+=|:;<>��,.?/{}\'\"\\[\\]\\\\]"))) +
+ "In0001." + m_intermediateFormat;
if (TSystem::doesExistFileOrLevel(TFilePath(tempPath))) {
return true;
} else
@@ -229,8 +231,9 @@ bool Ffmpeg::checkFilesExist() {
ffmpegFileInfo Ffmpeg::getInfo() {
QString ffmpegCachePath = getFfmpegCache().getQString();
QString tempPath = ffmpegCachePath + "//" +
- QString::fromStdString(m_path.getName()) +
- QString::fromStdString(m_path.getType()) + ".txt";
+ m_path.getQString().remove(QRegExp(QString::fromUtf8(
+ "[-`~!@#$%^&*()_�+=|:;<>��,.?/{}\'\"\\[\\]\\\\]"))) +
+ ".txt";
if (QFile::exists(tempPath)) {
QFile infoText(tempPath);
infoText.open(QIODevice::ReadOnly);
@@ -264,8 +267,8 @@ ffmpegFileInfo Ffmpeg::getInfo() {
TRasterImageP Ffmpeg::getImage(int frameIndex) {
QString ffmpegCachePath = getFfmpegCache().getQString();
QString tempPath = ffmpegCachePath + "//" +
- QString::fromStdString(m_path.getName()) +
- QString::fromStdString(m_path.getType());
+ m_path.getQString().remove(QRegExp(QString::fromUtf8(
+ "[-`~!@#$%^&*()_�+=|:;<>��,.?/{}\'\"\\[\\]\\\\]")));
std::string tmpPath = tempPath.toStdString();
// QString tempPath= m_path.getQString();
QString number = QString("%1").arg(frameIndex, 4, 10, QChar('0'));
@@ -356,8 +359,8 @@ int Ffmpeg::getFrameCount() {
void Ffmpeg::getFramesFromMovie(int frame) {
QString ffmpegCachePath = getFfmpegCache().getQString();
QString tempPath = ffmpegCachePath + "//" +
- QString::fromStdString(m_path.getName()) +
- QString::fromStdString(m_path.getType());
+ m_path.getQString().remove(QRegExp(QString::fromUtf8(
+ "[-`~!@#$%^&*()_�+=|:;<>��,.?/{}\'\"\\[\\]\\\\]")));
std::string tmpPath = tempPath.toStdString();
QString tempName = "In%04d." + m_intermediateFormat;
tempName = tempPath + tempName;
@@ -399,6 +402,26 @@ void Ffmpeg::getFramesFromMovie(int frame) {
}
}
+int Ffmpeg::getGifFrameCount() {
+ int frame = 1;
+ QString ffmpegCachePath = getFfmpegCache().getQString();
+ QString tempPath = ffmpegCachePath + "//" +
+ QString::fromStdString(m_path.getName()) +
+ QString::fromStdString(m_path.getType());
+ std::string tmpPath = tempPath.toStdString();
+ QString tempName = "In%04d." + m_intermediateFormat;
+ tempName = tempPath + tempName;
+ QString tempStart;
+ tempStart = "In0001." + m_intermediateFormat;
+ tempStart = tempPath + tempStart;
+ while (TSystem::doesExistFileOrLevel(TFilePath(tempStart))) {
+ frame++;
+ QString number = QString("%1").arg(frame, 4, 10, QChar('0'));
+ tempStart = tempPath + "In" + number + "." + m_intermediateFormat;
+ }
+ return frame - 1;
+}
+
void Ffmpeg::addToCleanUp(QString path) {
if (TSystem::doesExistFileOrLevel(TFilePath(path))) {
m_cleanUpList.push_back(path);
diff --git a/toonz/sources/image/ffmpeg/tiio_ffmpeg.h b/toonz/sources/image/ffmpeg/tiio_ffmpeg.h
index 4b3fe4f..853110a 100644
--- a/toonz/sources/image/ffmpeg/tiio_ffmpeg.h
+++ b/toonz/sources/image/ffmpeg/tiio_ffmpeg.h
@@ -41,6 +41,7 @@ public:
TFilePath getFfmpegCache();
ffmpegFileInfo getInfo();
void disablePrecompute();
+ int getGifFrameCount();
private:
QString m_intermediateFormat, m_ffmpegPath, m_audioPath, m_audioFormat;
diff --git a/toonz/sources/image/ffmpeg/tiio_gif.cpp b/toonz/sources/image/ffmpeg/tiio_gif.cpp
index 089461d..0676b91 100644
--- a/toonz/sources/image/ffmpeg/tiio_gif.cpp
+++ b/toonz/sources/image/ffmpeg/tiio_gif.cpp
@@ -3,6 +3,7 @@
#include "tiio_gif.h"
#include "trasterimage.h"
#include "timageinfo.h"
+#include "toonz/stage.h"
#include
//===========================================================
@@ -151,8 +152,9 @@ class TImageReaderGif final : public TImageReader {
public:
int m_frameIndex;
- TImageReaderGif(const TFilePath &path, int index, TLevelReaderGif *lra)
- : TImageReader(path), m_lra(lra), m_frameIndex(index) {
+ TImageReaderGif(const TFilePath &path, int index, TLevelReaderGif *lra,
+ TImageInfo *info)
+ : TImageReader(path), m_lra(lra), m_frameIndex(index), m_info(info) {
m_lra->addRef();
}
~TImageReaderGif() { m_lra->release(); }
@@ -160,9 +162,11 @@ public:
TImageP load() override { return m_lra->load(m_frameIndex); }
TDimension getSize() const { return m_lra->getSize(); }
TRect getBBox() const { return TRect(); }
+ const TImageInfo *getImageInfo() const override { return m_info; }
private:
TLevelReaderGif *m_lra;
+ TImageInfo *m_info;
// not implemented
TImageReaderGif(const TImageReaderGif &);
@@ -190,7 +194,7 @@ TLevelReaderGif::TLevelReaderGif(const TFilePath &path)
m_ly = m_size.ly;
ffmpegReader->getFramesFromMovie();
-
+ m_frameCount = ffmpegReader->getGifFrameCount();
// set values
m_info = new TImageInfo();
m_info->m_frameRate = fps;
@@ -198,6 +202,8 @@ TLevelReaderGif::TLevelReaderGif(const TFilePath &path)
m_info->m_ly = m_ly;
m_info->m_bitsPerSample = 8;
m_info->m_samplePerPixel = 4;
+ m_info->m_dpix = Stage::standardDpi;
+ m_info->m_dpiy = Stage::standardDpi;
}
//-----------------------------------------------------------
@@ -220,9 +226,8 @@ TImageReaderP TLevelReaderGif::getFrameReader(TFrameId fid) {
// if (IOError != 0)
// throw TImageException(m_path, buildAVIExceptionString(IOError));
if (fid.getLetter() != 0) return TImageReaderP(0);
- int index = fid.getNumber();
-
- TImageReaderGif *irm = new TImageReaderGif(m_path, index, this);
+ int index = fid.getNumber();
+ TImageReaderGif *irm = new TImageReaderGif(m_path, index, this, m_info);
return TImageReaderP(irm);
}
diff --git a/toonz/sources/image/ffmpeg/tiio_mp4.cpp b/toonz/sources/image/ffmpeg/tiio_mp4.cpp
index fb7d9a1..173d627 100644
--- a/toonz/sources/image/ffmpeg/tiio_mp4.cpp
+++ b/toonz/sources/image/ffmpeg/tiio_mp4.cpp
@@ -4,6 +4,7 @@
#include "trasterimage.h"
#include "timageinfo.h"
#include "tsound.h"
+#include "toonz/stage.h"
#include
//===========================================================
@@ -129,8 +130,9 @@ class TImageReaderMp4 final : public TImageReader {
public:
int m_frameIndex;
- TImageReaderMp4(const TFilePath &path, int index, TLevelReaderMp4 *lra)
- : TImageReader(path), m_lra(lra), m_frameIndex(index) {
+ TImageReaderMp4(const TFilePath &path, int index, TLevelReaderMp4 *lra,
+ TImageInfo *info)
+ : TImageReader(path), m_lra(lra), m_frameIndex(index), m_info(info) {
m_lra->addRef();
}
~TImageReaderMp4() { m_lra->release(); }
@@ -138,9 +140,11 @@ public:
TImageP load() override { return m_lra->load(m_frameIndex); }
TDimension getSize() const { return m_lra->getSize(); }
TRect getBBox() const { return TRect(); }
+ const TImageInfo *getImageInfo() const override { return m_info; }
private:
TLevelReaderMp4 *m_lra;
+ TImageInfo *m_info;
// not implemented
TImageReaderMp4(const TImageReaderMp4 &);
@@ -173,6 +177,8 @@ TLevelReaderMp4::TLevelReaderMp4(const TFilePath &path) : TLevelReader(path) {
m_info->m_ly = m_ly;
m_info->m_bitsPerSample = 8;
m_info->m_samplePerPixel = 4;
+ m_info->m_dpix = Stage::standardDpi;
+ m_info->m_dpiy = Stage::standardDpi;
}
//-----------------------------------------------------------
@@ -197,7 +203,7 @@ TImageReaderP TLevelReaderMp4::getFrameReader(TFrameId fid) {
if (fid.getLetter() != 0) return TImageReaderP(0);
int index = fid.getNumber();
- TImageReaderMp4 *irm = new TImageReaderMp4(m_path, index, this);
+ TImageReaderMp4 *irm = new TImageReaderMp4(m_path, index, this, m_info);
return TImageReaderP(irm);
}
diff --git a/toonz/sources/image/ffmpeg/tiio_webm.cpp b/toonz/sources/image/ffmpeg/tiio_webm.cpp
index 0d9e2b2..d780061 100644
--- a/toonz/sources/image/ffmpeg/tiio_webm.cpp
+++ b/toonz/sources/image/ffmpeg/tiio_webm.cpp
@@ -4,6 +4,7 @@
#include "trasterimage.h"
#include "tsound.h"
#include "timageinfo.h"
+#include "toonz/stage.h"
#include
//===========================================================
@@ -133,8 +134,9 @@ class TImageReaderWebm final : public TImageReader {
public:
int m_frameIndex;
- TImageReaderWebm(const TFilePath &path, int index, TLevelReaderWebm *lra)
- : TImageReader(path), m_lra(lra), m_frameIndex(index) {
+ TImageReaderWebm(const TFilePath &path, int index, TLevelReaderWebm *lra,
+ TImageInfo *info)
+ : TImageReader(path), m_lra(lra), m_frameIndex(index), m_info(info) {
m_lra->addRef();
}
~TImageReaderWebm() { m_lra->release(); }
@@ -142,9 +144,11 @@ public:
TImageP load() override { return m_lra->load(m_frameIndex); }
TDimension getSize() const { return m_lra->getSize(); }
TRect getBBox() const { return TRect(); }
+ const TImageInfo *getImageInfo() const override { return m_info; }
private:
TLevelReaderWebm *m_lra;
+ TImageInfo *m_info;
// not implemented
TImageReaderWebm(const TImageReaderWebm &);
@@ -177,6 +181,8 @@ TLevelReaderWebm::TLevelReaderWebm(const TFilePath &path) : TLevelReader(path) {
m_info->m_ly = m_ly;
m_info->m_bitsPerSample = 8;
m_info->m_samplePerPixel = 4;
+ m_info->m_dpix = Stage::standardDpi;
+ m_info->m_dpiy = Stage::standardDpi;
}
//-----------------------------------------------------------
@@ -201,7 +207,7 @@ TImageReaderP TLevelReaderWebm::getFrameReader(TFrameId fid) {
if (fid.getLetter() != 0) return TImageReaderP(0);
int index = fid.getNumber();
- TImageReaderWebm *irm = new TImageReaderWebm(m_path, index, this);
+ TImageReaderWebm *irm = new TImageReaderWebm(m_path, index, this, m_info);
return TImageReaderP(irm);
}
diff --git a/toonz/sources/include/tcolorstyles.h b/toonz/sources/include/tcolorstyles.h
index 1b999e7..2aecdad 100644
--- a/toonz/sources/include/tcolorstyles.h
+++ b/toonz/sources/include/tcolorstyles.h
@@ -118,6 +118,9 @@ private:
// This flag will be set when the
//! style is edited from the original one.
+ TPoint m_pickedPosition; // picked position from color model by using style
+ // picker tool with "organize palette" option.
+
protected:
TRaster32P m_icon; //!< Icon shown on TPalette viewers.
bool m_validIcon; //!< Icon's validity status.
@@ -212,6 +215,9 @@ The \a global name contains information about palette id.
m_flags = flags;
} //!< Returns color attributes.
+ void setPickedPosition(const TPoint &pos) { m_pickedPosition = pos; }
+ TPoint getPickedPosition() const { return m_pickedPosition; }
+
// Color-related functions
/*! \detail
diff --git a/toonz/sources/include/tfilepath.h b/toonz/sources/include/tfilepath.h
index ee04a45..0d58b5a 100644
--- a/toonz/sources/include/tfilepath.h
+++ b/toonz/sources/include/tfilepath.h
@@ -177,7 +177,7 @@ If the path is ":" a slash will be added*/
TFilePath getParentDir() const; // noSlash!;
TFrameId getFrame() const;
-
+ bool isFfmpegType() const;
bool isLevelName()
const; //{return getFrame() == TFrameId(TFrameId::EMPTY_FRAME);};
bool isAbsolute() const;
diff --git a/toonz/sources/include/tools/cursors.h b/toonz/sources/include/tools/cursors.h
index a912ffa..16eec82 100644
--- a/toonz/sources/include/tools/cursors.h
+++ b/toonz/sources/include/tools/cursors.h
@@ -66,6 +66,8 @@ enum {
PickerCursorWhite,
PickerCursorWhiteLine,
PickerCursorWhiteArea,
+ PickerCursorOrganize,
+ PickerCursorWhiteOrganize,
PickerRGB,
PickerRGBWhite,
diff --git a/toonz/sources/include/toonz/palettecmd.h b/toonz/sources/include/toonz/palettecmd.h
index bca5440..ada5ee4 100644
--- a/toonz/sources/include/toonz/palettecmd.h
+++ b/toonz/sources/include/toonz/palettecmd.h
@@ -88,6 +88,17 @@ DVAPI void renamePalettePage(TPaletteHandle *paletteHandle, int pageIndex,
DVAPI void renamePaletteStyle(TPaletteHandle *paletteHandle,
const std::wstring &newName);
+/* called in ColorModelViewer::pick() - move selected style to the first page */
+DVAPI void organizePaletteStyle(TPaletteHandle *paletteHandle, int styleId,
+ const TPoint &point);
+
+/*
+called in ColorModelViewer::repickFromColorModel().
+Pick color from the img for all styles with "picked position" value.
+*/
+DVAPI void pickColorByUsingPickedPosition(TPaletteHandle *paletteHandle,
+ TImageP img);
+
} // namespace
#endif
diff --git a/toonz/sources/include/toonz/preferences.h b/toonz/sources/include/toonz/preferences.h
index ed3fa2c..56f7e3e 100644
--- a/toonz/sources/include/toonz/preferences.h
+++ b/toonz/sources/include/toonz/preferences.h
@@ -99,6 +99,14 @@ public:
void setAutosavePeriod(int minutes);
int getAutosavePeriod() const { return m_autosavePeriod; } // minutes
+ void enableAutosaveScene(bool on);
+ bool isAutosaveSceneEnabled() const { return m_autosaveSceneEnabled; }
+
+ void enableAutosaveOtherFiles(bool on);
+ bool isAutosaveOtherFilesEnabled() const {
+ return m_autosaveOtherFilesEnabled;
+ }
+
void enableLevelsBackup(bool enabled);
bool isLevelsBackupEnabled() const { return m_levelsBackupEnabled; }
@@ -110,6 +118,15 @@ public:
return m_replaceAfterSaveLevelAs;
}
+ void enableStartupPopup(bool on);
+ bool isStartupPopupEnabled() { return m_startupPopupEnabled; }
+
+ void setProjectRoot(int index);
+ int getProjectRoot() { return m_projectRoot; }
+
+ void setCustomProjectRoot(std::wstring path);
+ QString getCustomProjectRoot() { return m_customProjectRoot; }
+
// Interface tab
void setCurrentLanguage(int currentLanguage);
@@ -406,6 +423,9 @@ public:
int getTextureSize() const { return m_textureSize; }
bool useDrawPixel() { return m_textureSize == 0; }
+ void setShortcutPreset(std::string preset);
+ QString getShortcutPreset() { return m_shortcutPreset; }
+
int getShmMax() const {
return m_shmmax;
} //! \sa The \p sysctl unix command.
@@ -433,8 +453,8 @@ private:
std::vector m_levelFormats;
QString m_units, m_cameraUnits, m_scanLevelType, m_currentRoomChoice,
- m_oldUnits, m_oldCameraUnits, m_ffmpegPath;
- ;
+ m_oldUnits, m_oldCameraUnits, m_ffmpegPath, m_shortcutPreset,
+ m_customProjectRoot;
double m_defLevelWidth, m_defLevelHeight, m_defLevelDpi;
@@ -447,7 +467,7 @@ private:
m_chunkSize, m_blanksCount, m_onionPaperThickness, m_step, m_shrink,
m_textureSize, m_autocreationType, m_keyframeType, m_animationStep,
m_ffmpegTimeout; // seconds
-
+ int m_projectRoot;
int m_currentLanguage, m_currentStyleSheet,
m_undoMemorySize, // in megabytes
m_dragCellsBehaviour, m_lineTestFpsCapture, m_defLevelType, m_xsheetStep,
@@ -457,11 +477,13 @@ private:
m_generatedMovieViewEnabled, m_xsheetAutopanEnabled,
m_ignoreAlphaonColumn1Enabled, m_previewAlwaysOpenNewFlipEnabled,
m_rewindAfterPlaybackEnabled, m_fitToFlipbookEnabled, m_autosaveEnabled,
+ m_autosaveSceneEnabled, m_autosaveOtherFilesEnabled,
m_defaultViewerEnabled, m_pixelsOnly;
bool m_rasterOptimizedMemory, m_saveUnpaintedInCleanup,
m_askForOverrideRender, m_automaticSVNFolderRefreshEnabled, m_SVNEnabled,
m_levelsBackupEnabled, m_minimizeSaveboxAfterEditing,
- m_sceneNumberingEnabled, m_animationSheetEnabled, m_inksOnly;
+ m_sceneNumberingEnabled, m_animationSheetEnabled, m_inksOnly,
+ m_startupPopupEnabled;
bool m_fillOnlySavebox, m_show0ThickLines, m_regionAntialias;
bool m_onionSkinDuringPlayback;
TPixel32 m_viewerBGColor, m_previewBGColor, m_chessboardColor1,
diff --git a/toonz/sources/include/toonzqt/camerasettingswidget.h b/toonz/sources/include/toonzqt/camerasettingswidget.h
index 18fc23b..1b2a995 100644
--- a/toonz/sources/include/toonzqt/camerasettingswidget.h
+++ b/toonz/sources/include/toonzqt/camerasettingswidget.h
@@ -71,6 +71,7 @@ protected:
//---------------------------------------------------------------
class DVAPI CameraSettingsWidget final : public QFrame {
+ friend class StartupPopup;
Q_OBJECT
bool m_forCleanup;
diff --git a/toonz/sources/include/toonzqt/dvdialog.h b/toonz/sources/include/toonzqt/dvdialog.h
index b61e366..6184bf5 100644
--- a/toonz/sources/include/toonzqt/dvdialog.h
+++ b/toonz/sources/include/toonzqt/dvdialog.h
@@ -58,10 +58,11 @@ void DVAPI MsgBoxInPopup(MsgType type, const QString &text);
// ATTENZIONE: Valore di ritorno
// 0 = l'utente ha chiuso la finestra (dovrebbe corrispondere ad un cancel o ad
-// un NO)
-// 1 = primo bottone da sx premuto
-// 2 = secondo bottone da sx premuto
-// 3 = terzo bottone da sx premuto
+// un NO) - closed window
+// 1 = primo bottone da sx premuto - first button selected
+// 2 = secondo bottone da sx premuto - second button
+// 3 = terzo bottone da sx premuto - third button
+// 4 = fourth button
int DVAPI MsgBox(MsgType type, const QString &text,
const std::vector &buttons,
@@ -77,6 +78,12 @@ int DVAPI MsgBox(const QString &text, const QString &button1,
const QString &button2, const QString &button3,
int defaultButtonIndex = 0, QWidget *parent = 0);
+// QUESTION: four botton user defined
+int DVAPI MsgBox(const QString &text, const QString &button1,
+ const QString &button2, const QString &button3,
+ const QString &button4, int defaultButtonIndex = 0,
+ QWidget *parent = 0);
+
Dialog DVAPI *createMsgBox(MsgType type, const QString &text,
const QStringList &buttons, int defaultButtonIndex,
QWidget *parent = 0);
@@ -229,6 +236,8 @@ public:
void addButtonBarWidget(QWidget *widget);
void addButtonBarWidget(QWidget *first, QWidget *second);
void addButtonBarWidget(QWidget *first, QWidget *second, QWidget *third);
+ void addButtonBarWidget(QWidget *first, QWidget *second, QWidget *third,
+ QWidget *fourth);
void hideEvent(QHideEvent *event) override;
diff --git a/toonz/sources/include/toonzqt/flipconsole.h b/toonz/sources/include/toonzqt/flipconsole.h
index f7d54e6..5e7c32a 100644
--- a/toonz/sources/include/toonzqt/flipconsole.h
+++ b/toonz/sources/include/toonzqt/flipconsole.h
@@ -214,7 +214,8 @@ public:
eFilledRaster = 0x4000000, // Used only in LineTest
eDefineLoadBox = 0x8000000,
eUseLoadBox = 0x10000000,
- eEnd = 0x20000000
+ eLocator = 0x20000000,
+ eEnd = 0x40000000
};
static const UINT cFullConsole = eEnd - 1;
diff --git a/toonz/sources/include/toonzqt/menubarcommand.h b/toonz/sources/include/toonzqt/menubarcommand.h
index 869b1be..b1b677b 100644
--- a/toonz/sources/include/toonzqt/menubarcommand.h
+++ b/toonz/sources/include/toonzqt/menubarcommand.h
@@ -145,7 +145,8 @@ public:
std::string getShortcutFromId(CommandId id);
int getKeyFromShortcut(const std::string &shortcut);
int getKeyFromId(CommandId id);
- void setShortcut(QAction *action, std::string shortcutString);
+ void setShortcut(QAction *action, std::string shortcutString,
+ bool keepDefault = true);
QAction *getAction(CommandId id, bool createIfNeeded = false);
diff --git a/toonz/sources/include/toonzqt/paletteviewergui.h b/toonz/sources/include/toonzqt/paletteviewergui.h
index 1d88c1c..e853458 100644
--- a/toonz/sources/include/toonzqt/paletteviewergui.h
+++ b/toonz/sources/include/toonzqt/paletteviewergui.h
@@ -201,12 +201,6 @@ protected:
bool hasShortcut(int indexInPage);
-protected slots:
-
- void toggleLink();
- void eraseToggleLink();
- void removeLink();
-
private:
DVGui::LineEdit *m_renameTextField;
QPoint m_dragStartPosition;
diff --git a/toonz/sources/include/toonzqt/selectioncommandids.h b/toonz/sources/include/toonzqt/selectioncommandids.h
index 0dd6b73..99ebe5e 100644
--- a/toonz/sources/include/toonzqt/selectioncommandids.h
+++ b/toonz/sources/include/toonzqt/selectioncommandids.h
@@ -12,6 +12,8 @@
#define MI_PasteColors "MI_PasteColors"
#define MI_PasteNames "MI_PasteNames"
#define MI_GetColorFromStudioPalette "MI_GetColorFromStudioPalette"
+#define MI_ToggleLinkToStudioPalette "MI_ToggleLinkToStudioPalette"
+#define MI_RemoveReferenceToStudioPalette "MI_RemoveReferenceToStudioPalette"
#define MI_Clear "MI_Clear"
#define MI_SelectAll "MI_SelectAll"
#define MI_InvertSelection "MI_InvertSelection"
diff --git a/toonz/sources/include/toonzqt/styleselection.h b/toonz/sources/include/toonzqt/styleselection.h
index fb78637..6e5099e 100644
--- a/toonz/sources/include/toonzqt/styleselection.h
+++ b/toonz/sources/include/toonzqt/styleselection.h
@@ -95,9 +95,11 @@ public:
void toggleKeyframe(int frame);
// remove link from the studio palette (if linked)
- bool removeLink();
+ void removeLink();
// get back the style from the studio palette (if linked)
void getBackOriginalStyle();
+ // return true if there is at least one linked style in the selection
+ bool hasLinkedStyle();
};
#endif // STYLESELECTION_INCLUDED
diff --git a/toonz/sources/include/tpalette.h b/toonz/sources/include/tpalette.h
index 339186f..e883e6d 100644
--- a/toonz/sources/include/tpalette.h
+++ b/toonz/sources/include/tpalette.h
@@ -420,6 +420,9 @@ between RGBA color components.
m_isLocked = lock;
}
+ bool hasPickedPosStyle(); // Returns true if there is at least one style with
+ // picked pos value
+
void nextShortcutScope(bool invert);
public:
diff --git a/toonz/sources/tcleanupper/tcleanupper.cpp b/toonz/sources/tcleanupper/tcleanupper.cpp
index e133730..b750387 100644
--- a/toonz/sources/tcleanupper/tcleanupper.cpp
+++ b/toonz/sources/tcleanupper/tcleanupper.cpp
@@ -63,8 +63,8 @@ inline ostream &operator<<(ostream &out, const TFilePath &fp) {
namespace {
const char *applicationName = "OpenToonz";
-const char *applicationVersion = "1.0";
-const char *applicationFullName = "OpenToonz 1.0";
+const char *applicationVersion = "1.1";
+const char *applicationFullName = "OpenToonz 1.1";
const char *rootVarName = "TOONZROOT";
const char *systemVarPrefix = "TOONZ";
@@ -625,6 +625,14 @@ int main(int argc, char *argv[]) {
/*-- CleanupSettingsファイルパスを直接入力した場合 --*/
else {
try {
+ TProjectManager *pm = TProjectManager::instance();
+ TProjectP sceneProject = pm->loadSceneProject(fp);
+ if (!sceneProject) {
+ cerr << "can't open project." << endl;
+ return -3;
+ }
+ scene->setProject(sceneProject.getPointer());
+
/*- CleanupSettingsファイルに対応するTIFファイルが有るかチェック -*/
TFilePath tifImagePath = fp.withType("tif");
std::wcout << L"tifImagePath : " << tifImagePath.getWideString()
diff --git a/toonz/sources/tcomposer/tcomposer.cpp b/toonz/sources/tcomposer/tcomposer.cpp
index 676857a..1eb9d32 100644
--- a/toonz/sources/tcomposer/tcomposer.cpp
+++ b/toonz/sources/tcomposer/tcomposer.cpp
@@ -104,8 +104,8 @@ namespace {
//
const char *applicationName = "OpenToonz";
-const char *applicationVersion = "1.0";
-const char *applicationFullName = "OpenToonz 1.0";
+const char *applicationVersion = "1.1";
+const char *applicationFullName = "OpenToonz 1.1";
const char *rootVarName = "TOONZROOT";
const char *systemVarPrefix = "TOONZ";
diff --git a/toonz/sources/tconverter/tconverter.cpp b/toonz/sources/tconverter/tconverter.cpp
index 31ae9c0..8b437aa 100644
--- a/toonz/sources/tconverter/tconverter.cpp
+++ b/toonz/sources/tconverter/tconverter.cpp
@@ -37,7 +37,7 @@ typedef QualifierT FilePathQualifier;
#define RENDER_LICENSE_NOT_FOUND 888
-const char *applicationVersion = "1.0";
+const char *applicationVersion = "1.1";
const char *applicationName = "OpenToonz";
const char *rootVarName = "TOONZROOT";
const char *systemVarPrefix = "TOONZ";
diff --git a/toonz/sources/tnztools/CMakeLists.txt b/toonz/sources/tnztools/CMakeLists.txt
index b3d5525..8f2b1c2 100644
--- a/toonz/sources/tnztools/CMakeLists.txt
+++ b/toonz/sources/tnztools/CMakeLists.txt
@@ -11,6 +11,7 @@ set(MOC_HEADERS
../include/tools/screenpicker.h
rgbpickertool.h
rulertool.h
+ stylepickertool.h
)
set(HEADERS ${MOC_HEADERS}
diff --git a/toonz/sources/tnztools/Resources/picker_style_organize.png b/toonz/sources/tnztools/Resources/picker_style_organize.png
new file mode 100644
index 0000000..c502b37
Binary files /dev/null and b/toonz/sources/tnztools/Resources/picker_style_organize.png differ
diff --git a/toonz/sources/tnztools/Resources/picker_style_white_organize.png b/toonz/sources/tnztools/Resources/picker_style_white_organize.png
new file mode 100644
index 0000000..b905466
Binary files /dev/null and b/toonz/sources/tnztools/Resources/picker_style_white_organize.png differ
diff --git a/toonz/sources/tnztools/brushtool.cpp b/toonz/sources/tnztools/brushtool.cpp
index 3272da2..1585aa8 100644
--- a/toonz/sources/tnztools/brushtool.cpp
+++ b/toonz/sources/tnztools/brushtool.cpp
@@ -45,7 +45,7 @@ using namespace ToolUtils;
TEnv::DoubleVar VectorBrushMinSize("InknpaintVectorBrushMinSize", 1);
TEnv::DoubleVar VectorBrushMaxSize("InknpaintVectorBrushMaxSize", 5);
-TEnv::IntVar VectorCapStyle("InknpaintVectorCapStyle", 0);
+TEnv::IntVar VectorCapStyle("InknpaintVectorCapStyle", 1);
TEnv::IntVar VectorJoinStyle("InknpaintVectorJoinStyle", 0);
TEnv::IntVar VectorMiterValue("InknpaintVectorMiterValue", 4);
TEnv::DoubleVar RasterBrushMinSize("InknpaintRasterBrushMinSize", 1);
diff --git a/toonz/sources/tnztools/cursormanager.cpp b/toonz/sources/tnztools/cursormanager.cpp
index 126610f..323ba47 100644
--- a/toonz/sources/tnztools/cursormanager.cpp
+++ b/toonz/sources/tnztools/cursormanager.cpp
@@ -73,6 +73,9 @@ const struct {
{ToolCursor::PickerCursorWhiteLine, "picker_style_white_line", 7, 22},
{ToolCursor::PickerCursorWhiteArea, "picker_style_white_area", 7, 22},
{ToolCursor::PickerCursorWhite, "picker_style_white", 7, 22},
+ {ToolCursor::PickerCursorOrganize, "picker_style_organize", 7, 22},
+ {ToolCursor::PickerCursorWhiteOrganize, "picker_style_white_organize", 7,
+ 22},
{ToolCursor::PickerRGB, "picker_rgb", 7, 22},
{ToolCursor::PickerRGBWhite, "picker_rgb_white", 7, 22},
{ToolCursor::FillCursorF, "fill_f", 6, 23},
diff --git a/toonz/sources/tnztools/stylepickertool.cpp b/toonz/sources/tnztools/stylepickertool.cpp
index e73625c..4c21641 100644
--- a/toonz/sources/tnztools/stylepickertool.cpp
+++ b/toonz/sources/tnztools/stylepickertool.cpp
@@ -1,238 +1,307 @@
+#include "stylepickertool.h"
-
+// TnzTools includes
#include "tools/tool.h"
#include "tools/cursors.h"
#include "tools/stylepicker.h"
-#include "toonz/txshsimplelevel.h"
-#include "toonz/txshlevelhandle.h"
+#include "tools/toolhandle.h"
-#include "drawutil.h"
-#include "tvectorimage.h"
-#include "ttoonzimage.h"
-#include "tundo.h"
+// TnzQt includes
+#include "toonzqt/tselectionhandle.h"
+#include "toonzqt/styleselection.h"
+// TnzLib includes
+#include "toonz/txshsimplelevel.h"
+#include "toonz/txshlevelhandle.h"
#include "toonz/tpalettehandle.h"
-
#include "toonz/stage2.h"
-#include "tproperty.h"
-#include "toonzqt/tselectionhandle.h"
-#include "toonzqt/styleselection.h"
-#include "tools/toolhandle.h"
#include "toonz/tframehandle.h"
#include "toonz/txsheethandle.h"
#include "toonz/preferences.h"
#include "toonz/tcolumnhandle.h"
#include "toonz/dpiscale.h"
#include "toonz/palettecontroller.h"
+#include "toonz/txshleveltypes.h"
+#include "toonz/txshpalettelevel.h"
+
+// TnzCore includes
+#include "drawutil.h"
+#include "tvectorimage.h"
+#include "ttoonzimage.h"
+#include "tundo.h"
+#include "tmsgcore.h"
#define LINES L"Lines"
#define AREAS L"Areas"
#define ALL L"Lines & Areas"
-namespace {
-
//========================================================================
// Pick Style Tool
//------------------------------------------------------------------------
-class StylePickerTool final : public TTool {
- int m_oldStyleId, m_currentStyleId;
-
- TEnumProperty m_colorType;
- TPropertyGroup m_prop;
-
- TBoolProperty m_passivePick;
+StylePickerTool::StylePickerTool()
+ : TTool("T_StylePicker")
+ , m_currentStyleId(0)
+ , m_colorType("Mode:")
+ , m_passivePick("Passive Pick", false)
+ , m_organizePalette("Organize Palette", false)
+ , m_paletteToBeOrganized(NULL) {
+ m_prop.bind(m_colorType);
+ m_colorType.addValue(AREAS);
+ m_colorType.addValue(LINES);
+ m_colorType.addValue(ALL);
+ m_colorType.setId("Mode");
+ bind(TTool::CommonLevels);
+
+ m_prop.bind(m_passivePick);
+ m_passivePick.setId("PassivePick");
+
+ m_prop.bind(m_organizePalette);
+ m_organizePalette.setId("OrganizePalette");
+}
-public:
- TPropertyGroup *getProperties(int targetType) override { return &m_prop; }
+void StylePickerTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e) {
+ m_oldStyleId = m_currentStyleId =
+ getApplication()->getCurrentLevelStyleIndex();
+ pick(pos, e);
+}
- StylePickerTool()
- : TTool("T_StylePicker")
- , m_currentStyleId(0)
- , m_colorType("Mode:")
- , m_passivePick("Passive Pick", false) {
- m_prop.bind(m_colorType);
- m_colorType.addValue(AREAS);
- m_colorType.addValue(LINES);
- m_colorType.addValue(ALL);
- m_colorType.setId("Mode");
- bind(TTool::CommonLevels);
+void StylePickerTool::leftButtonDrag(const TPointD &pos, const TMouseEvent &e) {
+ pick(pos, e);
+}
- m_prop.bind(m_passivePick);
- m_passivePick.setId("PassivePick");
+void StylePickerTool::pick(const TPointD &pos, const TMouseEvent &e) {
+ // Area = 0, Line = 1, All = 2
+ int modeValue = m_colorType.getIndex();
+
+ //------------------------------------
+ // MultiLayerStylePicker
+ /*---
+ PickしたStyleId = 0、かつ
+ Preference で MultiLayerStylePickerが有効、かつ
+ Scene編集モード、かつ
+ 下のカラムから拾った色がTransparentでない場合、
+ → カレントLevelを移動する。
+ ---*/
+ if (Preferences::instance()->isMultiLayerStylePickerEnabled() &&
+ getApplication()->getCurrentFrame()->isEditingScene()) {
+ int superPickedColumnId = getViewer()->posToColumnIndex(
+ e.m_pos, getPixelSize() * getPixelSize(), false);
+
+ if (superPickedColumnId >= 0 /*-- 何かColumnに当たった場合 --*/
+ &&
+ getApplication()->getCurrentColumn()->getColumnIndex() !=
+ superPickedColumnId) /*-- かつ、Current Columnでない場合 --*/
+ {
+ /*-- そのColumnからPickを試みる --*/
+ int currentFrame = getApplication()->getCurrentFrame()->getFrame();
+ TXshCell pickedCell =
+ getApplication()->getCurrentXsheet()->getXsheet()->getCell(
+ currentFrame, superPickedColumnId);
+ TImageP pickedImage = pickedCell.getImage(false).getPointer();
+ TToonzImageP picked_ti = pickedImage;
+ TVectorImageP picked_vi = pickedImage;
+ TXshSimpleLevel *picked_level = pickedCell.getSimpleLevel();
+ if ((picked_ti || picked_vi) && picked_level) {
+ TPointD tmpMousePosition = getColumnMatrix(superPickedColumnId).inv() *
+ getViewer()->winToWorld(e.m_pos);
+
+ TPointD tmpDpiScale = getCurrentDpiScale(picked_level, getCurrentFid());
+
+ tmpMousePosition.x /= tmpDpiScale.x;
+ tmpMousePosition.y /= tmpDpiScale.y;
+
+ StylePicker superPicker(pickedImage);
+ int picked_subsampling =
+ picked_level->getImageSubsampling(pickedCell.getFrameId());
+ int superPicked_StyleId = superPicker.pickStyleId(
+ TScale(1.0 / picked_subsampling) * tmpMousePosition +
+ TPointD(-0.5, -0.5),
+ getPixelSize() * getPixelSize(), modeValue);
+ /*-- 何かStyleが拾えて、Transparentでない場合 --*/
+ if (superPicked_StyleId > 0) {
+ /*-- Levelの移動 --*/
+ getApplication()->getCurrentLevel()->setLevel(picked_level);
+ /*-- Columnの移動 --*/
+ getApplication()->getCurrentColumn()->setColumnIndex(
+ superPickedColumnId);
+ /*-- 選択の解除 --*/
+ if (getApplication()->getCurrentSelection()->getSelection())
+ getApplication()
+ ->getCurrentSelection()
+ ->getSelection()
+ ->selectNone();
+ /*-- StyleIdの移動 --*/
+ getApplication()->setCurrentLevelStyleIndex(superPicked_StyleId);
+ return;
+ }
+ }
+ }
+ }
+ /*-- MultiLayerStylePicker ここまで --*/
+ //------------------------------------
+ TImageP image = getImage(false);
+ TToonzImageP ti = image;
+ TVectorImageP vi = image;
+ TXshSimpleLevel *level =
+ getApplication()->getCurrentLevel()->getSimpleLevel();
+ if ((!ti && !vi) || !level) return;
+
+ /*-- 画面外をpickしても拾えないようにする --*/
+ if (!m_viewer->getGeometry().contains(pos)) return;
+
+ int subsampling = level->getImageSubsampling(getCurrentFid());
+ StylePicker picker(image);
+ int styleId =
+ picker.pickStyleId(TScale(1.0 / subsampling) * pos + TPointD(-0.5, -0.5),
+ getPixelSize() * getPixelSize(), modeValue);
+
+ if (styleId < 0) return;
+
+ if (modeValue == 1) // LINES
+ {
+ /*-- pickLineモードのとき、取得Styleが0の場合はカレントStyleを変えない。
+ * --*/
+ if (styleId == 0) return;
+ /*--
+ * pickLineモードのとき、PurePaintの部分をクリックしてもカレントStyleを変えない
+ * --*/
+ if (ti &&
+ picker.pickTone(TScale(1.0 / subsampling) * pos +
+ TPointD(-0.5, -0.5)) == 255)
+ return;
}
- ToolType getToolType() const override { return TTool::LevelReadTool; }
+ /*--- Styleを選択している場合は選択を解除する ---*/
+ TSelection *selection =
+ TTool::getApplication()->getCurrentSelection()->getSelection();
+ if (selection) {
+ TStyleSelection *styleSelection =
+ dynamic_cast(selection);
+ if (styleSelection) styleSelection->selectNone();
+ }
- void draw() override {}
+ getApplication()->setCurrentLevelStyleIndex(styleId);
+}
- void leftButtonDown(const TPointD &pos, const TMouseEvent &e) override {
- m_oldStyleId = m_currentStyleId =
- getApplication()->getCurrentLevelStyleIndex();
- pick(pos, e);
- }
- void leftButtonDrag(const TPointD &pos, const TMouseEvent &e) override {
- pick(pos, e);
+void StylePickerTool::mouseMove(const TPointD &pos, const TMouseEvent &e) {
+ if (!m_passivePick.getValue()) return;
+ /*--- PassiveにStyleを拾う機能 ---*/
+ PaletteController *controller =
+ TTool::getApplication()->getPaletteController();
+
+ TImageP image = getImage(false);
+ TToonzImageP ti = image;
+ TVectorImageP vi = image;
+ TXshSimpleLevel *level =
+ getApplication()->getCurrentLevel()->getSimpleLevel();
+ if ((!ti && !vi) || !level || !m_viewer->getGeometry().contains(pos)) {
+ controller->notifyStylePassivePicked(-1, -1, -1);
+ return;
}
- void pick(const TPointD &pos, const TMouseEvent &e) {
- // Area = 0, Line = 1, All = 2
- int modeValue = m_colorType.getIndex();
-
- //------------------------------------
- // MultiLayerStylePicker
- /*---
- PickしたStyleId = 0、かつ
- Preference で MultiLayerStylePickerが有効、かつ
- Scene編集モード、かつ
- 下のカラムから拾った色がTransparentでない場合、
- → カレントLevelを移動する。
- ---*/
- if (Preferences::instance()->isMultiLayerStylePickerEnabled() &&
- getApplication()->getCurrentFrame()->isEditingScene()) {
- int superPickedColumnId = getViewer()->posToColumnIndex(
- e.m_pos, getPixelSize() * getPixelSize(), false);
-
- if (superPickedColumnId >= 0 /*-- 何かColumnに当たった場合 --*/
- &&
- getApplication()->getCurrentColumn()->getColumnIndex() !=
- superPickedColumnId) /*-- かつ、Current Columnでない場合 --*/
- {
- /*-- そのColumnからPickを試みる --*/
- int currentFrame = getApplication()->getCurrentFrame()->getFrame();
- TXshCell pickedCell =
- getApplication()->getCurrentXsheet()->getXsheet()->getCell(
- currentFrame, superPickedColumnId);
- TImageP pickedImage = pickedCell.getImage(false).getPointer();
- TToonzImageP picked_ti = pickedImage;
- TVectorImageP picked_vi = pickedImage;
- TXshSimpleLevel *picked_level = pickedCell.getSimpleLevel();
- if ((picked_ti || picked_vi) && picked_level) {
- TPointD tmpMousePosition =
- getColumnMatrix(superPickedColumnId).inv() *
- getViewer()->winToWorld(e.m_pos);
-
- TPointD tmpDpiScale =
- getCurrentDpiScale(picked_level, getCurrentFid());
-
- tmpMousePosition.x /= tmpDpiScale.x;
- tmpMousePosition.y /= tmpDpiScale.y;
-
- StylePicker superPicker(pickedImage);
- int picked_subsampling =
- picked_level->getImageSubsampling(pickedCell.getFrameId());
- int superPicked_StyleId = superPicker.pickStyleId(
- TScale(1.0 / picked_subsampling) * tmpMousePosition +
- TPointD(-0.5, -0.5),
- getPixelSize() * getPixelSize(), modeValue);
- /*-- 何かStyleが拾えて、Transparentでない場合 --*/
- if (superPicked_StyleId > 0) {
- /*-- Levelの移動 --*/
- getApplication()->getCurrentLevel()->setLevel(picked_level);
- /*-- Columnの移動 --*/
- getApplication()->getCurrentColumn()->setColumnIndex(
- superPickedColumnId);
- /*-- 選択の解除 --*/
- if (getApplication()->getCurrentSelection()->getSelection())
- getApplication()
- ->getCurrentSelection()
- ->getSelection()
- ->selectNone();
- /*-- StyleIdの移動 --*/
- getApplication()->setCurrentLevelStyleIndex(superPicked_StyleId);
- return;
- }
- }
- }
- }
- /*-- MultiLayerStylePicker ここまで --*/
- //------------------------------------
- TImageP image = getImage(false);
- TToonzImageP ti = image;
- TVectorImageP vi = image;
- TXshSimpleLevel *level =
- getApplication()->getCurrentLevel()->getSimpleLevel();
- if ((!ti && !vi) || !level) return;
-
- /*-- 画面外をpickしても拾えないようにする --*/
- if (!m_viewer->getGeometry().contains(pos)) return;
-
- int subsampling = level->getImageSubsampling(getCurrentFid());
- StylePicker picker(image);
- int styleId = picker.pickStyleId(
- TScale(1.0 / subsampling) * pos + TPointD(-0.5, -0.5),
- getPixelSize() * getPixelSize(), modeValue);
-
- if (styleId < 0) return;
-
- if (modeValue == 1) // LINES
- {
- /*-- pickLineモードのとき、取得Styleが0の場合はカレントStyleを変えない。
- * --*/
- if (styleId == 0) return;
- /*--
- * pickLineモードのとき、PurePaintの部分をクリックしてもカレントStyleを変えない
- * --*/
- if (ti &&
- picker.pickTone(TScale(1.0 / subsampling) * pos +
- TPointD(-0.5, -0.5)) == 255)
- return;
- }
-
- /*--- Styleを選択している場合は選択を解除する ---*/
- TSelection *selection =
- TTool::getApplication()->getCurrentSelection()->getSelection();
- if (selection) {
- TStyleSelection *styleSelection =
- dynamic_cast(selection);
- if (styleSelection) styleSelection->selectNone();
- }
+ int subsampling = level->getImageSubsampling(getCurrentFid());
+ StylePicker picker(image);
+ TPointD pickPos(TScale(1.0 / subsampling) * pos + TPointD(-0.5, -0.5));
+ int inkStyleId =
+ picker.pickStyleId(pickPos, getPixelSize() * getPixelSize(), 1);
+ int paintStyleId =
+ picker.pickStyleId(pickPos, getPixelSize() * getPixelSize(), 0);
+ int tone = picker.pickTone(pickPos);
+ controller->notifyStylePassivePicked(inkStyleId, paintStyleId, tone);
+}
- getApplication()->setCurrentLevelStyleIndex(styleId);
- }
+int StylePickerTool::getCursorId() const {
+ bool isBlackBG = ToonzCheck::instance()->getChecks() & ToonzCheck::eBlackBg;
+
+ /* in case the "organize palette" option is active */
+ if (m_organizePalette.getValue())
+ return (isBlackBG) ? ToolCursor::PickerCursorWhiteOrganize
+ : ToolCursor::PickerCursorOrganize;
+
+ if (m_colorType.getValue() == LINES)
+ return (isBlackBG) ? ToolCursor::PickerCursorWhiteLine
+ : ToolCursor::PickerCursorLine;
+ else if (m_colorType.getValue() == AREAS)
+ return (isBlackBG) ? ToolCursor::PickerCursorWhiteArea
+ : ToolCursor::PickerCursorArea;
+ else // line&areas
+ return (isBlackBG) ? ToolCursor::PickerCursorWhite
+ : ToolCursor::PickerCursor;
+}
- void mouseMove(const TPointD &pos, const TMouseEvent &e) override {
- if (!m_passivePick.getValue()) return;
- /*--- PassiveにStyleを拾う機能 ---*/
- PaletteController *controller =
- TTool::getApplication()->getPaletteController();
-
- TImageP image = getImage(false);
- TToonzImageP ti = image;
- TVectorImageP vi = image;
- TXshSimpleLevel *level =
- getApplication()->getCurrentLevel()->getSimpleLevel();
- if ((!ti && !vi) || !level || !m_viewer->getGeometry().contains(pos)) {
- controller->notifyStylePassivePicked(-1, -1, -1);
- return;
+bool StylePickerTool::onPropertyChanged(std::string propertyName) {
+ if (propertyName == m_organizePalette.getName()) {
+ if (m_organizePalette.getValue()) {
+ if (!startOrganizePalette()) {
+ m_organizePalette.setValue(false);
+ getApplication()->getCurrentTool()->notifyToolChanged();
+ return false;
+ }
+ } else {
+ std::cout << "End Organize Palette" << std::endl;
+ m_paletteToBeOrganized = NULL;
}
+ }
+ return true;
+}
- int subsampling = level->getImageSubsampling(getCurrentFid());
- StylePicker picker(image);
- TPointD pickPos(TScale(1.0 / subsampling) * pos + TPointD(-0.5, -0.5));
- int inkStyleId =
- picker.pickStyleId(pickPos, getPixelSize() * getPixelSize(), 1);
- int paintStyleId =
- picker.pickStyleId(pickPos, getPixelSize() * getPixelSize(), 0);
- int tone = picker.pickTone(pickPos);
- controller->notifyStylePassivePicked(inkStyleId, paintStyleId, tone);
+bool StylePickerTool::startOrganizePalette() {
+ /* Check if the organizing operation is available */
+ TXshLevel *level = getApplication()->getCurrentLevel()->getLevel();
+ if (!level) {
+ DVGui::error(tr("No current level."));
+ return false;
+ }
+ if (level->getType() != PLI_XSHLEVEL && level->getType() != TZP_XSHLEVEL &&
+ level->getType() != PLT_XSHLEVEL) {
+ DVGui::error(tr("Current level has no available palette."));
+ return false;
+ }
+ /* palette should have more than one page to organize */
+ TPalette *pal = NULL;
+ if (level->getType() == PLT_XSHLEVEL)
+ pal = level->getPaletteLevel()->getPalette();
+ else
+ pal = level->getSimpleLevel()->getPalette();
+ if (!pal || pal->getPageCount() < 2) {
+ DVGui::error(
+ tr("Palette must have more than one palette to be organized."));
+ return false;
}
- void onActivate() override {}
+ m_paletteToBeOrganized = pal;
- int getCursorId() const override {
- bool isBlackBG = ToonzCheck::instance()->getChecks() & ToonzCheck::eBlackBg;
+ std::cout << "Start Organize Palette" << std::endl;
- if (m_colorType.getValue() == LINES)
- return (isBlackBG) ? ToolCursor::PickerCursorWhiteLine
- : ToolCursor::PickerCursorLine;
- else if (m_colorType.getValue() == AREAS)
- return (isBlackBG) ? ToolCursor::PickerCursorWhiteArea
- : ToolCursor::PickerCursorArea;
- else // line&areas
- return (isBlackBG) ? ToolCursor::PickerCursorWhite
- : ToolCursor::PickerCursor;
- }
+ return true;
+}
-} stylePickerTool;
+/*
+ If the working palette is changed, then deactivate the "organize palette"
+ toggle.
+*/
+void StylePickerTool::onImageChanged() {
+ std::cout << "StylePickerTool::onImageChanged" << std::endl;
+ if (!m_organizePalette.getValue() || !m_paletteToBeOrganized) return;
+
+ TXshLevel *level = getApplication()->getCurrentLevel()->getLevel();
+ if (!level) {
+ m_organizePalette.setValue(false);
+ getApplication()->getCurrentTool()->notifyToolChanged();
+ return;
+ }
+ TPalette *pal = NULL;
+ if (level->getType() == PLT_XSHLEVEL)
+ pal = level->getPaletteLevel()->getPalette();
+ else if (level->getSimpleLevel()) {
+ pal = level->getSimpleLevel()->getPalette();
+ }
+ if (!pal || pal != m_paletteToBeOrganized) {
+ m_organizePalette.setValue(false);
+ getApplication()->getCurrentTool()->notifyToolChanged();
+ return;
+ }
}
+
+StylePickerTool stylePickerTool;
diff --git a/toonz/sources/tnztools/stylepickertool.h b/toonz/sources/tnztools/stylepickertool.h
new file mode 100644
index 0000000..2a6982a
--- /dev/null
+++ b/toonz/sources/tnztools/stylepickertool.h
@@ -0,0 +1,54 @@
+#pragma once
+
+#ifndef STYLEPICKERTOOL_H
+#define STYLEPICKERTOOL_H
+
+#include "tools/tool.h"
+#include "tproperty.h"
+#include
+
+class StylePickerTool final : public TTool, public QObject {
+ int m_oldStyleId, m_currentStyleId;
+
+ TEnumProperty m_colorType;
+ TPropertyGroup m_prop;
+ TBoolProperty m_passivePick;
+
+ TBoolProperty m_organizePalette;
+ TPalette *m_paletteToBeOrganized;
+
+ bool startOrganizePalette();
+
+public:
+ TPropertyGroup *getProperties(int targetType) override { return &m_prop; }
+
+ StylePickerTool();
+
+ ToolType getToolType() const override { return TTool::LevelReadTool; }
+
+ void draw() override {}
+
+ void leftButtonDown(const TPointD &pos, const TMouseEvent &e) override;
+
+ void leftButtonDrag(const TPointD &pos, const TMouseEvent &e) override;
+
+ void pick(const TPointD &pos, const TMouseEvent &e);
+
+ void mouseMove(const TPointD &pos, const TMouseEvent &e) override;
+
+ int getCursorId() const override;
+
+ bool onPropertyChanged(std::string propertyName);
+
+ bool isOrganizePaletteActive() { return m_organizePalette.getValue(); }
+
+ /*
+ This function is called when either frame/column/level/scene is switched or
+ either scene/level/object is changed (see tapp.cpp).
+ If the working palette is changed, then deactivate the "organize palette"
+ toggle.
+ */
+ void onImageChanged() override;
+};
+
+#endif
\ No newline at end of file
diff --git a/toonz/sources/tnztools/tnztools.qrc b/toonz/sources/tnztools/tnztools.qrc
index 98087dc..1b5b91b 100644
--- a/toonz/sources/tnztools/tnztools.qrc
+++ b/toonz/sources/tnztools/tnztools.qrc
@@ -50,6 +50,8 @@
Resources/picker_style_white_line.png
Resources/picker_style_white_area.png
Resources/picker_style_white.png
+ Resources/picker_style_organize.png
+ Resources/picker_style_white_organize.png
Resources/picker_rgb.png
Resources/picker_rgb_white.png
Resources/fill_f.png
diff --git a/toonz/sources/tnztools/tooloptions.cpp b/toonz/sources/tnztools/tooloptions.cpp
index d333ad4..399b876 100644
--- a/toonz/sources/tnztools/tooloptions.cpp
+++ b/toonz/sources/tnztools/tooloptions.cpp
@@ -2182,6 +2182,17 @@ StylePickerToolOptionsBox::StylePickerToolOptionsBox(
m_layout->addWidget(m_currentStyleLabel, 0);
m_layout->addStretch(1);
+ // retrieve the "organize palette" checkbox from the layout and insert
+ // into rightmost of the tool option bar
+ ToolOptionCheckbox *organizePaletteCB =
+ dynamic_cast(m_controls.value("Organize Palette"));
+ m_layout->removeWidget(organizePaletteCB);
+ m_layout->addWidget(new ToolOptionsBarSeparator(this), 0);
+ m_layout->addWidget(organizePaletteCB);
+ organizePaletteCB->setToolTip(
+ tr("With this option being activated, the picked style will be\nmoved to "
+ "the end of the first page of the palette."));
+
if (m_realTimePickMode) {
connect(m_realTimePickMode, SIGNAL(toggled(bool)), m_currentStyleLabel,
SLOT(setVisible(bool)));
diff --git a/toonz/sources/toonz/CMakeLists.txt b/toonz/sources/toonz/CMakeLists.txt
index 0215c13..62ee338 100644
--- a/toonz/sources/toonz/CMakeLists.txt
+++ b/toonz/sources/toonz/CMakeLists.txt
@@ -100,6 +100,7 @@ set(MOC_HEADERS
selectionutils.h
shifttracetool.h
shortcutpopup.h
+ startuppopup.h
subcameramanager.h
subscenecommand.h
svncleanupdialog.h
@@ -140,6 +141,7 @@ set(MOC_HEADERS
historypane.h
cleanupsettingspane.h
penciltestpopup.h
+ locatorpopup.h
# Tracker file
dummyprocessor.h
metnum.h
@@ -232,6 +234,7 @@ set(SOURCES
scriptconsolepanel.cpp
shifttracetool.cpp
shortcutpopup.cpp
+ startuppopup.cpp
subcameramanager.cpp
timestretchpopup.cpp
trackerpopup.cpp
@@ -298,6 +301,7 @@ set(SOURCES
historypane.cpp
cleanupsettingspane.cpp
penciltestpopup.cpp
+ locatorpopup.cpp
# Tracker file
dummyprocessor.cpp
metnum.cpp
@@ -374,11 +378,11 @@ if(WIN32)
endif()
endif()
-if(WIN32)
+if(WIN32)
target_link_libraries(OpenToonz_${VERSION}
Qt5::WinMain Qt5::Core Qt5::Gui Qt5::Network Qt5::OpenGL Qt5::Svg Qt5::Xml
Qt5::Script Qt5::Widgets Qt5::PrintSupport Qt5::Multimedia
- ${GL_LIB} ${GLUT_LIB}
+ ${GL_LIB} ${GLUT_LIB} strmiids
tnzcore tnzbase toonzlib colorfx tnzext image sound toonzqt tnztools tnzstdfx tfarm
)
elseif(APPLE)
diff --git a/toonz/sources/toonz/Resources/locator.png b/toonz/sources/toonz/Resources/locator.png
new file mode 100644
index 0000000..439df63
Binary files /dev/null and b/toonz/sources/toonz/Resources/locator.png differ
diff --git a/toonz/sources/toonz/Resources/locator_click.png b/toonz/sources/toonz/Resources/locator_click.png
new file mode 100644
index 0000000..8045221
Binary files /dev/null and b/toonz/sources/toonz/Resources/locator_click.png differ
diff --git a/toonz/sources/toonz/Resources/locator_over.png b/toonz/sources/toonz/Resources/locator_over.png
new file mode 100644
index 0000000..8045221
Binary files /dev/null and b/toonz/sources/toonz/Resources/locator_over.png differ
diff --git a/toonz/sources/toonz/Resources/startup.png b/toonz/sources/toonz/Resources/startup.png
new file mode 100644
index 0000000..10757e0
Binary files /dev/null and b/toonz/sources/toonz/Resources/startup.png differ
diff --git a/toonz/sources/toonz/cellselectioncommand.cpp b/toonz/sources/toonz/cellselectioncommand.cpp
index a670e73..fa3c108 100644
--- a/toonz/sources/toonz/cellselectioncommand.cpp
+++ b/toonz/sources/toonz/cellselectioncommand.cpp
@@ -1292,6 +1292,7 @@ TXshSimpleLevel *CloneLevelUndo::cloneLevel(
assert(palette);
dstSl->setPalette(palette->clone());
+ dstSl->getPalette()->setDirtyFlag(true);
}
// The level clone shell was created. Now, clone the associated frames found
@@ -1306,6 +1307,8 @@ TXshSimpleLevel *CloneLevelUndo::cloneLevel(
dstSl->setFrame(*ft, img->cloneImage());
}
+ dstSl->setDirtyFlag(true);
+
return dstSl;
}
diff --git a/toonz/sources/toonz/cleanupsettingspane.cpp b/toonz/sources/toonz/cleanupsettingspane.cpp
index d7e5579..30756ba 100644
--- a/toonz/sources/toonz/cleanupsettingspane.cpp
+++ b/toonz/sources/toonz/cleanupsettingspane.cpp
@@ -26,6 +26,7 @@
#include
#include
#include
+#include
#include "cleanupsettingspane.h"
@@ -80,6 +81,10 @@ void CleanupSaveInField::browseDirectory() {
CleanupSettingsPane::CleanupSettingsPane(QWidget *parent)
: QFrame(parent), m_attached(false) {
+ // Autocenter
+ m_autocenterBox = new QGroupBox(tr("Autocenter"), this);
+ m_pegHolesOm = new QComboBox(this);
+ m_fieldGuideOm = new QComboBox(this);
// Rotate&Flip
QFrame *rotFlipFrame = new QFrame(this);
m_rotateOm = new QComboBox(this);
@@ -103,6 +108,19 @@ CleanupSettingsPane::CleanupSettingsPane(QWidget *parent)
QPushButton *loadBtn = new QPushButton(tr("Load"));
QPushButton *resetBtn = new QPushButton(tr("Reset"));
+ // Autocenter
+ m_autocenterBox->setCheckable(true);
+ QStringList pegbarHoles;
+ pegbarHoles << "Bottom"
+ << "Top"
+ << "Left"
+ << "Right";
+ m_pegHolesOm->addItems(pegbarHoles);
+ std::vector fdgNames;
+ CleanupParameters::getFdgNames(fdgNames);
+ for (int i = 0; i < (int)fdgNames.size(); i++)
+ m_fieldGuideOm->addItem(QString(fdgNames[i].c_str()));
+
// Rotate&Flip
rotFlipFrame->setObjectName("CleanupSettingsFrame");
QStringList rotate;
@@ -137,6 +155,23 @@ CleanupSettingsPane::CleanupSettingsPane(QWidget *parent)
mainLay->setSpacing(2);
mainLay->setMargin(5);
{
+ // Autocenter
+ QGridLayout *autocenterLay = new QGridLayout();
+ autocenterLay->setMargin(5);
+ autocenterLay->setSpacing(3);
+ {
+ autocenterLay->addWidget(new QLabel(tr("Pegbar Holes")), 0, 0,
+ Qt::AlignRight | Qt::AlignVCenter);
+ autocenterLay->addWidget(m_pegHolesOm, 0, 1);
+ autocenterLay->addWidget(new QLabel(tr("Field Guide")), 1, 0,
+ Qt::AlignRight | Qt::AlignVCenter);
+ autocenterLay->addWidget(m_fieldGuideOm, 1, 1);
+ }
+ autocenterLay->setColumnStretch(0, 0);
+ autocenterLay->setColumnStretch(1, 1);
+ m_autocenterBox->setLayout(autocenterLay);
+ mainLay->addWidget(m_autocenterBox, 0);
+
// Rotate&Flip
QGridLayout *rotFlipLay = new QGridLayout();
rotFlipLay->setMargin(5);
@@ -226,7 +261,14 @@ CleanupSettingsPane::CleanupSettingsPane(QWidget *parent)
//-----signal-slot connections
bool ret = true;
- ret = ret && connect(m_rotateOm, SIGNAL(activated(int)),
+ ret = ret && connect(m_autocenterBox, SIGNAL(toggled(bool)),
+ SLOT(onGenericSettingsChange()));
+ ret = ret && connect(m_pegHolesOm, SIGNAL(activated(int)),
+ SLOT(onGenericSettingsChange()));
+ ret = ret && connect(m_fieldGuideOm, SIGNAL(activated(int)),
+ SLOT(onGenericSettingsChange()));
+
+ ret = ret && connect(m_rotateOm, SIGNAL(activated(int)),
SLOT(onGenericSettingsChange()));
ret = ret && connect(m_flipX, SIGNAL(stateChanged(int)),
SLOT(onGenericSettingsChange()));
@@ -336,6 +378,15 @@ void CleanupSettingsPane::updateGui(bool needsPostProcess) {
void CleanupSettingsPane::updateGui(CleanupParameters *params,
CleanupParameters *oldParams) {
+ m_autocenterBox->setChecked(params->m_autocenterType ==
+ CleanupTypes::AUTOCENTER_FDG);
+ m_pegHolesOm->setCurrentIndex(params->m_pegSide - 1);
+
+ QString fieldName = QString::fromStdString(params->getFdgName());
+ int index = (fieldName.isEmpty()) ? 0 : m_fieldGuideOm->findText(fieldName);
+ assert(index != -1);
+ m_fieldGuideOm->setCurrentIndex(index);
+
m_rotateOm->setCurrentIndex(params->m_rotate / 90);
m_flipX->setChecked(params->m_flipx);
m_flipY->setChecked(params->m_flipy);
@@ -462,6 +513,13 @@ void CleanupSettingsPane::onGenericSettingsChange() {
CleanupSettingsModel *model = CleanupSettingsModel::instance();
CleanupParameters *params = model->getCurrentParameters();
+ params->m_autocenterType = m_autocenterBox->isChecked()
+ ? CleanupTypes::AUTOCENTER_FDG
+ : CleanupTypes::AUTOCENTER_NONE;
+ params->m_pegSide =
+ (CleanupTypes::PEGS_SIDE)(m_pegHolesOm->currentIndex() + 1);
+ params->setFdgByName(m_fieldGuideOm->currentText().toStdString());
+
params->m_rotate = m_rotateOm->currentIndex() * 90;
params->m_flipx = m_flipX->isChecked();
params->m_flipy = m_flipY->isChecked();
diff --git a/toonz/sources/toonz/cleanupsettingspane.h b/toonz/sources/toonz/cleanupsettingspane.h
index b0069d8..75da278 100644
--- a/toonz/sources/toonz/cleanupsettingspane.h
+++ b/toonz/sources/toonz/cleanupsettingspane.h
@@ -18,6 +18,7 @@ class QComboBox;
class QLabel;
class QCheckBox;
class CleanupPaletteViewer;
+class QGroupBox;
namespace DVGui {
@@ -47,6 +48,9 @@ public:
CleanupCameraSettingsWidget *m_cameraWidget;
private:
+ //----Autocenter
+ QGroupBox *m_autocenterBox;
+ QComboBox *m_pegHolesOm, *m_fieldGuideOm;
//----Rotate & Flip
QComboBox *m_rotateOm;
QCheckBox *m_flipX;
diff --git a/toonz/sources/toonz/colormodelviewer.cpp b/toonz/sources/toonz/colormodelviewer.cpp
index 2e063b5..e4b0085 100644
--- a/toonz/sources/toonz/colormodelviewer.cpp
+++ b/toonz/sources/toonz/colormodelviewer.cpp
@@ -14,6 +14,7 @@
#include "tools/toolcommandids.h"
#include "tools/tool.h"
#include "tools/toolhandle.h"
+#include "../tnztools/stylepickertool.h"
// TnzQt includes
#include "toonzqt/menubarcommand.h"
@@ -84,7 +85,7 @@ ColorModelViewer::ColorModelViewer(QWidget *parent)
FlipConsole::eCompare | FlipConsole::eCustomize |
FlipConsole::eSave | FlipConsole::eFilledRaster |
FlipConsole::eDefineLoadBox | FlipConsole::eUseLoadBox |
- FlipConsole::eDefineSubCamera)),
+ FlipConsole::eDefineSubCamera | FlipConsole::eLocator)),
eDontKeepFilesOpened, true)
, m_mode(0)
, m_currentRefImgPath(TFilePath()) {
@@ -222,11 +223,28 @@ void ColorModelViewer::contextMenuEvent(QContextMenuEvent *event) {
connect(loadCurrentFrame, SIGNAL(triggered()), SLOT(loadCurrentFrame()));
menu.addAction(loadCurrentFrame);
+ if (!m_imageViewer->getImage()) {
+ menu.exec(event->globalPos());
+ return;
+ }
+
QAction *removeColorModel =
new QAction(QString(tr("Remove Color Model")), this);
connect(removeColorModel, SIGNAL(triggered()), SLOT(removeColorModel()));
menu.addAction(removeColorModel);
+ /* If there is at least one style with "picked pos" parameter, then enable
+ * repick command */
+ TRasterImageP ri = m_imageViewer->getImage();
+ if (ri && currentPalette->hasPickedPosStyle()) {
+ menu.addSeparator();
+ QAction *repickFromColorModelAct = new QAction(
+ QString(tr("Update Colors by Using Picked Positions")), this);
+ connect(repickFromColorModelAct, SIGNAL(triggered()),
+ SLOT(repickFromColorModel()));
+ menu.addAction(repickFromColorModelAct);
+ }
+
menu.addSeparator();
QString shortcut = QString::fromStdString(
@@ -306,6 +324,19 @@ void ColorModelViewer::pick(const QPoint &p) {
if (styleSelection) styleSelection->selectNone();
}
+ /*
+ if the Style Picker tool is current and "organize palette" is activated,
+ then move the picked style to the first page of the palette.
+ */
+ TTool *tool = TApp::instance()->getCurrentTool()->getTool();
+ if (tool->getName() == "T_StylePicker") {
+ StylePickerTool *spTool = dynamic_cast(tool);
+ if (spTool && spTool->isOrganizePaletteActive()) {
+ TPoint point = picker.getRasterPoint(pos);
+ PaletteCmd::organizePaletteStyle(ph, styleIndex, point);
+ }
+ }
+
ph->setStyleIndex(styleIndex);
}
@@ -356,8 +387,16 @@ void ColorModelViewer::showEvent(QShowEvent *e) {
//-----------------------------------------------------------------------------
/*- ツールのTypeに合わせてPickのタイプも変え、カーソルも切り替える -*/
void ColorModelViewer::changePickType() {
- TPropertyGroup *propGroup =
- TApp::instance()->getCurrentTool()->getTool()->getProperties(0);
+ TTool *tool = TApp::instance()->getCurrentTool()->getTool();
+ if (tool->getName() == T_StylePicker) {
+ StylePickerTool *stylePickerTool = dynamic_cast(tool);
+ if (stylePickerTool->isOrganizePaletteActive()) {
+ setToolCursor(m_imageViewer, ToolCursor::PickerCursorOrganize);
+ return;
+ }
+ }
+
+ TPropertyGroup *propGroup = tool->getProperties(0);
/*- Propertyの無いツールの場合 -*/
if (!propGroup) {
m_mode = 2;
@@ -573,6 +612,17 @@ void ColorModelViewer::onRefImageNotFound() {
"level."));
}
+//-----------------------------------------------------------------------------
+
+void ColorModelViewer::repickFromColorModel() {
+ TImageP img = m_imageViewer->getImage();
+ if (!img) return;
+ TPaletteHandle *ph =
+ TApp::instance()->getPaletteController()->getCurrentLevelPalette();
+
+ PaletteCmd::pickColorByUsingPickedPosition(ph, img);
+}
+
//=============================================================================
OpenFloatingPanel openColorModelCommand(MI_OpenColorModel, "ColorModel",
diff --git a/toonz/sources/toonz/colormodelviewer.h b/toonz/sources/toonz/colormodelviewer.h
index e068080..833a62d 100644
--- a/toonz/sources/toonz/colormodelviewer.h
+++ b/toonz/sources/toonz/colormodelviewer.h
@@ -48,6 +48,7 @@ protected:
* UseCurrentFrameのLevelに移動してきたときに、改めてCurrentFrameを格納しなおす
* -*/
void reloadCurrentFrame();
+
protected slots:
void showCurrentImage();
@@ -62,6 +63,8 @@ protected slots:
* -*/
void changePickType();
+ void repickFromColorModel();
+
signals:
void refImageNotFound();
};
diff --git a/toonz/sources/toonz/filebrowser.cpp b/toonz/sources/toonz/filebrowser.cpp
index f4f06e8..73f7f9a 100644
--- a/toonz/sources/toonz/filebrowser.cpp
+++ b/toonz/sources/toonz/filebrowser.cpp
@@ -148,7 +148,8 @@ QMutex levelFileMutex;
inline bool isMultipleFrameType(std::string type) {
return (type == "tlv" || type == "tzl" || type == "pli" || type == "mov" ||
- type == "avi" || type == "3gp");
+ type == "avi" || type == "3gp" || type == "gif" || type == "mp4" ||
+ type == "webm");
}
//=============================================================================
diff --git a/toonz/sources/toonz/flipbook.h b/toonz/sources/toonz/flipbook.h
index a116f3c..b9e13ee 100644
--- a/toonz/sources/toonz/flipbook.h
+++ b/toonz/sources/toonz/flipbook.h
@@ -179,7 +179,8 @@ public:
FlipBook(QWidget *parent = 0, QString viewerTitle = QString(),
UINT flipConsoleButtonMask = FlipConsole::cFullConsole &
(~(FlipConsole::eFilledRaster |
- FlipConsole::eDefineSubCamera)),
+ FlipConsole::eDefineSubCamera |
+ FlipConsole::eLocator)),
UCHAR flags = 0, bool isColorModel = false);
~FlipBook();
void setLevel(const TFilePath &path, TPalette *palette = 0, int from = -1,
diff --git a/toonz/sources/toonz/iocommand.cpp b/toonz/sources/toonz/iocommand.cpp
index f1b35d0..2cb728d 100644
--- a/toonz/sources/toonz/iocommand.cpp
+++ b/toonz/sources/toonz/iocommand.cpp
@@ -1176,17 +1176,21 @@ bool IoCmd::saveSceneIfNeeded(QString msg) {
QString question;
question = QObject::tr(
"%1: the current scene has been modified.\n"
- "Do you want to save your changes?")
+ "What would you like to do?")
.arg(msg);
- int ret = DVGui::MsgBox(question, QObject::tr("Save"),
- QObject::tr("Discard"), QObject::tr("Cancel"), 0);
- if (ret == 0 || ret == 3) {
+ int ret = DVGui::MsgBox(
+ question, QObject::tr("Save All"), QObject::tr("Save Scene Only"),
+ QObject::tr("Discard Changes"), QObject::tr("Cancel"), 0);
+ if (ret == 0 || ret == 4) {
// cancel (or closed message box window)
return false;
} else if (ret == 1) {
+ // save all
+ if (!IoCmd::saveAll()) return false;
+ } else if (ret == 2) {
// save
if (!IoCmd::saveScene()) return false;
- } else if (ret == 2) {
+ } else if (ret == 3) {
}
isLevelOrSceneIsDirty = true;
@@ -1203,21 +1207,25 @@ bool IoCmd::saveSceneIfNeeded(QString msg) {
if (!dirtyResources.empty()) {
QString question;
- question =
- msg + ":" + QObject::tr(" Following file(s) are modified.\n\n");
+ question = msg + ":" +
+ QObject::tr(" The following file(s) have been modified.\n\n");
for (int i = 0; i < dirtyResources.size(); i++) {
question += " " + dirtyResources[i] + "\n";
}
- question +=
- QObject::tr("\nAre you sure to ") + msg + QObject::tr(" anyway ?");
+ question += QObject::tr("\nWhat would you like to do? ");
int ret =
- DVGui::MsgBox(question, QObject::tr("OK"), QObject::tr("Cancel"), 0);
- if (ret == 0 || ret == 2) {
+ DVGui::MsgBox(question, QObject::tr("Save Changes"),
+ msg + QObject::tr(" Anyway"), QObject::tr("Cancel"), 0);
+ if (ret == 0 || ret == 3) {
// cancel (or closed message box window)
return false;
} else if (ret == 1) {
- // ok
+ // save non scene files
+ IoCmd::saveNonSceneFiles();
+ return false;
+ } else if (ret == 2) {
+ // quit
}
isLevelOrSceneIsDirty = true;
@@ -1604,7 +1612,7 @@ bool IoCmd::saveLevel(TXshSimpleLevel *sl) {
}
//===========================================================================
-// IoCmd::saveSound(soundPath, soundColumn, overwrite)
+// IoCmd::saveAll()
//---------------------------------------------------------------------------
bool IoCmd::saveAll() {
@@ -1614,7 +1622,7 @@ bool IoCmd::saveAll() {
TApp *app = TApp::instance();
ToonzScene *scene = app->getCurrentScene()->getScene();
-
+ bool untitled = scene->isUntitled();
SceneResources resources(scene, 0);
resources.save(scene->getScenePath());
resources.updatePaths();
@@ -1622,11 +1630,31 @@ bool IoCmd::saveAll() {
// for update title bar
app->getCurrentLevel()->notifyLevelTitleChange();
app->getCurrentPalette()->notifyPaletteTitleChanged();
-
+ if (untitled) scene->setUntitled();
return result;
}
//===========================================================================
+// IoCmd::saveNonSceneFiles()
+//---------------------------------------------------------------------------
+
+void IoCmd::saveNonSceneFiles() {
+ // try to save non scene files
+
+ TApp *app = TApp::instance();
+ ToonzScene *scene = app->getCurrentScene()->getScene();
+ bool untitled = scene->isUntitled();
+ SceneResources resources(scene, 0);
+ resources.save(scene->getScenePath());
+ if (untitled) scene->setUntitled();
+ resources.updatePaths();
+
+ // for update title bar
+ app->getCurrentLevel()->notifyLevelTitleChange();
+ app->getCurrentPalette()->notifyPaletteTitleChanged();
+}
+
+//===========================================================================
// IoCmd::saveSound(soundPath, soundColumn, overwrite)
//---------------------------------------------------------------------------
@@ -2738,3 +2766,12 @@ public:
SaveAllCommandHandler() : MenuItemHandler(MI_SaveAll) {}
void execute() override { IoCmd::saveAll(); }
} saveAllCommandHandler;
+
+//=============================================================================
+// Save all levels
+//-----------------------------------------------------------------------------
+class SaveAllLevelsCommandHandler : public MenuItemHandler {
+public:
+ SaveAllLevelsCommandHandler() : MenuItemHandler(MI_SaveAllLevels) {}
+ void execute() { IoCmd::saveNonSceneFiles(); }
+} saveAllLevelsCommandHandler;
diff --git a/toonz/sources/toonz/iocommand.h b/toonz/sources/toonz/iocommand.h
index 17f6fdb..2415e85 100644
--- a/toonz/sources/toonz/iocommand.h
+++ b/toonz/sources/toonz/iocommand.h
@@ -197,6 +197,8 @@ bool saveLevel(TXshSimpleLevel *sl);
bool saveAll();
+void saveNonSceneFiles();
+
bool saveSound(const TFilePath &fp, TXshSoundLevel *sc, bool overwrite);
bool saveSound(TXshSoundLevel *sc);
diff --git a/toonz/sources/toonz/locatorpopup.cpp b/toonz/sources/toonz/locatorpopup.cpp
new file mode 100644
index 0000000..434ca52
--- /dev/null
+++ b/toonz/sources/toonz/locatorpopup.cpp
@@ -0,0 +1,117 @@
+#include "locatorpopup.h"
+
+// TnzLib includes
+#include "toonz/txshlevelhandle.h"
+#include "toonz/tframehandle.h"
+#include "toonz/preferences.h"
+#include "toonz/stage2.h"
+
+// Tnz6 includes
+#include "tapp.h"
+#include "sceneviewer.h"
+
+#include
+
+LocatorPopup::LocatorPopup(QWidget *parent)
+ : QDialog(parent), m_initialZoom(true) {
+ m_viewer = new SceneViewer(NULL);
+ m_viewer->setParent(parent);
+ m_viewer->setIsLocator();
+
+ //---- layout
+ QVBoxLayout *mainLayout = new QVBoxLayout();
+ mainLayout->setMargin(0);
+ mainLayout->addWidget(m_viewer, 1);
+ setLayout(mainLayout);
+
+ bool ret = true;
+ // When zoom changed, change window title.
+ ret = connect(m_viewer, SIGNAL(onZoomChanged()), SLOT(changeWindowTitle()));
+ ret = ret &&
+ connect(m_viewer, SIGNAL(previewToggled()), SLOT(changeWindowTitle()));
+ assert(ret);
+
+ resize(400, 400);
+}
+
+//-----------------------------------------------------------------------------
+
+void LocatorPopup::onChangeViewAff(const TPointD &pos) {
+ TAffine curAff = m_viewer->getSceneMatrix();
+ TAffine newAff(curAff.a11, 0, -pos.x * curAff.a11, 0, curAff.a22,
+ -pos.y * curAff.a22);
+ m_viewer->setViewMatrix(newAff, 0);
+ m_viewer->setViewMatrix(newAff, 1);
+ m_viewer->update();
+}
+
+//-----------------------------------------------------------------------------
+
+void LocatorPopup::showEvent(QShowEvent *) {
+ // zoom the locator for the first time
+ if (m_initialZoom) {
+ for (int z = 0; z < 4; z++) m_viewer->zoomQt(true, false);
+ m_initialZoom = false;
+ }
+
+ TApp *app = TApp::instance();
+ TFrameHandle *frameHandle = app->getCurrentFrame();
+ TXshLevelHandle *levelHandle = app->getCurrentLevel();
+
+ bool ret = true;
+ ret = ret && connect(frameHandle, SIGNAL(frameSwitched()), this,
+ SLOT(changeWindowTitle()));
+ ret = ret && connect(levelHandle, SIGNAL(xshLevelSwitched(TXshLevel *)), this,
+ SLOT(changeWindowTitle()));
+ assert(ret);
+
+ changeWindowTitle();
+}
+
+//-----------------------------------------------------------------------------
+
+void LocatorPopup::hideEvent(QHideEvent *) {
+ TApp *app = TApp::instance();
+ disconnect(app->getCurrentLevel());
+ disconnect(app->getCurrentFrame());
+}
+
+//-----------------------------------------------------------------------------
+
+void LocatorPopup::changeWindowTitle() {
+ TApp *app = TApp::instance();
+ // put the titlebar texts in this string
+ QString name = tr("Locator");
+
+ bool showZoomFactor = false;
+
+ // if the frame type is "scene editing"
+ if (app->getCurrentFrame()->isEditingScene()) {
+ if (m_viewer->isPreviewEnabled()) showZoomFactor = true;
+
+ // If the current level exists and some option is set in the preference,
+ // set the zoom value to the current level's dpi
+ else if (Preferences::instance()
+ ->isActualPixelViewOnSceneEditingModeEnabled() &&
+ app->getCurrentLevel()->getSimpleLevel() &&
+ !CleanupPreviewCheck::instance()
+ ->isEnabled() // cleanup preview must be OFF
+ &&
+ !CameraTestCheck::instance()
+ ->isEnabled()) // camera test mode must be OFF neither
+ showZoomFactor = true;
+ }
+ // if the frame type is "level editing"
+ else {
+ TXshLevel *level = app->getCurrentLevel()->getLevel();
+ if (level) showZoomFactor = true;
+ }
+
+ if (showZoomFactor) {
+ name = name + " Zoom : " +
+ QString::number((int)(100.0 * sqrt(m_viewer->getViewMatrix().det()) *
+ m_viewer->getDpiFactor())) +
+ "%";
+ }
+ setWindowTitle(name);
+}
\ No newline at end of file
diff --git a/toonz/sources/toonz/locatorpopup.h b/toonz/sources/toonz/locatorpopup.h
new file mode 100644
index 0000000..2dc3448
--- /dev/null
+++ b/toonz/sources/toonz/locatorpopup.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#ifndef LOCATORPOPUP_H
+#define LOCATORPOPUP_H
+
+#include "tgeometry.h"
+#include
+
+class SceneViewer;
+
+//=============================================================================
+// LoactorPopup
+//-----------------------------------------------------------------------------
+
+class LocatorPopup : public QDialog {
+ Q_OBJECT
+ SceneViewer* m_viewer;
+ bool m_initialZoom;
+
+public:
+ LocatorPopup(QWidget* parent = 0);
+ SceneViewer* viewer() { return m_viewer; }
+
+ void onChangeViewAff(const TPointD& curPos);
+
+protected:
+ void showEvent(QShowEvent*);
+ void hideEvent(QHideEvent*);
+
+protected slots:
+ void changeWindowTitle();
+};
+
+#endif
\ No newline at end of file
diff --git a/toonz/sources/toonz/magpiefileimportpopup.cpp b/toonz/sources/toonz/magpiefileimportpopup.cpp
index 5134d72..72a90ab 100644
--- a/toonz/sources/toonz/magpiefileimportpopup.cpp
+++ b/toonz/sources/toonz/magpiefileimportpopup.cpp
@@ -124,7 +124,7 @@ MagpieFileImportPopup::MagpieFileImportPopup()
FlipConsole::eRed | FlipConsole::eGreen | FlipConsole::eBlue |
FlipConsole::eMatte | FlipConsole::eDefineSubCamera |
FlipConsole::eDefineLoadBox | FlipConsole::eUseLoadBox |
- FlipConsole::eFilledRaster));
+ FlipConsole::eFilledRaster | FlipConsole::eLocator));
m_flipbook = new FlipBook(this, tr("Import Magpie File"), buttonMask);
m_flipbook->setFixedHeight(250);
frameLayout->addWidget(m_flipbook);
diff --git a/toonz/sources/toonz/mainwindow.cpp b/toonz/sources/toonz/mainwindow.cpp
index e0acfec..afca011 100644
--- a/toonz/sources/toonz/mainwindow.cpp
+++ b/toonz/sources/toonz/mainwindow.cpp
@@ -12,6 +12,7 @@
#include "iocommand.h"
#include "tapp.h"
#include "comboviewerpane.h"
+#include "startuppopup.h"
// TnzTools includes
#include "tools/toolcommandids.h"
@@ -1275,6 +1276,12 @@ void MainWindow::onMenuCheckboxChanged() {
void MainWindow::showEvent(QShowEvent *event) {
getCurrentRoom()->layout()->setEnabled(true); // See main function in
// main.cpp
+ if (Preferences::instance()->isStartupPopupEnabled() &&
+ !m_startupPopupShown) {
+ StartupPopup *startupPopup = new StartupPopup();
+ startupPopup->show();
+ m_startupPopupShown = true;
+ }
}
extern const char *applicationName;
extern const char *applicationVersion;
@@ -1558,9 +1565,9 @@ QAction *MainWindow::createToolAction(const char *id, const char *iconName,
void MainWindow::defineActions() {
createMenuFileAction(MI_NewScene, tr("&New Scene"), "Ctrl+N");
createMenuFileAction(MI_LoadScene, tr("&Load Scene..."), "Ctrl+L");
- createMenuFileAction(MI_SaveScene, tr("&Save Scene"), "Ctrl+S");
- createMenuFileAction(MI_SaveSceneAs, tr("&Save Scene As..."), "Ctrl+Shift+S");
- createMenuFileAction(MI_SaveAll, tr("&Save All"), "");
+ createMenuFileAction(MI_SaveScene, tr("&Save Scene"), "Ctrl+Shift+S");
+ createMenuFileAction(MI_SaveSceneAs, tr("&Save Scene As..."), "");
+ createMenuFileAction(MI_SaveAll, tr("&Save All"), "Ctrl+S");
createMenuFileAction(MI_RevertScene, tr("&Revert Scene"), "");
QAction *act = CommandManager::instance()->getAction(MI_RevertScene);
@@ -1576,9 +1583,10 @@ void MainWindow::defineActions() {
"");
createMenuFileAction(MI_ClearRecentLevel, tr("&Clear Recent level File List"),
"");
- createMenuFileAction(MI_NewLevel, tr("&New Level..."), "");
+ createMenuFileAction(MI_NewLevel, tr("&New Level..."), "Alt+N");
createMenuFileAction(MI_LoadLevel, tr("&Load Level..."), "");
createMenuFileAction(MI_SaveLevel, tr("&Save Level"), "");
+ createMenuFileAction(MI_SaveAllLevels, tr("&Save All Levels"), "");
createMenuFileAction(MI_SaveLevelAs, tr("&Save Level As..."), "");
createMenuFileAction(MI_ExportLevel, tr("&Export Level..."), "");
createMenuFileAction(MI_ConvertFileWithInput, tr("&Convert File..."), "");
@@ -1590,9 +1598,9 @@ void MainWindow::defineActions() {
createMenuFileAction(MI_ProjectSettings, tr("&Project Settings..."), "");
createMenuFileAction(MI_SaveDefaultSettings, tr("&Save Default Settings"),
"");
- createMenuFileAction(MI_OutputSettings, tr("&Output Settings..."), "");
+ createMenuFileAction(MI_OutputSettings, tr("&Output Settings..."), "Ctrl+O");
createMenuFileAction(MI_PreviewSettings, tr("&Preview Settings..."), "");
- createMenuFileAction(MI_Render, tr("&Render"), "");
+ createMenuFileAction(MI_Render, tr("&Render"), "Ctrl+Shift+R");
createMenuFileAction(MI_Preview, tr("&Preview"), "Ctrl+R");
createRightClickMenuAction(MI_SavePreviewedFrames,
tr("&Save Previewed Frames"), "");
@@ -1607,13 +1615,13 @@ void MainWindow::defineActions() {
MI_FreezePreview, tr("Freeze Preview"), tr("Unfreeze Preview"));
// createAction(MI_SavePreview, "&Save Preview", "");
createRightClickMenuAction(MI_SavePreset, tr("&Save As Preset"), "");
- createMenuFileAction(MI_Preferences, tr("&Preferences..."), "");
+ createMenuFileAction(MI_Preferences, tr("&Preferences..."), "Ctrl+U");
createMenuFileAction(MI_ShortcutPopup, tr("&Configure Shortcuts..."), "");
createMenuFileAction(MI_PrintXsheet, tr("&Print Xsheet"), "");
createMenuFileAction("MI_RunScript", tr("Run Script..."), "");
createMenuFileAction("MI_OpenScriptConsole", tr("Open Script Console..."),
"");
- createMenuFileAction(MI_Print, tr("&Print Current Frame..."), "");
+ createMenuFileAction(MI_Print, tr("&Print Current Frame..."), "Ctrl+P");
createMenuFileAction(MI_Quit, tr("&Quit"), "Ctrl+Q");
#ifndef NDEBUG
createMenuFileAction("MI_ReloadStyle", tr("Reload qss"), "");
@@ -1639,10 +1647,14 @@ void MainWindow::defineActions() {
createRightClickMenuAction(MI_PasteNames, tr("Paste Name"), "");
createRightClickMenuAction(MI_GetColorFromStudioPalette,
tr("Get Color from Studio Palette"), "");
+ createRightClickMenuAction(MI_ToggleLinkToStudioPalette,
+ tr("Toggle Link to Studio Palette"), "");
+ createRightClickMenuAction(MI_RemoveReferenceToStudioPalette,
+ tr("Remove Reference to Studio Palette"), "");
createMenuEditAction(MI_Clear, tr("&Delete"), "Delete");
createMenuEditAction(MI_Insert, tr("&Insert"), "Ins");
createMenuEditAction(MI_Group, tr("&Group"), "Ctrl+G");
- createMenuEditAction(MI_Ungroup, tr("&Ungroup"), "");
+ createMenuEditAction(MI_Ungroup, tr("&Ungroup"), "Ctrl+Shift+G");
createMenuEditAction(MI_BringToFront, tr("&Bring to Front"), "Ctrl+]");
createMenuEditAction(MI_BringForward, tr("&Bring Forward"), "]");
createMenuEditAction(MI_SendBack, tr("&Send Back"), "Ctrl+[");
@@ -1747,8 +1759,8 @@ void MainWindow::defineActions() {
createMenuCellsAction(MI_Increment, tr("&Autoexpose"), "");
createMenuCellsAction(MI_Dup, tr("&Repeat..."), "");
createMenuCellsAction(MI_ResetStep, tr("&Reset Step"), "");
- createMenuCellsAction(MI_IncreaseStep, tr("&Increase Step"), "");
- createMenuCellsAction(MI_DecreaseStep, tr("&Decrease Step"), "");
+ createMenuCellsAction(MI_IncreaseStep, tr("&Increase Step"), "'");
+ createMenuCellsAction(MI_DecreaseStep, tr("&Decrease Step"), ";");
createMenuCellsAction(MI_Step2, tr("&Step 2"), "");
createMenuCellsAction(MI_Step3, tr("&Step 3"), "");
createMenuCellsAction(MI_Step4, tr("&Step 4"), "");
@@ -1762,26 +1774,26 @@ void MainWindow::defineActions() {
createMenuCellsAction(MI_Autorenumber, tr("&Autorenumber"), "");
createMenuCellsAction(MI_CloneLevel, tr("&Clone"), "");
createMenuCellsAction(MI_DrawingSubForward,
- tr("Drawing Substitution Forward"), ".");
+ tr("Drawing Substitution Forward"), "W");
createMenuCellsAction(MI_DrawingSubBackward,
- tr("Drawing Substitution Backward"), ",");
+ tr("Drawing Substitution Backward"), "Q");
createMenuCellsAction(MI_DrawingSubGroupForward,
- tr("Similar Drawing Substitution Forward"), "Ctrl+.");
+ tr("Similar Drawing Substitution Forward"), "Alt+W");
createMenuCellsAction(MI_DrawingSubGroupBackward,
- tr("Similar Drawing Substitution Backward"), "Ctrl+,");
+ tr("Similar Drawing Substitution Backward"), "Alt+Q");
createMenuCellsAction(MI_Reframe1, tr("1's"), "");
createMenuCellsAction(MI_Reframe2, tr("2's"), "");
createMenuCellsAction(MI_Reframe3, tr("3's"), "");
createMenuCellsAction(MI_Reframe4, tr("4's"), "");
- createRightClickMenuAction(MI_SetKeyframes, tr("&Set Key"), "");
+ createRightClickMenuAction(MI_SetKeyframes, tr("&Set Key"), "Z");
createToggle(MI_ViewCamera, tr("&Camera Box"), "",
ViewCameraToggleAction ? 1 : 0, MenuViewCommandType);
createToggle(MI_ViewTable, tr("&Table"), "", ViewTableToggleAction ? 1 : 0,
MenuViewCommandType);
- createToggle(MI_FieldGuide, tr("&Field Guide"), "",
+ createToggle(MI_FieldGuide, tr("&Field Guide"), "Shift+G",
FieldGuideToggleAction ? 1 : 0, MenuViewCommandType);
createToggle(MI_ViewBBox, tr("&Raster Bounding Box"), "",
ViewBBoxToggleAction ? 1 : 0, MenuViewCommandType);
@@ -1840,18 +1852,16 @@ void MainWindow::defineActions() {
createToggle(MI_Link, tr("Link Flipbooks"), "", LinkToggleAction ? 1 : 0,
MenuViewCommandType);
- createPlaybackAction(MI_Play, tr("Play"), "");
- createPlaybackAction(MI_Loop, tr("Loop"), "");
+ createPlaybackAction(MI_Play, tr("Play"), "P");
+ createPlaybackAction(MI_Loop, tr("Loop"), "L");
createPlaybackAction(MI_Pause, tr("Pause"), "");
- createPlaybackAction(MI_FirstFrame, tr("First Frame"), "");
- createPlaybackAction(MI_LastFrame, tr("Last Frame"), "");
- createPlaybackAction(MI_PrevFrame, tr("Previous Frame"), "Shift+A");
- createPlaybackAction(MI_NextFrame, tr("Next Frame"), "Shift+S");
-
- createAction(MI_NextDrawing, tr("Next Drawing"), "Shift+X",
- PlaybackCommandType);
- createAction(MI_PrevDrawing, tr("Prev Drawing"), "Shift+Z",
- PlaybackCommandType);
+ createPlaybackAction(MI_FirstFrame, tr("First Frame"), "Alt+,");
+ createPlaybackAction(MI_LastFrame, tr("Last Frame"), "Alt+.");
+ createPlaybackAction(MI_PrevFrame, tr("Previous Frame"), "Shift+,");
+ createPlaybackAction(MI_NextFrame, tr("Next Frame"), "Shift+.");
+
+ createAction(MI_NextDrawing, tr("Next Drawing"), ".", PlaybackCommandType);
+ createAction(MI_PrevDrawing, tr("Prev Drawing"), ",", PlaybackCommandType);
createAction(MI_NextStep, tr("Next Step"), "", PlaybackCommandType);
createAction(MI_PrevStep, tr("Prev Step"), "", PlaybackCommandType);
@@ -1866,7 +1876,7 @@ void MainWindow::defineActions() {
createViewerAction(MI_CompareToSnapshot, tr("Compare to Snapshot"), "");
createFillAction(MI_AutoFillToggle,
- tr("Toggle Autofill on Current Palette Color"), "");
+ tr("Toggle Autofill on Current Palette Color"), "Shift+A");
toggle =
createToggle(MI_DockingCheck, tr("&Lock Room Panes"), "",
@@ -1908,7 +1918,7 @@ void MainWindow::defineActions() {
// createAction(MI_Export, "Export", "Ctrl+E");
createMenuWindowsAction(MI_OpenComboViewer, tr("&ComboViewer"), "");
- createMenuWindowsAction(MI_OpenHistoryPanel, tr("&History"), "");
+ createMenuWindowsAction(MI_OpenHistoryPanel, tr("&History"), "Ctrl+H");
createMenuWindowsAction(MI_ResetRoomLayout, tr("&Reset to Default Rooms"),
"");
@@ -1917,10 +1927,10 @@ void MainWindow::defineActions() {
tr("Toggle Main Window's Full Screen Mode"),
"Ctrl+`");
createMenuWindowsAction(MI_About, tr("&About OpenToonz..."), "");
-
+ createMenuWindowsAction(MI_StartupPopup, tr("&Startup Popup..."), "Alt+S");
createRightClickMenuAction(MI_BlendColors, tr("&Blend colors"), "");
- createToggle(MI_OnionSkin, tr("Onion Skin Toggle"), "//", false,
+ createToggle(MI_OnionSkin, tr("Onion Skin Toggle"), "/", false,
RightClickMenuCommandType);
createToggle(MI_ZeroThick, tr("Zero Thick Lines"), "Shift+/", false,
RightClickMenuCommandType);
@@ -1991,12 +2001,16 @@ void MainWindow::defineActions() {
createRightClickMenuAction(MI_DisableAllColumns, tr("OFF All"), "");
createRightClickMenuAction(MI_DisableSelectedColumns, tr("OFF Selected"), "");
createRightClickMenuAction(MI_SwapEnabledColumns, tr("Swap ON/OFF"), "");
- createRightClickMenuAction(MI_LockThisColumnOnly, tr("Lock This Only"), "");
- createRightClickMenuAction(MI_LockSelectedColumns, tr("Lock Selected"), "");
- createRightClickMenuAction(MI_LockAllColumns, tr("Lock All"), "");
+ createRightClickMenuAction(MI_LockThisColumnOnly, tr("Lock This Only"),
+ "Shift+L");
+ createRightClickMenuAction(MI_LockSelectedColumns, tr("Lock Selected"),
+ "Ctrl+Shift+L");
+ createRightClickMenuAction(MI_LockAllColumns, tr("Lock All"),
+ "Ctrl+Alt+Shift+L");
createRightClickMenuAction(MI_UnlockSelectedColumns, tr("Unlock Selected"),
- "");
- createRightClickMenuAction(MI_UnlockAllColumns, tr("Unlock All"), "");
+ "Ctrl+Shift+U");
+ createRightClickMenuAction(MI_UnlockAllColumns, tr("Unlock All"),
+ "Ctrl+Alt+Shift+U");
createRightClickMenuAction(MI_ToggleColumnLocks, tr("Swap Lock/Unlock"), "");
/*-- カレントカラムの右側のカラムを全て非表示にするコマンド --*/
createRightClickMenuAction(MI_DeactivateUpperColumns,
@@ -2012,31 +2026,32 @@ void MainWindow::defineActions() {
createToolAction(T_Eraser, "eraser", tr("Eraser Tool"), "A");
createToolAction(T_Tape, "tape", tr("Tape Tool"), "T");
createToolAction(T_StylePicker, "stylepicker", tr("Style Picker Tool"), "K");
- createToolAction(T_RGBPicker, "RGBpicker", tr("RGB Picker Tool"), "");
+ createToolAction(T_RGBPicker, "RGBpicker", tr("RGB Picker Tool"), "R");
createToolAction(T_ControlPointEditor, "controlpointeditor",
tr("Control Point Editor Tool"), "C");
- createToolAction(T_Pinch, "pinch", tr("Pinch Tool"), "P");
+ createToolAction(T_Pinch, "pinch", tr("Pinch Tool"), "M");
createToolAction(T_Pump, "pump", tr("Pump Tool"), "");
createToolAction(T_Magnet, "magnet", tr("Magnet Tool"), "");
createToolAction(T_Bender, "bender", tr("Bender Tool"), "");
createToolAction(T_Iron, "iron", tr("Iron Tool"), "");
createToolAction(T_Cutter, "cutter", tr("Cutter Tool"), "");
- createToolAction(T_Skeleton, "skeleton", tr("Skeleton Tool"), "");
+ createToolAction(T_Skeleton, "skeleton", tr("Skeleton Tool"), "V");
createToolAction(T_Tracker, "tracker", tr("Tracker Tool"), "");
- createToolAction(T_Hook, "hook", tr("Hook Tool"), "");
+ createToolAction(T_Hook, "hook", tr("Hook Tool"), "O");
createToolAction(T_Zoom, "zoom", tr("Zoom Tool"), "Shift+Space");
createToolAction(T_Rotate, "rotate", tr("Rotate Tool"), "Ctrl+Space");
createToolAction(T_Hand, "hand", tr("Hand Tool"), "Space");
- createToolAction(T_Plastic, "plastic", tr("Plastic Tool"), "");
+ createToolAction(T_Plastic, "plastic", tr("Plastic Tool"), "X");
createToolAction(T_Ruler, "ruler", tr("Ruler Tool"), "");
createToolAction(T_Finger, "finger", tr("Finger Tool"), "");
createViewerAction(V_ZoomIn, tr("Zoom In"), "+");
createViewerAction(V_ZoomOut, tr("Zoom Out"), "-");
createViewerAction(V_ZoomReset, tr("Reset View"), "0");
- createViewerAction(V_ZoomFit, tr("Fit to Window"), "");
+ createViewerAction(V_ZoomFit, tr("Fit to Window"), "9");
createViewerAction(V_ActualPixelSize, tr("Actual Pixel Size"), "N");
- createViewerAction(V_ShowHideFullScreen, tr("Show//Hide Full Screen"), "");
+ createViewerAction(V_ShowHideFullScreen, tr("Show//Hide Full Screen"),
+ "Alt+F");
CommandManager::instance()->setToggleTexts(V_ShowHideFullScreen,
tr("Full Screen Mode"),
tr("Exit Full Screen Mode"));
@@ -2046,13 +2061,13 @@ void MainWindow::defineActions() {
createToolOptionsAction("A_ToolOption_GlobalKey", tr("Global Key"), "");
createToolOptionsAction("A_IncreaseMaxBrushThickness",
- tr("Brush size - Increase max"), "");
+ tr("Brush size - Increase max"), "I");
createToolOptionsAction("A_DecreaseMaxBrushThickness",
- tr("Brush size - Decrease max"), "");
+ tr("Brush size - Decrease max"), "U");
createToolOptionsAction("A_IncreaseMinBrushThickness",
- tr("Brush size - Increase min"), "");
+ tr("Brush size - Increase min"), "J");
createToolOptionsAction("A_DecreaseMinBrushThickness",
- tr("Brush size - Decrease min"), "");
+ tr("Brush size - Decrease min"), "H");
createToolOptionsAction("A_IncreaseBrushHardness",
tr("Brush hardness - Increase"), "");
createToolOptionsAction("A_DecreaseBrushHardness",
@@ -2071,7 +2086,7 @@ void MainWindow::defineActions() {
createToolOptionsAction("A_ToolOption_PreserveThickness",
tr("Preserve Thickness"), "");
createToolOptionsAction("A_ToolOption_PressureSensitivity",
- tr("Pressure Sensitivity"), "");
+ tr("Pressure Sensitivity"), "Shift+P");
createToolOptionsAction("A_ToolOption_SegmentInk", tr("Segment Ink"), "F8");
createToolOptionsAction("A_ToolOption_Selective", tr("Selective"), "F7");
createToolOptionsAction("A_ToolOption_Smooth", tr("Smooth"), "");
diff --git a/toonz/sources/toonz/mainwindow.h b/toonz/sources/toonz/mainwindow.h
index 8efc118..4eb088a 100644
--- a/toonz/sources/toonz/mainwindow.h
+++ b/toonz/sources/toonz/mainwindow.h
@@ -67,6 +67,7 @@ class MainWindow final : public QMainWindow {
Q_OBJECT
bool m_saveSettingsOnQuit;
+ bool m_startupPopupShown = false;
int m_oldRoomIndex;
QString m_currentRoomsChoice;
UpdateChecker *m_updateChecker;
@@ -212,6 +213,7 @@ signals:
};
class RecentFiles {
+ friend class StartupPopup;
QList m_recentScenes;
QList m_recentLevels;
QList m_recentFlipbookImages;
diff --git a/toonz/sources/toonz/menubar.cpp b/toonz/sources/toonz/menubar.cpp
index 512c136..c578245 100644
--- a/toonz/sources/toonz/menubar.cpp
+++ b/toonz/sources/toonz/menubar.cpp
@@ -1077,6 +1077,7 @@ QMenuBar *StackedMenuBar::createFullMenuBar() {
fileMenu->addSeparator();
addMenuItem(fileMenu, MI_NewLevel);
addMenuItem(fileMenu, MI_LoadLevel);
+ addMenuItem(fileMenu, MI_SaveAllLevels);
addMenuItem(fileMenu, MI_SaveLevel);
addMenuItem(fileMenu, MI_SaveLevelAs);
addMenuItem(fileMenu, MI_ExportLevel);
@@ -1343,6 +1344,7 @@ QMenuBar *StackedMenuBar::createFullMenuBar() {
//---Help Menu
QMenu *helpMenu = addMenu(tr("Help"), fullMenuBar);
+ addMenuItem(helpMenu, MI_StartupPopup);
addMenuItem(helpMenu, MI_About);
return fullMenuBar;
diff --git a/toonz/sources/toonz/menubarcommandids.h b/toonz/sources/toonz/menubarcommandids.h
index ac9a5bf..6c79b5e 100644
--- a/toonz/sources/toonz/menubarcommandids.h
+++ b/toonz/sources/toonz/menubarcommandids.h
@@ -16,6 +16,7 @@
#define MI_SaveScene "MI_SaveScene"
#define MI_SaveSceneAs "MI_SaveSceneAs"
#define MI_SaveAll "MI_SaveAll"
+#define MI_SaveAllLevels "MI_SaveAllLevels"
#define MI_RevertScene "MI_RevertScene"
#define MI_LoadSubSceneFile "MI_LoadSubSceneFile"
@@ -310,5 +311,6 @@
#define MI_PreviewFx "MI_PreviewFx"
#define MI_About "MI_About"
+#define MI_StartupPopup "MI_StartupPopup"
#define MI_PencilTest "MI_PencilTest"
#endif
diff --git a/toonz/sources/toonz/penciltestpopup.cpp b/toonz/sources/toonz/penciltestpopup.cpp
index 4667d68..02fb1b2 100644
--- a/toonz/sources/toonz/penciltestpopup.cpp
+++ b/toonz/sources/toonz/penciltestpopup.cpp
@@ -33,6 +33,7 @@
// TnzCore includes
#include "tsystem.h"
#include "tpixelutils.h"
+#include "tenv.h"
#include
@@ -64,9 +65,17 @@
#include
#include
#include
+#include
+
+#ifdef _WIN32
+#include
+#endif
using namespace DVGui;
+// Connected camera
+TEnv::StringVar CamCapCameraName("CamCapCameraName", "");
+
namespace {
void convertImageToRaster(TRaster32P dstRas, const QImage& srcImg) {
@@ -301,6 +310,90 @@ int letterToNum(QChar appendix) {
return 0;
}
+#ifdef _WIN32
+void openCaptureFilterSettings(const QWidget* parent,
+ const QString& cameraName) {
+ HRESULT hr;
+
+ ICreateDevEnum* createDevEnum = NULL;
+ IEnumMoniker* enumMoniker = NULL;
+ IMoniker* moniker = NULL;
+
+ IBaseFilter* deviceFilter;
+
+ ISpecifyPropertyPages* specifyPropertyPages;
+ CAUUID cauuid;
+ // set parent's window handle in order to make the dialog modal
+ HWND ghwndApp = (HWND)(parent->winId());
+
+ // initialize COM
+ CoInitialize(NULL);
+
+ // get device list
+ CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
+ IID_ICreateDevEnum, (PVOID*)&createDevEnum);
+
+ // create EnumMoniker
+ createDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
+ &enumMoniker, 0);
+ if (enumMoniker == NULL) {
+ // if no connected devices found
+ return;
+ }
+
+ // reset EnumMoniker
+ enumMoniker->Reset();
+
+ // find target camera
+ ULONG fetched = 0;
+ bool isCameraFound = false;
+ while (hr = enumMoniker->Next(1, &moniker, &fetched), hr == S_OK) {
+ // get friendly name (= device name) of the camera
+ IPropertyBag* pPropertyBag;
+ moniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPropertyBag);
+ VARIANT var;
+ var.vt = VT_BSTR;
+ VariantInit(&var);
+
+ pPropertyBag->Read(L"FriendlyName", &var, 0);
+
+ QString deviceName = QString::fromWCharArray(var.bstrVal);
+
+ VariantClear(&var);
+
+ if (deviceName == cameraName) {
+ // bind monkier to the filter
+ moniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&deviceFilter);
+
+ // release moniker etc.
+ moniker->Release();
+ enumMoniker->Release();
+ createDevEnum->Release();
+
+ isCameraFound = true;
+ break;
+ }
+ }
+
+ // if no matching camera found
+ if (!isCameraFound) return;
+
+ // open capture filter popup
+ hr = deviceFilter->QueryInterface(IID_ISpecifyPropertyPages,
+ (void**)&specifyPropertyPages);
+ if (hr == S_OK) {
+ hr = specifyPropertyPages->GetPages(&cauuid);
+
+ hr = OleCreatePropertyFrame(ghwndApp, 30, 30, NULL, 1,
+ (IUnknown**)&deviceFilter, cauuid.cElems,
+ (GUID*)cauuid.pElems, 0, 0, NULL);
+
+ CoTaskMemFree(cauuid.pElems);
+ specifyPropertyPages->Release();
+ }
+}
+#endif
+
} // namespace
//=============================================================================
@@ -363,7 +456,7 @@ void MyViewFinder::paintEvent(QPaintEvent* event) {
}
}
-void MyViewFinder::resizeEvent(QResizeEvent* event) {
+void MyViewFinder::updateSize() {
if (!m_camera) return;
QSize cameraReso = m_camera->viewfinderSettings().resolution();
double cameraAR = (double)cameraReso.width() / (double)cameraReso.height();
@@ -381,6 +474,8 @@ void MyViewFinder::resizeEvent(QResizeEvent* event) {
}
}
+void MyViewFinder::resizeEvent(QResizeEvent* event) { updateSize(); }
+
//=============================================================================
FrameNumberLineEdit::FrameNumberLineEdit(QWidget* parent, int value)
@@ -449,10 +544,34 @@ void FrameNumberLineEdit::focusOutEvent(QFocusEvent*) {}
//=============================================================================
+LevelNameLineEdit::LevelNameLineEdit(QWidget* parent)
+ : QLineEdit(parent), m_textOnFocusIn("") {
+ // Exclude all character which cannot fit in a filepath (Win).
+ // Dots are also prohibited since they are internally managed by Toonz.
+ QRegExp rx("[^\\\\/:?*.\"<>|]+");
+ setValidator(new QRegExpValidator(rx, this));
+ setObjectName("LargeSizedText");
+
+ connect(this, SIGNAL(editingFinished()), this, SLOT(onEditingFinished()));
+}
+
+void LevelNameLineEdit::focusInEvent(QFocusEvent* e) {
+ m_textOnFocusIn = text();
+}
+
+void LevelNameLineEdit::onEditingFinished() {
+ // if the content is not changed, do nothing.
+ if (text() == m_textOnFocusIn) return;
+
+ emit levelNameEdited();
+}
+
+//=============================================================================
+
PencilTestPopup::PencilTestPopup()
: Dialog(TApp::instance()->getMainWindow(), false, false, "PencilTest")
- , m_currentCamera(0)
- , m_cameraImageCapture(0)
+ , m_currentCamera(NULL)
+ , m_cameraImageCapture(NULL)
, m_captureWhiteBGCue(false)
, m_captureCue(false) {
setWindowTitle(tr("Camera Capture"));
@@ -479,7 +598,7 @@ PencilTestPopup::PencilTestPopup()
m_resolutionCombo = new QComboBox(this);
QGroupBox* fileFrame = new QGroupBox(tr("File"), this);
- m_levelNameEdit = new QLineEdit(this);
+ m_levelNameEdit = new LevelNameLineEdit(this);
// set the start frame 10 if the option in preferences
// "Show ABC Appendix to the Frame Number in Xsheet Cell" is active.
// (frame 10 is displayed as "1" with this option)
@@ -517,6 +636,12 @@ PencilTestPopup::PencilTestPopup()
m_captureButton = new QPushButton(tr("Capture\n[Return key]"), this);
QPushButton* closeButton = new QPushButton(tr("Close"), this);
+
+#ifdef _WIN32
+ m_captureFilterSettingsBtn = new QPushButton(this);
+#else
+ m_captureFilterSettingsBtn = 0;
+#endif
//----
m_resolutionCombo->setMaximumWidth(fontMetrics().width("0000 x 0000") + 25);
@@ -524,11 +649,6 @@ PencilTestPopup::PencilTestPopup()
m_fileTypeCombo->setCurrentIndex(0);
fileFrame->setObjectName("CleanupSettingsFrame");
- // Exclude all character which cannot fit in a filepath (Win).
- // Dots are also prohibited since they are internally managed by Toonz.
- QRegExp rx("[^\\\\/:?*.\"<>|]+");
- m_levelNameEdit->setValidator(new QRegExpValidator(rx, this));
- m_levelNameEdit->setObjectName("LargeSizedText");
m_frameNumberEdit->setObjectName("LargeSizedText");
nextLevelButton->setFixedSize(24, 24);
nextLevelButton->setArrowType(Qt::RightArrow);
@@ -573,6 +693,14 @@ PencilTestPopup::PencilTestPopup()
m_captureButton->setIcon(style.standardIcon(QStyle::SP_DialogOkButton));
m_captureButton->setIconSize(QSize(30, 30));
+ if (m_captureFilterSettingsBtn) {
+ m_captureFilterSettingsBtn->setObjectName("GearButton");
+ m_captureFilterSettingsBtn->setFixedSize(23, 23);
+ m_captureFilterSettingsBtn->setIconSize(QSize(15, 15));
+ m_captureFilterSettingsBtn->setToolTip(
+ tr("Video Capture Filter Settings..."));
+ }
+
//---- layout ----
QHBoxLayout* mainLay = new QHBoxLayout();
mainLay->setMargin(0);
@@ -592,6 +720,12 @@ PencilTestPopup::PencilTestPopup()
camLay->addSpacing(10);
camLay->addWidget(new QLabel(tr("Resolution:"), this), 0);
camLay->addWidget(m_resolutionCombo, 1);
+
+ if (m_captureFilterSettingsBtn) {
+ camLay->addSpacing(10);
+ camLay->addWidget(m_captureFilterSettingsBtn);
+ }
+
camLay->addStretch(0);
}
leftLay->addLayout(camLay, 0);
@@ -739,6 +873,8 @@ PencilTestPopup::PencilTestPopup()
this, SLOT(onResolutionComboActivated(const QString&)));
ret = ret && connect(m_fileFormatOptionButton, SIGNAL(pressed()), this,
SLOT(onFileFormatOptionButtonPressed()));
+ ret = ret && connect(m_levelNameEdit, SIGNAL(levelNameEdited()), this,
+ SLOT(onLevelNameEdited()));
ret = ret &&
connect(nextLevelButton, SIGNAL(pressed()), this, SLOT(onNextName()));
ret = ret && connect(m_colorTypeCombo, SIGNAL(currentIndexChanged(int)), this,
@@ -761,17 +897,33 @@ PencilTestPopup::PencilTestPopup()
ret = ret && connect(closeButton, SIGNAL(clicked()), this, SLOT(reject()));
ret = ret && connect(m_captureButton, SIGNAL(clicked(bool)), this,
SLOT(onCaptureButtonClicked(bool)));
+ if (m_captureFilterSettingsBtn)
+ ret = ret && connect(m_captureFilterSettingsBtn, SIGNAL(pressed()), this,
+ SLOT(onCaptureFilterSettingsBtnPressed()));
assert(ret);
refreshCameraList();
+
+ int startupCamIndex = m_cameraListCombo->findText(
+ QString::fromStdString(CamCapCameraName.getValue()));
+ if (startupCamIndex > 0) {
+ m_cameraListCombo->setCurrentIndex(startupCamIndex);
+ onCameraListComboActivated(startupCamIndex);
+ }
+
onNextName();
}
//-----------------------------------------------------------------------------
PencilTestPopup::~PencilTestPopup() {
- if (m_currentCamera && m_currentCamera->state() == QCamera::ActiveState)
- m_currentCamera->stop();
+ if (m_currentCamera) {
+ if (m_currentCamera->state() == QCamera::ActiveState)
+ m_currentCamera->stop();
+ if (m_currentCamera->state() == QCamera::LoadedState)
+ m_currentCamera->unload();
+ delete m_currentCamera;
+ }
// remove the cache image, if it exists
TFilePath fp(m_cacheImagePath);
if (TFileStatus(fp).doesExist()) TSystem::deleteFile(fp);
@@ -790,27 +942,48 @@ void PencilTestPopup::refreshCameraList() {
}
int maxTextLength = 0;
- int defaultIndex;
+ // add non-connected state as default
+ m_cameraListCombo->addItem(tr("- Select camera -"));
for (int c = 0; c < cameras.size(); c++) {
QString camDesc = cameras.at(c).description();
m_cameraListCombo->addItem(camDesc);
maxTextLength = std::max(maxTextLength, fontMetrics().width(camDesc));
- if (cameras.at(c).deviceName() == QCameraInfo::defaultCamera().deviceName())
- defaultIndex = c;
}
m_cameraListCombo->setMaximumWidth(maxTextLength + 25);
m_cameraListCombo->setEnabled(true);
- m_cameraListCombo->setCurrentIndex(defaultIndex);
-
- onCameraListComboActivated(defaultIndex);
+ m_cameraListCombo->setCurrentIndex(0);
}
//-----------------------------------------------------------------------------
-void PencilTestPopup::onCameraListComboActivated(int index) {
+void PencilTestPopup::onCameraListComboActivated(int comboIndex) {
QList cameras = QCameraInfo::availableCameras();
- if (cameras.size() != m_cameraListCombo->count()) return;
+ if (cameras.size() != m_cameraListCombo->count() - 1) return;
+
+ // if selected the non-connected state, then disconnect the current camera
+ if (comboIndex == 0) {
+ m_cameraViewfinder->setCamera(NULL);
+ if (m_cameraImageCapture) {
+ disconnect(m_cameraImageCapture,
+ SIGNAL(imageCaptured(int, const QImage&)), this,
+ SLOT(onImageCaptured(int, const QImage&)));
+ delete m_cameraImageCapture;
+ m_cameraImageCapture = NULL;
+ }
+ if (m_currentCamera) {
+ if (m_currentCamera->state() == QCamera::ActiveState)
+ m_currentCamera->stop();
+ if (m_currentCamera->state() == QCamera::LoadedState)
+ m_currentCamera->unload();
+ }
+ m_deviceName = QString();
+ m_cameraViewfinder->setImage(QImage());
+ // update env
+ CamCapCameraName = "";
+ return;
+ }
+ int index = comboIndex - 1;
// in case the camera is not changed (just click the combobox)
if (cameras.at(index).deviceName() == m_deviceName) return;
@@ -850,11 +1023,13 @@ void PencilTestPopup::onCameraListComboActivated(int index) {
settings.setResolution(sizes.last());
m_currentCamera->setViewfinderSettings(settings);
QImageEncoderSettings imageEncoderSettings;
- imageEncoderSettings.setCodec("PNG");
+ imageEncoderSettings.setCodec("image/jpeg");
+ imageEncoderSettings.setQuality(QMultimedia::NormalQuality);
imageEncoderSettings.setResolution(sizes.last());
m_cameraImageCapture->setEncodingSettings(imageEncoderSettings);
}
m_cameraViewfinder->setCamera(m_currentCamera);
+ m_cameraViewfinder->updateSize();
// deleting old camera
if (oldCamera) {
@@ -864,6 +1039,9 @@ void PencilTestPopup::onCameraListComboActivated(int index) {
// start new camera
m_currentCamera->start();
m_cameraViewfinder->setImage(QImage());
+
+ // update env
+ CamCapCameraName = m_cameraListCombo->itemText(comboIndex).toStdString();
}
//-----------------------------------------------------------------------------
@@ -886,6 +1064,7 @@ void PencilTestPopup::onResolutionComboActivated(const QString& itemText) {
imageEncoderSettings.setQuality(QMultimedia::NormalQuality);
imageEncoderSettings.setResolution(newResolution);
m_cameraImageCapture->setEncodingSettings(imageEncoderSettings);
+ m_cameraViewfinder->updateSize();
// reset white bg
m_whiteBGImg = QImage();
@@ -909,6 +1088,17 @@ void PencilTestPopup::onFileFormatOptionButtonPressed() {
//-----------------------------------------------------------------------------
+void PencilTestPopup::onLevelNameEdited() {
+ // set the start frame 10 if the option in preferences
+ // "Show ABC Appendix to the Frame Number in Xsheet Cell" is active.
+ // (frame 10 is displayed as "1" with this option)
+ int startFrame =
+ Preferences::instance()->isShowFrameNumberWithLettersEnabled() ? 10 : 1;
+ m_frameNumberEdit->setValue(startFrame);
+}
+
+//-----------------------------------------------------------------------------
+
void PencilTestPopup::onNextName() {
const std::auto_ptr nameBuilder(NameBuilder::getBuilder(L""));
@@ -956,6 +1146,7 @@ void PencilTestPopup::onColorTypeComboChanged(int index) {
//-----------------------------------------------------------------------------
void PencilTestPopup::onImageCaptured(int id, const QImage& image) {
+ if (!m_cameraViewfinder) return;
// capture the white BG
if (m_captureWhiteBGCue) {
m_whiteBGImg = image.copy();
@@ -1018,6 +1209,14 @@ void PencilTestPopup::showEvent(QShowEvent* event) {
// then release the shortcut key temporary while the popup opens
QAction* action = CommandManager::instance()->getActionFromShortcut("Return");
if (action) action->setShortcut(QKeySequence(""));
+
+ // reload camera
+ if (m_currentCamera) {
+ if (m_currentCamera->state() == QCamera::UnloadedState)
+ m_currentCamera->load();
+ if (m_currentCamera->state() == QCamera::LoadedState)
+ m_currentCamera->start();
+ }
}
//-----------------------------------------------------------------------------
@@ -1034,6 +1233,14 @@ void PencilTestPopup::hideEvent(QHideEvent* event) {
m_captureButton->setChecked(false);
onCaptureButtonClicked(false);
}
+
+ // release camera
+ if (m_currentCamera) {
+ if (m_currentCamera->state() == QCamera::ActiveState)
+ m_currentCamera->stop();
+ if (m_currentCamera->state() == QCamera::LoadedState)
+ m_currentCamera->unload();
+ }
}
//-----------------------------------------------------------------------------
@@ -1213,7 +1420,7 @@ bool PencilTestPopup::importImage(QImage& image) {
/* if the level does not exist in the scene cast */
else {
/* if the file does exist, load it first */
- if (TFileStatus(actualLevelFp).doesExist()) {
+ if (TSystem::doesExistFileOrLevel(actualLevelFp)) {
level = scene->loadLevel(actualLevelFp);
if (!level) {
error(tr("Failed to load %1.").arg(toQString(actualLevelFp)));
@@ -1229,6 +1436,15 @@ bool PencilTestPopup::importImage(QImage& image) {
"The captured image size does not match with the existing level."));
return false;
}
+
+ /* confirm overwrite */
+ QString question =
+ tr("File %1 does exist.\nDo you want to overwrite it?")
+ .arg(toQString(actualLevelFp.withFrame(frameNumber)));
+ int ret = DVGui::MsgBox(question, QObject::tr("Overwrite"),
+ QObject::tr("Cancel"));
+ if (ret == 0 || ret == 2) return false;
+
}
/* if the file does not exist, then create a new level */
else {
@@ -1267,29 +1483,28 @@ bool PencilTestPopup::importImage(QImage& image) {
int col = app->getCurrentColumn()->getColumnIndex();
/* try to find the vacant cell */
- int tmpRow = row;
- bool isFoundEmptyCell = false;
+ int tmpRow = row;
while (1) {
- if (xsh->getCell(tmpRow, col).isEmpty()) {
- isFoundEmptyCell = true;
+ /* if the same cell is already in the column, then just replace the content
+ * and do not set a new cell */
+ if (xsh->getCell(tmpRow, col) == TXshCell(sl, fid)) break;
+ /* in case setting the same level as the the current column */
+ else if (xsh->getCell(tmpRow, col).isEmpty()) {
+ xsh->setCell(tmpRow, col, TXshCell(sl, fid));
+ break;
+ }
+ /* in case the level is different from the current column, then insert a new
+ column */
+ else if (xsh->getCell(tmpRow, col).m_level->getSimpleLevel() != sl) {
+ col += 1;
+ xsh->insertColumn(col);
+ xsh->setCell(row, col, TXshCell(sl, fid));
+ app->getCurrentColumn()->setColumnIndex(col);
break;
}
- if (xsh->getCell(tmpRow, col).m_level->getSimpleLevel() != sl) break;
tmpRow++;
}
- /* in case setting the same level as the the current column */
- if (isFoundEmptyCell) {
- xsh->setCell(tmpRow, col, TXshCell(sl, fid));
- }
- /* in case the level is different from the current column, then insert a new
- column */
- else {
- col += 1;
- xsh->insertColumn(col);
- xsh->setCell(row, col, TXshCell(sl, fid));
- app->getCurrentColumn()->setColumnIndex(col);
- }
/* notify */
app->getCurrentScene()->notifySceneChanged();
app->getCurrentScene()->notifyCastChange();
@@ -1300,4 +1515,20 @@ bool PencilTestPopup::importImage(QImage& image) {
//-----------------------------------------------------------------------------
+void PencilTestPopup::onCaptureFilterSettingsBtnPressed() {
+ if (!m_currentCamera || m_deviceName.isNull()) return;
+
+ QList cameras = QCameraInfo::availableCameras();
+ for (int c = 0; c < cameras.size(); c++) {
+ if (cameras.at(c).deviceName() == m_deviceName) {
+#ifdef _WIN32
+ openCaptureFilterSettings(this, cameras.at(c).description());
+#endif
+ return;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+
OpenPopupCommandHandler openPencilTestPopup(MI_PencilTest);
\ No newline at end of file
diff --git a/toonz/sources/toonz/penciltestpopup.h b/toonz/sources/toonz/penciltestpopup.h
index d2150ba..0ff31f4 100644
--- a/toonz/sources/toonz/penciltestpopup.h
+++ b/toonz/sources/toonz/penciltestpopup.h
@@ -21,6 +21,7 @@ class QVideoFrame;
class QTimer;
class QIntValidator;
class QRegExpValidator;
+class QPushButton;
namespace DVGui {
class FileField;
@@ -61,6 +62,8 @@ public:
repaint();
}
+ void updateSize();
+
protected:
void paintEvent(QPaintEvent* event);
void resizeEvent(QResizeEvent* event);
@@ -100,6 +103,25 @@ protected:
};
//=============================================================================
+
+class LevelNameLineEdit : public QLineEdit {
+ Q_OBJECT
+ QString m_textOnFocusIn;
+
+public:
+ LevelNameLineEdit(QWidget* parent = 0);
+
+protected:
+ void focusInEvent(QFocusEvent* e);
+
+protected slots:
+ void onEditingFinished();
+
+signals:
+ void levelNameEdited();
+};
+
+//=============================================================================
// PencilTestPopup
//-----------------------------------------------------------------------------
@@ -113,7 +135,7 @@ class PencilTestPopup : public DVGui::Dialog {
QComboBox *m_cameraListCombo, *m_resolutionCombo, *m_fileTypeCombo,
*m_colorTypeCombo;
- QLineEdit* m_levelNameEdit;
+ LevelNameLineEdit* m_levelNameEdit;
QCheckBox *m_upsideDownCB, *m_onionSkinCB, *m_saveOnCaptureCB, *m_timerCB;
QPushButton *m_fileFormatOptionButton, *m_captureWhiteBGButton,
*m_captureButton;
@@ -126,6 +148,9 @@ class PencilTestPopup : public DVGui::Dialog {
QImage m_whiteBGImg;
+ // used only for Windows
+ QPushButton* m_captureFilterSettingsBtn;
+
int m_timerId;
QString m_cacheImagePath;
bool m_captureWhiteBGCue;
@@ -150,6 +175,7 @@ protected slots:
void onCameraListComboActivated(int index);
void onResolutionComboActivated(const QString&);
void onFileFormatOptionButtonPressed();
+ void onLevelNameEdited();
void onNextName();
void onColorTypeComboChanged(int index);
void onImageCaptured(int, const QImage&);
@@ -161,6 +187,7 @@ protected slots:
void onCountDown();
void onCaptureButtonClicked(bool);
+ void onCaptureFilterSettingsBtnPressed();
};
#endif
\ No newline at end of file
diff --git a/toonz/sources/toonz/preferencespopup.cpp b/toonz/sources/toonz/preferencespopup.cpp
index 1ee465b..d9d06f1 100644
--- a/toonz/sources/toonz/preferencespopup.cpp
+++ b/toonz/sources/toonz/preferencespopup.cpp
@@ -45,6 +45,7 @@
#include
#include
#include
+#include
using namespace DVGui;
@@ -278,6 +279,33 @@ void PreferencesPopup::onPixelsOnlyChanged(int index) {
//-----------------------------------------------------------------------------
+void PreferencesPopup::onProjectRootChanged() {
+ int index = 0;
+ if (m_projectRootStuff->isChecked()) index |= 0x08;
+ if (m_projectRootDocuments->isChecked()) index |= 0x04;
+ if (m_projectRootDesktop->isChecked()) index |= 0x02;
+ if (m_projectRootCustom->isChecked()) index |= 0x01;
+ m_pref->setProjectRoot(index);
+ if (index & 0x01) {
+ m_customProjectRootFileField->show();
+ m_customProjectRootLabel->show();
+ m_projectRootDirections->show();
+ } else {
+ m_customProjectRootFileField->hide();
+ m_customProjectRootLabel->hide();
+ m_projectRootDirections->hide();
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+void PreferencesPopup::onCustomProjectRootChanged() {
+ QString text = m_customProjectRootFileField->getPath();
+ m_pref->setCustomProjectRoot(text.toStdWString());
+}
+
+//-----------------------------------------------------------------------------
+
void PreferencesPopup::onPixelUnitExternallySelected(bool on) {
// call slot function onPixelsOnlyChanged() accordingly
m_pixelsOnlyCB->setCheckState((on) ? Qt::Checked : Qt::Unchecked);
@@ -526,9 +554,37 @@ void PreferencesPopup::onDefaultViewerChanged(int index) {
//-----------------------------------------------------------------------------
-void PreferencesPopup::onAutoSaveChanged(int index) {
- m_minuteFld->setEnabled(index == Qt::Checked);
- m_pref->enableAutosave(index == Qt::Checked);
+void PreferencesPopup::onAutoSaveChanged(bool on) {
+ m_pref->enableAutosave(on);
+ if (on && !m_autoSaveSceneCB->isChecked() &&
+ !m_autoSaveOtherFilesCB->isChecked()) {
+ m_autoSaveSceneCB->setChecked(true);
+ m_autoSaveOtherFilesCB->setChecked(true);
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+void PreferencesPopup::onAutoSaveSceneChanged(int index) {
+ m_pref->enableAutosaveScene(index == Qt::Checked);
+ if (!m_autoSaveOtherFilesCB->isChecked() && index == Qt::Unchecked) {
+ m_autoSaveGroup->setChecked(false);
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+void PreferencesPopup::onAutoSaveOtherFilesChanged(int index) {
+ m_pref->enableAutosaveOtherFiles(index == Qt::Checked);
+ if (!m_autoSaveSceneCB->isChecked() && index == Qt::Unchecked) {
+ m_autoSaveGroup->setChecked(false);
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+void PreferencesPopup::onStartupPopupChanged(int index) {
+ m_pref->enableStartupPopup(index == Qt::Checked);
}
//-----------------------------------------------------------------------------
@@ -939,8 +995,14 @@ PreferencesPopup::PreferencesPopup()
new CheckBox(tr("Use Default Viewer for Movie Formats"), this);
CheckBox *minimizeRasterMemoryCB =
new CheckBox(tr("Minimize Raster Memory Fragmentation *"), this);
- CheckBox *autoSaveCB = new CheckBox(tr("Save Automatically Every Minutes"));
- m_minuteFld = new DVGui::IntLineEdit(this, 15, 1, 60);
+ m_autoSaveGroup = new QGroupBox(tr("Save Automatically"), this);
+ m_autoSaveGroup->setCheckable(true);
+ m_autoSaveSceneCB = new CheckBox(tr("Automatically Save the Scene File"));
+ m_autoSaveOtherFilesCB =
+ new CheckBox(tr("Automatically Save Non-Scene Files"));
+ CheckBox *startupPopupCB =
+ new CheckBox(tr("Show Startup Window when OpenToonz Starts"));
+ m_minuteFld = new DVGui::IntLineEdit(this, 15, 1, 60);
CheckBox *replaceAfterSaveLevelAsCB =
new CheckBox(tr("Replace Toonz Level after SaveLevelAs command"), this);
@@ -952,6 +1014,15 @@ PreferencesPopup::PreferencesPopup()
new DVGui::IntLineEdit(this, m_pref->getDefaultTaskChunkSize(), 1, 2000);
CheckBox *sceneNumberingCB = new CheckBox(tr("Show Info in Rendered Frames"));
+ m_projectRootDocuments = new CheckBox(tr("My Documents/OpenToonz*"), this);
+ m_projectRootDesktop = new CheckBox(tr("Desktop/OpenToonz*"), this);
+ m_projectRootStuff = new CheckBox(tr("Stuff Folder*"), this);
+ m_projectRootCustom = new CheckBox(tr("Custom*"), this);
+ m_customProjectRootFileField = new DVGui::FileField(this, QString(""));
+ m_customProjectRootLabel = new QLabel(tr("Custom Project Path(s): "));
+ m_projectRootDirections = new QLabel(
+ tr("Advanced: Multiple paths can be separated by ** (No Spaces)"));
+
QLabel *note_general =
new QLabel(tr("* Changes will take effect the next time you run Toonz"));
note_general->setStyleSheet("font-size: 10px; font: italic;");
@@ -1143,9 +1214,11 @@ PreferencesPopup::PreferencesPopup()
//--- General ------------------------------
useDefaultViewerCB->setChecked(m_pref->isDefaultViewerEnabled());
minimizeRasterMemoryCB->setChecked(m_pref->isRasterOptimizedMemory());
- autoSaveCB->setChecked(m_pref->isAutosaveEnabled());
+ m_autoSaveGroup->setChecked(m_pref->isAutosaveEnabled());
+ m_autoSaveSceneCB->setChecked(m_pref->isAutosaveSceneEnabled());
+ m_autoSaveOtherFilesCB->setChecked(m_pref->isAutosaveOtherFilesEnabled());
m_minuteFld->setValue(m_pref->getAutosavePeriod());
- m_minuteFld->setEnabled(m_pref->isAutosaveEnabled());
+ startupPopupCB->setChecked(m_pref->isStartupPopupEnabled());
replaceAfterSaveLevelAsCB->setChecked(
m_pref->isReplaceAfterSaveLevelAsEnabled());
@@ -1156,6 +1229,20 @@ PreferencesPopup::PreferencesPopup()
m_levelsBackup->setChecked(m_pref->isLevelsBackupEnabled());
sceneNumberingCB->setChecked(m_pref->isSceneNumberingEnabled());
+ m_customProjectRootFileField->setPath(m_pref->getCustomProjectRoot());
+
+ int projectPaths = m_pref->getProjectRoot();
+ m_projectRootStuff->setChecked(projectPaths & 0x08);
+ m_projectRootDocuments->setChecked(projectPaths & 0x04);
+ m_projectRootDesktop->setChecked(projectPaths & 0x02);
+ m_projectRootCustom->setChecked(projectPaths & 0x01);
+
+ m_projectRootStuff->hide();
+ if (!(projectPaths & 0x01)) {
+ m_customProjectRootFileField->hide();
+ m_customProjectRootLabel->hide();
+ m_projectRootDirections->hide();
+ }
//--- Interface ------------------------------
QStringList styleSheetList;
for (int i = 0; i < m_pref->getStyleSheetCount(); i++) {
@@ -1378,16 +1465,29 @@ PreferencesPopup::PreferencesPopup()
Qt::AlignLeft | Qt::AlignVCenter);
generalFrameLay->addWidget(minimizeRasterMemoryCB, 0,
Qt::AlignLeft | Qt::AlignVCenter);
- QHBoxLayout *saveAutoLay = new QHBoxLayout();
- saveAutoLay->setMargin(0);
- saveAutoLay->setSpacing(15);
+
+ QVBoxLayout *autoSaveOptionsLay = new QVBoxLayout();
+ autoSaveOptionsLay->setMargin(10);
{
- saveAutoLay->addWidget(autoSaveCB, 0);
- saveAutoLay->addWidget(m_minuteFld, 0);
- saveAutoLay->addStretch(1);
- }
- generalFrameLay->addLayout(saveAutoLay, 0);
+ QHBoxLayout *saveAutoLay = new QHBoxLayout();
+ saveAutoLay->setMargin(0);
+ saveAutoLay->setSpacing(5);
+ {
+ saveAutoLay->addWidget(new QLabel(tr("Interval(Minutes): "), this));
+ saveAutoLay->addWidget(m_minuteFld, 0);
+ saveAutoLay->addStretch(1);
+ }
+ autoSaveOptionsLay->addLayout(saveAutoLay, 0);
+ autoSaveOptionsLay->addWidget(m_autoSaveSceneCB, 0,
+ Qt::AlignLeft | Qt::AlignVCenter);
+ autoSaveOptionsLay->addWidget(m_autoSaveOtherFilesCB, 0,
+ Qt::AlignLeft | Qt::AlignVCenter);
+ }
+ m_autoSaveGroup->setLayout(autoSaveOptionsLay);
+ generalFrameLay->addWidget(m_autoSaveGroup);
+ generalFrameLay->addWidget(startupPopupCB, 0,
+ Qt::AlignLeft | Qt::AlignVCenter);
// Unit, CameraUnit
QGridLayout *unitLay = new QGridLayout();
unitLay->setMargin(0);
@@ -1414,6 +1514,24 @@ PreferencesPopup::PreferencesPopup()
Qt::AlignLeft | Qt::AlignVCenter);
generalFrameLay->addWidget(sceneNumberingCB, 0,
Qt::AlignLeft | Qt::AlignVCenter);
+ QGroupBox *projectGroupBox =
+ new QGroupBox(tr("Additional Project Locations"), this);
+ QGridLayout *projectRootLay = new QGridLayout();
+ projectRootLay->setMargin(10);
+ projectRootLay->setHorizontalSpacing(5);
+ projectRootLay->setVerticalSpacing(10);
+ {
+ projectRootLay->addWidget(m_projectRootStuff, 0, 0);
+ projectRootLay->addWidget(m_projectRootDocuments, 1, 0);
+ projectRootLay->addWidget(m_projectRootDesktop, 2, 0);
+ projectRootLay->addWidget(m_projectRootCustom, 3, 0);
+ projectRootLay->addWidget(m_customProjectRootLabel, 4, 0,
+ Qt::AlignRight | Qt::AlignVCenter);
+ projectRootLay->addWidget(m_customProjectRootFileField, 4, 1, 1, 3);
+ projectRootLay->addWidget(m_projectRootDirections, 5, 0, 1, 4);
+ }
+ projectGroupBox->setLayout(projectRootLay);
+ generalFrameLay->addWidget(projectGroupBox, 0);
generalFrameLay->addStretch(1);
generalFrameLay->addWidget(note_general, 0);
@@ -1882,10 +2000,16 @@ PreferencesPopup::PreferencesPopup()
SLOT(onDefaultViewerChanged(int)));
ret = ret && connect(minimizeRasterMemoryCB, SIGNAL(stateChanged(int)), this,
SLOT(onRasterOptimizedMemoryChanged(int)));
- ret = ret && connect(autoSaveCB, SIGNAL(stateChanged(int)),
- SLOT(onAutoSaveChanged(int)));
+ ret = ret && connect(m_autoSaveGroup, SIGNAL(toggled(bool)),
+ SLOT(onAutoSaveChanged(bool)));
+ ret = ret && connect(m_autoSaveSceneCB, SIGNAL(stateChanged(int)),
+ SLOT(onAutoSaveSceneChanged(int)));
+ ret = ret && connect(m_autoSaveOtherFilesCB, SIGNAL(stateChanged(int)),
+ SLOT(onAutoSaveOtherFilesChanged(int)));
ret = ret && connect(m_minuteFld, SIGNAL(editingFinished()),
SLOT(onMinuteChanged()));
+ ret = ret && connect(startupPopupCB, SIGNAL(stateChanged(int)),
+ SLOT(onStartupPopupChanged(int)));
ret = ret && connect(m_cellsDragBehaviour, SIGNAL(currentIndexChanged(int)),
SLOT(onDragCellsBehaviourChanged(int)));
ret = ret && connect(m_undoMemorySize, SIGNAL(editingFinished()),
@@ -1896,7 +2020,16 @@ PreferencesPopup::PreferencesPopup()
SLOT(onSceneNumberingChanged(int)));
ret = ret && connect(m_chunkSizeFld, SIGNAL(editingFinished()), this,
SLOT(onChunkSizeChanged()));
-
+ ret = ret && connect(m_customProjectRootFileField, SIGNAL(pathChanged()),
+ this, SLOT(onCustomProjectRootChanged()));
+ ret = ret && connect(m_projectRootDocuments, SIGNAL(stateChanged(int)),
+ SLOT(onProjectRootChanged()));
+ ret = ret && connect(m_projectRootDesktop, SIGNAL(stateChanged(int)),
+ SLOT(onProjectRootChanged()));
+ ret = ret && connect(m_projectRootStuff, SIGNAL(stateChanged(int)),
+ SLOT(onProjectRootChanged()));
+ ret = ret && connect(m_projectRootCustom, SIGNAL(stateChanged(int)),
+ SLOT(onProjectRootChanged()));
//--- Interface ----------------------
ret = ret && connect(styleSheetType, SIGNAL(currentIndexChanged(int)),
SLOT(onStyleSheetTypeChanged(int)));
diff --git a/toonz/sources/toonz/preferencespopup.h b/toonz/sources/toonz/preferencespopup.h
index 616582a..ba790d7 100644
--- a/toonz/sources/toonz/preferencespopup.h
+++ b/toonz/sources/toonz/preferencespopup.h
@@ -24,6 +24,7 @@
class QLineEdit;
class QPushButton;
class QLabel;
+class QGroupBox;
//==============================================================
@@ -58,7 +59,7 @@ private:
DVGui::DoubleLineEdit *m_defLevelDpi;
- QLabel *m_dpiLabel;
+ QLabel *m_dpiLabel, *m_customProjectRootLabel, *m_projectRootDirections;
DVGui::IntLineEdit *m_minuteFld, *m_chunkSizeFld, *m_iconSizeLx,
*m_iconSizeLy, *m_viewShrink, *m_viewStep, *m_blanksCount,
@@ -68,11 +69,17 @@ private:
QPushButton *m_addLevelFormat, *m_removeLevelFormat, *m_editLevelFormat;
DVGui::CheckBox *m_inksOnly, *m_enableVersionControl, *m_levelsBackup,
- *m_onionSkinVisibility, *m_pixelsOnlyCB, *m_onionSkinDuringPlayback,
+ *m_onionSkinVisibility, *m_pixelsOnlyCB, *m_projectRootDocuments,
+ *m_projectRootDesktop, *m_projectRootCustom, *m_projectRootStuff,
+ *m_onionSkinDuringPlayback, *m_autoSaveSceneCB, *m_autoSaveOtherFilesCB,
*m_useNumpadForSwitchingStyles;
+ DVGui::FileField *m_customProjectRootFileField;
+
DVGui::FileField *m_ffmpegPathFileFld;
+ QGroupBox *m_autoSaveGroup;
+
private:
// QWidget* create(const QString& lbl, bool def, const char* slot);
void rebuildFormatsList();
@@ -80,6 +87,8 @@ private:
private slots:
void onPixelsOnlyChanged(int index);
+ void onProjectRootChanged();
+ void onCustomProjectRootChanged();
void onPixelUnitExternallySelected(bool on);
void onUnitChanged(int index);
void onCameraUnitChanged(int index);
@@ -99,7 +108,10 @@ private slots:
void onRasterOptimizedMemoryChanged(int index);
void onSaveUnpaintedInCleanupChanged(int index);
void onMinimizeSaveboxAfterEditing(int index);
- void onAutoSaveChanged(int index);
+ void onAutoSaveChanged(bool on);
+ void onAutoSaveSceneChanged(int index);
+ void onAutoSaveOtherFilesChanged(int index);
+ void onStartupPopupChanged(int index);
void onDefaultViewerChanged(int index);
void onBlankCountChanged();
void onBlankColorChanged(const TPixel32 &, bool isDragging);
diff --git a/toonz/sources/toonz/sceneviewer.cpp b/toonz/sources/toonz/sceneviewer.cpp
index d039b34..1b521a2 100644
--- a/toonz/sources/toonz/sceneviewer.cpp
+++ b/toonz/sources/toonz/sceneviewer.cpp
@@ -10,6 +10,7 @@
#include "viewerdraw.h"
#include "menubarcommandids.h"
#include "ruler.h"
+#include "locatorpopup.h"
// TnzTools includes
#include "tools/cursors.h"
@@ -501,9 +502,9 @@ SceneViewer::SceneViewer(ImageUtils::FullScreenWidget *parent)
, m_sideRasterPos()
, m_topRasterPos()
, m_toolDisableReason("")
- , m_editPreviewSubCamera(false) {
- assert(parent);
-
+ , m_editPreviewSubCamera(false)
+ , m_locator(NULL)
+ , m_isLocator(false) {
m_visualSettings.m_sceneProperties =
TApp::instance()->getCurrentScene()->getScene()->getProperties();
// Enables multiple key input.
@@ -880,6 +881,9 @@ void SceneViewer::hideEvent(QHideEvent *) {
ToolHandle *toolHandle = app->getCurrentTool();
if (toolHandle) toolHandle->disconnect(this);
+
+ // hide locator
+ if (m_locator && m_locator->isVisible()) m_locator->hide();
}
//-----------------------------------------------------------------------------
@@ -967,7 +971,7 @@ void SceneViewer::drawBuildVars() {
}
TTool *tool = app->getCurrentTool()->getTool();
- if (tool) tool->setViewer(this);
+ if (tool && !m_isLocator) tool->setViewer(this);
}
//-----------------------------------------------------------------------------
@@ -1100,7 +1104,7 @@ void SceneViewer::drawCameraStand() {
// Show white background when level editing mode.
TTool *tool = TApp::instance()->getCurrentTool()->getTool();
if (m_drawEditingLevel && tool && tool->isEnabled()) {
- tool->setViewer(this);
+ if (!m_isLocator) tool->setViewer(this);
glPushMatrix();
if (m_referenceMode == CAMERA3D_REFERENCE) {
mult3DMatrix();
@@ -1358,6 +1362,13 @@ void SceneViewer::drawOverlay() {
// use
// another glContext
if (tool->getName() == "T_RGBPicker") tool->onImageChanged();
+
+ // draw cross at the center of the locator window
+ if (m_isLocator) {
+ glColor3d(1.0, 0.0, 0.0);
+ tglDrawSegment(TPointD(-4, 0), TPointD(5, 0));
+ tglDrawSegment(TPointD(0, -4), TPointD(0, 5));
+ }
}
}
diff --git a/toonz/sources/toonz/sceneviewer.h b/toonz/sources/toonz/sceneviewer.h
index 68ed8de..0941505 100644
--- a/toonz/sources/toonz/sceneviewer.h
+++ b/toonz/sources/toonz/sceneviewer.h
@@ -33,6 +33,7 @@
class Ruler;
class QMenu;
class SceneViewer;
+class LocatorPopup;
namespace ImageUtils {
class FullScreenWidget;
@@ -135,6 +136,9 @@ class SceneViewer final : public QGLWidget,
TOP_3D,
} m_current3DDevice;
+ LocatorPopup *m_locator;
+ bool m_isLocator;
+
// iwsw commented out temporarily
// Ghibli3DLutUtil * m_ghibli3DLutUtil;
public:
@@ -230,6 +234,8 @@ public:
void setFocus(Qt::FocusReason reason) { QWidget::setFocus(reason); };
+ void setIsLocator() { m_isLocator = true; }
+
public:
// SceneViewer's gadget public functions
TPointD winToWorld(const QPoint &pos) const;
diff --git a/toonz/sources/toonz/sceneviewerevents.cpp b/toonz/sources/toonz/sceneviewerevents.cpp
index c55a75a..201a553 100644
--- a/toonz/sources/toonz/sceneviewerevents.cpp
+++ b/toonz/sources/toonz/sceneviewerevents.cpp
@@ -14,6 +14,7 @@
#include "onionskinmaskgui.h"
#include "ruler.h"
#include "comboviewerpane.h"
+#include "locatorpopup.h"
// TnzQt includes
#include "toonzqt/tselectionhandle.h"
@@ -184,6 +185,14 @@ void SceneViewer::onButtonPressed(FlipConsole::EGadget button) {
m_editPreviewSubCamera = !m_editPreviewSubCamera;
update();
break;
+
+ // open locator. Create one for the first time
+ case FlipConsole::eLocator:
+ if (!m_locator) m_locator = new LocatorPopup(this);
+ m_locator->show();
+ m_locator->raise();
+ m_locator->activateWindow();
+ break;
}
}
@@ -351,7 +360,12 @@ void SceneViewer::mouseMoveEvent(QMouseEvent *event) {
TMouseEvent toonzEvent;
initToonzEvent(toonzEvent, event, height(), m_pressure, m_tabletEvent,
false);
- TPointD pos = tool->getMatrix().inv() * winToWorld(curPos);
+ TPointD worldPos = winToWorld(curPos);
+ TPointD pos = tool->getMatrix().inv() * worldPos;
+
+ if (m_locator) {
+ m_locator->onChangeViewAff(worldPos);
+ }
TObjectHandle *objHandle = TApp::instance()->getCurrentObject();
if (tool->getToolType() & TTool::LevelTool && !objHandle->isSpline()) {
@@ -379,6 +393,7 @@ void SceneViewer::mouseMoveEvent(QMouseEvent *event) {
// panning
panQt(curPos - m_pos);
m_pos = curPos;
+
return;
}
}
@@ -1009,6 +1024,7 @@ void SceneViewer::contextMenuEvent(QContextMenuEvent *e) {
#endif
if (m_freezedStatus != NO_FREEZED) return;
+ if (m_isLocator) return;
TPoint winPos(e->pos().x(), height() - e->pos().y());
std::vector columnIndices;
diff --git a/toonz/sources/toonz/shortcutpopup.cpp b/toonz/sources/toonz/shortcutpopup.cpp
index 5e36062..b51b020 100644
--- a/toonz/sources/toonz/shortcutpopup.cpp
+++ b/toonz/sources/toonz/shortcutpopup.cpp
@@ -5,8 +5,13 @@
// Tnz6 includes
#include "menubarcommandids.h"
#include "tapp.h"
+#include "tenv.h"
+#include "tsystem.h"
+#include "toonz/preferences.h"
+#include "toonz/toonzfolders.h"
// TnzQt includes
+#include "toonzqt/gutil.h"
#include "toonzqt/menubarcommand.h"
#include "toonzqt/dvdialog.h"
@@ -27,6 +32,9 @@
#include
#include
#include
+#include
+#include
+#include
// STD includes
#include
@@ -166,7 +174,7 @@ void ShortcutViewer::keyPressEvent(QKeyEvent *event) {
void ShortcutViewer::removeShortcut() {
if (m_action) {
- CommandManager::instance()->setShortcut(m_action, "");
+ CommandManager::instance()->setShortcut(m_action, "", false);
emit shortcutChanged();
update();
}
@@ -350,14 +358,32 @@ void ShortcutTree::onShortcutChanged() {
ShortcutPopup::ShortcutPopup()
: Dialog(TApp::instance()->getMainWindow(), false, false, "Shortcut") {
setWindowTitle(tr("Configure Shortcuts"));
+ m_presetChoiceCB = new QComboBox(this);
+ buildPresets();
+ m_presetChoiceCB->setCurrentIndex(0);
m_list = new ShortcutTree(this);
m_list->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_list->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_list->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
- m_sViewer = new ShortcutViewer(this);
- m_removeBtn = new QPushButton(tr("Remove"), this);
+ m_sViewer = new ShortcutViewer(this);
+ m_removeBtn = new QPushButton(tr("Remove"), this);
+ m_loadShortcutsPopup = NULL;
+ m_saveShortcutsPopup = NULL;
+ m_dialog = NULL;
+ m_exportButton = new QPushButton(tr("Export Current Shortcuts"), this);
+ m_exportButton->setToolTip(tr("Export Current Shortcuts"));
+ m_deletePresetButton = new QPushButton("Delete", this);
+ m_deletePresetButton->setToolTip(tr("Delete Current Preset"));
+ m_deletePresetButton->setIcon(QIcon(":Resources/delete_on.png"));
+ m_savePresetButton = new QPushButton("Save As", this);
+ m_savePresetButton->setToolTip(tr("Save Current Shortcuts as New Preset"));
+ m_savePresetButton->setIcon(QIcon(":Resources/saveas_on.png"));
+ m_loadPresetButton = new QPushButton(tr("Apply"));
+ m_loadPresetButton->setToolTip(tr("Use selected preset as shortcuts"));
+ m_loadPresetButton->setIcon(QIcon(":Resources/green.png"));
+ m_clearAllShortcutsButton = new QPushButton(tr("Clear All Shortcuts"));
QLabel *noSearchResultLabel =
new QLabel(tr("Couldn't find any matching command."), this);
noSearchResultLabel->setHidden(true);
@@ -394,6 +420,28 @@ ShortcutPopup::ShortcutPopup()
bottomLayout->addWidget(m_removeBtn, 0);
}
m_topLayout->addLayout(bottomLayout, 0);
+ m_topLayout->addSpacing(10);
+ QHBoxLayout *presetLay = new QHBoxLayout();
+ presetLay->setMargin(0);
+ presetLay->setSpacing(5);
+ {
+ presetLay->addWidget(new QLabel("Preset:", this), 0);
+ presetLay->addWidget(m_presetChoiceCB, 1);
+ presetLay->addWidget(m_loadPresetButton, 0);
+ presetLay->addWidget(m_savePresetButton, 0);
+ presetLay->addWidget(m_deletePresetButton, 0);
+ }
+ m_topLayout->addLayout(presetLay, 0);
+ m_topLayout->addSpacing(10);
+ QHBoxLayout *exportLay = new QHBoxLayout();
+ exportLay->setMargin(0);
+ exportLay->setSpacing(5);
+ {
+ exportLay->addWidget(m_exportButton, 0);
+ exportLay->addWidget(m_clearAllShortcutsButton, 0);
+ }
+ m_topLayout->addLayout(exportLay, 0);
+ // m_topLayout->addWidget(m_exportButton, 0);
}
connect(m_list, SIGNAL(actionSelected(QAction *)), m_sViewer,
@@ -408,6 +456,14 @@ ShortcutPopup::ShortcutPopup()
SLOT(setHidden(bool)));
connect(searchEdit, SIGNAL(textChanged(const QString &)), this,
SLOT(onSearchTextChanged(const QString &)));
+ connect(m_presetChoiceCB, SIGNAL(currentIndexChanged(int)),
+ SLOT(onPresetChanged(int)));
+ connect(m_exportButton, SIGNAL(clicked()), SLOT(onExportButton()));
+ connect(m_deletePresetButton, SIGNAL(clicked()), SLOT(onDeletePreset()));
+ connect(m_savePresetButton, SIGNAL(clicked()), SLOT(onSavePreset()));
+ connect(m_loadPresetButton, SIGNAL(clicked()), SLOT(onLoadPreset()));
+ connect(m_clearAllShortcutsButton, SIGNAL(clicked()),
+ SLOT(clearAllShortcuts()));
}
//-----------------------------------------------------------------------------
@@ -426,4 +482,324 @@ void ShortcutPopup::onSearchTextChanged(const QString &text) {
//-----------------------------------------------------------------------------
+void ShortcutPopup::onPresetChanged(int index) {
+ if (m_presetChoiceCB->currentText() == "Load from file...") {
+ importPreset();
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+void ShortcutPopup::clearAllShortcuts(bool warning) {
+ if (warning) {
+ QString question(tr("This will erase ALL shortcuts. Continue?"));
+ int ret =
+ DVGui::MsgBox(question, QObject::tr("OK"), QObject::tr("Cancel"), 0);
+ if (ret == 0 || ret == 2) {
+ // cancel (or closed message box window)
+ return;
+ }
+ showDialog("Clearing All Shortcuts");
+ }
+ for (int commandType = UndefinedCommandType; commandType <= MenuCommandType;
+ commandType++) {
+ std::vector actions;
+ CommandManager::instance()->getActions((CommandType)commandType, actions);
+ for (QAction *action : actions) {
+ qApp->processEvents();
+ m_sViewer->setAction(action);
+ m_sViewer->removeShortcut();
+ }
+ }
+ setCurrentPresetPref("DELETED");
+ // if warning is true, this was called directly- need to hide the dialog after
+ if (warning) m_dialog->hide();
+}
+
+//-----------------------------------------------------------------------------
+
+void ShortcutPopup::setPresetShortcuts(TFilePath fp) {
+ QSettings preset(toQString(fp), QSettings::IniFormat);
+ preset.beginGroup("shortcuts");
+ QStringList allIds = preset.allKeys();
+ QAction *action;
+ for (QString id : allIds) {
+ QByteArray ba = id.toLatin1();
+ const char *charId = ba.data();
+ action = CommandManager::instance()->getAction((CommandId)charId);
+ CommandManager::instance()->setShortcut(
+ action, preset.value(id).toString().toStdString(), false);
+ }
+ preset.endGroup();
+ emit m_sViewer->shortcutChanged();
+ m_dialog->hide();
+ buildPresets();
+ setCurrentPresetPref(QString::fromStdString(fp.getName()));
+}
+
+//-----------------------------------------------------------------------------
+
+bool ShortcutPopup::showConfirmDialog() {
+ QString question(tr("This will overwrite all current shortcuts. Continue?"));
+ int ret =
+ DVGui::MsgBox(question, QObject::tr("OK"), QObject::tr("Cancel"), 0);
+ if (ret == 0 || ret == 2) {
+ // cancel (or closed message box window)
+ return false;
+ } else
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+
+bool ShortcutPopup::showOverwriteDialog(QString name) {
+ QString question(tr("A file named ") + name +
+ tr(" already exists. Do you want to replace it?"));
+ int ret = DVGui::MsgBox(question, QObject::tr("Yes"), QObject::tr("No"), 0);
+ if (ret == 0 || ret == 2) {
+ // cancel (or closed message box window)
+ return false;
+ } else
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+
+void ShortcutPopup::showDialog(QString text) {
+ if (m_dialog == NULL) {
+ m_dialogLabel = new QLabel("", this);
+ m_dialog = new DVGui::Dialog(this, false, false);
+ m_dialog->setWindowTitle(tr("OpenToonz - Setting Shortcuts"));
+ m_dialog->setModal(false);
+
+ m_dialog->setTopMargin(10);
+ m_dialog->setTopSpacing(10);
+ m_dialog->setLabelWidth(500);
+ m_dialog->beginVLayout();
+ m_dialog->addWidget(m_dialogLabel, false);
+ m_dialog->endVLayout();
+ }
+ m_dialogLabel->setText(text);
+ m_dialog->show();
+}
+
+//-----------------------------------------------------------------------------
+
+void ShortcutPopup::onExportButton(TFilePath fp) {
+ if (fp == TFilePath()) {
+ m_saveShortcutsPopup = new GenericSaveFilePopup("Save Current Shortcuts");
+ m_saveShortcutsPopup->addFilterType("ini");
+ fp = m_saveShortcutsPopup->getPath();
+ if (fp == TFilePath()) return;
+ }
+ showDialog("Saving Shortcuts");
+ QString shortcutString = "[shortcuts]\n";
+ for (int commandType = UndefinedCommandType; commandType <= MenuCommandType;
+ commandType++) {
+ std::vector actions;
+ CommandManager::instance()->getActions((CommandType)commandType, actions);
+ for (QAction *action : actions) {
+ qApp->processEvents();
+ std::string id = CommandManager::instance()->getIdFromAction(action);
+ std::string shortcut =
+ CommandManager::instance()->getShortcutFromAction(action);
+ if (shortcut != "") {
+ shortcutString = shortcutString + QString::fromStdString(id) + "=" +
+ QString::fromStdString(shortcut) + "\n";
+ }
+ }
+ }
+ QFile file(fp.getQString());
+ file.open(QIODevice::WriteOnly | QIODevice::Text);
+ QTextStream out(&file);
+ out << shortcutString;
+ file.close();
+ m_dialog->hide();
+}
+
+//-----------------------------------------------------------------------------
+
+void ShortcutPopup::onDeletePreset() {
+ // change this to 4 once RETAS shortcuts are updated
+ if (m_presetChoiceCB->currentIndex() <= 3) {
+ DVGui::MsgBox(DVGui::CRITICAL, tr("Included presets cannot be deleted."));
+ return;
+ }
+
+ QString question(tr("Are you sure you want to delete the preset: ") +
+ m_presetChoiceCB->currentText() + tr("?"));
+ int ret = DVGui::MsgBox(question, QObject::tr("Yes"), QObject::tr("No"), 0);
+ if (ret == 0 || ret == 2) {
+ // cancel (or closed message box window)
+ return;
+ }
+ TFilePath presetDir =
+ ToonzFolder::getMyModuleDir() + TFilePath("shortcutpresets");
+ QString presetName = m_presetChoiceCB->currentText();
+ if (TSystem::doesExistFileOrLevel(presetDir +
+ TFilePath(presetName + ".ini"))) {
+ TSystem::deleteFile(presetDir + TFilePath(presetName + ".ini"));
+ buildPresets();
+ m_presetChoiceCB->setCurrentIndex(0);
+ }
+ if (Preferences::instance()->getShortcutPreset() == presetName)
+ setCurrentPresetPref("DELETED");
+ getCurrentPresetPref();
+}
+
+//-----------------------------------------------------------------------------
+
+void ShortcutPopup::importPreset() {
+ m_loadShortcutsPopup = new GenericLoadFilePopup("Load Shortcuts File");
+ m_loadShortcutsPopup->addFilterType("ini");
+ TFilePath shortcutPath = m_loadShortcutsPopup->getPath();
+ if (shortcutPath == TFilePath()) {
+ m_presetChoiceCB->setCurrentIndex(0);
+ return;
+ }
+ if (!showConfirmDialog()) return;
+
+ TFilePath presetDir =
+ ToonzFolder::getMyModuleDir() + TFilePath("shortcutpresets");
+ if (!TSystem::doesExistFileOrLevel(presetDir)) {
+ TSystem::mkDir(presetDir);
+ }
+ QString name = shortcutPath.withoutParentDir().getQString();
+ std::string strName = name.toStdString();
+ if (TSystem::doesExistFileOrLevel(presetDir + TFilePath(name))) {
+ if (!showOverwriteDialog(name)) return;
+ }
+ showDialog("Importing Shortcuts");
+ TSystem::copyFile(presetDir + TFilePath(name), shortcutPath, true);
+ clearAllShortcuts(false);
+ setPresetShortcuts(presetDir + TFilePath(name));
+ return;
+}
+
+//-----------------------------------------------------------------------------
+
+void ShortcutPopup::onLoadPreset() {
+ QString preset = m_presetChoiceCB->currentText();
+ TFilePath presetDir =
+ ToonzFolder::getMyModuleDir() + TFilePath("shortcutpresets");
+ TFilePath defaultPresetDir =
+ ToonzFolder::getProfileFolder() + TFilePath("layouts/shortcuts");
+ if (preset == "") return;
+ if (preset == "Load from file...") {
+ importPreset();
+ return;
+ }
+
+ if (!showConfirmDialog()) return;
+ showDialog("Setting Shortcuts");
+ if (preset == "OpenToonz") {
+ clearAllShortcuts(false);
+ TFilePath fp = defaultPresetDir + TFilePath("defopentoonz.ini");
+ setPresetShortcuts(fp);
+ return;
+ } else if (preset == "Toon Boom Harmony") {
+ clearAllShortcuts(false);
+ TFilePath fp = defaultPresetDir + TFilePath("otharmony.ini");
+ setPresetShortcuts(fp);
+ return;
+ } else if (preset == "Adobe Animate(Flash)") {
+ clearAllShortcuts(false);
+ TFilePath fp = defaultPresetDir + TFilePath("otadobe.ini");
+ setPresetShortcuts(fp);
+ return;
+ } else if (preset == "RETAS PaintMan") {
+ clearAllShortcuts(false);
+ TFilePath fp = defaultPresetDir + TFilePath("otretas.ini");
+ setPresetShortcuts(fp);
+ return;
+ } else if (TSystem::doesExistFileOrLevel(presetDir +
+ TFilePath(preset + ".ini"))) {
+ clearAllShortcuts(false);
+ TFilePath fp = presetDir + TFilePath(preset + ".ini");
+ setPresetShortcuts(fp);
+ return;
+ }
+ m_dialog->hide();
+}
+
+//-----------------------------------------------------------------------------
+
+QStringList ShortcutPopup::buildPresets() {
+ QStringList presets;
+ presets << ""
+ << "OpenToonz"
+ //<< "RETAS PaintMan"
+ << "Toon Boom Harmony"
+ << "Adobe Animate(Flash)";
+ TFilePath presetDir =
+ ToonzFolder::getMyModuleDir() + TFilePath("shortcutpresets");
+ if (TSystem::doesExistFileOrLevel(presetDir)) {
+ TFilePathSet fps = TSystem::readDirectory(presetDir, true, true, false);
+ QStringList customPresets;
+ for (TFilePath fp : fps) {
+ if (fp.getType() == "ini") {
+ customPresets << QString::fromStdString(fp.getName());
+ std::string name = fp.getName();
+ }
+ }
+ customPresets.sort();
+ presets = presets + customPresets;
+ }
+ presets << tr("Load from file...");
+ m_presetChoiceCB->clear();
+ m_presetChoiceCB->addItems(presets);
+ return presets;
+}
+
+//-----------------------------------------------------------------------------
+
+void ShortcutPopup::onSavePreset() {
+ QString presetName = DVGui::getText("Enter Preset Name", "Preset Name:", "");
+ if (presetName == "") return;
+ TFilePath presetDir =
+ ToonzFolder::getMyModuleDir() + TFilePath("shortcutpresets");
+ if (!TSystem::doesExistFileOrLevel(presetDir)) {
+ TSystem::mkDir(presetDir);
+ }
+ TFilePath fp;
+ fp = presetDir + TFilePath(presetName + ".ini");
+ if (TSystem::doesExistFileOrLevel(fp)) {
+ if (!showOverwriteDialog(QString::fromStdString(fp.getName()))) return;
+ }
+ onExportButton(fp);
+
+ buildPresets();
+ setCurrentPresetPref(presetName);
+}
+
+//-----------------------------------------------------------------------------
+
+void ShortcutPopup::showEvent(QShowEvent *se) { getCurrentPresetPref(); }
+
+//-----------------------------------------------------------------------------
+
+void ShortcutPopup::setCurrentPresetPref(QString name) {
+ Preferences::instance()->setShortcutPreset(name.toStdString());
+ getCurrentPresetPref();
+}
+
+//-----------------------------------------------------------------------------
+
+void ShortcutPopup::getCurrentPresetPref() {
+ QString name = Preferences::instance()->getShortcutPreset();
+ if (name == "DELETED")
+ m_presetChoiceCB->setCurrentText("");
+ else if (name == "defopentoonz")
+ m_presetChoiceCB->setCurrentText("OpenToonz");
+ else if (name == "otharmony")
+ m_presetChoiceCB->setCurrentText("Toon Boom Harmony");
+ else if (name == "otadobe")
+ m_presetChoiceCB->setCurrentText("Adobe Animate(Flash)");
+ else if (name == "otretas")
+ m_presetChoiceCB->setCurrentText("RETAS PaintMan");
+
+ else
+ m_presetChoiceCB->setCurrentText(name);
+}
+
OpenPopupCommandHandler openShortcutPopup(MI_ShortcutPopup);
diff --git a/toonz/sources/toonz/shortcutpopup.h b/toonz/sources/toonz/shortcutpopup.h
index 2044ac6..142d04f 100644
--- a/toonz/sources/toonz/shortcutpopup.h
+++ b/toonz/sources/toonz/shortcutpopup.h
@@ -5,7 +5,8 @@
#include
#include
-
+#include
+#include "filebrowserpopup.h"
#include "toonzqt/dvdialog.h"
// forward declaration
@@ -92,13 +93,40 @@ class ShortcutPopup final : public DVGui::Dialog {
QPushButton *m_removeBtn;
ShortcutViewer *m_sViewer;
ShortcutTree *m_list;
+ QComboBox *m_presetChoiceCB;
+ DVGui::Dialog *m_dialog;
+ GenericLoadFilePopup *m_loadShortcutsPopup;
+ GenericSaveFilePopup *m_saveShortcutsPopup;
+ QPushButton *m_exportButton;
+ QPushButton *m_deletePresetButton;
+ QPushButton *m_savePresetButton;
+ QPushButton *m_loadPresetButton;
+ QPushButton *m_clearAllShortcutsButton;
+ QLabel *m_dialogLabel;
public:
ShortcutPopup();
~ShortcutPopup();
+private:
+ void setPresetShortcuts(TFilePath fp);
+ void showDialog(QString text);
+ bool showConfirmDialog();
+ bool showOverwriteDialog(QString name);
+ void importPreset();
+ QStringList buildPresets();
+ void showEvent(QShowEvent *se) override;
+ void setCurrentPresetPref(QString preset);
+ void getCurrentPresetPref();
+
protected slots:
+ void clearAllShortcuts(bool warning = true);
void onSearchTextChanged(const QString &text);
+ void onPresetChanged(int index);
+ void onExportButton(TFilePath fp = TFilePath());
+ void onDeletePreset();
+ void onSavePreset();
+ void onLoadPreset();
};
#endif // SHORTCUTPOPUP_H
diff --git a/toonz/sources/toonz/startuppopup.cpp b/toonz/sources/toonz/startuppopup.cpp
new file mode 100644
index 0000000..bf8c375
--- /dev/null
+++ b/toonz/sources/toonz/startuppopup.cpp
@@ -0,0 +1,917 @@
+
+
+#include "startuppopup.h"
+
+// Tnz6 includes
+#include "mainwindow.h"
+#include "tapp.h"
+#include "iocommand.h"
+#include "toutputproperties.h"
+#include "toonzqt/flipconsole.h"
+#include "menubarcommandids.h"
+#include "tenv.h"
+#include "toonz/stage.h"
+
+// TnzQt includes
+#include "toonzqt/menubarcommand.h"
+#include "toonzqt/gutil.h"
+#include "toonzqt/doublefield.h"
+
+// TnzLib includes
+#include "toonz/toonzscene.h"
+#include "toonz/txsheet.h"
+#include "toonz/levelproperties.h"
+#include "toonz/sceneproperties.h"
+#include "toonz/tcamera.h"
+#include "toonz/tscenehandle.h"
+#include "toonz/txsheethandle.h"
+#include "toonz/preferences.h"
+#include "toonz/tproject.h"
+
+// TnzCore includes
+#include "tsystem.h"
+#include "filebrowsermodel.h"
+
+// Qt includes
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace std;
+using namespace DVGui;
+
+namespace {
+
+// the first value in the preset list
+const QString custom = QObject::tr("");
+
+QString removeZeros(QString srcStr) {
+ if (!srcStr.contains('.')) return srcStr;
+
+ for (int i = srcStr.length() - 1; i >= 0; i--) {
+ if (srcStr.at(i) == '0')
+ srcStr.chop(1);
+ else if (srcStr.at(i) == '.') {
+ srcStr.chop(1);
+ break;
+ } else
+ break;
+ }
+ return srcStr;
+}
+} // namespace
+
+//=============================================================================
+/*! \class StartupPopup
+ \brief The StartupPopup class provides a modal dialog to
+ bring up recent files or create a new scene.
+
+ Inherits \b Dialog.
+*/
+//-----------------------------------------------------------------------------
+
+StartupPopup::StartupPopup()
+ : Dialog(TApp::instance()->getMainWindow(), true, true, "StartupPopup") {
+ setWindowTitle(tr("OpenToonz Startup"));
+
+ m_projectBox = new QGroupBox(tr("Choose Project"), this);
+ m_sceneBox = new QGroupBox(tr("Create a New Scene"), this);
+ m_recentBox = new QGroupBox(tr("Open Scene"), this);
+ m_projectBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ m_nameFld = new LineEdit(this);
+ m_pathFld = new FileField(this);
+ m_sceneNameLabel = new QLabel(tr("Scene Name:"));
+ m_widthLabel = new QLabel(tr("Width:"), this);
+ m_widthFld = new MeasuredDoubleLineEdit(this);
+ m_heightLabel = new QLabel(tr("Height:"), this);
+ m_heightFld = new MeasuredDoubleLineEdit(this);
+ m_dpiLabel = new QLabel(tr("DPI:"), this);
+ m_dpiFld = new DoubleLineEdit(this, 120);
+ m_resXLabel = new QLabel(tr("X"), this);
+ m_resXFld = new DoubleLineEdit(this);
+ m_resYFld = new DoubleLineEdit(this);
+ m_resTextLabel = new QLabel(tr("Resolution:"), this);
+ m_fpsLabel = new QLabel(tr("Frame Rate:"), this);
+ m_fpsFld = new DoubleLineEdit(this, 24.0);
+ m_cameraSettingsWidget = new CameraSettingsWidget(false);
+ m_presetCombo = new QComboBox(this);
+ m_unitsCB = new QComboBox(this);
+ m_addPresetBtn = new QPushButton(tr("Add"), this);
+ m_removePresetBtn = new QPushButton(tr("Remove"), this);
+ m_showAtStartCB = new QCheckBox(tr("Show this at startup"), this);
+ QPushButton *createButton = new QPushButton(tr("Create Scene"), this);
+ QPushButton *newProjectButton = new QPushButton(tr("New Project..."), this);
+ QPushButton *loadOtherSceneButton =
+ new QPushButton(tr("Open Another Scene..."), this);
+ m_projectsCB = new QComboBox(this);
+ QStringList type;
+ type << tr("pixel") << tr("cm") << tr("mm") << tr("inch") << tr("field");
+ m_unitsCB->addItems(type);
+
+ // Exclude all character which cannot fit in a filepath (Win).
+ // Dots are also prohibited since they are internally managed by Toonz.
+ QRegExp rx("[^\\\\/:?*.\"<>|]+");
+ m_nameFld->setValidator(new QRegExpValidator(rx, this));
+
+ m_widthFld->setMeasure("camera.lx");
+ m_heightFld->setMeasure("camera.ly");
+
+ m_widthFld->setRange(0.1, (std::numeric_limits::max)());
+ m_heightFld->setRange(0.1, (std::numeric_limits::max)());
+ m_fpsFld->setRange(1.0, (std::numeric_limits::max)());
+ m_dpiFld->setRange(1.0, (std::numeric_limits::max)());
+ m_resXFld->setRange(0.1, (std::numeric_limits::max)());
+ m_resYFld->setRange(0.1, (std::numeric_limits::max)());
+ m_showAtStartCB->setChecked(Preferences::instance()->isStartupPopupEnabled());
+ m_showAtStartCB->setStyleSheet("QCheckBox{ background-color: none; }");
+ m_addPresetBtn->setStyleSheet(
+ "QPushButton { padding-left: 4px; padding-right: 4px;}");
+ m_removePresetBtn->setStyleSheet(
+ "QPushButton { padding-left: 4px; padding-right: 4px;}");
+ QLabel *label = new QLabel();
+ label->setPixmap(QPixmap(":Resources/startup.png"));
+ m_projectBox->setObjectName("SolidLineFrame");
+ m_sceneBox->setObjectName("SolidLineFrame");
+ m_recentBox->setObjectName("SolidLineFrame");
+ m_projectBox->setContentsMargins(10, 10, 10, 10);
+ m_sceneBox->setContentsMargins(10, 10, 10, 10);
+ m_recentBox->setContentsMargins(10, 10, 10, 10);
+ m_recentBox->setFixedWidth(200);
+ m_sceneBox->setMinimumWidth(480);
+ m_projectBox->setMinimumWidth(480);
+ m_buttonFrame->setFixedHeight(30);
+ //--- layout
+ m_topLayout->setMargin(0);
+ m_topLayout->setSpacing(0);
+ {
+ QGridLayout *guiLay = new QGridLayout();
+ QHBoxLayout *projectLay = new QHBoxLayout();
+ QGridLayout *newSceneLay = new QGridLayout();
+ m_recentSceneLay = new QVBoxLayout();
+ guiLay->setMargin(10);
+ guiLay->setVerticalSpacing(10);
+ guiLay->setHorizontalSpacing(10);
+
+ guiLay->addWidget(label, 0, 0, 1, 2, Qt::AlignLeft);
+
+ projectLay->setSpacing(8);
+ projectLay->setMargin(8);
+ {
+ projectLay->addWidget(m_projectsCB, 1);
+ projectLay->addWidget(newProjectButton, 0);
+ }
+ m_projectBox->setLayout(projectLay);
+ guiLay->addWidget(m_projectBox, 1, 0, 1, 1, Qt::AlignCenter);
+
+ newSceneLay->setMargin(8);
+ newSceneLay->setVerticalSpacing(8);
+ newSceneLay->setHorizontalSpacing(8);
+ {
+ // Scene Name
+ newSceneLay->addWidget(m_sceneNameLabel, 0, 0,
+ Qt::AlignRight | Qt::AlignVCenter);
+ newSceneLay->addWidget(m_nameFld, 0, 1, 1, 3);
+
+ // Save In
+ newSceneLay->addWidget(new QLabel(tr("Save In:")), 1, 0,
+ Qt::AlignRight | Qt::AlignVCenter);
+ newSceneLay->addWidget(m_pathFld, 1, 1, 1, 3);
+ newSceneLay->addWidget(new QLabel(tr("Camera Size:")), 2, 0,
+ Qt::AlignRight | Qt::AlignVCenter);
+ QHBoxLayout *resListLay = new QHBoxLayout();
+ resListLay->setSpacing(3);
+ resListLay->setMargin(1);
+ {
+ resListLay->addWidget(m_presetCombo, 1);
+ resListLay->addWidget(m_addPresetBtn, 0);
+ resListLay->addWidget(m_removePresetBtn, 0);
+ }
+ newSceneLay->addLayout(resListLay, 2, 1, 1, 3, Qt::AlignLeft);
+
+ // Width - Height
+ newSceneLay->addWidget(m_widthLabel, 3, 0,
+ Qt::AlignRight | Qt::AlignVCenter);
+ newSceneLay->addWidget(m_widthFld, 3, 1);
+ newSceneLay->addWidget(m_heightLabel, 3, 2,
+ Qt::AlignRight | Qt::AlignVCenter);
+ newSceneLay->addWidget(m_heightFld, 3, 3);
+
+ newSceneLay->addWidget(m_resTextLabel, 4, 0, 1, 1, Qt::AlignRight);
+ newSceneLay->addWidget(m_resXFld, 4, 1);
+ newSceneLay->addWidget(m_resXLabel, 4, 2, 1, 1, Qt::AlignCenter);
+ newSceneLay->addWidget(m_resYFld, 4, 3);
+ newSceneLay->addWidget(new QLabel(tr("Units:")), 5, 0,
+ Qt::AlignRight | Qt::AlignVCenter);
+ newSceneLay->addWidget(m_unitsCB, 5, 1, 1, 1);
+ newSceneLay->addWidget(m_dpiLabel, 5, 2,
+ Qt::AlignRight | Qt::AlignVCenter);
+ newSceneLay->addWidget(m_dpiFld, 5, 3, 1, 1);
+ newSceneLay->addWidget(m_fpsLabel, 6, 0,
+ Qt::AlignRight | Qt::AlignVCenter);
+ newSceneLay->addWidget(m_fpsFld, 6, 1, 1, 1);
+ newSceneLay->addWidget(createButton, 7, 1, 1, 3, Qt::AlignLeft);
+ }
+ m_sceneBox->setLayout(newSceneLay);
+ guiLay->addWidget(m_sceneBox, 2, 0, 4, 1, Qt::AlignLeft);
+
+ m_recentSceneLay->setMargin(5);
+ m_recentSceneLay->setSpacing(2);
+ {
+ // Recent Scene List
+ m_recentBox->setLayout(m_recentSceneLay);
+ guiLay->addWidget(m_recentBox, 1, 1, 4, 1, Qt::AlignTop);
+ guiLay->addWidget(loadOtherSceneButton, 5, 1, 1, 1, Qt::AlignRight);
+ }
+ m_topLayout->addLayout(guiLay, 0);
+ }
+
+ m_buttonLayout->setMargin(0);
+ m_buttonLayout->setSpacing(10);
+ { m_buttonLayout->addWidget(m_showAtStartCB, Qt::AlignLeft); }
+
+ TApp *app = TApp::instance();
+ TSceneHandle *sceneHandle = app->getCurrentScene();
+
+ //---- signal-slot connections
+ bool ret = true;
+ ret = ret && connect(sceneHandle, SIGNAL(sceneChanged()), this,
+ SLOT(onSceneChanged()));
+ ret = ret && connect(sceneHandle, SIGNAL(sceneSwitched()), this,
+ SLOT(onSceneChanged()));
+ ret = ret && connect(newProjectButton, SIGNAL(clicked()), this,
+ SLOT(onNewProjectButtonPressed()));
+ ret = ret && connect(loadOtherSceneButton, SIGNAL(clicked()), this,
+ SLOT(onLoadSceneButtonPressed()));
+ ret = ret && connect(m_projectsCB, SIGNAL(currentIndexChanged(int)),
+ SLOT(onProjectChanged(int)));
+ ret = ret &&
+ connect(createButton, SIGNAL(clicked()), this, SLOT(onCreateButton()));
+ ret = ret && connect(m_showAtStartCB, SIGNAL(stateChanged(int)), this,
+ SLOT(onShowAtStartChanged(int)));
+ ret = ret && connect(m_widthFld, SIGNAL(valueChanged()), this,
+ SLOT(updateResolution()));
+ ret = ret && connect(m_heightFld, SIGNAL(valueChanged()), this,
+ SLOT(updateResolution()));
+ ret = ret &&
+ connect(m_resXFld, SIGNAL(valueChanged()), this, SLOT(updateSize()));
+ ret = ret &&
+ connect(m_resYFld, SIGNAL(valueChanged()), this, SLOT(updateSize()));
+ ret = ret && connect(m_dpiFld, SIGNAL(editingFinished()), this,
+ SLOT(onDpiChanged()));
+ ret = ret && connect(m_presetCombo, SIGNAL(activated(const QString &)),
+ SLOT(onPresetSelected(const QString &)));
+ ret = ret && connect(m_addPresetBtn, SIGNAL(clicked()), SLOT(addPreset()));
+ ret = ret && connect(m_unitsCB, SIGNAL(currentIndexChanged(int)),
+ SLOT(onCameraUnitChanged(int)));
+ ret = ret &&
+ connect(m_removePresetBtn, SIGNAL(clicked()), SLOT(removePreset()));
+ ret = ret && connect(m_nameFld, SIGNAL(returnPressedNow()), createButton,
+ SLOT(animateClick()));
+ assert(ret);
+}
+
+//-----------------------------------------------------------------------------
+
+void StartupPopup::showEvent(QShowEvent *) {
+ loadPresetList();
+ updateProjectCB();
+ m_nameFld->setFocus();
+ m_pathFld->setPath(TApp::instance()
+ ->getCurrentScene()
+ ->getScene()
+ ->getProject()
+ ->getScenesPath()
+ .getQString());
+ TDimensionD cameraSize = TApp::instance()
+ ->getCurrentScene()
+ ->getScene()
+ ->getCurrentCamera()
+ ->getSize();
+ TDimension cameraRes = TApp::instance()
+ ->getCurrentScene()
+ ->getScene()
+ ->getCurrentCamera()
+ ->getRes();
+ double fps = TApp::instance()
+ ->getCurrentScene()
+ ->getScene()
+ ->getProperties()
+ ->getOutputProperties()
+ ->getFrameRate();
+ m_widthFld->setValue(cameraSize.lx);
+ m_heightFld->setValue(cameraSize.ly);
+ if (Preferences::instance()->getCameraUnits() == "pixel") {
+ m_widthFld->setDecimals(0);
+ m_heightFld->setDecimals(0);
+ m_resTextLabel->hide();
+ m_resXFld->hide();
+ m_resYFld->hide();
+ m_resXLabel->hide();
+ m_dpiFld->hide();
+ m_dpiLabel->hide();
+ } else {
+ m_widthFld->setDecimals(4);
+ m_heightFld->setDecimals(4);
+ m_resXFld->show();
+ m_resYFld->show();
+ m_resXLabel->show();
+ m_resTextLabel->show();
+ m_dpiFld->show();
+ m_dpiLabel->show();
+ }
+
+ m_fpsFld->setValue(fps);
+ m_unitsCB->setCurrentText(Preferences::instance()->getCameraUnits());
+ m_dpi = cameraRes.lx / cameraSize.lx;
+ m_xRes = cameraRes.lx;
+ m_yRes = cameraRes.ly;
+ m_resXFld->setValue(m_xRes);
+ m_resYFld->setValue(m_yRes);
+ m_resXFld->setDecimals(0);
+ m_resYFld->setDecimals(0);
+ m_dpiFld->setValue(m_dpi);
+
+ int boxWidth = m_sceneBox->width();
+ int boxHeight = m_sceneBox->height();
+ m_sceneBox->setFixedWidth(boxWidth);
+ m_projectBox->setFixedWidth(boxWidth);
+ m_recentBox->setMinimumHeight(boxHeight);
+
+ // update recent scenes
+ // clear items if they exist first
+
+ if (m_recentSceneLay->count() > 0) {
+ QLayoutItem *child;
+ while (m_recentSceneLay->count() != 0) {
+ child = m_recentSceneLay->takeAt(0);
+ delete child;
+ }
+ }
+
+ m_sceneNames = RecentFiles::instance()->getFilesNameList(RecentFiles::Scene);
+ m_recentNamesLabels = QVector(m_sceneNames.count());
+
+ if (m_sceneNames.count() <= 0) {
+ m_recentSceneLay->addWidget(new QLabel(tr("No Recent Scenes"), this), 1,
+ Qt::AlignTop);
+ } else {
+ int i = 0;
+ for (QString name : m_sceneNames) {
+ if (i > 9) break; // box can hold 10 scenes
+ QString justName = QString::fromStdString(TFilePath(name).getName());
+ m_recentNamesLabels[i] = new StartupLabel(justName, this, i);
+ m_recentNamesLabels[i]->setToolTip(
+ name.remove(0, name.indexOf(" ") + 1)); // remove "#. " prefix
+ m_recentSceneLay->addWidget(m_recentNamesLabels[i], i, Qt::AlignTop);
+ i++;
+ }
+ m_recentSceneLay->addStretch(100);
+ }
+
+ bool ret = true;
+ for (int i = 0; i < m_recentNamesLabels.count() && i < 7; i++) {
+ ret = ret && connect(m_recentNamesLabels[i], SIGNAL(wasClicked(int)), this,
+ SLOT(onRecentSceneClicked(int)));
+ }
+ assert(ret);
+ // center window
+ this->move(QApplication::desktop()->screen()->rect().center() -
+ this->rect().center());
+}
+
+//-----------------------------------------------------------------------------
+
+void StartupPopup::onCreateButton() {
+ if (m_nameFld->text().trimmed() == "") {
+ DVGui::warning(tr("The name cannot be empty."));
+ m_nameFld->setFocus();
+ return;
+ }
+ if (!TSystem::doesExistFileOrLevel(TFilePath(m_pathFld->getPath()))) {
+ DVGui::warning(tr("The chosen file path is not valid."));
+ m_pathFld->setFocus();
+ return;
+ }
+
+ if (m_widthFld->getValue() < 1) {
+ DVGui::warning(tr("The width must be 1 or more."));
+ m_widthFld->setFocus();
+ return;
+ }
+ if (m_heightFld->getValue() < 1) {
+ DVGui::warning(tr("The height must be 1 or more."));
+ m_heightFld->setFocus();
+ return;
+ }
+ if (m_fpsFld->getValue() < 1) {
+ DVGui::warning(tr("The frame rate must be 1 or more."));
+ m_fpsFld->setFocus();
+ return;
+ }
+ if (TSystem::doesExistFileOrLevel(
+ TFilePath(m_pathFld->getPath()) +
+ TFilePath(m_nameFld->text().trimmed().toStdWString() + L".tnz"))) {
+ QString question;
+ question = QObject::tr(
+ "The file name already exists."
+ "\nDo you want to overwrite it?");
+ int ret = DVGui::MsgBox(question, QObject::tr("Yes"), QObject::tr("No"), 0);
+ if (ret == 0 || ret == 2) {
+ // no (or closed message box window)
+ return;
+ ;
+ }
+ }
+ CommandManager::instance()->execute(MI_NewScene);
+ TApp::instance()->getCurrentScene()->getScene()->setScenePath(
+ TFilePath(m_pathFld->getPath()) +
+ TFilePath(m_nameFld->text().trimmed().toStdWString()));
+ TDimensionD size =
+ TDimensionD(m_widthFld->getValue(), m_heightFld->getValue());
+ TDimension res = TDimension(m_xRes, m_yRes);
+ double fps = m_fpsFld->getValue();
+ TApp::instance()
+ ->getCurrentScene()
+ ->getScene()
+ ->getProperties()
+ ->getOutputProperties()
+ ->setFrameRate(fps);
+ TApp::instance()->getCurrentScene()->getScene()->getCurrentCamera()->setSize(
+ size);
+ TApp::instance()->getCurrentScene()->getScene()->getCurrentCamera()->setRes(
+ res);
+ // this one is debatable - should the scene be saved right away?
+ // IoCmd::saveScene();
+ // this makes sure the scene viewers update to the right fps
+ TApp::instance()->getCurrentScene()->notifySceneSwitched();
+
+ hide();
+}
+
+//-----------------------------------------------------------------------------
+
+void StartupPopup::updateProjectCB() {
+ m_updating = true;
+ m_projectPaths.clear();
+ m_projectsCB->clear();
+
+ TFilePath sandboxFp = TProjectManager::instance()->getSandboxProjectFolder() +
+ "sandbox_otprj.xml";
+ m_projectPaths.push_back(sandboxFp);
+ m_projectsCB->addItem("sandbox");
+
+ std::vector prjRoots;
+ TProjectManager::instance()->getProjectRoots(prjRoots);
+ for (int i = 0; i < prjRoots.size(); i++) {
+ TFilePathSet fps;
+ TSystem::readDirectory_Dir_ReadExe(fps, prjRoots[i]);
+
+ TFilePathSet::iterator it;
+ for (it = fps.begin(); it != fps.end(); ++it) {
+ TFilePath fp(*it);
+ if (TProjectManager::instance()->isProject(fp)) {
+ m_projectPaths.push_back(
+ TProjectManager::instance()->projectFolderToProjectPath(fp));
+ m_projectsCB->addItem(QString::fromStdString(fp.getName()));
+ }
+ }
+ }
+ int i;
+ for (i = 0; i < m_projectPaths.size(); i++) {
+ if (TProjectManager::instance()->getCurrentProjectPath() ==
+ m_projectPaths[i]) {
+ m_projectsCB->setCurrentIndex(i);
+ break;
+ }
+ }
+ m_pathFld->setPath(TApp::instance()
+ ->getCurrentScene()
+ ->getScene()
+ ->getProject()
+ ->getScenesPath()
+ .getQString());
+ m_updating = false;
+}
+
+//-----------------------------------------------------------------------------
+
+void StartupPopup::onProjectChanged(int index) {
+ if (m_updating) return;
+ TFilePath projectFp = m_projectPaths[index];
+
+ TProjectManager::instance()->setCurrentProjectPath(projectFp);
+
+ IoCmd::newScene();
+ m_pathFld->setPath(TApp::instance()
+ ->getCurrentScene()
+ ->getScene()
+ ->getProject()
+ ->getScenesPath()
+ .getQString());
+ m_fpsFld->setValue(TApp::instance()
+ ->getCurrentScene()
+ ->getScene()
+ ->getProperties()
+ ->getOutputProperties()
+ ->getFrameRate());
+ TDimension res = TApp::instance()
+ ->getCurrentScene()
+ ->getScene()
+ ->getCurrentCamera()
+ ->getRes();
+ m_xRes = res.lx;
+ m_yRes = res.ly;
+ m_resXFld->setValue(m_xRes);
+ m_resYFld->setValue(m_yRes);
+ TDimensionD size = TApp::instance()
+ ->getCurrentScene()
+ ->getScene()
+ ->getCurrentCamera()
+ ->getSize();
+ m_widthFld->setValue(size.lx);
+ m_heightFld->setValue(size.ly);
+ m_dpi = m_xRes / size.lx;
+ m_dpiFld->setValue(m_dpi);
+}
+
+//-----------------------------------------------------------------------------
+
+void StartupPopup::loadPresetList() {
+ m_presetCombo->clear();
+ m_presetCombo->addItem("...");
+ m_presetListFile = ToonzFolder::getReslistPath(false).getQString();
+ QFile file(m_presetListFile);
+ if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ QTextStream in(&file);
+ while (!in.atEnd()) {
+ QString line = in.readLine().trimmed();
+ if (line != "") m_presetCombo->addItem(line);
+ }
+ }
+ m_presetCombo->setCurrentIndex(0);
+}
+
+//-----------------------------------------------------------------------------
+
+void StartupPopup::savePresetList() {
+ QFile file(m_presetListFile);
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) return;
+ QTextStream out(&file);
+ int n = m_presetCombo->count();
+ for (int i = 1; i < n; i++) out << m_presetCombo->itemText(i) << "\n";
+}
+
+//-----------------------------------------------------------------------------
+
+void StartupPopup::addPreset() {
+ int xRes = (int)(m_widthFld->getValue() * m_dpi);
+ int yRes = (int)(m_heightFld->getValue() * m_dpi);
+ double lx = m_widthFld->getValue();
+ double ly = m_heightFld->getValue();
+ double ar = m_widthFld->getValue() / m_heightFld->getValue();
+
+ QString presetString;
+ presetString = QString::number(xRes) + "x" + QString::number(yRes) + ", " +
+ removeZeros(QString::number(lx)) + "x" +
+ removeZeros(QString::number(ly)) + ", " +
+ aspectRatioValueToString(ar);
+
+ bool ok;
+ QString qs;
+ while (1) {
+ qs = DVGui::getText(tr("Preset name"),
+ tr("Enter the name for %1").arg(presetString), "", &ok);
+
+ if (!ok) return;
+
+ if (qs.indexOf(",") != -1)
+ QMessageBox::warning(this, tr("Error : Preset Name is Invalid"),
+ tr("The preset name must not use ','(comma)."));
+ else
+ break;
+ }
+
+ int oldn = m_presetCombo->count();
+ m_presetCombo->addItem(qs + "," + presetString);
+ int newn = m_presetCombo->count();
+ m_presetCombo->blockSignals(true);
+ m_presetCombo->setCurrentIndex(m_presetCombo->count() - 1);
+ m_presetCombo->blockSignals(false);
+
+ savePresetList();
+}
+
+//-----------------------------------------------------------------------------
+
+void StartupPopup::removePreset() {
+ int index = m_presetCombo->currentIndex();
+ if (index <= 0) return;
+
+ // confirmation dialog
+ int ret = DVGui::MsgBox(QObject::tr("Deleting \"%1\".\nAre you sure?")
+ .arg(m_presetCombo->currentText()),
+ QObject::tr("Delete"), QObject::tr("Cancel"));
+ if (ret == 0 || ret == 2) return;
+
+ m_presetCombo->removeItem(index);
+ m_presetCombo->setCurrentIndex(0);
+ savePresetList();
+}
+
+//-----------------------------------------------------------------------------
+
+void StartupPopup::onPresetSelected(const QString &str) {
+ if (str == custom || str.isEmpty()) return;
+ QString name, arStr;
+ int xres = 0, yres = 0;
+ double fx = -1.0, fy = -1.0;
+ QString xoffset = "", yoffset = "";
+ double ar;
+
+ if (parsePresetString(str, name, xres, yres, fx, fy, xoffset, yoffset, ar,
+ false)) {
+ m_xRes = xres;
+ m_yRes = yres;
+ // The current solution is to preserve the DPI so that scenes are less
+ // likely to become incompatible with pixels only mode in the future
+ // Commented below is the default behavior of the camera settings widget
+ // m_widthFld->setValue(m_heightFld->getValue() * ar);
+ // m_dpiFld->setValue(m_xRes / m_widthFld->getValue());
+
+ // here is the system that preserves dpi
+ m_widthFld->setValue((double)xres / (double)m_dpi);
+ m_heightFld->setValue((double)yres / (double)m_dpi);
+ if (Preferences::instance()->getPixelsOnly()) {
+ m_widthFld->setValue((double)xres / Stage::standardDpi);
+ m_heightFld->setValue((double)yres / Stage::standardDpi);
+ m_dpiFld->setValue(Stage::standardDpi);
+ }
+ m_resXFld->setValue(m_xRes);
+ m_resYFld->setValue(m_yRes);
+ } else {
+ QMessageBox::warning(
+ this, tr("Bad camera preset"),
+ tr("'%1' doesn't seem to be a well formed camera preset. \n"
+ "Possibly the preset file has been corrupted")
+ .arg(str));
+ }
+}
+
+//--------------------------------------------------------------------------
+
+bool StartupPopup::parsePresetString(const QString &str, QString &name,
+ int &xres, int &yres, double &fx,
+ double &fy, QString &xoffset,
+ QString &yoffset, double &ar,
+ bool forCleanup) {
+ /*
+ parsing preset string with QString::split().
+ !NOTE! fx/fy (camera size in inch) and xoffset/yoffset (camera offset used in
+ cleanup camera) are optional,
+ in order to keep compatibility with default (Harlequin's) reslist.txt
+ */
+
+ QStringList tokens = str.split(",", QString::SkipEmptyParts);
+
+ if (!(tokens.count() == 3 ||
+ (!forCleanup && tokens.count() == 4) || /*- with "fx x fy" token -*/
+ (forCleanup &&
+ tokens.count() ==
+ 6))) /*- with "fx x fy", xoffset and yoffset tokens -*/
+ return false;
+ /*- name -*/
+ name = tokens[0];
+
+ /*- xres, yres (like: 1024x768) -*/
+ QStringList values = tokens[1].split("x");
+ if (values.count() != 2) return false;
+ bool ok;
+ xres = values[0].toInt(&ok);
+ if (!ok) return false;
+ yres = values[1].toInt(&ok);
+ if (!ok) return false;
+
+ if (tokens.count() >= 4) {
+ /*- fx, fy -*/
+ values = tokens[2].split("x");
+ if (values.count() != 2) return false;
+ fx = values[0].toDouble(&ok);
+ if (!ok) return false;
+ fy = values[1].toDouble(&ok);
+ if (!ok) return false;
+
+ /*- xoffset, yoffset -*/
+ if (forCleanup) {
+ xoffset = tokens[3];
+ yoffset = tokens[4];
+ /*- remove single space -*/
+ if (xoffset.startsWith(' ')) xoffset.remove(0, 1);
+ if (yoffset.startsWith(' ')) yoffset.remove(0, 1);
+ }
+ }
+
+ /*- AR -*/
+ ar = aspectRatioStringToValue(tokens.last());
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+
+double StartupPopup::aspectRatioStringToValue(const QString &s) {
+ if (s == "") {
+ return 1;
+ }
+ int i = s.indexOf("/");
+ if (i <= 0 || i + 1 >= s.length()) return s.toDouble();
+ int num = s.left(i).toInt();
+ int den = s.mid(i + 1).toInt();
+ if (den <= 0) den = 1;
+ return (double)num / (double)den;
+}
+
+//-----------------------------------------------------------------------------
+
+// A/R : value => string (e.g. '4/3' or '1.23')
+QString StartupPopup::aspectRatioValueToString(double value, int width,
+ int height) {
+ double v = value;
+
+ if (width != 0 && height != 0) {
+ if (areAlmostEqual(value, (double)width / (double)height, 1e-3))
+ return QString("%1/%2").arg(width).arg(height);
+ }
+
+ double iv = tround(v);
+ if (fabs(iv - v) > 0.01) {
+ for (int d = 2; d < 20; d++) {
+ int n = tround(v * d);
+ if (fabs(n - v * d) <= 0.01)
+ return QString::number(n) + "/" + QString::number(d);
+ }
+ return QString::number(value, 'f', 5);
+ } else {
+ return QString::number((int)iv);
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+void StartupPopup::onNewProjectButtonPressed() {
+ CommandManager::instance()->execute(MI_NewProject);
+}
+
+//-----------------------------------------------------------------------------
+
+void StartupPopup::onSceneChanged() {
+ // close the box if a recent scene has been selected
+ if (!TApp::instance()->getCurrentScene()->getScene()->isUntitled()) {
+ hide();
+ } else {
+ updateProjectCB();
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+void StartupPopup::onDpiChanged() {
+ if (Preferences::instance()->getPixelsOnly()) {
+ m_dpi = Stage::standardDpi;
+ m_dpiFld->setValue(Stage::standardDpi);
+ updateResolution();
+ } else {
+ m_dpi = m_dpiFld->getValue();
+ updateResolution();
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+void StartupPopup::onLoadSceneButtonPressed() {
+ CommandManager::instance()->execute(MI_LoadScene);
+}
+
+//-----------------------------------------------------------------------------
+
+void StartupPopup::onRecentSceneClicked(int index) {
+ if (index < 0) return;
+ QString path =
+ RecentFiles::instance()->getFilePath(index, RecentFiles::Scene);
+ IoCmd::loadScene(TFilePath(path.toStdWString()), false);
+ RecentFiles::instance()->moveFilePath(index, 0, RecentFiles::Scene);
+ RecentFiles::instance()->refreshRecentFilesMenu(RecentFiles::Scene);
+ hide();
+}
+
+//-----------------------------------------------------------------------------
+
+void StartupPopup::onCameraUnitChanged(int index) {
+ Preferences *pref = Preferences::instance();
+ QStringList type;
+ type << tr("pixel") << tr("cm") << tr("mm") << tr("inch") << tr("field");
+
+ double width = m_widthFld->getValue();
+ double height = m_heightFld->getValue();
+ if (index != 0) {
+ pref->setPixelsOnly(false);
+ pref->setCameraUnits(type[index].toStdString());
+ m_widthFld->setDecimals(4);
+ m_heightFld->setDecimals(4);
+ m_resTextLabel->show();
+ m_resXFld->show();
+ m_resYFld->show();
+ m_resXLabel->show();
+ m_dpiFld->show();
+ m_dpiLabel->show();
+ m_widthFld->setMeasure("camera.lx");
+ m_heightFld->setMeasure("camera.ly");
+ m_widthFld->setValue(width);
+ m_heightFld->setValue(height);
+ } else {
+ pref->setPixelsOnly(true);
+ pref->setUnits("pixel");
+ pref->setCameraUnits("pixel");
+ m_widthFld->setDecimals(0);
+ m_heightFld->setDecimals(0);
+ m_resTextLabel->hide();
+ m_resXFld->hide();
+ m_resYFld->hide();
+ m_resXLabel->hide();
+ m_dpiFld->hide();
+ m_dpiLabel->hide();
+ m_dpiFld->setValue(Stage::standardDpi);
+ m_widthFld->setMeasure("camera.lx");
+ m_heightFld->setMeasure("camera.ly");
+ m_widthFld->setValue(m_xRes / Stage::standardDpi);
+ m_heightFld->setValue(m_yRes / Stage::standardDpi);
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+void StartupPopup::onShowAtStartChanged(int index) {
+ Preferences::instance()->enableStartupPopup(index);
+}
+
+//-----------------------------------------------------------------------------
+
+void StartupPopup::updateResolution() {
+ if (Preferences::instance()->getPixelsOnly()) {
+ if (m_dpiFld->getValue() != Stage::standardDpi) {
+ m_dpiFld->setValue(Stage::standardDpi);
+ }
+ m_xRes = m_widthFld->getValue() * Stage::standardDpi;
+ m_yRes = m_heightFld->getValue() * Stage::standardDpi;
+ m_resXFld->setValue(m_xRes);
+ m_resYFld->setValue(m_yRes);
+ } else {
+ m_xRes = m_widthFld->getValue() * m_dpi;
+ m_yRes = m_heightFld->getValue() * m_dpi;
+ m_resXFld->setValue(m_xRes);
+ m_resYFld->setValue(m_yRes);
+ }
+ m_presetCombo->setCurrentIndex(0);
+}
+
+//-----------------------------------------------------------------------------
+
+void StartupPopup::updateSize() {
+ m_xRes = m_resXFld->getValue();
+ m_yRes = m_resYFld->getValue();
+ if (Preferences::instance()->getPixelsOnly()) {
+ if (m_dpiFld->getValue() != Stage::standardDpi) {
+ m_dpiFld->setValue(Stage::standardDpi);
+ }
+ m_widthFld->setValue((double)m_xRes / Stage::standardDpi);
+ m_heightFld->setValue((double)m_yRes / Stage::standardDpi);
+ } else {
+ m_widthFld->setValue((double)m_xRes / m_dpi);
+ m_heightFld->setValue((double)m_yRes / m_dpi);
+ }
+ m_presetCombo->setCurrentIndex(0);
+}
+
+//-----------------------------------------------------------------------------
+
+StartupLabel::StartupLabel(const QString &text, QWidget *parent, int index)
+ : QLabel(parent), m_index(index) {
+ setText(text);
+ setObjectName("StartupLabel");
+}
+
+StartupLabel::~StartupLabel() {}
+
+void StartupLabel::mousePressEvent(QMouseEvent *event) {
+ m_text = text();
+ std::string strText = m_text.toStdString();
+ emit wasClicked(m_index);
+}
+
+OpenPopupCommandHandler openStartupPopup(MI_StartupPopup);
diff --git a/toonz/sources/toonz/startuppopup.h b/toonz/sources/toonz/startuppopup.h
new file mode 100644
index 0000000..cd1e33d
--- /dev/null
+++ b/toonz/sources/toonz/startuppopup.h
@@ -0,0 +1,109 @@
+#pragma once
+
+#ifndef STARTUPPOPUP_H
+#define STARTUPPOPUP_H
+
+#include "toonzqt/dvdialog.h"
+#include "toonzqt/doublefield.h"
+#include "toonzqt/intfield.h"
+#include "toonzqt/filefield.h"
+#include "toonzqt/camerasettingswidget.h"
+#include
+#include
+#include
+#include
+
+// forward declaration
+class QLabel;
+class QComboBox;
+class StartupLabel;
+
+//=============================================================================
+// LevelCreatePopup
+//-----------------------------------------------------------------------------
+
+class StartupPopup final : public DVGui::Dialog {
+ Q_OBJECT
+
+ DVGui::LineEdit *m_nameFld;
+ DVGui::FileField *m_pathFld;
+ QLabel *m_widthLabel;
+ QLabel *m_heightLabel;
+ QLabel *m_fpsLabel;
+ QLabel *m_resXLabel;
+ QLabel *m_resTextLabel;
+ QLabel *m_dpiLabel;
+ QLabel *m_sceneNameLabel;
+ DVGui::DoubleLineEdit *m_dpiFld;
+ DVGui::MeasuredDoubleLineEdit *m_widthFld;
+ DVGui::MeasuredDoubleLineEdit *m_heightFld;
+ DVGui::DoubleLineEdit *m_fpsFld;
+ DVGui::DoubleLineEdit *m_resXFld;
+ DVGui::DoubleLineEdit *m_resYFld;
+ QList m_sceneNames;
+ QList m_projectPaths;
+ QCheckBox *m_showAtStartCB;
+ QComboBox *m_projectsCB;
+ QComboBox *m_unitsCB;
+ QPushButton *m_loadOtherSceneButton;
+ QPushButton *m_newProjectButton;
+ QComboBox *m_presetCombo;
+ QPushButton *m_addPresetBtn, *m_removePresetBtn;
+ CameraSettingsWidget *m_cameraSettingsWidget;
+ double m_dpi;
+ int m_xRes, m_yRes;
+ bool m_updating = false;
+ QString m_presetListFile;
+ QGroupBox *m_projectBox;
+ QGroupBox *m_sceneBox;
+ QGroupBox *m_recentBox;
+ QVBoxLayout *m_recentSceneLay;
+ QVector m_recentNamesLabels;
+
+public:
+ StartupPopup();
+
+protected:
+ void showEvent(QShowEvent *) override;
+ void loadPresetList();
+ void savePresetList();
+ QString aspectRatioValueToString(double value, int width = 0, int height = 0);
+ double aspectRatioStringToValue(const QString &s);
+ bool parsePresetString(const QString &str, QString &name, int &xres,
+ int &yres, double &fx, double &fy, QString &xoffset,
+ QString &yoffset, double &ar, bool forCleanup = false);
+
+public slots:
+ void onRecentSceneClicked(int index);
+ void onCreateButton();
+ void onShowAtStartChanged(int index);
+ void updateProjectCB();
+ void onProjectChanged(int index);
+ void onNewProjectButtonPressed();
+ void onLoadSceneButtonPressed();
+ void onSceneChanged();
+ void updateResolution();
+ void updateSize();
+ void onDpiChanged();
+ void addPreset();
+ void removePreset();
+ void onPresetSelected(const QString &str);
+ void onCameraUnitChanged(int index);
+};
+
+class StartupLabel : public QLabel {
+ Q_OBJECT
+public:
+ explicit StartupLabel(const QString &text = "", QWidget *parent = 0,
+ int index = -1);
+ ~StartupLabel();
+ QString m_text;
+ int m_index;
+signals:
+ void wasClicked(int index);
+
+protected:
+ void mousePressEvent(QMouseEvent *event);
+};
+
+#endif // STARTUPPOPUP_H
diff --git a/toonz/sources/toonz/tapp.cpp b/toonz/sources/toonz/tapp.cpp
index a6ef8b2..698fe26 100644
--- a/toonz/sources/toonz/tapp.cpp
+++ b/toonz/sources/toonz/tapp.cpp
@@ -673,16 +673,25 @@ void TApp::autosave() {
} else
m_autosaveSuspended = false;
- if (scene->isUntitled()) {
+ if (scene->isUntitled() &&
+ Preferences::instance()->isAutosaveSceneEnabled()) {
DVGui::warning(
- tr("It is not possible to save automatically an untitled scene."));
+ tr("It is not possible to automatically save an untitled scene."));
return;
}
DVGui::ProgressDialog pb(
"Autosaving scene..." + toQString(scene->getScenePath()), 0, 0, 1);
pb.show();
- IoCmd::saveScene();
+ Preferences *pref = Preferences::instance();
+ if (pref->isAutosaveSceneEnabled() && pref->isAutosaveOtherFilesEnabled()) {
+ IoCmd::saveAll();
+ } else if (pref->isAutosaveSceneEnabled()) {
+ IoCmd::saveScene();
+ } else if (pref->isAutosaveOtherFilesEnabled()) {
+ IoCmd::saveNonSceneFiles();
+ }
+
pb.setValue(1);
}
@@ -705,7 +714,7 @@ void TApp::onStartAutoSave() {
//-----------------------------------------------------------------------------
void TApp::onStopAutoSave() {
- assert(!Preferences::instance()->isAutosaveEnabled());
+ // assert(!Preferences::instance()->isAutosaveEnabled());
m_autosaveTimer->stop();
}
diff --git a/toonz/sources/toonz/toonz.qrc b/toonz/sources/toonz/toonz.qrc
index 75aa7a1..3ad3f78 100644
--- a/toonz/sources/toonz/toonz.qrc
+++ b/toonz/sources/toonz/toonz.qrc
@@ -264,6 +264,7 @@
Resources/standard.png
Resources/standard_on.png
Resources/standard_over.png
+ Resources/startup.png
Resources/start_off.png
Resources/start_on.png
Resources/stop_off.png
@@ -442,5 +443,8 @@
Resources/finger_rollover.svg
Resources/ruler.svg
Resources/ruler_rollover.svg
+ Resources/locator.png
+ Resources/locator_click.png
+ Resources/locator_over.png
diff --git a/toonz/sources/toonzlib/convert2tlv.cpp b/toonz/sources/toonzlib/convert2tlv.cpp
index 8e9c529..2fbed64 100644
--- a/toonz/sources/toonzlib/convert2tlv.cpp
+++ b/toonz/sources/toonzlib/convert2tlv.cpp
@@ -566,6 +566,18 @@ TPalette *Convert2Tlv::buildPalette() {
page->addStyle(stylesToBeAddedToPage.at(s));
}
+ /*
+ If the palette path is empty, an initial palette with four colors are set in
+ the palette here.
+ ( see Convert2Tlv::init() ) So here I make the latter three styles in the
+ initial palette to set
+ "AutoPaint" options.
+ */
+ if (m_palettePath.isEmpty()) {
+ assert(m_palette->getStyleCount() >= 5);
+ for (int id = 2; id <= 4; id++) m_palette->getStyle(id)->setFlags(1);
+ }
+
if (!m_appendDefaultPalette) return m_palette;
/*-- Adding styles in the default palette to the result palette, starts here
@@ -810,11 +822,17 @@ bool Convert2Tlv::init(std::string &errorMessage) {
m_it = m_level1->begin();
- /*- 既定のパレットを作る。黒、赤、青、緑の順 -*/
- m_colorMap[TPixel::Black] = ++m_lastIndex;
- m_colorMap[TPixel::Red] = ++m_lastIndex;
- m_colorMap[TPixel::Blue] = ++m_lastIndex;
- m_colorMap[TPixel::Green] = ++m_lastIndex;
+ /*-
+ If the palette is empty, make an initial palette with black, red, blue and
+ green styles.
+ For the latter three styles the "autopaint" option should be set.
+ -*/
+ if (m_lastIndex == 0) {
+ m_colorMap[TPixel::Black] = ++m_lastIndex;
+ m_colorMap[TPixel::Red] = ++m_lastIndex;
+ m_colorMap[TPixel::Blue] = ++m_lastIndex;
+ m_colorMap[TPixel::Green] = ++m_lastIndex;
+ }
return true;
}
diff --git a/toonz/sources/toonzlib/palettecmd.cpp b/toonz/sources/toonzlib/palettecmd.cpp
index 5e16930..c23f12e 100644
--- a/toonz/sources/toonzlib/palettecmd.cpp
+++ b/toonz/sources/toonzlib/palettecmd.cpp
@@ -33,6 +33,7 @@
#include "tstroke.h"
#include "tregion.h"
#include "tlevel_io.h"
+#include "tpixelutils.h"
#include "historytypes.h"
@@ -45,6 +46,8 @@
#include
#include
+#include
+
//===================================================================
void findPaletteLevels(set &levels, int &rowIndex,
@@ -1168,3 +1171,177 @@ void PaletteCmd::renamePaletteStyle(TPaletteHandle *paletteHandle,
paletteHandle->notifyColorStyleChanged(false);
TUndoManager::manager()->add(undo);
}
+
+//=============================================================================
+// organizePaletteStyle
+// called in ColorModelViewer::pick() - move selected style to the first page
+//-----------------------------------------------------------------------------
+namespace {
+
+class setStylePickedPositionUndo final : public TUndo {
+ TPaletteHandle *m_paletteHandle; // Used in undo and redo to notify change
+ int m_styleId;
+ TPaletteP m_palette;
+ TPoint m_newPos;
+ TPoint m_oldPos;
+
+public:
+ setStylePickedPositionUndo(TPaletteHandle *paletteHandle, int styleId,
+ const TPoint &newPos)
+ : m_paletteHandle(paletteHandle), m_styleId(styleId), m_newPos(newPos) {
+ m_palette = paletteHandle->getPalette();
+ assert(m_palette);
+ TColorStyle *style = m_palette->getStyle(m_styleId);
+ assert(style);
+ m_oldPos = style->getPickedPosition();
+ }
+ void undo() const override {
+ TColorStyle *style = m_palette->getStyle(m_styleId);
+ assert(style);
+ style->setPickedPosition(m_oldPos);
+ m_paletteHandle->notifyColorStyleChanged(false);
+ }
+ void redo() const override {
+ TColorStyle *style = m_palette->getStyle(m_styleId);
+ assert(style);
+ style->setPickedPosition(m_newPos);
+ m_paletteHandle->notifyColorStyleChanged(false);
+ }
+ int getSize() const override { return sizeof *this; }
+ QString getHistoryString() override {
+ return QObject::tr("Set Picked Position of Style#%1 in Palette%2 : %3,%4")
+ .arg(QString::number(m_styleId))
+ .arg(QString::fromStdWString(m_palette->getPaletteName()))
+ .arg(QString::number(m_newPos.x))
+ .arg(QString::number(m_newPos.y));
+ }
+ int getHistoryType() override { return HistoryType::Palette; }
+};
+}
+
+void PaletteCmd::organizePaletteStyle(TPaletteHandle *paletteHandle,
+ int styleId, const TPoint &point) {
+ if (!paletteHandle) return;
+ TPalette *palette = paletteHandle->getPalette();
+ if (!palette) return;
+ // if the style is already in the first page, then do nothing
+ TPalette::Page *page = palette->getStylePage(styleId);
+ if (!page || page->getIndex() == 0) return;
+
+ int indexInPage = page->search(styleId);
+
+ TUndoManager::manager()->beginBlock();
+
+ // call arrangeStyles() to move style to the first page
+ arrangeStyles(paletteHandle, 0, palette->getPage(0)->getStyleCount(),
+ page->getIndex(), {indexInPage});
+ // then set the picked position
+ setStylePickedPositionUndo *undo =
+ new setStylePickedPositionUndo(paletteHandle, styleId, point);
+ undo->redo();
+ TUndoManager::manager()->add(undo);
+
+ TUndoManager::manager()->endBlock();
+}
+
+//=============================================================================
+// called in ColorModelViewer::repickFromColorModel().
+// Pick color from the img for all styles with "picked position" value.
+//-----------------------------------------------------------------------------
+namespace {
+
+class pickColorByUsingPickedPositionUndo final : public TUndo {
+ TPaletteHandle *m_paletteHandle; // Used in undo and redo to notify change
+ TPaletteP m_palette;
+ QHash> m_styleList;
+
+public:
+ pickColorByUsingPickedPositionUndo(
+ TPaletteHandle *paletteHandle,
+ QHash> styleList)
+ : m_paletteHandle(paletteHandle), m_styleList(styleList) {
+ m_palette = paletteHandle->getPalette();
+ assert(m_palette);
+ }
+ void undo() const override {
+ QHash>::const_iterator i =
+ m_styleList.constBegin();
+ while (i != m_styleList.constEnd()) {
+ TColorStyle *style = m_palette->getStyle(i.key());
+ assert(style);
+ style->setMainColor(i.value().first);
+ ++i;
+ }
+ m_paletteHandle->notifyColorStyleChanged(false);
+ }
+ void redo() const override {
+ QHash>::const_iterator i =
+ m_styleList.constBegin();
+ while (i != m_styleList.constEnd()) {
+ TColorStyle *style = m_palette->getStyle(i.key());
+ assert(style);
+ style->setMainColor(i.value().second);
+ ++i;
+ }
+ m_paletteHandle->notifyColorStyleChanged(false);
+ }
+ int getSize() const override { return sizeof *this; }
+ QString getHistoryString() override {
+ return QObject::tr("Update Colors by Using Picked Positions in Palette %1")
+ .arg(QString::fromStdWString(m_palette->getPaletteName()));
+ }
+ int getHistoryType() override { return HistoryType::Palette; }
+};
+
+TPixel32 pickColor(TRasterImageP ri, const TPoint &rasterPoint) {
+ TRasterP raster;
+ raster = ri->getRaster();
+
+ if (!TRect(raster->getSize()).contains(rasterPoint))
+ return TPixel32::Transparent;
+
+ TRaster32P raster32 = raster;
+ if (raster32) return raster32->pixels(rasterPoint.y)[rasterPoint.x];
+
+ TRasterGR8P rasterGR8 = raster;
+ if (rasterGR8)
+ return toPixel32(rasterGR8->pixels(rasterPoint.y)[rasterPoint.x]);
+
+ return TPixel32::Transparent;
+}
+}
+
+void PaletteCmd::pickColorByUsingPickedPosition(TPaletteHandle *paletteHandle,
+ TImageP img) {
+ TRasterImageP ri = img;
+ if (!ri) return;
+
+ TPalette *currentPalette = paletteHandle->getPalette();
+ if (!currentPalette) return;
+
+ TDimension imgSize = ri->getRaster()->getSize();
+ QHash> styleList;
+
+ // For all styles (starting from #1 as #0 is reserved for the transparent)
+ for (int sId = 1; sId < currentPalette->getStyleCount(); sId++) {
+ TColorStyle *style = currentPalette->getStyle(sId);
+ TPoint pp = style->getPickedPosition();
+ // If style has a valid picked position
+ if (pp != TPoint() && pp.x >= 0 && pp.x < imgSize.lx && pp.y >= 0 &&
+ pp.y < imgSize.ly && style->hasMainColor()) {
+ TPixel32 beforeColor = style->getMainColor();
+ TPixel32 afterColor = pickColor(ri, pp);
+ style->setMainColor(afterColor);
+ //... store the style in the list for undo
+ styleList.insert(sId, QPair(beforeColor, afterColor));
+ }
+ }
+
+ // if some style has been changed, then register undo and notify changes
+ if (!styleList.isEmpty()) {
+ pickColorByUsingPickedPositionUndo *undo =
+ new pickColorByUsingPickedPositionUndo(paletteHandle, styleList);
+ TUndoManager::manager()->add(undo);
+ paletteHandle->notifyColorStyleChanged(false, true); // set dirty flag here
+ }
+}
\ No newline at end of file
diff --git a/toonz/sources/toonzlib/preferences.cpp b/toonz/sources/toonzlib/preferences.cpp
index 9af590c..588792e 100644
--- a/toonz/sources/toonzlib/preferences.cpp
+++ b/toonz/sources/toonzlib/preferences.cpp
@@ -256,6 +256,9 @@ Preferences::Preferences()
, m_fitToFlipbookEnabled(false)
, m_previewAlwaysOpenNewFlipEnabled(false)
, m_autosaveEnabled(false)
+ , m_autosaveSceneEnabled(true)
+ , m_autosaveOtherFilesEnabled(true)
+ , m_startupPopupEnabled(true)
, m_defaultViewerEnabled(false)
, m_saveUnpaintedInCleanup(true)
, m_askForOverrideRender(true)
@@ -288,8 +291,11 @@ Preferences::Preferences()
, m_multiLayerStylePickerEnabled(false)
, m_paletteTypeOnLoadRasterImageAsColorModel(0)
, m_showKeyframesOnXsheetCellArea(true)
+ , m_projectRoot(0x08)
+ , m_customProjectRoot("")
, m_precompute(true)
, m_ffmpegTimeout(30)
+ , m_shortcutPreset("defopentoonz")
, m_useNumpadForSwitchingStyles(false) {
TCamera camera;
m_defLevelType = PLI_XSHLEVEL;
@@ -324,6 +330,10 @@ Preferences::Preferences()
getValue(*m_settings, "sceneNumberingEnabled", m_sceneNumberingEnabled);
getValue(*m_settings, "animationSheetEnabled", m_animationSheetEnabled);
getValue(*m_settings, "autosaveEnabled", m_autosaveEnabled);
+ getValue(*m_settings, "autosaveSceneEnabled", m_autosaveSceneEnabled);
+ getValue(*m_settings, "autosaveOtherFilesEnabled",
+ m_autosaveOtherFilesEnabled);
+ getValue(*m_settings, "startupPopupEnabled", m_startupPopupEnabled);
getValue(*m_settings, "defaultViewerEnabled", m_defaultViewerEnabled);
getValue(*m_settings, "rasterOptimizedMemory", m_rasterOptimizedMemory);
getValue(*m_settings, "saveUnpaintedInCleanup", m_saveUnpaintedInCleanup);
@@ -394,6 +404,9 @@ Preferences::Preferences()
m_oldCameraUnits = units;
// end for pixels only
+ getValue(*m_settings, "projectRoot", m_projectRoot);
+ m_customProjectRoot = m_settings->value("customProjectRoot").toString();
+
units = m_settings->value("linearUnits").toString();
if (units != "") m_units = units;
setUnits(m_units.toStdString());
@@ -549,6 +562,9 @@ Preferences::Preferences()
if (ffmpegPath != "") m_ffmpegPath = ffmpegPath;
setFfmpegPath(m_ffmpegPath.toStdString());
getValue(*m_settings, "ffmpegTimeout", m_ffmpegTimeout);
+ QString shortcutPreset = m_settings->value("shortcutPreset").toString();
+ if (shortcutPreset != "") m_shortcutPreset = shortcutPreset;
+ setShortcutPreset(m_shortcutPreset.toStdString());
getValue(*m_settings, "useNumpadForSwitchingStyles",
m_useNumpadForSwitchingStyles);
}
@@ -643,6 +659,27 @@ void Preferences::enableAutosave(bool on) {
//-----------------------------------------------------------------
+void Preferences::enableAutosaveScene(bool on) {
+ m_autosaveSceneEnabled = on;
+ m_settings->setValue("autosaveSceneEnabled", on ? "1" : "0");
+}
+
+//-----------------------------------------------------------------
+
+void Preferences::enableAutosaveOtherFiles(bool on) {
+ m_autosaveOtherFilesEnabled = on;
+ m_settings->setValue("autosaveOtherFilesEnabled", on ? "1" : "0");
+}
+
+//-----------------------------------------------------------------
+
+void Preferences::enableStartupPopup(bool on) {
+ m_startupPopupEnabled = on;
+ m_settings->setValue("startupPopupEnabled", on ? "1" : "0");
+}
+
+//-----------------------------------------------------------------
+
void Preferences::setAskForOverrideRender(bool on) {
m_autosaveEnabled = on;
m_settings->setValue("askForOverrideRender", on ? "1" : "0");
@@ -975,6 +1012,22 @@ void Preferences::setPixelsOnly(bool state) {
//-----------------------------------------------------------------
+void Preferences::setProjectRoot(int index) {
+ // storing the index of the selection instead of the text
+ // to make translation work
+ m_projectRoot = index;
+ m_settings->setValue("projectRoot", m_projectRoot);
+}
+
+//-----------------------------------------------------------------
+
+void Preferences::setCustomProjectRoot(std::wstring customProjectRoot) {
+ m_customProjectRoot = QString::fromStdWString(customProjectRoot);
+ m_settings->setValue("customProjectRoot", m_customProjectRoot);
+}
+
+//-----------------------------------------------------------------
+
void Preferences::setUnits(std::string units) {
m_units = QString::fromStdString(units);
m_settings->setValue("linearUnits", m_units);
@@ -1206,6 +1259,13 @@ void Preferences::setFfmpegPath(std::string path) {
//-----------------------------------------------------------------
+void Preferences::setShortcutPreset(std::string preset) {
+ m_shortcutPreset = QString::fromStdString(preset);
+ m_settings->setValue("shortcutPreset", m_shortcutPreset);
+}
+
+//-----------------------------------------------------------------
+
void Preferences::setPrecompute(bool enabled) { m_precompute = enabled; }
//-----------------------------------------------------------------
diff --git a/toonz/sources/toonzlib/stagevisitor.cpp b/toonz/sources/toonzlib/stagevisitor.cpp
index f3746ab..dc256db 100644
--- a/toonz/sources/toonzlib/stagevisitor.cpp
+++ b/toonz/sources/toonzlib/stagevisitor.cpp
@@ -602,6 +602,9 @@ void RasterPainter::flushRasterImages() {
glDisable(GL_DITHER);
glDisable(GL_LOGIC_OP);
+/* disable, since these features are never enabled, and cause OpenGL to assert
+ * on systems that don't support them: see #591 */
+#if 0
#ifdef GL_EXT_convolution
glDisable(GL_CONVOLUTION_1D_EXT);
glDisable(GL_CONVOLUTION_2D_EXT);
@@ -612,6 +615,7 @@ void RasterPainter::flushRasterImages() {
glDisable(GL_HISTOGRAM_EXT);
glDisable(GL_MINMAX_EXT);
#endif
+#endif
#ifdef GL_EXT_texture3D
glDisable(GL_TEXTURE_3D_EXT);
diff --git a/toonz/sources/toonzlib/studiopalettecmd.cpp b/toonz/sources/toonzlib/studiopalettecmd.cpp
index 8cf07e9..c8023ec 100644
--- a/toonz/sources/toonzlib/studiopalettecmd.cpp
+++ b/toonz/sources/toonzlib/studiopalettecmd.cpp
@@ -501,7 +501,11 @@ void StudioPaletteCmd::loadIntoCurrentPalette(TPaletteHandle *paletteHandle,
// keep the color model path unchanged
TFilePath oldRefImagePath = current->getRefImgPath();
+ std::wstring oldGlobalName = current->getGlobalName();
current->assign(palette, true);
+ // keep global name unchanged
+ current->setGlobalName(oldGlobalName);
+
current->setDirtyFlag(true);
current->setRefImgPath(oldRefImagePath);
diff --git a/toonz/sources/toonzlib/toonzfolders.cpp b/toonz/sources/toonzlib/toonzfolders.cpp
index ff09da0..a8ccd6b 100644
--- a/toonz/sources/toonzlib/toonzfolders.cpp
+++ b/toonz/sources/toonzlib/toonzfolders.cpp
@@ -3,20 +3,75 @@
#include "toonz/toonzfolders.h"
#include "tsystem.h"
#include "tenv.h"
-//#include "appmainshell.h"
#include "tconvert.h"
#include "toonz/preferences.h"
+#include
using namespace TEnv;
+//-------------------------------------------------------------------
+namespace {
+TFilePath getMyDocumentsPath() {
+ QString documentsPath =
+ QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation)[0];
+ return TFilePath(documentsPath);
+}
+
+// Desktop Path
+TFilePath getDesktopPath() {
+ QString desktopPath =
+ QStandardPaths::standardLocations(QStandardPaths::DesktopLocation)[0];
+ return TFilePath(desktopPath);
+}
+}
+//-------------------------------------------------------------------
+
TFilePath ToonzFolder::getModulesDir() {
return getProfileFolder() + "layouts";
}
TFilePathSet ToonzFolder::getProjectsFolders() {
- TFilePathSet fps =
+ int location = Preferences::instance()->getProjectRoot();
+ QString path = Preferences::instance()->getCustomProjectRoot();
+ TFilePathSet fps;
+ int projectPaths = Preferences::instance()->getProjectRoot();
+ bool stuff = projectPaths & 0x08;
+ bool documents = projectPaths & 0x04;
+ bool desktop = projectPaths & 0x02;
+ bool custom = projectPaths & 0x01;
+
+ // make sure at least something is there
+ if (!desktop && !custom && !documents) stuff = 1;
+ TFilePathSet tempFps =
getSystemVarPathSetValue(getSystemVarPrefix() + "PROJECTS");
- if (fps.empty()) fps.push_back(TEnv::getStuffDir() + "Projects");
+ if (stuff) {
+ for (TFilePath tempPath : tempFps) {
+ if (TSystem::doesExistFileOrLevel(TFilePath(tempPath))) {
+ fps.push_back(TFilePath(tempPath));
+ }
+ }
+ if (tempFps.size() == 0) fps.push_back(TEnv::getStuffDir() + "Projects");
+ }
+ if (documents) {
+ fps.push_back(getMyDocumentsPath() + "OpenToonz");
+ if (!TSystem::doesExistFileOrLevel(getMyDocumentsPath() + "OpenToonz")) {
+ TSystem::mkDir(getMyDocumentsPath() + "OpenToonz");
+ }
+ }
+ if (desktop) {
+ fps.push_back(getDesktopPath() + "OpenToonz");
+ if (!TSystem::doesExistFileOrLevel(getDesktopPath() + "OpenToonz")) {
+ TSystem::mkDir(getDesktopPath() + "OpenToonz");
+ }
+ }
+ if (custom) {
+ QStringList paths = path.split("**");
+ for (QString tempPath : paths) {
+ if (TSystem::doesExistFileOrLevel(TFilePath(tempPath))) {
+ fps.push_back(TFilePath(tempPath));
+ }
+ }
+ }
return fps;
}
diff --git a/toonz/sources/toonzqt/dvdialog.cpp b/toonz/sources/toonzqt/dvdialog.cpp
index 281586e..59cfbd8 100644
--- a/toonz/sources/toonzqt/dvdialog.cpp
+++ b/toonz/sources/toonzqt/dvdialog.cpp
@@ -729,6 +729,23 @@ void Dialog::addButtonBarWidget(QWidget *first, QWidget *second,
}
}
+//-----------------------------------------------------------------------------
+/*! Add four widget to the button part of dialog.
+*/
+void Dialog::addButtonBarWidget(QWidget *first, QWidget *second, QWidget *third,
+ QWidget *fourth) {
+ first->setMinimumSize(65, 25);
+ second->setMinimumSize(65, 25);
+ third->setMinimumSize(65, 25);
+ assert(m_hasButton);
+ if (m_hasButton) {
+ m_buttonLayout->addWidget(first);
+ m_buttonLayout->addWidget(second);
+ m_buttonLayout->addWidget(third);
+ m_buttonLayout->addWidget(fourth);
+ }
+}
+
//=============================================================================
RadioButtonDialog::RadioButtonDialog(const QString &labelText,
@@ -1060,6 +1077,65 @@ int DVGui::MsgBox(const QString &text, const QString &button1Text,
//-----------------------------------------------------------------------------
+int DVGui::MsgBox(const QString &text, const QString &button1Text,
+ const QString &button2Text, const QString &button3Text,
+ const QString &button4Text, int defaultButtonIndex,
+ QWidget *parent) {
+ Dialog dialog(parent, true);
+ dialog.setWindowFlags(dialog.windowFlags() | Qt::WindowStaysOnTopHint);
+ dialog.setAlignment(Qt::AlignLeft);
+ QString msgBoxTitle = getMsgBoxTitle(QUESTION);
+ dialog.setWindowTitle(msgBoxTitle);
+
+ QLabel *mainTextLabel = new QLabel(text, &dialog);
+ QPixmap iconPixmap = getMsgBoxPixmap(QUESTION);
+ if (!iconPixmap.isNull()) {
+ QLabel *iconLabel = new QLabel(&dialog);
+ iconLabel->setPixmap(iconPixmap);
+
+ QHBoxLayout *mainLayout = new QHBoxLayout;
+ mainLayout->addWidget(iconLabel);
+ mainLayout->addSpacing(16);
+ mainLayout->addWidget(mainTextLabel);
+ dialog.addLayout(mainLayout);
+ } else
+ dialog.addWidget(mainTextLabel);
+
+ // ButtonGroup: is used only to retrieve the clicked button
+ QButtonGroup *buttonGroup = new QButtonGroup(&dialog);
+
+ QPushButton *button1 = new QPushButton(button1Text, &dialog);
+ button1->setDefault(false);
+ if (defaultButtonIndex == 0) button1->setDefault(true);
+ dialog.addButtonBarWidget(button1);
+ buttonGroup->addButton(button1, 1);
+
+ QPushButton *button2 = new QPushButton(button2Text, &dialog);
+ button2->setDefault(false);
+ if (defaultButtonIndex == 1) button2->setDefault(true);
+ dialog.addButtonBarWidget(button2);
+ buttonGroup->addButton(button2, 2);
+
+ QPushButton *button3 = new QPushButton(button3Text, &dialog);
+ button3->setDefault(false);
+ if (defaultButtonIndex == 2) button3->setDefault(true);
+ dialog.addButtonBarWidget(button3);
+ buttonGroup->addButton(button3, 3);
+
+ QPushButton *button4 = new QPushButton(button4Text, &dialog);
+ button4->setDefault(false);
+ if (defaultButtonIndex == 3) button4->setDefault(true);
+ dialog.addButtonBarWidget(button4);
+ buttonGroup->addButton(button4, 4);
+
+ QObject::connect(buttonGroup, SIGNAL(buttonPressed(int)), &dialog,
+ SLOT(done(int)));
+ dialog.raise();
+ return dialog.exec();
+}
+
+//-----------------------------------------------------------------------------
+
int DVGui::MsgBox(const QString &text, const QString &button1,
const QString &button2, int defaultButtonIndex,
QWidget *parent) {
diff --git a/toonz/sources/toonzqt/flipconsole.cpp b/toonz/sources/toonzqt/flipconsole.cpp
index 706bb6e..1caa5ac 100644
--- a/toonz/sources/toonzqt/flipconsole.cpp
+++ b/toonz/sources/toonzqt/flipconsole.cpp
@@ -1234,16 +1234,19 @@ void FlipConsole::createPlayToolBar(bool withCustomWidget) {
if (m_gadgetsMask & eRed || m_gadgetsMask & eGRed)
m_colorFilterSep = m_playToolBar->addSeparator();
- // Sound & Histogram
- if (m_gadgetsMask & eSound || m_gadgetsMask & eHisto) {
+ // Sound & Histogram & Locator
+ if (m_gadgetsMask & eSound || m_gadgetsMask & eHisto ||
+ m_gadgetsMask & eLocator) {
if (m_gadgetsMask & eSound) {
createButton(eSound, "sound", tr("&Soundtrack "), true);
m_soundSep = m_playToolBar->addSeparator();
}
- if (m_gadgetsMask & eHisto) {
+ if (m_gadgetsMask & eHisto)
createButton(eHisto, "histograms", tr("&Histogram"), false);
+ if (m_gadgetsMask & eLocator)
+ createButton(eLocator, "locator", tr("&Locator"), false);
+ if (m_gadgetsMask & eHisto || m_gadgetsMask & eLocator)
m_histoSep = m_playToolBar->addSeparator();
- }
}
if (m_gadgetsMask & eFilledRaster) {
@@ -1572,6 +1575,7 @@ void FlipConsole::doButtonPressed(UINT button) {
case eHisto:
case eSaveImg:
case eSave:
+ case eLocator:
// nothing to do
return;
diff --git a/toonz/sources/toonzqt/menubarcommand.cpp b/toonz/sources/toonzqt/menubarcommand.cpp
index 5e9612f..723cfda 100644
--- a/toonz/sources/toonzqt/menubarcommand.cpp
+++ b/toonz/sources/toonzqt/menubarcommand.cpp
@@ -279,7 +279,8 @@ int CommandManager::getKeyFromId(const char *id) {
//---------------------------------------------------------
-void CommandManager::setShortcut(QAction *action, std::string shortcutString) {
+void CommandManager::setShortcut(QAction *action, std::string shortcutString,
+ bool keepDefault) {
QString shortcut = QString::fromStdString(shortcutString);
std::string oldShortcutString = action->shortcut().toString().toStdString();
@@ -296,7 +297,7 @@ void CommandManager::setShortcut(QAction *action, std::string shortcutString) {
if (node->m_type == ZoomCommandType && ks.count() > 1) {
DVGui::warning(
- QObject::tr("It is not possible to assing a shortcut with modifiers to "
+ QObject::tr("It is not possible to assign a shortcut with modifiers to "
"the visualization commands."));
return;
}
@@ -328,7 +329,9 @@ void CommandManager::setShortcut(QAction *action, std::string shortcutString) {
settings.beginGroup("shortcuts");
settings.setValue(QString::fromStdString(node->m_id),
QString::fromStdString(shortcutString));
- if (oldActionId != "") settings.remove(oldActionId);
+ if (keepDefault) {
+ if (oldActionId != "") settings.remove(oldActionId);
+ }
settings.endGroup();
}
diff --git a/toonz/sources/toonzqt/paletteviewer.cpp b/toonz/sources/toonzqt/paletteviewer.cpp
index faace8b..b7a59ea 100644
--- a/toonz/sources/toonzqt/paletteviewer.cpp
+++ b/toonz/sources/toonzqt/paletteviewer.cpp
@@ -911,10 +911,7 @@ void PaletteViewer::saveStudioPalette() {
if (ret == 2 || ret == 0) return;
sp->setPalette(fp, getPalette(), false);
- question = "Do you want to update all linked styles in current scene ?";
- ret = DVGui::MsgBox(question, tr("Update"), tr("Don't Update"), 0);
- if (ret == 1)
- StudioPaletteCmd::updateAllLinkedStyles(m_paletteHandle, m_xsheetHandle);
+ StudioPaletteCmd::updateAllLinkedStyles(m_paletteHandle, m_xsheetHandle);
palette->setDirtyFlag(false);
}
diff --git a/toonz/sources/toonzqt/paletteviewergui.cpp b/toonz/sources/toonzqt/paletteviewergui.cpp
index 43f0e81..a692b71 100644
--- a/toonz/sources/toonzqt/paletteviewergui.cpp
+++ b/toonz/sources/toonzqt/paletteviewergui.cpp
@@ -454,7 +454,11 @@ void PageViewer::drawColorName(QPainter &p, QRect &nameRect, TColorStyle *style,
name += " " + toQString(g.first) + ":" + QString::number(g.second);
if (style->getFlags() != 0) name += "(autopaint)";
- p.drawText(nameRect.adjusted(8, 4, -6, -4), name);
+ TPoint pickedPos = style->getPickedPosition();
+ if (pickedPos != TPoint())
+ name += QString(" (%1,%2)").arg(pickedPos.x).arg(pickedPos.y);
+
+ p.drawText(nameRect.adjusted(6, 4, -6, -4), name);
QColor borderCol(getTextColor());
borderCol.setAlphaF(0.3);
@@ -809,10 +813,23 @@ void PageViewer::paintEvent(QPaintEvent *e) {
p.drawText(indexRect, Qt::AlignCenter, QString().setNum(styleIndex));
// draw "Autopaint for lines" indicator
+ int offset = 0;
if (style->getFlags() != 0) {
QRect aflRect(chipRect.bottomLeft() + QPoint(0, -14), QSize(12, 15));
p.drawRect(aflRect);
p.drawText(aflRect, Qt::AlignCenter, "A");
+ offset += 12;
+ }
+
+ // draw "Picked Position" indicator (not show on small chip mode)
+ if (style->getPickedPosition() != TPoint() && m_viewMode != SmallChips) {
+ QRect ppRect(chipRect.bottomLeft() + QPoint(offset, -14),
+ QSize(12, 15));
+ p.drawRect(ppRect);
+ QPoint markPos = ppRect.center() + QPoint(1, 0);
+ p.drawEllipse(markPos, 3, 3);
+ p.drawLine(markPos - QPoint(5, 0), markPos + QPoint(5, 0));
+ p.drawLine(markPos - QPoint(0, 5), markPos + QPoint(0, 5));
}
// revert font set
@@ -1060,27 +1077,21 @@ void PageViewer::contextMenuEvent(QContextMenuEvent *event) {
// remove links from studio palette
if (m_viewType == LEVEL_PALETTE && m_styleSelection &&
- !m_styleSelection->isEmpty() && !isLocked) {
+ !m_styleSelection->isEmpty() && !isLocked &&
+ m_styleSelection->hasLinkedStyle()) {
menu.addSeparator();
- QAction *removeLinkAct = menu.addAction(tr("Remove Links"));
- connect(removeLinkAct, SIGNAL(triggered()), this, SLOT(removeLink()));
+ QAction *toggleStyleLink = cmd->getAction("MI_ToggleLinkToStudioPalette");
+ menu.addAction(toggleStyleLink);
+ QAction *removeStyleLink =
+ cmd->getAction("MI_RemoveReferenceToStudioPalette");
+ menu.addAction(removeStyleLink);
+ QAction *getBackOriginalAct =
+ cmd->getAction("MI_GetColorFromStudioPalette");
+ menu.addAction(getBackOriginalAct);
}
if (((indexPage == 0 && index > 0) || (indexPage > 0 && index >= 0)) &&
index < getChipCount() && !isLocked) {
- // iwsw commented out temporarly
- /*
- wstring globalName = m_page->getStyle(index)->getGlobalName();
- if (m_viewType != STUDIO_PALETTE &&
- globalName != L"" &&
- (globalName[0] == L'-' || globalName[0] == L'+'))
- {
- createMenuAction(menu, "MI_ToggleLinkToStudioPalette", tr("Toggle
- Link to Studio Palette"), "toggleLink()");
- createMenuAction(menu, "MI_RemoveReferenceToStudioPalette",
- tr("Remove Reference to Studio Palette"), "eraseToggleLink()");
- }
- */
if (pasteValueAct) pasteValueAct->setEnabled(true);
if (pasteColorsAct) pasteColorsAct->setEnabled(true);
@@ -1098,29 +1109,20 @@ void PageViewer::contextMenuEvent(QContextMenuEvent *event) {
clearAct->setEnabled(false);
}
- // get color from the original studio palette
- if (m_viewType == LEVEL_PALETTE && m_styleSelection &&
- !m_styleSelection->isEmpty() && !isLocked) {
+ if (m_page) {
menu.addSeparator();
- QAction *getBackOriginalAct =
- cmd->getAction("MI_GetColorFromStudioPalette");
- menu.addAction(getBackOriginalAct);
+ QAction *newStyle = menu.addAction(tr("New Style"));
+ connect(newStyle, SIGNAL(triggered()), SLOT(addNewColor()));
+ QAction *newPage = menu.addAction(tr("New Page"));
+ connect(newPage, SIGNAL(triggered()), SLOT(addNewPage()));
}
- // iwsw commented out temporarly
/*
- if (m_viewType != STUDIO_PALETTE)
- {
- menu.addSeparator();
+ if (m_viewType != STUDIO_PALETTE) {
menu.addAction(cmd->getAction(MI_EraseUnusedStyles));
}
*/
- if (m_page) {
- QAction *newStyle = menu.addAction(tr("New Style"));
- connect(newStyle, SIGNAL(triggered()), SLOT(addNewColor()));
- QAction *newPage = menu.addAction(tr("New Page"));
- connect(newPage, SIGNAL(triggered()), SLOT(addNewPage()));
- }
+
menu.exec(event->globalPos());
}
@@ -1408,25 +1410,6 @@ void PageViewer::onStyleRenamed() {
}
//-----------------------------------------------------------------------------
-/*! Recall \b TStyleSelection::toggleLink() to current page style selection.
-*/
-void PageViewer::toggleLink() {
- if (!m_page || !m_styleSelection || m_styleSelection->isEmpty()) return;
- m_styleSelection->toggleLink();
- update();
- emit changeWindowTitleSignal();
-}
-
-//-----------------------------------------------------------------------------
-/*! Recall \b TStyleSelection::eraseToggleLink() to current page style
- * selection.
-*/
-void PageViewer::eraseToggleLink() {
- if (!m_page || !m_styleSelection || m_styleSelection->isEmpty()) return;
- m_styleSelection->eraseToggleLink();
-}
-
-//-----------------------------------------------------------------------------
bool PageViewer::hasShortcut(int indexInPage) {
if (!m_page) return false;
@@ -1698,13 +1681,6 @@ void PageViewer::updateCommandLocks() {
cmd->getAction("MI_BlendColors")->setEnabled(!isLocked);
cmd->getAction("MI_PasteNames")->setEnabled(!isLocked);
cmd->getAction("MI_GetColorFromStudioPalette")->setEnabled(!isLocked);
-}
-
-//-----------------------------------------------------------------------------
-/*! remove link and revert to the normal style
-*/
-void PageViewer::removeLink() {
- if (!m_page || !m_styleSelection || m_styleSelection->isEmpty()) return;
-
- if (m_styleSelection->removeLink()) emit changeWindowTitleSignal();
+ cmd->getAction("MI_ToggleLinkToStudioPalette")->setEnabled(!isLocked);
+ cmd->getAction("MI_RemoveReferenceToStudioPalette")->setEnabled(!isLocked);
}
diff --git a/toonz/sources/toonzqt/studiopaletteviewer.cpp b/toonz/sources/toonzqt/studiopaletteviewer.cpp
index 052335e..bb6b00e 100644
--- a/toonz/sources/toonzqt/studiopaletteviewer.cpp
+++ b/toonz/sources/toonzqt/studiopaletteviewer.cpp
@@ -497,6 +497,7 @@ void StudioPaletteTreeViewer::onCurrentItemChanged(QTreeWidgetItem *current,
m_currentPalette = StudioPalette::instance()->getPalette(newPath, false);
m_studioPaletteHandle->setPalette(m_currentPalette.getPointer());
m_studioPaletteHandle->notifyPaletteSwitched();
+ StudioPaletteCmd::updateAllLinkedStyles(m_levelPaletteHandle, m_xsheetHandle);
}
//-----------------------------------------------------------------------------
diff --git a/toonz/sources/toonzqt/styleeditor.cpp b/toonz/sources/toonzqt/styleeditor.cpp
index 107db3e..361b879 100644
--- a/toonz/sources/toonzqt/styleeditor.cpp
+++ b/toonz/sources/toonzqt/styleeditor.cpp
@@ -3060,9 +3060,13 @@ void StyleEditor::onStyleSwitched() {
QString::fromStdWString(L" Palette : " + palette->getPaletteName());
// style name
- statusText += QString::fromStdWString(L" | Style#");
+ statusText += QString::fromStdWString(L" | #");
statusText += QString::number(styleIndex);
statusText += QString::fromStdWString(L" : " + m_editedStyle->getName());
+ TPoint pickedPos = m_editedStyle->getPickedPosition();
+ if (pickedPos != TPoint())
+ statusText +=
+ QString(" (Picked from %1,%2)").arg(pickedPos.x).arg(pickedPos.y);
m_statusLabel->setText(statusText);
} else
diff --git a/toonz/sources/toonzqt/styleselection.cpp b/toonz/sources/toonzqt/styleselection.cpp
index 024ace0..99f9bb9 100644
--- a/toonz/sources/toonzqt/styleselection.cpp
+++ b/toonz/sources/toonzqt/styleselection.cpp
@@ -505,9 +505,14 @@ void TStyleSelection::enableCommands() {
enableCommand(this, MI_PasteNames, &TStyleSelection::pasteStylesName);
// available only for level palette
- if (m_paletteHandle->getPalette()->getGlobalName() == L"")
+ if (m_paletteHandle->getPalette()->getGlobalName() == L"") {
enableCommand(this, MI_GetColorFromStudioPalette,
&TStyleSelection::getBackOriginalStyle);
+ enableCommand(this, MI_ToggleLinkToStudioPalette,
+ &TStyleSelection::toggleLink);
+ enableCommand(this, MI_RemoveReferenceToStudioPalette,
+ &TStyleSelection::removeLink);
+ }
}
enableCommand(this, MI_Clear, &TStyleSelection::deleteStyles);
enableCommand(this, MI_EraseUnusedStyles, &TStyleSelection::eraseUnsedStyle);
@@ -1408,14 +1413,15 @@ public:
void TStyleSelection::toggleLink() {
TPalette *palette = getPalette();
if (!palette || m_pageIndex < 0) return;
+ if (isEmpty() || palette->isLocked()) return;
int n = m_styleIndicesInPage.size();
if (n <= 0) return;
std::vector> oldColorStylesLinked;
std::vector> newColorStylesLinked;
- bool somethingHasBeenLinked = false;
-
+ bool somethingHasBeenLinked = false;
+ bool somethingChanged = false;
bool currentStyleIsInSelection = false;
TPalette::Page *page = palette->getPage(m_pageIndex);
@@ -1435,6 +1441,7 @@ void TStyleSelection::toggleLink() {
name[0] = name[0] == L'-' ? L'+' : L'-';
cs->setGlobalName(name);
if (name[0] == L'+') somethingHasBeenLinked = true;
+ somethingChanged = true;
}
undo->setColorStyle(index, oldCs, name);
@@ -1442,6 +1449,13 @@ void TStyleSelection::toggleLink() {
palette->getPage(m_pageIndex)->search(m_paletteHandle->getStyleIndex()))
currentStyleIsInSelection = true;
}
+
+ // if nothing changed, do not set dirty flag, nor register undo
+ if (!somethingChanged) {
+ delete undo;
+ return;
+ }
+
if (somethingHasBeenLinked)
StudioPalette::instance()->updateLinkedColors(palette);
@@ -1460,6 +1474,7 @@ void TStyleSelection::toggleLink() {
void TStyleSelection::eraseToggleLink() {
TPalette *palette = getPalette();
if (!palette || m_pageIndex < 0) return;
+ if (isEmpty() || palette->isLocked()) return;
int n = m_styleIndicesInPage.size();
if (n <= 0) return;
@@ -1575,7 +1590,7 @@ public:
int getSize() const override { return sizeof(*this); }
QString getHistoryString() override {
- return QObject::tr("Remove Link in Palette : %1")
+ return QObject::tr("Remove Reference in Palette : %1")
.arg(QString::fromStdWString(m_palette->getPaletteName()));
}
int getHistoryType() override { return HistoryType::Palette; }
@@ -1585,11 +1600,11 @@ public:
/*! remove link from studio palette. Delete the global and the orginal names.
* return true if something changed
*/
-bool TStyleSelection::removeLink() {
+void TStyleSelection::removeLink() {
TPalette *palette = getPalette();
- if (!palette || m_pageIndex < 0) return false;
+ if (!palette || m_pageIndex < 0) return;
int n = m_styleIndicesInPage.size();
- if (n <= 0) return false;
+ if (n <= 0) return;
TPalette::Page *page = palette->getPage(m_pageIndex);
assert(page);
@@ -1614,12 +1629,10 @@ bool TStyleSelection::removeLink() {
}
if (somethingChanged) {
- palette->setDirtyFlag(true);
+ m_paletteHandle->notifyColorStyleChanged(false);
TUndoManager::manager()->add(undo);
} else
delete undo;
-
- return somethingChanged;
}
//=============================================================================
@@ -1781,3 +1794,26 @@ void TStyleSelection::getBackOriginalStyle() {
} else
delete undo;
}
+
+//-----------------------------------------------------------------------------
+/*! return true if there is at least one linked style in the selection
+*/
+
+bool TStyleSelection::hasLinkedStyle() {
+ TPalette *palette = getPalette();
+ if (!palette || m_pageIndex < 0 || isEmpty()) return false;
+ if (m_styleIndicesInPage.size() <= 0) return false;
+
+ TPalette::Page *page = palette->getPage(m_pageIndex);
+ assert(page);
+
+ // for each selected style
+ for (std::set::iterator it = m_styleIndicesInPage.begin();
+ it != m_styleIndicesInPage.end(); ++it) {
+ TColorStyle *cs = page->getStyle(*it);
+ std::wstring gname = cs->getGlobalName();
+ // if the style has link, return true
+ if (gname != L"" && (gname[0] == L'-' || gname[0] == L'+')) return true;
+ }
+ return false;
+}