void ScintillaAccelerator::updateKeys() { NppParameters *pNppParam = NppParameters::getInstance(); vector<ScintillaKeyMap> & map = pNppParam->getScintillaKeyList(); size_t mapSize = map.size(); size_t index; for(int i = 0; i < _nrScintillas; ++i) { ::SendMessage(_vScintillas[i], SCI_CLEARALLCMDKEYS, 0, 0); for(int32_t j = static_cast<int32_t>(mapSize) - 1; j >= 0; j--) //reverse order, top of the list has highest priority { ScintillaKeyMap skm = map[j]; if (skm.isEnabled()) { //no validating, scintilla accepts more keys size_t size = skm.getSize(); for(index = 0; index < size; ++index) ::SendMessage(_vScintillas[i], SCI_ASSIGNCMDKEY, skm.toKeyDef(index), skm.getScintillaKeyID()); } if (skm.getMenuCmdID() != 0) { updateMenuItemByID(skm, skm.getMenuCmdID()); } if (j == 0) //j is unsigned, so default method doesnt work break; } } }
BOOL CALLBACK ShortcutMapper::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG : { initTabs(); initList(); populateShortCuts(); goToCenter(); GetWindowRect(_hSelf,&default_sm_size); AnchorInit(_hSelf,ShortcutAnchors,sizeof(ShortcutAnchors)/sizeof(CONTROL_ANCHOR)); RestoreWinRelPosition(_hParent,_hSelf,&WinRelPos); return TRUE; } case WM_DESTROY: SaveWinRelPosition(_hParent,_hSelf,&WinRelPos); break; case WM_SIZE: AnchorResize(_hSelf,ShortcutAnchors,sizeof(ShortcutAnchors)/sizeof(CONTROL_ANCHOR)); break; case WM_SIZING: return ClampMinWindowSize(&default_sm_size,wParam,(RECT*)lParam); break; case WM_NOTIFY: { NMHDR nmh = *((NMHDR*)lParam); if (nmh.hwndFrom == _hTabCtrl) { if (nmh.code == TCN_SELCHANGE) { int index = TabCtrl_GetCurSel(_hTabCtrl); switch (index) { case 0: _currentState = STATE_MENU; break; case 1: _currentState = STATE_MACRO; break; case 2: _currentState = STATE_USER; break; case 3: _currentState = STATE_PLUGIN; break; case 4: _currentState = STATE_SCINTILLA; break; } populateShortCuts(); } } else if(nmh.hwndFrom==hlistview){ switch(nmh.code){ case NM_DBLCLK: return ::SendMessage(_hSelf, WM_COMMAND, IDC_SHORTCUT_MODIFY, LOWORD(lParam)); case NM_RCLICK: { POINT p; ::GetCursorPos(&p); if (!_rightClickMenu.isCreated()) { vector<MenuItemUnit> itemUnitArray; itemUnitArray.push_back(MenuItemUnit(IDC_SHORTCUT_MODIFY, TEXT("Modify"))); itemUnitArray.push_back(MenuItemUnit(IDC_SHORTCUT_DISABLE, TEXT("Disable"))); itemUnitArray.push_back(MenuItemUnit(0, 0)); itemUnitArray.push_back(MenuItemUnit(IDC_SHORTCUT_DELETE, TEXT("Delete"))); _rightClickMenu.create(_hSelf, itemUnitArray); } switch(_currentState) { case STATE_MACRO: case STATE_USER: { _rightClickMenu.enableItem(IDC_SHORTCUT_DELETE, true); break; } case STATE_MENU: case STATE_PLUGIN: case STATE_SCINTILLA: { _rightClickMenu.enableItem(IDC_SHORTCUT_DELETE, false); break; } } _rightClickMenu.display(p); return TRUE; } } } break; } case WM_COMMAND : { switch (LOWORD(wParam)) { case IDCANCEL : { ::EndDialog(_hSelf, -1); return TRUE; } case IDOK : { if(GetFocus()==hlistview) return ::SendMessage(_hSelf, WM_COMMAND, IDC_SHORTCUT_MODIFY, LOWORD(lParam)); else ::EndDialog(_hSelf, 0); return TRUE; } case IDC_SHORTCUT_FILTER2: case IDC_SHORTCUT_FILTER1: if(HIWORD(wParam)==EN_CHANGE) populateShortCuts(); break; case IDC_SHORTCUT_DISABLE: { int sel=0; sel=disable_selected(FALSE); if(sel!=0){ if(IDOK==MessageBox(_hSelf,TEXT("Ok to disable selected shortcuts?"),TEXT("Warning!"),MB_OKCANCEL|MB_SYSTEMMODAL)){ disable_selected(TRUE); populateShortCuts(); } } } break; case IDC_SHORTCUT_MODIFY : { NppParameters *nppParam = NppParameters::getInstance(); int index; int selected_row=getselectedrow(); if(selected_row<0) break; index=getitemindex(selected_row); switch(_currentState) { case STATE_MENU: { //Get CommandShortcut corresponding to index vector<CommandShortcut> & shortcuts = nppParam->getUserShortcuts(); CommandShortcut csc = shortcuts[index], prevcsc = shortcuts[index]; csc.init(_hInst, _hSelf); csc.set_shortcut_info(_currentState,index); if (csc.doDialog() != -1 && prevcsc != csc) { //shortcut was altered generic_string keys=csc.toString(); nppParam->addUserModifiedIndex(index); shortcuts[index] = csc; ListView_SetItemText(hlistview,selected_row,2,(LPWSTR)keys.c_str()); update_col_width(keys.c_str(),2); //Notify current Accelerator class to update everything nppParam->getAccelerator()->updateShortcuts(); TCHAR str[255]; if(0<check_in_use(_currentState,index,&csc.getKeyCombo(),nppParam,str,sizeof(str)/sizeof(TCHAR))) MessageBox(_hSelf,str,L"Duplicates found",MB_OK); } break; } case STATE_MACRO: { //Get MacroShortcut corresponding to index vector<MacroShortcut> & shortcuts = nppParam->getMacroList(); MacroShortcut msc = shortcuts[index], prevmsc = shortcuts[index]; msc.init(_hInst, _hSelf); msc.set_shortcut_info(_currentState,index); if (msc.doDialog() != -1 && prevmsc != msc) { //shortcut was altered generic_string name=msc.getName(); generic_string keys=msc.toString(); shortcuts[index] = msc; ListView_SetItemText(hlistview,selected_row,1,(LPWSTR)name.c_str()); ListView_SetItemText(hlistview,selected_row,2,(LPWSTR)keys.c_str()); update_col_width(keys.c_str(),2); //Notify current Accelerator class to update everything nppParam->getAccelerator()->updateShortcuts(); TCHAR str[255]; if(0<check_in_use(_currentState,index,&msc.getKeyCombo(),nppParam,str,sizeof(str)/sizeof(TCHAR))) MessageBox(_hSelf,str,L"Duplicates found",MB_OK); } break; } case STATE_USER: { //Get UserCommand corresponding to index vector<UserCommand> & shortcuts = nppParam->getUserCommandList(); UserCommand ucmd = shortcuts[index], prevucmd = shortcuts[index]; ucmd.init(_hInst, _hSelf); ucmd.set_shortcut_info(_currentState,index); prevucmd = ucmd; if (ucmd.doDialog() != -1 && prevucmd != ucmd) { //shortcut was altered generic_string name=ucmd.getName(); generic_string keys=ucmd.toString(); shortcuts[index] = ucmd; ListView_SetItemText(hlistview,selected_row,1,(LPWSTR)name.c_str()); ListView_SetItemText(hlistview,selected_row,2,(LPWSTR)keys.c_str()); update_col_width(name.c_str(),1); update_col_width(keys.c_str(),2); //Notify current Accelerator class to update everything nppParam->getAccelerator()->updateShortcuts(); TCHAR str[255]; if(0<check_in_use(_currentState,index,&ucmd.getKeyCombo(),nppParam,str,sizeof(str)/sizeof(TCHAR))) MessageBox(_hSelf,str,L"Duplicates found",MB_OK); } break; } case STATE_PLUGIN: { //Get PluginCmdShortcut corresponding to index vector<PluginCmdShortcut> & shortcuts = nppParam->getPluginCommandList(); if(shortcuts.empty()) break; PluginCmdShortcut pcsc = shortcuts[index], prevpcsc = shortcuts[index]; pcsc.init(_hInst, _hSelf); pcsc.set_shortcut_info(_currentState,index); prevpcsc = pcsc; if (pcsc.doDialog() != -1 && prevpcsc != pcsc) { //shortcut was altered nppParam->addPluginModifiedIndex(index); generic_string keys=pcsc.toString(); shortcuts[index] = pcsc; ListView_SetItemText(hlistview,selected_row,2,(LPWSTR)keys.c_str()); update_col_width(keys.c_str(),2); //Notify current Accelerator class to update everything nppParam->getAccelerator()->updateShortcuts(); TCHAR str[255]; if(0<check_in_use(_currentState,index,&pcsc.getKeyCombo(),nppParam,str,sizeof(str)/sizeof(TCHAR))) MessageBox(_hSelf,str,L"Duplicates found",MB_OK); unsigned long cmdID = pcsc.getID(); ShortcutKey shortcut; shortcut._isAlt = pcsc.getKeyCombo()._isAlt; shortcut._isCtrl = pcsc.getKeyCombo()._isCtrl; shortcut._isShift = pcsc.getKeyCombo()._isShift; shortcut._key = pcsc.getKeyCombo()._key; ::SendMessage(_hParent, NPPM_INTERNAL_PLUGINSHORTCUTMOTIFIED, cmdID, (LPARAM)&shortcut); } break; } case STATE_SCINTILLA: { //Get ScintillaKeyMap corresponding to index vector<ScintillaKeyMap> & shortcuts = nppParam->getScintillaKeyList(); ScintillaKeyMap skm = shortcuts[index], prevskm = shortcuts[index]; skm.init(_hInst, _hSelf); skm.set_shortcut_info(_currentState,index); if (skm.doDialog() != -1 && prevskm != skm) { //shortcut was altered nppParam->addScintillaModifiedIndex(index); shortcuts[index] = skm; int i,max; TCHAR str[40]={0}; max=skm.getSize(); for(i=0;i<max;i++){ generic_string keys=skm.toString(i); _sntprintf_s(str,sizeof(str)/sizeof(TCHAR),_TRUNCATE,L"%s%s%c",str,keys.c_str(),i<(max-1)?L';':L''); } ListView_SetItemText(hlistview,selected_row,2,(LPWSTR)str); update_col_width(str,2); if(max>0){ TCHAR str[255]; KeyCombo skmkc=skm.getKeyComboByIndex(0); if(0<check_in_use(_currentState,index,&skmkc,nppParam,str,sizeof(str)/sizeof(TCHAR))) MessageBox(_hSelf,str,L"Duplicates found",MB_OK); } //Notify current Accelerator class to update key nppParam->getScintillaAccelerator()->updateKeys(); } break; } } return TRUE; } case IDC_SHORTCUT_DELETE : { NppParameters *nppParam = NppParameters::getInstance(); int index,selected_row=getselectedrow(); TCHAR str[255]={0},msg[255]={0}; if(selected_row<0) break; index=getitemindex(selected_row); ListView_GetItemText(hlistview,selected_row,1,str,sizeof(str)/sizeof(TCHAR)); _sntprintf_s(msg,sizeof(msg)/sizeof(TCHAR),_TRUNCATE, TEXT("%s\r\n%s"), TEXT("Are you sure you want to delete this shortcut?"), str); if (::MessageBox(_hSelf, msg, TEXT("Are you sure?"), MB_OKCANCEL) == IDOK) { int shortcutIndex = index; DWORD cmdID = 0; // Menu data size_t posBase = 0; size_t nbElem = 0; HMENU hMenu = NULL; int modifCmd = IDM_SETTING_SHORTCUT_MAPPER_RUN; switch(_currentState) { case STATE_MENU: case STATE_PLUGIN: case STATE_SCINTILLA: { return FALSE; //this is bad } case STATE_MACRO: { vector<MacroShortcut> & theMacros = nppParam->getMacroList(); vector<MacroShortcut>::iterator it = theMacros.begin(); cmdID = theMacros[shortcutIndex].getID(); theMacros.erase(it + shortcutIndex); populateShortCuts(); // preparing to remove from menu posBase = 6; nbElem = theMacros.size(); hMenu = ::GetSubMenu((HMENU)::SendMessage(_hParent, NPPM_INTERNAL_GETMENU, 0, 0), MENUINDEX_MACRO); modifCmd = IDM_SETTING_SHORTCUT_MAPPER_MACRO; for (size_t i = shortcutIndex ; i < nbElem ; i++) //lower the IDs of the remaining items so there are no gaps { MacroShortcut ms = theMacros[i]; ms.setID(ms.getID() - 1); //shift all IDs theMacros[i] = ms; } break; } case STATE_USER: { vector<UserCommand> & theUserCmds = nppParam->getUserCommandList(); vector<UserCommand>::iterator it = theUserCmds.begin(); cmdID = theUserCmds[shortcutIndex].getID(); theUserCmds.erase(it + shortcutIndex); populateShortCuts(); // preparing to remove from menu posBase = 2; nbElem = theUserCmds.size(); hMenu = ::GetSubMenu((HMENU)::SendMessage(_hParent, NPPM_INTERNAL_GETMENU, 0, 0), MENUINDEX_RUN); modifCmd = IDM_SETTING_SHORTCUT_MAPPER_RUN; for (size_t i = shortcutIndex ; i < nbElem ; i++) //lower the IDs of the remaining items so there are no gaps { UserCommand uc = theUserCmds[i]; uc.setID(uc.getID() - 1); //shift all IDs theUserCmds[i] = uc; } break; } } // updateShortcuts() will update all menu item - the menu items will be shifted nppParam->getAccelerator()->updateShortcuts(); // All menu items are shifted up. So we delete the last item ::RemoveMenu(hMenu, posBase + nbElem, MF_BYPOSITION); if (nbElem == 0) { ::RemoveMenu(hMenu, modifCmd, MF_BYCOMMAND); //remove separator ::RemoveMenu(hMenu, posBase-1, MF_BYPOSITION); ::RemoveMenu(hMenu, posBase-1, MF_BYPOSITION); } } return TRUE; } } } default: return FALSE; } return FALSE; }
int ShortcutMapper::disable_selected(int disable) { int i,count,sel=0; NppParameters *nppParam = NppParameters::getInstance(); count=ListView_GetItemCount(hlistview); for(i=0;i<count;i++){ if(ListView_GetItemState(hlistview,i,LVIS_SELECTED)==LVIS_SELECTED){ int index=getitemindex(i); switch(_currentState) { case STATE_MENU: { vector<CommandShortcut> & shortcuts = nppParam->getUserShortcuts(); CommandShortcut csc = shortcuts[index]; if(disable){ sel+=csc.Disable(); shortcuts[index]=csc; } else sel+=csc.isEnabled(); } break; case STATE_MACRO: { vector<MacroShortcut> & shortcuts = nppParam->getMacroList(); MacroShortcut msc = shortcuts[index]; if(disable){ sel+=msc.Disable(); shortcuts[index]=msc; } else sel+=msc.isEnabled(); } break; case STATE_USER: { vector<UserCommand> & shortcuts = nppParam->getUserCommandList(); UserCommand ucmd = shortcuts[index]; if(disable){ sel+=ucmd.Disable(); shortcuts[index]=ucmd; } else sel+=ucmd.isEnabled(); } break; case STATE_PLUGIN: { vector<PluginCmdShortcut> & shortcuts = nppParam->getPluginCommandList(); if(shortcuts.empty()) break; PluginCmdShortcut pcsc = shortcuts[index]; if(disable){ sel+=pcsc.Disable(); shortcuts[index]=pcsc; } else sel+=pcsc.isEnabled(); } break; case STATE_SCINTILLA: { vector<ScintillaKeyMap> & shortcuts = nppParam->getScintillaKeyList(); ScintillaKeyMap skm = shortcuts[index]; if(disable){ int j; for(j=skm.getSize()-1;j>=0;j--) skm.removeKeyComboByIndex(j); skm.Disable(); sel++; shortcuts[index]=skm; } else sel+=skm.isEnabled(); } break; } } } return sel; }