Add ability to do leading spaces with ColumnEditor

Fix #11148, fix #13309, close #13336
pull/13409/head
Alan Kilborn 2 years ago committed by Don Ho
parent 1f96776757
commit 7f54a4b959

@ -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"/>

@ -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)
@ -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)
@ -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");
@ -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;

@ -1209,6 +1209,8 @@ struct FindHistory final
struct ColumnEditorParam final
{
enum leadingChoice : UCHAR { noneLeading, zeroLeading, spaceLeading };
bool _mainChoice = true; // true (1): text false (0): number
std::wstring _insertedTextContent;
@ -1216,8 +1218,8 @@ struct ColumnEditorParam final
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

@ -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;
}
@ -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);
@ -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)
@ -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

@ -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
@ -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);
@ -601,7 +600,7 @@ public:
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;

@ -54,8 +54,19 @@ intptr_t CALLBACK ColumnEditorDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR
if (colEditParam._repeatNum != -1)
::SetDlgItemInt(_hSelf, IDC_COL_REPEATNUM_EDIT, colEditParam._repeatNum, FALSE);
::SendDlgItemMessage(_hSelf, IDC_COL_LEADZERO_CHECK, BM_SETCHECK, colEditParam._isLeadingZeros, 0);
::SendDlgItemMessage(_hSelf, IDC_COL_LEADING_COMBO, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(TEXT("None")));
::SendDlgItemMessage(_hSelf, IDC_COL_LEADING_COMBO, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(TEXT("Zeros")));
::SendDlgItemMessage(_hSelf, IDC_COL_LEADING_COMBO, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(TEXT("Spaces")));
WPARAM curSel = 0;
switch (colEditParam._leadingChoice)
{
case ColumnEditorParam::noneLeading: { curSel = 0; break; }
case ColumnEditorParam::zeroLeading : { curSel = 1; break; }
case ColumnEditorParam::spaceLeading : { curSel = 2; break; }
default : { curSel = 0; break; }
}
::SendMessage(::GetDlgItem(_hSelf, IDC_COL_LEADING_COMBO), CB_SETCURSEL, curSel, 0);
int format = IDC_COL_DEC_RADIO;
if (colEditParam._formatChoice == 1)
format = IDC_COL_HEX_RADIO;
@ -230,7 +241,7 @@ intptr_t CALLBACK ColumnEditorDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR
if (colInfos.size() > 0)
{
std::sort(colInfos.begin(), colInfos.end(), SortInPositionOrder());
(*_ppEditView)->columnReplace(colInfos, initialNumber, increaseNumber, repeat, format);
(*_ppEditView)->columnReplace(colInfos, initialNumber, increaseNumber, repeat, format, getLeading());
std::sort(colInfos.begin(), colInfos.end(), SortInSelectOrder());
(*_ppEditView)->setMultiSelections(colInfos);
}
@ -266,9 +277,7 @@ intptr_t CALLBACK ColumnEditorDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR
int lineAllocatedLen = 1024;
TCHAR *line = new TCHAR[lineAllocatedLen];
UCHAR f = format & MASK_FORMAT;
bool isZeroLeading = (MASK_ZERO_LEADING & format) != 0;
int base = 10;
if (f == BASE_16)
@ -303,7 +312,7 @@ intptr_t CALLBACK ColumnEditorDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR
//
// Calcule generic_string
//
int2str(str, stringSize, numbers.at(i - cursorLine), base, nb, isZeroLeading);
int2str(str, stringSize, numbers.at(i - cursorLine), base, nb, getLeading());
if (lineEndCol < cursorCol)
{
@ -356,14 +365,6 @@ intptr_t CALLBACK ColumnEditorDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR
return TRUE;
}
case IDC_COL_LEADZERO_CHECK:
{
ColumnEditorParam& colEditParam = NppParameters::getInstance()._columnEditParam;
bool isLeadingZeros = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_COL_LEADZERO_CHECK, BM_GETCHECK, 0, 0));
colEditParam._isLeadingZeros = isLeadingZeros;
return TRUE;
}
default :
{
switch (HIWORD(wParam))
@ -427,6 +428,17 @@ intptr_t CALLBACK ColumnEditorDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR
}
}
break;
case CBN_SELCHANGE:
{
if (LOWORD(wParam) == IDC_COL_LEADING_COMBO)
{
ColumnEditorParam& colEditParam = NppParameters::getInstance()._columnEditParam;
colEditParam._leadingChoice = getLeading();
return TRUE;
}
}
break;
}
break;
}
@ -455,7 +467,8 @@ void ColumnEditorDlg::switchTo(bool toText)
::EnableWindow(::GetDlgItem(_hSelf, IDC_COL_HEX_RADIO), !toText);
::EnableWindow(::GetDlgItem(_hSelf, IDC_COL_OCT_RADIO), !toText);
::EnableWindow(::GetDlgItem(_hSelf, IDC_COL_BIN_RADIO), !toText);
::EnableWindow(::GetDlgItem(_hSelf, IDC_COL_LEADZERO_CHECK), !toText);
::EnableWindow(::GetDlgItem(_hSelf, IDC_COL_LEADING_STATIC), !toText);
::EnableWindow(::GetDlgItem(_hSelf, IDC_COL_LEADING_COMBO), !toText);
::SetFocus(toText?hText:hNum);
@ -472,7 +485,6 @@ void ColumnEditorDlg::switchTo(bool toText)
UCHAR ColumnEditorDlg::getFormat()
{
bool isLeadingZeros = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_COL_LEADZERO_CHECK, BM_GETCHECK, 0, 0));
UCHAR f = 0; // Dec by default
if (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_COL_HEX_RADIO, BM_GETCHECK, 0, 0))
f = 1;
@ -480,5 +492,31 @@ UCHAR ColumnEditorDlg::getFormat()
f = 2;
else if (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_COL_BIN_RADIO, BM_GETCHECK, 0, 0))
f = 3;
return (f | (isLeadingZeros?MASK_ZERO_LEADING:0));
return f;
}
ColumnEditorParam::leadingChoice ColumnEditorDlg::getLeading()
{
ColumnEditorParam::leadingChoice leading = ColumnEditorParam::noneLeading;
int curSel = static_cast<int>(::SendDlgItemMessage(_hSelf, IDC_COL_LEADING_COMBO, CB_GETCURSEL, 0, 0));
switch (curSel)
{
case 0:
default:
{
leading = ColumnEditorParam::noneLeading;
break;
}
case 1:
{
leading = ColumnEditorParam::zeroLeading;
break;
}
case 2:
{
leading = ColumnEditorParam::spaceLeading;
break;
}
}
return leading;
}

