mirror of
				https://github.com/notepad-plus-plus/notepad-plus-plus.git
				synced 2025-11-03 21:14:08 +01:00 
			
		
		
		
	
							parent
							
								
									bbde64c308
								
							
						
					
					
						commit
						8426c9ccd9
					
				@ -3653,35 +3653,91 @@ int Notepad_plus::wordCount()
 | 
			
		||||
    return _findReplaceDlg.processAll(ProcessCountAll, &env, true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void Notepad_plus::updateStatusBar()
 | 
			
		||||
{
 | 
			
		||||
    TCHAR strLnCol[128];
 | 
			
		||||
	TCHAR strSel[64];
 | 
			
		||||
	int selByte = 0;
 | 
			
		||||
	int selLine = 0;
 | 
			
		||||
 | 
			
		||||
	_pEditView->getSelectedCount(selByte, selLine);
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
		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);
 | 
			
		||||
	// these sections of status bar NOT updated by this function:
 | 
			
		||||
	// STATUSBAR_DOC_TYPE , STATUSBAR_EOF_FORMAT , STATUSBAR_UNICODE_TYPE
 | 
			
		||||
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
	TCHAR strSel[64];
 | 
			
		||||
 | 
			
		||||
	int numSelections = static_cast<int>(_pEditView->execute(SCI_GETSELECTIONS));
 | 
			
		||||
	if (numSelections == 1)
 | 
			
		||||
	{
 | 
			
		||||
		if (_pEditView->execute(SCI_GETSELECTIONEMPTY))
 | 
			
		||||
		{
 | 
			
		||||
			int currPos = static_cast<int>(_pEditView->execute(SCI_GETCURRENTPOS));
 | 
			
		||||
			wsprintf(strSel, TEXT("Pos : %s"), commafyInt(currPos + 1).c_str());
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			const std::pair<int, int> oneSelCharsAndLines = _pEditView->getSelectedCharsAndLinesCount();
 | 
			
		||||
			wsprintf(strSel, TEXT("Sel : %s | %s"),
 | 
			
		||||
				commafyInt(oneSelCharsAndLines.first).c_str(),
 | 
			
		||||
				commafyInt(oneSelCharsAndLines.second).c_str());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else if (_pEditView->execute(SCI_SELECTIONISRECTANGLE))
 | 
			
		||||
	{
 | 
			
		||||
		const std::pair<int, int> rectSelCharsAndLines = _pEditView->getSelectedCharsAndLinesCount();
 | 
			
		||||
 | 
			
		||||
		bool sameCharCountOnEveryLine = true;
 | 
			
		||||
		int maxLineCharCount = 0;
 | 
			
		||||
 | 
			
		||||
		for (int sel = 0; sel < numSelections; ++sel)
 | 
			
		||||
		{
 | 
			
		||||
			int start = static_cast<int>(_pEditView->execute(SCI_GETSELECTIONNSTART, sel));
 | 
			
		||||
			int end = static_cast<int>(_pEditView->execute(SCI_GETSELECTIONNEND, sel));
 | 
			
		||||
			int lineCharCount = static_cast<int>(_pEditView->execute(SCI_COUNTCHARACTERS, start, end));
 | 
			
		||||
 | 
			
		||||
			if (sel == 0)
 | 
			
		||||
			{
 | 
			
		||||
				maxLineCharCount = lineCharCount;
 | 
			
		||||
			}
 | 
			
		||||
			else 
 | 
			
		||||
			{
 | 
			
		||||
				if (lineCharCount != maxLineCharCount)
 | 
			
		||||
				{
 | 
			
		||||
					sameCharCountOnEveryLine = false;
 | 
			
		||||
					if (lineCharCount > maxLineCharCount)
 | 
			
		||||
					{
 | 
			
		||||
						maxLineCharCount = lineCharCount;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		wsprintf(strSel, TEXT("Sel : %sx%s %s %s"),
 | 
			
		||||
			commafyInt(numSelections).c_str(),  // lines (rows) in rectangular selection
 | 
			
		||||
			commafyInt(maxLineCharCount).c_str(),  // show maximum width for columns
 | 
			
		||||
			sameCharCountOnEveryLine ? TEXT("=") : TEXT("->"),
 | 
			
		||||
			commafyInt(rectSelCharsAndLines.first).c_str());
 | 
			
		||||
	}
 | 
			
		||||
	else  // multiple stream selections
 | 
			
		||||
	{
 | 
			
		||||
		const int maxSelsToProcessLineCount = 99;  // limit the number of selections to process, for performance reasons
 | 
			
		||||
		const std::pair<int, int> multipleSelCharsAndLines = _pEditView->getSelectedCharsAndLinesCount(maxSelsToProcessLineCount);
 | 
			
		||||
 | 
			
		||||
		wsprintf(strSel, TEXT("Sel %s : %s | %s"),
 | 
			
		||||
			commafyInt(numSelections).c_str(),
 | 
			
		||||
			commafyInt(multipleSelCharsAndLines.first).c_str(),
 | 
			
		||||
			numSelections <= maxSelsToProcessLineCount ?
 | 
			
		||||
				commafyInt(multipleSelCharsAndLines.second).c_str() :
 | 
			
		||||
				TEXT("..."));  // show ellipsis for line count if too many selections are active
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	TCHAR strLnColSel[128];
 | 
			
		||||
	wsprintf(strLnColSel, TEXT("Ln : %s    Col : %s    %s"),
 | 
			
		||||
		commafyInt(_pEditView->getCurrentLineNumber() + 1).c_str(),
 | 
			
		||||
		commafyInt(_pEditView->getCurrentColumnNumber() + 1).c_str(),
 | 
			
		||||
		strSel);
 | 
			
		||||
	_statusBar.setText(strLnColSel, STATUSBAR_CUR_POS);
 | 
			
		||||
 | 
			
		||||
	_statusBar.setText(_pEditView->execute(SCI_GETOVERTYPE) ? TEXT("OVR") : TEXT("INS"), STATUSBAR_TYPING_MODE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1521,9 +1521,9 @@ void Notepad_plus::command(int id)
 | 
			
		||||
 | 
			
		||||
		case IDM_EDIT_SPLIT_LINES:
 | 
			
		||||
		{
 | 
			
		||||
			pair<int, int> lineRange = _pEditView->getSelectionLinesRange();
 | 
			
		||||
			if (lineRange.first != -1)
 | 
			
		||||
			if (_pEditView->execute(SCI_GETSELECTIONS) == 1)
 | 
			
		||||
			{
 | 
			
		||||
				pair<int, int> 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);
 | 
			
		||||
 | 
			
		||||
@ -890,7 +890,14 @@ BOOL Notepad_plus::notify(SCNotification *notification)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			bool selectionIsChanged = (notification->updated & SC_UPDATE_SELECTION) != 0;
 | 
			
		||||
			// note: changing insert/overwrite mode will cause Scintilla to notify with SC_UPDATE_SELECTION
 | 
			
		||||
			bool contentIsChanged = (notification->updated & SC_UPDATE_CONTENT) != 0;
 | 
			
		||||
			if (selectionIsChanged || contentIsChanged)
 | 
			
		||||
			{
 | 
			
		||||
				updateStatusBar();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (_pFuncList && (!_pFuncList->isClosed()) && _pFuncList->isVisible())
 | 
			
		||||
				_pFuncList->markEntry();
 | 
			
		||||
			AutoCompletion * autoC = isFromPrimary?&_autoCompleteMain:&_autoCompleteSub;
 | 
			
		||||
 | 
			
		||||
@ -2789,27 +2789,36 @@ void ScintillaEditView::setMultiSelections(const ColumnModeInfos & cmi)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get selection range : (fromLine, toLine)
 | 
			
		||||
// return (-1, -1) if multi-selection
 | 
			
		||||
pair<int, int> ScintillaEditView::getSelectionLinesRange() const
 | 
			
		||||
// Get selection range (fromLine, toLine) for the specified selection
 | 
			
		||||
// specify selectionNumber = -1 for the MAIN selection
 | 
			
		||||
pair<int, int> ScintillaEditView::getSelectionLinesRange(int selectionNumber /* = -1 */) const
 | 
			
		||||
{
 | 
			
		||||
    pair<int, int> range(-1, -1);
 | 
			
		||||
    if (execute(SCI_GETSELECTIONS) > 1) // multi-selection
 | 
			
		||||
        return range;
 | 
			
		||||
	int32_t start = static_cast<int32_t>(execute(SCI_GETSELECTIONSTART));
 | 
			
		||||
	int32_t end = static_cast<int32_t>(execute(SCI_GETSELECTIONEND));
 | 
			
		||||
	int numSelections = static_cast<int>(execute(SCI_GETSELECTIONS));
 | 
			
		||||
 | 
			
		||||
	range.first = static_cast<int32_t>(execute(SCI_LINEFROMPOSITION, start));
 | 
			
		||||
	range.second = static_cast<int32_t>(execute(SCI_LINEFROMPOSITION, end));
 | 
			
		||||
	int start_pos, end_pos;
 | 
			
		||||
 | 
			
		||||
	if ((range.first != range.second) && (execute(SCI_POSITIONFROMLINE, range.second) == end))
 | 
			
		||||
	if ((selectionNumber < 0) || (selectionNumber >= numSelections))
 | 
			
		||||
	{
 | 
			
		||||
		start_pos = static_cast<int>(execute(SCI_GETSELECTIONSTART));
 | 
			
		||||
		end_pos = static_cast<int>(execute(SCI_GETSELECTIONEND));
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		start_pos = static_cast<int>(execute(SCI_GETSELECTIONNSTART, selectionNumber));
 | 
			
		||||
		end_pos = static_cast<int>(execute(SCI_GETSELECTIONNEND, selectionNumber));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int line1 = static_cast<int>(execute(SCI_LINEFROMPOSITION, start_pos));
 | 
			
		||||
	int line2 = static_cast<int>(execute(SCI_LINEFROMPOSITION, end_pos));
 | 
			
		||||
 | 
			
		||||
	if ((line1 != line2) && (execute(SCI_POSITIONFROMLINE, line2) == end_pos))
 | 
			
		||||
	{
 | 
			
		||||
		// if the end of the selection includes the line-ending, 
 | 
			
		||||
		// then don't include the following line in the range
 | 
			
		||||
		--range.second;
 | 
			
		||||
		--line2;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    return range;
 | 
			
		||||
	return pair<int, int>(line1, line2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ScintillaEditView::currentLinesUp() const
 | 
			
		||||
@ -3715,3 +3724,65 @@ void ScintillaEditView::getFoldColor(COLORREF& fgColor, COLORREF& bgColor, COLOR
 | 
			
		||||
		activeFgColor = style._fgColor;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pair<int, int> ScintillaEditView::getSelectedCharsAndLinesCount(int maxSelectionsForLineCount /* = -1 */) const
 | 
			
		||||
{
 | 
			
		||||
	pair<int, int> selectedCharsAndLines(0, 0);
 | 
			
		||||
 | 
			
		||||
	selectedCharsAndLines.first = getUnicodeSelectedLength();
 | 
			
		||||
 | 
			
		||||
	int numSelections = static_cast<int>(execute(SCI_GETSELECTIONS));
 | 
			
		||||
 | 
			
		||||
	if (numSelections == 1)
 | 
			
		||||
	{
 | 
			
		||||
		pair<int, int> lineRange = getSelectionLinesRange();
 | 
			
		||||
		selectedCharsAndLines.second = lineRange.second - lineRange.first + 1;
 | 
			
		||||
	}
 | 
			
		||||
	else if (execute(SCI_SELECTIONISRECTANGLE))
 | 
			
		||||
	{
 | 
			
		||||
		selectedCharsAndLines.second = numSelections;
 | 
			
		||||
	}
 | 
			
		||||
	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 <int, int> > 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<int>(execute(SCI_GETSELECTIONS));
 | 
			
		||||
 | 
			
		||||
	for (int s = 0; s < numSelections; ++s)
 | 
			
		||||
	{
 | 
			
		||||
		int start = static_cast<int>(execute(SCI_GETSELECTIONNSTART, s));
 | 
			
		||||
		int end = static_cast<int>(execute(SCI_GETSELECTIONNEND, s));
 | 
			
		||||
		length += static_cast<int>(execute(SCI_COUNTCHARACTERS, start, end));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return length;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -459,36 +459,9 @@ public:
 | 
			
		||||
        return long(execute(SCI_GETCOLUMN, execute(SCI_GETCURRENTPOS)));
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
	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;
 | 
			
		||||
	};
 | 
			
		||||
	std::pair<int, int> getSelectedCharsAndLinesCount(int maxSelectionsForLineCount = -1) const;
 | 
			
		||||
 | 
			
		||||
	int getUnicodeSelectedLength() const;
 | 
			
		||||
 | 
			
		||||
	long getLineLength(int line) const {
 | 
			
		||||
		return long(execute(SCI_GETLINEENDPOSITION, line) - execute(SCI_POSITIONFROMLINE, line));
 | 
			
		||||
@ -531,7 +504,7 @@ public:
 | 
			
		||||
 | 
			
		||||
	void expand(size_t& line, bool doExpand, bool force = false, int visLevels = 0, int level = -1);
 | 
			
		||||
 | 
			
		||||
	std::pair<int, int> getSelectionLinesRange() const;
 | 
			
		||||
	std::pair<int, int> getSelectionLinesRange(int selectionNumber = -1) const;
 | 
			
		||||
    void currentLinesUp() const;
 | 
			
		||||
    void currentLinesDown() const;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user