Skip to content

Commit a1f27e8

Browse files
committed
Run Previous Script feature
- Remembers last run script - Updates menu item (including shortcut) with script name - Fixed bug with Stop-Script that meant it was disabled but not greyed out on XP
1 parent 1b1b5b0 commit a1f27e8

3 files changed

Lines changed: 117 additions & 9 deletions

File tree

PythonScript/src/MenuManager.cpp

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ MenuManager::MenuManager(HWND hNotepad, HINSTANCE hInst, void(*runScript)(const
5858
m_hInst (hInst),
5959
m_hNotepad (hNotepad),
6060
m_runScript (runScript),
61-
m_pythonPluginMenu (NULL)
62-
61+
m_pythonPluginMenu (NULL),
62+
m_funcItems(NULL)
6363
{
6464
s_startDynamicEntryID = 1;
6565
s_endDynamicEntryID = 0;
@@ -248,9 +248,10 @@ HMENU MenuManager::getOurMenu()
248248

249249
void MenuManager::stopScriptEnabled(bool enabled)
250250
{
251-
if (m_pythonPluginMenu)
251+
HMENU pythonPluginMenu = getOurMenu();
252+
if (pythonPluginMenu)
252253
{
253-
::EnableMenuItem(m_pythonPluginMenu, m_stopScriptIndex, MF_BYPOSITION | (enabled ? MF_ENABLED : MF_DISABLED));
254+
::EnableMenuItem(pythonPluginMenu, m_stopScriptIndex, MF_BYPOSITION | (enabled ? MF_ENABLED : MF_GRAYED));
254255
}
255256

256257
}
@@ -501,7 +502,7 @@ void MenuManager::subclassNotepadPlusPlus()
501502

502503

503504

504-
FuncItem* MenuManager::getFuncItemArray(int *nbF, ItemVectorTD items, void (*runScript)(int), int dynamicStartIndex, int scriptsMenuIndex, int stopScriptIndex)
505+
FuncItem* MenuManager::getFuncItemArray(int *nbF, ItemVectorTD items, void (*runScript)(int), int dynamicStartIndex, int scriptsMenuIndex, int stopScriptIndex, int runPreviousIndex)
505506
{
506507
s_runScript = runScript;
507508

@@ -570,7 +571,8 @@ FuncItem* MenuManager::getFuncItemArray(int *nbF, ItemVectorTD items, void (*run
570571
m_originalDynamicCount = m_dynamicCount;
571572
m_scriptsMenuIndex = scriptsMenuIndex;
572573
m_stopScriptIndex = stopScriptIndex;
573-
574+
m_runPreviousIndex = runPreviousIndex;
575+
574576
return m_funcItems;
575577

576578
}
@@ -807,4 +809,65 @@ int MenuManager::findMenuCommand(HMENU hParentMenu, const TCHAR *menuName, const
807809

808810
return retVal;
809811

812+
}
813+
814+
void MenuManager::initPreviousScript()
815+
{
816+
ShortcutKey key;
817+
if (::SendMessage(m_hNotepad, NPPM_GETSHORTCUTBYCMDID, m_funcItems[m_runPreviousIndex]._cmdID, reinterpret_cast<LPARAM>(&key)))
818+
{
819+
m_runLastScriptShortcut = getKeyName(key);
820+
}
821+
822+
::EnableMenuItem(getOurMenu(), m_runPreviousIndex, MF_GRAYED | MF_BYPOSITION);
823+
824+
}
825+
826+
void MenuManager::updateShortcut(UINT cmdID, ShortcutKey* key)
827+
{
828+
if (cmdID == static_cast<UINT>(m_funcItems[m_runPreviousIndex]._cmdID))
829+
{
830+
if (key && key->_key != VK_NULL)
831+
{
832+
m_runLastScriptShortcut = getKeyName(*key);
833+
}
834+
else
835+
{
836+
m_runLastScriptShortcut.erase();
837+
}
838+
839+
updatePreviousScript(m_previousRunFilename.c_str());
840+
}
841+
}
842+
843+
void MenuManager::updatePreviousScript(const char *filename)
844+
{
845+
char displayName[MAX_PATH];
846+
strcpy_s(displayName, MAX_PATH, PathFindFileNameA(filename));
847+
PathRemoveExtensionA(displayName);
848+
849+
m_previousRunFilename = filename;
850+
851+
tstring tdisplayName(_T("Run Previous Script ("));
852+
tdisplayName.append(WcharMbcsConverter::char2tchar(displayName).get());
853+
tdisplayName.append(_T(")"));
854+
855+
if (!m_runLastScriptShortcut.empty())
856+
{
857+
tdisplayName.append(_T("\t"));
858+
tdisplayName.append(m_runLastScriptShortcut);
859+
}
860+
861+
862+
MENUITEMINFO mi;
863+
mi.cbSize = sizeof(MENUITEMINFO);
864+
mi.fMask = MIIM_STATE | MIIM_STRING;
865+
mi.fState = MFS_ENABLED;
866+
867+
// string is not altered in SetMenuItemInfo() call, so we're safe to cast this
868+
mi.dwTypeData = const_cast<TCHAR*>(tdisplayName.c_str());
869+
870+
SetMenuItemInfo(getOurMenu(), m_runPreviousIndex, TRUE, &mi);
871+
DrawMenuBar(m_hNotepad);
872+
810873
}

PythonScript/src/MenuManager.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ class MenuManager
3535

3636
void stopScriptEnabled(bool enabled);
3737

38-
FuncItem* getFuncItemArray(int *nbF, ItemVectorTD items, void (*runScript)(int), int dynamicStartIndex, int scriptsMenuIndex, int stopScriptIndex);
38+
FuncItem* getFuncItemArray(int *nbF, ItemVectorTD items, void (*runScript)(int), int dynamicStartIndex, int scriptsMenuIndex, int stopScriptIndex, int runPreviousIndex);
39+
FuncItem* getFuncItems() { return m_funcItems; }
3940

4041
bool populateScriptsMenu();
4142
void menuCommand(int commandID);
@@ -51,6 +52,11 @@ class MenuManager
5152
int findPluginCommand(const TCHAR *pluginName, const TCHAR *menuOption);
5253
int findMenuCommand(const TCHAR *menuName, const TCHAR *menuOption);
5354
int findMenuCommand(HMENU parentMenu, const TCHAR *menuName, const TCHAR *menuOption);
55+
56+
void updatePreviousScript(const char *filename);
57+
void updateShortcut(UINT cmdID, ShortcutKey* key);
58+
void initPreviousScript();
59+
5460
static int s_startCommandID;
5561
static int s_endCommandID;
5662
static int s_startFixedID;
@@ -98,12 +104,15 @@ class MenuManager
98104
int m_originalDynamicCount;
99105
int m_scriptsMenuIndex;
100106
int m_stopScriptIndex;
107+
int m_runPreviousIndex;
101108
HMENU m_pythonPluginMenu;
102109
HMENU m_hScriptsMenu;
103110
FuncItem* m_funcItems;
104111
int m_funcItemCount;
105112
std::string m_machineScriptsPath;
106113
std::string m_userScriptsPath;
114+
tstring m_runLastScriptShortcut;
115+
std::string m_previousRunFilename;
107116

108117
// Function pointer to the real run script function
109118
static void (*s_runScript)(int);

PythonScript/src/PythonScript.cpp

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,12 @@ PythonConsole *g_console = 0;
4545
// Paths
4646
char g_pluginDir[MAX_PATH];
4747
char g_configDir[MAX_PATH];
48+
string g_previousScript;
4849

4950
bool g_infoSet = false;
5051
int g_scriptsMenuIndex = 0;
5152
int g_stopScriptIndex = 0;
5253
bool g_initialised = false;
53-
5454
MenuManager *g_menuManager;
5555

5656
// Scripts on the menu
@@ -72,6 +72,8 @@ void runScript(const char *script, bool synchronous, HANDLE completedEvent = NUL
7272
void runStatement(const char *statement, bool synchronous, HANDLE completedEvent = NULL, bool allowQueuing = false);
7373
void shutdown(void *);
7474
void doHelp();
75+
void previousScript();
76+
7577
FuncItem* getGeneratedFuncItemArray(int *nbF);
7678

7779

@@ -180,6 +182,7 @@ FuncItem* getGeneratedFuncItemArray(int *nbF)
180182
int stopScriptIndex;
181183
int dynamicStartIndex;
182184
int scriptsMenuIndex;
185+
int runPreviousIndex;
183186

184187
items.push_back(pair<tstring, void(*)()>(_T("New Script"), newScript));
185188
items.push_back(pair<tstring, void(*)()>(_T("Show Console"), showConsole));
@@ -192,6 +195,10 @@ FuncItem* getGeneratedFuncItemArray(int *nbF)
192195
items.push_back(pair<tstring, void(*)()>(_T("--"), reinterpret_cast<void(*)()>(NULL)));
193196

194197

198+
199+
items.push_back(pair<tstring, void(*)()>(_T("Run Previous Script"), previousScript));
200+
runPreviousIndex = items.size() - 1;
201+
195202
items.push_back(pair<tstring, void(*)()>(_T("--"), reinterpret_cast<void(*)()>(NULL)));
196203
scriptsMenuIndex = items.size() - 1;
197204

@@ -208,7 +215,7 @@ FuncItem* getGeneratedFuncItemArray(int *nbF)
208215

209216

210217

211-
FuncItem* funcItems = menuManager->getFuncItemArray(nbF, items, runScript, dynamicStartIndex, scriptsMenuIndex, stopScriptIndex);
218+
FuncItem* funcItems = menuManager->getFuncItemArray(nbF, items, runScript, dynamicStartIndex, scriptsMenuIndex, stopScriptIndex, runPreviousIndex);
212219

213220

214221
return funcItems;
@@ -234,6 +241,7 @@ void initialise()
234241
MenuManager* menuManager = MenuManager::getInstance();
235242
menuManager->populateScriptsMenu();
236243
menuManager->stopScriptEnabled(false);
244+
menuManager->initPreviousScript();
237245

238246

239247
}
@@ -313,6 +321,13 @@ extern "C" __declspec(dllexport) void beNotified(SCNotification *notifyCode)
313321
registerToolbarIcons();
314322
break;
315323

324+
case NPPN_SHORTCUTREMAPPED:
325+
{
326+
MenuManager *menuManager = MenuManager::getInstance();
327+
menuManager->updateShortcut(notifyCode->nmhdr.idFrom, reinterpret_cast<ShortcutKey*>(notifyCode->nmhdr.hwndFrom));
328+
}
329+
break;
330+
316331
}
317332

318333
// Notify the scripts
@@ -431,8 +446,20 @@ void runStatement(const char *statement, bool synchronous, HANDLE completedEvent
431446

432447
}
433448

449+
void updatePreviousScript(const char *filename)
450+
{
451+
if (g_previousScript == filename)
452+
return;
453+
454+
g_previousScript = filename;
455+
456+
MenuManager *menuManager = MenuManager::getInstance();
457+
menuManager->updatePreviousScript(filename);
458+
}
459+
434460
void runScript(const char *filename, bool synchronous, HANDLE completedEvent /* = NULL */, bool allowQueuing /* = false */)
435461
{
462+
436463
BYTE keyState[256];
437464
::GetKeyboardState(keyState);
438465

@@ -448,6 +475,10 @@ void runScript(const char *filename, bool synchronous, HANDLE completedEvent /*
448475
{
449476
CHECK_INITIALISED();
450477
MenuManager::getInstance()->stopScriptEnabled(true);
478+
479+
// TODO: Really need to not change this if it's a MSGTOPLUGIN run
480+
updatePreviousScript(filename);
481+
451482
if (!pythonHandler->runScript(filename, synchronous, allowQueuing, completedEvent))
452483
{
453484
MessageBox(NULL, _T("Another script is currently running. Running two scripts at the same time could produce unpredicable results, and is therefore disabled."), _T("Python Script"), 0);
@@ -558,4 +589,9 @@ void doHelp()
558589

559590
HelpController help(nppData._nppHandle, which ? nppData._scintillaSecondHandle : nppData._scintillaMainHandle);
560591
help.callHelp();
592+
}
593+
594+
void previousScript()
595+
{
596+
runScript(g_previousScript.c_str(), false);
561597
}

0 commit comments

Comments
 (0)