feat: Implement core functionality for DTC C/C++ IDE

- Added ProjectManager class to handle project operations including opening, closing, building, and running projects.
- Introduced SyntaxHighlighter class for syntax highlighting in C and C++ files.
- Developed TerminalWidget for command execution and output display.
- Created TextEditor with line numbering and auto-indentation features.
- Established main application entry point in main.cpp.
- Designed UI layout for MainWindow using Qt Designer.
This commit is contained in:
TIPC1110
2025-07-04 12:23:20 +07:00
parent cb1b9863e0
commit a32f79f6d5
22 changed files with 2930 additions and 0 deletions

47
include/FileTreeWidget.h Normal file
View File

@@ -0,0 +1,47 @@
#pragma once
#include <QtWidgets/QTreeWidget>
#include <QtWidgets/QTreeWidgetItem>
#include <QtWidgets/QMenu>
#include <QtCore/QFileSystemWatcher>
#include <QtCore/QDir>
class FileTreeWidget : public QTreeWidget
{
Q_OBJECT
public:
explicit FileTreeWidget(QWidget *parent = nullptr);
~FileTreeWidget();
void setRootPath(const QString &path);
QString rootPath() const;
void refreshTree();
signals:
void fileSelected(const QString &filePath);
void fileDoubleClicked(const QString &filePath);
void directorySelected(const QString &dirPath);
private slots:
void onItemClicked(QTreeWidgetItem *item, int column);
void onItemDoubleClicked(QTreeWidgetItem *item, int column);
void onCustomContextMenu(const QPoint &point);
void onDirectoryChanged(const QString &path);
void newFile();
void newFolder();
void deleteItem();
void renameItem();
private:
void populateTree(const QString &path, QTreeWidgetItem *parent = nullptr);
void setupContextMenu();
QString getItemPath(QTreeWidgetItem *item) const;
bool isDirectory(QTreeWidgetItem *item) const;
QString m_rootPath;
QFileSystemWatcher *m_fileWatcher;
QMenu *m_contextMenu;
QTreeWidgetItem *m_contextItem;
};

65
include/MainWindow.h Normal file
View File

@@ -0,0 +1,65 @@
#pragma once
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QToolBar>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QSplitter>
#include <QtWidgets/QTabWidget>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QFileDialog>
#include <QtWidgets/QMessageBox>
#include <QtCore/QSettings>
class TextEditor;
class FileTreeWidget;
class TerminalWidget;
class ProjectManager;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void newFile();
void openFile();
void saveFile();
void saveAsFile();
void openProject();
void buildProject();
void runProject();
void debugProject();
void showAbout();
void toggleTheme();
private:
void setupUI();
void setupMenus();
void setupToolbar();
void setupStatusBar();
void connectSignals();
void loadSettings();
void saveSettings();
// UI Components
QSplitter *m_centralSplitter;
QSplitter *m_leftSplitter;
QTabWidget *m_editorTabs;
FileTreeWidget *m_fileTree;
TerminalWidget *m_terminal;
// Managers
ProjectManager *m_projectManager;
// Settings
QSettings *m_settings;
bool m_darkTheme;
// Current file
QString m_currentFilePath;
};

66
include/ProjectManager.h Normal file
View File

@@ -0,0 +1,66 @@
#pragma once
#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QProcess>
class ProjectManager : public QObject
{
Q_OBJECT
public:
explicit ProjectManager(QObject *parent = nullptr);
~ProjectManager();
bool openProject(const QString &projectPath);
void closeProject();
QString projectPath() const;
QString projectName() const;
bool hasProject() const;
bool isCMakeProject() const;
bool isQMakeProject() const;
void buildProject();
void cleanProject();
void configureProject();
void runProject();
QString buildDirectory() const;
QString sourceDirectory() const;
signals:
void projectOpened(const QString &projectPath);
void projectClosed();
void buildStarted();
void buildFinished(bool success);
void buildOutput(const QString &output);
private slots:
void onBuildProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
void onBuildProcessError(QProcess::ProcessError error);
void onBuildOutput();
private:
void detectProjectType();
void setupBuildDirectory();
QString findCMakeListsFile(const QString &directory) const;
QString findQMakeFile(const QString &directory) const;
QString m_projectPath;
QString m_projectName;
QString m_buildDirectory;
enum ProjectType {
Unknown,
CMake,
QMake
};
ProjectType m_projectType;
QProcess *m_buildProcess;
bool m_isBuilding;
};

