358 lines
8.9 KiB
C++
358 lines
8.9 KiB
C++
#include "tabwidget.h"
|
|
#include "sciedit.h"
|
|
#include "documentmanager.h"
|
|
|
|
#include <QFileDialog>
|
|
#include <QMessageBox>
|
|
#include <QDebug>
|
|
|
|
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<int, int> newTabToDocumentId;
|
|
QHash<int, int> 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<SciEdit*>(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);
|
|
}
|
|
} |