mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-19 11:26:11 +00:00
[WIP] Add multiline selection with Shift + Left Click
This commit is contained in:
parent
f8c7df8260
commit
f8a258f98c
@ -439,6 +439,29 @@ void DisassemblyWidget::highlightPCLine()
|
||||
mDisasTextEdit->setExtraSelections(currentSelections);
|
||||
}
|
||||
|
||||
void DisassemblyWidget::highlightMultiLineSelections()
|
||||
{
|
||||
QList<QTextEdit::ExtraSelection> extraSelections;
|
||||
QTextEdit::ExtraSelection highlightSelection;
|
||||
QColor highlightColor = ConfigColor("lineHighlight");
|
||||
|
||||
// Highlight each selection in the multilineSelections list
|
||||
for (const QTextEdit::ExtraSelection &selection : mDisasTextEdit->getMultiLineSelections()) {
|
||||
highlightSelection.format.setBackground(highlightColor);
|
||||
highlightSelection.format.setProperty(QTextFormat::FullWidthSelection, true);
|
||||
highlightSelection.cursor = mDisasTextEdit->textCursor();
|
||||
highlightSelection.cursor.setPosition(selection.cursor.selectionStart());
|
||||
highlightSelection.cursor.setPosition(selection.cursor.selectionEnd(),
|
||||
QTextCursor::KeepAnchor);
|
||||
extraSelections.append(highlightSelection);
|
||||
}
|
||||
|
||||
// Don't override any extraSelections already set
|
||||
QList<QTextEdit::ExtraSelection> currentSelections = mDisasTextEdit->extraSelections();
|
||||
currentSelections.append(extraSelections);
|
||||
mDisasTextEdit->setExtraSelections(currentSelections);
|
||||
}
|
||||
|
||||
void DisassemblyWidget::showDisasContextMenu(const QPoint &pt)
|
||||
{
|
||||
mCtxMenu->exec(mDisasTextEdit->mapToGlobal(pt));
|
||||
@ -511,7 +534,7 @@ void DisassemblyWidget::updateCursorPosition()
|
||||
}
|
||||
|
||||
highlightPCLine();
|
||||
|
||||
highlightMultiLineSelections();
|
||||
connectCursorPositionChanged(false);
|
||||
}
|
||||
|
||||
@ -546,6 +569,7 @@ void DisassemblyWidget::cursorPositionChanged()
|
||||
seekFromCursor = false;
|
||||
highlightCurrentLine();
|
||||
highlightPCLine();
|
||||
highlightMultiLineSelections();
|
||||
mCtxMenu->setCanCopy(mDisasTextEdit->textCursor().hasSelection());
|
||||
if (mDisasTextEdit->textCursor().hasSelection()) {
|
||||
// A word is selected so use it
|
||||
@ -615,6 +639,7 @@ void DisassemblyWidget::moveCursorRelative(bool up, bool page)
|
||||
seekable->seek(offset);
|
||||
highlightCurrentLine();
|
||||
highlightPCLine();
|
||||
highlightMultiLineSelections();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -661,7 +686,10 @@ bool DisassemblyWidget::eventFilter(QObject *obj, QEvent *event)
|
||||
|
||||
void DisassemblyWidget::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
if (event->key() == Qt::Key_Return) {
|
||||
if (event->key() == Qt::Key_Shift) {
|
||||
qDebug() << "shift key pressed";
|
||||
mDisasTextEdit->setMultiLineSelection(true);
|
||||
} else if (event->key() == Qt::Key_Return) {
|
||||
const QTextCursor cursor = mDisasTextEdit->textCursor();
|
||||
jumpToOffsetUnderCursor(cursor);
|
||||
}
|
||||
@ -669,6 +697,16 @@ void DisassemblyWidget::keyPressEvent(QKeyEvent *event)
|
||||
MemoryDockWidget::keyPressEvent(event);
|
||||
}
|
||||
|
||||
void DisassemblyWidget::keyReleaseEvent(QKeyEvent *event)
|
||||
{
|
||||
if (event->key() == Qt::Key_Shift) {
|
||||
qDebug() << "shift key released";
|
||||
mDisasTextEdit->setMultiLineSelection(false);
|
||||
}
|
||||
|
||||
MemoryDockWidget::keyReleaseEvent(event);
|
||||
}
|
||||
|
||||
QString DisassemblyWidget::getWindowTitle() const
|
||||
{
|
||||
return tr("Disassembly");
|
||||
@ -788,9 +826,64 @@ void DisassemblyTextEdit::keyPressEvent(QKeyEvent *event)
|
||||
Q_UNUSED(event)
|
||||
// QPlainTextEdit::keyPressEvent(event);
|
||||
}
|
||||
|
||||
void DisassemblyTextEdit::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton && !multiLineSelection) {
|
||||
multilineSelections.clear();
|
||||
}
|
||||
|
||||
// Check for left button click and multiline individual selection mode (shift key pressed)
|
||||
if (event->button() == Qt::LeftButton && multiLineSelection) {
|
||||
// Use cursorForPosition to set the cursor to the exact click position
|
||||
QTextCursor cursor = cursorForPosition(event->pos());
|
||||
setTextCursor(cursor); // Update the text cursor to this position
|
||||
|
||||
int startPos = cursor.selectionStart();
|
||||
int endPos = cursor.selectionEnd();
|
||||
|
||||
// Format selection
|
||||
QTextEdit::ExtraSelection selection;
|
||||
selection.format.setBackground(QColor("green"));
|
||||
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
|
||||
|
||||
// Move cursor to start of the line
|
||||
cursor.movePosition(QTextCursor::StartOfLine);
|
||||
startPos = cursor.position();
|
||||
|
||||
// Extend cursor to the end of the line
|
||||
cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
|
||||
endPos = cursor.position();
|
||||
|
||||
// Debug log
|
||||
qDebug() << "Offset of line added: " << startPos << "-" << endPos;
|
||||
|
||||
// Check if line is already selected
|
||||
auto it = std::find_if(multilineSelections.begin(), multilineSelections.end(),
|
||||
[startPos, endPos](const QTextEdit::ExtraSelection &s) {
|
||||
return s.cursor.selectionStart() == startPos
|
||||
&& s.cursor.selectionEnd() == endPos;
|
||||
});
|
||||
|
||||
if (it != multilineSelections.end()) {
|
||||
// Deselect if already selected
|
||||
multilineSelections.erase(it);
|
||||
} else {
|
||||
// Add this line to the selections if not already selected
|
||||
selection.cursor = cursor;
|
||||
multilineSelections.append(selection);
|
||||
}
|
||||
|
||||
// Apply the selections
|
||||
setExtraSelections(multilineSelections);
|
||||
|
||||
// Debug log
|
||||
qDebug() << "Multiline selections:";
|
||||
for (const auto &selection : multilineSelections) {
|
||||
qDebug() << "Start:" << selection.cursor.selectionStart()
|
||||
<< "End:" << selection.cursor.selectionEnd();
|
||||
}
|
||||
}
|
||||
|
||||
QPlainTextEdit::mousePressEvent(event);
|
||||
|
||||
if (event->button() == Qt::RightButton && !textCursor().hasSelection()) {
|
||||
@ -1027,4 +1120,4 @@ void DisassemblyLeftPanel::clearArrowFrom(RVA offset)
|
||||
if (it != arrows.end()) {
|
||||
arrows.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
@ -41,6 +41,7 @@ public slots:
|
||||
* overrides all previous highlighting.
|
||||
*/
|
||||
void highlightPCLine();
|
||||
void highlightMultiLineSelections();
|
||||
void showDisasContextMenu(const QPoint &pt);
|
||||
void fontsUpdatedSlot();
|
||||
void colorsUpdatedSlot();
|
||||
@ -86,6 +87,7 @@ private:
|
||||
RVA readCurrentDisassemblyOffset();
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
void keyReleaseEvent(QKeyEvent *event) override;
|
||||
QString getWindowTitle() const override;
|
||||
|
||||
int topOffsetHistoryPos = 0;
|
||||
@ -129,11 +131,16 @@ class DisassemblyTextEdit : public QPlainTextEdit
|
||||
|
||||
public:
|
||||
explicit DisassemblyTextEdit(QWidget *parent = nullptr)
|
||||
: QPlainTextEdit(parent), lockScroll(false)
|
||||
: QPlainTextEdit(parent), lockScroll(false), multiLineSelection(false)
|
||||
{
|
||||
}
|
||||
|
||||
void setLockScroll(bool lock) { this->lockScroll = lock; }
|
||||
void setMultiLineSelection(bool multiLineSelection) { this->multiLineSelection = multiLineSelection; }
|
||||
void setMultiLineSelections(const QList<QTextEdit::ExtraSelection> &selections) { multilineSelections = selections; }
|
||||
|
||||
bool getMultiLineSelection() const { return multiLineSelection; }
|
||||
QList<QTextEdit::ExtraSelection> getMultiLineSelections() const { return multilineSelections; }
|
||||
|
||||
qreal textOffset() const;
|
||||
|
||||
@ -145,6 +152,8 @@ protected:
|
||||
|
||||
private:
|
||||
bool lockScroll;
|
||||
bool multiLineSelection;
|
||||
QList<QTextEdit::ExtraSelection> multilineSelections;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -197,4 +206,4 @@ private:
|
||||
std::vector<Arrow> arrows;
|
||||
};
|
||||
|
||||
#endif // DISASSEMBLYWIDGET_H
|
||||
#endif // DISASSEMBLYWIDGET_H
|
Loading…
Reference in New Issue
Block a user