From 13d911c0f9737759bed36b1b5c46d92fa6ba658a Mon Sep 17 00:00:00 2001 From: kogaki Date: Apr 18 2016 14:21:11 +0000 Subject: Merge pull request #192 from shun-iwasawa/revert_room_feature Reverting room editing feature + Adding menu bar customizing feature --- diff --git a/stuff/profiles/layouts/OpenToonz/layouts.txt b/stuff/profiles/layouts/OpenToonz/layouts.txt new file mode 100644 index 0000000..21ed22c --- /dev/null +++ b/stuff/profiles/layouts/OpenToonz/layouts.txt @@ -0,0 +1,6 @@ +room1.ini +room2.ini +room3.ini +room4.ini +room5.ini +room6.ini diff --git a/stuff/profiles/layouts/OpenToonz/menubar_template.xml b/stuff/profiles/layouts/OpenToonz/menubar_template.xml new file mode 100644 index 0000000..8b96152 --- /dev/null +++ b/stuff/profiles/layouts/OpenToonz/menubar_template.xml @@ -0,0 +1,221 @@ + + + MI_NewScene + MI_LoadScene + MI_SaveScene + MI_SaveSceneAs + MI_OpenRecentScene + MI_RevertScene + + MI_LoadFolder + MI_LoadSubSceneFile + + MI_NewLevel + MI_LoadLevel + MI_SaveLevel + MI_SaveLevelAs + MI_ExportLevel + MI_OpenRecentLevel + + MI_ConvertFileWithInput + + MI_LoadColorModel + + MI_ImportMagpieFile + + MI_NewProject + MI_ProjectSettings + MI_SaveDefaultSettings + + MI_PreviewSettings + MI_Preview + + MI_OutputSettings + MI_Render + + MI_PrintXsheet + MI_Print + + MI_Preferences + MI_ShortcutPopup + + MI_RunScript + MI_OpenScriptConsole + + MI_Quit + MI_ReloadStyle + + + MI_Undo + MI_Redo + + MI_Cut + MI_Copy + MI_Paste + MI_PasteInto + + MI_Clear + MI_Insert + + MI_SelectAll + MI_InvertSelection + + MI_RemoveEndpoints + + MI_Group + MI_Ungroup + MI_EnterGroup + MI_ExitGroup + + MI_BringToFront + MI_BringForward + MI_SendBack + MI_SendBackward + + + MI_DefineScanner + MI_ScanSettings + MI_Scan + MI_SetScanCropbox + MI_ResetScanCropbox + + MI_CleanupSettings + MI_CleanupPreview + MI_CameraTest + MI_Cleanup + + + MI_AddFrames + MI_Renumber + MI_ReplaceLevel + MI_RevertToCleanedUp + MI_RevertToLastSaved + MI_ConvertToVectors + MI_Tracking + + MI_ExposeResource + MI_EditLevel + + MI_LevelSettings + MI_FileInfo + + MI_AdjustLevels + MI_AdjustThickness + MI_Antialias + MI_Binarize + MI_BrightnessAndContrast + MI_CanvasSize + MI_LinesFade + + MI_RemoveUnused + + + MI_SceneSettings + MI_CameraSettings + + MI_OpenChild + MI_CloseChild + MI_SaveSubxsheetAs + MI_Collapse + MI_Resequence + MI_CloneChild + MI_ExplodeChild + + MI_ApplyMatchLines + MI_MergeCmapped + + MI_MergeColumns + MI_DeleteMatchLines + MI_DeleteInk + + MI_InsertFx + MI_NewOutputFx + + MI_InsertSceneFrame + MI_RemoveSceneFrame + MI_InsertGlobalKeyframe + MI_RemoveGlobalKeyframe + + + MI_Reverse + MI_Swing + MI_Random + MI_Increment + MI_Dup + + MI_ResetStep + MI_IncreaseStep + MI_DecreaseStep + MI_Step2 + MI_Step3 + MI_Step4 + MI_Each2 + MI_Each3 + MI_Each4 + MI_Rollup + MI_Rolldown + MI_TimeStretch + + MI_Autorenumber + MI_Duplicate + MI_MergeFrames + MI_CloneLevel + + + MI_ViewCamera + MI_ViewTable + MI_FieldGuide + MI_SafeArea + MI_ViewBBox + MI_ViewColorcard + MI_ViewGuide + MI_ViewRuler + + MI_TCheck + MI_ICheck + MI_Ink1Check + MI_PCheck + MI_IOnly + MI_BCheck + MI_GCheck + MI_ACheck + + MI_ShiftTrace + MI_EditShift + MI_NoShift + MI_ResetShift + + MI_RasterizePli + + MI_Link + + + MI_DockingCheck + + MI_OpenBatchServers + MI_OpenCleanupSettings + MI_OpenColorModel + MI_OpenFileBrowser + MI_OpenFileViewer + MI_OpenFunctionEditor + MI_OpenFilmStrip + MI_OpenPalette + MI_OpenFileBrowser2 + MI_OpenSchematic + MI_OpenStudioPalette + MI_OpenStyleControl + MI_OpenTasks + MI_OpenTMessage + MI_OpenToolbar + MI_OpenToolOptionBar + MI_OpenLevelView + MI_OpenComboViewer + MI_OpenXshView + MI_OpenHistoryPanel + + MI_ResetRoomLayout + + + MI_About + + \ No newline at end of file diff --git a/stuff/profiles/layouts/OpenToonz/room1.ini b/stuff/profiles/layouts/OpenToonz/room1.ini new file mode 100644 index 0000000..9b976c3 --- /dev/null +++ b/stuff/profiles/layouts/OpenToonz/room1.ini @@ -0,0 +1,9 @@ +[room] +pane_0\name=ComboViewer +pane_0\geometry=@Rect(0 0 851 452) +pane_1\name=CleanupSettings +pane_1\geometry=@Rect(859 0 251 611) +pane_2\name=Xsheet +pane_2\geometry=@Rect(0 460 851 151) +hierarchy="-1 0 [ [ 0 2 ] 1 ] " +name=Cleanup diff --git a/stuff/profiles/layouts/OpenToonz/room1_menubar.xml b/stuff/profiles/layouts/OpenToonz/room1_menubar.xml new file mode 100644 index 0000000..13bae22 --- /dev/null +++ b/stuff/profiles/layouts/OpenToonz/room1_menubar.xml @@ -0,0 +1,105 @@ + + + MI_LoadLevel + MI_LoadFolder + MI_SaveLevelAs + MI_ExportLevel + MI_OpenRecentLevel + + MI_LoadScene + MI_SaveScene + MI_SaveSceneAs + MI_OpenRecentScene + MI_RevertScene + + MI_ConvertFileWithInput + + MI_NewScene + + MI_Quit + + + MI_DefineScanner + MI_ScanSettings + MI_Scan + MI_SetScanCropbox + MI_ResetScanCropbox + + + MI_CleanupSettings + + MI_OutputSettings + MI_LevelSettings + + + MI_CameraTest + MI_OpacityCheck + MI_CleanupPreview + MI_Cleanup + + + MI_Undo + MI_Redo + + MI_NextFrame + MI_PrevFrame + MI_FirstFrame + MI_LastFrame + MI_TestAnimation + + MI_Copy + MI_Cut + MI_Paste + MI_PasteInto + + MI_Clear + MI_Insert + MI_SelectAll + MI_InvertSelection + + + MI_OpenFileBrowser + MI_OpenStyleControl + MI_OpenComboViewer + MI_OpenXshView + + + MI_OpenBatchServers + MI_OpenTasks + MI_OpenColorModel + MI_OpenFileViewer + MI_OpenFunctionEditor + MI_OpenFilmStrip + MI_OpenPalette + MI_OpenFileBrowser2 + MI_OpenSchematic + MI_OpenStudioPalette + MI_OpenToolbar + MI_OpenToolOptionBar + MI_OpenHistoryPanel + MI_OpenTMessage + + + + MI_Preferences + MI_ShortcutPopup + MI_SceneSettings + + MI_ViewCamera + MI_ViewTable + MI_FieldGuide + MI_SafeArea + MI_ViewBBox + MI_ViewColorcard + + + MI_DockingCheck + + MI_RunScript + MI_OpenScriptConsole + MI_ReloadStyle + + + MI_About + + \ No newline at end of file diff --git a/stuff/profiles/layouts/OpenToonz/room2.ini b/stuff/profiles/layouts/OpenToonz/room2.ini new file mode 100644 index 0000000..3ecf3f4 --- /dev/null +++ b/stuff/profiles/layouts/OpenToonz/room2.ini @@ -0,0 +1,14 @@ +[room] +pane_0\name=ComboViewer +pane_0\geometry=@Rect(0 0 700 600) +pane_1\name=LevelPalette +pane_1\geometry=@Rect(0 0 100 50) +pane_1\viewtype=2 +pane_2\name=StyleEditor +pane_2\geometry=@Rect(0 0 340 630) +pane_3\name=Xsheet +pane_3\geometry=@Rect(0 0 500 300) +pane_4\name=StudioPalette +pane_4\geometry=@Rect(0 0 100 50) +hierarchy="-1 1 [ [ 2 0 ] [ 4 3 1 ] ] " +name=PltEdit diff --git a/stuff/profiles/layouts/OpenToonz/room2_menubar.xml b/stuff/profiles/layouts/OpenToonz/room2_menubar.xml new file mode 100644 index 0000000..d503306 --- /dev/null +++ b/stuff/profiles/layouts/OpenToonz/room2_menubar.xml @@ -0,0 +1,143 @@ + + + MI_LoadLevel + MI_LoadFolder + MI_SaveLevel + MI_SaveLevelAs + MI_ExportLevel + MI_OpenRecentLevel + MI_LevelSettings + + MI_NewLevel + + MI_OverwritePalette + MI_SavePaletteAs + + MI_LoadScene + MI_SaveScene + MI_SaveSceneAs + MI_OpenRecentScene + MI_RevertScene + + MI_ConvertFileWithInput + + MI_NewScene + + MI_Quit + + + T_StylePicker + T_RGBPicker + T_Tape + + T_Fill + T_Brush + T_PaintBrush + T_Geometric + T_Type + + T_Eraser + + T_Edit + T_Selection + + T_ControlPointEditor + T_Pinch + T_Pump + T_Magnet + T_Bender + T_Iron + T_Cutter + + T_Skeleton + T_Tracker + T_Hook + T_Plastic + + T_Zoom + T_Rotate + T_Hand + + + + MI_Undo + MI_Redo + + MI_NextFrame + MI_PrevFrame + MI_FirstFrame + MI_LastFrame + MI_TestAnimation + + MI_Copy + MI_Cut + MI_Paste + MI_PasteInto + + MI_Clear + MI_Insert + MI_SelectAll + MI_InvertSelection + + + MI_TCheck + MI_BCheck + MI_ICheck + MI_Ink1Check + MI_PCheck + + + MI_PreviewSettings + MI_Preview + MI_SavePreviewedFrames + + MI_OutputSettings + MI_Render + + + MI_OpenFileBrowser + MI_OpenFileViewer + MI_OpenFilmStrip + MI_OpenPalette + MI_OpenStudioPalette + MI_OpenStyleControl + MI_OpenLevelView + MI_OpenComboViewer + MI_OpenXshView + + + MI_OpenBatchServers + MI_OpenColorModel + MI_OpenFunctionEditor + MI_OpenFileBrowser2 + MI_OpenSchematic + MI_OpenTasks + MI_OpenToolbar + MI_OpenToolOptionBar + MI_OpenHistoryPanel + MI_OpenTMessage + + + + MI_Preferences + MI_ShortcutPopup + MI_SceneSettings + + + MI_ViewCamera + MI_ViewTable + MI_FieldGuide + MI_SafeArea + MI_ViewColorcard + + + MI_DockingCheck + + MI_RunScript + MI_OpenScriptConsole + MI_ReloadStyle + + + MI_About + + \ No newline at end of file diff --git a/stuff/profiles/layouts/OpenToonz/room3.ini b/stuff/profiles/layouts/OpenToonz/room3.ini new file mode 100644 index 0000000..a82ba30 --- /dev/null +++ b/stuff/profiles/layouts/OpenToonz/room3.ini @@ -0,0 +1,10 @@ +[room] +pane_0\name=ComboViewer +pane_0\geometry=@Rect(0 0 700 600) +pane_1\name=LevelPalette +pane_1\geometry=@Rect(0 0 100 50) +pane_1\viewtype=2 +pane_2\name=FilmStrip +pane_2\geometry=@Rect(0 0 201 50) +hierarchy="-1 1 [ [ 0 2 ] 1 ] " +name=InknPaint diff --git a/stuff/profiles/layouts/OpenToonz/room3_menubar.xml b/stuff/profiles/layouts/OpenToonz/room3_menubar.xml new file mode 100644 index 0000000..6b15f61 --- /dev/null +++ b/stuff/profiles/layouts/OpenToonz/room3_menubar.xml @@ -0,0 +1,153 @@ + + + MI_LoadLevel + MI_LoadFolder + MI_SaveLevel + MI_SaveLevelAs + MI_OpenRecentLevel + MI_ExportLevel + MI_LevelSettings + MI_CanvasSize + + MI_NewLevel + + MI_OverwritePalette + MI_SavePaletteAs + + MI_LoadColorModel + + MI_ApplyMatchLines + MI_DeleteMatchLines + MI_DeleteInk + MI_MergeCmapped + MI_MergeColumns + + MI_LoadScene + MI_SaveScene + MI_SaveSceneAs + MI_OpenRecentScene + + MI_NewScene + + MI_Quit + + + T_StylePicker + T_RGBPicker + T_Tape + + T_Fill + T_Brush + T_PaintBrush + T_Geometric + T_Type + + T_Eraser + + + T_Edit + T_Selection + + T_ControlPointEditor + T_Pinch + T_Pump + T_Magnet + T_Bender + T_Iron + T_Cutter + + T_Skeleton + T_Tracker + T_Hook + T_Plastic + + T_Zoom + T_Rotate + T_Hand + + + + MI_ShiftTrace + MI_EditShift + MI_NoShift + MI_ResetShift + + MI_RasterizePli + + + MI_Undo + MI_Redo + + MI_NextFrame + MI_PrevFrame + MI_FirstFrame + MI_LastFrame + MI_TestAnimation + + MI_Copy + MI_Cut + MI_Paste + MI_PasteInto + + MI_Clear + MI_Insert + MI_SelectAll + MI_InvertSelection + + + MI_TCheck + MI_BCheck + MI_ICheck + MI_Ink1Check + MI_PCheck + MI_GCheck + MI_ACheck + MI_IOnly + + + MI_OpenStyleControl + MI_OpenPltGizmo + MI_OpenPalette + MI_OpenStudioPalette + MI_OpenComboViewer + MI_OpenXshView + MI_OpenColorModel + MI_OpenFileBrowser + MI_OpenFilmStrip + MI_OpenToolbar + MI_OpenToolOptionBar + + + MI_OpenBatchServers + MI_OpenFileViewer + MI_OpenFunctionEditor + MI_OpenFileBrowser2 + MI_OpenSchematic + MI_OpenTasks + MI_OpenHistoryPanel + MI_OpenTMessage + + + + MI_Preferences + MI_ShortcutPopup + MI_SceneSettings + + + MI_ViewCamera + MI_ViewTable + MI_FieldGuide + MI_SafeArea + MI_ViewColorcard + + + MI_DockingCheck + + MI_RunScript + MI_OpenScriptConsole + MI_ReloadStyle + + + MI_About + + \ No newline at end of file diff --git a/stuff/profiles/layouts/OpenToonz/room4.ini b/stuff/profiles/layouts/OpenToonz/room4.ini new file mode 100644 index 0000000..97e1552 --- /dev/null +++ b/stuff/profiles/layouts/OpenToonz/room4.ini @@ -0,0 +1,7 @@ +[room] +pane_0\name=Xsheet +pane_0\geometry=@Rect(0 0 500 300) +pane_1\name=FunctionEditor +pane_1\geometry=@Rect(0 0 100 50) +hierarchy="-1 0 [ 0 1 ] " +name=Xsheet diff --git a/stuff/profiles/layouts/OpenToonz/room4_menubar.xml b/stuff/profiles/layouts/OpenToonz/room4_menubar.xml new file mode 100644 index 0000000..b37b517 --- /dev/null +++ b/stuff/profiles/layouts/OpenToonz/room4_menubar.xml @@ -0,0 +1,156 @@ + + + MI_LoadScene + MI_SaveScene + MI_SaveSceneAs + MI_OpenRecentScene + MI_RevertScene + + MI_NewScene + + MI_PrintXsheet + MI_Export + + MI_Quit + + + MI_OpenChild + MI_CloseChild + MI_Collapse + MI_Resequence + MI_SaveSubxsheetAs + MI_LoadSubSceneFile + MI_CloneChild + MI_ExplodeChild + + + MI_LoadLevel + MI_LoadFolder + MI_SaveLevel + MI_SaveLevelAs + MI_ExportLevel + MI_OpenRecentLevel + MI_LevelSettings + MI_CanvasSize + + MI_NewLevel + + MI_ViewFile + MI_FileInfo + + MI_CloneLevel + MI_ReplaceLevel + + MI_AddFrames + MI_Renumber + MI_RevertToCleanedUp + MI_ConvertToVectors + MI_ConvertFileWithInput + MI_Tracking + MI_ExposeResource + MI_EditLevel + MI_RemoveUnused + + + MI_Dup + MI_Reverse + MI_Rollup + MI_Rolldown + MI_Swing + MI_Random + MI_TimeStretch + + + MI_Reframe1 + MI_Reframe2 + MI_Reframe3 + MI_Reframe4 + + + MI_Step2 + MI_Step3 + MI_Step4 + + + MI_Each2 + MI_Each3 + MI_Each4 + + + + MI_Undo + MI_Redo + + MI_Copy + MI_Cut + MI_Paste + MI_PasteInto + + MI_Clear + MI_Insert + MI_SelectAll + MI_InvertSelection + + MI_InsertSceneFrame + MI_RemoveSceneFrame + MI_InsertGlobalKeyframe + MI_RemoveGlobalKeyframe + + + MI_PreviewSettings + MI_Preview + MI_SavePreviewedFrames + + MI_OutputSettings + MI_Render + + MI_Link + + + MI_OpenSchematic + MI_OpenComboViewer + MI_OpenFileBrowser + MI_OpenFunctionEditor + MI_OpenFileViewer + MI_OpenFilmStrip + MI_OpenLevelView + MI_OpenXshView + + + MI_OpenBatchServers + MI_OpenColorModel + MI_OpenPalette + MI_OpenFileBrowser2 + MI_OpenStudioPalette + MI_OpenStyleControl + MI_OpenTasks + MI_OpenToolbar + MI_OpenToolOptionBar + MI_OpenHistoryPanel + MI_OpenTMessage + + + + MI_Preferences + MI_ShortcutPopup + MI_SceneSettings + + + MI_ViewCamera + MI_ViewTable + MI_FieldGuide + MI_SafeArea + MI_ViewBBox + MI_ViewColorcard + + + MI_DockingCheck + + MI_RunScript + MI_OpenScriptConsole + MI_ReloadStyle + + + MI_About + + \ No newline at end of file diff --git a/stuff/profiles/layouts/OpenToonz/room5.ini b/stuff/profiles/layouts/OpenToonz/room5.ini new file mode 100644 index 0000000..c428f02 --- /dev/null +++ b/stuff/profiles/layouts/OpenToonz/room5.ini @@ -0,0 +1,7 @@ +[room] +pane_0\name=Tasks +pane_0\geometry=@Rect(0 0 100 50) +pane_1\name=BatchServers +pane_1\geometry=@Rect(0 0 100 50) +hierarchy="-1 0 [ 0 1 ] " +name=Batches diff --git a/stuff/profiles/layouts/OpenToonz/room5_menubar.xml b/stuff/profiles/layouts/OpenToonz/room5_menubar.xml new file mode 100644 index 0000000..67f381e --- /dev/null +++ b/stuff/profiles/layouts/OpenToonz/room5_menubar.xml @@ -0,0 +1,23 @@ + + + MI_Quit + + + MI_OpenFileBrowser + MI_OpenBatchServers + MI_OpenTasks + + + MI_Preferences + MI_ShortcutPopup + + MI_DockingCheck + + "MI_RunScript" + "MI_OpenScriptConsole" + "MI_ReloadStyle" + + + MI_About + + \ No newline at end of file diff --git a/stuff/profiles/layouts/OpenToonz/room6.ini b/stuff/profiles/layouts/OpenToonz/room6.ini new file mode 100644 index 0000000..b2ee247 --- /dev/null +++ b/stuff/profiles/layouts/OpenToonz/room6.ini @@ -0,0 +1,7 @@ +[room] +pane_0\name=Browser +pane_0\geometry=@Rect(0 0 100 50) +pane_1\name=SceneCast +pane_1\geometry=@Rect(0 0 100 50) +hierarchy="-1 1 [ 0 1 ] " +name=Browser diff --git a/stuff/profiles/layouts/OpenToonz/room6_menubar.xml b/stuff/profiles/layouts/OpenToonz/room6_menubar.xml new file mode 100644 index 0000000..46eab24 --- /dev/null +++ b/stuff/profiles/layouts/OpenToonz/room6_menubar.xml @@ -0,0 +1,22 @@ + + + MI_NewProject + MI_ProjectSettings + MI_SaveDefaultSettings + + MI_Quit + + + MI_Preferences + MI_ShortcutPopup + + MI_DockingCheck + + "MI_RunScript" + "MI_OpenScriptConsole" + "MI_ReloadStyle" + + + MI_About + + \ No newline at end of file diff --git a/toonz/sources/include/toonzqt/menubarcommand.h b/toonz/sources/include/toonzqt/menubarcommand.h index 8bb6e9b..8891923 100644 --- a/toonz/sources/include/toonzqt/menubarcommand.h +++ b/toonz/sources/include/toonzqt/menubarcommand.h @@ -170,6 +170,8 @@ public: // use setToggleTexts for toggle commands that have two names according to the current status. e.g. show/hide something void setToggleTexts(CommandId id, const QString &onText, const QString &offText); + + std::string getIdFromAction(QAction* action); }; //----------------------------------------------------------------------------- diff --git a/toonz/sources/toonz/CMakeLists.txt b/toonz/sources/toonz/CMakeLists.txt index 97776f3..ba14c23 100644 --- a/toonz/sources/toonz/CMakeLists.txt +++ b/toonz/sources/toonz/CMakeLists.txt @@ -72,6 +72,7 @@ set(MOC_HEADERS mainwindow.h matchline.h menubar.h + menubarpopup.h menubarcommandids.h meshifypopup.h messagepanel.h @@ -159,6 +160,7 @@ set(SOURCES mainwindow.cpp matchline.cpp menubar.cpp + menubarpopup.cpp mergecolumns.cpp moviegenerator.cpp pane.cpp diff --git a/toonz/sources/toonz/mainwindow.cpp b/toonz/sources/toonz/mainwindow.cpp index 45d42ef..a38fcb9 100644 --- a/toonz/sources/toonz/mainwindow.cpp +++ b/toonz/sources/toonz/mainwindow.cpp @@ -176,6 +176,7 @@ void makePrivate(Room *room) { TFilePath layoutDir = ToonzFolder::getMyModuleDir(); TFilePath roomPath = room->getPath(); + std::string mbSrcFileName = roomPath.getName() + "_menubar.xml"; if (roomPath == TFilePath() || roomPath.getParentDir() != layoutDir) { int count = 1; for (;;) { @@ -187,6 +188,23 @@ void makePrivate(Room *room) TSystem::touchParentDir(roomPath); room->save(); } + /*- create private menubar settings if not exists -*/ + std::string mbDstFileName = roomPath.getName() + "_menubar.xml"; + TFilePath myMBPath = layoutDir + mbDstFileName; + if (!TFileStatus(myMBPath).isReadable()) + { + TFilePath templateRoomMBPath = ToonzFolder::getTemplateModuleDir() + mbSrcFileName; + if (TFileStatus(templateRoomMBPath).doesExist()) + TSystem::copyFile(myMBPath, templateRoomMBPath); + else + { + TFilePath templateFullMBPath = ToonzFolder::getTemplateModuleDir() + "menubar_template.xml"; + if (TFileStatus(templateFullMBPath).doesExist()) + TSystem::copyFile(myMBPath, templateFullMBPath); + else + DVGui::MsgBox(WARNING, QObject::tr("Cannot open menubar settings template file. Re-installing Toonz will solve this problem.")); + } + } } //----------------------------------------------------------------------------- @@ -370,10 +388,10 @@ MainWindow::MainWindow(const QString &argumentLayoutFileName, QWidget *parent, Q changeWindowTitle(); //Connetto i comandi che sono in RoomTabWidget - //connect(roomTabWidget, SIGNAL(indexSwapped(int , int )), SLOT(onIndexSwapped(int ,int ))); - //connect(roomTabWidget, SIGNAL(insertNewTabRoom()), SLOT(insertNewRoom())); - //connect(roomTabWidget, SIGNAL(deleteTabRoom(int)), SLOT(deleteRoom(int))); - //connect(roomTabWidget, SIGNAL(renameTabRoom(int, const QString)), SLOT(renameRoom(int, const QString))); + connect(roomTabWidget, SIGNAL(indexSwapped(int , int )), SLOT(onIndexSwapped(int ,int ))); + connect(roomTabWidget, SIGNAL(insertNewTabRoom()), SLOT(insertNewRoom())); + connect(roomTabWidget, SIGNAL(deleteTabRoom(int)), SLOT(deleteRoom(int))); + connect(roomTabWidget, SIGNAL(renameTabRoom(int, const QString)), SLOT(renameRoom(int, const QString))); setCommandHandler("MI_Quit", this, &MainWindow::onQuit); setCommandHandler("MI_Undo", this, &MainWindow::onUndo); @@ -518,7 +536,9 @@ void MainWindow::readSettings(const QString &argumentLayoutFileName) m_stackedWidget->addWidget(room); roomTabWidget->addTab(room->getName()); - stackedMenuBar->createMenuBarByName(room->getName()); + /*- ここでMenuBarファイルをロードする -*/ + std::string mbFileName = roomPath.getName() + "_menubar.xml"; + stackedMenuBar->loadAndAddMenubar(ToonzFolder::getModuleFile(mbFileName)); //room->setDockOptions(QMainWindow::DockOptions( // (QMainWindow::AnimatedDocks | QMainWindow::AllowNestedDocks) & ~QMainWindow::AllowTabbedDocks)); @@ -529,6 +549,7 @@ void MainWindow::readSettings(const QString &argumentLayoutFileName) //Read the flipbook history FlipBookPool::instance()->load(ToonzFolder::getMyModuleDir() + TFilePath("fliphistory.ini")); + /*- レイアウト設定ファイルが見つからなかった場合、初期Roomの生成 -*/ //Se leggendo i settings non ho inizializzato le stanze lo faccio ora. // Puo' accadere se si buttano i file di inizializzazione. if (rooms.empty()) { @@ -567,11 +588,12 @@ void MainWindow::readSettings(const QString &argumentLayoutFileName) m_stackedWidget->addWidget(browserRoom); rooms.push_back(browserRoom); stackedMenuBar->createMenuBarByName(browserRoom->getName()); - - makePrivate(rooms); - writeRoomList(rooms); } + /*- If the layout files were loaded from template, then save them as private ones -*/ + makePrivate(rooms); + writeRoomList(rooms); + // Imposto la stanza corrente fp = ToonzFolder::getModuleFile(currentRoomFileName); Tifstream is(fp); @@ -651,6 +673,7 @@ void MainWindow::writeSettings() rooms.push_back(room); room->save(); } + writeRoomList(rooms); //Current room settings Tofstream os(ToonzFolder::getMyModuleDir() + currentRoomFileName); @@ -1123,6 +1146,11 @@ void MainWindow::deleteRoom(int index) return; } + /*- delete menubar settings file as well -*/ + std::string mbFileName = fp.getName() + "_menubar.xml"; + TFilePath mbFp = fp.getParentDir() + mbFileName; + TSystem::deleteFile(mbFp); + //The old room index must be updated if index < of it if (index < m_oldRoomIndex) m_oldRoomIndex--; diff --git a/toonz/sources/toonz/menubar.cpp b/toonz/sources/toonz/menubar.cpp index be8b84f..866880f 100644 --- a/toonz/sources/toonz/menubar.cpp +++ b/toonz/sources/toonz/menubar.cpp @@ -6,11 +6,14 @@ #include "menubarcommandids.h" #include "tapp.h" #include "cellselection.h" +#include "mainwindow.h" +#include "menubarpopup.h" // TnzQt includes #include "toonzqt/tselectionhandle.h" #include "toonzqt/dvdialog.h" #include "toonzqt/menubarcommand.h" +#include "toonzqt/gutil.h" // TnzLib includes #include "toonz/toonzscene.h" @@ -19,6 +22,7 @@ #include "toonz/txsheethandle.h" #include "toonz/tframehandle.h" #include "toonz/tcolumnhandle.h" +#include "toonz/toonzfolders.h" // TnzTools includes #include "tools/toolcommandids.h" @@ -28,6 +32,7 @@ // TnzCore includes #include "tconvert.h" +#include "tsystem.h" // Qt includes #include @@ -37,6 +42,9 @@ #include #include #include +#include +#include +#include void UrlOpener::open() { @@ -46,6 +54,178 @@ void UrlOpener::open() UrlOpener dvHome(QUrl("http://www.toonz.com/")); UrlOpener manual(QUrl("file:///C:/gmt/butta/M&C in EU.pdf")); +TEnv::IntVar LockRoomTabToggle("LockRoomTabToggle", 0); + +//============================================================================= +// RoomTabWidget +//----------------------------------------------------------------------------- + +RoomTabWidget::RoomTabWidget(QWidget *parent) + : QTabBar(parent) + , m_clickedTabIndex(-1) + , m_tabToDeleteIndex(-1) + , m_renameTabIndex(-1) + , m_renameTextField(new DVGui::LineEdit(this)) + , m_isLocked( LockRoomTabToggle != 0 ) +{ + m_renameTextField->hide(); + connect(m_renameTextField, SIGNAL(editingFinished()), this, SLOT(updateTabName())); +} + +//----------------------------------------------------------------------------- + +RoomTabWidget::~RoomTabWidget() +{ +} + +//----------------------------------------------------------------------------- + +void RoomTabWidget::swapIndex(int firstIndex, int secondIndex) +{ + QString firstText = tabText(firstIndex); + removeTab(firstIndex); + insertTab(secondIndex, firstText); + emit indexSwapped(firstIndex, secondIndex); + + setCurrentIndex(secondIndex); +} + +//----------------------------------------------------------------------------- + +void RoomTabWidget::mousePressEvent(QMouseEvent *event) +{ + m_renameTextField->hide(); + if (event->button() == Qt::LeftButton) + { + m_clickedTabIndex = tabAt(event->pos()); + if (m_clickedTabIndex<0) return; + setCurrentIndex(m_clickedTabIndex); + } +} + +//----------------------------------------------------------------------------- + +void RoomTabWidget::mouseMoveEvent(QMouseEvent *event) +{ + if (m_isLocked) return; + if (event->buttons()) + { + int tabIndex = tabAt(event->pos()); + if (tabIndex == m_clickedTabIndex || + tabIndex<0 || tabIndex >= count() || + m_clickedTabIndex<0) + return; + swapIndex(m_clickedTabIndex, tabIndex); + m_clickedTabIndex = tabIndex; + } +} + +//----------------------------------------------------------------------------- + +void RoomTabWidget::mouseReleaseEvent(QMouseEvent *event) +{ + m_clickedTabIndex = -1; +} + +//----------------------------------------------------------------------------- +/*! Set a text field with focus in event position to edit tab name. +*/ +void RoomTabWidget::mouseDoubleClickEvent(QMouseEvent * event) +{ + if (m_isLocked) return; + int index = tabAt(event->pos()); + if (index<0) return; + m_renameTabIndex = index; + DVGui::LineEdit *fld = m_renameTextField; + fld->setText(tabText(index)); + fld->setGeometry(tabRect(index)); + fld->show(); + fld->selectAll(); + fld->setFocus(Qt::OtherFocusReason); +} + +//----------------------------------------------------------------------------- + +void RoomTabWidget::contextMenuEvent(QContextMenuEvent *event) +{ + if (m_isLocked) return; + m_tabToDeleteIndex = -1; + QMenu *menu = new QMenu(this); + QAction* newRoom = menu->addAction(tr("New Room")); + connect(newRoom, SIGNAL(triggered()), SLOT(addNewTab())); + + int index = tabAt(event->pos()); + if (index >= 0) + { + m_tabToDeleteIndex = index; + if (index != currentIndex()) + { + QAction* deleteRoom = menu->addAction(tr("Delete Room \"%1\"").arg(tabText(index))); + connect(deleteRoom, SIGNAL(triggered()), SLOT(deleteTab())); + } +#if defined(_WIN32) || defined(_CYGWIN_) + /*- customize menubar -*/ + QAction* customizeMenuBar = menu->addAction(tr("Customize Menu Bar of Room \"%1\"").arg(tabText(index))); + connect(customizeMenuBar, SIGNAL(triggered()), SLOT(onCustomizeMenuBar())); +#endif + } + menu->exec(event->globalPos()); +} + +//----------------------------------------------------------------------------- + +void RoomTabWidget::updateTabName() +{ + int index = m_renameTabIndex; + if (index<0) return; + m_renameTabIndex = -1; + QString newName = m_renameTextField->text(); + setTabText(index, newName); + m_renameTextField->hide(); + emit renameTabRoom(index, newName); +} + +//----------------------------------------------------------------------------- + +void RoomTabWidget::addNewTab() +{ + insertTab(0, tr("Room")); + emit insertNewTabRoom(); +} + +//----------------------------------------------------------------------------- + +void RoomTabWidget::deleteTab() +{ + assert(m_tabToDeleteIndex != -1); + + QString question(tr("Are you sure you want to remove room %1").arg(tabText(m_tabToDeleteIndex))); + int ret = DVGui::MsgBox(question, QObject::tr("Yes"), QObject::tr("No")); + if (ret == 0 || ret == 2) return; + + emit deleteTabRoom(m_tabToDeleteIndex); + removeTab(m_tabToDeleteIndex); + m_tabToDeleteIndex = -1; +} + +//----------------------------------------------------------------------------- + +void RoomTabWidget::setIsLocked(bool lock) +{ + m_isLocked = lock; + LockRoomTabToggle = (lock) ? 1 : 0; +} + +//----------------------------------------------------------------------------- + +void RoomTabWidget::onCustomizeMenuBar() +{ + /*- use m_tabToDeleteIndex for index of a room of which menubar is to be customized -*/ + assert(m_tabToDeleteIndex != -1); + + emit customizeMenuBar(m_tabToDeleteIndex); +} + //============================================================================= // StackedMenuBar //----------------------------------------------------------------------------- @@ -63,31 +243,154 @@ void StackedMenuBar::createMenuBarByName(const QString &roomName) std::cout << "create " << roomName.toStdString() << std::endl; #if defined(_WIN32) || defined(_CYGWIN_) if (roomName == "Cleanup") - createCleanupMenuBar(); + addWidget(createCleanupMenuBar()); else if (roomName == "PltEdit") - createPltEditMenuBar(); + addWidget(createPltEditMenuBar()); else if (roomName == "InknPaint") - createInknPaintMenuBar(); + addWidget(createInknPaintMenuBar()); else if (roomName == "Xsheet" || roomName == "Schematic" || roomName == "QAR" || roomName == "Flip") - createXsheetMenuBar(); + addWidget(createXsheetMenuBar()); else if (roomName == "Batches") - createBatchesMenuBar(); + addWidget(createBatchesMenuBar()); else if (roomName == "Browser") - createBrowserMenuBar(); + addWidget(createBrowserMenuBar()); else /*-- どれにもあてはまらない場合は全てのコマンドの入ったメニューバーを作る --*/ - createFullMenuBar(); + addWidget(createFullMenuBar()); +#else + /* OSX では stacked menu が動いていないのでとりあえず full のみ作成する */ + addWidget(createFullMenuBar()); +#endif +} + +//--------------------------------------------------------------------------------- + +void StackedMenuBar::loadAndAddMenubar(const TFilePath & fp) +{ +#if defined(_WIN32) || defined(_CYGWIN_) + QMenuBar* menuBar = loadMenuBar(fp); + if (menuBar) + addWidget(menuBar); + else + addWidget(createFullMenuBar()); #else /* OSX では stacked menu が動いていないのでとりあえず full のみ作成する */ - createFullMenuBar(); + addWidget(createFullMenuBar()); #endif } //--------------------------------------------------------------------------------- -void StackedMenuBar::createCleanupMenuBar() +QMenuBar* StackedMenuBar::loadMenuBar(const TFilePath & fp) { - QMenuBar *cleanupMenuBar; - cleanupMenuBar = new QMenuBar(this); + + QFile file(toQString(fp)); + if (!file.open(QFile::ReadOnly | QFile::Text)){ + qDebug() << "Cannot read file" << file.errorString(); + return 0; + } + + QXmlStreamReader reader(&file); + + QMenuBar* menuBar = new QMenuBar(this); + if (reader.readNextStartElement()) + { + if (reader.name() == "menubar") + { + while (reader.readNextStartElement()) + { + if (reader.name() == "menu") + { + QString title = reader.attributes().value("title").toString(); + /*- Menu title will be translated if the title is registered in translation file -*/ + QMenu* menu = new QMenu(tr(title.toStdString().c_str())); + + if (readMenuRecursive(reader, menu)) + menuBar->addMenu(menu); + else + { + reader.raiseError(tr("Failed to load menu %1").arg(title)); + delete menu; + } + + } + else if (reader.name() == "command") + { + QString cmdName = reader.readElementText(); + + QAction *action = CommandManager::instance()->getAction(cmdName.toStdString().c_str()); + if (action) + menuBar->addAction(action); + else + reader.raiseError(tr("Failed to add command %1").arg(cmdName)); + } + else + reader.skipCurrentElement(); + } + } + else + reader.raiseError(QObject::tr("Incorrect file")); + } + + if (reader.hasError()) + { + delete menuBar; + return 0; + } + return menuBar; +} + +//--------------------------------------------------------------------------------- + +bool StackedMenuBar::readMenuRecursive( QXmlStreamReader& reader, QMenu* menu) +{ + while (reader.readNextStartElement()) + { + if (reader.name() == "menu") + { + QString title = reader.attributes().value("title").toString(); + QMenu* subMenu = new QMenu(tr(title.toStdString().c_str())); + + if (readMenuRecursive(reader, subMenu)) + menu->addMenu(subMenu); + else + { + reader.raiseError(tr("Failed to load menu %1").arg(title)); + delete subMenu; + return false; + } + + } + else if (reader.name() == "command") + { + QString cmdName = reader.readElementText(); + addMenuItem(menu, cmdName.toStdString().c_str()); + } + else if (reader.name() == "command_debug") + { +#ifndef NDEBUG + QString cmdName = reader.readElementText(); + addMenuItem(menu, cmdName.toStdString().c_str()); +#else + reader.skipCurrentElement(); +#endif + } + else if (reader.name() == "separator") + { + menu->addSeparator(); + reader.skipCurrentElement(); + } + else + reader.skipCurrentElement(); + } + + return !reader.hasError(); +} + +//--------------------------------------------------------------------------------- + +QMenuBar* StackedMenuBar::createCleanupMenuBar() +{ + QMenuBar *cleanupMenuBar = new QMenuBar(this); //----Files Menu QMenu *filesMenu = addMenu(tr("Files"), cleanupMenuBar); addMenuItem(filesMenu, MI_LoadLevel); @@ -205,15 +508,14 @@ void StackedMenuBar::createCleanupMenuBar() QMenu *helpMenu = addMenu(tr("Help"), cleanupMenuBar); addMenuItem(helpMenu, MI_About); - addWidget(cleanupMenuBar); + return cleanupMenuBar; } //--------------------------------------------------------------------------------- -void StackedMenuBar::createPltEditMenuBar() +QMenuBar* StackedMenuBar::createPltEditMenuBar() { - QMenuBar *pltEditMenuBar; - pltEditMenuBar = new QMenuBar(this); + QMenuBar *pltEditMenuBar = new QMenuBar(this); //---Files Menu QMenu *filesMenu = addMenu(tr("Files"), pltEditMenuBar); @@ -369,15 +671,14 @@ void StackedMenuBar::createPltEditMenuBar() QMenu *helpMenu = addMenu(tr("Help"), pltEditMenuBar); addMenuItem(helpMenu, MI_About); - addWidget(pltEditMenuBar); + return pltEditMenuBar; } //--------------------------------------------------------------------------------- -void StackedMenuBar::createInknPaintMenuBar() +QMenuBar* StackedMenuBar::createInknPaintMenuBar() { - QMenuBar *inknPaintMenuBar; - inknPaintMenuBar = new QMenuBar(this); + QMenuBar *inknPaintMenuBar = new QMenuBar(this); //---Files Menu QMenu *filesMenu = addMenu(tr("Files"), inknPaintMenuBar); @@ -543,15 +844,14 @@ void StackedMenuBar::createInknPaintMenuBar() QMenu *helpMenu = addMenu(tr("Help"), inknPaintMenuBar); addMenuItem(helpMenu, MI_About); - addWidget(inknPaintMenuBar); + return inknPaintMenuBar; } //--------------------------------------------------------------------------------- -void StackedMenuBar::createXsheetMenuBar() +QMenuBar* StackedMenuBar::createXsheetMenuBar() { - QMenuBar *xsheetMenuBar; - xsheetMenuBar = new QMenuBar(this); + QMenuBar *xsheetMenuBar = new QMenuBar(this); //----Xsheet Menu QMenu *xsheetMenu = addMenu(tr("Xsheet"), xsheetMenuBar); addMenuItem(xsheetMenu, MI_LoadScene); @@ -722,15 +1022,14 @@ void StackedMenuBar::createXsheetMenuBar() QMenu *helpMenu = addMenu(tr("Help"), xsheetMenuBar); addMenuItem(helpMenu, MI_About); - addWidget(xsheetMenuBar); + return xsheetMenuBar; } //--------------------------------------------------------------------------------- -void StackedMenuBar::createBatchesMenuBar() +QMenuBar* StackedMenuBar::createBatchesMenuBar() { - QMenuBar *batchesMenuBar; - batchesMenuBar = new QMenuBar(this); + QMenuBar *batchesMenuBar = new QMenuBar(this); //---Files Menu QMenu *filesMenu = addMenu(tr("Files"), batchesMenuBar); @@ -759,15 +1058,14 @@ void StackedMenuBar::createBatchesMenuBar() QMenu *helpMenu = addMenu(tr("Help"), batchesMenuBar); addMenuItem(helpMenu, MI_About); - addWidget(batchesMenuBar); + return batchesMenuBar; } //--------------------------------------------------------------------------------- -void StackedMenuBar::createBrowserMenuBar() +QMenuBar* StackedMenuBar::createBrowserMenuBar() { - QMenuBar *browserMenuBar; - browserMenuBar = new QMenuBar(this); + QMenuBar * browserMenuBar = new QMenuBar(this); //---Files Menu QMenu *filesMenu = addMenu(tr("Files"), browserMenuBar); @@ -798,12 +1096,12 @@ void StackedMenuBar::createBrowserMenuBar() QMenu *helpMenu = addMenu(tr("Help"), browserMenuBar); addMenuItem(helpMenu, MI_About); - addWidget(browserMenuBar); + return browserMenuBar; } //--------------------------------------------------------------------------------- -void StackedMenuBar::createFullMenuBar() +QMenuBar* StackedMenuBar::createFullMenuBar() { QMenuBar *fullMenuBar = new QMenuBar(this); //Menu' FILE @@ -1083,7 +1381,7 @@ void StackedMenuBar::createFullMenuBar() QMenu *helpMenu = addMenu(tr("Help"), fullMenuBar); addMenuItem(helpMenu, MI_About); - addWidget(fullMenuBar); + return fullMenuBar; } //----------------------------------------------------------------------------- @@ -1106,6 +1404,71 @@ void StackedMenuBar::addMenuItem(QMenu *menu, const char *cmdId) menu->addAction(action); } +//----------------------------------------------------------------------------- + +void StackedMenuBar::onIndexSwapped(int firstIndex, int secondIndex) +{ + assert(firstIndex >= 0 && secondIndex >= 0); + QWidget* menuBar = widget(firstIndex); + removeWidget(menuBar); + insertWidget(secondIndex, menuBar); +} + +//----------------------------------------------------------------------------- + +void StackedMenuBar::insertNewMenuBar() +{ + insertWidget(0, createFullMenuBar()); +} + +//----------------------------------------------------------------------------- + +void StackedMenuBar::deleteMenuBar(int index) +{ + QWidget* menuBar = widget(index); + removeWidget(menuBar); + delete menuBar; +} + +//----------------------------------------------------------------------------- + +void StackedMenuBar::doCustomizeMenuBar(int index) +{ + MainWindow* mainWin = dynamic_cast(TApp::instance()->getMainWindow()); + assert(mainWin); + Room* room = mainWin->getRoom(index); + if (!room) return; + + MenuBarPopup mbPopup(room); + + if (mbPopup.exec()) + { + /*- OKが押され、roomname_menubar.xmlが更新された状態 -*/ + /*- xmlファイルからメニューバーを作り直して格納 -*/ + std::string mbFileName = room->getPath().getName() + "_menubar.xml"; + TFilePath mbPath = ToonzFolder::getMyModuleDir() + mbFileName; + if (!TFileStatus(mbPath).isReadable()) + { + DVGui::MsgBox(WARNING, tr("Cannot open menubar settings file %1").arg(QString::fromStdString(mbFileName))); + return; + } + QMenuBar* newMenu = loadMenuBar(mbPath); + if (!newMenu) + { + DVGui::MsgBox(WARNING, tr("Failed to create menubar")); + return; + } + + QWidget* oldMenu = widget(index); + removeWidget(oldMenu); + insertWidget(index, newMenu); + delete oldMenu; + + setCurrentIndex(index); + } +} + + //============================================================================= // DvTopBar //----------------------------------------------------------------------------- @@ -1119,12 +1482,16 @@ TopBar::TopBar(QWidget *parent) setObjectName("TopBar"); m_containerFrame = new QFrame(this); - m_roomTabBar = new QTabBar(this); + m_roomTabBar = new RoomTabWidget(this); m_stackedMenuBar = new StackedMenuBar(this); + m_lockRoomCB = new QCheckBox(this); m_containerFrame->setObjectName("TopBarTabContainer"); m_roomTabBar->setObjectName("TopBarTab"); m_roomTabBar->setDrawBase(false); + m_lockRoomCB->setObjectName("EditToolLockButton"); + m_lockRoomCB->setToolTip(tr("Lock Rooms Tab")); + m_lockRoomCB->setChecked(m_roomTabBar->isLocked()); QHBoxLayout *mainLayout = new QHBoxLayout(); mainLayout->setSpacing(0); @@ -1141,10 +1508,20 @@ TopBar::TopBar(QWidget *parent) mainLayout->addLayout(menuLayout); mainLayout->addStretch(1); mainLayout->addWidget(m_roomTabBar, 0); + mainLayout->addSpacing(2); + mainLayout->addWidget(m_lockRoomCB, 0); } m_containerFrame->setLayout(mainLayout); addWidget(m_containerFrame); - connect(m_roomTabBar, SIGNAL(currentChanged(int)), + bool ret = true; + ret = ret && connect(m_roomTabBar, SIGNAL(currentChanged(int)), m_stackedMenuBar, SLOT(setCurrentIndex(int))); + + ret = ret && connect(m_roomTabBar, SIGNAL(indexSwapped(int, int)), m_stackedMenuBar, SLOT(onIndexSwapped(int, int))); + ret = ret && connect(m_roomTabBar, SIGNAL(insertNewTabRoom()), m_stackedMenuBar, SLOT(insertNewMenuBar())); + ret = ret && connect(m_roomTabBar, SIGNAL(deleteTabRoom(int)), m_stackedMenuBar, SLOT(deleteMenuBar(int))); + ret = ret && connect(m_roomTabBar, SIGNAL(customizeMenuBar(int)), m_stackedMenuBar, SLOT(doCustomizeMenuBar(int))); + ret = ret && connect(m_lockRoomCB, SIGNAL(toggled(bool)), m_roomTabBar, SLOT(setIsLocked(bool))); + assert(ret); } diff --git a/toonz/sources/toonz/menubar.h b/toonz/sources/toonz/menubar.h index 673a067..e4b6d1a 100644 --- a/toonz/sources/toonz/menubar.h +++ b/toonz/sources/toonz/menubar.h @@ -23,46 +23,53 @@ class TFilePath; class QPainterEvent; class QHBoxLayout; class SubXsheetRoomTabContainer; +class QCheckBox; +class QXmlStreamReader; //----------------------------------------------------------------------------- -/* + class RoomTabWidget : public QTabBar { - Q_OBJECT + Q_OBJECT - int m_clickedTabIndex; + int m_clickedTabIndex; int m_tabToDeleteIndex; int m_renameTabIndex; DVGui::LineEdit* m_renameTextField; + bool m_isLocked; public: - RoomTabWidget(QWidget *parent); - ~RoomTabWidget(); - - void drawContextMenu(QContextMenuEvent *event); + RoomTabWidget(QWidget *parent); + ~RoomTabWidget(); + + bool isLocked(){ return m_isLocked; } protected: void swapIndex(int firstIndex, int secondIndex); - void mousePressEvent(QMouseEvent *event); - void mouseMoveEvent(QMouseEvent *event); - void mouseReleaseEvent(QMouseEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); void mouseDoubleClickEvent(QMouseEvent * event); + void contextMenuEvent(QContextMenuEvent *event); protected slots: void updateTabName(); void addNewTab(); void deleteTab(); + void setIsLocked(bool lock); + void onCustomizeMenuBar(); signals: void indexSwapped(int firstIndex, int secondIndex); void insertNewTabRoom(); void deleteTabRoom(int index); void renameTabRoom(int index, const QString name); + void customizeMenuBar(int index); }; //----------------------------------------------------------------------------- - +/* class SubSheetBar : public QFrame { Q_OBJECT @@ -137,22 +144,31 @@ class StackedMenuBar : public QStackedWidget { Q_OBJECT - void createCleanupMenuBar(); - void createPltEditMenuBar(); - void createInknPaintMenuBar(); - void createXsheetMenuBar(); - void createBatchesMenuBar(); - void createBrowserMenuBar(); - void createFullMenuBar(); + QMenuBar* createCleanupMenuBar(); + QMenuBar* createPltEditMenuBar(); + QMenuBar* createInknPaintMenuBar(); + QMenuBar* createXsheetMenuBar(); + QMenuBar* createBatchesMenuBar(); + QMenuBar* createBrowserMenuBar(); + QMenuBar* createFullMenuBar(); + QMenuBar* loadMenuBar(const TFilePath & fp); public: StackedMenuBar(QWidget *parent); ~StackedMenuBar(){}; void createMenuBarByName(const QString &roomName); + void loadAndAddMenubar(const TFilePath & fp); + bool readMenuRecursive( QXmlStreamReader&, QMenu*); QMenu *addMenu(const QString &, QMenuBar *); void addMenuItem(QMenu *, const char *); + +protected slots: + void onIndexSwapped(int firstIndex, int secondIndex); + void insertNewMenuBar(); + void deleteMenuBar(int index); + void doCustomizeMenuBar(int index); }; //----------------------------------------------------------------------------- @@ -162,8 +178,9 @@ class TopBar : public QToolBar Q_OBJECT QFrame *m_containerFrame; - QTabBar *m_roomTabBar; + RoomTabWidget *m_roomTabBar; StackedMenuBar *m_stackedMenuBar; + QCheckBox* m_lockRoomCB; public: TopBar(QWidget *parent); diff --git a/toonz/sources/toonz/menubarpopup.cpp b/toonz/sources/toonz/menubarpopup.cpp new file mode 100644 index 0000000..2088292 --- /dev/null +++ b/toonz/sources/toonz/menubarpopup.cpp @@ -0,0 +1,553 @@ +#include "menubarpopup.h" + +// Tnz includes +#include "tapp.h" +#include "mainwindow.h" +#include "menubar.h" +#include "shortcutpopup.h" + +// TnzQt includes +#include "toonzqt/gutil.h" + +// TnzLib includes +#include "toonz/toonzfolders.h" + +// TnzCore includes +#include "tsystem.h" + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//============================================================================= +// MenuBarCommandItem +//----------------------------------------------------------------------------- + +class MenuBarCommandItem : public QTreeWidgetItem +{ + QAction *m_action; +public: + MenuBarCommandItem(QTreeWidgetItem *parent, QAction *action) + : QTreeWidgetItem(parent, UserType), m_action(action) + { + setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren); + setText(0, m_action->text().remove("&")); + setToolTip(0, QObject::tr("[Drag] to move position")); + } + QAction *getAction() const { return m_action; } + +}; + +//============================================================================= +// MenuBarSeparatorItem +//----------------------------------------------------------------------------- + +class MenuBarSeparatorItem : public QTreeWidgetItem +{ +public: + MenuBarSeparatorItem(QTreeWidgetItem *parent) + : QTreeWidgetItem(parent, UserType) + { + setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren); + setText(0, QObject::tr("----Separator----")); + setToolTip(0, QObject::tr("[Drag] to move position")); + } +}; + +//============================================================================= +// MenuBarSubmenuItem +//----------------------------------------------------------------------------- + +class MenuBarSubmenuItem : public QTreeWidgetItem +{ +public: + MenuBarSubmenuItem(QTreeWidgetItem *parent, QString & title) + : QTreeWidgetItem(parent, UserType) + { + setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled); + /*- Menu title will be translated if the title is registered in translation file -*/ + setText(0, StackedMenuBar::tr(title.toStdString().c_str())); + QIcon subMenuIcon(":Resources/browser_folder_close.png"); + subMenuIcon.addFile(":Resources/browser_folder_open.png", QSize(), QIcon::Normal, QIcon::On); + setIcon(0, subMenuIcon); + setToolTip(0, QObject::tr("[Drag] to move position, [Double Click] to edit title")); + } +}; + +//============================================================================= +// MenuBarTree +//----------------------------------------------------------------------------- + +MenuBarTree::MenuBarTree(TFilePath & path, QWidget* parent) + : QTreeWidget(parent) + , m_path(path) +{ + setObjectName("SolidLineFrame"); + setAlternatingRowColors(true); + setDragEnabled(true); + setDropIndicatorShown(true); + setDefaultDropAction(Qt::MoveAction); + setDragDropMode(QAbstractItemView::DragDrop); + + setColumnCount(1); + header()->close(); + + /*- m_path�����݂���Ȃ�t�@�C������ǂݍ��ށB������΃e���v���[�g��ǂݍ��� -*/ + TFilePath fp; + if (TFileStatus(path).isWritable()) + fp = m_path; + else + { + fp = m_path.withParentDir(ToonzFolder::getTemplateModuleDir()); + if (!TFileStatus(path).isReadable()) + fp = ToonzFolder::getTemplateModuleDir() + "menubar_template.xml"; + } + + loadMenuTree(fp); +} + +//----------------------------------------------------------------------------- + +void MenuBarTree::loadMenuTree(const TFilePath& fp) +{ + QFile file(toQString(fp)); + if (!file.open(QFile::ReadOnly | QFile::Text)){ + qDebug() << "Cannot read file" << file.errorString(); + return; + } + + QXmlStreamReader reader(&file); + + if (reader.readNextStartElement()) + { + if (reader.name() == "menubar") + { + while (reader.readNextStartElement()) + { + if (reader.name() == "menu") + { + QString title = reader.attributes().value("title").toString(); + MenuBarSubmenuItem *menu = new MenuBarSubmenuItem(0, title); + addTopLevelItem(menu); + loadMenuRecursive(reader, menu); + } + else if (reader.name() == "command") + { + QString cmdName = reader.readElementText(); + + QAction *action = CommandManager::instance()->getAction(cmdName.toStdString().c_str()); + if (action) + { + MenuBarCommandItem* item = new MenuBarCommandItem(0, action); + addTopLevelItem(item); + } + } + else + reader.skipCurrentElement(); + } + } + else + reader.raiseError(QObject::tr("Incorrect file")); + } + + if (reader.hasError()) + { + qDebug() << "Cannot read menubar xml"; + } +} + +//----------------------------------------------------------------------------- + +void MenuBarTree::loadMenuRecursive(QXmlStreamReader& reader, QTreeWidgetItem* parentItem) +{ + while (reader.readNextStartElement()) + { + if (reader.name() == "menu") + { + QString title = reader.attributes().value("title").toString(); + MenuBarSubmenuItem *subMenu = new MenuBarSubmenuItem(parentItem, title); + loadMenuRecursive(reader, subMenu); + } + else if (reader.name() == "command") + { + QString cmdName = reader.readElementText(); + QAction* action = CommandManager::instance()->getAction(cmdName.toStdString().c_str()); + if (action) + MenuBarCommandItem* item = new MenuBarCommandItem(parentItem, action); + } + else if (reader.name() == "command_debug") + { +#ifndef NDEBUG + QString cmdName = reader.readElementText(); + QAction* action = CommandManager::instance()->getAction(cmdName.toStdString().c_str()); + if (action) + MenuBarCommandItem* item = new MenuBarCommandItem(parentItem, action); +#else + reader.skipCurrentElement(); +#endif + } + else if (reader.name() == "separator") + { + MenuBarSeparatorItem* sep = new MenuBarSeparatorItem(parentItem); + reader.skipCurrentElement(); + } + else + reader.skipCurrentElement(); + } +} + +//----------------------------------------------------------------------------- + +void MenuBarTree::saveMenuTree() +{ + QFile file(toQString(m_path)); + if (!file.open(QFile::WriteOnly | QFile::Text)){ + qDebug() << "Cannot read file" << file.errorString(); + return; + } + + QXmlStreamWriter writer(&file); + writer.setAutoFormatting(true); + writer.writeStartDocument(); + + writer.writeStartElement("menubar"); + { + saveMenuRecursive(writer, invisibleRootItem()); + + } + writer.writeEndElement(); // menubar + + writer.writeEndDocument(); + +} + +//----------------------------------------------------------------------------- + +void MenuBarTree::saveMenuRecursive(QXmlStreamWriter& writer, QTreeWidgetItem* parentItem) +{ + for (int c = 0; c < parentItem->childCount(); c++) + { + MenuBarCommandItem* command = dynamic_cast(parentItem->child(c)); + MenuBarSeparatorItem* sep = dynamic_cast(parentItem->child(c)); + MenuBarSubmenuItem* subMenu = dynamic_cast(parentItem->child(c)); + if (command) + writer.writeTextElement("command", QString::fromStdString(CommandManager::instance()->getIdFromAction(command->getAction()))); + else if (sep) + writer.writeEmptyElement("separator"); + else if (subMenu) + { + writer.writeStartElement("menu"); + writer.writeAttribute("title", subMenu->text(0)); + + saveMenuRecursive(writer, subMenu); + + writer.writeEndElement(); // menu + } + else + {} + } +} + +//----------------------------------------------------------------------------- + +bool MenuBarTree::dropMimeData(QTreeWidgetItem * parent, int index, const QMimeData * data, Qt::DropAction action) +{ + + if (data->hasText()) + { + QString txt = data->text(); + QTreeWidgetItem* item; + if (txt == "separator") + item = new MenuBarSeparatorItem(0); + else + { + QAction * act = CommandManager::instance()->getAction(txt.toStdString().c_str()); + if (!act) return false; + item = new MenuBarCommandItem(0, act); + } + + + if (parent) + parent->insertChild(index, item); + else + insertTopLevelItem(index, item); + + + return true; + + } + + return false; + +} + +//----------------------------------------------------------------------------- + +QStringList MenuBarTree::mimeTypes() const +{ + QStringList qstrList; + qstrList.append("text/plain"); + return qstrList; +} + +//----------------------------------------------------------------------------- + +void MenuBarTree::contextMenuEvent(QContextMenuEvent * event) +{ + QTreeWidgetItem* item = itemAt(event->pos()); + if (item != currentItem()) + setCurrentItem(item); + QMenu* menu = new QMenu(this); + QAction * action; + if (!item || indexOfTopLevelItem(item) >= 0) + action = menu->addAction(tr("Insert Menu")); + else + action = menu->addAction(tr("Insert Submenu")); + + connect(action, SIGNAL(triggered()), this, SLOT(insertMenu())); + + if (item) + { + action = menu->addAction(tr("Remove \"%1\"").arg(item->text(0))); + connect(action, SIGNAL(triggered()), this, SLOT(removeItem())); + } + + menu->exec(event->globalPos()); + delete menu; +} + +//----------------------------------------------------------------------------- + +void MenuBarTree::insertMenu() +{ + QTreeWidgetItem* item = currentItem(); + QString title = tr("New Menu"); + MenuBarSubmenuItem * insItem = new MenuBarSubmenuItem(0, title); + if (!item) + addTopLevelItem(insItem); + else if (indexOfTopLevelItem(item) >= 0) + insertTopLevelItem(indexOfTopLevelItem(item), insItem); + else + item->parent()->insertChild(item->parent()->indexOfChild(item), insItem); +} + +//----------------------------------------------------------------------------- + +void MenuBarTree::removeItem() +{ + QTreeWidgetItem* item = currentItem(); + if (!item) return; + + if (indexOfTopLevelItem(item) >= 0) + takeTopLevelItem(indexOfTopLevelItem(item)); + else + item->parent()->removeChild(item); + + delete item; +} + +//============================================================================= +// CommandListTree +//----------------------------------------------------------------------------- + +CommandListTree::CommandListTree(QWidget* parent) + : QTreeWidget(parent) +{ + setObjectName("SolidLineFrame"); + setAlternatingRowColors(true); + setDragEnabled(true); + setDragDropMode(QAbstractItemView::DragOnly); + setColumnCount(1); + header()->close(); + + QIcon menuFolderIcon(":Resources/browser_project_close.png"); + menuFolderIcon.addFile(":Resources/browser_project_open.png", QSize(), QIcon::Normal, QIcon::On); + invisibleRootItem()->setIcon(0, menuFolderIcon); + + QTreeWidgetItem *menuCommandFolder = new QTreeWidgetItem(this); + menuCommandFolder->setFlags( Qt::ItemIsEnabled ); + menuCommandFolder->setText(0, ShortcutTree::tr("Menu Commands")); + menuCommandFolder->setExpanded(true); + menuCommandFolder->setIcon(0,invisibleRootItem()->icon(0)); + + addFolder(ShortcutTree::tr("File"), MenuFileCommandType, menuCommandFolder); + addFolder(ShortcutTree::tr("Edit"), MenuEditCommandType, menuCommandFolder); + addFolder(ShortcutTree::tr("Scan & Cleanup"), MenuScanCleanupCommandType, menuCommandFolder); + addFolder(ShortcutTree::tr("Level"), MenuLevelCommandType, menuCommandFolder); + addFolder(ShortcutTree::tr("Xsheet"), MenuXsheetCommandType, menuCommandFolder); + addFolder(ShortcutTree::tr("Cells"), MenuCellsCommandType, menuCommandFolder); + addFolder(ShortcutTree::tr("View"), MenuViewCommandType, menuCommandFolder); + addFolder(ShortcutTree::tr("Windows"), MenuWindowsCommandType, menuCommandFolder); + + addFolder(ShortcutTree::tr("Tools"), ToolCommandType); + + MenuBarSeparatorItem* sep = new MenuBarSeparatorItem(0); + sep->setToolTip(0, QObject::tr("[Drag&Drop] to copy separator to menu bar")); + addTopLevelItem(sep); + +} + +//----------------------------------------------------------------------------- + +void CommandListTree::addFolder(const QString &title, int commandType, QTreeWidgetItem *parentFolder) +{ + QTreeWidgetItem *folder; + if (!parentFolder) + folder = new QTreeWidgetItem(this); + else + folder = new QTreeWidgetItem(parentFolder); + assert(folder); + folder->setText(0, title); + folder->setIcon(0, invisibleRootItem()->icon(0)); + + std::vector actions; + CommandManager::instance()->getActions((CommandType)commandType, actions); + for (int i = 0; i < (int)actions.size(); i++) { + MenuBarCommandItem *item = new MenuBarCommandItem(folder, actions[i]); + item->setToolTip(0, QObject::tr("[Drag&Drop] to copy command to menu bar")); + } +} + +//----------------------------------------------------------------------------- + +void CommandListTree::mousePressEvent(QMouseEvent *event) +{ + setCurrentItem(itemAt(event->pos())); + MenuBarCommandItem *commandItem = dynamic_cast(itemAt(event->pos())); + MenuBarSeparatorItem *separatorItem = dynamic_cast(itemAt(event->pos())); + + if (commandItem || separatorItem) + { + std::string dragStr; + QString dragPixmapTxt; + if (commandItem) + { + dragStr = CommandManager::instance()->getIdFromAction(commandItem->getAction()); + dragPixmapTxt = commandItem->getAction()->text(); + dragPixmapTxt.remove("&"); + } + else + { + dragStr = "separator"; + dragPixmapTxt = tr("----Separator----"); + } + + QMimeData *mimeData = new QMimeData; + mimeData->setText(QString::fromStdString(dragStr)); + + QFontMetrics fm(QApplication::font()); + QPixmap pix(fm.boundingRect(dragPixmapTxt).adjusted(-2,-2,2,2).size()); + QPainter painter(&pix); + painter.fillRect(pix.rect(),Qt::white); + painter.setPen(Qt::black); + painter.drawText(pix.rect(), Qt::AlignCenter, dragPixmapTxt); + + QDrag *drag = new QDrag(this); + drag->setMimeData(mimeData); + drag->setPixmap(pix); + + drag->exec(Qt::CopyAction); + } + + QTreeWidget::mousePressEvent(event); +} + +//============================================================================= +// MenuBarPopup +//----------------------------------------------------------------------------- + +MenuBarPopup::MenuBarPopup(Room* room) + : Dialog(TApp::instance()->getMainWindow(), true, false, "CustomizeMenuBar") +{ + setWindowTitle(tr("Customize Menu Bar of Room \"%1\"").arg(room->getName())); + + /*- get menubar setting file path -*/ + std::string mbFileName = room->getPath().getName() + "_menubar.xml"; + TFilePath mbPath = ToonzFolder::getMyModuleDir() + mbFileName; + + m_commandListTree = new CommandListTree(this); + m_menuBarTree = new MenuBarTree(mbPath, this); + + QPushButton *okBtn = new QPushButton(tr("OK"), this); + QPushButton *cancelBtn = new QPushButton(tr("Cancel"), this); + + okBtn->setFocusPolicy(Qt::NoFocus); + cancelBtn->setFocusPolicy(Qt::NoFocus); + + QLabel* menuBarLabel = new QLabel(tr("%1 Menu Bar").arg(room->getName()), this); + QLabel* menuItemListLabel = new QLabel(tr("Menu Items"), this); + + QFont f("Arial", 15, QFont::Bold); + menuBarLabel->setFont(f); + menuItemListLabel->setFont(f); + + QLabel* noticeLabel = new QLabel(tr("N.B. If you put unique title to submenu, it may not be translated to another language.\nN.B. Duplicated commands will be ignored. Only the last one will appear in the menu bar."),this); + QFont nf("Arial", 9, QFont::Normal); + nf.setItalic(true); + noticeLabel->setFont(nf); + + //--- layout + QVBoxLayout* mainLay = new QVBoxLayout(); + m_topLayout->setMargin(0); + m_topLayout->setSpacing(0); + { + QGridLayout* mainUILay = new QGridLayout(); + mainUILay->setMargin(5); + mainUILay->setHorizontalSpacing(8); + mainUILay->setVerticalSpacing(5); + { + mainUILay->addWidget(menuBarLabel, 0, 0); + mainUILay->addWidget(menuItemListLabel, 0, 1); + mainUILay->addWidget(m_menuBarTree, 1, 0); + mainUILay->addWidget(m_commandListTree, 1, 1); + + mainUILay->addWidget(noticeLabel, 2, 0, 1, 2); + } + mainUILay->setRowStretch(0, 0); + mainUILay->setRowStretch(1, 1); + mainUILay->setRowStretch(2, 0); + mainUILay->setColumnStretch(0, 1); + mainUILay->setColumnStretch(1, 1); + + m_topLayout->addLayout(mainUILay, 1); + } + + m_buttonLayout->setMargin(0); + m_buttonLayout->setSpacing(30); + { + m_buttonLayout->addStretch(1); + m_buttonLayout->addWidget(okBtn, 0); + m_buttonLayout->addWidget(cancelBtn, 0); + m_buttonLayout->addStretch(1); + } + + //--- signal/slot connections + + bool ret = connect(okBtn, SIGNAL(clicked()), this, SLOT(onOkPressed())); + ret = ret && connect(cancelBtn, SIGNAL(clicked()), this, SLOT(reject())); + assert(ret); +} + +//----------------------------------------------------------------------------- + +void MenuBarPopup::onOkPressed() +{ + /*- TODO: xml�Ƀc���[�̏�Ԃ��������� -*/ + m_menuBarTree->saveMenuTree(); + + accept(); +} \ No newline at end of file diff --git a/toonz/sources/toonz/menubarpopup.h b/toonz/sources/toonz/menubarpopup.h new file mode 100644 index 0000000..2670331 --- /dev/null +++ b/toonz/sources/toonz/menubarpopup.h @@ -0,0 +1,75 @@ +#ifndef MENUBARPOPUP_H +#define MENUBARPOPUP_H + +#include +#include +#include + +#include "toonzqt/dvdialog.h" +#include "tfilepath.h" + +class Room; +class QXmlStreamReader; +class QXmlStreamWriter; + +//============================================================================= +// MenuBarTree +//----------------------------------------------------------------------------- + +class MenuBarTree : public QTreeWidget +{ + Q_OBJECT + + TFilePath m_path; + + void loadMenuTree(const TFilePath& fp); + void loadMenuRecursive(QXmlStreamReader& reader, QTreeWidgetItem* parentItem); + void saveMenuRecursive(QXmlStreamWriter& writer, QTreeWidgetItem* parentItem); +public: + MenuBarTree(TFilePath & path, QWidget* parent = 0); + void saveMenuTree(); +protected: + bool dropMimeData(QTreeWidgetItem * parent, int index, const QMimeData * data, Qt::DropAction action); + QStringList mimeTypes() const; + void contextMenuEvent(QContextMenuEvent * event); +protected slots: + void insertMenu(); + void removeItem(); +}; + +//============================================================================= +// CommandListTree +//----------------------------------------------------------------------------- + +class CommandListTree : public QTreeWidget +{ + Q_OBJECT + + void addFolder(const QString &title, int commandType, QTreeWidgetItem *parentFolder=0); +public: + CommandListTree(QWidget* parent = 0); +protected: + void mousePressEvent(QMouseEvent*); +}; + + +//============================================================================= +// MenuBarPopup +//----------------------------------------------------------------------------- + +class MenuBarPopup : public Dialog +{ + Q_OBJECT + CommandListTree* m_commandListTree; + MenuBarTree* m_menuBarTree; + +public: + MenuBarPopup(Room* room); +protected slots: + void onOkPressed(); + +}; + + + +#endif \ No newline at end of file diff --git a/toonz/sources/toonzqt/menubarcommand.cpp b/toonz/sources/toonzqt/menubarcommand.cpp index 864f897..eea1883 100644 --- a/toonz/sources/toonzqt/menubarcommand.cpp +++ b/toonz/sources/toonzqt/menubarcommand.cpp @@ -424,6 +424,17 @@ void CommandManager::setToggleTexts(CommandId id, const QString &onText, const Q } } +//--------------------------------------------------------- + +std::string CommandManager::getIdFromAction(QAction* action) +{ + std::map::iterator it = m_qactionTable.find(action); + if (it != m_qactionTable.end()) + return it->second->m_id; + else + return ""; +} + /* //---------------------------------------------------------