Skip to content

Commit

Permalink
feat: [editor] Implement a feature of cursor position back or forward
Browse files Browse the repository at this point in the history
as title

Log: new feature
  • Loading branch information
Kakueeen committed Jan 19, 2024
1 parent ce66c64 commit 530c2a9
Show file tree
Hide file tree
Showing 11 changed files with 176 additions and 84 deletions.
17 changes: 17 additions & 0 deletions src/plugins/codeeditor/gui/private/tabwidget_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,31 @@ class TabWidgetPrivate : public QObject
{
Q_OBJECT
public:
struct PosRecord
{
int pos = 0;
QString fileName;
};

explicit TabWidgetPrivate(TabWidget *qq);

void initUI();
void initConnection();

TextEditor *currentTextEditor() const;
void changeFocusProxy();
bool processKeyPressEvent(QKeyEvent *event);

void doSave();
void gotoNextPosition();
void gotoPreviousPsontion();
void removePositionRecord(const QString &fileName);

public:
void onTabSwitched(const QString &fileName);
void onTabClosed(const QString &fileName);
void onSpliterClicked(Qt::Orientation ori);
void onLinePositionChanged(int line, int index);

public:
TabWidget *q;
Expand All @@ -36,6 +49,10 @@ class TabWidgetPrivate : public QObject
TextEditorManager *editorMng { nullptr };

QHash<QString, int> editorIndexHash;

PosRecord curPosRecord;
QList<PosRecord> prePosRecord;
QList<PosRecord> nextPosRecord;
};

#endif // TABWIDGET_P_H
9 changes: 8 additions & 1 deletion src/plugins/codeeditor/gui/private/texteditor_p.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ static constexpr int TAB_DEFAULT_WIDTH = 4;
DGUI_USE_NAMESPACE

TextEditorPrivate::TextEditorPrivate(TextEditor *qq)
: q(qq)
: QObject(qq),
q(qq)
{
init();
initConnection();
}

void TextEditorPrivate::init()
Expand All @@ -34,6 +36,11 @@ void TextEditorPrivate::init()
updateSettings();
}

void TextEditorPrivate::initConnection()
{
connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged, this, &TextEditorPrivate::updateColorTheme);
}

