feat: multitab and basic file saving
This commit is contained in:
221
mainwindow.cpp
221
mainwindow.cpp
@ -1,6 +1,8 @@
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include "sciedit.h"
|
||||
#include "tabwidget.h"
|
||||
#include "documentmanager.h"
|
||||
#include "appsettings.h"
|
||||
#include "editorviewhelper.h"
|
||||
|
||||
@ -9,6 +11,8 @@
|
||||
#include <QMenu>
|
||||
#include <QStringBuilder>
|
||||
#include <QStatusBar>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <KActionCollection>
|
||||
#include <KStandardAction>
|
||||
@ -23,30 +27,29 @@
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: KXmlGuiWindow(parent)
|
||||
, m_editor(new SciEdit(this))
|
||||
, m_documentManager(new DocumentManager(this))
|
||||
, m_tabWidget(new TabWidget(m_documentManager, this))
|
||||
, m_cursorPosStatusLabel(new QLabel(QString("Ln: ? Col: ?"), this))
|
||||
, m_encodingStatusLabel(new QLabel(QString("UTF-8"), this))
|
||||
, m_languageStatusLabel(new QLabel(QString("Plain Text"), this))
|
||||
{
|
||||
setCentralWidget(m_editor);
|
||||
setCentralWidget(m_tabWidget);
|
||||
|
||||
// 设置状态栏
|
||||
statusBar()->addPermanentWidget(m_cursorPosStatusLabel);
|
||||
statusBar()->addPermanentWidget(m_encodingStatusLabel);
|
||||
statusBar()->addPermanentWidget(m_languageStatusLabel);
|
||||
|
||||
QFont font(AppSettings::self()->editorFont());
|
||||
m_editor->setStyleFont(font);
|
||||
m_editor->setStyleFont(font, STYLE_LINENUMBER);
|
||||
|
||||
m_editor->setMarginTypeN(1, SC_MARGIN_NUMBER);
|
||||
m_editor->setMarginWidthN(1, m_editor->textWidth(STYLE_LINENUMBER, "_99999"));
|
||||
m_editor->setFolding(SciEdit::BoxFoldType);
|
||||
// m_editor->setBraceMatching(QsciScintilla::SloppyBraceMatch);
|
||||
|
||||
m_editor->setTabWidth(AppSettings::self()->tabWidth());
|
||||
m_editor->setEOLMode(SC_EOL_LF);
|
||||
|
||||
connect(m_editor, &SciEdit::cursorPosChanged, this, [this](int line, int index){
|
||||
m_cursorPosStatusLabel->setText(QString("Ln: %1 Col: %2").arg(line).arg(index));
|
||||
});
|
||||
// 连接标签页信号
|
||||
connect(m_tabWidget, &TabWidget::currentEditorChanged, this, &MainWindow::onCurrentEditorChanged);
|
||||
|
||||
// 连接文档管理器信号
|
||||
connect(m_documentManager, &DocumentManager::documentModified, this, &MainWindow::onDocumentModified);
|
||||
|
||||
setupActions();
|
||||
|
||||
// 创建第一个标签页
|
||||
newFile();
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
@ -58,27 +61,40 @@ void MainWindow::setupActions()
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
// "File" menu
|
||||
KStandardAction::openNew(this, [](){}, actionCollection());
|
||||
KStandardAction::open(this, [](){}, actionCollection());
|
||||
KStandardAction::save(this, [](){}, actionCollection());
|
||||
KStandardAction::close(this, [](){}, actionCollection());
|
||||
KStandardAction::openNew(this, &MainWindow::newFile, actionCollection());
|
||||
KStandardAction::open(this, &MainWindow::openFile, actionCollection());
|
||||
KStandardAction::save(this, &MainWindow::saveFile, actionCollection());
|
||||
KStandardAction::close(this, &MainWindow::closeFile, actionCollection());
|
||||
KStandardAction::quit(qApp, &QApplication::quit, actionCollection());
|
||||
|
||||
// 添加另存为动作
|
||||
QAction *saveAsAction = KStandardAction::saveAs(this, &MainWindow::saveAsFile, actionCollection());
|
||||
|
||||
// "Edit" menu
|
||||
KStandardAction::undo(this, [this](){
|
||||
m_editor->undo();
|
||||
if (SciEdit *editor = m_tabWidget->currentEditor()) {
|
||||
editor->undo();
|
||||
}
|
||||
}, actionCollection());
|
||||
KStandardAction::redo(this, [this](){
|
||||
m_editor->redo();
|
||||
if (SciEdit *editor = m_tabWidget->currentEditor()) {
|
||||
editor->redo();
|
||||
}
|
||||
}, actionCollection());
|
||||
KStandardAction::cut(this, [this](){
|
||||
m_editor->cut();
|
||||
if (SciEdit *editor = m_tabWidget->currentEditor()) {
|
||||
editor->cut();
|
||||
}
|
||||
}, actionCollection());
|
||||
KStandardAction::copy(this, [this](){
|
||||
m_editor->copy();
|
||||
if (SciEdit *editor = m_tabWidget->currentEditor()) {
|
||||
editor->copy();
|
||||
}
|
||||
}, actionCollection());
|
||||
KStandardAction::paste(this, [this](){
|
||||
m_editor->paste();
|
||||
if (SciEdit *editor = m_tabWidget->currentEditor()) {
|
||||
editor->paste();
|
||||
}
|
||||
}, actionCollection());
|
||||
|
||||
// "Search" menu
|
||||
@ -104,10 +120,14 @@ void MainWindow::setupActions()
|
||||
|
||||
// Toolbar actions
|
||||
KStandardAction::zoomIn(this, [this](){
|
||||
m_editor->zoomIn();
|
||||
if (SciEdit *editor = m_tabWidget->currentEditor()) {
|
||||
editor->zoomIn();
|
||||
}
|
||||
}, actionCollection());
|
||||
KStandardAction::zoomOut(this, [this](){
|
||||
m_editor->zoomOut();
|
||||
if (SciEdit *editor = m_tabWidget->currentEditor()) {
|
||||
editor->zoomOut();
|
||||
}
|
||||
}, actionCollection());
|
||||
|
||||
KStandardAction::preferences(this, &MainWindow::showSettings, actionCollection());
|
||||
@ -118,9 +138,11 @@ void MainWindow::setupActions()
|
||||
toggleWrapModeAction->setCheckable(true);
|
||||
actionCollection()->addAction(u"toggle_wrap_mode"_s, toggleWrapModeAction);
|
||||
connect(toggleWrapModeAction, &QAction::triggered, this, [this, toggleWrapModeAction](){
|
||||
bool switchToWrapNone = m_editor->wrapMode() == SC_WRAP_WORD;
|
||||
m_editor->setWrapMode(switchToWrapNone ? SC_WRAP_NONE : SC_WRAP_WORD);
|
||||
toggleWrapModeAction->setChecked(!switchToWrapNone);
|
||||
if (SciEdit *editor = m_tabWidget->currentEditor()) {
|
||||
bool switchToWrapNone = editor->wrapMode() == SC_WRAP_WORD;
|
||||
editor->setWrapMode(switchToWrapNone ? SC_WRAP_NONE : SC_WRAP_WORD);
|
||||
toggleWrapModeAction->setChecked(!switchToWrapNone);
|
||||
}
|
||||
});
|
||||
|
||||
QAction *toggleWhitespaceVisibilityAction = new QAction(this);
|
||||
@ -129,10 +151,12 @@ void MainWindow::setupActions()
|
||||
// toggleWhitespaceVisibilityAction->setIcon(QIcon::fromTheme(u"text-wrap"_s));
|
||||
actionCollection()->addAction(u"toggle_show_all_characters"_s, toggleWhitespaceVisibilityAction);
|
||||
connect(toggleWhitespaceVisibilityAction, &QAction::triggered, this, [this, toggleWhitespaceVisibilityAction](){
|
||||
bool switchToVisible = m_editor->viewWS() == SCWS_INVISIBLE;
|
||||
m_editor->setViewWS(switchToVisible ? SCWS_VISIBLEALWAYS : SCWS_INVISIBLE);
|
||||
m_editor->setViewEOL(switchToVisible);
|
||||
toggleWhitespaceVisibilityAction->setChecked(switchToVisible);
|
||||
if (SciEdit *editor = m_tabWidget->currentEditor()) {
|
||||
bool switchToVisible = editor->viewWS() == SCWS_INVISIBLE;
|
||||
editor->setViewWS(switchToVisible ? SCWS_VISIBLEALWAYS : SCWS_INVISIBLE);
|
||||
editor->setViewEOL(switchToVisible);
|
||||
toggleWhitespaceVisibilityAction->setChecked(switchToVisible);
|
||||
}
|
||||
});
|
||||
|
||||
QAction *toggleIndentGuideAction = new QAction(this);
|
||||
@ -144,7 +168,7 @@ void MainWindow::setupActions()
|
||||
});
|
||||
|
||||
// Load themes
|
||||
KColorSchemeManager *manager = new KColorSchemeManager(this);
|
||||
KColorSchemeManager *manager = KColorSchemeManager::instance();
|
||||
auto *colorSelectionMenu = KColorSchemeMenu::createMenu(manager, this);
|
||||
colorSelectionMenu->menu()->setTitle("&Window Color Scheme");
|
||||
actionCollection()->addAction(QStringLiteral("colorscheme_menu"), colorSelectionMenu);
|
||||
@ -170,6 +194,127 @@ void MainWindow::showSettings()
|
||||
|
||||
void MainWindow::applyLexer(const QString &lexerName)
|
||||
{
|
||||
Scintilla::ILexer5 * lexer = CreateLexer(lexerName.toStdString().c_str());
|
||||
m_editor->setLexer(lexer);
|
||||
if (SciEdit *editor = m_tabWidget->currentEditor()) {
|
||||
Scintilla::ILexer5 * lexer = CreateLexer(lexerName.toStdString().c_str());
|
||||
editor->setLexer(lexer);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::newFile()
|
||||
{
|
||||
m_tabWidget->newDocument();
|
||||
}
|
||||
|
||||
void MainWindow::openFile()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this,
|
||||
tr("Open File"),
|
||||
QString(),
|
||||
tr("All Files (*.*)"));
|
||||
|
||||
if (!fileName.isEmpty()) {
|
||||
m_tabWidget->openDocument(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::saveFile()
|
||||
{
|
||||
m_tabWidget->saveCurrentDocument();
|
||||
}
|
||||
|
||||
void MainWindow::saveAsFile()
|
||||
{
|
||||
m_tabWidget->saveCurrentDocumentAs();
|
||||
}
|
||||
|
||||
void MainWindow::closeFile()
|
||||
{
|
||||
m_tabWidget->closeCurrentTab();
|
||||
}
|
||||
|
||||
void MainWindow::onCurrentTabChanged()
|
||||
{
|
||||
updateWindowTitle();
|
||||
updateStatusBar();
|
||||
updateActions();
|
||||
}
|
||||
|
||||
void MainWindow::onCurrentEditorChanged(SciEdit *editor)
|
||||
{
|
||||
Q_UNUSED(editor)
|
||||
updateWindowTitle();
|
||||
updateStatusBar();
|
||||
updateActions();
|
||||
|
||||
// 连接当前编辑器的光标位置变化信号
|
||||
if (editor) {
|
||||
connect(editor, &SciEdit::cursorPosChanged, this, [this](int line, int column) {
|
||||
m_cursorPosStatusLabel->setText(QString("Ln: %1 Col: %2").arg(line).arg(column));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onDocumentModified(int docIndex, bool modified)
|
||||
{
|
||||
Q_UNUSED(docIndex)
|
||||
Q_UNUSED(modified)
|
||||
updateWindowTitle();
|
||||
}
|
||||
|
||||
void MainWindow::updateWindowTitle()
|
||||
{
|
||||
QString title = "Pineapple Notepad";
|
||||
|
||||
if (SciEdit *editor = m_tabWidget->currentEditor()) {
|
||||
int docId = m_tabWidget->currentDocumentId();
|
||||
if (docId >= 0) {
|
||||
QString fileName = m_documentManager->getDocumentTitle(docId);
|
||||
bool isModified = m_documentManager->isDocumentModified(docId);
|
||||
|
||||
title = QString("%1%2 - Pineapple Notepad")
|
||||
.arg(fileName)
|
||||
.arg(isModified ? "*" : "");
|
||||
}
|
||||
}
|
||||
|
||||
setWindowTitle(title);
|
||||
}
|
||||
|
||||
void MainWindow::updateStatusBar()
|
||||
{
|
||||
if (SciEdit *editor = m_tabWidget->currentEditor()) {
|
||||
int docId = m_tabWidget->currentDocumentId();
|
||||
if (docId >= 0) {
|
||||
QString encoding = m_documentManager->getDocumentEncoding(docId);
|
||||
QString language = m_documentManager->getDocumentLanguage(docId);
|
||||
|
||||
m_encodingStatusLabel->setText(encoding);
|
||||
m_languageStatusLabel->setText(language);
|
||||
}
|
||||
} else {
|
||||
m_encodingStatusLabel->setText("UTF-8");
|
||||
m_languageStatusLabel->setText("Plain Text");
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::updateActions()
|
||||
{
|
||||
bool hasEditor = (m_tabWidget->currentEditor() != nullptr);
|
||||
|
||||
// 更新编辑相关的动作状态
|
||||
if (QAction *undoAction = actionCollection()->action(KStandardAction::name(KStandardAction::Undo))) {
|
||||
undoAction->setEnabled(hasEditor);
|
||||
}
|
||||
if (QAction *redoAction = actionCollection()->action(KStandardAction::name(KStandardAction::Redo))) {
|
||||
redoAction->setEnabled(hasEditor);
|
||||
}
|
||||
if (QAction *cutAction = actionCollection()->action(KStandardAction::name(KStandardAction::Cut))) {
|
||||
cutAction->setEnabled(hasEditor);
|
||||
}
|
||||
if (QAction *copyAction = actionCollection()->action(KStandardAction::name(KStandardAction::Copy))) {
|
||||
copyAction->setEnabled(hasEditor);
|
||||
}
|
||||
if (QAction *pasteAction = actionCollection()->action(KStandardAction::name(KStandardAction::Paste))) {
|
||||
pasteAction->setEnabled(hasEditor);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user