Skip to content

Commit

Permalink
Add "open include" for C/C++ editor
Browse files Browse the repository at this point in the history
Signed-off-by: Martin Ribelotta <[email protected]>
  • Loading branch information
martinribelotta committed Jun 24, 2020
1 parent 669791b commit 20ce25d
Show file tree
Hide file tree
Showing 9 changed files with 207 additions and 0 deletions.
25 changes: 25 additions & 0 deletions ide/cpptexteditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ static const QStringList C_CXX_EXTENSIONS = { "c", "cpp", "h", "hpp", "cc", "hh"
static const QStringList C_MIMETYPE = { "text/x-c++src", "text/x-c++hdr" };
static const QStringList CXX_MIMETYPE = { "text/x-c", "text/x-csrc", "text/x-chdr" };

static inline void triggerFindAndOpen(const QString& filePath)
{
TextMessageBrocker::instance().publish("findAndOpen", filePath);
}

class MyQsciLexerCPP: public QsciLexerCPP {
private:
QLatin1String keywordList;
Expand Down Expand Up @@ -81,6 +86,7 @@ CPPTextEditor::CPPTextEditor(QWidget *parent) : CodeTextEditor(parent)
setAutoCompletionSource(AcsNone);
connect(new QShortcut(QKeySequence("Ctrl+Return"), this), &QShortcut::activated, this, &CPPTextEditor::findReference);
connect(new QShortcut(QKeySequence("Ctrl+i"), this), &QShortcut::activated, this, &CPPTextEditor::formatCode);
connect(new QShortcut(QKeySequence("Ctrl+Shift+i"), this), &QShortcut::activated, this, &CPPTextEditor::openIncludeInCursor);
}

CPPTextEditor::~CPPTextEditor() = default;
Expand Down Expand Up @@ -186,13 +192,32 @@ void CPPTextEditor::formatCode()
ensureLineVisible(l);
}

void CPPTextEditor::openIncludeInCursor()
{
static const QRegularExpression incRe(R"(^\s*\#\s*include(?:_next)?\s+[\<\"](.*)[\>\"])");
auto m = incRe.match(lineUnderCursor());
if (m.hasMatch()) {
auto file = m.captured(1);
triggerFindAndOpen(file);
}
}

QMenu *CPPTextEditor::createContextualMenu()
{
auto menu = CodeTextEditor::createContextualMenu();
menu->addAction(QIcon(AppConfig::resourceImage({ "actions", "code-context" })),
tr("Find Reference"),
this, &CPPTextEditor::findReference)
->setShortcut(QKeySequence("CTRL+ENTER"));
static const QRegularExpression incRe(R"(^\s*\#\s*include(?:_next)?\s+[\<\"](.*)[\>\"])");
auto m = incRe.match(lineUnderCursor());
if (m.hasMatch()) {
auto file = m.captured(1);
menu->addAction(QIcon(AppConfig::resourceImage({"actions", "document-open"})),
tr("Open Include"), this, [file]() {
triggerFindAndOpen(file);
})->setShortcut(QKeySequence("Ctrl+Shift+i"));
}
return menu;
}

Expand Down
4 changes: 4 additions & 0 deletions ide/cpptexteditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,13 @@ class CPPTextEditor : public CodeTextEditor

static IDocumentEditorCreator *creator();

signals:
void queryToOpen(const QString& path);

private slots:
void findReference();
void formatCode();
void openIncludeInCursor();

protected:
QMenu *createContextualMenu() override;
Expand Down
51 changes: 51 additions & 0 deletions ide/findandopenfiledialog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include "findandopenfiledialog.h"
#include "ui_findandopenfiledialog.h"

#include <QDirIterator>
#include <QStandardItemModel>
#include <QStringListModel>
#include <QPushButton>

FindAndOpenFileDialog::FindAndOpenFileDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::FindAndOpenFileDialog)
{
ui->setupUi(this);
ui->buttonBox->button(QDialogButtonBox::Open)->setDisabled(true);
connect(ui->fileList, &QAbstractItemView::activated, this, &QDialog::accept);
}

FindAndOpenFileDialog::~FindAndOpenFileDialog()
{
delete ui;
}

void FindAndOpenFileDialog::setFileList(const QString& prefix, const QStringList &list)
{
if (ui->fileList->model())
ui->fileList->model()->deleteLater();
auto m = new QStandardItemModel(this);
for (const auto& e: list) {
auto item = new QStandardItem{"..." + QString{e}.remove(prefix)};
item->setData(e, Qt::UserRole + 1);
m->appendRow(item);
}
ui->fileList->setModel(m);
ui->buttonBox->button(QDialogButtonBox::Open)->setDisabled(list.isEmpty());
}