@ -18,6 +18,7 @@
#include "columnEditor_rc.h"
#include "StaticDialog.h"
#include "Parameters.h"
class ScintillaEditView;
@ -45,6 +46,7 @@ public :
virtual void display(bool toShow = true) const;
void switchTo(bool toText);
UCHAR getFormat();
ColumnEditorParam::leadingChoice getLeading();
protected :
virtual intptr_t CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam);

@ -33,19 +33,20 @@ BEGIN
RTEXT "&Initial number :",IDC_COL_INITNUM_STATIC,15,91,76,8
EDITTEXT IDC_COL_INITNUM_EDIT,95,89,38,12,ES_NUMBER
RTEXT "Increase b&y :",IDC_COL_INCRNUM_STATIC,16,112,75,8
EDITTEXT IDC_COL_INCREASENUM_EDIT,95,110,38,12,ES_NUMBER
RTEXT "Increase b&y :",IDC_COL_INCRNUM_STATIC,16,108,75,8
EDITTEXT IDC_COL_INCREASENUM_EDIT,95,106,38,12,ES_NUMBER
RTEXT "&Repeat :",IDC_COL_REPEATNUM_STATIC,16,133,75,8
EDITTEXT IDC_COL_REPEATNUM_EDIT,95,131,38,12,ES_NUMBER
RTEXT "&Repeat :",IDC_COL_REPEATNUM_STATIC,16,125,75,8
EDITTEXT IDC_COL_REPEATNUM_EDIT,95,123,38,12,ES_NUMBER
CONTROL "Leading &zeros", IDC_COL_LEADZERO_CHECK,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,140,133,70,10
CONTROL "&Dec",IDC_COL_DEC_RADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,30,169,70,10
CONTROL "&Hex",IDC_COL_HEX_RADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,124,169,70,10
CONTROL "&Oct",IDC_COL_OCT_RADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,30,188,70,10
CONTROL "&Bin",IDC_COL_BIN_RADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,124,188,70,10
GROUPBOX "Format",IDC_COL_FORMAT_GRP_STATIC,20,153,188,54,BS_CENTER
RTEXT "&Leading :",IDC_COL_LEADING_STATIC,16,142,75,8
COMBOBOX IDC_COL_LEADING_COMBO,95,140,100,30,CBS_DROPDOWNLIST | WS_TABSTOP
CONTROL "&Dec",IDC_COL_DEC_RADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,30,175,70,10
CONTROL "&Hex",IDC_COL_HEX_RADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,124,175,70,10
CONTROL "&Oct",IDC_COL_OCT_RADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,30,189,70,10
CONTROL "&Bin",IDC_COL_BIN_RADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,124,189,70,10
GROUPBOX "Format",IDC_COL_FORMAT_GRP_STATIC,20,163,188,44,BS_CENTER
DEFPUSHBUTTON "OK",IDOK,145,13,70,14,BS_NOTIFY
PUSHBUTTON "Cancel",IDCANCEL,145,36,70,14,BS_NOTIFY
END

@ -33,8 +33,8 @@
#define IDC_COL_FORMAT_GRP_STATIC (IDD_COLUMNEDIT + 12)
#define IDC_COL_NUM_RADIO (IDD_COLUMNEDIT + 13)
#define IDC_COL_TEXT_EDIT (IDD_COLUMNEDIT + 14)
#define IDC_COL_LEADZERO_CHECK (IDD_COLUMNEDIT + 15)
#define IDC_COL_REPEATNUM_STATIC (IDD_COLUMNEDIT + 16)
#define IDC_COL_REPEATNUM_EDIT (IDD_COLUMNEDIT + 17)
#define IDC_COL_LEADING_STATIC (IDD_COLUMNEDIT + 18)
#define IDC_COL_LEADING_COMBO (IDD_COLUMNEDIT + 19)
#endif// COLUMNEDITOR_RC_H

Loading…
Cancel
Save