#include "EditorPanel.h" #include "EditorTab.h" #include "CodeEditor.h" #include "SearchPanel.h" #include "FileSearchPanel.h" #include "FunctionListDialog.h" #include "DeadCodeDialog.h" #include "FunctionIndex.h" #include #include #include #include EditorPanel::EditorPanel(Settings *settings, QWidget *parent) : QWidget(parent) , m_settings(settings) { setupUi(); } // --------------------------------------------------------------------------- // Setup // --------------------------------------------------------------------------- void EditorPanel::setupUi() { m_layout = new QVBoxLayout(this); m_layout->setContentsMargins(0, 0, 0, 0); m_layout->setSpacing(0); m_tabWidget = new QTabWidget(this); m_tabWidget->setTabsClosable(true); m_tabWidget->setMovable(true); m_tabWidget->setDocumentMode(true); m_searchPanel = new SearchPanel(this); m_fileSearch = new FileSearchPanel(this); m_funcDialog = new FunctionListDialog(window()); m_deadCode = new DeadCodeDialog(window()); m_funcIndex = new FunctionIndex(this); m_layout->addWidget(m_tabWidget, 1); m_layout->addWidget(m_searchPanel, 0); m_layout->addWidget(m_fileSearch, 0); connect(m_tabWidget, &QTabWidget::tabCloseRequested, this, &EditorPanel::onTabCloseRequested); connect(m_tabWidget, &QTabWidget::currentChanged, this, &EditorPanel::onCurrentTabChanged); connect(m_fileSearch, &FileSearchPanel::fileLineRequested, this, &EditorPanel::goToLine); connect(m_funcDialog, &FunctionListDialog::fileLineRequested, this, &EditorPanel::goToLine); connect(m_deadCode, &DeadCodeDialog::fileLineRequested, this, &EditorPanel::goToLine); } // --------------------------------------------------------------------------- // Hilfsmethoden // --------------------------------------------------------------------------- EditorTab *EditorPanel::currentTab() const { return qobject_cast(m_tabWidget->currentWidget()); } int EditorPanel::findTabForFile(const QString &filePath) const { EditorTab *tab = m_openTabs.value(filePath, nullptr); return tab ? m_tabWidget->indexOf(tab) : -1; } // --------------------------------------------------------------------------- // Öffentliche Slots // --------------------------------------------------------------------------- void EditorPanel::openFile(const QString &filePath) { const int existing = findTabForFile(filePath); if (existing != -1) { m_tabWidget->setCurrentIndex(existing); return; } EditorTab *tab = new EditorTab(filePath, m_settings, m_tabWidget); const int index = m_tabWidget->addTab(tab, tab->fileName()); m_tabWidget->setCurrentIndex(index); m_tabWidget->setTabToolTip(index, filePath); m_openTabs.insert(filePath, tab); // FunctionIndex dem Editor mitgeben für Doppelklick-Navigation tab->editor()->setFunctionIndex(m_funcIndex); // Doppelklick auf Funktion → zur Definition springen connect(tab->editor(), &CodeEditor::navigateToRequested, this, &EditorPanel::goToLine); // Änderungsindikator im Tab-Titel (● = ungespeichert) connect(tab->editor()->document(), &QTextDocument::modificationChanged, this, [this, tab](bool modified) { const int idx = m_tabWidget->indexOf(tab); if (idx == -1) { return; } const QString name = QFileInfo(tab->filePath()).fileName(); m_tabWidget->setTabText(idx, modified ? "● " + name : name); }); // Tab-Titel nach "Speichern unter" aktualisieren (neuer Dateiname, kein Punkt) connect(tab->editor(), &CodeEditor::fileSaved, this, [this, tab](const QString &savedPath) { const int idx = m_tabWidget->indexOf(tab); if (idx != -1) { m_tabWidget->setTabText(idx, QFileInfo(savedPath).fileName()); m_tabWidget->setTabToolTip(idx, savedPath); } emit currentFileSaved(savedPath); // Index und Funktionsliste aktualisieren m_funcIndex->refresh(); if (m_funcDialog->isVisible()) { m_funcDialog->refresh(); } }); } void EditorPanel::saveCurrentFile() { if (EditorTab *tab = currentTab()) { tab->save(); } } void EditorPanel::saveCurrentFileAs() { if (EditorTab *tab = currentTab()) { tab->saveAs(); } } void EditorPanel::saveAllFiles() { for (int i = 0; i < m_tabWidget->count(); ++i) { EditorTab *tab = qobject_cast(m_tabWidget->widget(i)); if (tab && tab->isModified()) { tab->save(); } } } void EditorPanel::showSearchPanel() { m_fileSearch->hide(); m_searchPanel->activate(); } void EditorPanel::showFileSearchPanel() { m_searchPanel->hide(); m_fileSearch->activate(); } void EditorPanel::showFunctionList() { m_funcDialog->show(); m_funcDialog->raise(); m_funcDialog->activateWindow(); } void EditorPanel::showDeadCode() { m_deadCode->show(); m_deadCode->raise(); m_deadCode->activateWindow(); } void EditorPanel::setSearchRoot(const QString &path) { m_fileSearch->setSearchRoot(path); m_funcDialog->setProjectRoot(path); m_deadCode->setProjectRoot(path); m_funcIndex->setProjectRoot(path); } void EditorPanel::goToLine(const QString &filePath, int line) { // Datei öffnen falls noch nicht geöffnet openFile(filePath); EditorTab *tab = m_openTabs.value(filePath, nullptr); if (!tab) { return; } m_tabWidget->setCurrentWidget(tab); // Zur gewünschten Zeile springen CodeEditor *editor = tab->editor(); QTextBlock block = editor->document()->findBlockByLineNumber(line - 1); if (block.isValid()) { QTextCursor cursor(block); cursor.movePosition(QTextCursor::StartOfBlock); editor->setTextCursor(cursor); editor->centerCursor(); editor->setFocus(); } } QStringList EditorPanel::openFilePaths() const { QStringList paths; for (int i = 0; i < m_tabWidget->count(); ++i) { EditorTab *tab = qobject_cast(m_tabWidget->widget(i)); if (tab) { paths.append(tab->filePath()); } } return paths; } QString EditorPanel::activeFilePath() const { EditorTab *tab = currentTab(); return tab ? tab->filePath() : QString(); } void EditorPanel::restoreSession(const QStringList &files, const QString &activeFile) { for (const QString &path : files) { if (QFile::exists(path)) { openFile(path); } } // Aktiven Tab wiederherstellen if (!activeFile.isEmpty()) { const int idx = findTabForFile(activeFile); if (idx != -1) { m_tabWidget->setCurrentIndex(idx); } } } void EditorPanel::undo() { if (EditorTab *tab = currentTab()) { tab->editor()->undo(); } } void EditorPanel::redo() { if (EditorTab *tab = currentTab()) { tab->editor()->redo(); } } // --------------------------------------------------------------------------- // Private Slots // --------------------------------------------------------------------------- void EditorPanel::onTabCloseRequested(int index) { EditorTab *tab = qobject_cast(m_tabWidget->widget(index)); if (!tab) { return; } m_openTabs.remove(tab->filePath()); m_tabWidget->removeTab(index); tab->deleteLater(); m_searchPanel->setEditor(currentTab() ? currentTab()->editor() : nullptr); } void EditorPanel::onCurrentTabChanged(int /*index*/) { EditorTab *tab = currentTab(); m_searchPanel->setEditor(tab ? tab->editor() : nullptr); }