Add incompatible (unloaded) plugin list in Plugin Admin

The plugins which are not compatible but their newer versions are available are not only on the incompatible list, but also on the Updates list.

Fix #12069, close #12105
This commit is contained in:
Don Ho 2022-09-06 05:10:22 +02:00
parent 85d7215d9b
commit 5a94263bee
5 changed files with 156 additions and 36 deletions

View File

@ -317,7 +317,7 @@ int PluginsManager::loadPluginFromPath(const TCHAR *pluginFilePath)
} }
} }
bool PluginsManager::loadPlugins(const TCHAR* dir, const PluginViewList* pluginUpdateInfoList) bool PluginsManager::loadPlugins(const TCHAR* dir, const PluginViewList* pluginUpdateInfoList, PluginViewList* pluginImcompatibleList)
{ {
if (_isDisabled) if (_isDisabled)
return false; return false;
@ -350,6 +350,9 @@ bool PluginsManager::loadPlugins(const TCHAR* dir, const PluginViewList* pluginU
Version nppVer; Version nppVer;
nppVer.setVersionFrom(nppFullPathName); nppVer.setVersionFrom(nppFullPathName);
const TCHAR* incompatibleWarning = L"%s's version %s is not compatible to this version of Notepad++ (v%s).\r\nAs a result the plugin cannot be loaded.";
const TCHAR* incompatibleWarningWithSolution = L"%s's version %s is not compatible to this version of Notepad++ (v%s).\r\nAs a result the plugin cannot be loaded.\r\n\r\nGo to Updates section and update your plugin to %s for solving the compatibility issue.";
// get plugin folder // get plugin folder
if (hFindFolder != INVALID_HANDLE_VALUE && (foundData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) if (hFindFolder != INVALID_HANDLE_VALUE && (foundData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{ {
@ -385,6 +388,16 @@ bool PluginsManager::loadPlugins(const TCHAR* dir, const PluginViewList* pluginU
{ {
// Find compatible Notepad++ versions // Find compatible Notepad++ versions
isCompatible = nppVer.isCompatibleTo(pui->_nppCompatibleVersions.first, pui->_nppCompatibleVersions.second); isCompatible = nppVer.isCompatibleTo(pui->_nppCompatibleVersions.first, pui->_nppCompatibleVersions.second);
if (!isCompatible && pluginImcompatibleList)
{
PluginUpdateInfo* incompatiblePlg = new PluginUpdateInfo(*pui);
incompatiblePlg->_version = v;
TCHAR msg[1024];
wsprintf(msg, incompatibleWarning, incompatiblePlg->_displayName.c_str(), v.toString().c_str(), nppVer.toString().c_str());
incompatiblePlg->_description = msg;
pluginImcompatibleList->pushBack(incompatiblePlg);
}
} }
else if (v < pui->_version && // If dll version is older, and _oldVersionCompatibility is valid (not empty), we search in "_oldVersionCompatibility" else if (v < pui->_version && // If dll version is older, and _oldVersionCompatibility is valid (not empty), we search in "_oldVersionCompatibility"
!(pui->_oldVersionCompatibility.first.first.empty() && pui->_oldVersionCompatibility.first.second.empty()) && // first version interval is valid !(pui->_oldVersionCompatibility.first.first.empty() && pui->_oldVersionCompatibility.first.second.empty()) && // first version interval is valid
@ -393,6 +406,16 @@ bool PluginsManager::loadPlugins(const TCHAR* dir, const PluginViewList* pluginU
if (v.isCompatibleTo(pui->_oldVersionCompatibility.first.first, pui->_oldVersionCompatibility.first.second)) // dll older version found if (v.isCompatibleTo(pui->_oldVersionCompatibility.first.first, pui->_oldVersionCompatibility.first.second)) // dll older version found
{ {
isCompatible = nppVer.isCompatibleTo(pui->_oldVersionCompatibility.second.first, pui->_oldVersionCompatibility.second.second); isCompatible = nppVer.isCompatibleTo(pui->_oldVersionCompatibility.second.first, pui->_oldVersionCompatibility.second.second);
if (!isCompatible && pluginImcompatibleList)
{
PluginUpdateInfo* incompatiblePlg = new PluginUpdateInfo(*pui);
incompatiblePlg->_version = v;
TCHAR msg[1024];
wsprintf(msg, incompatibleWarningWithSolution, incompatiblePlg->_displayName.c_str(), v.toString().c_str(), nppVer.toString().c_str(), pui->_version.toString().c_str());
incompatiblePlg->_description = msg;
pluginImcompatibleList->pushBack(incompatiblePlg);
}
} }
} }
} }
@ -443,6 +466,16 @@ bool PluginsManager::loadPlugins(const TCHAR* dir, const PluginViewList* pluginU
{ {
// Find compatible Notepad++ versions // Find compatible Notepad++ versions
isCompatible2 = nppVer.isCompatibleTo(pui2->_nppCompatibleVersions.first, pui2->_nppCompatibleVersions.second); isCompatible2 = nppVer.isCompatibleTo(pui2->_nppCompatibleVersions.first, pui2->_nppCompatibleVersions.second);
if (!isCompatible2 && pluginImcompatibleList)
{
PluginUpdateInfo* incompatiblePlg = new PluginUpdateInfo(*pui2);
incompatiblePlg->_version = v2;
TCHAR msg[1024];
wsprintf(msg, incompatibleWarning, incompatiblePlg->_displayName.c_str(), v2.toString().c_str(), nppVer.toString().c_str());
incompatiblePlg->_description = msg;
pluginImcompatibleList->pushBack(incompatiblePlg);
}
} }
else if (v2 < pui2->_version && // If dll version is older, and _oldVersionCompatibility is valid (not empty), we search in "_oldVersionCompatibility" else if (v2 < pui2->_version && // If dll version is older, and _oldVersionCompatibility is valid (not empty), we search in "_oldVersionCompatibility"
!(pui2->_oldVersionCompatibility.first.first.empty() && pui2->_oldVersionCompatibility.first.second.empty()) && // first version interval is valid !(pui2->_oldVersionCompatibility.first.first.empty() && pui2->_oldVersionCompatibility.first.second.empty()) && // first version interval is valid
@ -451,6 +484,16 @@ bool PluginsManager::loadPlugins(const TCHAR* dir, const PluginViewList* pluginU
if (v2.isCompatibleTo(pui2->_oldVersionCompatibility.first.first, pui2->_oldVersionCompatibility.first.second)) // dll older version found if (v2.isCompatibleTo(pui2->_oldVersionCompatibility.first.first, pui2->_oldVersionCompatibility.first.second)) // dll older version found
{ {
isCompatible2 = nppVer.isCompatibleTo(pui2->_oldVersionCompatibility.second.first, pui2->_oldVersionCompatibility.second.second); isCompatible2 = nppVer.isCompatibleTo(pui2->_oldVersionCompatibility.second.first, pui2->_oldVersionCompatibility.second.second);
if (!isCompatible2 && pluginImcompatibleList)
{
PluginUpdateInfo* incompatiblePlg = new PluginUpdateInfo(*pui2);
incompatiblePlg->_version = v2;
TCHAR msg[1024];
wsprintf(msg, incompatibleWarningWithSolution, incompatiblePlg->_displayName.c_str(), v2.toString().c_str(), nppVer.toString().c_str(), pui2->_version.toString().c_str());
incompatiblePlg->_description = msg;
pluginImcompatibleList->pushBack(incompatiblePlg);
}
} }
} }
} }

View File

@ -91,7 +91,7 @@ public:
_nppData = nppData; _nppData = nppData;
} }
bool loadPlugins(const TCHAR *dir = NULL, const PluginViewList* pluginUpdateInfoList = nullptr); bool loadPlugins(const TCHAR *dir = NULL, const PluginViewList* pluginUpdateInfoList = nullptr, PluginViewList* pluginImcompatibleList = nullptr);
bool unloadPlugin(int index, HWND nppHandle); bool unloadPlugin(int index, HWND nppHandle);
@ -133,16 +133,14 @@ private:
int loadPluginFromPath(const TCHAR* pluginFilePath); int loadPluginFromPath(const TCHAR* pluginFilePath);
void pluginCrashAlert(const TCHAR *pluginName, const TCHAR *funcSignature) void pluginCrashAlert(const TCHAR *pluginName, const TCHAR *funcSignature) {
{
generic_string msg = pluginName; generic_string msg = pluginName;
msg += TEXT(" just crashed in\r"); msg += TEXT(" just crashed in\r");
msg += funcSignature; msg += funcSignature;
::MessageBox(NULL, msg.c_str(), TEXT("Plugin Crash"), MB_OK|MB_ICONSTOP); ::MessageBox(NULL, msg.c_str(), TEXT("Plugin Crash"), MB_OK|MB_ICONSTOP);
} }
void pluginExceptionAlert(const TCHAR *pluginName, const std::exception& e) void pluginExceptionAlert(const TCHAR *pluginName, const std::exception& e) {
{
generic_string msg = TEXT("An exception occurred due to plugin: "); generic_string msg = TEXT("An exception occurred due to plugin: ");
msg += pluginName; msg += pluginName;
msg += TEXT("\r\n\r\nException reason: "); msg += TEXT("\r\n\r\nException reason: ");
@ -151,8 +149,7 @@ private:
::MessageBox(NULL, msg.c_str(), TEXT("Plugin Exception"), MB_OK); ::MessageBox(NULL, msg.c_str(), TEXT("Plugin Exception"), MB_OK);
} }
bool isInLoadedDlls(const TCHAR *fn) const bool isInLoadedDlls(const TCHAR *fn) const {
{
for (size_t i = 0; i < _loadedDlls.size(); ++i) for (size_t i = 0; i < _loadedDlls.size(); ++i)
if (generic_stricmp(fn, _loadedDlls[i]._fileName.c_str()) == 0) if (generic_stricmp(fn, _loadedDlls[i]._fileName.c_str()) == 0)
return true; return true;

View File

@ -425,7 +425,7 @@ LRESULT Notepad_plus::init(HWND hwnd)
_pluginsManager.init(nppData); _pluginsManager.init(nppData);
bool enablePluginAdmin = _pluginsAdminDlg.initFromJson(); bool enablePluginAdmin = _pluginsAdminDlg.initFromJson();
_pluginsManager.loadPlugins(nppParam.getPluginRootDir(), enablePluginAdmin ? &_pluginsAdminDlg.getAvailablePluginUpdateInfoList() : nullptr); _pluginsManager.loadPlugins(nppParam.getPluginRootDir(), enablePluginAdmin ? &_pluginsAdminDlg.getAvailablePluginUpdateInfoList() : nullptr, enablePluginAdmin ? &_pluginsAdminDlg.getIncompatibleList() : nullptr);
_restoreButton.init(_pPublicInterface->getHinst(), hwnd); _restoreButton.init(_pPublicInterface->getHinst(), hwnd);
// ------------ // // ------------ //

View File

@ -139,10 +139,12 @@ void PluginsAdminDlg::create(int dialogID, bool isRTL, bool msgDestParent)
const TCHAR *available = TEXT("Available"); const TCHAR *available = TEXT("Available");
const TCHAR *updates = TEXT("Updates"); const TCHAR *updates = TEXT("Updates");
const TCHAR *installed = TEXT("Installed"); const TCHAR *installed = TEXT("Installed");
const TCHAR *incompatible = TEXT("Incompatible");
_tab.insertAtEnd(available); _tab.insertAtEnd(available);
_tab.insertAtEnd(updates); _tab.insertAtEnd(updates);
_tab.insertAtEnd(installed); _tab.insertAtEnd(installed);
_tab.insertAtEnd(incompatible);
rect.bottom -= dpiManager.scaleX(100); rect.bottom -= dpiManager.scaleX(100);
_tab.reSizeTo(rect); _tab.reSizeTo(rect);
@ -216,50 +218,46 @@ void PluginsAdminDlg::create(int dialogID, bool isRTL, bool msgDestParent)
NativeLangSpeaker *pNativeSpeaker = nppParam.getNativeLangSpeaker(); NativeLangSpeaker *pNativeSpeaker = nppParam.getNativeLangSpeaker();
generic_string pluginStr = pNativeSpeaker->getAttrNameStr(TEXT("Plugin"), "PluginAdmin", "Plugin"); generic_string pluginStr = pNativeSpeaker->getAttrNameStr(TEXT("Plugin"), "PluginAdmin", "Plugin");
generic_string vesionStr = pNativeSpeaker->getAttrNameStr(TEXT("Version"), "PluginAdmin", "Version"); generic_string vesionStr = pNativeSpeaker->getAttrNameStr(TEXT("Version"), "PluginAdmin", "Version");
//generic_string stabilityStr = pNativeSpeaker->getAttrNameStr(TEXT("Stability"), "PluginAdmin", "Stability");
_availableList.addColumn(columnInfo(pluginStr, nppParam._dpiManager.scaleX(200)));
_availableList.addColumn(columnInfo(vesionStr, nppParam._dpiManager.scaleX(100)));
//_availableList.addColumn(columnInfo(stabilityStr, nppParam._dpiManager.scaleX(70)));
_availableList.setViewStyleOption(LVS_EX_CHECKBOXES);
COLORREF fgColor = (NppParameters::getInstance()).getCurrentDefaultFgColor(); COLORREF fgColor = (NppParameters::getInstance()).getCurrentDefaultFgColor();
COLORREF bgColor = (NppParameters::getInstance()).getCurrentDefaultBgColor(); COLORREF bgColor = (NppParameters::getInstance()).getCurrentDefaultBgColor();
_availableList.addColumn(columnInfo(pluginStr, nppParam._dpiManager.scaleX(200)));
_availableList.addColumn(columnInfo(vesionStr, nppParam._dpiManager.scaleX(100)));
_availableList.setViewStyleOption(LVS_EX_CHECKBOXES);
_availableList.initView(_hInst, _hSelf); _availableList.initView(_hInst, _hSelf);
ListView_SetBkColor(_availableList.getViewHwnd(), bgColor); ListView_SetBkColor(_availableList.getViewHwnd(), bgColor);
ListView_SetTextBkColor(_availableList.getViewHwnd(), bgColor); ListView_SetTextBkColor(_availableList.getViewHwnd(), bgColor);
ListView_SetTextColor(_availableList.getViewHwnd(), fgColor); ListView_SetTextColor(_availableList.getViewHwnd(), fgColor);
_availableList.reSizeView(listRect); _availableList.reSizeView(listRect);
_updateList.addColumn(columnInfo(pluginStr, nppParam._dpiManager.scaleX(200))); _updateList.addColumn(columnInfo(pluginStr, nppParam._dpiManager.scaleX(200)));
_updateList.addColumn(columnInfo(vesionStr, nppParam._dpiManager.scaleX(100))); _updateList.addColumn(columnInfo(vesionStr, nppParam._dpiManager.scaleX(100)));
//_updateList.addColumn(columnInfo(stabilityStr, nppParam._dpiManager.scaleX(70)));
_updateList.setViewStyleOption(LVS_EX_CHECKBOXES); _updateList.setViewStyleOption(LVS_EX_CHECKBOXES);
_updateList.initView(_hInst, _hSelf); _updateList.initView(_hInst, _hSelf);
ListView_SetBkColor(_updateList.getViewHwnd(), bgColor); ListView_SetBkColor(_updateList.getViewHwnd(), bgColor);
ListView_SetTextBkColor(_updateList.getViewHwnd(), bgColor); ListView_SetTextBkColor(_updateList.getViewHwnd(), bgColor);
ListView_SetTextColor(_updateList.getViewHwnd(), fgColor); ListView_SetTextColor(_updateList.getViewHwnd(), fgColor);
_updateList.reSizeView(listRect); _updateList.reSizeView(listRect);
_installedList.addColumn(columnInfo(pluginStr, nppParam._dpiManager.scaleX(200))); _installedList.addColumn(columnInfo(pluginStr, nppParam._dpiManager.scaleX(200)));
_installedList.addColumn(columnInfo(vesionStr, nppParam._dpiManager.scaleX(100))); _installedList.addColumn(columnInfo(vesionStr, nppParam._dpiManager.scaleX(100)));
//_installedList.addColumn(columnInfo(stabilityStr, nppParam._dpiManager.scaleX(70)));
_installedList.setViewStyleOption(LVS_EX_CHECKBOXES); _installedList.setViewStyleOption(LVS_EX_CHECKBOXES);
_installedList.initView(_hInst, _hSelf); _installedList.initView(_hInst, _hSelf);
ListView_SetBkColor(_installedList.getViewHwnd(), bgColor); ListView_SetBkColor(_installedList.getViewHwnd(), bgColor);
ListView_SetTextBkColor(_installedList.getViewHwnd(), bgColor); ListView_SetTextBkColor(_installedList.getViewHwnd(), bgColor);
ListView_SetTextColor(_installedList.getViewHwnd(), fgColor); ListView_SetTextColor(_installedList.getViewHwnd(), fgColor);
_installedList.reSizeView(listRect); _installedList.reSizeView(listRect);
_incompatibleList.addColumn(columnInfo(pluginStr, nppParam._dpiManager.scaleX(200)));
_incompatibleList.addColumn(columnInfo(vesionStr, nppParam._dpiManager.scaleX(100)));
_incompatibleList.initView(_hInst, _hSelf);
ListView_SetBkColor(_incompatibleList.getViewHwnd(), bgColor);
ListView_SetTextBkColor(_incompatibleList.getViewHwnd(), bgColor);
ListView_SetTextColor(_incompatibleList.getViewHwnd(), fgColor);
_incompatibleList.reSizeView(listRect);
HWND hDesc = ::GetDlgItem(_hSelf, IDC_PLUGINADM_EDIT); HWND hDesc = ::GetDlgItem(_hSelf, IDC_PLUGINADM_EDIT);
::MoveWindow(hDesc, descRect.left, descRect.top, descRect.right, descRect.bottom, TRUE); ::MoveWindow(hDesc, descRect.left, descRect.top, descRect.right, descRect.bottom, TRUE);
::InvalidateRect(hDesc, nullptr, TRUE); ::InvalidateRect(hDesc, nullptr, TRUE);
@ -466,6 +464,7 @@ void PluginsAdminDlg::changeColumnName(COLUMN_TYPE index, const TCHAR *name2chan
_availableList.changeColumnName(index, name2change); _availableList.changeColumnName(index, name2change);
_updateList.changeColumnName(index, name2change); _updateList.changeColumnName(index, name2change);
_installedList.changeColumnName(index, name2change); _installedList.changeColumnName(index, name2change);
_incompatibleList.changeColumnName(index, name2change);
} }
void PluginViewList::changeColumnName(COLUMN_TYPE index, const TCHAR *name2change) void PluginViewList::changeColumnName(COLUMN_TYPE index, const TCHAR *name2change)
@ -788,6 +787,9 @@ bool PluginsAdminDlg::updateList()
// initialize update list view // initialize update list view
checkUpdates(); checkUpdates();
// initialize incompatible list view
initIncompatiblePluginList();
// initialize installed list view // initialize installed list view
loadFromPluginInfos(); loadFromPluginInfos();
@ -823,6 +825,30 @@ bool PluginsAdminDlg::initAvailablePluginsViewFromList()
return true; return true;
} }
bool PluginsAdminDlg::initIncompatiblePluginList()
{
TCHAR nppFullPathName[MAX_PATH];
GetModuleFileName(NULL, nppFullPathName, MAX_PATH);
Version nppVer;
nppVer.setVersionFrom(nppFullPathName);
for (const auto& i : _incompatibleList._list)
{
vector<generic_string> values2Add;
values2Add.push_back(i->_displayName);
Version v = i->_version;
values2Add.push_back(v.toString());
// add in order
size_t j = _incompatibleList._ui.findAlphabeticalOrderPos(i->_displayName, _incompatibleList._sortType == DISPLAY_NAME_ALPHABET_ENCREASE ? ListView::sortEncrease : ListView::sortDecrease);
_incompatibleList._ui.addLine(values2Add, reinterpret_cast<LPARAM>(i), static_cast<int>(j));
}
return true;
}
bool PluginsAdminDlg::loadFromPluginInfos() bool PluginsAdminDlg::loadFromPluginInfos()
{ {
if (!_pPluginsManager) if (!_pPluginsManager)
@ -868,6 +894,27 @@ bool PluginsAdminDlg::loadFromPluginInfos()
} }
} }
// Search from unloaded incompatible plugins
for (size_t j = 0, nb = _incompatibleList.nbItem(); j < nb; j++)
{
PluginUpdateInfo* incompatiblePluginInfo = _incompatibleList.getPluginInfoFromUiIndex(j);
int listIndex;
PluginUpdateInfo* foundInfoOfAvailable = _availableList.findPluginInfoFromFolderName(incompatiblePluginInfo->_folderName, listIndex);
if (foundInfoOfAvailable)
{
// if the incompatible plugin version is smaller than the one on the available list, put it in the update list
if (foundInfoOfAvailable->_version > incompatiblePluginInfo->_version)
{
// Hide it from the available list
_availableList.hideFromListIndex(listIndex);
PluginUpdateInfo* pui = new PluginUpdateInfo(*foundInfoOfAvailable);
_updateList.pushBack(pui);
}
}
}
return true; return true;
} }
@ -1024,7 +1071,7 @@ bool PluginsAdminDlg::searchInPlugins(bool isNextMode) const
void PluginsAdminDlg::switchDialog(int indexToSwitch) void PluginsAdminDlg::switchDialog(int indexToSwitch)
{ {
generic_string desc; generic_string desc;
bool showAvailable, showUpdate, showInstalled; bool showAvailable, showUpdate, showInstalled, showIncompatibile;
switch (indexToSwitch) switch (indexToSwitch)
{ {
case 0: // available plugins case 0: // available plugins
@ -1032,6 +1079,7 @@ void PluginsAdminDlg::switchDialog(int indexToSwitch)
showAvailable = true; showAvailable = true;
showUpdate = false; showUpdate = false;
showInstalled = false; showInstalled = false;
showIncompatibile = false;
long infoIndex = _availableList.getSelectedIndex(); long infoIndex = _availableList.getSelectedIndex();
if (infoIndex != -1 && infoIndex < static_cast<long>(_availableList.nbItem())) if (infoIndex != -1 && infoIndex < static_cast<long>(_availableList.nbItem()))
@ -1044,6 +1092,7 @@ void PluginsAdminDlg::switchDialog(int indexToSwitch)
showAvailable = false; showAvailable = false;
showUpdate = true; showUpdate = true;
showInstalled = false; showInstalled = false;
showIncompatibile = false;
long infoIndex = _updateList.getSelectedIndex(); long infoIndex = _updateList.getSelectedIndex();
if (infoIndex != -1 && infoIndex < static_cast<long>(_updateList.nbItem())) if (infoIndex != -1 && infoIndex < static_cast<long>(_updateList.nbItem()))
@ -1056,6 +1105,7 @@ void PluginsAdminDlg::switchDialog(int indexToSwitch)
showAvailable = false; showAvailable = false;
showUpdate = false; showUpdate = false;
showInstalled = true; showInstalled = true;
showIncompatibile = false;
long infoIndex = _installedList.getSelectedIndex(); long infoIndex = _installedList.getSelectedIndex();
if (infoIndex != -1 && infoIndex < static_cast<long>(_installedList.nbItem())) if (infoIndex != -1 && infoIndex < static_cast<long>(_installedList.nbItem()))
@ -1063,6 +1113,19 @@ void PluginsAdminDlg::switchDialog(int indexToSwitch)
} }
break; break;
case 3: // incompability plugins
{
showAvailable = false;
showUpdate = false;
showInstalled = false;
showIncompatibile = true;
long infoIndex = _incompatibleList.getSelectedIndex();
if (infoIndex != -1 && infoIndex < static_cast<long>(_incompatibleList.nbItem()))
desc = _incompatibleList.getPluginInfoFromUiIndex(infoIndex)->_description;
}
break;
default: default:
return; return;
} }
@ -1070,6 +1133,7 @@ void PluginsAdminDlg::switchDialog(int indexToSwitch)
_availableList.displayView(showAvailable); _availableList.displayView(showAvailable);
_updateList.displayView(showUpdate); _updateList.displayView(showUpdate);
_installedList.displayView(showInstalled); _installedList.displayView(showInstalled);
_incompatibleList.displayView(showIncompatibile);
::SetDlgItemText(_hSelf, IDC_PLUGINADM_EDIT, desc.c_str()); ::SetDlgItemText(_hSelf, IDC_PLUGINADM_EDIT, desc.c_str());
@ -1219,7 +1283,8 @@ intptr_t CALLBACK PluginsAdminDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR
} }
else if (pnmh->hwndFrom == _availableList.getViewHwnd() || else if (pnmh->hwndFrom == _availableList.getViewHwnd() ||
pnmh->hwndFrom == _updateList.getViewHwnd() || pnmh->hwndFrom == _updateList.getViewHwnd() ||
pnmh->hwndFrom == _installedList.getViewHwnd()) pnmh->hwndFrom == _installedList.getViewHwnd() ||
pnmh->hwndFrom == _incompatibleList.getViewHwnd())
{ {
PluginViewList* pViewList; PluginViewList* pViewList;
int buttonID; int buttonID;
@ -1234,11 +1299,16 @@ intptr_t CALLBACK PluginsAdminDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR
pViewList = &_updateList; pViewList = &_updateList;
buttonID = IDC_PLUGINADM_UPDATE; buttonID = IDC_PLUGINADM_UPDATE;
} }
else // pnmh->hwndFrom == _installedList.getViewHwnd() else if (pnmh->hwndFrom == _installedList.getViewHwnd())
{ {
pViewList = &_installedList; pViewList = &_installedList;
buttonID = IDC_PLUGINADM_REMOVE; buttonID = IDC_PLUGINADM_REMOVE;
} }
else // pnmh->hwndFrom == _incompatibleList.getViewHwnd()
{
pViewList = &_incompatibleList;
buttonID = 0;
}
LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam; LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam;
@ -1249,16 +1319,19 @@ intptr_t CALLBACK PluginsAdminDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR
if ((pnmv->uNewState & LVIS_STATEIMAGEMASK) == INDEXTOSTATEIMAGEMASK(2) || // checked if ((pnmv->uNewState & LVIS_STATEIMAGEMASK) == INDEXTOSTATEIMAGEMASK(2) || // checked
(pnmv->uNewState & LVIS_STATEIMAGEMASK) == INDEXTOSTATEIMAGEMASK(1)) // unchecked (pnmv->uNewState & LVIS_STATEIMAGEMASK) == INDEXTOSTATEIMAGEMASK(1)) // unchecked
{ {
HWND hButton = ::GetDlgItem(_hSelf, buttonID); if (buttonID)
vector<size_t> checkedArray = pViewList->getCheckedIndexes(); {
bool showButton = checkedArray.size() > 0; HWND hButton = ::GetDlgItem(_hSelf, buttonID);
vector<size_t> checkedArray = pViewList->getCheckedIndexes();
bool showButton = checkedArray.size() > 0;
::EnableWindow(hButton, showButton); ::EnableWindow(hButton, showButton);
}
} }
else if (pnmv->uNewState & LVIS_SELECTED) else if (pnmv->uNewState & LVIS_SELECTED)
{ {
PluginUpdateInfo* pui = pViewList->getPluginInfoFromUiIndex(pnmv->iItem); PluginUpdateInfo* pui = pViewList->getPluginInfoFromUiIndex(pnmv->iItem);
generic_string desc = pui->describe(); generic_string desc = buttonID ? pui->describe() : pui->_description;
::SetDlgItemText(_hSelf, IDC_PLUGINADM_EDIT, desc.c_str()); ::SetDlgItemText(_hSelf, IDC_PLUGINADM_EDIT, desc.c_str());
} }
} }

