diff --git a/PowerEditor/src/MISC/Process/Processus.cpp b/PowerEditor/src/MISC/Process/Processus.cpp index af1c44ec2..271ba8ae3 100644 --- a/PowerEditor/src/MISC/Process/Processus.cpp +++ b/PowerEditor/src/MISC/Process/Processus.cpp @@ -30,9 +30,34 @@ #include "Processus.h" -void Process::run() +void Process::run() const { TCHAR *opVerb = TEXT("open"); ::ShellExecute(NULL, opVerb, _command.c_str(), _args.c_str(), _curDir.c_str(), SW_SHOWNORMAL); } +unsigned long Process::runSync() const +{ + SHELLEXECUTEINFO ShExecInfo = { 0 }; + ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); + ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; + ShExecInfo.hwnd = NULL; + ShExecInfo.lpVerb = TEXT("open"); + ShExecInfo.lpFile = _command.c_str(); + ShExecInfo.lpParameters = _args.c_str(); + ShExecInfo.lpDirectory = _curDir.c_str(); + ShExecInfo.nShow = SW_SHOWNORMAL; + ShExecInfo.hInstApp = NULL; + + ShellExecuteEx(&ShExecInfo); + WaitForSingleObject(ShExecInfo.hProcess, INFINITE); + + unsigned long exitCode; + if (::GetExitCodeProcess(ShExecInfo.hProcess, &exitCode) == FALSE) + { + // throw exception + throw GetLastErrorAsString(GetLastError()); + } + + return exitCode; +} diff --git a/PowerEditor/src/MISC/Process/Processus.h b/PowerEditor/src/MISC/Process/Processus.h index 62cee103c..42773f3e8 100644 --- a/PowerEditor/src/MISC/Process/Processus.h +++ b/PowerEditor/src/MISC/Process/Processus.h @@ -39,7 +39,8 @@ public: Process(const TCHAR *cmd, const TCHAR *args, const TCHAR *cDir) :_command(cmd), _args(args), _curDir(cDir){} - void run(); + void run() const; + unsigned long runSync() const; protected: generic_string _command; diff --git a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.rc b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.rc index 06309bc8d..4c0f96cbb 100644 --- a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.rc +++ b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.rc @@ -74,7 +74,7 @@ BEGIN CONTROL "", IDC_2_BUTTONS_MODE, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 363, 20, 15, 15 PUSHBUTTON "Coun&t",IDCCOUNTALL,268,38,91,14 PUSHBUTTON "Find All in All &Opened Documents",IDC_FINDALL_OPENEDFILES,268,56,91,21,BS_MULTILINE - PUSHBUTTON "Find All in Current Document",IDC_FINDALL_CURRENTFILE,268,80,91,21,BS_MULTILINE + PUSHBUTTON "Find All in Current &Document",IDC_FINDALL_CURRENTFILE,268,80,91,21,BS_MULTILINE PUSHBUTTON "&Replace",IDREPLACE,268,38,91,14 PUSHBUTTON "Replace &All",IDREPLACEALL,268,56,91,14 PUSHBUTTON "Replace All in All &Opened Documents",IDC_REPLACE_OPENEDFILES,268,74,91,21,BS_MULTILINE diff --git a/PowerEditor/src/WinControls/PluginsAdmin/pluginsAdmin.cpp b/PowerEditor/src/WinControls/PluginsAdmin/pluginsAdmin.cpp index 8896ec140..cb8cfdc07 100644 --- a/PowerEditor/src/WinControls/PluginsAdmin/pluginsAdmin.cpp +++ b/PowerEditor/src/WinControls/PluginsAdmin/pluginsAdmin.cpp @@ -149,7 +149,7 @@ bool findStrNoCase(const generic_string & strHaystack, const generic_string & st bool PluginsAdminDlg::isFoundInAvailableListFromIndex(int index, generic_string str2search, bool inWhichPart) const { - PluginUpdateInfo* pui = _availableList.getPluginInfoFromIndex(index); + PluginUpdateInfo* pui = _availableList.getPluginInfoFromUiIndex(index); generic_string searchIn; if (inWhichPart == _inNames) searchIn = pui->_displayName; @@ -337,9 +337,24 @@ void PluginsAdminDlg::collectNppCurrentStatusInfos() } +vector PluginViewList::fromUiIndexesToPluginInfos(const std::vector& uiIndexes) const +{ + std::vector r; + + for (auto i : uiIndexes) + { + if (i < _ui.nbItem()) + { + r.push_back(getPluginInfoFromUiIndex(i)); + } + } + return r; +} + bool PluginsAdminDlg::installPlugins() { vector indexes = _availableList.getCheckedIndexes(); + vector puis = _availableList.fromUiIndexesToPluginInfos(indexes); NppParameters *pNppParameters = NppParameters::getInstance(); generic_string updaterDir = pNppParameters->getNppPath(); @@ -348,22 +363,34 @@ bool PluginsAdminDlg::installPlugins() generic_string updaterFullPath = updaterDir + TEXT("gup.exe"); generic_string updaterParams = TEXT("-unzipTo "); - for (auto i : indexes) + for (auto i : puis) { - //printStr(_availablePluginList[i]._name .c_str()); - // add folder to operate generic_string destFolder = pNppParameters->getAppDataNppDir(); - PathAppend(destFolder, _availableList.getPluginInfoFromIndex(i)->_folderName); + PathAppend(destFolder, i->_folderName); updaterParams += destFolder; // add zipFile's url updaterParams += TEXT(" "); - updaterParams += _availableList.getPluginInfoFromIndex(i)->_repository; + updaterParams += i->_repository; Process updater(updaterFullPath.c_str(), updaterParams.c_str(), updaterDir.c_str()); - updater.run(); + int result = updater.runSync(); + if (result == 0) // wingup return 0 -> OK + { + // Remove (Hide) installed plugin from available list + _availableList.hideFromPluginInfoPtr(i); + + // Add installed plugin into insttalled list + PluginUpdateInfo* installedPui = new PluginUpdateInfo(*i); + installedPui->_isVisible = true; + _installedList.pushBack(installedPui); + } + else // wingup return non-zero (-1) -> Not OK + { + // just move on + } } return true; @@ -372,6 +399,7 @@ bool PluginsAdminDlg::installPlugins() bool PluginsAdminDlg::updatePlugins() { vector indexes = _updateList.getCheckedIndexes(); + vector puis = _updateList.fromUiIndexesToPluginInfos(indexes); NppParameters *pNppParameters = NppParameters::getInstance(); generic_string updaterDir = pNppParameters->getNppPath(); @@ -380,20 +408,30 @@ bool PluginsAdminDlg::updatePlugins() generic_string updaterFullPath = updaterDir + TEXT("gup.exe"); generic_string updaterParams = TEXT("-unzipTo "); - for (auto i : indexes) + for (auto i : puis) { // add folder to operate generic_string destFolder = pNppParameters->getAppDataNppDir(); - PathAppend(destFolder, _availableList.getPluginInfoFromIndex(i)->_folderName); + PathAppend(destFolder, i->_folderName); updaterParams += destFolder; // add zipFile's url updaterParams += TEXT(" "); - updaterParams += _availableList.getPluginInfoFromIndex(i)->_repository; + updaterParams += i->_repository; Process updater(updaterFullPath.c_str(), updaterParams.c_str(), updaterDir.c_str()); - updater.run(); + int result = updater.runSync(); + if (result == 0) // wingup return 0 -> OK + { + // Remove updated plugin from update list + _updateList.removeFromPluginInfoPtr(i); + + } + else // wingup return non-zero (-1) -> Not OK + { + // just move on + } } return true; @@ -402,6 +440,7 @@ bool PluginsAdminDlg::updatePlugins() bool PluginsAdminDlg::removePlugins() { vector indexes = _installedList.getCheckedIndexes(); + vector puis = _updateList.fromUiIndexesToPluginInfos(indexes); NppParameters *pNppParameters = NppParameters::getInstance(); generic_string updaterDir = pNppParameters->getNppPath(); @@ -410,23 +449,62 @@ bool PluginsAdminDlg::removePlugins() generic_string updaterFullPath = updaterDir + TEXT("gup.exe"); generic_string updaterParams = TEXT("-clean "); - for (auto i : indexes) + for (auto i : puis) { - //printStr(_installedPluginList[i]._fullFilePath.c_str()); - // add folder to operate generic_string destFolder = pNppParameters->getAppDataNppDir(); - PathAppend(destFolder, _availableList.getPluginInfoFromIndex(i)->_folderName); + PathAppend(destFolder, i->_folderName); updaterParams += destFolder; Process updater(updaterFullPath.c_str(), updaterParams.c_str(), updaterDir.c_str()); - updater.run(); + int result = updater.runSync(); + if (result == 0) // wingup return 0 -> OK + { + // Remove removed plugin from installed list + _installedList.removeFromPluginInfoPtr(i); + + // Remove removed plugin from update list eventually + _updateList.removeFromFolderName(i->_folderName); + + // Add removed plugin back to available list (if available) + _availableList.restore(i->_folderName); + + } + else // wingup return non-zero (-1) -> Not OK + { + // just move on + + } } return true; } +bool PluginViewList::removeFromFolderName(const generic_string& folderName) +{ + + for (size_t i = 0; i < _ui.nbItem(); ++i) + { + PluginUpdateInfo* pi = getPluginInfoFromUiIndex(i); + if (pi->_folderName == folderName) + { + if (!_ui.removeFromIndex(i)) + return false; + + for (size_t j = 0; j < _list.size(); ++j) + { + if (_list[j] == pi) + { + _list.erase(_list.begin() + j); + return true; + } + } + } + } + return false; +} + void PluginViewList::pushBack(PluginUpdateInfo* pi) { _list.push_back(pi); @@ -556,8 +634,8 @@ bool PluginsAdminDlg::loadFromPluginInfos() lstrcpy(fnNoExt, i._fileName.c_str()); ::PathRemoveExtension(fnNoExt); - int index; - PluginUpdateInfo* foundInfo = _availableList.findPluginInfoFromFolderName(fnNoExt, index); + int listIndex; + PluginUpdateInfo* foundInfo = _availableList.findPluginInfoFromFolderName(fnNoExt, listIndex); if (!foundInfo) { PluginUpdateInfo* pui = new PluginUpdateInfo(i._fullFilePath, i._fileName); @@ -565,14 +643,14 @@ bool PluginsAdminDlg::loadFromPluginInfos() } else { - // add new updated info to installed list + // Add new updated info to installed list PluginUpdateInfo* pui = new PluginUpdateInfo(*foundInfo); pui->_fullFilePath = i._fullFilePath; pui->_version.setVersionFrom(i._fullFilePath); _installedList.pushBack(pui); - // remove it from the available list - _availableList.removeFromIndex(index); + // Hide it from the available list + _availableList.hideFromListIndex(listIndex); } } @@ -592,7 +670,14 @@ PluginUpdateInfo* PluginViewList::findPluginInfoFromFolderName(const generic_str return nullptr; } -bool PluginViewList::removeFromIndex(size_t index2remove) +bool PluginViewList::removeFromUiIndex(size_t index2remove) +{ + if (index2remove >= _ui.nbItem()) + return false; + return _ui.removeFromIndex(index2remove); +} + +bool PluginViewList::removeFromListIndex(size_t index2remove) { if (index2remove >= _list.size()) return false; @@ -611,6 +696,91 @@ bool PluginViewList::removeFromIndex(size_t index2remove) return true; } +bool PluginViewList::removeFromPluginInfoPtr(PluginUpdateInfo* pluginInfo2hide) +{ + for (size_t i = 0; i < _ui.nbItem(); ++i) + { + if (_ui.getLParamFromIndex(i) == reinterpret_cast(pluginInfo2hide)) + { + if (!_ui.removeFromIndex(i)) + { + return false; + } + } + } + + for (size_t j = 0; j < _list.size(); ++j) + { + if (_list[j] == pluginInfo2hide) + { + _list.erase(_list.begin() + j); + return true; + } + } + + return false; +} + +bool PluginViewList::hideFromPluginInfoPtr(PluginUpdateInfo* pluginInfo2hide) +{ + for (size_t i = 0; i < _ui.nbItem(); ++i) + { + if (_ui.getLParamFromIndex(i) == reinterpret_cast(pluginInfo2hide)) + { + if (!_ui.removeFromIndex(i)) + { + return false; + } + else + { + pluginInfo2hide->_isVisible = false; + return true; + } + } + } + return false; +} + +bool PluginViewList::restore(const generic_string& folderName) +{ + for (auto i : _list) + { + if (i->_folderName == folderName) + { + vector values2Add; + values2Add.push_back(i->_displayName); + Version v = i->_version; + values2Add.push_back(v.toString()); + values2Add.push_back(TEXT("Yes")); + _ui.addLine(values2Add, reinterpret_cast(i)); + + i->_isVisible = true; + + return true; + } + } + return false; +} + +bool PluginViewList::hideFromListIndex(size_t index2hide) +{ + if (index2hide >= _list.size()) + return false; + + for (size_t i = 0; i < _ui.nbItem(); ++i) + { + if (_ui.getLParamFromIndex(i) == reinterpret_cast(_list[index2hide])) + { + if (!_ui.removeFromIndex(i)) + return false; + } + } + + _list[index2hide]->_isVisible = false; + + return true; +} + bool PluginsAdminDlg::checkUpdates() { return true; @@ -651,7 +821,7 @@ void PluginsAdminDlg::switchDialog(int indexToSwitch) long infoIndex = _availableList.getSelectedIndex(); if (infoIndex != -1 && infoIndex < static_cast(_availableList.nbItem())) - desc = _availableList.getPluginInfoFromIndex(infoIndex)->describe(); + desc = _availableList.getPluginInfoFromUiIndex(infoIndex)->describe(); } break; @@ -663,7 +833,7 @@ void PluginsAdminDlg::switchDialog(int indexToSwitch) long infoIndex = _updateList.getSelectedIndex(); if (infoIndex != -1 && infoIndex < static_cast(_updateList.nbItem())) - desc = _updateList.getPluginInfoFromIndex(infoIndex)->describe(); + desc = _updateList.getPluginInfoFromUiIndex(infoIndex)->describe(); } break; @@ -675,7 +845,7 @@ void PluginsAdminDlg::switchDialog(int indexToSwitch) long infoIndex = _installedList.getSelectedIndex(); if (infoIndex != -1 && infoIndex < static_cast(_installedList.nbItem())) - desc = _installedList.getPluginInfoFromIndex(infoIndex)->describe(); + desc = _installedList.getPluginInfoFromUiIndex(infoIndex)->describe(); } break; @@ -825,7 +995,7 @@ INT_PTR CALLBACK PluginsAdminDlg::run_dlgProc(UINT message, WPARAM wParam, LPARA } else if (pnmv->uNewState & LVIS_SELECTED) { - PluginUpdateInfo* pui = pViewList->getPluginInfoFromIndex(pnmv->iItem); + PluginUpdateInfo* pui = pViewList->getPluginInfoFromUiIndex(pnmv->iItem); generic_string desc = pui->describe(); ::SetDlgItemText(_hSelf, IDC_PLUGINADM_EDIT, desc.c_str()); } diff --git a/PowerEditor/src/WinControls/PluginsAdmin/pluginsAdmin.h b/PowerEditor/src/WinControls/PluginsAdmin/pluginsAdmin.h index 3d8953c24..233e0b1b0 100644 --- a/PowerEditor/src/WinControls/PluginsAdmin/pluginsAdmin.h +++ b/PowerEditor/src/WinControls/PluginsAdmin/pluginsAdmin.h @@ -60,6 +60,7 @@ struct PluginUpdateInfo generic_string _md5; generic_string _id; generic_string _repository; + bool _isVisible = true; // if false then it should not be displayed generic_string describe(); PluginUpdateInfo() {}; @@ -100,6 +101,7 @@ public: HWND getViewHwnd() { return _ui.getHSelf(); }; void displayView(bool doShow) const { _ui.display(doShow); }; std::vector getCheckedIndexes() const { return _ui.getCheckedIndexes(); }; + std::vector fromUiIndexesToPluginInfos(const std::vector& ) const; long getSelectedIndex() const { return _ui.getSelectedIndex(); }; void setSelection(int index) const { _ui.setSelection(index); }; void initView(HINSTANCE hInst, HWND parent) { _ui.init(hInst, parent); }; @@ -107,9 +109,15 @@ public: void reSizeView(RECT & rc) { _ui.reSizeTo(rc); } void setViewStyleOption(int32_t extraStyle) { _ui.setStyleOption(extraStyle); }; size_t nbItem() const { return _ui.nbItem(); }; - PluginUpdateInfo* getPluginInfoFromIndex(int index) const { return reinterpret_cast(_ui.getLParamFromIndex(index)); }; + PluginUpdateInfo* getPluginInfoFromUiIndex(int index) const { return reinterpret_cast(_ui.getLParamFromIndex(index)); }; PluginUpdateInfo* findPluginInfoFromFolderName(const generic_string& folderName, int& index) const; - bool removeFromIndex(size_t index2remove); + bool removeFromListIndex(size_t index2remove); + bool hideFromListIndex(size_t index2Hide); + bool removeFromFolderName(const generic_string& folderName); + bool removeFromUiIndex(size_t index2remove); + bool hideFromPluginInfoPtr(PluginUpdateInfo* pluginInfo2hide); + bool restore(const generic_string& folderName); + bool removeFromPluginInfoPtr(PluginUpdateInfo* pluginInfo2hide); private: std::vector _list; @@ -156,9 +164,9 @@ protected: private : TabBar _tab; - PluginViewList _availableList; // All plugins (pluginList.json) - installed plugins - PluginViewList _updateList; // A list returned by gitup.exe - PluginViewList _installedList; // for each installed plugin, check its json file + PluginViewList _availableList; // A permanent list, once it's loaded (no removal - only hide or show) + PluginViewList _updateList; // A dynamical list, items are removable + PluginViewList _installedList; // A dynamical list, items are removable PluginsManager *_pPluginsManager = nullptr; NppCurrentStatus _nppCurrentStatus;