QString FindAndOpenFileDialog::selectedFile() const
{
auto idx = ui->fileList->currentIndex();
return ui->fileList->model()->data(idx, Qt::UserRole + 1).toString();
}

QStringList FindAndOpenFileDialog::findFilesInPath(const QString &file, const QString &path)
{
QStringList list;
QDirIterator it(path, { file }, QDir::NoDotAndDotDot | QDir::Files, QDirIterator::Subdirectories);
while (it.hasNext()) {
list.append(it.next());
}
return list;
}
27 changes: 27 additions & 0 deletions ide/findandopenfiledialog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef FINDANDOPENFILEDIALOG_H
#define FINDANDOPENFILEDIALOG_H

#include <QDialog>

namespace Ui {
class FindAndOpenFileDialog;
}

class FindAndOpenFileDialog : public QDialog
{
Q_OBJECT

public:
explicit FindAndOpenFileDialog(QWidget *parent = nullptr);
~FindAndOpenFileDialog();

void setFileList(const QString &prefix, const QStringList &list);
QString selectedFile() const;

static QStringList findFilesInPath(const QString& file, const QString& path);

private:
Ui::FindAndOpenFileDialog *ui;
};

#endif // FINDANDOPENFILEDIALOG_H
74 changes: 74 additions & 0 deletions ide/findandopenfiledialog.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FindAndOpenFileDialog</class>
<widget class="QDialog" name="FindAndOpenFileDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>582</width>
<height>355</height>
</rect>
</property>
<property name="windowTitle">
<string>Select file to open</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QListView" name="fileList">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Open</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>FindAndOpenFileDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>FindAndOpenFileDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
3 changes: 3 additions & 0 deletions ide/ide.pro
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ INCLUDEPATH += $$PWD/../3rdpart

SOURCES += \
envinputdialog.cpp \
findandopenfiledialog.cpp \
findmakefiledialog.cpp \
main.cpp \
mainwindow.cpp \
Expand Down Expand Up @@ -78,6 +79,7 @@ SOURCES += \
HEADERS += \
buttoneditoritemdelegate.h \
envinputdialog.h \
findandopenfiledialog.h \
findmakefiledialog.h \
mainwindow.h \
markdowneditor.h \
Expand Down Expand Up @@ -119,6 +121,7 @@ HEADERS += \

FORMS += \
envinputdialog.ui \
findandopenfiledialog.ui \
findmakefiledialog.ui \
mainwindow.ui \
newprojectfromremotedialog.ui \
Expand Down
8 changes: 8 additions & 0 deletions ide/plaintexteditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,14 @@ QString PlainTextEditor::wordUnderCursor() const
return wordAtLineIndex(line, col);
}

QString PlainTextEditor::lineUnderCursor() const
{
int line;
int col;
getCursorPosition(&line, &col);
return text(line);
}

void PlainTextEditor::adjustLineNumberMargin()
{
QFontMetrics m(font());
Expand Down
1 change: 1 addition & 0 deletions ide/plaintexteditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class PlainTextEditor : public IDocumentEditor, public QsciScintilla
static IDocumentEditorCreator *creator();

QString wordUnderCursor() const;
QString lineUnderCursor() const;

virtual void triggerAutocompletion();

Expand Down
14 changes: 14 additions & 0 deletions ide/projectmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "appconfig.h"
#include "buildmanager.h"
#include "childprocess.h"
#include "findandopenfiledialog.h"
#include "icodemodelprovider.h"
#include "processmanager.h"
#include "projectmanager.h"
Expand Down Expand Up @@ -122,6 +123,19 @@ ProjectManager::ProjectManager(QListView *view, ProcessManager *pman, QObject *p
button->setIcon(QIcon(AppConfig::resourceImage({ "actions", "run-build" })));
});

TextMessageBrocker::instance().subscribe("findAndOpen", [this](const QString& path) {
auto files = FindAndOpenFileDialog::findFilesInPath(path, projectPath());
if (files.length() == 1) {
requestFileOpen(files.first());
} else {
FindAndOpenFileDialog d(priv->targetView->window());
d.setFileList(projectPath(), files);
if (d.exec()) {
requestFileOpen(d.selectedFile());
}
}
});

auto label = new QLabel(view);
auto g = new QGridLayout(view);
g->addWidget(label, 1, 1);
Expand Down

0 comments on commit 20ce25d

Please sign in to comment.