View File

@ -128,6 +128,7 @@ public:
void changeColumnName(COLUMN_TYPE index, const TCHAR *name2change); void changeColumnName(COLUMN_TYPE index, const TCHAR *name2change);
private: private:
// _list & _ui should keep being synchronized
std::vector<PluginUpdateInfo*> _list; std::vector<PluginUpdateInfo*> _list;
ListView _ui; ListView _ui;
@ -180,6 +181,10 @@ public :
const PluginViewList & getAvailablePluginUpdateInfoList() const { const PluginViewList & getAvailablePluginUpdateInfoList() const {
return _availableList; return _availableList;
}; };
PluginViewList & getIncompatibleList() {
return _incompatibleList;
};
protected: protected:
virtual intptr_t CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); virtual intptr_t CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam);
@ -191,9 +196,10 @@ private :
TabBar _tab; TabBar _tab;
PluginViewList _availableList; // A permanent list, once it's loaded (no removal - only hide or show) PluginViewList _availableList; // A permanent list, once it's loaded (no removal - only hide or show)
PluginViewList _updateList; // A dynamical list, items are removable PluginViewList _updateList; // A dynamical list, items are removable
PluginViewList _installedList; // A dynamical list, items are removable PluginViewList _installedList; // A dynamical list, items are removable
PluginViewList _incompatibleList; // A permanent list, once it's loaded (no removal - only hide or show)
PluginsManager *_pPluginsManager = nullptr; PluginsManager *_pPluginsManager = nullptr;
NppCurrentStatus _nppCurrentStatus; NppCurrentStatus _nppCurrentStatus;
@ -213,6 +219,7 @@ private :
}; };
bool initAvailablePluginsViewFromList(); bool initAvailablePluginsViewFromList();
bool initIncompatiblePluginList();
bool loadFromPluginInfos(); bool loadFromPluginInfos();
bool checkUpdates(); bool checkUpdates();