diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index 6c5b29f5c..c056e9965 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -3235,65 +3235,33 @@ int Notepad_plus::wordCount() void Notepad_plus::updateStatusBar() { - TCHAR strLnCol[128]; + TCHAR strLnCol[128]; TCHAR strSel[64]; + int selByte = 0; + int selLine = 0; - int selCount = static_cast(_pEditView->execute(SCI_GETSELECTIONS)); + _pEditView->getSelectedCount(selByte, selLine); - const int maxSelsToProcessLineCount = 99; // limit the number of selections to process, for performance reasons - const std::pair selCharsAndLines = _pEditView->getSelectedCharsAndLinesCount(maxSelsToProcessLineCount); - - if (_pEditView->execute(SCI_SELECTIONISRECTANGLE)) - { - int rectAnchor = static_cast(_pEditView->execute(SCI_GETCOLUMN, _pEditView->execute(SCI_GETRECTANGULARSELECTIONANCHOR))); - rectAnchor += static_cast(_pEditView->execute(SCI_GETRECTANGULARSELECTIONANCHORVIRTUALSPACE)); - int rectCaret = static_cast(_pEditView->execute(SCI_GETCOLUMN, _pEditView->execute(SCI_GETRECTANGULARSELECTIONCARET))); - rectCaret += static_cast(_pEditView->execute(SCI_GETRECTANGULARSELECTIONCARETVIRTUALSPACE)); - int rectWidth = std::abs(rectCaret - rectAnchor); - bool hasVirtualSpace = selCharsAndLines.first != selCount * rectWidth; - - wsprintf(strSel, TEXT("Sel : %sx%s %s %s"), - commafyInt(selCount).c_str(), - commafyInt(rectWidth).c_str(), - hasVirtualSpace ? TEXT("🡢") : TEXT("="), - commafyInt(selCharsAndLines.first).c_str()); - } - else if (selCount > 1) - { - wsprintf(strSel, TEXT("Sel %s : %s | %s"), - commafyInt(selCount).c_str(), - commafyInt(selCharsAndLines.first).c_str(), - selCount <= maxSelsToProcessLineCount ? - commafyInt(selCharsAndLines.second).c_str() : - TEXT("…")); // show ellipsis for line count if too many selections are active - } - else if (selCharsAndLines.first > 0) - { - wsprintf(strSel, TEXT("Sel : %s | %s"), - commafyInt(selCharsAndLines.first).c_str(), - commafyInt(selCharsAndLines.second).c_str()); - } + long selected_length = _pEditView->getUnicodeSelectedLength(); + if (selected_length != -1) + wsprintf(strSel, TEXT("Sel : %s | %s"), commafyInt(selected_length).c_str(), commafyInt(selLine).c_str()); else - { - int curPos = static_cast(_pEditView->execute(SCI_GETCURRENTPOS)); - - wsprintf(strSel, TEXT("Pos : %s"), commafyInt(curPos + 1).c_str()); - } + wsprintf(strSel, TEXT("Sel : %s"), TEXT("N/A")); wsprintf(strLnCol, TEXT("Ln : %s Col : %s %s"), commafyInt(_pEditView->getCurrentLineNumber() + 1).c_str(), commafyInt(_pEditView->getCurrentColumnNumber() + 1).c_str(), strSel); - _statusBar.setText(strLnCol, STATUSBAR_CUR_POS); + _statusBar.setText(strLnCol, STATUSBAR_CUR_POS); - TCHAR strDocLen[256]; + TCHAR strDocLen[256]; wsprintf(strDocLen, TEXT("length : %s lines : %s"), commafyInt(_pEditView->getCurrentDocLen()).c_str(), commafyInt(_pEditView->execute(SCI_GETLINECOUNT)).c_str()); - _statusBar.setText(strDocLen, STATUSBAR_DOC_SIZE); - _statusBar.setText(_pEditView->execute(SCI_GETOVERTYPE) ? TEXT("OVR") : TEXT("INS"), STATUSBAR_TYPING_MODE); + _statusBar.setText(strDocLen, STATUSBAR_DOC_SIZE); + _statusBar.setText(_pEditView->execute(SCI_GETOVERTYPE) ? TEXT("OVR") : TEXT("INS"), STATUSBAR_TYPING_MODE); } void Notepad_plus::dropFiles(HDROP hdrop) diff --git a/PowerEditor/src/NppCommands.cpp b/PowerEditor/src/NppCommands.cpp index f1383d082..feec82d84 100644 --- a/PowerEditor/src/NppCommands.cpp +++ b/PowerEditor/src/NppCommands.cpp @@ -1484,9 +1484,9 @@ void Notepad_plus::command(int id) case IDM_EDIT_SPLIT_LINES: { - if (_pEditView->execute(SCI_GETSELECTIONS) == 1) + pair lineRange = _pEditView->getSelectionLinesRange(); + if (lineRange.first != -1) { - pair lineRange = _pEditView->getSelectionLinesRange(); auto anchorPos = _pEditView->execute(SCI_POSITIONFROMLINE, lineRange.first); auto caretPos = _pEditView->execute(SCI_GETLINEENDPOSITION, lineRange.second); _pEditView->execute(SCI_SETSELECTION, caretPos, anchorPos); diff --git a/PowerEditor/src/ScitillaComponent/ScintillaEditView.cpp b/PowerEditor/src/ScitillaComponent/ScintillaEditView.cpp index 528d97ca7..1c11ff13a 100644 --- a/PowerEditor/src/ScitillaComponent/ScintillaEditView.cpp +++ b/PowerEditor/src/ScitillaComponent/ScintillaEditView.cpp @@ -2787,36 +2787,27 @@ void ScintillaEditView::setMultiSelections(const ColumnModeInfos & cmi) } } -// Get selection range (fromLine, toLine) for the specified selection -// specify selectionNumber = -1 for the MAIN selection -pair ScintillaEditView::getSelectionLinesRange(int selectionNumber /* = -1 */) const +// Get selection range : (fromLine, toLine) +// return (-1, -1) if multi-selection +pair ScintillaEditView::getSelectionLinesRange() const { - int numSelections = static_cast(execute(SCI_GETSELECTIONS)); + pair range(-1, -1); + if (execute(SCI_GETSELECTIONS) > 1) // multi-selection + return range; + int32_t start = static_cast(execute(SCI_GETSELECTIONSTART)); + int32_t end = static_cast(execute(SCI_GETSELECTIONEND)); - int start_pos, end_pos; + range.first = static_cast(execute(SCI_LINEFROMPOSITION, start)); + range.second = static_cast(execute(SCI_LINEFROMPOSITION, end)); - if ((selectionNumber < 0) || (selectionNumber >= numSelections)) - { - start_pos = static_cast(execute(SCI_GETSELECTIONSTART)); - end_pos = static_cast(execute(SCI_GETSELECTIONEND)); - } - else - { - start_pos = static_cast(execute(SCI_GETSELECTIONNSTART, selectionNumber)); - end_pos = static_cast(execute(SCI_GETSELECTIONNEND, selectionNumber)); - } - - int line1 = static_cast(execute(SCI_LINEFROMPOSITION, start_pos)); - int line2 = static_cast(execute(SCI_LINEFROMPOSITION, end_pos)); - - if ((line1 != line2) && (execute(SCI_POSITIONFROMLINE, line2) == end_pos)) + if ((range.first != range.second) && (execute(SCI_POSITIONFROMLINE, range.second) == end)) { // if the end of the selection includes the line-ending, // then don't include the following line in the range - --line2; + --range.second; } - return pair(line1, line2); + return range; } void ScintillaEditView::currentLinesUp() const @@ -3722,61 +3713,3 @@ void ScintillaEditView::getFoldColor(COLORREF& fgColor, COLORREF& bgColor, COLOR activeFgColor = style._fgColor; } } - -pair ScintillaEditView::getSelectedCharsAndLinesCount(int maxSelectionsForLineCount /* = -1 */) const -{ - pair selectedCharsAndLines(0, 0); - - selectedCharsAndLines.first = getUnicodeSelectedLength(); - - int numSelections = static_cast(execute(SCI_GETSELECTIONS)); - - if (numSelections == 1) - { - pair lineRange = getSelectionLinesRange(); - selectedCharsAndLines.second = lineRange.second - lineRange.first + 1; - } - else if ((maxSelectionsForLineCount == -1) || // -1 means process ALL of the selections - (numSelections <= maxSelectionsForLineCount)) - { - // selections are obtained from Scintilla in the order user creates them, - // not in a lowest-to-highest position-based order; - // to be able to get a line-count that can't count the same line more than once, - // we have to reorder the lines touched - // by selection into low-to-high line number order before processing them further - - vector< pair > v; - for (int s = 0; s < numSelections; ++s) - { - v.push_back(getSelectionLinesRange(s)); - } - sort(v.begin(), v.end()); - int previousSecondLine = -1; - for (auto lineRange : v) - { - selectedCharsAndLines.second += lineRange.second - lineRange.first; - if (lineRange.first != previousSecondLine) - { - ++selectedCharsAndLines.second; - } - previousSecondLine = lineRange.second; - } - } - - return selectedCharsAndLines; -}; - -int ScintillaEditView::getUnicodeSelectedLength() const -{ - int length = 0; - int numSelections = static_cast(execute(SCI_GETSELECTIONS)); - - for (int s = 0; s < numSelections; ++s) - { - int start = static_cast(execute(SCI_GETSELECTIONNSTART, s)); - int end = static_cast(execute(SCI_GETSELECTIONNEND, s)); - length += static_cast(execute(SCI_COUNTCHARACTERS, start, end)); - } - - return length; -}; diff --git a/PowerEditor/src/ScitillaComponent/ScintillaEditView.h b/PowerEditor/src/ScitillaComponent/ScintillaEditView.h index 9cdc25f38..ba374160e 100644 --- a/PowerEditor/src/ScitillaComponent/ScintillaEditView.h +++ b/PowerEditor/src/ScitillaComponent/ScintillaEditView.h @@ -459,9 +459,36 @@ public: return long(execute(SCI_GETCOLUMN, execute(SCI_GETCURRENTPOS))); }; - std::pair getSelectedCharsAndLinesCount(int maxSelectionsForLineCount = -1) const; + bool getSelectedCount(int & selByte, int & selLine) const { + // return false if it's multi-selection or rectangle selection + if ((execute(SCI_GETSELECTIONS) > 1) || execute(SCI_SELECTIONISRECTANGLE)) + return false; + long pStart = long(execute(SCI_GETSELECTIONSTART)); + long pEnd = long(execute(SCI_GETSELECTIONEND)); + selByte = pEnd - pStart; + + long lStart = long(execute(SCI_LINEFROMPOSITION, pStart)); + long lEnd = long(execute(SCI_LINEFROMPOSITION, pEnd)); + selLine = lEnd - lStart; + if (selLine || selByte) + ++selLine; + + return true; + }; + + long getUnicodeSelectedLength() const + { + // return -1 if it's multi-selection or rectangle selection + if ((execute(SCI_GETSELECTIONS) > 1) || execute(SCI_SELECTIONISRECTANGLE)) + return -1; + + long start = long(execute(SCI_GETSELECTIONSTART)); + long end = long(execute(SCI_GETSELECTIONEND)); + long length = long(execute(SCI_COUNTCHARACTERS, start, end)); + + return length; + }; - int getUnicodeSelectedLength() const; long getLineLength(int line) const { return long(execute(SCI_GETLINEENDPOSITION, line) - execute(SCI_POSITIONFROMLINE, line)); @@ -504,7 +531,7 @@ public: void expand(size_t& line, bool doExpand, bool force = false, int visLevels = 0, int level = -1); - std::pair getSelectionLinesRange(int selectionNumber = -1) const; + std::pair getSelectionLinesRange() const; void currentLinesUp() const; void currentLinesDown() const;