Skip to content

Commit 1a7e466

Browse files
committed
Several minor bugs fixed, notepad.getNppDir and notepad.getCommandLine added
- Parsing improvements for Console - Caching in runMenuCommand and runPluginCommand - Save session shared_ptr fix - messageBox() defaults added
1 parent 76a0f0b commit 1a7e466

11 files changed

Lines changed: 308 additions & 46 deletions

File tree

PythonScript/src/ConsoleDialog.cpp

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -670,8 +670,23 @@ bool ConsoleDialog::parseVSErrorLine(LineDetails *lineDetails)
670670
break;
671671

672672
case SS_FILENAME:
673+
673674
while(lineDetails->line[pos] != '(' && pos < lineDetails->lineLength)
674675
{
676+
if (pos - lineDetails->filenameStart == 1)
677+
{
678+
if (lineDetails->line[pos] != ':')
679+
{
680+
styleState = SS_EXIT;
681+
break;
682+
}
683+
}
684+
else if (!isValidFilenameChar(lineDetails->line[pos]))
685+
{
686+
styleState = SS_EXIT;
687+
break;
688+
}
689+
675690
++pos;
676691
}
677692

@@ -711,6 +726,13 @@ bool ConsoleDialog::parseVSErrorLine(LineDetails *lineDetails)
711726
&& lineDetails->line[pos] == ')'
712727
&& lineDetails->line[pos+1] == ':')
713728
{
729+
// If no line number, jump out
730+
if (endLineNoPos == startLineNoPos)
731+
{
732+
styleState = SS_EXIT;
733+
break;
734+
}
735+
714736
char *lineNumber = new char[endLineNoPos - startLineNoPos + 2];
715737
strncpy_s(lineNumber, endLineNoPos - startLineNoPos + 2, lineDetails->line + startLineNoPos, endLineNoPos - startLineNoPos);
716738
lineDetails->errorLineNo = atoi(lineNumber) - 1;
@@ -785,6 +807,13 @@ bool ConsoleDialog::parseGCCErrorLine(LineDetails *lineDetails)
785807
break;
786808
}
787809

810+
// Unescaped invalid char, so it's not a gcc error
811+
if (!isEscaped && !isValidFilenameChar(lineDetails->line[pos]))
812+
{
813+
styleState = SS_EXIT;
814+
break;
815+
}
816+
788817
if (lineDetails->line[pos] == '\\')
789818
isEscaped = true;
790819

@@ -816,15 +845,26 @@ bool ConsoleDialog::parseGCCErrorLine(LineDetails *lineDetails)
816845
&& lineDetails->line[pos] == ':')
817846
{
818847
lineDetails->errorLineNo = atoi(lineDetails->line + startLineNoPos) - 1;
819-
lineDetails->filenameEnd = startLineNoPos - 1;
820-
retVal = true;
821-
pos += 2;
822-
styleState = SS_ERRORTYPE;
848+
849+
// If the line number came out as 0, ie. there wasn't any,
850+
// then the line is not a gcc error
851+
if (lineDetails->errorLineNo == -1)
852+
{
853+
styleState = SS_EXIT;
854+
}
855+
else
856+
{
857+
lineDetails->filenameEnd = startLineNoPos - 1;
858+
retVal = true;
859+
pos += 2;
860+
styleState = SS_ERRORTYPE;
861+
}
823862
}
824863
else
825864
{
826-
pos = startLineNoPos + 1;
827-
styleState = SS_FILENAME;
865+
// If we've found the end of the number, and it isn't followed with a colon:
866+
// then it's not a gcc error.
867+
styleState = SS_EXIT;
828868
}
829869
break;
830870
}

PythonScript/src/ConsoleDialog.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ class ConsoleDialog : public DockingDlgInterface
5757
void onHotspotClick(SCNotification* notification);
5858
bool parseLine(LineDetails *lineDetails);
5959

60+
bool isValidFilenameChar(char ch)
61+
{ return (ch != '<' && ch != '>' && ch != ':' && ch != '|' && ch != '\"' && ch != '?'); };
62+
6063
//HWND m_hNpp;
6164
tTbData m_data;
6265
HWND m_scintilla;

PythonScript/src/MenuManager.cpp

Lines changed: 87 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -716,11 +716,52 @@ void MenuManager::deleteInstance()
716716
}
717717

718718

