mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-24 05:45:27 +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);
|
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)
|
void DisassemblyWidget::showDisasContextMenu(const QPoint &pt)
|
||||||
{
|
{
|
||||||
mCtxMenu->exec(mDisasTextEdit->mapToGlobal(pt));
|
mCtxMenu->exec(mDisasTextEdit->mapToGlobal(pt));
|
||||||
@ -511,7 +534,7 @@ void DisassemblyWidget::updateCursorPosition()
|
|||||||
}
|
}
|
||||||
|
|
||||||
highlightPCLine();
|
highlightPCLine();
|
||||||
|
highlightMultiLineSelections();
|
||||||
connectCursorPositionChanged(false);
|
connectCursorPositionChanged(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -546,6 +569,7 @@ void DisassemblyWidget::cursorPositionChanged()
|
|||||||
seekFromCursor = false;
|
seekFromCursor = false;
|
||||||
highlightCurrentLine();
|
highlightCurrentLine();
|
||||||
highlightPCLine();
|
highlightPCLine();
|
||||||
|
highlightMultiLineSelections();
|
||||||
mCtxMenu->setCanCopy(mDisasTextEdit->textCursor().hasSelection());
|
mCtxMenu->setCanCopy(mDisasTextEdit->textCursor().hasSelection());
|
||||||
if (mDisasTextEdit->textCursor().hasSelection()) {
|
if (mDisasTextEdit->textCursor().hasSelection()) {
|
||||||
// A word is selected so use it
|
// A word is selected so use it
|
||||||
@ -615,6 +639,7 @@ void DisassemblyWidget::moveCursorRelative(bool up, bool page)
|
|||||||
seekable->seek(offset);
|
seekable->seek(offset);
|
||||||
highlightCurrentLine();
|
highlightCurrentLine();
|
||||||
highlightPCLine();
|
highlightPCLine();
|
||||||
|
highlightMultiLineSelections();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -661,7 +686,10 @@ bool DisassemblyWidget::eventFilter(QObject *obj, QEvent *event)
|
|||||||
|
|
||||||
void DisassemblyWidget::keyPressEvent(QKeyEvent *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();
|
const QTextCursor cursor = mDisasTextEdit->textCursor();
|
||||||
jumpToOffsetUnderCursor(cursor);
|
jumpToOffsetUnderCursor(cursor);
|
||||||
}
|
}
|
||||||
@ -669,6 +697,16 @@ void DisassemblyWidget::keyPressEvent(QKeyEvent *event)
|
|||||||
MemoryDockWidget::keyPressEvent(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
|
QString DisassemblyWidget::getWindowTitle() const
|
||||||
{
|
{
|
||||||
return tr("Disassembly");
|
return tr("Disassembly");
|
||||||
@ -788,9 +826,64 @@ void DisassemblyTextEdit::keyPressEvent(QKeyEvent *event)
|
|||||||
Q_UNUSED(event)
|
Q_UNUSED(event)
|
||||||
// QPlainTextEdit::keyPressEvent(event);
|
// QPlainTextEdit::keyPressEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisassemblyTextEdit::mousePressEvent(QMouseEvent *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);
|
QPlainTextEdit::mousePressEvent(event);
|
||||||
|
|
||||||
if (event->button() == Qt::RightButton && !textCursor().hasSelection()) {
|
if (event->button() == Qt::RightButton && !textCursor().hasSelection()) {
|
||||||
|
@ -41,6 +41,7 @@ public slots:
|
|||||||
* overrides all previous highlighting.
|
* overrides all previous highlighting.
|
||||||
*/
|
*/
|
||||||
void highlightPCLine();
|
void highlightPCLine();
|
||||||
|
void highlightMultiLineSelections();
|
||||||
void showDisasContextMenu(const QPoint &pt);
|
void showDisasContextMenu(const QPoint &pt);
|
||||||
void fontsUpdatedSlot();
|
void fontsUpdatedSlot();
|
||||||
void colorsUpdatedSlot();
|
void colorsUpdatedSlot();
|
||||||
@ -86,6 +87,7 @@ private:
|
|||||||
RVA readCurrentDisassemblyOffset();
|
RVA readCurrentDisassemblyOffset();
|
||||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||||
void keyPressEvent(QKeyEvent *event) override;
|
void keyPressEvent(QKeyEvent *event) override;
|
||||||
|
void keyReleaseEvent(QKeyEvent *event) override;
|
||||||
QString getWindowTitle() const override;
|
QString getWindowTitle() const override;
|
||||||
|
|
||||||
int topOffsetHistoryPos = 0;
|
int topOffsetHistoryPos = 0;
|
||||||
@ -129,11 +131,16 @@ class DisassemblyTextEdit : public QPlainTextEdit
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DisassemblyTextEdit(QWidget *parent = nullptr)
|
explicit DisassemblyTextEdit(QWidget *parent = nullptr)
|
||||||
: QPlainTextEdit(parent), lockScroll(false)
|
: QPlainTextEdit(parent), lockScroll(false), multiLineSelection(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLockScroll(bool lock) { this->lockScroll = lock; }
|
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;
|
qreal textOffset() const;
|
||||||
|
|
||||||
@ -145,6 +152,8 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool lockScroll;
|
bool lockScroll;
|
||||||
|
bool multiLineSelection;
|
||||||
|
QList<QTextEdit::ExtraSelection> multilineSelections;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user