Skip to content

Commit

Permalink
Add ability to do leading spaces with ColumnEditor
Browse files Browse the repository at this point in the history
Fix #11148, fix #13309, close #13336
  • Loading branch information
alankilborn authored and donho committed Mar 25, 2023
1 parent 1f96776 commit 7f54a4b
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 86 deletions.
7 changes: 6 additions & 1 deletion PowerEditor/installer/nativeLang/english.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1280,7 +1280,12 @@ You can define several column markers by using white space to separate the diffe
<Item id="2033" name="&amp;Number to Insert"/>
<Item id="2030" name="&amp;Initial number :"/>
<Item id="2031" name="Increase b&amp;y :"/>
<Item id="2035" name="Leading &amp;zeros"/>
<Item id="2038" name="&amp;Leading :"/>
<ComboBox id="2039">
<Element name="None"/>
<Element name="Zeros"/>
<Element name="Spaces"/>
</ComboBox>
<Item id="2036" name="&amp;Repeat :"/>
<Item id="2032" name="Format"/>
<Item id="2024" name="&amp;Dec"/>
Expand Down
29 changes: 20 additions & 9 deletions PowerEditor/src/Parameters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2525,7 +2525,6 @@ void NppParameters::feedColumnEditorParameters(TiXmlNode *node)
_columnEditParam._repeatNum = val;

strVal = (childNode->ToElement())->Attribute(TEXT("formatChoice"));

if (strVal)
{
if (lstrcmp(strVal, TEXT("hex")) == 0)
Expand All @@ -2534,13 +2533,23 @@ void NppParameters::feedColumnEditorParameters(TiXmlNode *node)
_columnEditParam._formatChoice = 2;
else if (lstrcmp(strVal, TEXT("bin")) == 0)
_columnEditParam._formatChoice = 3;
else // "bin"
else // "dec"
_columnEditParam._formatChoice = 0;
}

const TCHAR* boolStr = (childNode->ToElement())->Attribute(TEXT("leadingZeros"));
if (boolStr)
_columnEditParam._isLeadingZeros = (lstrcmp(TEXT("yes"), boolStr) == 0);
strVal = (childNode->ToElement())->Attribute(TEXT("leadingChoice"));
if (strVal)
{
_columnEditParam._leadingChoice = ColumnEditorParam::noneLeading;
if (lstrcmp(strVal, TEXT("zeros")) == 0)
{
_columnEditParam._leadingChoice = ColumnEditorParam::zeroLeading;
}
else if (lstrcmp(strVal, TEXT("spaces")) == 0)
{
_columnEditParam._leadingChoice = ColumnEditorParam::spaceLeading;
}
}
}

void NppParameters::feedFindHistoryParameters(TiXmlNode *node)
Expand Down Expand Up @@ -4102,8 +4111,6 @@ bool NppParameters::writeColumnEditorSettings() const
(numberNode.ToElement())->SetAttribute(TEXT("initial"), _columnEditParam._initialNum);
(numberNode.ToElement())->SetAttribute(TEXT("increase"), _columnEditParam._increaseNum);
(numberNode.ToElement())->SetAttribute(TEXT("repeat"), _columnEditParam._repeatNum);
(numberNode.ToElement())->SetAttribute(TEXT("leadingZeros"), _columnEditParam._isLeadingZeros ? L"yes" : L"no");

wstring format = TEXT("dec");
if (_columnEditParam._formatChoice == 1)
format = TEXT("hex");
Expand All @@ -4112,10 +4119,14 @@ bool NppParameters::writeColumnEditorSettings() const
else if (_columnEditParam._formatChoice == 3)
format = TEXT("bin");
(numberNode.ToElement())->SetAttribute(TEXT("formatChoice"), format);
wstring leading = TEXT("none");
if (_columnEditParam._leadingChoice == ColumnEditorParam::zeroLeading)
leading = TEXT("zeros");
else if (_columnEditParam._leadingChoice == ColumnEditorParam::spaceLeading)
leading = TEXT("spaces");
(numberNode.ToElement())->SetAttribute(TEXT("leadingChoice"), leading);
(columnEditorRootNode.ToElement())->InsertEndChild(numberNode);



