From 783798e1ab5f063911f6863155380d8a7599f89a Mon Sep 17 00:00:00 2001 From: Udo Hoffmann Date: Mon, 6 Jul 2020 16:21:50 +0200 Subject: [PATCH] Enable project panels toggle from menu Close #8533 --- PowerEditor/src/Notepad_plus.cpp | 65 +++++++++++++++---- PowerEditor/src/Notepad_plus.h | 5 +- PowerEditor/src/Notepad_plus.rc | 2 +- PowerEditor/src/Notepad_plus_Window.cpp | 16 ++--- PowerEditor/src/NppBigSwitch.cpp | 5 +- PowerEditor/src/NppCommands.cpp | 35 +++++++--- PowerEditor/src/NppIO.cpp | 3 +- .../WinControls/ProjectPanel/ProjectPanel.cpp | 44 +++++++++---- .../WinControls/ProjectPanel/ProjectPanel.h | 18 +++-- 9 files changed, 132 insertions(+), 61 deletions(-) diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index 1bc55829..3c7a65a5 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -810,17 +810,17 @@ bool Notepad_plus::saveProjectPanelsParams() { if (_pProjectPanel_1) { - _pProjectPanel_1->checkIfNeedSave(TEXT("Project Panel 1")); + if (!_pProjectPanel_1->checkIfNeedSave()) return false; (NppParameters::getInstance()).setWorkSpaceFilePath(0, _pProjectPanel_1->getWorkSpaceFilePath()); } if (_pProjectPanel_2) { - _pProjectPanel_2->checkIfNeedSave(TEXT("Project Panel 2")); + if (!_pProjectPanel_2->checkIfNeedSave()) return false; (NppParameters::getInstance()).setWorkSpaceFilePath(1, _pProjectPanel_2->getWorkSpaceFilePath()); } if (_pProjectPanel_3) { - _pProjectPanel_3->checkIfNeedSave(TEXT("Project Panel 3")); + if (!_pProjectPanel_3->checkIfNeedSave()) return false; (NppParameters::getInstance()).setWorkSpaceFilePath(2, _pProjectPanel_3->getWorkSpaceFilePath()); } return (NppParameters::getInstance()).writeProjectPanelsSettings(); @@ -6053,6 +6053,44 @@ void Notepad_plus::launchFileBrowser(const vector & folders, boo _pFileBrowser->setClosed(false); } +void Notepad_plus::checkProjectMenuItem() +{ + HMENU viewMenu = ::GetSubMenu(_mainMenuHandle, MENUINDEX_VIEW); + int viewMenuCount = ::GetMenuItemCount(viewMenu); + for (int i = 0; i < viewMenuCount; i++) + { + HMENU subMenu = ::GetSubMenu(viewMenu, i); + if (subMenu) + { + int subMenuCount = ::GetMenuItemCount(subMenu); + bool found = false; + bool checked = false; + for (int j = 0; j < subMenuCount; j++) + { + UINT const ids [] = {IDM_VIEW_PROJECT_PANEL_1, IDM_VIEW_PROJECT_PANEL_2, IDM_VIEW_PROJECT_PANEL_3}; + UINT id = GetMenuItemID (subMenu, j); + for (int k = 0; k < _countof(ids); k++) + { + if (id == ids [k]) + { + found = true; + UINT s = GetMenuState(subMenu, j, MF_BYPOSITION); + if (s & MF_CHECKED) + { + checked = true; + break; + } + } + } + } + if (found) + { + CheckMenuItem(viewMenu, i, (checked ? MF_CHECKED : MF_UNCHECKED) | MF_BYPOSITION); + break; + } + } + } +} void Notepad_plus::launchProjectPanel(int cmdID, ProjectPanel ** pProjPanel, int panelID) { @@ -6060,7 +6098,7 @@ void Notepad_plus::launchProjectPanel(int cmdID, ProjectPanel ** pProjPanel, int if (!(*pProjPanel)) { (*pProjPanel) = new ProjectPanel; - (*pProjPanel)->init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf()); + (*pProjPanel)->init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf(), panelID); (*pProjPanel)->setWorkSpaceFilePath(nppParam.getWorkSpaceFilePath(panelID)); tTbData data; @@ -6080,14 +6118,10 @@ void Notepad_plus::launchProjectPanel(int cmdID, ProjectPanel ** pProjPanel, int data.dlgID = cmdID; NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance()).getNativeLangSpeaker(); - generic_string title_temp = pNativeSpeaker->getAttrNameStr(PM_PROJECTPANELTITLE, "ProjectManager", "PanelTitle"); - - static TCHAR title[32]; - if (title_temp.length() < 32) - { - wcscpy_s(title, title_temp.c_str()); - data.pszName = title; - } + generic_string title_no = to_wstring (panelID + 1); + generic_string title_temp = pNativeSpeaker->getAttrNameStr(PM_PROJECTPANELTITLE, "ProjectManager", "PanelTitle") + TEXT(" ") + title_no; + (*pProjPanel)->setPanelTitle(title_temp); + data.pszName = (*pProjPanel)->getPanelTitle(); ::SendMessage(_pPublicInterface->getHSelf(), NPPM_DMMREGASDCKDLG, 0, reinterpret_cast(&data)); COLORREF fgColor = (NppParameters::getInstance()).getCurrentDefaultFgColor(); @@ -6098,10 +6132,13 @@ void Notepad_plus::launchProjectPanel(int cmdID, ProjectPanel ** pProjPanel, int } else { - if ((*pProjPanel)->saveWorkspaceRequest()) - (*pProjPanel)->openWorkSpace(nppParam.getWorkSpaceFilePath(panelID)); + (*pProjPanel)->openWorkSpace(nppParam.getWorkSpaceFilePath(panelID)); } (*pProjPanel)->display(); + + checkMenuItem(cmdID, true); + checkProjectMenuItem(); + (*pProjPanel)->setClosed(false); } diff --git a/PowerEditor/src/Notepad_plus.h b/PowerEditor/src/Notepad_plus.h index 06699b5e..7317b293 100644 --- a/PowerEditor/src/Notepad_plus.h +++ b/PowerEditor/src/Notepad_plus.h @@ -387,10 +387,6 @@ private: // and "Enable session snapshot and periodic backup" is not enabled // then WM_ENDSESSION is send with wParam == FALSE // in this case this boolean is set true, so Notepad++ will quit and its current session will be saved - - bool _isWorkspaceFileLoadedFromCommandLine = false; // Set during Notepad_plus::doOpen if workspace file is opened. - // But it is only evaluated during startup, when doOpen - // has been called while command line interpretation. ScintillaCtrls _scintillaCtrls4Plugins; std::vector > _hideLinesMarks; @@ -607,6 +603,7 @@ private: void launchAnsiCharPanel(); void launchClipboardHistoryPanel(); void launchFileSwitcherPanel(); + void checkProjectMenuItem(); void launchProjectPanel(int cmdID, ProjectPanel ** pProjPanel, int panelID); void launchDocMap(); void launchFunctionList(); diff --git a/PowerEditor/src/Notepad_plus.rc b/PowerEditor/src/Notepad_plus.rc index 495acc20..a107f993 100644 --- a/PowerEditor/src/Notepad_plus.rc +++ b/PowerEditor/src/Notepad_plus.rc @@ -549,7 +549,7 @@ BEGIN MENUITEM SEPARATOR MENUITEM "Summary...", IDM_VIEW_SUMMARY MENUITEM SEPARATOR - POPUP "Project" + POPUP "Project Panels" BEGIN MENUITEM "Project Panel 1", IDM_VIEW_PROJECT_PANEL_1 MENUITEM "Project Panel 2", IDM_VIEW_PROJECT_PANEL_2 diff --git a/PowerEditor/src/Notepad_plus_Window.cpp b/PowerEditor/src/Notepad_plus_Window.cpp index 67aaf339..b72ee7ae 100644 --- a/PowerEditor/src/Notepad_plus_Window.cpp +++ b/PowerEditor/src/Notepad_plus_Window.cpp @@ -185,10 +185,6 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLin _notepad_plus_plus_core._pTrayIco->doTrayIcon(ADD); } - std::vector fns; - if (cmdLine) - fns = _notepad_plus_plus_core.loadCommandlineParams(cmdLine, cmdLineParams); - std::vector fileNames; std::vector patterns; patterns.push_back(TEXT("*.xml")); @@ -239,20 +235,16 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLin for (size_t i = 0, len = _notepad_plus_plus_core._internalFuncIDs.size() ; i < len ; ++i) ::SendMessage(_hSelf, WM_COMMAND, _notepad_plus_plus_core._internalFuncIDs[i], 0); + std::vector fns; + if (cmdLine) + fns = _notepad_plus_plus_core.loadCommandlineParams(cmdLine, cmdLineParams); + // Launch folder as workspace after all this dockable panel being restored from the last session // To avoid dockable panel toggle problem. if (cmdLineParams->_openFoldersAsWorkspace) { _notepad_plus_plus_core.launchFileBrowser(fns, true); } - else if (_notepad_plus_plus_core._isWorkspaceFileLoadedFromCommandLine) - { - // Switch back to Project Panel 1, when a workspace file has been specified in the command line. - // This code is executed only once in lifetime of the process, at the first initialization. It is necessary, because - // the Project Panels are not loaded by Notepad_plus::doOpen only, but also by the Plugin Manager restoring the state - // of the last session from config.xml. - ::SendMessage(_hSelf, WM_COMMAND, IDM_VIEW_PROJECT_PANEL_1, 0); - } ::SendMessage(_hSelf, WM_ACTIVATE, WA_ACTIVE, 0); // Notify plugins that Notepad++ is ready diff --git a/PowerEditor/src/NppBigSwitch.cpp b/PowerEditor/src/NppBigSwitch.cpp index a81e1f7d..8315ce06 100644 --- a/PowerEditor/src/NppBigSwitch.cpp +++ b/PowerEditor/src/NppBigSwitch.cpp @@ -1786,6 +1786,9 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa if (nppgui._rememberLastSession) _lastRecentFileList.setLock(false); //only lock when the session is remembered + if (!saveProjectPanelsParams()) allClosed = false; //writeProjectPanelsSettings + saveFileBrowserParam(); + if (!allClosed) { //User cancelled the shutdown @@ -1813,8 +1816,6 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa saveGUIParams(); //writeGUIParams writeScintillaParams saveFindHistory(); //writeFindHistory _lastRecentFileList.saveLRFL(); //writeRecentFileHistorySettings, writeHistory - saveProjectPanelsParams(); //writeProjectPanelsSettings - saveFileBrowserParam(); // // saving config.xml // diff --git a/PowerEditor/src/NppCommands.cpp b/PowerEditor/src/NppCommands.cpp index bddf49bf..4693dfbf 100644 --- a/PowerEditor/src/NppCommands.cpp +++ b/PowerEditor/src/NppCommands.cpp @@ -35,6 +35,7 @@ #include "VerticalFileSwitcher.h" #include "documentMap.h" #include "functionListPanel.h" +#include "ProjectPanel.h" #include "fileBrowser.h" #include "Sorters.h" #include "verifySignedfile.h" @@ -687,18 +688,34 @@ void Notepad_plus::command(int id) break; case IDM_VIEW_PROJECT_PANEL_1: - { - launchProjectPanel(id, &_pProjectPanel_1, 0); - } - break; case IDM_VIEW_PROJECT_PANEL_2: - { - launchProjectPanel(id, &_pProjectPanel_2, 1); - } - break; case IDM_VIEW_PROJECT_PANEL_3: { - launchProjectPanel(id, &_pProjectPanel_3, 2); + ProjectPanel** pp [] = {&_pProjectPanel_1, &_pProjectPanel_2, &_pProjectPanel_3}; + int idx = id - IDM_VIEW_PROJECT_PANEL_1; + if (*pp [idx] == nullptr) + { + launchProjectPanel(id, pp [idx], idx); + } + else + { + if (not (*pp[idx])->isClosed()) + { + if ((*pp[idx])->checkIfNeedSave()) + { + if (::IsChild((*pp[idx])->getHSelf(), ::GetFocus())) + ::SetFocus(_pEditView->getHSelf()); + (*pp[idx])->display(false); + (*pp[idx])->setClosed(true); + checkMenuItem(id, false); + checkProjectMenuItem(); + } + } + else + { + launchProjectPanel(id, pp [idx], idx); + } + } } break; diff --git a/PowerEditor/src/NppIO.cpp b/PowerEditor/src/NppIO.cpp index 12c94a0d..960ee751 100644 --- a/PowerEditor/src/NppIO.cpp +++ b/PowerEditor/src/NppIO.cpp @@ -211,10 +211,9 @@ BufferID Notepad_plus::doOpen(const generic_string& fileName, bool isRecursive, if (isFileWorkspace(longFileName) && PathFileExists(longFileName)) { nppParam.setWorkSpaceFilePath(0, longFileName); - _isWorkspaceFileLoadedFromCommandLine = true; // This line switches to Project Panel 1 while starting up Npp // and after dragging a workspace file to Npp: - command(IDM_VIEW_PROJECT_PANEL_1); + launchProjectPanel(IDM_VIEW_PROJECT_PANEL_1, &_pProjectPanel_1, 0); return BUFFER_INVALID; } diff --git a/PowerEditor/src/WinControls/ProjectPanel/ProjectPanel.cpp b/PowerEditor/src/WinControls/ProjectPanel/ProjectPanel.cpp index 0a9b11f7..70d2dacd 100644 --- a/PowerEditor/src/WinControls/ProjectPanel/ProjectPanel.cpp +++ b/PowerEditor/src/WinControls/ProjectPanel/ProjectPanel.cpp @@ -99,7 +99,7 @@ INT_PTR CALLBACK ProjectPanel::run_dlgProc(UINT message, WPARAM wParam, LPARAM l _treeView.addCanNotDragOutList(INDEX_PROJECT); _treeView.display(); - if (!openWorkSpace(_workSpaceFilePath.c_str())) + if (!openWorkSpace(_workSpaceFilePath.c_str(), true)) newWorkSpace(); return TRUE; @@ -185,18 +185,17 @@ INT_PTR CALLBACK ProjectPanel::run_dlgProc(UINT message, WPARAM wParam, LPARAM l return DockingDlgInterface::run_dlgProc(message, wParam, lParam); } -void ProjectPanel::checkIfNeedSave(const TCHAR *title) +bool ProjectPanel::checkIfNeedSave() { if (_isDirty) { - display(); - + const TCHAR * title = _workSpaceFilePath.length() > 0 ? PathFindFileName (_workSpaceFilePath.c_str()) : _panelTitle.c_str(); NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance()).getNativeLangSpeaker(); int res = pNativeSpeaker->messageBox("ProjectPanelChanged", _hSelf, TEXT("The workspace was modified. Do you want to save it?"), TEXT("$STR_REPLACE$"), - MB_YESNO | MB_ICONQUESTION, + MB_YESNOCANCEL | MB_ICONQUESTION, 0, title); @@ -211,9 +210,17 @@ void ProjectPanel::checkIfNeedSave(const TCHAR *title) 0, title); } - //else if (res == IDNO) + else if (res == IDNO) + { // Don't save so do nothing here + } + else + { + // Cancelled + return false; + } } + return true; } void ProjectPanel::initMenus() @@ -362,8 +369,17 @@ void ProjectPanel::destroyMenus() ::DestroyMenu(_hFileMenu); } -bool ProjectPanel::openWorkSpace(const TCHAR *projectFileName) +bool ProjectPanel::openWorkSpace(const TCHAR *projectFileName, bool force) { + if ((!force) && (_workSpaceFilePath.length() > 0)) + { // Return if it is better to keep the current workspace tree + generic_string newWorkspace = projectFileName; + if (newWorkspace == _workSpaceFilePath) + return true; + if (!saveWorkspaceRequest()) + return true; + } + TiXmlDocument *pXmlDocProject = new TiXmlDocument(projectFileName); bool loadOkay = pXmlDocProject->LoadFile(); if (!loadOkay) @@ -396,8 +412,6 @@ bool ProjectPanel::openWorkSpace(const TCHAR *projectFileName) _treeView.removeAllItems(); _workSpaceFilePath = projectFileName; - NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance()).getNativeLangSpeaker(); - generic_string workspace = pNativeSpeaker->getAttrNameStr(PM_WORKSPACEROOTNAME, "ProjectManager", "WorkspaceRootName"); TCHAR * fileName = PathFindFileName(projectFileName); HTREEITEM rootItem = _treeView.addItem(fileName, TVI_ROOT, INDEX_CLEAN_ROOT); @@ -432,7 +446,6 @@ bool ProjectPanel::saveWorkSpace() { writeWorkSpace(); setWorkSpaceDirty(false); - _isDirty = false; return true; } } @@ -455,7 +468,7 @@ bool ProjectPanel::writeWorkSpace(TCHAR *projectFileName) if (!tvRoot) return false; - TCHAR * fileName = PathFindFileName(projectFileName); + TCHAR * fileName = PathFindFileName(fn2write); _treeView.renameItem(tvRoot, fileName); for (HTREEITEM tvProj = _treeView.getChildFrom(tvRoot); @@ -595,7 +608,12 @@ void ProjectPanel::openSelectFile() void ProjectPanel::notified(LPNMHDR notification) { - if ((notification->hwndFrom == _treeView.getHSelf())) + if (notification->code == DMN_CLOSE) + { + ::SendMessage(_hParent, WM_COMMAND, IDM_VIEW_PROJECT_PANEL_1 + _panelID, 0); + SetWindowLongPtr (getHSelf(), DWLP_MSGRESULT, _isClosed ? 0 : 1); + } + else if ((notification->hwndFrom == _treeView.getHSelf())) { TCHAR textBuffer[MAX_PATH]; TVITEM tvItem; @@ -1025,7 +1043,7 @@ void ProjectPanel::popupMenuCmd(int cmdID) setFileExtFilter(fDlg); if (TCHAR *fn = fDlg.doOpenSingleFileDlg()) { - if (!openWorkSpace(fn)) + if (!openWorkSpace(fn, true)) { NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance()).getNativeLangSpeaker(); pNativeSpeaker->messageBox("ProjectPanelOpenFailed", diff --git a/PowerEditor/src/WinControls/ProjectPanel/ProjectPanel.h b/PowerEditor/src/WinControls/ProjectPanel/ProjectPanel.h index f29eb7f4..4e06008a 100644 --- a/PowerEditor/src/WinControls/ProjectPanel/ProjectPanel.h +++ b/PowerEditor/src/WinControls/ProjectPanel/ProjectPanel.h @@ -32,7 +32,7 @@ #include "TreeView.h" #include "ProjectPanel_rc.h" -#define PM_PROJECTPANELTITLE TEXT("Project") +#define PM_PROJECTPANELTITLE TEXT("Project Panel") #define PM_WORKSPACEROOTNAME TEXT("Workspace") #define PM_NEWFOLDERNAME TEXT("Folder Name") #define PM_NEWPROJECTNAME TEXT("Project Name") @@ -70,8 +70,9 @@ public: ProjectPanel(): DockingDlgInterface(IDD_PROJECTPANEL) {}; ~ProjectPanel(); - void init(HINSTANCE hInst, HWND hPere) { + void init(HINSTANCE hInst, HWND hPere, int panelID) { DockingDlgInterface::init(hInst, hPere); + _panelID = panelID; } virtual void display(bool toShow = true) const { @@ -82,9 +83,16 @@ public: _hParent = parent2set; }; + void setPanelTitle(generic_string title) { + _panelTitle = title; + }; + const TCHAR * getPanelTitle() const { + return _panelTitle.c_str(); + }; + void newWorkSpace(); bool saveWorkspaceRequest(); - bool openWorkSpace(const TCHAR *projectFileName); + bool openWorkSpace(const TCHAR *projectFileName, bool force = false); bool saveWorkSpace(); bool saveWorkSpaceAs(bool saveCopyAs); void setWorkSpaceFilePath(const TCHAR *projectFileName){ @@ -96,7 +104,7 @@ public: bool isDirty() const { return _isDirty; }; - void checkIfNeedSave(const TCHAR *title); + bool checkIfNeedSave(); virtual void setBackgroundColor(COLORREF bgColour) { TreeView_SetBkColor(_treeView.getHSelf(), bgColour); @@ -113,9 +121,11 @@ protected: HMENU _hProjectMenu = nullptr; HMENU _hFolderMenu = nullptr; HMENU _hFileMenu = nullptr; + generic_string _panelTitle; generic_string _workSpaceFilePath; generic_string _selDirOfFilesFromDirDlg; bool _isDirty = false; + int _panelID = 0; void initMenus(); void destroyMenus();