void TextEditorPrivate::initMargins()
{
// Display line number
Expand Down
4 changes: 3 additions & 1 deletion src/plugins/codeeditor/gui/private/texteditor_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@

#include "gui/texteditor.h"

class TextEditorPrivate
class TextEditorPrivate : public QObject
{
Q_OBJECT
public:
enum MarkSymbol {
BreakpointSymbol = 0,
Expand Down Expand Up @@ -38,6 +39,7 @@ class TextEditorPrivate
explicit TextEditorPrivate(TextEditor *qq);

void init();
void initConnection();
void initMargins();
void updateColorTheme();
void updateSettings();
Expand Down
186 changes: 136 additions & 50 deletions src/plugins/codeeditor/gui/tabwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <QLabel>
#include <QScrollBar>

static constexpr int MAX_PRE_NEXT_TIMES = 30;

TabWidgetPrivate::TabWidgetPrivate(TabWidget *qq)
: QObject(qq),
q(qq),
Expand Down Expand Up @@ -67,6 +69,88 @@ void TabWidgetPrivate::changeFocusProxy()
q->setFocus();
}

bool TabWidgetPrivate::processKeyPressEvent(QKeyEvent *event)
{
switch (event->modifiers()) {
case Qt::ControlModifier: {
switch (event->key()) {
case Qt::Key_S:
doSave();
return true;
}
} break;
case Qt::AltModifier: {
switch (event->key()) {
case Qt::Key_Left:
gotoPreviousPsontion();
return true;
case Qt::Key_Right:
gotoNextPosition();
return true;
}
} break;
}

return false;
}

void TabWidgetPrivate::doSave()
{
if (auto editor = currentTextEditor())
editor->save();
}

void TabWidgetPrivate::gotoNextPosition()
{
if (nextPosRecord.isEmpty())
return;

auto record = nextPosRecord.takeFirst();
auto editor = editorMng->findEditor(record.fileName);
if (!editor)
return;

prePosRecord.append(record);
tabBar->switchTab(record.fileName);
editor->gotoPosition(record.pos);
curPosRecord = record;
}

void TabWidgetPrivate::gotoPreviousPsontion()
{
if (prePosRecord.size() <= 1)
return;

auto record = prePosRecord.takeLast();
nextPosRecord.push_front(record);
if (nextPosRecord.size() >= MAX_PRE_NEXT_TIMES)
nextPosRecord.takeLast();

record = prePosRecord.last();
auto editor = editorMng->findEditor(record.fileName);
if (!editor)
return;

tabBar->switchTab(record.fileName);
editor->gotoPosition(record.pos);
curPosRecord = record;
}

void TabWidgetPrivate::removePositionRecord(const QString &fileName)
{
auto iter = std::remove_if(prePosRecord.begin(), prePosRecord.end(),
[=](const PosRecord &record) {
return record.fileName == fileName;
});
prePosRecord.erase(iter, prePosRecord.end());

iter = std::remove_if(nextPosRecord.begin(), nextPosRecord.end(),
[=](const PosRecord &record) {
return record.fileName == fileName;
});
nextPosRecord.erase(iter, nextPosRecord.end());
}

void TabWidgetPrivate::onTabSwitched(const QString &fileName)
{
if (!editorIndexHash.contains(fileName))
Expand All @@ -82,6 +166,7 @@ void TabWidgetPrivate::onTabClosed(const QString &fileName)
if (!editor)
return;

removePositionRecord(fileName);
editorIndexHash.remove(fileName);
editorLayout->removeWidget(editor);
changeFocusProxy();
Expand All @@ -101,6 +186,22 @@ void TabWidgetPrivate::onSpliterClicked(Qt::Orientation ori)
emit q->splitRequested(ori, fileName);
}

void TabWidgetPrivate::onLinePositionChanged(int line, int index)
{
auto editor = qobject_cast<TextEditor *>(sender());
if (!editor)
return;

int pos = editor->positionFromLineIndex(line, index);

if (curPosRecord.fileName == editor->getFile() && curPosRecord.pos == pos)
return;

prePosRecord.append({ pos, editor->getFile() });
if (prePosRecord.size() >= MAX_PRE_NEXT_TIMES)
prePosRecord.takeFirst();
}

TabWidget::TabWidget(QWidget *parent)
: QWidget(parent),
d(new TabWidgetPrivate(this))
Expand All @@ -121,74 +222,60 @@ void TabWidget::setSplitButtonVisible(bool visible)

QString TabWidget::selectedText() const
{
auto editor = d->currentTextEditor();
if (!editor)
return "";
if (auto editor = d->currentTextEditor())

Check warning on line 225 in src/plugins/codeeditor/gui/tabwidget.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Variable 'editor' is assigned a value that is never used.
return d->currentTextEditor()->selectedText();

return d->currentTextEditor()->selectedText();
return "";
}

QString TabWidget::cursorBeforeText() const
{
auto editor = d->currentTextEditor();
if (!editor)
return "";
if (auto editor = d->currentTextEditor())
return editor->cursorBeforeText();

return editor->cursorBeforeText();
return "";
}

QString TabWidget::cursorBehindText() const
{
auto editor = d->currentTextEditor();
if (!editor)
return "";
if (auto editor = d->currentTextEditor())
return editor->cursorBehindText();

return editor->cursorBehindText();
return "";
}

void TabWidget::replaceSelectedText(const QString &text)
{
auto editor = d->currentTextEditor();
if (!editor)
return;

return editor->replaceSelectedText(text);
if (auto editor = d->currentTextEditor())
editor->replaceSelectedText(text);
}

void TabWidget::setEditorCursorPosition(int pos)
{
auto editor = d->currentTextEditor();
if (!editor)
return;

editor->gotoPosition(pos);
if (auto editor = d->currentTextEditor())
editor->gotoPosition(pos);
}

int TabWidget::editorCursorPosition()
{
auto editor = d->currentTextEditor();
if (!editor)
return 0;
if (auto editor = d->currentTextEditor())
return editor->cursorPosition();

return editor->cursorPosition();
return 0;
}

void TabWidget::setEditorScrollValue(int value)
{
auto editor = d->currentTextEditor();
if (!editor)
return;

editor->verticalScrollBar()->setValue(value);
if (auto editor = d->currentTextEditor())
editor->verticalScrollBar()->setValue(value);
}

int TabWidget::editorScrollValue()
{
auto editor = d->currentTextEditor();
if (!editor)
return 0;
if (auto editor = d->currentTextEditor())
return editor->verticalScrollBar()->value();

return editor->verticalScrollBar()->value();
return 0;
}

void TabWidget::addBreakpoint(const QString &fileName, int line)
Expand Down Expand Up @@ -223,7 +310,9 @@ void TabWidget::openFile(const QString &fileName)

d->tabBar->setFileName(fileName);
TextEditor *editor = d->editorMng->createEditor(this, fileName);
editor->installEventFilter(this);
editor->setCursorPosition(0, 0);
connect(editor, &TextEditor::cursorPositionChanged, d.data(), &TabWidgetPrivate::onLinePositionChanged);
connect(editor, &TextEditor::fileSaved, d->tabBar, &TabBar::onFileSaved);
connect(editor, &TextEditor::textChanged, d->tabBar,
[this, fileName] {
Expand All @@ -240,21 +329,6 @@ void TabWidget::openFile(const QString &fileName)
d->editorIndexHash.insert(fileName, index);
}

void TabWidget::keyPressEvent(QKeyEvent *event)
{
QWidget::keyPressEvent(event);
}

void TabWidget::focusInEvent(QFocusEvent *event)
{
QWidget::focusInEvent(event);
}

void TabWidget::focusOutEvent(QFocusEvent *event)
{
QWidget::focusOutEvent(event);
}

void TabWidget::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasUrls()) {
Expand All @@ -274,3 +348,15 @@ void TabWidget::dropEvent(QDropEvent *event)
openFile(fileName);
}
}

bool TabWidget::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() != QEvent::KeyPress)
return false;

