//this file is part of notepad++ //Copyright (C)2003 Don HO // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License //as published by the Free Software Foundation; either //version 2 of the License, or (at your option) any later version. // //This program is distributed in the hope that it will be useful, //but WITHOUT ANY WARRANTY; without even the implied warranty of //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //GNU General Public License for more details. // //You should have received a copy of the GNU General Public License //along with this program; if not, write to the Free Software //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "precompiledHeaders.h" #include "lastRecentFileList.h" #include "menuCmdID.h" #include "localization.h" void LastRecentFileList::initMenu(HMENU hMenu, int idBase, int posBase, bool doSubMenu) { if (doSubMenu) { _hParentMenu = hMenu; _hMenu = ::CreatePopupMenu(); } else { _hParentMenu = NULL; _hMenu = hMenu; } _idBase = idBase; _posBase = posBase; _nativeLangEncoding = NPP_CP_WIN_1252; for (int i = 0 ; i < sizeof(_idFreeArray) ; i++) _idFreeArray[i] = true; } void LastRecentFileList::switchMode() { //Remove all menu items ::RemoveMenu(_hMenu, IDM_OPEN_ALL_RECENT_FILE, MF_BYCOMMAND); ::RemoveMenu(_hMenu, IDM_CLEAN_RECENT_FILE_LIST, MF_BYCOMMAND); for(int i = 0; i < _size; i++) { ::RemoveMenu(_hMenu, _lrfl.at(i)._id, MF_BYCOMMAND); } if (_hParentMenu == NULL) // mode main menu { if (_size > 0) { ::RemoveMenu(_hMenu, _posBase, MF_BYPOSITION); ::RemoveMenu(_hMenu, _posBase, MF_BYPOSITION); } // switch to sub-menu mode _hParentMenu = _hMenu; _hMenu = ::CreatePopupMenu(); ::RemoveMenu(_hMenu, _posBase+1, MF_BYPOSITION); } else // mode sub-menu { if (_size > 0) { ::RemoveMenu(_hParentMenu, _posBase, MF_BYPOSITION); ::RemoveMenu(_hParentMenu, _posBase, MF_BYPOSITION); } // switch to main menu mode ::DestroyMenu(_hMenu); _hMenu = _hParentMenu; _hParentMenu = NULL; } _hasSeparators = false; }; void LastRecentFileList::updateMenu() { NppParameters *pNppParam = NppParameters::getInstance(); if (!_hasSeparators && _size > 0) { //add separators NativeLangSpeaker *pNativeLangSpeaker = pNppParam->getNativeLangSpeaker(); generic_string recentFileList = pNativeLangSpeaker->getSpecialMenuEntryName("RecentFiles"); generic_string openAllFiles = pNativeLangSpeaker->getNativeLangMenuString(IDM_OPEN_ALL_RECENT_FILE); generic_string cleanFileList = pNativeLangSpeaker->getNativeLangMenuString(IDM_CLEAN_RECENT_FILE_LIST); if (recentFileList == TEXT("")) recentFileList = TEXT("&Recent Files"); if (openAllFiles == TEXT("")) openAllFiles = TEXT("Open All Recent Files"); if (cleanFileList == TEXT("")) cleanFileList = TEXT("Empty Recent Files List"); if (!isSubMenuMode()) ::InsertMenu(_hMenu, _posBase + 0, MF_BYPOSITION, UINT(-1), 0); ::InsertMenu(_hMenu, _posBase + 1, MF_BYPOSITION, IDM_OPEN_ALL_RECENT_FILE, openAllFiles.c_str()); ::InsertMenu(_hMenu, _posBase + 2, MF_BYPOSITION, IDM_CLEAN_RECENT_FILE_LIST, cleanFileList.c_str()); ::InsertMenu(_hMenu, _posBase + 3, MF_BYPOSITION, UINT(-1), 0); _hasSeparators = true; if (isSubMenuMode()) { ::InsertMenu(_hParentMenu, _posBase + 0, MF_BYPOSITION | MF_POPUP, UINT(_hMenu), (LPCTSTR)recentFileList.c_str()); ::InsertMenu(_hParentMenu, _posBase + 1, MF_BYPOSITION, UINT(-1), 0); } } else if (_hasSeparators && _size == 0) //remove separators { ::RemoveMenu(_hMenu, _posBase + 3, MF_BYPOSITION); ::RemoveMenu(_hMenu, IDM_CLEAN_RECENT_FILE_LIST, MF_BYCOMMAND); ::RemoveMenu(_hMenu, IDM_OPEN_ALL_RECENT_FILE, MF_BYCOMMAND); ::RemoveMenu(_hMenu, _posBase + 0, MF_BYPOSITION); _hasSeparators = false; if (isSubMenuMode()) { // Remove "Recent Files" Entry and the separator from the main menu ::RemoveMenu(_hParentMenu, _posBase + 1, MF_BYPOSITION); ::RemoveMenu(_hParentMenu, _posBase + 0, MF_BYPOSITION); // Remove the last left separator from the submenu ::RemoveMenu(_hMenu, 0, MF_BYPOSITION); } } //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 TCHAR buffer[MAX_PATH]; for(int j = 0; j < _size; j++) { BuildMenuFileName(buffer, pNppParam->getRecentFileCustomLength(), j, _lrfl.at(j)._name.c_str()); ::InsertMenu(_hMenu, _posBase + j, MF_BYPOSITION, _lrfl.at(j)._id, buffer); } } void LastRecentFileList::add(const TCHAR *fn) { if (_userMax == 0 || _locked) return; RecentItem itemToAdd(fn); int index = find(fn); if (index != -1) { //already in list, bump upwards remove(index); } if (_size == _userMax) { itemToAdd._id = _lrfl.back()._id; _lrfl.pop_back(); //remove oldest } else { itemToAdd._id = popFirstAvailableID(); _size++; } _lrfl.push_front(itemToAdd); updateMenu(); }; void LastRecentFileList::remove(const TCHAR *fn) { int index = find(fn); if (index != -1) remove(index); }; void LastRecentFileList::remove(int index) { if (_size == 0 || _locked) return; if (index > -1 && index < (int)_lrfl.size()) { ::RemoveMenu(_hMenu, _lrfl.at(index)._id, MF_BYCOMMAND); setAvailable(_lrfl.at(index)._id); _lrfl.erase(_lrfl.begin() + index); _size--; updateMenu(); } }; void LastRecentFileList::clear() { if (_size == 0) return; for(int i = (_size-1); i >= 0; i--) { ::RemoveMenu(_hMenu, _lrfl.at(i)._id, MF_BYCOMMAND); setAvailable(_lrfl.at(i)._id); _lrfl.erase(_lrfl.begin() + i); } _size = 0; updateMenu(); } generic_string & LastRecentFileList::getItem(int id) { int i = 0; for(; i < _size; i++) { if (_lrfl.at(i)._id == id) break; } if (i == _size) i = 0; return _lrfl.at(i)._name; //if not found, return first }; generic_string & LastRecentFileList::getIndex(int index) { return _lrfl.at(index)._name; //if not found, return first } void LastRecentFileList::setUserMaxNbLRF(int size) { _userMax = size; if (_size > _userMax) { //start popping items int toPop = _size-_userMax; while(toPop > 0) { ::RemoveMenu(_hMenu, _lrfl.back()._id, MF_BYCOMMAND); setAvailable(_lrfl.back()._id); _lrfl.pop_back(); toPop--; _size--; } updateMenu(); _size = _userMax; } } void LastRecentFileList::saveLRFL() { NppParameters *pNppParams = NppParameters::getInstance(); if (pNppParams->writeRecentFileHistorySettings(_userMax)) { for(int i = _size - 1; i >= 0; i--) //reverse order: so loading goes in correct order { pNppParams->writeHistory(_lrfl.at(i)._name.c_str()); } } } int LastRecentFileList::find(const TCHAR *fn) { for(int i = 0; i < _size; i++) { if (!lstrcmpi(_lrfl.at(i)._name.c_str(), fn)) { return i; } } return -1; } int LastRecentFileList::popFirstAvailableID() { for (int i = 0 ; i < NB_MAX_LRF_FILE ; i++) { if (_idFreeArray[i]) { _idFreeArray[i] = false; return i + _idBase; } } return 0; } void LastRecentFileList::setAvailable(int id) { int index = id - _idBase; _idFreeArray[index] = true; }