/************************************************************************** ** ** This file is part of Qt Creator ** ** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** Commercial Usage ** ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at http://qt.nokia.com/contact. ** **************************************************************************/ #include "multipledocumentscontroller.h" #include #include #include #include #include #include "designdocumentcontroller.h" #include "documentcloser.h" namespace QmlDesigner { static QString createTitle(const QString& fileName) { return QFileInfo(fileName).baseName(); } MultipleDocumentsController::MultipleDocumentsController(QWidget* parent): QObject(parent), m_tabWidget(new QTabWidget), m_undoAction(new QAction(tr("&Undo"), this)), m_redoAction(new QAction(tr("&Redo"), this)) { m_tabWidget->setDocumentMode(true); m_tabWidget->setTabsClosable(true); m_tabWidget->setMovable(true); connect(tabWidget(), SIGNAL(currentChanged(int)), this, SLOT(currentTabChanged(int))); connect(tabWidget(), SIGNAL(tabCloseRequested(int)), this, SLOT(tabCloseRequested(int))); } MultipleDocumentsController::~MultipleDocumentsController() { } QTabWidget *MultipleDocumentsController::tabWidget() const { return m_tabWidget.data(); } DesignDocumentController* MultipleDocumentsController::findActiveDocument(QWidget* documentWidget) { foreach (const QWeakPointer &controller, m_documentControllers) if (controller->documentWidget() == documentWidget) return controller.data(); return 0; } void MultipleDocumentsController::rewireDocumentActions(DesignDocumentController* oldActiveDocument, DesignDocumentController* newActiveDocument) { if (oldActiveDocument) { disconnect(undoAction(), SIGNAL(triggered()), oldActiveDocument, SLOT(undo())); disconnect(redoAction(), SIGNAL(triggered()), oldActiveDocument, SLOT(redo())); #ifdef ENABLE_TEXT_VIEW disconnect(m_showTextAction.data(), SIGNAL(triggered()), oldActiveDocument, SLOT(showText())); disconnect(m_showFormAction.data(), SIGNAL(triggered()), oldActiveDocument, SLOT(showForm())); #endif // ENABLE_TEXT_VIEW } if (newActiveDocument) { connect(undoAction(), SIGNAL(triggered()), newActiveDocument, SLOT(undo())); connect(redoAction(), SIGNAL(triggered()), newActiveDocument, SLOT(redo())); #ifdef ENABLE_TEXT_VIEW connect(m_showTextAction.data(), SIGNAL(triggered()), newActiveDocument, SLOT(showText())); connect(m_showFormAction.data(), SIGNAL(triggered()), newActiveDocument, SLOT(showForm())); if (m_showTextAction->isChecked()) newActiveDocument->showText(); else newActiveDocument->showForm(); #endif // ENABLE_TEXT_VIEW } } void MultipleDocumentsController::currentTabChanged(int newCurrentTab) { DesignDocumentController* oldActiveDocument = 0; if (!m_documentControllers.isEmpty()) { oldActiveDocument = m_documentControllers.first().data(); } if (newCurrentTab == -1) { emit activeDocumentChanged(0); if (oldActiveDocument && oldActiveDocument->previewVisible()) emit previewVisibilityChanged(false); if (oldActiveDocument && oldActiveDocument->previewWithDebugVisible()) emit previewWithDebugVisibilityChanged(false); if (oldActiveDocument) rewireDocumentActions(oldActiveDocument, 0); } else { DesignDocumentController* newActiveDocument = findActiveDocument(m_tabWidget->currentWidget()); m_undoAction->setEnabled(newActiveDocument->isUndoAvailable()); m_redoAction->setEnabled(newActiveDocument->isRedoAvailable()); rewireDocumentActions(oldActiveDocument, newActiveDocument); m_documentControllers.removeOne(newActiveDocument); m_documentControllers.prepend(newActiveDocument); emit activeDocumentChanged(newActiveDocument); if (oldActiveDocument && oldActiveDocument->previewVisible()) emit previewVisibilityChanged(newActiveDocument->previewVisible()); if (oldActiveDocument && oldActiveDocument->previewWithDebugVisible()) emit previewWithDebugVisibilityChanged(newActiveDocument->previewWithDebugVisible()); } } void MultipleDocumentsController::tabCloseRequested(int tabIndex) { DesignDocumentController* controller = findActiveDocument(m_tabWidget->widget(tabIndex)); if (controller) DocumentCloser::close(controller); } void MultipleDocumentsController::documentDisplayNameChanged(const QString &/*fileName*/) { DesignDocumentController *documentController = qobject_cast(sender()); Q_ASSERT(documentController); documentDirtyStateChanged(documentController->isDirty()); } void MultipleDocumentsController::documentDirtyStateChanged(bool newState) { DesignDocumentController *documentController = qobject_cast(sender()); Q_ASSERT(documentController); int tabIdx = m_tabWidget->indexOf(documentController->documentWidget()); if (newState) m_tabWidget->setTabText(tabIdx, tr("* %1").arg(createTitle(documentController->displayName()))); else m_tabWidget->setTabText(tabIdx, createTitle(documentController->displayName())); } void MultipleDocumentsController::documentUndoAvailable(bool isAvailable) { DesignDocumentController *documentController = qobject_cast(sender()); Q_ASSERT(documentController); if (m_documentControllers.first().data() == documentController) m_undoAction->setEnabled(isAvailable); } void MultipleDocumentsController::documentRedoAvailable(bool isAvailable) { DesignDocumentController *documentController = qobject_cast(sender()); Q_ASSERT(documentController); if (m_documentControllers.first().data() == documentController) m_redoAction->setEnabled(isAvailable); } void MultipleDocumentsController::documentPreviewVisibilityChanged(bool visible) { DesignDocumentController *documentController = qobject_cast(sender()); Q_ASSERT(documentController); if (m_documentControllers.first().data() == documentController) emit previewVisibilityChanged(visible); } void MultipleDocumentsController::documentPreviewWithDebugVisibilityChanged(bool visible) { DesignDocumentController *documentController = qobject_cast(sender()); Q_ASSERT(documentController); if (m_documentControllers.first().data() == documentController) emit previewWithDebugVisibilityChanged(visible); } void MultipleDocumentsController::open(DesignDocumentController* documentController) { m_documentControllers.append(documentController); int newTabIndex = m_tabWidget->addTab(documentController->documentWidget(), createTitle(documentController->displayName())); m_tabWidget->setCurrentIndex(newTabIndex); connect(documentController, SIGNAL(displayNameChanged(QString)), this, SLOT(documentDisplayNameChanged(QString))); connect(documentController, SIGNAL(dirtyStateChanged(bool)), this, SLOT(documentDirtyStateChanged(bool))); connect(documentController, SIGNAL(undoAvailable(bool)), this, SLOT(documentUndoAvailable(bool))); connect(documentController, SIGNAL(redoAvailable(bool)), this, SLOT(documentRedoAvailable(bool))); connect(documentController, SIGNAL(previewVisibilityChanged(bool)), this, SLOT(documentPreviewVisibilityChanged(bool))); connect(documentController, SIGNAL(previewWithDebugVisibilityChanged(bool)), this, SLOT(documentPreviewWithDebugVisibilityChanged(bool))); connect(documentController, SIGNAL(designDocumentClosed()), this, SLOT(designDocumentClosed())); connect(documentController, SIGNAL(qmlErrorsChanged(QList)), this, SLOT(designDocumentError(QList))); emit documentCountChanged(m_documentControllers.size()); } void MultipleDocumentsController::designDocumentClosed() { DesignDocumentController *documentController = qobject_cast(sender()); Q_ASSERT(documentController); rewireDocumentActions(documentController, 0); m_tabWidget->removeTab(m_tabWidget->indexOf(documentController->documentWidget())); m_documentControllers.removeOne(documentController); emit documentClosed(documentController); emit documentCountChanged(m_documentControllers.size()); } void MultipleDocumentsController::designDocumentError(const QList &error) { DesignDocumentController *documentController = qobject_cast(sender()); Q_ASSERT(documentController); if (error.isEmpty()) return; QMessageBox msgBox(documentController->documentWidget()); msgBox.setWindowFlags(Qt::Sheet | Qt::MSWindowsFixedSizeDialogHint); msgBox.setWindowTitle("Invalid qml"); msgBox.setText(error.first().toString()); msgBox.setIcon(QMessageBox::Warning); msgBox.exec(); } void MultipleDocumentsController::doSave() { if (!m_documentControllers.isEmpty()) m_documentControllers.first()->save(dynamic_cast(parent())); } void MultipleDocumentsController::doSaveAs() { QWidget* parentWindow = dynamic_cast(parent()); if (!m_documentControllers.isEmpty()) m_documentControllers.first()->saveAs(parentWindow); } void MultipleDocumentsController::doPreview(bool visible) { if (m_documentControllers.isEmpty()) return; m_documentControllers.first()->togglePreview(visible); } void MultipleDocumentsController::doPreviewWithDebug(bool visible) { if (m_documentControllers.isEmpty()) return; m_documentControllers.first()->toggleWithDebugPreview(visible); } void MultipleDocumentsController::doDelete() { m_documentControllers.first()->deleteSelected(); } void MultipleDocumentsController::doCopy() { m_documentControllers.first()->copySelected(); } void MultipleDocumentsController::doCut() { m_documentControllers.first()->cutSelected(); } void MultipleDocumentsController::doPaste() { m_documentControllers.first()->paste(); } void MultipleDocumentsController::closeAll(bool quitWhenAllEditorsClosed) { DocumentCloser::close(m_documentControllers, quitWhenAllEditorsClosed); } QAction* MultipleDocumentsController::undoAction() { return m_undoAction.data(); } QAction* MultipleDocumentsController::redoAction() { return m_redoAction.data(); } #ifdef ENABLE_TEXT_VIEW QAction* MultipleDocumentsController::showFormAction(QMenu* parent) { if (!m_showFormAction) { m_showFormAction = new QAction(tr("&Form"), parent); m_showFormAction->setShortcut(QKeySequence("Ctrl+Shift+F")); m_showFormAction->setCheckable(true); } return m_showFormAction.data(); } #endif // ENABLE_TEXT_VIEW #ifdef ENABLE_TEXT_VIEW QAction* MultipleDocumentsController::showTextAction(QMenu* parent) { if (!m_showTextAction) { m_showTextAction = new QAction(tr("&Text"), parent); m_showTextAction->setShortcut(QKeySequence("Ctrl+Shift+T")); m_showTextAction->setCheckable(true); } return m_showTextAction.data(); } #endif // ENABLE_TEXT_VIEW } // namespace QmlDesigner