View File

@@ -0,0 +1,47 @@
#pragma once
#include <QtGui/QSyntaxHighlighter>
#include <QtGui/QTextDocument>
#include <QtGui/QTextCharFormat>
#include <QtCore/QRegularExpression>
class SyntaxHighlighter : public QSyntaxHighlighter
{
Q_OBJECT
public:
explicit SyntaxHighlighter(QTextDocument *parent = nullptr);
~SyntaxHighlighter();
void setLanguage(const QString &language);
QString language() const;
protected:
void highlightBlock(const QString &text) override;
private:
struct HighlightingRule
{
QRegularExpression pattern;
QTextCharFormat format;
};
QVector<HighlightingRule> m_highlightingRules;
void setupCppHighlighting();
void setupCHighlighting();
void setupCommonRules();
QTextCharFormat m_keywordFormat;
QTextCharFormat m_classFormat;
QTextCharFormat m_singleLineCommentFormat;
QTextCharFormat m_multiLineCommentFormat;
QTextCharFormat m_quotationFormat;
QTextCharFormat m_functionFormat;
QTextCharFormat m_numberFormat;
QTextCharFormat m_preprocessorFormat;
QRegularExpression m_commentStartExpression;
QRegularExpression m_commentEndExpression;
QString m_language;
};

58
include/TerminalWidget.h Normal file
View File

@@ -0,0 +1,58 @@
#pragma once
#include <QtWidgets/QWidget>
#include <QtWidgets/QTextEdit>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QPushButton>
#include <QtCore/QProcess>
#include <QtCore/QTimer>
class TerminalWidget : public QWidget
{
Q_OBJECT
public:
explicit TerminalWidget(QWidget *parent = nullptr);
~TerminalWidget();
void setWorkingDirectory(const QString &directory);
QString workingDirectory() const;
void executeCommand(const QString &command);
void clear();
void showBuildOutput();
void showRunOutput();
signals:
void commandFinished(int exitCode);
private slots:
void onCommandEntered();
void onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
void onProcessError(QProcess::ProcessError error);
void onProcessOutput();
void updatePrompt();
private:
void setupUI();
void setupProcess();
void appendOutput(const QString &text, const QColor &color = Qt::white);
void appendPrompt();
QTextEdit *m_output;
QLineEdit *m_input;
QPushButton *m_clearButton;
QProcess *m_process;
QString m_workingDirectory;
QString m_currentPrompt;
// Colors for different output types
QColor m_normalColor;
QColor m_errorColor;
QColor m_successColor;
QColor m_promptColor;
};

77
include/TextEditor.h Normal file
View File

@@ -0,0 +1,77 @@
#pragma once
#include <QtWidgets/QPlainTextEdit>
#include <QtCore/QTextStream>
#include <QtGui/QTextDocument>
#include <QtGui/QTextCursor>
#include <QtGui/QKeyEvent>
#include <QtCore/QTimer>
class SyntaxHighlighter;
class TextEditor : public QPlainTextEdit
{
Q_OBJECT
friend class LineNumberArea;
public:
explicit TextEditor(QWidget *parent = nullptr);
~TextEditor();
void setFilePath(const QString &filePath);
QString filePath() const;
bool isModified() const;
void setModified(bool modified);
bool loadFile(const QString &filePath);
bool saveFile();
bool saveAsFile(const QString &filePath);
void setLineNumberAreaWidth(int width);
void updateLineNumberArea(const QRect &rect, int dy);
signals:
void fileModified(bool modified);
void cursorPositionChanged(int line, int column);
protected:
void keyPressEvent(QKeyEvent *event) override;
void paintEvent(QPaintEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
private slots:
void highlightCurrentLine();
void updateCursorPosition();
void autoIndent();
private:
void setupEditor();
void updateLineNumberAreaWidth(int newBlockCount);
public:
int lineNumberAreaWidth();
QString m_filePath;
bool m_isModified;
SyntaxHighlighter *m_syntaxHighlighter;
QWidget *m_lineNumberArea;
QTimer *m_autoSaveTimer;
};
// Line number area widget
class LineNumberArea : public QWidget
{
public:
LineNumberArea(TextEditor *editor) : QWidget(editor), m_textEditor(editor) {}
QSize sizeHint() const override {
return QSize(m_textEditor->lineNumberAreaWidth(), 0);
}
protected:
void paintEvent(QPaintEvent *event) override;
private:
TextEditor *m_textEditor;
};