YFX_BRANCH注释

YFX_BRANCH
Feixiu Yao 1 year ago
parent 5e5c5aa9c7
commit 541a642a52

@ -16,291 +16,331 @@
// 引入LastRecentFileList类的头文件
#include "lastRecentFileList.h" #include "lastRecentFileList.h"
// 引入菜单命令ID的头文件
#include "menuCmdID.h" #include "menuCmdID.h"
// 引入本地化的头文件,可能用于支持多语言
#include "localization.h" #include "localization.h"
void LastRecentFileList::initMenu(HMENU hMenu, int idBase, int posBase, Accelerator *pAccelerator, bool doSubMenu) // LastRecentFileList类的initMenu函数
void LastRecentFileList::initMenu(HMENU hMenu, int idBase, int posBase, Accelerator* pAccelerator, bool doSubMenu)
{ {
if (doSubMenu) // 如果doSubMenu为真表示需要创建一个弹出菜单
{ if (doSubMenu)
_hParentMenu = hMenu; {
_hMenu = ::CreatePopupMenu(); // 设置父菜单句柄
} _hParentMenu = hMenu;
else // 创建一个新的弹出菜单
{ _hMenu = ::CreatePopupMenu();
_hParentMenu = NULL; }
_hMenu = hMenu; // 如果doSubMenu为假表示直接使用传入的菜单句柄
} else
{
_idBase = idBase; // 设置父菜单句柄为NULL表示主菜单
_posBase = posBase; _hParentMenu = NULL;
_pAccelerator = pAccelerator; // 使用传入的菜单句柄作为当前菜单
_nativeLangEncoding = NPP_CP_WIN_1252; _hMenu = hMenu;
}
for (size_t i = 0 ; i < sizeof(_idFreeArray) ; ++i)
_idFreeArray[i] = true; // 设置ID的基础值
_idBase = idBase;
// 设置位置的基础值
_posBase = posBase;
// 设置指向Accelerator对象的指针用于处理键盘快捷键等加速功能
_pAccelerator = pAccelerator;
// 设置本地化语言编码为Windows的1252编码这是一种西欧语言编码
_nativeLangEncoding = NPP_CP_WIN_1252;
// 初始化idFreeArray数组所有元素都设置为true表示ID可用
for (size_t i = 0; i < sizeof(_idFreeArray); ++i)
_idFreeArray[i] = true;
} }
// LastRecentFileList类的switchMode函数用于切换模式
void LastRecentFileList::switchMode() void LastRecentFileList::switchMode()
{ {
//Remove all menu items // 从菜单中移除所有相关菜单项
::RemoveMenu(_hMenu, IDM_FILE_RESTORELASTCLOSEDFILE, MF_BYCOMMAND); ::RemoveMenu(_hMenu, IDM_FILE_RESTORELASTCLOSEDFILE, MF_BYCOMMAND);
::RemoveMenu(_hMenu, IDM_OPEN_ALL_RECENT_FILE, MF_BYCOMMAND); ::RemoveMenu(_hMenu, IDM_OPEN_ALL_RECENT_FILE, MF_BYCOMMAND);
::RemoveMenu(_hMenu, IDM_CLEAN_RECENT_FILE_LIST, MF_BYCOMMAND); ::RemoveMenu(_hMenu, IDM_CLEAN_RECENT_FILE_LIST, MF_BYCOMMAND);
for (int i = 0; i < _size; ++i) // 遍历最近打开文件列表,移除所有菜单项
{ for (int i = 0; i < _size; ++i)
::RemoveMenu(_hMenu, _lrfl.at(i)._id, MF_BYCOMMAND); {
} ::RemoveMenu(_hMenu, _lrfl.at(i)._id, MF_BYCOMMAND);
}
if (_hParentMenu == NULL) // mode main menu
{ if (_size > 0) // 根据_hParentMenu的值判断当前模式主菜单模式或子菜单模式
{ if (_hParentMenu == NULL) // mode main menu主菜单模式
::RemoveMenu(_hMenu, _posBase, MF_BYPOSITION); {
::RemoveMenu(_hMenu, _posBase, MF_BYPOSITION); if (_size > 0) // 如果最近打开文件列表不为空
} {
// switch to sub-menu mode // 从主菜单中移除一些特定的菜单项(具体移除哪些项未给出)
_hParentMenu = _hMenu; ::RemoveMenu(_hMenu, _posBase, MF_BYPOSITION);
_hMenu = ::CreatePopupMenu(); ::RemoveMenu(_hMenu, _posBase, MF_BYPOSITION);
::RemoveMenu(_hMenu, _posBase+1, MF_BYPOSITION); }
} // 切换到子菜单模式创建一个新的弹出菜单作为当前菜单并设置_hParentMenu为当前菜单即新创建的弹出菜单
else // mode sub-menu // 同时移除一些特定的菜单项(具体移除哪些项未给出)
{ _hParentMenu = _hMenu;
if (_size > 0) _hMenu = ::CreatePopupMenu();
{ ::RemoveMenu(_hMenu, _posBase + 1, MF_BYPOSITION);
::RemoveMenu(_hParentMenu, _posBase, MF_BYPOSITION); }
::RemoveMenu(_hParentMenu, _posBase, MF_BYPOSITION); else // mode sub-menu子菜单模式
} {
// switch to main menu mode if (_size > 0) // 如果最近打开文件列表不为空
::DestroyMenu(_hMenu); {
_hMenu = _hParentMenu; // 从子菜单中移除一些特定的菜单项(具体移除哪些项未给出)
_hParentMenu = NULL; ::RemoveMenu(_hParentMenu, _posBase, MF_BYPOSITION);
} ::RemoveMenu(_hParentMenu, _posBase, MF_BYPOSITION);
_hasSeparators = false; }
// switch to main menu mode
::DestroyMenu(_hMenu);
_hMenu = _hParentMenu;
_hParentMenu = NULL;
}
_hasSeparators = false;
} }
void LastRecentFileList::updateMenu() void LastRecentFileList::updateMenu()
{ {
NppParameters& nppParam = NppParameters::getInstance(); // 获取 NppParameters 的单例实例
NppParameters& nppParam = NppParameters::getInstance();
if (!_hasSeparators && _size > 0)
{ // 检查是否没有分隔符且大小大于0满足条件则进入下面的 if 语句块
//add separators if (!_hasSeparators && _size > 0)
NativeLangSpeaker *pNativeLangSpeaker = nppParam.getNativeLangSpeaker(); {
// 获取本地化语言的发言人对象
generic_string recentFileList = pNativeLangSpeaker->getSubMenuEntryName("file-recentFiles"); NativeLangSpeaker* pNativeLangSpeaker = nppParam.getNativeLangSpeaker();
generic_string openRecentClosedFile = pNativeLangSpeaker->getNativeLangMenuString(IDM_FILE_RESTORELASTCLOSEDFILE);
generic_string openAllFiles = pNativeLangSpeaker->getNativeLangMenuString(IDM_OPEN_ALL_RECENT_FILE); // 从发言人对象中获取一些本地化菜单字符串
generic_string cleanFileList = pNativeLangSpeaker->getNativeLangMenuString(IDM_CLEAN_RECENT_FILE_LIST); generic_string recentFileList = pNativeLangSpeaker->getSubMenuEntryName("file-recentFiles");
generic_string openRecentClosedFile = pNativeLangSpeaker->getNativeLangMenuString(IDM_FILE_RESTORELASTCLOSEDFILE);
if (recentFileList == TEXT("")) generic_string openAllFiles = pNativeLangSpeaker->getNativeLangMenuString(IDM_OPEN_ALL_RECENT_FILE);
recentFileList = TEXT("&Recent Files"); generic_string cleanFileList = pNativeLangSpeaker->getNativeLangMenuString(IDM_CLEAN_RECENT_FILE_LIST);
if (openRecentClosedFile == TEXT(""))
openRecentClosedFile = TEXT("Restore Recent Closed File"); // 如果获取的字符串为空,则使用默认的字符串进行初始化
if (openAllFiles == TEXT("")) if (recentFileList == TEXT(""))
openAllFiles = TEXT("Open All Recent Files"); recentFileList = TEXT("&Recent Files");
if (cleanFileList == TEXT("")) if (openRecentClosedFile == TEXT(""))
cleanFileList = TEXT("Empty Recent Files List"); openRecentClosedFile = TEXT("Restore Recent Closed File");
if (openAllFiles == TEXT(""))
if (!isSubMenuMode()) openAllFiles = TEXT("Open All Recent Files");
::InsertMenu(_hMenu, _posBase + 0, MF_BYPOSITION, static_cast<UINT_PTR>(-1), 0); if (cleanFileList == TEXT(""))
cleanFileList = TEXT("Empty Recent Files List");
::InsertMenu(_hMenu, _posBase + 1, MF_BYPOSITION, IDM_FILE_RESTORELASTCLOSEDFILE, openRecentClosedFile.c_str());
::InsertMenu(_hMenu, _posBase + 2, MF_BYPOSITION, IDM_OPEN_ALL_RECENT_FILE, openAllFiles.c_str()); // 如果当前不是子菜单模式,则在菜单中插入一个分隔符
::InsertMenu(_hMenu, _posBase + 3, MF_BYPOSITION, IDM_CLEAN_RECENT_FILE_LIST, cleanFileList.c_str()); if (!isSubMenuMode())
::InsertMenu(_hMenu, _posBase + 4, MF_BYPOSITION, static_cast<UINT_PTR>(-1), 0); ::InsertMenu(_hMenu, _posBase + 0, MF_BYPOSITION, static_cast<UINT_PTR>(-1), 0);
_hasSeparators = true;
// 在菜单中插入四个子菜单项,分别是恢复最近关闭的文件、打开所有最近文件、清空最近文件列表和另一个分隔符
if (isSubMenuMode()) ::InsertMenu(_hMenu, _posBase + 1, MF_BYPOSITION, IDM_FILE_RESTORELASTCLOSEDFILE, openRecentClosedFile.c_str());
{ ::InsertMenu(_hMenu, _posBase + 2, MF_BYPOSITION, IDM_OPEN_ALL_RECENT_FILE, openAllFiles.c_str());
::InsertMenu(_hParentMenu, _posBase + 0, MF_BYPOSITION | MF_POPUP, reinterpret_cast<UINT_PTR>(_hMenu), (LPCTSTR)recentFileList.c_str()); ::InsertMenu(_hMenu, _posBase + 3, MF_BYPOSITION, IDM_CLEAN_RECENT_FILE_LIST, cleanFileList.c_str());
::InsertMenu(_hParentMenu, _posBase + 1, MF_BYPOSITION, static_cast<UINT_PTR>(-1), 0); ::InsertMenu(_hMenu, _posBase + 4, MF_BYPOSITION, static_cast<UINT_PTR>(-1), 0); // 插入分隔符
} // 设置标志表示已有分隔符
} _hasSeparators = true;
else if (_hasSeparators && _size == 0) //remove separators
{ // 如果当前是子菜单模式,则在父菜单中插入子菜单和分隔符
::RemoveMenu(_hMenu, _posBase + 4, MF_BYPOSITION); if (isSubMenuMode())
::RemoveMenu(_hMenu, IDM_CLEAN_RECENT_FILE_LIST, MF_BYCOMMAND); {
::RemoveMenu(_hMenu, IDM_OPEN_ALL_RECENT_FILE, MF_BYCOMMAND); ::InsertMenu(_hParentMenu, _posBase + 0, MF_BYPOSITION | MF_POPUP, reinterpret_cast<UINT_PTR>(_hMenu), (LPCTSTR)recentFileList.c_str());
::RemoveMenu(_hMenu, IDM_FILE_RESTORELASTCLOSEDFILE, MF_BYCOMMAND); ::InsertMenu(_hParentMenu, _posBase + 1, MF_BYPOSITION, static_cast<UINT_PTR>(-1), 0); // 插入分隔符
::RemoveMenu(_hMenu, _posBase + 0, MF_BYPOSITION); }
_hasSeparators = false; }
else if (_hasSeparators && _size == 0) // 当已有分隔符且大小为0时进入下面的 if 语句块,用于移除分隔符和菜单项
if (isSubMenuMode()) {
{ // 从菜单中移除一个分隔符和清空最近文件列表的菜单项
// Remove "Recent Files" Entry and the separator from the main menu ::RemoveMenu(_hMenu, _posBase + 4, MF_BYPOSITION);
::RemoveMenu(_hParentMenu, _posBase + 1, MF_BYPOSITION); ::RemoveMenu(_hMenu, IDM_CLEAN_RECENT_FILE_LIST, MF_BYCOMMAND);
::RemoveMenu(_hParentMenu, _posBase + 0, MF_BYPOSITION); ::RemoveMenu(_hMenu, IDM_OPEN_ALL_RECENT_FILE, MF_BYCOMMAND);
::RemoveMenu(_hMenu, IDM_FILE_RESTORELASTCLOSEDFILE, MF_BYCOMMAND);
// Remove the last left separator from the submenu ::RemoveMenu(_hMenu, _posBase + 0, MF_BYPOSITION);
::RemoveMenu(_hMenu, 0, MF_BYPOSITION); _hasSeparators = false;
}
} if (isSubMenuMode())
{
_pAccelerator->updateFullMenu(); // Remove "Recent Files" Entry and the separator from the main menu
::RemoveMenu(_hParentMenu, _posBase + 1, MF_BYPOSITION);
//Remove all menu items ::RemoveMenu(_hParentMenu, _posBase + 0, MF_BYPOSITION);
for (int i = 0; i < _size; ++i)
{ // Remove the last left separator from the submenu
::RemoveMenu(_hMenu, _lrfl.at(i)._id, MF_BYCOMMAND); ::RemoveMenu(_hMenu, 0, MF_BYPOSITION);
} }
//Then readd them, so everything stays in sync }
for (int j = 0; j < _size; ++j)
{ _pAccelerator->updateFullMenu();
generic_string strBuffer(BuildMenuFileName(nppParam.getRecentFileCustomLength(), j, _lrfl.at(j)._name));
::InsertMenu(_hMenu, _posBase + j, MF_BYPOSITION, _lrfl.at(j)._id, strBuffer.c_str()); //Remove all menu items
} for (int i = 0; i < _size; ++i)
{
::RemoveMenu(_hMenu, _lrfl.at(i)._id, MF_BYCOMMAND);
}
//Then readd them, so everything stays in sync
for (int j = 0; j < _size; ++j)
{
generic_string strBuffer(BuildMenuFileName(nppParam.getRecentFileCustomLength(), j, _lrfl.at(j)._name));
::InsertMenu(_hMenu, _posBase + j, MF_BYPOSITION, _lrfl.at(j)._id, strBuffer.c_str());
}
} }
// 向最近的文件列表中添加一个文件名。如果达到用户定义的最大限制或列表被锁定,则不会添加。
void LastRecentFileList::add(const TCHAR *fn) // 如果文件名已存在,则会先将其移除再添加。
void LastRecentFileList::add(const TCHAR* fn)
{ {
if (_userMax == 0 || _locked) if (_userMax == 0 || _locked) // 如果用户定义的最大数量为0或列表被锁定直接返回不进行添加
return; return;
RecentItem itemToAdd(fn); RecentItem itemToAdd(fn); // 创建一个新的RecentItem对象使用传入的文件名初始化
int index = find(fn); int index = find(fn); // 查找该文件名在列表中的索引
if (index != -1) if (index != -1) // 如果找到
{ {
//already in list, bump upwards // 如果文件名已存在,先将其移除,然后重新添加
remove(index); remove(index);
} }
if (_size == _userMax) if (_size == _userMax) // 如果列表已满
{ {
itemToAdd._id = _lrfl.back()._id; itemToAdd._id = _lrfl.back()._id; // 使用最后一个元素的ID初始化新元素的ID
_lrfl.pop_back(); //remove oldest _lrfl.pop_back(); // 移除列表中的最后一个元素(即最旧的一个)
} }
else else // 如果列表未满
{ {
itemToAdd._id = popFirstAvailableID(); itemToAdd._id = popFirstAvailableID(); // 获取第一个可用的ID并初始化新元素的ID
++_size; ++_size; // 增加列表的大小
} }
_lrfl.push_front(itemToAdd); _lrfl.push_front(itemToAdd); // 在列表的前面添加新元素
updateMenu(); updateMenu(); // 更新菜单
} }
void LastRecentFileList::remove(const TCHAR *fn) // 根据文件名从最近的文件列表中移除一个文件。如果找到,则移除;否则什么也不做。
void LastRecentFileList::remove(const TCHAR* fn)
{ {
int index = find(fn); int index = find(fn); // 查找文件名在列表中的索引
if (index != -1) if (index != -1) // 如果找到
remove(index); remove(index); // 移除该元素
} }
// 根据索引从最近的文件列表中移除一个文件。如果索引有效,则移除;否则什么也不做。
void LastRecentFileList::remove(size_t index) void LastRecentFileList::remove(size_t index)
{ {
if (_size == 0 || _locked) if (_size == 0 || _locked) // 如果列表为空或被锁定,直接返回,不进行移除操作
return; return;
if (index < _lrfl.size()) if (index < _lrfl.size()) // 如果索引有效
{ {
::RemoveMenu(_hMenu, _lrfl.at(index)._id, MF_BYCOMMAND); ::RemoveMenu(_hMenu, _lrfl.at(index)._id, MF_BYCOMMAND); // 从菜单中移除该ID对应的菜单项
setAvailable(_lrfl.at(index)._id); setAvailable(_lrfl.at(index)._id); // 将该ID标记为可用可能是为了下次添加时重复使用
_lrfl.erase(_lrfl.begin() + index); _lrfl.erase(_lrfl.begin() + index); // 从列表中移除该元素
--_size; --_size; // 减少列表的大小
updateMenu(); updateMenu(); // 更新菜单
} }
} }
// 清空最近的文件列表。所有文件名和ID都会被移除菜单也会相应地更新。
void LastRecentFileList::clear() void LastRecentFileList::clear()
{ {
if (_size == 0) if (_size == 0) // 如果列表为空,直接返回,不进行任何操作
return; return;
for (int i = (_size - 1); i >= 0; i--) // 从后向前遍历列表,因为移除元素会影响后续元素的索引
for (int i = (_size-1); i >= 0; i--) {
{ ::RemoveMenu(_hMenu, _lrfl.at(i)._id, MF_BYCOMMAND); // 从菜单中移除该ID对应的菜单项
::RemoveMenu(_hMenu, _lrfl.at(i)._id, MF_BYCOMMAND); setAvailable(_lrfl.at(i)._id); // 将该ID标记为可用可能是为了下次添加时重复使用
setAvailable(_lrfl.at(i)._id); _lrfl.erase(_lrfl.begin() + i); // 从列表中移除该元素
_lrfl.erase(_lrfl.begin() + i); }
} _size = 0; // 将列表大小设置为0
_size = 0; updateMenu(); // 更新菜单
updateMenu();
} }
LastRecentFileList
generic_string & LastRecentFileList::getItem(int id) cpp
// 根据ID从最近的文件列表中获取一个文件名。如果找到则返回对应的文件名否则返回列表中的第一个文件名。
generic_string& LastRecentFileList::getItem(int id)
{ {
int i = 0; int i = 0; // 从索引0开始查找因为如果ID不存在可能会返回第一个文件名作为默认值。
for (; i < _size; ++i) for (; i < _size; ++i) // 遍历整个列表查找匹配的ID。如果找不到i会等于_size此时i会被重新设置为0。这是一个后备计划以防ID不存在于列表
{ {
if (_lrfl.at(i)._id == id) if (_lrfl.at(i)._id == id) // 如果找到匹配的ID
break; break;
} }
if (i == _size) if (i == _size) // 如果遍历完整个列表都没有找到匹配的ID
i = 0; i = 0; // 将索引重置为0这样可以从列表的第一个元素开始返回文件名作为默认值
return _lrfl.at(i)._name; //if not found, return first return _lrfl.at(i)._name; // 返回找到的文件名或默认文件名
} }
generic_string & LastRecentFileList::getIndex(int index) // 根据索引从最近的文件列表中获取一个文件名。如果索引有效,则返回对应的文件名;否则返回列表中的第一个文件名。
generic_string& LastRecentFileList::getIndex(int index)
{ {
return _lrfl.at(index)._name; //if not found, return first return _lrfl.at(index)._name; // 返回找到的文件名或默认文件名
} }
// 设置用户定义的最大最近文件列表大小。如果当前列表大小大于新设置的大小,则移除最旧的文件直到列表大小等于新设置的大小。
void LastRecentFileList::setUserMaxNbLRF(int size) void LastRecentFileList::setUserMaxNbLRF(int size)
{ {
_userMax = size; _userMax = size; // 设置用户定义的最大列表大小
if (_size > _userMax) if (_size > _userMax) // 如果当前列表大小大于新设置的大小
{ //start popping items {
int toPop = _size-_userMax; int toPop = _size - _userMax; // 计算需要移除的文件数量
while (toPop > 0) while (toPop > 0) // 当还有文件需要移除时
{ {
::RemoveMenu(_hMenu, _lrfl.back()._id, MF_BYCOMMAND); ::RemoveMenu(_hMenu, _lrfl.back()._id, MF_BYCOMMAND); // 从菜单中移除该ID对应的菜单项
setAvailable(_lrfl.back()._id); setAvailable(_lrfl.back()._id); // 将该ID标记为可用可能是为了下次添加时重复使用
_lrfl.pop_back(); _lrfl.pop_back(); // 从列表中移除该元素
toPop--; toPop--; // 减少剩余需要移除的文件数量
_size--; _size--; // 减少当前列表大小
} }
updateMenu(); updateMenu(); // 更新菜单
_size = _userMax; _size = _userMax; // 将当前列表大小设置为新设置的大小
} }
} }
// 将最近的文件列表保存到配置文件中。保存的文件名顺序与加载时相同。
void LastRecentFileList::saveLRFL() void LastRecentFileList::saveLRFL()
{ {
NppParameters& nppParams = NppParameters::getInstance(); NppParameters& nppParams = NppParameters::getInstance(); // 获取NppParameters的实例引用
if (nppParams.writeRecentFileHistorySettings(_userMax)) if (nppParams.writeRecentFileHistorySettings(_userMax)) // 如果成功写入最近的文件历史设置
{ {
for (int i = _size - 1; i >= 0; i--) //reverse order: so loading goes in correct order for (int i = _size - 1; i >= 0; i--) // 按照从后往前的顺序保存文件名,确保加载时的顺序正确
{ {
nppParams.writeHistory(_lrfl.at(i)._name.c_str()); nppParams.writeHistory(_lrfl.at(i)._name.c_str()); // 将文件名写入配置文件的历史记录部分
} }
} }
} }
int LastRecentFileList::find(const TCHAR *fn)
// 在最近的文件列表中查找指定的文件名。
int LastRecentFileList::find(const TCHAR* fn)
{ {
for (int i = 0; i < _size; ++i) for (int i = 0; i < _size; ++i) // 遍历整个列表
{ {
if (OrdinalIgnoreCaseCompareStrings(_lrfl.at(i)._name.c_str(), fn) == 0) if (OrdinalIgnoreCaseCompareStrings(_lrfl.at(i)._name.c_str(), fn) == 0) // 如果找到匹配的文件名(忽略大小写)
{ {
return i; return i; // 返回该文件在列表中的索引
} }
} }
return -1; return -1; // 如果未找到,返回-1
} }
// 弹出第一个可用的ID。
int LastRecentFileList::popFirstAvailableID() int LastRecentFileList::popFirstAvailableID()
{ {
for (int i = 0 ; i < NB_MAX_LRF_FILE ; ++i) for (int i = 0; i < NB_MAX_LRF_FILE; ++i) // 遍历所有可能的ID
{ {
if (_idFreeArray[i]) if (_idFreeArray[i]) // 如果该ID可用未被使用
{ {
_idFreeArray[i] = false; _idFreeArray[i] = false; // 标记该ID为已使用
return i + _idBase; return i + _idBase; // 返回该ID的值从_idBase开始计算
} }
} }
return 0; return 0; // 如果所有ID都已使用返回0或默认值
} }
// 设置指定的ID为可用。
void LastRecentFileList::setAvailable(int id) void LastRecentFileList::setAvailable(int id)
{ {
int index = id - _idBase; int index = id - _idBase; // 根据ID计算其在_idFreeArray中的索引
_idFreeArray[index] = true; _idFreeArray[index] = true; // 将该索引对应的值设置为true表示该ID可用
} }

Loading…
Cancel
Save