// (Re)Insert the Project Panel root
(nppRoot->ToElement())->InsertEndChild(columnEditorRootNode);
return true;
Expand Down
4 changes: 3 additions & 1 deletion PowerEditor/src/Parameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -1209,15 +1209,17 @@ struct FindHistory final

struct ColumnEditorParam final
{
enum leadingChoice : UCHAR { noneLeading, zeroLeading, spaceLeading };

bool _mainChoice = true; // true (1): text false (0): number

std::wstring _insertedTextContent;

int _initialNum = -1;
int _increaseNum = -1;
int _repeatNum = -1;
bool _isLeadingZeros = false;
int _formatChoice = 0; // 0:Dec 1:Hex 2:Oct 3:Bin
leadingChoice _leadingChoice = noneLeading;
};

class LocalizationSwitcher final
Expand Down
106 changes: 64 additions & 42 deletions PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3221,64 +3221,90 @@ bool ScintillaEditView::expandWordSelection()
return false;
}

TCHAR * int2str(TCHAR *str, int strLen, int number, int base, int nbChiffre, bool isZeroLeading)
TCHAR* int2str(TCHAR* str, int strLen, int number, int base, int nbDigits, ColumnEditorParam::leadingChoice lead)
{
if (nbChiffre >= strLen) return NULL;
constexpr size_t bufSize = 64;
TCHAR f[bufSize] = { '\0' };
TCHAR fStr[2] = TEXT("d");
if (base == 16)
fStr[0] = 'X';
else if (base == 8)
fStr[0] = 'o';
else if (base == 2)
if (nbDigits >= strLen) return NULL;

if (base == 2)
{
const unsigned int MASK_ULONG_BITFORT = 0x80000000;
int nbBits = sizeof(unsigned int) * 8;
int nbBit2Shift = (nbChiffre >= nbBits)?nbBits:(nbBits - nbChiffre);
int nbBit2Shift = (nbDigits >= nbBits) ? nbBits : (nbBits - nbDigits);
unsigned long mask = MASK_ULONG_BITFORT >> nbBit2Shift;
int i = 0;
for (; mask > 0 ; ++i)
for (; mask > 0; ++i)
{
str[i] = (mask & number)?'1':'0';
str[i] = (mask & number) ? '1' : '0';
mask >>= 1;
}
str[i] = '\0';
}
// str is now leading zero padded

if (!isZeroLeading)
{
if (base == 2)
if (lead == ColumnEditorParam::spaceLeading)
{
TCHAR *j = str;
for ( ; *j != '\0' ; ++j)
if (*j == '1')
// replace leading zeros with spaces
for (TCHAR* j = str; *j != '\0'; ++j)
{
if ((*j == '1') || (*(j + 1) == '\0'))
{
break;
wcscpy_s(str, strLen, j);
}
else
{
*j = ' ';
}
}
}
else
else if (lead != ColumnEditorParam::zeroLeading)
{
// use sprintf or swprintf instead of wsprintf
// to make octal format work
swprintf(f, bufSize, TEXT("%%%s"), fStr);
swprintf(str, strLen, f, number);
// left-align within the field width, i.e. pad on right with space

// first, remove leading zeros
for (TCHAR* j = str; *j != '\0'; ++j)
{
if (*j == '1' || *(j + 1) == '\0')
{
wcscpy_s(str, strLen, j);
break;
}
}
// add trailing spaces to pad out to field width
int i = lstrlen(str);
for (; i < nbDigits; ++i)
{
str[i] = ' ';
}
str[i] = '\0';
}
int i = lstrlen(str);
for ( ; i < nbChiffre ; ++i)
str[i] = ' ';
str[i] = '\0';
}
else
{
if (base != 2)
constexpr size_t bufSize = 64;
TCHAR f[bufSize] = { '\0' };

TCHAR fStr[2] = TEXT("d");
if (base == 16)
fStr[0] = 'X';
else if (base == 8)
fStr[0] = 'o';

if (lead == ColumnEditorParam::zeroLeading)
{
// use sprintf or swprintf instead of wsprintf
// to make octal format work
swprintf(f, bufSize, TEXT("%%.%d%s"), nbChiffre, fStr);
swprintf(str, strLen, f, number);
swprintf(f, bufSize, TEXT("%%.%d%s"), nbDigits, fStr);
}
// else already done.
else if (lead == ColumnEditorParam::spaceLeading)
{
swprintf(f, bufSize, TEXT("%%%d%s"), nbDigits, fStr);
}
else
{
// left-align within the field width, i.e. pad on right with space
swprintf(f, bufSize, TEXT("%%-%d%s"), nbDigits, fStr);
}
// use swprintf (or sprintf) instead of wsprintf to make octal format work!
swprintf(str, strLen, f, number);
}

return str;
}

