#include "tabwidget.h" #include "sciedit.h" #include "documentmanager.h" #include #include #include TabWidget::TabWidget(DocumentManager *documentManager, QWidget *parent) : QTabWidget(parent) , m_documentManager(documentManager) { setTabsClosable(true); setMovable(true); setUsesScrollButtons(true); // 连接信号 connect(this, &QTabWidget::currentChanged, this, &TabWidget::onCurrentChanged); connect(this, &QTabWidget::tabCloseRequested, this, &TabWidget::onTabCloseRequested); // 连接文档管理器信号 connect(m_documentManager, &DocumentManager::documentModified, this, &TabWidget::onDocumentModified); connect(m_documentManager, &DocumentManager::documentTitleChanged, this, &TabWidget::onDocumentTitleChanged); // 创建第一个文档 newDocument(); } TabWidget::~TabWidget() { } int TabWidget::newDocument() { int docId = m_documentManager->createNewDocument(); if (docId == -1) { return -1; } SciEdit *editor = createEditor(); m_editors[docId] = editor; QString title = m_documentManager->getDocumentTitle(docId); int tabIndex = addTab(editor, title); m_tabToDocumentId[tabIndex] = docId; m_documentIdToTab[docId] = tabIndex; setCurrentIndex(tabIndex); return docId; } int TabWidget::openDocument(const QString &filePath) { int docId = m_documentManager->openDocument(filePath); if (docId == -1) { QMessageBox::warning(this, "Error", "Failed to open file: " + filePath); return -1; } SciEdit *editor = createEditor(); m_editors[docId] = editor; // 设置编辑器内容 QString content = m_documentManager->getDocumentContent(docId); editor->setText(content.toUtf8().constData()); QString title = m_documentManager->getDocumentTitle(docId); int tabIndex = addTab(editor, title); m_tabToDocumentId[tabIndex] = docId; m_documentIdToTab[docId] = tabIndex; setCurrentIndex(tabIndex); return docId; } bool TabWidget::saveCurrentDocument() { SciEdit *editor = currentEditor(); if (!editor) { return false; } int docId = currentDocumentId(); if (docId == -1) { return false; } // 更新文档内容 QByteArray content = editor->getText(editor->textLength()); m_documentManager->setDocumentContent(docId, QString::fromUtf8(content)); if (m_documentManager->isDocumentUntitled(docId)) { return saveCurrentDocumentAs(); } return m_documentManager->saveDocument(docId); } bool TabWidget::saveCurrentDocumentAs() { SciEdit *editor = currentEditor(); if (!editor) { return false; } int docId = currentDocumentId(); if (docId == -1) { return false; } QString fileName = QFileDialog::getSaveFileName(this, "Save File", m_documentManager->getDocumentTitle(docId), "All Files (*.*)"); if (fileName.isEmpty()) { return false; } // 更新文档内容 QByteArray content = editor->getText(editor->textLength()); m_documentManager->setDocumentContent(docId, QString::fromUtf8(content)); return m_documentManager->saveDocumentAs(docId, fileName); } void TabWidget::closeCurrentTab() { int index = currentIndex(); if (index >= 0) { closeTab(index); } } bool TabWidget::closeTab(int index) { if (index < 0 || index >= count()) { return false; } int docId = m_tabToDocumentId.value(index, -1); if (docId == -1) { return false; } // 检查是否需要保存 if (m_documentManager->isDocumentModified(docId)) { QString title = m_documentManager->getDocumentTitle(docId); int ret = QMessageBox::question(this, "Save Changes", QString("The document '%1' has been modified.\nDo you want to save your changes?").arg(title), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); if (ret == QMessageBox::Save) { // 更新文档内容 SciEdit *editor = editorAt(index); if (editor) { QByteArray content = editor->getText(editor->textLength()); m_documentManager->setDocumentContent(docId, QString::fromUtf8(content)); } bool saved = false; if (m_documentManager->isDocumentUntitled(docId)) { QString fileName = QFileDialog::getSaveFileName(this, "Save File", title, "All Files (*.*)"); if (!fileName.isEmpty()) { saved = m_documentManager->saveDocumentAs(docId, fileName); } } else { saved = m_documentManager->saveDocument(docId); } if (!saved) { return false; // 保存失败,不关闭标签页 } } else if (ret == QMessageBox::Cancel) { return false; // 取消关闭 } } // 移除标签页 QWidget *widget = this->widget(index); removeTab(index); // 清理映射关系 m_tabToDocumentId.remove(index); m_documentIdToTab.remove(docId); // 更新其他标签页的索引映射 QHash newTabToDocumentId; QHash newDocumentIdToTab; for (int i = 0; i < count(); ++i) { int oldIndex = (i >= index) ? i + 1 : i; int oldDocId = m_tabToDocumentId.value(oldIndex, -1); if (oldDocId != -1) { newTabToDocumentId[i] = oldDocId; newDocumentIdToTab[oldDocId] = i; } } m_tabToDocumentId = newTabToDocumentId; m_documentIdToTab = newDocumentIdToTab; // 清理编辑器和文档 if (m_editors.contains(docId)) { SciEdit *editor = m_editors[docId]; disconnectEditorSignals(editor); m_editors.remove(docId); } m_documentManager->closeDocument(docId); if (widget) { widget->deleteLater(); } // 如果没有标签页了,创建一个新的 if (count() == 0) { newDocument(); } return true; } void TabWidget::closeAllTabs() { while (count() > 0) { closeTab(0); } } SciEdit *TabWidget::currentEditor() const { int docId = currentDocumentId(); return m_editors.value(docId, nullptr); } SciEdit *TabWidget::editorAt(int index) const { int docId = m_tabToDocumentId.value(index, -1); return m_editors.value(docId, nullptr); } int TabWidget::currentDocumentId() const { int index = currentIndex(); return m_tabToDocumentId.value(index, -1); } int TabWidget::documentIdAt(int index) const { return m_tabToDocumentId.value(index, -1); } void TabWidget::setCurrentTab(int index) { if (index >= 0 && index < count()) { setCurrentIndex(index); } } int TabWidget::findTabByDocumentId(int docId) const { return m_documentIdToTab.value(docId, -1); } void TabWidget::onCurrentChanged(int index) { SciEdit *editor = editorAt(index); emit currentEditorChanged(editor); } void TabWidget::onTabCloseRequested(int index) { closeTab(index); } void TabWidget::onDocumentModified(int docId, bool modified) { int tabIndex = findTabByDocumentId(docId); if (tabIndex >= 0) { updateTabTitle(tabIndex); } } void TabWidget::onDocumentTitleChanged(int docId, const QString &title) { int tabIndex = findTabByDocumentId(docId); if (tabIndex >= 0) { updateTabTitle(tabIndex); } } void TabWidget::onEditorTextChanged() { SciEdit *editor = qobject_cast(sender()); if (!editor) { return; } // 找到对应的文档ID int docId = -1; for (auto it = m_editors.begin(); it != m_editors.end(); ++it) { if (it.value() == editor) { docId = it.key(); break; } } if (docId != -1) { QByteArray content = editor->getText(editor->textLength()); m_documentManager->setDocumentContent(docId, QString::fromUtf8(content)); } } SciEdit *TabWidget::createEditor() { SciEdit *editor = new SciEdit(this); connectEditorSignals(editor); return editor; } void TabWidget::updateTabTitle(int tabIndex) { int docId = m_tabToDocumentId.value(tabIndex, -1); if (docId == -1) { return; } QString title = m_documentManager->getDocumentTitle(docId); if (m_documentManager->isDocumentModified(docId)) { title += " *"; } setTabText(tabIndex, title); } void TabWidget::connectEditorSignals(SciEdit *editor) { if (editor) { connect(editor, &SciEdit::textChanged, this, &TabWidget::onEditorTextChanged); } } void TabWidget::disconnectEditorSignals(SciEdit *editor) { if (editor) { disconnect(editor, &SciEdit::textChanged, this, &TabWidget::onEditorTextChanged); } }