719-
int MenuManager::findPluginCommand(const TCHAR *pluginName, const TCHAR *menuOption)
719+
int MenuManager::findPluginCommand(const TCHAR *pluginName, const TCHAR *menuOption, bool refreshCache)
720720
{
721+
int retVal = 0;
722+
bool fromCache = false;
723+
if (!refreshCache)
724+
{
725+
MenuCommandCacheTD::iterator it = m_pluginCommandCache.find(pair<tstring, tstring>(tstring(pluginName), tstring(menuOption)));
726+
if (it != m_pluginCommandCache.end())
727+
{
728+
retVal = it->second;
729+
fromCache = true;
730+
}
731+
}
732+
733+
if (0 == retVal)
734+
{
735+
HMENU hPluginMenu = (HMENU)::SendMessage(m_hNotepad, NPPM_GETMENUHANDLE, 0, 0);
721736

722-
HMENU hPluginMenu = (HMENU)::SendMessage(m_hNotepad, NPPM_GETMENUHANDLE, 0, 0);
723-
737+
int iMenuItems = GetMenuItemCount(hPluginMenu);
738+
TCHAR strBuffer[500];
739+
for ( int i = 0; i < iMenuItems; ++i )
740+
{
741+
MENUITEMINFO mii;
742+
mii.cbSize = sizeof(MENUITEMINFO);
743+
mii.fMask = MIIM_ID | MIIM_STRING | MIIM_SUBMENU;
744+
mii.cch = 500;
745+
mii.dwTypeData = strBuffer;
746+
747+
::GetMenuItemInfo(hPluginMenu, i, TRUE, &mii);
748+
tstring thisMenuName = formatMenuName(strBuffer);
749+
if (NULL != mii.hSubMenu && 0 == _tcsicmp(pluginName, thisMenuName.c_str()))
750+
{
751+
retVal = findMenuCommand(mii.hSubMenu, NULL, menuOption);
752+
break;
753+
}
754+
755+
}
756+
}
757+
758+
if (!fromCache && retVal != 0)
759+
{
760+
m_pluginCommandCache[pair<tstring,tstring>(tstring(pluginName), tstring(menuOption))] = retVal;
761+
}
762+
763+
return retVal;
764+
/*
724765
int iMenuItems = GetMenuItemCount(hPluginMenu);
725766
TCHAR strBuffer[500];
726767
@@ -752,17 +793,45 @@ int MenuManager::findPluginCommand(const TCHAR *pluginName, const TCHAR *menuOpt
752793
}
753794
754795
return 0;
796+
*/
755797
}
756798

757799

758800

759-
int MenuManager::findMenuCommand(const TCHAR *menuName, const TCHAR *menuOption)
801+
int MenuManager::findMenuCommand(const TCHAR *menuName, const TCHAR *menuOption, bool refreshCache)
760802
{
803+
int retVal = 0;
804+
805+
if (!refreshCache)
806+
{
807+
MenuCommandCacheTD::iterator it = m_menuCommandCache.find(pair<tstring, tstring>(tstring(menuName), tstring(menuOption)));
808+
if (it != m_menuCommandCache.end())
809+
{
810+
return it->second;
811+
}
812+
}
813+
761814
HMENU hMenuBar = ::GetMenu(m_hNotepad);
815+
retVal = findMenuCommand(hMenuBar, menuName, menuOption);
816+
817+
if (retVal != 0)
818+
{
819+
m_menuCommandCache[pair<tstring,tstring>(tstring(menuName), tstring(menuOption))] = retVal;
820+
}
762821

763-
return findMenuCommand(hMenuBar, menuName, menuOption);
822+
return retVal;
764823
}
765824

825+
tstring MenuManager::formatMenuName(const TCHAR *name)
826+
{
827+
tstring nameStr(name);
828+
size_t pos = nameStr.find(_T('&'));
829+
if (pos != tstring::npos && pos < nameStr.size() - 1 && nameStr[pos + 1] != _T('&'))
830+
{
831+
nameStr.erase(pos, 1);
832+
}
833+
return nameStr;
834+
}
766835