Expand Down Expand Up @@ -3358,7 +3384,7 @@ void ScintillaEditView::columnReplace(ColumnModeInfos & cmi, const TCHAR *str)
}
}

void ScintillaEditView::columnReplace(ColumnModeInfos & cmi, int initial, int incr, int repeat, UCHAR format)
void ScintillaEditView::columnReplace(ColumnModeInfos & cmi, int initial, int incr, int repeat, UCHAR format, ColumnEditorParam::leadingChoice lead)
{
assert(repeat > 0);

Expand All @@ -3372,14 +3398,10 @@ void ScintillaEditView::columnReplace(ColumnModeInfos & cmi, int initial, int in
// 0000 00 10 : Oct BASE_08
// 0000 00 11 : Bin BASE_02

// 0000 01 00 : 0 leading

//Defined in ScintillaEditView.h :
//const UCHAR MASK_FORMAT = 0x03;
//const UCHAR MASK_ZERO_LEADING = 0x04;

UCHAR f = format & MASK_FORMAT;
bool isZeroLeading = (MASK_ZERO_LEADING & format) != 0;

int base = 10;
if (f == BASE_16)
Expand Down Expand Up @@ -3429,7 +3451,7 @@ void ScintillaEditView::columnReplace(ColumnModeInfos & cmi, int initial, int in
cmi[i]._selLpos += totalDiff;
cmi[i]._selRpos += totalDiff;

int2str(str, stringSize, numbers.at(i), base, kib, isZeroLeading);
int2str(str, stringSize, numbers.at(i), base, kib, lead);

const bool hasVirtualSpc = cmi[i]._nbVirtualAnchorSpc > 0;
if (hasVirtualSpc) // if virtual space is present, then insert space
Expand Down
5 changes: 2 additions & 3 deletions PowerEditor/src/ScintillaComponent/ScintillaEditView.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ enum TextCase : UCHAR
};

const UCHAR MASK_FORMAT = 0x03;
const UCHAR MASK_ZERO_LEADING = 0x04;
const UCHAR BASE_10 = 0x00; // Dec
const UCHAR BASE_16 = 0x01; // Hex
const UCHAR BASE_08 = 0x02; // Oct
Expand Down Expand Up @@ -169,7 +168,7 @@ const std::vector<std::vector<const char*>> g_nonPrintingChars =
int getNbDigits(int aNum, int base);
//HMODULE loadSciLexerDll();

TCHAR * int2str(TCHAR *str, int strLen, int number, int base, int nbChiffre, bool isZeroLeading);
TCHAR* int2str(TCHAR* str, int strLen, int number, int base, int nbDigits, ColumnEditorParam::leadingChoice lead);

typedef LRESULT (WINAPI *CallWindowProcFunc) (WNDPROC,HWND,UINT,WPARAM,LPARAM);

Expand Down Expand Up @@ -601,7 +600,7 @@ friend class Finder;
ColumnModeInfos getColumnModeSelectInfo();

void columnReplace(ColumnModeInfos & cmi, const TCHAR *str);
void columnReplace(ColumnModeInfos & cmi, int initial, int incr, int repeat, UCHAR format);
void columnReplace(ColumnModeInfos & cmi, int initial, int incr, int repeat, UCHAR format, ColumnEditorParam::leadingChoice lead);

void clearIndicator(int indicatorNumber) {
size_t docStart = 0;
Expand Down
Loading

0 comments on commit 7f54a4b

Please sign in to comment.