parent
61bcf3a2bc
commit
df4e8f5b73
|
@ -15,6 +15,7 @@
|
|||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include <memory>
|
||||
#include <bitset>
|
||||
#include <shlwapi.h>
|
||||
#include <cinttypes>
|
||||
#include <windowsx.h>
|
||||
|
@ -163,11 +164,9 @@ LanguageNameInfo ScintillaEditView::_langNameInfoArray[L_EXTERNAL + 1] = {
|
|||
};
|
||||
|
||||
|
||||
int getNbDigits(int aNum, int base)
|
||||
size_t getNbDigits(size_t aNum, size_t base)
|
||||
{
|
||||
if (base <= 0) return 0;
|
||||
|
||||
int nbDigits = 0;
|
||||
size_t nbDigits = 0;
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -3658,92 +3657,6 @@ bool ScintillaEditView::expandWordSelection()
|
|||
return false;
|
||||
}
|
||||
|
||||
TCHAR* int2str(TCHAR* str, int strLen, int number, int base, int nbDigits, ColumnEditorParam::leadingChoice lead)
|
||||
{
|
||||
if (nbDigits <= 0 || nbDigits >= strLen) return NULL;
|
||||
|
||||
if (base == 2)
|
||||
{
|
||||
const unsigned int MASK_ULONG_BITFORT = 0x80000000;
|
||||
int nbBits = sizeof(unsigned int) * 8;
|
||||
int nbBit2Shift = (nbDigits >= nbBits) ? nbBits : (nbBits - nbDigits);
|
||||
unsigned long mask = MASK_ULONG_BITFORT >> nbBit2Shift;
|
||||
int i = 0;
|
||||
for (; mask > 0; ++i)
|
||||
{
|
||||
str[i] = (mask & number) ? '1' : '0';
|
||||
mask >>= 1;
|
||||
}
|
||||
str[i] = '\0';
|
||||
// str is now leading zero padded
|
||||
|
||||
if (lead == ColumnEditorParam::spaceLeading)
|
||||
{
|
||||
// replace leading zeros with spaces
|
||||
for (TCHAR* j = str; *j != '\0'; ++j)
|
||||
{
|
||||
if ((*j == '1') || (*(j + 1) == '\0'))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
*j = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (lead != ColumnEditorParam::zeroLeading)
|
||||
{
|
||||
// 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';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
swprintf(f, bufSize, TEXT("%%.%d%s"), nbDigits, fStr);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
ColumnModeInfos ScintillaEditView::getColumnModeSelectInfo()
|
||||
{
|
||||
|
@ -3821,7 +3734,7 @@ void ScintillaEditView::columnReplace(ColumnModeInfos & cmi, const TCHAR *str)
|
|||
}
|
||||
}
|
||||
|
||||
void ScintillaEditView::columnReplace(ColumnModeInfos & cmi, int initial, int incr, int repeat, UCHAR format, ColumnEditorParam::leadingChoice lead)
|
||||
void ScintillaEditView::columnReplace(ColumnModeInfos & cmi, size_t initial, size_t incr, size_t repeat, UCHAR format, ColumnEditorParam::leadingChoice lead)
|
||||
{
|
||||
assert(repeat > 0);
|
||||
|
||||
|
@ -3849,16 +3762,16 @@ void ScintillaEditView::columnReplace(ColumnModeInfos & cmi, int initial, int in
|
|||
base = 2;
|
||||
|
||||
const int stringSize = 512;
|
||||
TCHAR str[stringSize];
|
||||
char str[stringSize];
|
||||
|
||||
// Compute the numbers to be placed at each column.
|
||||
std::vector<int> numbers;
|
||||
{
|
||||
int curNumber = initial;
|
||||
std::vector<size_t> numbers;
|
||||
|
||||
size_t curNumber = initial;
|
||||
const size_t kiMaxSize = cmi.size();
|
||||
while (numbers.size() < kiMaxSize)
|
||||
{
|
||||
for (int i = 0; i < repeat; i++)
|
||||
for (size_t i = 0; i < repeat; i++)
|
||||
{
|
||||
numbers.push_back(curNumber);
|
||||
if (numbers.size() >= kiMaxSize)
|
||||
|
@ -3868,13 +3781,10 @@ void ScintillaEditView::columnReplace(ColumnModeInfos & cmi, int initial, int in
|
|||
}
|
||||
curNumber += incr;
|
||||
}
|
||||
}
|
||||
|
||||
assert(numbers.size()> 0);
|
||||
|
||||
const int kibEnd = getNbDigits(*numbers.rbegin(), base);
|
||||
const int kibInit = getNbDigits(initial, base);
|
||||
const int kib = std::max<int>(kibInit, kibEnd);
|
||||
const size_t kibEnd = getNbDigits(*numbers.rbegin(), base);
|
||||
const size_t kibInit = getNbDigits(initial, base);
|
||||
const size_t kib = std::max<size_t>(kibInit, kibEnd);
|
||||
|
||||
intptr_t totalDiff = 0;
|
||||
const size_t len = cmi.size();
|
||||
|
@ -3888,7 +3798,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, lead);
|
||||
variedFormatNumber2String<char>(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
|
||||
|
@ -3901,15 +3811,11 @@ void ScintillaEditView::columnReplace(ColumnModeInfos & cmi, int initial, int in
|
|||
cmi[i]._selRpos += cmi[i]._nbVirtualCaretSpc;
|
||||
}
|
||||
execute(SCI_SETTARGETRANGE, cmi[i]._selLpos, cmi[i]._selRpos);
|
||||
|
||||
WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance();
|
||||
size_t cp = execute(SCI_GETCODEPAGE);
|
||||
const char *strA = wmc.wchar2char(str, cp);
|
||||
execute(SCI_REPLACETARGET, static_cast<WPARAM>(-1), reinterpret_cast<LPARAM>(strA));
|
||||
execute(SCI_REPLACETARGET, static_cast<WPARAM>(-1), reinterpret_cast<LPARAM>(str));
|
||||
|
||||
if (hasVirtualSpc)
|
||||
{
|
||||
totalDiff += cmi[i]._nbVirtualAnchorSpc + lstrlen(str);
|
||||
totalDiff += cmi[i]._nbVirtualAnchorSpc + strlen(str);
|
||||
// Now there's no more virtual space
|
||||
cmi[i]._nbVirtualAnchorSpc = 0;
|
||||
cmi[i]._nbVirtualCaretSpc = 0;
|
||||
|
|
|
@ -245,10 +245,106 @@ const std::vector<std::vector<const char*>> g_nonPrintingChars =
|
|||
{"\xEF\xBF\xBB", "IAT", "U+FFFB"} // U+FFFB : interlinear annotation terminator
|
||||
};
|
||||
|
||||
int getNbDigits(int aNum, int base);
|
||||
//HMODULE loadSciLexerDll();
|
||||
size_t getNbDigits(size_t aNum, size_t base);
|
||||
|
||||
TCHAR* int2str(TCHAR* str, int strLen, int number, int base, int nbDigits, ColumnEditorParam::leadingChoice lead);
|
||||
template<typename T>
|
||||
T* variedFormatNumber2String(T* str, size_t strLen, size_t number, size_t base, size_t nbDigits, ColumnEditorParam::leadingChoice lead)
|
||||
{
|
||||
if (nbDigits == 0 || nbDigits >= strLen) return NULL;
|
||||
|
||||
//
|
||||
// Reset the output string
|
||||
//
|
||||
memset(str, 0, sizeof(T) * strLen);
|
||||
|
||||
//
|
||||
// Form number string according its base
|
||||
//
|
||||
std::string numberStr;
|
||||
|
||||
if (base == 2)
|
||||
{
|
||||
std::string tmpStr;
|
||||
size_t aNum = number;
|
||||
do
|
||||
{
|
||||
tmpStr += aNum % 2 ? "1" : "0";
|
||||
aNum = aNum / 2;
|
||||
|
||||
} while (aNum != 0);
|
||||
|
||||
size_t i = 0;
|
||||
size_t j = tmpStr.length() - 1;
|
||||
for (; j >= 0 && i < tmpStr.length(); i++, j--)
|
||||
{
|
||||
numberStr += tmpStr[j];
|
||||
}
|
||||
}
|
||||
else if (base == 8)
|
||||
{
|
||||
std::stringstream stream;
|
||||
stream << std::oct << number;
|
||||
numberStr = stream.str();
|
||||
}
|
||||
else if (base == 16)
|
||||
{
|
||||
std::stringstream stream;
|
||||
stream << std::hex << number;
|
||||
numberStr = stream.str();
|
||||
}
|
||||
else //if (base == 10)
|
||||
{
|
||||
numberStr = std::to_string(number);
|
||||
}
|
||||
|
||||
size_t numberStrLen = numberStr.length();
|
||||
size_t noneUsedZoneLen = nbDigits - numberStrLen;
|
||||
|
||||
size_t nbStart = 0;
|
||||
size_t nbEnd = 0;
|
||||
|
||||
size_t noneUsedStart = 0;
|
||||
size_t noneUsedEnd = 0;
|
||||
|
||||
T noUsedSymbol = ' ';
|
||||
|
||||
//
|
||||
// Determinate leading zero/space or none
|
||||
//
|
||||
if (lead == ColumnEditorParam::spaceLeading)
|
||||
{
|
||||
noneUsedStart = 0;
|
||||
noneUsedEnd = nbStart = noneUsedZoneLen;
|
||||
nbEnd = nbDigits;
|
||||
}
|
||||
else if (lead == ColumnEditorParam::zeroLeading)
|
||||
{
|
||||
noUsedSymbol = '0';
|
||||
|
||||
noneUsedStart = 0;
|
||||
noneUsedEnd = nbStart = noneUsedZoneLen;
|
||||
nbEnd = nbDigits;
|
||||
}
|
||||
else //if (lead != ColumnEditorParam::noneLeading)
|
||||
{
|
||||
nbStart = 0;
|
||||
nbEnd = noneUsedStart = numberStrLen;
|
||||
noneUsedEnd = nbDigits;
|
||||
}
|
||||
|
||||
//
|
||||
// Fill str with the correct position
|
||||
//
|
||||
size_t i = 0;
|
||||
for (size_t k = nbStart; k < nbEnd; ++k)
|
||||
str[k] = numberStr[i++];
|
||||
|
||||
size_t j = 0;
|
||||
for (j = noneUsedStart; j < noneUsedEnd; ++j)
|
||||
str[j] = noUsedSymbol;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
typedef LRESULT (WINAPI *CallWindowProcFunc) (WNDPROC,HWND,UINT,WPARAM,LPARAM);
|
||||
|
||||
|
@ -687,7 +783,7 @@ public:
|
|||
ColumnModeInfos getColumnModeSelectInfo();
|
||||
|
||||
void columnReplace(ColumnModeInfos & cmi, const TCHAR *str);
|
||||
void columnReplace(ColumnModeInfos & cmi, int initial, int incr, int repeat, UCHAR format, ColumnEditorParam::leadingChoice lead);
|
||||
void columnReplace(ColumnModeInfos & cmi, size_t initial, size_t incr, size_t repeat, UCHAR format, ColumnEditorParam::leadingChoice lead);
|
||||
|
||||
void clearIndicator(int indicatorNumber) {
|
||||
size_t docStart = 0;
|
||||
|
|
|
@ -172,7 +172,7 @@ intptr_t CALLBACK ColumnEditorDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR
|
|||
(*_ppEditView)->execute(SCI_BEGINUNDOACTION);
|
||||
|
||||
constexpr int stringSize = 1024;
|
||||
TCHAR str[stringSize]{};
|
||||
wchar_t str[stringSize]{};
|
||||
|
||||
bool isTextMode = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_COL_TEXT_RADIO, BM_GETCHECK, 0, 0));
|
||||
|
||||
|
@ -239,13 +239,14 @@ intptr_t CALLBACK ColumnEditorDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR
|
|||
}
|
||||
else
|
||||
{
|
||||
int initialNumber = ::GetDlgItemInt(_hSelf, IDC_COL_INITNUM_EDIT, NULL, TRUE);
|
||||
int increaseNumber = ::GetDlgItemInt(_hSelf, IDC_COL_INCREASENUM_EDIT, NULL, TRUE);
|
||||
int repeat = ::GetDlgItemInt(_hSelf, IDC_COL_REPEATNUM_EDIT, NULL, TRUE);
|
||||
if (repeat <= 0)
|
||||
size_t initialNumber = ::GetDlgItemInt(_hSelf, IDC_COL_INITNUM_EDIT, NULL, TRUE);
|
||||
size_t increaseNumber = ::GetDlgItemInt(_hSelf, IDC_COL_INCREASENUM_EDIT, NULL, TRUE);
|
||||
size_t repeat = ::GetDlgItemInt(_hSelf, IDC_COL_REPEATNUM_EDIT, NULL, TRUE);
|
||||
if (repeat == 0)
|
||||
{
|
||||
repeat = 1; // Without this we might get an infinite loop while calculating the set "numbers" below.
|
||||
}
|
||||
|
||||
UCHAR format = getFormat();
|
||||
display(false);
|
||||
|
||||
|
@ -272,31 +273,28 @@ intptr_t CALLBACK ColumnEditorDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR
|
|||
auto endLine = (*_ppEditView)->execute(SCI_LINEFROMPOSITION, endPos);
|
||||
|
||||
// Compute the numbers to be placed at each column.
|
||||
std::vector<int> numbers;
|
||||
{
|
||||
int curNumber = initialNumber;
|
||||
std::vector<size_t> numbers;
|
||||
|
||||
size_t curNumber = initialNumber;
|
||||
const size_t kiMaxSize = 1 + (size_t)endLine - (size_t)cursorLine;
|
||||
while (numbers.size() < kiMaxSize)
|
||||
{
|
||||
for (int i = 0; i < repeat; i++)
|
||||
for (size_t i = 0; i < repeat; i++)
|
||||
{
|
||||
numbers.push_back(curNumber);
|
||||
|
||||
if (numbers.size() >= kiMaxSize)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
curNumber += increaseNumber;
|
||||
}
|
||||
}
|
||||
assert(numbers.size() > 0);
|
||||
|
||||
constexpr int lineAllocatedLen = 1024;
|
||||
TCHAR *line = new TCHAR[lineAllocatedLen];
|
||||
|
||||
UCHAR f = format & MASK_FORMAT;
|
||||
|
||||
int base = 10;
|
||||
size_t base = 10;
|
||||
if (f == BASE_16)
|
||||
base = 16;
|
||||
else if (f == BASE_08)
|
||||
|
@ -304,10 +302,10 @@ intptr_t CALLBACK ColumnEditorDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR
|
|||
else if (f == BASE_02)
|
||||
base = 2;
|
||||
|
||||
int endNumber = *numbers.rbegin();
|
||||
int nbEnd = getNbDigits(endNumber, base);
|
||||
int nbInit = getNbDigits(initialNumber, base);
|
||||
int nb = std::max<int>(nbInit, nbEnd);
|
||||
size_t endNumber = *numbers.rbegin();
|
||||
size_t nbEnd = getNbDigits(endNumber, base);
|
||||
size_t nbInit = getNbDigits(initialNumber, base);
|
||||
size_t nb = std::max<size_t>(nbInit, nbEnd);
|
||||
|
||||
|
||||
for (size_t i = cursorLine ; i <= size_t(endLine) ; ++i)
|
||||
|
@ -324,12 +322,13 @@ intptr_t CALLBACK ColumnEditorDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR
|
|||
line = new TCHAR[lineLen];
|
||||
}
|
||||
(*_ppEditView)->getGenericText(line, lineLen, lineBegin, lineEnd);
|
||||
|
||||
generic_string s2r(line);
|
||||
|
||||
//
|
||||
// Calcule generic_string
|
||||
//
|
||||
int2str(str, stringSize, numbers.at(i - cursorLine), base, nb, getLeading());
|
||||
variedFormatNumber2String<wchar_t>(str, stringSize, numbers.at(i - cursorLine), base, nb, getLeading());
|
||||
|
||||
if (lineEndCol < cursorCol)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue