[ENHANCEMENT] (Author: Anton Vasiliev) Add some enhancement to common functions.

git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@908 f5eea248-9336-0410-98b8-ebc06183d4e3
This commit is contained in:
Don Ho 2012-05-03 01:02:54 +00:00
parent fa987cc470
commit 5d28d74ac7
4 changed files with 76 additions and 46 deletions

View File

@ -433,76 +433,103 @@ std::string wstring2string(const std::wstring & rwString, UINT codepage)
return "";
}
static TCHAR* convertFileName(TCHAR *buffer, const TCHAR *filename)
// Escapes ampersands in file name to use it in menu
template <typename T>
generic_string convertFileName(T beg, T end)
{
TCHAR *b = buffer;
const TCHAR *p = filename;
while (*p)
generic_string strTmp;
for (T it = beg; it != end; ++it)
{
if (*p == '&') *b++ = '&';
*b++ = *p++;
if (*it == '&') strTmp.push_back('&');
strTmp.push_back(*it);
}
*b = 0;
return buffer;
return strTmp;
}
generic_string intToString(int val)
{
std::vector<TCHAR> vt;
bool isNegative = val < 0;
// can't use abs here because std::numeric_limits<int>::min() has no positive representation
//val = std::abs(val);
vt.push_back('0' + (TCHAR)(std::abs(val % 10)));
val /= 10;
while (val != 0) {
vt.push_back('0' + (TCHAR)(std::abs(val % 10)));
val /= 10;
}
if (isNegative)
vt.push_back('-');
return generic_string(vt.rbegin(), vt.rend());
}
generic_string uintToString(unsigned int val)
{
std::vector<TCHAR> vt;
vt.push_back('0' + (TCHAR)(val % 10));
val /= 10;
while (val != 0) {
vt.push_back('0' + (TCHAR)(val % 10));
val /= 10;
}
return generic_string(vt.rbegin(), vt.rend());
}
// Build Recent File menu entries from given
TCHAR *BuildMenuFileName(TCHAR *buffer, int len, int pos, const TCHAR *filename)
generic_string BuildMenuFileName(int filenameLen, unsigned int pos, const generic_string &filename)
{
buffer[0] = 0;
generic_string strTemp;
TCHAR *itr = buffer;
TCHAR *end = buffer + MAX_PATH - 1;
if (pos < 9)
{
*itr++ = '&';
*itr++ = '1' + (TCHAR)pos;
strTemp.push_back('&');
strTemp.push_back('1' + (TCHAR)pos);
}
else if (pos == 9)
{
*itr++ = '1';
*itr++ = '&';
*itr++ = '0';
strTemp.append(TEXT("1&0"));
}
else
{
wsprintf(itr, TEXT("%d"), pos+1);
itr = itr + lstrlen(itr);
strTemp.append(uintToString(pos + 1));
}
*itr++ = ':';
*itr++ = ' ';
strTemp.append(TEXT(": "));
if (len > 0)
if (filenameLen > 0)
{
TCHAR cnvName[MAX_PATH*2];
convertFileName(cnvName, filename);
::PathCompactPathEx(itr, filename, len - (itr-buffer), 0);
std::vector<TCHAR> vt(filenameLen + 1);
PathCompactPathExW(&vt[0], filename.c_str(), filenameLen + 1, 0);
strTemp.append(convertFileName(vt.begin(), vt.begin() + lstrlen(&vt[0])));
}
else
{
TCHAR cnvName[MAX_PATH];
const TCHAR *s1;
// (filenameLen < 0)
generic_string::const_iterator it = filename.begin();
if (len == 0)
s1 = PathFindFileName(filename);
else // (len < 0)
s1 = filename;
if (filenameLen == 0)
it += PathFindFileName(filename.c_str()) - filename.c_str();
int len = lstrlen(s1);
if (len < (end-itr))
// MAX_PATH is still here to keep old trimming behaviour.
if (filename.end() - it < MAX_PATH)
{
lstrcpy(cnvName, s1);
strTemp.append(convertFileName(it, filename.end()));
}
else
{
int n = (len-3-(itr-buffer))/2;
generic_strncpy(cnvName, s1, n);
lstrcpy(cnvName+n, TEXT("..."));
lstrcat(cnvName, s1 + lstrlen(s1) - n);
strTemp.append(convertFileName(it, it + MAX_PATH / 2 - 3));
strTemp.append(TEXT("..."));
strTemp.append(convertFileName(filename.end() - MAX_PATH / 2, filename.end()));
}
convertFileName(itr, cnvName);
}
return buffer;
return strTemp;
}
generic_string PathRemoveFileSpec(generic_string & path)

View File

@ -101,7 +101,7 @@ void ScreenRectToClientRect(HWND hWnd, RECT* rect);
std::wstring string2wstring(const std::string & rString, UINT codepage);
std::string wstring2string(const std::wstring & rwString, UINT codepage);
bool isInList(const TCHAR *token, const TCHAR *list);
TCHAR *BuildMenuFileName(TCHAR *buffer, int len, int pos, const TCHAR *filename);
generic_string BuildMenuFileName(int filenameLen, unsigned int pos, const generic_string &filename);
class WcharMbcsConvertor {
public:

View File

@ -803,7 +803,6 @@ void WindowsMenu::initPopupMenu(HMENU hMenu, DocTabView *pTab)
int id, pos;
for (id=IDM_WINDOW_MRU_FIRST, pos=0; id<IDM_WINDOW_MRU_FIRST + nDoc; ++id, ++pos)
{
TCHAR buffer[MAX_PATH];
BufferID bufID = pTab->getBufferByIndex(pos);
Buffer * buf = MainFileManager->getBufferByID(bufID);
@ -811,7 +810,12 @@ void WindowsMenu::initPopupMenu(HMENU hMenu, DocTabView *pTab)
memset(&mii, 0, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STRING|MIIM_STATE|MIIM_ID;
mii.dwTypeData = BuildMenuFileName(buffer, 60, pos, buf->getFileName());
generic_string strBuffer(BuildMenuFileName(60, pos, buf->getFileName()));
// Can't make mii.dwTypeData = strBuffer.c_str() because of const cast.
// So, making temporary buffer for this.
std::vector<TCHAR> vBuffer(strBuffer.begin(), strBuffer.end());
vBuffer.push_back('\0');
mii.dwTypeData = (&vBuffer[0]);
mii.fState &= ~(MF_GRAYED|MF_DISABLED|MF_CHECKED);
if (pos == curDoc)
mii.fState |= MF_CHECKED;

View File

@ -149,11 +149,10 @@ void LastRecentFileList::updateMenu()
::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);
generic_string strBuffer(BuildMenuFileName(pNppParam->getRecentFileCustomLength(), j, _lrfl.at(j)._name));
::InsertMenu(_hMenu, _posBase + j, MF_BYPOSITION, _lrfl.at(j)._id, strBuffer.c_str());
}
}