auto editor = qobject_cast<TextEditor *>(obj);
if (!editor)
return false;

return d->processKeyPressEvent(static_cast<QKeyEvent *>(event));
}
5 changes: 1 addition & 4 deletions src/plugins/codeeditor/gui/tabwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,11 @@ public slots:
void splitRequested(Qt::Orientation ori, const QString &fileName);

protected:
virtual void keyPressEvent(QKeyEvent *event) override;
virtual void focusInEvent(QFocusEvent *event) override;
virtual void focusOutEvent(QFocusEvent *event) override;
virtual void dragEnterEvent(QDragEnterEvent *event) override;
virtual void dropEvent(QDropEvent *event) override;
virtual bool eventFilter(QObject *obj, QEvent *event) override;

private:
std::once_flag flag;
QSharedPointer<TabWidgetPrivate> d { nullptr };
};

Expand Down
1 change: 1 addition & 0 deletions src/plugins/codeeditor/gui/texteditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ void TextEditor::save()

file.write(text().toUtf8());
file.close();
emit fileSaved(d->fileName);
}

void TextEditor::saveAs()

Check warning on line 85 in src/plugins/codeeditor/gui/texteditor.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'saveAs' is never used.
Expand Down
6 changes: 3 additions & 3 deletions src/plugins/codeeditor/gui/workspacewidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ void WorkspaceWidgetPrivate::initConnection()
{
connect(qApp, &QApplication::focusChanged, this, &WorkspaceWidgetPrivate::onFocusChanged);

connect(EditorCallProxy::instance(), &EditorCallProxy::openFileRequested, this, &WorkspaceWidgetPrivate::onOpenFileRequested);
connect(EditorCallProxy::instance(), &EditorCallProxy::addBreakpointRequested, this, &WorkspaceWidgetPrivate::onAddBreakpointRequested);
connect(EditorCallProxy::instance(), &EditorCallProxy::removeBreakpointRequested, this, &WorkspaceWidgetPrivate::onRemoveBreakpointRequested);
connect(EditorCallProxy::instance(), &EditorCallProxy::reqOpenFile, this, &WorkspaceWidgetPrivate::onOpenFileRequested);
connect(EditorCallProxy::instance(), &EditorCallProxy::reqAddBreakpoint, this, &WorkspaceWidgetPrivate::onAddBreakpointRequested);
connect(EditorCallProxy::instance(), &EditorCallProxy::reqRemoveBreakpoint, this, &WorkspaceWidgetPrivate::onRemoveBreakpointRequested);
}

void WorkspaceWidgetPrivate::connectTabWidgetSignals(TabWidget *tabWidget)
Expand Down
Loading

0 comments on commit 530c2a9

Please sign in to comment.