Added more Change Case variants

Closes #2032

Added some more Change Case functions (Title Case, Sentence Case,
Invertcase, Randomcase).
Some of them have a normal and a blend version. The normal version will
change any formatting in the start/middle/end part of the word/sentence to
the chosen case. The blend version applies the changes only to the start
part but don't changes the middle/end part of the word/sentence. You can
use it when you want to keep some formatting in the middle/end part, for
instance CamelCase or proper nouns.
This commit is contained in:
A-R-C-A 2016-06-30 01:13:00 +00:00 committed by Don HO
parent 7fcc20f84a
commit f6e47cd536
7 changed files with 204 additions and 21 deletions

View File

@ -1873,6 +1873,12 @@ void Notepad_plus::checkClipboard()
enableCommand(IDM_EDIT_DELETE, hasSelection, MENU | TOOLBAR);
enableCommand(IDM_EDIT_UPPERCASE, hasSelection, MENU);
enableCommand(IDM_EDIT_LOWERCASE, hasSelection, MENU);
enableCommand(IDM_EDIT_TITLECASE_FORCE, hasSelection, MENU);
enableCommand(IDM_EDIT_TITLECASE_BLEND, hasSelection, MENU);
enableCommand(IDM_EDIT_SENTENCECASE_FORCE, hasSelection, MENU);
enableCommand(IDM_EDIT_SENTENCECASE_BLEND, hasSelection, MENU);
enableCommand(IDM_EDIT_INVERTCASE, hasSelection, MENU);
enableCommand(IDM_EDIT_RANDOMCASE, hasSelection, MENU);
}
void Notepad_plus::checkDocState()

View File

@ -276,6 +276,12 @@ BEGIN
BEGIN
MENUITEM "&UPPERCASE", IDM_EDIT_UPPERCASE
MENUITEM "&lowercase", IDM_EDIT_LOWERCASE
MENUITEM "&Title Case", IDM_EDIT_TITLECASE_FORCE
MENUITEM "Title Case (blend)", IDM_EDIT_TITLECASE_BLEND
MENUITEM "&Sentence case", IDM_EDIT_SENTENCECASE_FORCE
MENUITEM "Sentence case (blend)", IDM_EDIT_SENTENCECASE_BLEND
MENUITEM "&iNVERTCASE", IDM_EDIT_INVERTCASE
MENUITEM "&RAnDomCaSe", IDM_EDIT_RANDOMCASE
END
POPUP "Line Operations"
BEGIN

View File

@ -1206,6 +1206,30 @@ void Notepad_plus::command(int id)
_pEditView->convertSelectedTextToLowerCase();
break;
case IDM_EDIT_TITLECASE_FORCE:
_pEditView->convertSelectedTextToNewerCase(TITLECASE_FORCE);
break;
case IDM_EDIT_TITLECASE_BLEND:
_pEditView->convertSelectedTextToNewerCase(TITLECASE_BLEND);
break;
case IDM_EDIT_SENTENCECASE_FORCE:
_pEditView->convertSelectedTextToNewerCase(SENTENCECASE_FORCE);
break;
case IDM_EDIT_SENTENCECASE_BLEND:
_pEditView->convertSelectedTextToNewerCase(SENTENCECASE_BLEND);
break;
case IDM_EDIT_INVERTCASE:
_pEditView->convertSelectedTextToNewerCase(INVERTCASE);
break;
case IDM_EDIT_RANDOMCASE:
_pEditView->convertSelectedTextToNewerCase(RANDOMCASE);
break;
case IDM_EDIT_BLOCK_COMMENT:
doBlockComment(cm_toggle);
break;
@ -2871,6 +2895,12 @@ void Notepad_plus::command(int id)
case IDM_EDIT_REMOVEEMPTYLINESWITHBLANK:
case IDM_EDIT_UPPERCASE:
case IDM_EDIT_LOWERCASE:
case IDM_EDIT_TITLECASE_FORCE:
case IDM_EDIT_TITLECASE_BLEND:
case IDM_EDIT_SENTENCECASE_FORCE:
case IDM_EDIT_SENTENCECASE_BLEND:
case IDM_EDIT_INVERTCASE:
case IDM_EDIT_RANDOMCASE:
case IDM_EDIT_BLOCK_COMMENT:
case IDM_EDIT_BLOCK_COMMENT_SET:
case IDM_EDIT_BLOCK_UNCOMMENT:

View File