767836
int MenuManager::findMenuCommand(HMENU hParentMenu, const TCHAR *menuName, const TCHAR *menuOption)
768837
{
@@ -780,25 +849,30 @@ int MenuManager::findMenuCommand(HMENU hParentMenu, const TCHAR *menuName, const
780849
mii.dwTypeData = strBuffer;
781850

782851
::GetMenuItemInfo(hParentMenu, i, TRUE, &mii);
783-
784-
if (NULL != mii.hSubMenu && 0 == _tcsicmp(menuName, strBuffer))
852+
tstring thisMenuName = formatMenuName(strBuffer);
853+
if (NULL != mii.hSubMenu && (NULL == menuName || 0 == _tcsicmp(menuName, thisMenuName.c_str())))
785854
{
786855
int subMenuItems = ::GetMenuItemCount(mii.hSubMenu);
787856
for (int subMenuPos = 0; subMenuPos < subMenuItems; ++subMenuPos)
788857
{
789858
TCHAR *context = NULL;;
790859
::GetMenuString(mii.hSubMenu, subMenuPos, strBuffer, 500, MF_BYPOSITION);
791860
TCHAR *name = _tcstok_s(strBuffer, _T("\t"), &context);
792-
793-
if (name && 0 == _tcsicmp(menuOption, name))
861+
if (name)
794862
{
795-
return ::GetMenuItemID(mii.hSubMenu, subMenuPos);
863+
tstring nameStr = formatMenuName(name);
864+
865+
if (0 == _tcsicmp(menuOption, nameStr.c_str()))
866+
{
867+
return ::GetMenuItemID(mii.hSubMenu, subMenuPos);
868+
}
796869
}
797870
}
798871
}
799872

800873
if (NULL != mii.hSubMenu)
801874
{
875+
802876
retVal = findMenuCommand(mii.hSubMenu, menuName, menuOption);
803877
// If we've found it in the sub menu (or within the sub menu)
804878
if (0 != retVal)
@@ -811,6 +885,9 @@ int MenuManager::findMenuCommand(HMENU hParentMenu, const TCHAR *menuName, const
811885

812886
}
813887

888+
889+
890+
814891
void MenuManager::initPreviousScript()
815892
{
816893
ShortcutKey key;

PythonScript/src/MenuManager.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,9 @@ class MenuManager
4949

5050
void configureToolbarIcons();
5151

52-
int findPluginCommand(const TCHAR *pluginName, const TCHAR *menuOption);
53-
int findMenuCommand(const TCHAR *menuName, const TCHAR *menuOption);
52+
int findPluginCommand(const TCHAR *pluginName, const TCHAR *menuOption, bool refreshCache);
53+
int findMenuCommand(const TCHAR *menuName, const TCHAR *menuOption, bool refreshCache);
54+
5455
int findMenuCommand(HMENU parentMenu, const TCHAR *menuName, const TCHAR *menuOption);
5556

5657
void updatePreviousScript(const char *filename);
@@ -80,11 +81,16 @@ class MenuManager
8081
int findScripts(HMENU hBaseMenu, int basePathLength, int startID, std::string& path);
8182
void subclassNotepadPlusPlus();
8283

84+
tstring formatMenuName(const TCHAR *name);
85+
8386
void(*m_runScript)(const char *, bool, HANDLE, bool);
8487

8588
typedef std::set<std::string> MachineScriptNamesTD;
8689
typedef std::map<int, std::string> ScriptCommandsTD;
8790
typedef std::map<std::string, HMENU> SubmenusTD;
91+
typedef std::map<std::pair<tstring, tstring>, int> MenuCommandCacheTD;
92+
MenuCommandCacheTD m_menuCommandCache;
93+
MenuCommandCacheTD m_pluginCommandCache;
8894

8995
MachineScriptNamesTD m_machineScriptNames;
9096
ScriptCommandsTD m_scriptCommands;

PythonScript/src/NotepadPlusWrapper.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,8 @@ void NotepadPlusWrapper::saveSession(const char *sessionFilename, boost::python:
301301
{
302302

303303
sessionInfo si;
304-
305-
si.sessionFilePathName = WcharMbcsConverter::char2tchar(sessionFilename).get();
304+
shared_ptr<TCHAR> tsessionFilename = WcharMbcsConverter::char2tchar(sessionFilename);
305+
si.sessionFilePathName = tsessionFilename.get();
306306

307307
int filesCount = len(files);
308308
si.files = (TCHAR **)new TCHAR*[filesCount];
@@ -317,7 +317,7 @@ void NotepadPlusWrapper::saveSession(const char *sessionFilename, boost::python:
317317
}
318318

319319
si.nbFile = filesCount;
320-
320+
321321
Py_BEGIN_ALLOW_THREADS
322322
callNotepad(NPPM_SAVESESSION, 0, reinterpret_cast<LPARAM>(&si));
323323
Py_END_ALLOW_THREADS
@@ -429,7 +429,7 @@ str NotepadPlusWrapper::getPluginConfigDir()
429429
{
430430
TCHAR temp[MAX_PATH];
431431
callNotepad(NPPM_GETPLUGINSCONFIGDIR, MAX_PATH, reinterpret_cast<LPARAM>(temp));
432-
return str(WcharMbcsConverter::tchar2char(temp).get());
432+
return str(const_cast<const char *>(WcharMbcsConverter::tchar2char(temp).get()));
433433
}
434434

435435
void NotepadPlusWrapper::menuCommand(int commandID)
@@ -756,7 +756,7 @@ boost::python::str NotepadPlusWrapper::getCurrentFilename()
756756
}
757757

758758

759-
bool NotepadPlusWrapper::runPluginCommand(boost::python::str pluginName, boost::python::str menuOption)
759+
bool NotepadPlusWrapper::runPluginCommand(boost::python::str pluginName, boost::python::str menuOption, bool refreshCache)
760760
{
761761
bool retVal = false;
762762

@@ -766,7 +766,7 @@ bool NotepadPlusWrapper::runPluginCommand(boost::python::str pluginName, boost::
766766
shared_ptr<TCHAR> tpluginName = WcharMbcsConverter::char2tchar(extract<const char *>(pluginName));
767767
shared_ptr<TCHAR> tmenuOption = WcharMbcsConverter::char2tchar(extract<const char *>(menuOption));
768768
Py_BEGIN_ALLOW_THREADS
769-
int commandID = menuManager->findPluginCommand(tpluginName.get(), tmenuOption.get());
769+
int commandID = menuManager->findPluginCommand(tpluginName.get(), tmenuOption.get(), refreshCache);
770770
if (commandID)
771771
{
772772
::SendMessage(m_nppHandle, WM_COMMAND, commandID, 0);
@@ -778,7 +778,7 @@ bool NotepadPlusWrapper::runPluginCommand(boost::python::str pluginName, boost::
778778

779779
}
780780

781-
bool NotepadPlusWrapper::runMenuCommand(boost::python::str menuName, boost::python::str menuOption)
781+
bool NotepadPlusWrapper::runMenuCommand(boost::python::str menuName, boost::python::str menuOption, bool refreshCache)
782782
{
783783
bool retVal = false;
784784
MenuManager *menuManager = MenuManager::getInstance();
@@ -787,7 +787,7 @@ bool NotepadPlusWrapper::runMenuCommand(boost::python::str menuName, boost::pyth
787787
shared_ptr<TCHAR> tmenuName = WcharMbcsConverter::char2tchar(extract<const char *>(menuName));
788788
shared_ptr<TCHAR> tmenuOption = WcharMbcsConverter::char2tchar(extract<const char *>(menuOption));
789789
Py_BEGIN_ALLOW_THREADS
790-
int commandID = menuManager->findMenuCommand(tmenuName.get(), tmenuOption.get());
790+
int commandID = menuManager->findMenuCommand(tmenuName.get(), tmenuOption.get(), refreshCache);
791791
if (commandID)
792792
{
793793
::SendMessage(m_nppHandle, WM_COMMAND, commandID, 0);
@@ -798,3 +798,16 @@ bool NotepadPlusWrapper::runMenuCommand(boost::python::str menuName, boost::pyth
798798
return retVal;
799799

800800
}
801+
802+
803+
str NotepadPlusWrapper::getNppDir()
804+
{
805+
TCHAR buffer[MAX_PATH];
806+
::SendMessage(m_nppHandle, NPPM_GETNPPDIRECTORY, MAX_PATH, reinterpret_cast<LPARAM>(buffer));
807+
return str(const_cast<const char *>(WcharMbcsConverter::tchar2char(buffer).get()));
808+
}
809+
810+
str NotepadPlusWrapper::getCommandLine()
811+
{
812+
return str(const_cast<const char *>(WcharMbcsConverter::tchar2char(::GetCommandLine()).get()));
813+
}

0 commit comments

Comments
 (0)