@ -131,6 +131,12 @@ static const WinMenuKeyDefinition winKeyDefs[] =
{VK_C, IDM_EDIT_COLUMNMODE, false, true, false, nullptr},
{VK_U, IDM_EDIT_UPPERCASE, true, false, true, nullptr},
{VK_U, IDM_EDIT_LOWERCASE, true, false, false, nullptr},
{VK_U, IDM_EDIT_TITLECASE_FORCE, false, true, false, nullptr},
{VK_U, IDM_EDIT_TITLECASE_BLEND, false, true, true, nullptr},
{VK_U, IDM_EDIT_SENTENCECASE_FORCE, true, true, false, nullptr},
{VK_U, IDM_EDIT_SENTENCECASE_BLEND, true, true, true, nullptr},
{VK_NULL, IDM_EDIT_INVERTCASE, false, false, false, nullptr},
{VK_NULL, IDM_EDIT_RANDOMCASE, false, false, false, nullptr},
{VK_Q, IDM_EDIT_BLOCK_COMMENT, true, false, false, nullptr},
{VK_K, IDM_EDIT_BLOCK_COMMENT_SET, true, false, false, nullptr},
{VK_K, IDM_EDIT_BLOCK_UNCOMMENT, true, false, true, nullptr},

View File

@ -2399,7 +2399,129 @@ void ScintillaEditView::currentLinesDown() const
execute(SCI_SCROLLRANGE, execute(SCI_GETSELECTIONEND), execute(SCI_GETSELECTIONSTART));
}
void ScintillaEditView::convertSelectedTextTo(bool Case)
void ScintillaEditView::changeCase(__inout wchar_t * const strWToConvert, const int & nbChars, const TextCase & caseToConvert) const
{
if (strWToConvert == nullptr || nbChars == NULL)
return;
switch (caseToConvert)
{
case UPPERCASE:
{
for (int i = 0; i < nbChars; ++i)
{
strWToConvert[i] = (WCHAR)(UINT_PTR)::CharUpperW((LPWSTR)strWToConvert[i]);
}
break;
} //case UPPERCASE
case LOWERCASE:
{
for (int i = 0; i < nbChars; ++i)
{
strWToConvert[i] = (WCHAR)(UINT_PTR)::CharLowerW((LPWSTR)strWToConvert[i]);
}
break;
} //case LOWERCASE
case TITLECASE_FORCE:
case TITLECASE_BLEND:
{
for (int i = 0; i < nbChars; ++i)
{
if (::IsCharAlphaW(strWToConvert[i]))
{
if ((i < 1) ? true : not ::IsCharAlphaNumericW(strWToConvert[i - 1]))
strWToConvert[i] = (WCHAR)(UINT_PTR)::CharUpperW((LPWSTR)strWToConvert[i]);
else if (caseToConvert == TITLECASE_FORCE)
strWToConvert[i] = (WCHAR)(UINT_PTR)::CharLowerW((LPWSTR)strWToConvert[i]);
//An exception
if ((i < 2) ? false : (strWToConvert[i - 1] == L'\'' && ::IsCharAlphaW(strWToConvert[i - 2])))
strWToConvert[i] = (WCHAR)(UINT_PTR)::CharLowerW((LPWSTR)strWToConvert[i]);
}
}
break;
} //case TITLECASE
case SENTENCECASE_FORCE:
case SENTENCECASE_BLEND:
{
bool isNewSentence = true;
bool wasEolR = false;
bool wasEolN = false;
for (int i = 0; i < nbChars; ++i)
{
if (::IsCharAlphaW(strWToConvert[i]))
{
if (isNewSentence)
{
strWToConvert[i] = (WCHAR)(UINT_PTR)::CharUpperW((LPWSTR)strWToConvert[i]);
isNewSentence = false;
}
else if (caseToConvert == SENTENCECASE_FORCE)
{
strWToConvert[i] = (WCHAR)(UINT_PTR)::CharLowerW((LPWSTR)strWToConvert[i]);
}
wasEolR = false;
wasEolN = false;
//An exception
if (strWToConvert[i] == L'i' &&
((i < 1) ? false : (::iswspace(strWToConvert[i - 1]) || strWToConvert[i - 1] == L'(' || strWToConvert[i - 1] == L'"')) &&
((i + 1 == nbChars) ? false : (::iswspace(strWToConvert[i + 1]) || strWToConvert[i + 1] == L'\'')))
{
strWToConvert[i] = L'I';
}
}
else if (strWToConvert[i] == L'.' || strWToConvert[i] == L'!' || strWToConvert[i] == L'?')
{
if ((i + 1 == nbChars) ? true : ::IsCharAlphaNumericW(strWToConvert[i + 1]))
isNewSentence = false;
else
isNewSentence = true;
}
else if (strWToConvert[i] == L'\r')
{
if (wasEolR)
isNewSentence = true;
else
wasEolR = true;
}
else if (strWToConvert[i] == L'\n')
{
if (wasEolN)
isNewSentence = true;
else
wasEolN = true;
}
}
break;
} //case SENTENCECASE
case INVERTCASE:
{
for (int i = 0; i < nbChars; ++i)
{
if (::IsCharLowerW(strWToConvert[i]))
strWToConvert[i] = (WCHAR)(UINT_PTR)::CharUpperW((LPWSTR)strWToConvert[i]);
else
strWToConvert[i] = (WCHAR)(UINT_PTR)::CharLowerW((LPWSTR)strWToConvert[i]);
}
break;
} //case INVERTCASE
case RANDOMCASE:
{
for (int i = 0; i < nbChars; ++i)
{
if (::IsCharAlphaW(strWToConvert[i]))
{
if (std::rand() & true)
strWToConvert[i] = (WCHAR)(UINT_PTR)::CharUpperW((LPWSTR)strWToConvert[i]);
else
strWToConvert[i] = (WCHAR)(UINT_PTR)::CharLowerW((LPWSTR)strWToConvert[i]);
}
}
break;
} //case RANDOMCASE
} //switch (caseToConvert)
}
void ScintillaEditView::convertSelectedTextTo(const TextCase & caseToConvert)
{
unsigned int codepage = _codepage;
UniMode um = getCurrentBuffer()->getUnicodeMode();
@ -2424,13 +2546,8 @@ void ScintillaEditView::convertSelectedTextTo(bool Case)
int nbChar = ::MultiByteToWideChar(codepage, 0, srcStr, len, destStr, len);
for (int j = 0 ; j < nbChar ; ++j)
{
if (Case == UPPERCASE)
destStr[j] = (wchar_t)(UINT_PTR)::CharUpperW((LPWSTR)destStr[j]);
else
destStr[j] = (wchar_t)(UINT_PTR)::CharLowerW((LPWSTR)destStr[j]);
}
changeCase(destStr, nbChar, caseToConvert);
::WideCharToMultiByte(codepage, 0, destStr, len, srcStr, len, NULL, NULL);
execute(SCI_SETTARGETRANGE, start, end);
@ -2464,13 +2581,8 @@ void ScintillaEditView::convertSelectedTextTo(bool Case)
int nbChar = ::MultiByteToWideChar(codepage, 0, selectedStr, strSize, selectedStrW, strWSize);
for (int i = 0 ; i < nbChar ; ++i)
{
if (Case == UPPERCASE)
selectedStrW[i] = (WCHAR)(UINT_PTR)::CharUpperW((LPWSTR)selectedStrW[i]);
else
selectedStrW[i] = (WCHAR)(UINT_PTR)::CharLowerW((LPWSTR)selectedStrW[i]);
}
changeCase(selectedStrW, nbChar, caseToConvert);
::WideCharToMultiByte(codepage, 0, selectedStrW, strWSize, selectedStr, strSize, NULL, NULL);
execute(SCI_SETTARGETRANGE, selectionStart, selectionEnd);

View File

@ -99,9 +99,17 @@ const int CP_GREEK = 1253;
const bool fold_uncollapse = true;
const bool fold_collapse = false;
const bool UPPERCASE = true;
const bool LOWERCASE = false;
enum TextCase : UCHAR
{
UPPERCASE,
LOWERCASE,
TITLECASE_FORCE,
TITLECASE_BLEND,
SENTENCECASE_FORCE,
SENTENCECASE_BLEND,
INVERTCASE,
RANDOMCASE
};
const UCHAR MASK_FORMAT = 0x03;
const UCHAR MASK_ZERO_LEADING = 0x04;
@ -518,7 +526,8 @@ public:
void currentLinesUp() const;
void currentLinesDown() const;
void convertSelectedTextTo(bool Case);
void changeCase(__inout wchar_t * const strWToConvert, const int & nbChars, const TextCase & caseToConvert) const;
void convertSelectedTextTo(const TextCase & caseToConvert);
void setMultiSelections(const ColumnModeInfos & cmi);
void convertSelectedTextToLowerCase() {
@ -537,6 +546,14 @@ public:
execute(SCI_UPPERCASE);
};
void convertSelectedTextToNewerCase(const TextCase & caseToConvert) {
// if system is w2k or xp
if ((NppParameters::getInstance())->isTransparentAvailable())
convertSelectedTextTo(caseToConvert);
else
::MessageBox(_hSelf, TEXT("This function needs a newer OS version."), TEXT("Change Case Error"), MB_OK | MB_ICONHAND);
};
void collapse(int level2Collapse, bool mode);
void foldAll(bool mode);
void fold(size_t line, bool mode);

View File

@ -109,6 +109,12 @@
#define IDM_EDIT_LINE_DOWN (IDM_EDIT + 15)
#define IDM_EDIT_UPPERCASE (IDM_EDIT + 16)
#define IDM_EDIT_LOWERCASE (IDM_EDIT + 17)
#define IDM_EDIT_TITLECASE_FORCE (IDM_EDIT + 67)
#define IDM_EDIT_TITLECASE_BLEND (IDM_EDIT + 68)
#define IDM_EDIT_SENTENCECASE_FORCE (IDM_EDIT + 69)
#define IDM_EDIT_SENTENCECASE_BLEND (IDM_EDIT + 70)
#define IDM_EDIT_INVERTCASE (IDM_EDIT + 71)
#define IDM_EDIT_RANDOMCASE (IDM_EDIT + 72)
#define IDM_EDIT_REMOVEEMPTYLINES (IDM_EDIT + 55)
#define IDM_EDIT_REMOVEEMPTYLINESWITHBLANK (IDM_EDIT + 56)
#define IDM_EDIT_BLANKLINEABOVECURRENT (IDM_EDIT + 57)