diff --git a/src/plugins/designer/README.txt b/src/plugins/designer/README.txt index 7665e29c98e28668a8cf33d814907c396acc8d18..44ef03b8754184381d04610c6322f58b9d1dd164 100644 --- a/src/plugins/designer/README.txt +++ b/src/plugins/designer/README.txt @@ -4,6 +4,15 @@ They are dependent on the CPP editor plugin. Including cpp.pri in designer.pro enables them and defines CPP_ENABLED. +Editor +------ + +The editor shows read-only XML text in a PlainTextEditor and Designer +in Design mode. The switch is done in the currentEditorChanged signal. +To make the text editor work, IEditor needs to aggregate a PlainTextEditable +and delegate some functionality to it, while the isModified()-handling +needs to be done by Designer itself. + Resource handling: ------------------ diff --git a/src/plugins/designer/designer.pro b/src/plugins/designer/designer.pro index 5bbc140976886093fe4b1b7694707a45491df697..923c9a9808145061a896b5a1c9bd35b895f547ca 100644 --- a/src/plugins/designer/designer.pro +++ b/src/plugins/designer/designer.pro @@ -64,4 +64,4 @@ SOURCES += formeditorplugin.cpp \ RESOURCES += designer.qrc -OTHER_FILES += Designer.pluginspec Designer.mimetypes.xml +OTHER_FILES += Designer.pluginspec Designer.mimetypes.xml README.txt diff --git a/src/plugins/designer/designerxmleditor.cpp b/src/plugins/designer/designerxmleditor.cpp index 0b063d0689e453d14b525722c1f67ba2aa64b531..0d58c36e5bc2c15b522089e61b352d717b9fdcfc 100644 --- a/src/plugins/designer/designerxmleditor.cpp +++ b/src/plugins/designer/designerxmleditor.cpp @@ -28,208 +28,26 @@ **************************************************************************/ #include "designerxmleditor.h" +#include "formwindoweditor.h" #include "designerconstants.h" -#include "resourcehandler.h" -#include "qt_private/formwindowbase_p.h" - #include <coreplugin/editormanager/editormanager.h> #include <coreplugin/icore.h> #include <coreplugin/modemanager.h> #include <coreplugin/imode.h> #include <coreplugin/coreconstants.h> -#include <coreplugin/uniqueidmanager.h> -#include <texteditor/basetextdocument.h> - -#include <utils/qtcassert.h> #include <QtDesigner/QDesignerFormWindowInterface> #include <QtCore/QDebug> -#include <QtCore/QFileInfo> -#include <QtCore/QFile> namespace Designer { - -DesignerXmlEditorEditable::DesignerXmlEditorEditable(Internal::DesignerXmlEditor *editor, - QDesignerFormWindowInterface *form, - QObject *parent) : - Core::IEditor(parent), - m_textEditable(editor), - m_file(form) -{ - Core::UniqueIDManager *uidm = Core::UniqueIDManager::instance(); - m_context << uidm->uniqueIdentifier(QLatin1String(Designer::Constants::K_DESIGNER_XML_EDITOR_ID)); - m_context << uidm->uniqueIdentifier(QLatin1String(Designer::Constants::C_DESIGNER_XML_EDITOR)); - connect(form, SIGNAL(changed()), this, SIGNAL(changed())); - // Revert to saved/load externally modified files - connect(&m_file, SIGNAL(reload(QString)), this, SLOT(slotOpen(QString))); -} - -bool DesignerXmlEditorEditable::createNew(const QString &contents) -{ - if (Designer::Constants::Internal::debug) - qDebug() << "DesignerXmlEditorEditable::createNew" << contents.size(); - - syncXmlEditor(QString()); - - QDesignerFormWindowInterface *form = m_file.formWindow(); - QTC_ASSERT(form, return false); - - if (contents.isEmpty()) - return false; - - form->setContents(contents); - if (form->mainContainer() == 0) - return false; - - syncXmlEditor(contents); - m_file.setFileName(QString()); - return true; -} - -void DesignerXmlEditorEditable::slotOpen(const QString &fileName) -{ - open(fileName); -} - -bool DesignerXmlEditorEditable::open(const QString &fileName) -{ - if (Designer::Constants::Internal::debug) - qDebug() << "DesignerXmlEditorEditable::open" << fileName; - - QDesignerFormWindowInterface *form = m_file.formWindow(); - QTC_ASSERT(form, return false); - - if (fileName.isEmpty()) { - setDisplayName(tr("untitled")); - return true; - } - - const QFileInfo fi(fileName); - const QString absfileName = fi.absoluteFilePath(); - - QFile file(absfileName); - if (!file.open(QIODevice::ReadOnly|QIODevice::Text)) - return false; - - form->setFileName(absfileName); - - const QString contents = QString::fromUtf8(file.readAll()); - form->setContents(contents); - file.close(); - if (!form->mainContainer()) - return false; - form->setDirty(false); - syncXmlEditor(contents); - - setDisplayName(fi.fileName()); - m_file.setFileName(absfileName); - - if (Internal::ResourceHandler *rh = qFindChild<Designer::Internal::ResourceHandler*>(form)) - rh->updateResources(); - - emit changed(); - - return true; -} - -void DesignerXmlEditorEditable::syncXmlEditor() -{ - if (Designer::Constants::Internal::debug) - qDebug() << "DesignerXmlEditorEditable::syncXmlEditor" << m_file.fileName(); - syncXmlEditor(contents()); -} - -void DesignerXmlEditorEditable::syncXmlEditor(const QString &contents) -{ - m_textEditable.editor()->setPlainText(contents); - m_textEditable.editor()->setReadOnly(true); -} - -Core::IFile *DesignerXmlEditorEditable::file() -{ - return &m_file; -} - -QString DesignerXmlEditorEditable::id() const -{ - return QLatin1String(Designer::Constants::K_DESIGNER_XML_EDITOR_ID); -} - -QString DesignerXmlEditorEditable::displayName() const -{ - return m_textEditable.displayName(); -} - -void DesignerXmlEditorEditable::setDisplayName(const QString &title) -{ - m_textEditable.setDisplayName(title); -} - -bool DesignerXmlEditorEditable::duplicateSupported() const -{ - return false; -} - -Core::IEditor *DesignerXmlEditorEditable::duplicate(QWidget *) -{ - return 0; -} - -QByteArray DesignerXmlEditorEditable::saveState() const -{ - return m_textEditable.saveState(); -} - -bool DesignerXmlEditorEditable::restoreState(const QByteArray &state) -{ - return m_textEditable.restoreState(state); -} - -QList<int> DesignerXmlEditorEditable::context() const -{ - return m_context; -} - -QWidget *DesignerXmlEditorEditable::widget() -{ - return m_textEditable.widget(); -} - -bool DesignerXmlEditorEditable::isTemporary() const -{ - return false; -} - -QWidget *DesignerXmlEditorEditable::toolBar() -{ - return 0; -} - -QString DesignerXmlEditorEditable::contents() const -{ - const qdesigner_internal::FormWindowBase *fw = qobject_cast<const qdesigner_internal::FormWindowBase *>(m_file.formWindow()); - QTC_ASSERT(fw, return QString()); - return fw->fileContents(); // No warnings about spacers here -} - -TextEditor::BaseTextDocument *DesignerXmlEditorEditable::textDocument() -{ - return qobject_cast<TextEditor::BaseTextDocument*>(m_textEditable.file()); -} - -TextEditor::PlainTextEditorEditable *DesignerXmlEditorEditable::textEditable() -{ - return &m_textEditable; -} - namespace Internal { DesignerXmlEditor::DesignerXmlEditor(QDesignerFormWindowInterface *form, QWidget *parent) : TextEditor::PlainTextEditor(parent), - m_editable(new DesignerXmlEditorEditable(this, form)) + m_designerEditor(new FormWindowEditor(this, form)) { setReadOnly(true); connect(Core::EditorManager::instance(), SIGNAL(currentEditorChanged(Core::IEditor*)), @@ -240,12 +58,12 @@ TextEditor::BaseTextEditorEditable *DesignerXmlEditor::createEditableInterface() { if (Designer::Constants::Internal::debug) qDebug() << "DesignerXmlEditor::createEditableInterface()"; - return m_editable->textEditable(); + return m_designerEditor->textEditable(); } void DesignerXmlEditor::updateEditorInfoBar(Core::IEditor *editor) { - if (editor == m_editable) { + if (editor == m_designerEditor) { Core::EditorManager::instance()->showEditorInfoBar(Constants::INFO_READ_ONLY, tr("This file can only be edited in Design Mode."), "Open Designer", this, SLOT(designerModeClicked())); @@ -259,9 +77,9 @@ void DesignerXmlEditor::designerModeClicked() Core::ICore::instance()->modeManager()->activateMode(QLatin1String(Core::Constants::MODE_DESIGN)); } -DesignerXmlEditorEditable *DesignerXmlEditor::designerEditable() const +FormWindowEditor *DesignerXmlEditor::designerEditor() const { - return m_editable; + return m_designerEditor; } } diff --git a/src/plugins/designer/designerxmleditor.h b/src/plugins/designer/designerxmleditor.h index d5f32ceedc9a2725f5c2c67669a74c2dc68e02f6..dcedcb808a6665a1979c795a2f13072be917c5e7 100644 --- a/src/plugins/designer/designerxmleditor.h +++ b/src/plugins/designer/designerxmleditor.h @@ -30,88 +30,24 @@ #ifndef DESIGNERXMLEDITOR_H #define DESIGNERXMLEDITOR_H -#include "designer_export.h" -#include "formwindowfile.h" - #include <texteditor/plaintexteditor.h> -namespace Core { - class IMode; -} - -namespace TextEditor { - class BaseTextDocument; -} +QT_BEGIN_NAMESPACE +class QDesignerFormWindowInterface; +QT_END_NAMESPACE namespace Designer { +class FormWindowEditor; namespace Internal { -class DesignerXmlEditor; -} - -// The actual Core::IEditor belonging to Qt Designer. It internally embeds -// a TextEditor::PlainTextEditorEditable which is used to make the -// Read-only edit mode XML text editor work and delegates some functionality -// to it. However, the isDirty() handling is delegated to the FormWindowFile, -// which is the Core::IFile used for it. -class DESIGNER_EXPORT DesignerXmlEditorEditable : public Core::IEditor -{ - Q_OBJECT -public: - explicit DesignerXmlEditorEditable(Internal::DesignerXmlEditor *editor, - QDesignerFormWindowInterface *form, - QObject *parent = 0); - - // IEditor - virtual bool createNew(const QString &contents = QString()); - virtual bool open(const QString &fileName = QString()); - virtual Core::IFile *file(); - virtual QString id() const; - virtual QString displayName() const; - virtual void setDisplayName(const QString &title); - - virtual bool duplicateSupported() const; - virtual IEditor *duplicate(QWidget *parent); - - virtual QByteArray saveState() const; - virtual bool restoreState(const QByteArray &state); - - virtual bool isTemporary() const; - - virtual QWidget *toolBar(); - - // IContext - virtual QList<int> context() const; - virtual QWidget *widget(); - - // For uic code model support - QString contents() const; - - TextEditor::BaseTextDocument *textDocument(); - TextEditor::PlainTextEditorEditable *textEditable(); - -public slots: - void syncXmlEditor(); - -private slots: - void slotOpen(const QString &fileName); - -private: - void syncXmlEditor(const QString &contents); - - TextEditor::PlainTextEditorEditable m_textEditable; - Internal::FormWindowFile m_file; - QList<int> m_context; -}; /* A stub-like, read-only text editor which displays UI files as text. Could be used as a * read/write editor too, but due to lack of XML editor, highlighting and other such * functionality, editing is disabled. * Provides an informational title bar containing a button triggering a * switch to design mode. - * Internally manages DesignerXmlEditorEditable and uses the plain text + * Internally manages a FormWindowEditor and uses the plain text * editable embedded in it. */ -namespace Internal { class DesignerXmlEditor : public TextEditor::PlainTextEditor { @@ -120,7 +56,7 @@ public: explicit DesignerXmlEditor(QDesignerFormWindowInterface *form, QWidget *parent = 0); - DesignerXmlEditorEditable *designerEditable() const; + FormWindowEditor *designerEditor() const; private slots: void designerModeClicked(); @@ -130,7 +66,7 @@ protected: virtual TextEditor::BaseTextEditorEditable *createEditableInterface(); private: - DesignerXmlEditorEditable *m_editable; + FormWindowEditor *m_designerEditor; }; } // Internal diff --git a/src/plugins/designer/editordata.h b/src/plugins/designer/editordata.h index 26c37d9d2fd0ccc424ab969769f7b9143cfbd5e0..7bc20bd72c9342b4dbb3a708eccd9faf5cb37f1a 100644 --- a/src/plugins/designer/editordata.h +++ b/src/plugins/designer/editordata.h @@ -30,19 +30,22 @@ #ifndef EDITORDATA_H #define EDITORDATA_H +namespace SharedTools { + class WidgetHost; +} + namespace Designer { class FormWindowEditor; - class DesignerXmlEditorEditable; namespace Internal { -// Associates XML and its form editor +// Associates the XML editor implementing the IEditor and its form widget host struct EditorData { - EditorData() : xmlEditor(0), formEditor(0) {} - operator bool() const { return xmlEditor != 0; } + EditorData() : formWindowEditor(0), widgetHost(0) {} + operator bool() const { return formWindowEditor != 0; } - DesignerXmlEditorEditable *xmlEditor; - Designer::FormWindowEditor *formEditor; + FormWindowEditor *formWindowEditor; + SharedTools::WidgetHost *widgetHost; }; } // namespace Internal diff --git a/src/plugins/designer/editorwidget.cpp b/src/plugins/designer/editorwidget.cpp index 3e6453f45a373788431436999b27687ca69a422f..cd6796e1e676ba50b304a90a123ee855bb73f099 100644 --- a/src/plugins/designer/editorwidget.cpp +++ b/src/plugins/designer/editorwidget.cpp @@ -107,7 +107,7 @@ bool EditorWidget::setVisibleEditor(Core::IEditor *xmlEditor) return m_stack->setVisibleEditor(xmlEditor); } -Designer::FormWindowEditor *EditorWidget::formWindowEditorForXmlEditor(const Core::IEditor *xmlEditor) const +SharedTools::WidgetHost *EditorWidget::formWindowEditorForXmlEditor(const Core::IEditor *xmlEditor) const { return m_stack->formWindowEditorForXmlEditor(xmlEditor); } @@ -117,7 +117,7 @@ EditorData EditorWidget::activeEditor() const return m_stack->activeEditor(); } -Designer::FormWindowEditor *EditorWidget::formWindowEditorForFormWindow(const QDesignerFormWindowInterface *fw) const +SharedTools::WidgetHost *EditorWidget::formWindowEditorForFormWindow(const QDesignerFormWindowInterface *fw) const { return m_stack->formWindowEditorForFormWindow(fw); } diff --git a/src/plugins/designer/editorwidget.h b/src/plugins/designer/editorwidget.h index 4294f51d2d6047ea20c545791a9abdf24d6b7985..5f253e924303a38936552caf777449580554e25d 100644 --- a/src/plugins/designer/editorwidget.h +++ b/src/plugins/designer/editorwidget.h @@ -38,12 +38,14 @@ QT_BEGIN_NAMESPACE class QDesignerFormWindowInterface; QT_END_NAMESPACE +namespace SharedTools { + class WidgetHost; +} namespace Core { class IEditor; } namespace Designer { class FormWindowEditor; -class DesignerXmlEditorEditable; namespace Internal { struct EditorData; @@ -64,8 +66,8 @@ public: void add(const EditorData &d); bool removeFormWindowEditor(Core::IEditor *xmlEditor); bool setVisibleEditor(Core::IEditor *xmlEditor); - Designer::FormWindowEditor *formWindowEditorForXmlEditor(const Core::IEditor *xmlEditor) const; - Designer::FormWindowEditor *formWindowEditorForFormWindow(const QDesignerFormWindowInterface *fw) const; + SharedTools::WidgetHost *formWindowEditorForXmlEditor(const Core::IEditor *xmlEditor) const; + SharedTools::WidgetHost *formWindowEditorForFormWindow(const QDesignerFormWindowInterface *fw) const; EditorData activeEditor() const; diff --git a/src/plugins/designer/formeditorfactory.cpp b/src/plugins/designer/formeditorfactory.cpp index 5891741698f9a92d323203390ecf92912610619f..042fd5c77bd83ff64597e4b5bcab4acdeea9f6bf 100644 --- a/src/plugins/designer/formeditorfactory.cpp +++ b/src/plugins/designer/formeditorfactory.cpp @@ -74,7 +74,7 @@ Core::IFile *FormEditorFactory::open(const QString &fileName) Core::IEditor *FormEditorFactory::createEditor(QWidget *parent) { const EditorData data = FormEditorW::instance()->createEditor(parent); - return data.xmlEditor; + return data.formWindowEditor; } QStringList FormEditorFactory::mimeTypes() const diff --git a/src/plugins/designer/formeditorstack.cpp b/src/plugins/designer/formeditorstack.cpp index 06d15b4ba39e5012dde8bc92d77918c30f8ee454..a21a81595ccc4b463342133c302aff834dd43624 100644 --- a/src/plugins/designer/formeditorstack.cpp +++ b/src/plugins/designer/formeditorstack.cpp @@ -28,11 +28,12 @@ **************************************************************************/ #include "formeditorstack.h" -#include "designerxmleditor.h" #include "formwindoweditor.h" #include "formeditorw.h" #include "designerconstants.h" +#include <widgethost.h> + #include <coreplugin/coreconstants.h> #include <coreplugin/modemanager.h> #include <coreplugin/imode.h> @@ -42,8 +43,11 @@ #include <QDesignerFormWindowInterface> #include <QDesignerFormWindowManagerInterface> #include <QDesignerFormEditorInterface> +#include <QDesignerPropertyEditorInterface> #include <QtCore/QDebug> +#include <QtCore/QVariant> +#include <QtCore/QRect> namespace Designer { namespace Internal { @@ -58,7 +62,7 @@ FormEditorStack::FormEditorStack(QWidget *parent) : void FormEditorStack::add(const EditorData &data) { if (m_designerCore == 0) { // Initialize first time here - m_designerCore = data.formEditor->formWindow()->core(); + m_designerCore = data.widgetHost->formWindow()->core(); connect(m_designerCore->formWindowManager(), SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface*)), this, SLOT(updateFormWindowSelectionHandles())); connect(Core::ModeManager::instance(), SIGNAL(currentModeAboutToChange(Core::IMode*)), @@ -66,20 +70,23 @@ void FormEditorStack::add(const EditorData &data) } if (Designer::Constants::Internal::debug) - qDebug() << "FormEditorStack::add" << data.xmlEditor << data.formEditor; + qDebug() << "FormEditorStack::add" << data.formWindowEditor << data.widgetHost; m_formEditors.append(data); - addWidget(data.formEditor); + addWidget(data.widgetHost); + + connect(data.widgetHost, SIGNAL(formWindowSizeChanged(int,int)), + this, SLOT(formSizeChanged(int,int))); if (Designer::Constants::Internal::debug) - qDebug() << "FormEditorStack::add" << data.formEditor; + qDebug() << "FormEditorStack::add" << data.widgetHost; } int FormEditorStack::indexOf(const QDesignerFormWindowInterface *fw) const { const int count = m_formEditors.size(); for(int i = 0; i < count; ++i) - if (m_formEditors[i].formEditor->formWindow() == fw) + if (m_formEditors[i].widgetHost->formWindow() == fw) return i; return -1; } @@ -88,7 +95,7 @@ int FormEditorStack::indexOf(const Core::IEditor *xmlEditor) const { const int count = m_formEditors.size(); for(int i = 0; i < count; ++i) - if (m_formEditors[i].xmlEditor == xmlEditor) + if (m_formEditors[i].formWindowEditor == xmlEditor) return i; return -1; } @@ -104,10 +111,10 @@ EditorData FormEditorStack::activeEditor() const return EditorData(); } -Designer::FormWindowEditor *FormEditorStack::formWindowEditorForFormWindow(const QDesignerFormWindowInterface *fw) const +SharedTools::WidgetHost *FormEditorStack::formWindowEditorForFormWindow(const QDesignerFormWindowInterface *fw) const { const int i = indexOf(fw); - return i != -1 ? m_formEditors[i].formEditor : static_cast<Designer::FormWindowEditor *>(0); + return i != -1 ? m_formEditors[i].widgetHost : static_cast<SharedTools::WidgetHost *>(0); } bool FormEditorStack::removeFormWindowEditor(Core::IEditor *xmlEditor) @@ -117,8 +124,8 @@ bool FormEditorStack::removeFormWindowEditor(Core::IEditor *xmlEditor) const int i = indexOf(xmlEditor); if (i == -1) // Fail silently as this is invoked for all editors. return false; - removeWidget(m_formEditors[i].formEditor->widget()); - delete m_formEditors[i].formEditor; + removeWidget(m_formEditors[i].widgetHost->widget()); + delete m_formEditors[i].widgetHost; m_formEditors.removeAt(i); return true; } @@ -142,15 +149,27 @@ void FormEditorStack::updateFormWindowSelectionHandles() qDebug() << "updateFormWindowSelectionHandles"; QDesignerFormWindowInterface *activeFormWindow = m_designerCore->formWindowManager()->activeFormWindow(); foreach(const EditorData &fdm, m_formEditors) { - const bool active = activeFormWindow == fdm.formEditor->formWindow(); - fdm.formEditor->updateFormWindowSelectionHandles(active); + const bool active = activeFormWindow == fdm.widgetHost->formWindow(); + fdm.widgetHost->updateFormWindowSelectionHandles(active); + } +} + +void FormEditorStack::formSizeChanged(int w, int h) +{ + // Handle main container resize. + if (Designer::Constants::Internal::debug) + qDebug() << Q_FUNC_INFO << w << h; + if (const SharedTools::WidgetHost *wh = qobject_cast<const SharedTools::WidgetHost *>(sender())) { + wh->formWindow()->setDirty(true); + static const QString geometry = QLatin1String("geometry"); + m_designerCore->propertyEditor()->setPropertyValue(geometry, QRect(0,0,w,h) ); } } -Designer::FormWindowEditor *FormEditorStack::formWindowEditorForXmlEditor(const Core::IEditor *xmlEditor) const +SharedTools::WidgetHost *FormEditorStack::formWindowEditorForXmlEditor(const Core::IEditor *xmlEditor) const { const int i = indexOf(xmlEditor); - return i != -1 ? m_formEditors.at(i).formEditor : static_cast<Designer::FormWindowEditor *>(0); + return i != -1 ? m_formEditors.at(i).widgetHost : static_cast<SharedTools::WidgetHost *>(0); } void FormEditorStack::modeAboutToChange(Core::IMode *m) @@ -161,7 +180,7 @@ void FormEditorStack::modeAboutToChange(Core::IMode *m) // Sync the editor when leaving design mode if (m && m->id() == QLatin1String(Core::Constants::MODE_DESIGN)) foreach(const EditorData &data, m_formEditors) - data.xmlEditor->syncXmlEditor(); + data.formWindowEditor->syncXmlEditor(); } } // Internal diff --git a/src/plugins/designer/formeditorstack.h b/src/plugins/designer/formeditorstack.h index c3fce4e8d8457b5dda95ca5151955295444e94d7..130625aa724f5839e014bae477835ab6202dc57d 100644 --- a/src/plugins/designer/formeditorstack.h +++ b/src/plugins/designer/formeditorstack.h @@ -47,9 +47,6 @@ namespace Core { } namespace Designer { -class FormWindowEditor; -class DesignerXmlEditorEditable; - namespace Internal { /* FormEditorStack: Maintains a stack of Qt Designer form windows embedded @@ -68,14 +65,15 @@ public: bool removeFormWindowEditor(Core::IEditor *xmlEditor); bool setVisibleEditor(Core::IEditor *xmlEditor); - Designer::FormWindowEditor *formWindowEditorForXmlEditor(const Core::IEditor *xmlEditor) const; - Designer::FormWindowEditor *formWindowEditorForFormWindow(const QDesignerFormWindowInterface *fw) const; + SharedTools::WidgetHost *formWindowEditorForXmlEditor(const Core::IEditor *xmlEditor) const; + SharedTools::WidgetHost *formWindowEditorForFormWindow(const QDesignerFormWindowInterface *fw) const; EditorData activeEditor() const; private slots: void updateFormWindowSelectionHandles(); void modeAboutToChange(Core::IMode *); + void formSizeChanged(int w, int h); private: inline int indexOf(const QDesignerFormWindowInterface *) const; diff --git a/src/plugins/designer/formeditorw.cpp b/src/plugins/designer/formeditorw.cpp index d8708305e0653f28f00ad24d2256cbe9081bf315..4b377eaad4634307a4e63027d8c1afae66dadf5c 100644 --- a/src/plugins/designer/formeditorw.cpp +++ b/src/plugins/designer/formeditorw.cpp @@ -40,6 +40,7 @@ #include "designercontext.h" #include "editorwidget.h" #include "resourcehandler.h" +#include <widgethost.h> #include <coreplugin/modemanager.h> #include <coreplugin/designmode.h> @@ -666,13 +667,13 @@ EditorData FormEditorW::createEditor(QWidget *parent) ResourceHandler *resourceHandler = new ResourceHandler(form); form->setDesignerGrid(qdesigner_internal::FormWindowBase::defaultDesignerGrid()); qdesigner_internal::FormWindowBase::setupDefaultAction(form); - data.formEditor = new FormWindowEditor(form); + data.widgetHost = new SharedTools::WidgetHost( /* parent */ 0, form); DesignerXmlEditor *xmlEditor = new DesignerXmlEditor(form, parent); TextEditor::TextEditorSettings::instance()->initializeEditor(xmlEditor); - data.xmlEditor = xmlEditor->designerEditable(); - connect(data.formEditor, SIGNAL(formWindowSizeChanged(int,int)), + data.formWindowEditor = xmlEditor->designerEditor(); + connect(data.widgetHost, SIGNAL(formWindowSizeChanged(int,int)), xmlEditor, SIGNAL(changed())); - connect(data.xmlEditor->file(), SIGNAL(changed()), + connect(data.formWindowEditor->file(), SIGNAL(changed()), resourceHandler, SLOT(updateResources())); m_editorWidget->add(data); return data; @@ -695,10 +696,10 @@ void FormEditorW::currentEditorChanged(Core::IEditor *editor) qDebug() << Q_FUNC_INFO << editor << " of " << m_fwm->formWindowCount(); if (editor && editor->id() == QLatin1String(Constants::K_DESIGNER_XML_EDITOR_ID)) { - DesignerXmlEditorEditable *xmlEditor = qobject_cast<DesignerXmlEditorEditable *>(editor); + FormWindowEditor *xmlEditor = qobject_cast<FormWindowEditor *>(editor); QTC_ASSERT(xmlEditor, return); ensureInitStage(FullyInitialized); - FormWindowEditor *fw = m_editorWidget->formWindowEditorForXmlEditor(xmlEditor); + SharedTools::WidgetHost *fw = m_editorWidget->formWindowEditorForXmlEditor(xmlEditor); QTC_ASSERT(fw, return) m_editorWidget->setVisibleEditor(xmlEditor); m_fwm->setActiveFormWindow(fw->formWindow()); diff --git a/src/plugins/designer/formeditorw.h b/src/plugins/designer/formeditorw.h index 76f4b0ebd43ab88d1d846aea638dcadf1f15235f..63ab2cf019833ae3c9f4b744c68f25f44b33db39 100644 --- a/src/plugins/designer/formeditorw.h +++ b/src/plugins/designer/formeditorw.h @@ -64,8 +64,6 @@ class DesignMode; } namespace Designer { -class FormWindowEditor; - namespace Internal { struct EditorData; diff --git a/src/plugins/designer/formwindoweditor.cpp b/src/plugins/designer/formwindoweditor.cpp index 75a95329b5cc2d9940acccf3c87e3dea41a8e96f..63ae50127e5e08ed43c30bc3b53a3dfac0aa4fb3 100644 --- a/src/plugins/designer/formwindoweditor.cpp +++ b/src/plugins/designer/formwindoweditor.cpp @@ -28,37 +28,226 @@ **************************************************************************/ #include "formwindoweditor.h" +#include "formwindowfile.h" #include "designerconstants.h" -#include "formeditorw.h" +#include "resourcehandler.h" +#include "qt_private/formwindowbase_p.h" +#include "designerxmleditor.h" +#include <widgethost.h> + +#include <coreplugin/editormanager/editormanager.h> +#include <coreplugin/icore.h> +#include <coreplugin/modemanager.h> +#include <coreplugin/imode.h> +#include <coreplugin/coreconstants.h> +#include <coreplugin/uniqueidmanager.h> +#include <texteditor/basetextdocument.h> +#include <texteditor/plaintexteditor.h> -#include <coreplugin/ifile.h> #include <utils/qtcassert.h> #include <QtDesigner/QDesignerFormWindowInterface> -#include <QtDesigner/QDesignerFormEditorInterface> -#include <QtDesigner/QDesignerFormWindowManagerInterface> -#include <QtDesigner/QDesignerPropertyEditorInterface> -#include "qt_private/formwindowbase_p.h" #include <QtCore/QDebug> +#include <QtCore/QFileInfo> +#include <QtCore/QFile> + +namespace Designer { + +struct FormWindowEditorPrivate { + explicit FormWindowEditorPrivate(Internal::DesignerXmlEditor *editor, + QDesignerFormWindowInterface *form); + + TextEditor::PlainTextEditorEditable m_textEditable; + Internal::FormWindowFile m_file; + QList<int> m_context; +}; + +FormWindowEditorPrivate::FormWindowEditorPrivate(Internal::DesignerXmlEditor *editor, + QDesignerFormWindowInterface *form) : + m_textEditable(editor), m_file(form) +{ +} + +FormWindowEditor::FormWindowEditor(Internal::DesignerXmlEditor *editor, + QDesignerFormWindowInterface *form, + QObject *parent) : + Core::IEditor(parent), + d(new FormWindowEditorPrivate(editor, form)) +{ + Core::UniqueIDManager *uidm = Core::UniqueIDManager::instance(); + d->m_context << uidm->uniqueIdentifier(QLatin1String(Designer::Constants::K_DESIGNER_XML_EDITOR_ID)) + << uidm->uniqueIdentifier(QLatin1String(Designer::Constants::C_DESIGNER_XML_EDITOR)); + connect(form, SIGNAL(changed()), this, SIGNAL(changed())); + // Revert to saved/load externally modified files + connect(&(d->m_file), SIGNAL(reload(QString)), this, SLOT(slotOpen(QString))); +} -using namespace Designer; -using namespace Designer::Internal; -using namespace Designer::Constants; +FormWindowEditor::~FormWindowEditor() +{ + delete d; +} + +bool FormWindowEditor::createNew(const QString &contents) +{ + if (Designer::Constants::Internal::debug) + qDebug() << "FormWindowEditor::createNew" << contents.size(); + + syncXmlEditor(QString()); + + QDesignerFormWindowInterface *form = d->m_file.formWindow(); + QTC_ASSERT(form, return false); + + if (contents.isEmpty()) + return false; + + form->setContents(contents); + if (form->mainContainer() == 0) + return false; + + syncXmlEditor(contents); + d->m_file.setFileName(QString()); + return true; +} -FormWindowEditor::FormWindowEditor(QDesignerFormWindowInterface *form, - QWidget *parent) : - SharedTools::WidgetHost(parent, form) +void FormWindowEditor::slotOpen(const QString &fileName) { - connect(this, SIGNAL(formWindowSizeChanged(int,int)), this, SLOT(slotFormSizeChanged(int,int))); + open(fileName); } -void FormWindowEditor::slotFormSizeChanged(int w, int h) +bool FormWindowEditor::open(const QString &fileName) { if (Designer::Constants::Internal::debug) - qDebug() << Q_FUNC_INFO << w << h; + qDebug() << "FormWindowEditor::open" << fileName; - formWindow()->setDirty(true); - static const QString geometry = QLatin1String("geometry"); - FormEditorW::instance()->designerEditor()->propertyEditor()->setPropertyValue(geometry, QRect(0,0,w,h) ); + QDesignerFormWindowInterface *form = d->m_file.formWindow(); + QTC_ASSERT(form, return false); + + if (fileName.isEmpty()) { + setDisplayName(tr("untitled")); + return true; + } + + const QFileInfo fi(fileName); + const QString absfileName = fi.absoluteFilePath(); + + QFile file(absfileName); + if (!file.open(QIODevice::ReadOnly|QIODevice::Text)) + return false; + + form->setFileName(absfileName); + + const QString contents = QString::fromUtf8(file.readAll()); + form->setContents(contents); + file.close(); + if (!form->mainContainer()) + return false; + form->setDirty(false); + syncXmlEditor(contents); + + setDisplayName(fi.fileName()); + d->m_file.setFileName(absfileName); + + if (Internal::ResourceHandler *rh = qFindChild<Designer::Internal::ResourceHandler*>(form)) + rh->updateResources(); + + emit changed(); + + return true; +} + +void FormWindowEditor::syncXmlEditor() +{ + if (Designer::Constants::Internal::debug) + qDebug() << "FormWindowEditor::syncXmlEditor" << d->m_file.fileName(); + syncXmlEditor(contents()); +} + +void FormWindowEditor::syncXmlEditor(const QString &contents) +{ + d->m_textEditable.editor()->setPlainText(contents); + d->m_textEditable.editor()->setReadOnly(true); +} + +Core::IFile *FormWindowEditor::file() +{ + return &d->m_file; +} + +QString FormWindowEditor::id() const +{ + return QLatin1String(Designer::Constants::K_DESIGNER_XML_EDITOR_ID); } + +QString FormWindowEditor::displayName() const +{ + return d->m_textEditable.displayName(); +} + +void FormWindowEditor::setDisplayName(const QString &title) +{ + d->m_textEditable.setDisplayName(title); +} + +bool FormWindowEditor::duplicateSupported() const +{ + return false; +} + +Core::IEditor *FormWindowEditor::duplicate(QWidget *) +{ + return 0; +} + +QByteArray FormWindowEditor::saveState() const +{ + return d->m_textEditable.saveState(); +} + +bool FormWindowEditor::restoreState(const QByteArray &state) +{ + return d->m_textEditable.restoreState(state); +} + +QList<int> FormWindowEditor::context() const +{ + return d->m_context; +} + +QWidget *FormWindowEditor::widget() +{ + return d->m_textEditable.widget(); +} + +bool FormWindowEditor::isTemporary() const +{ + return false; +} + +QWidget *FormWindowEditor::toolBar() +{ + return 0; +} + +QString FormWindowEditor::contents() const +{ + const qdesigner_internal::FormWindowBase *fw = qobject_cast<const qdesigner_internal::FormWindowBase *>(d->m_file.formWindow()); + QTC_ASSERT(fw, return QString()); + return fw->fileContents(); // No warnings about spacers here +} + +TextEditor::BaseTextDocument *FormWindowEditor::textDocument() +{ + return qobject_cast<TextEditor::BaseTextDocument*>(d->m_textEditable.file()); +} + +TextEditor::PlainTextEditorEditable *FormWindowEditor::textEditable() +{ + return &d->m_textEditable; +} + + + + +} // namespace Designer + diff --git a/src/plugins/designer/formwindoweditor.h b/src/plugins/designer/formwindoweditor.h index 5694902136b21ab2d4a2ed56f4fbb426ea017f4c..b99317e9ce9e38a5117072c87e460388304cc32b 100644 --- a/src/plugins/designer/formwindoweditor.h +++ b/src/plugins/designer/formwindoweditor.h @@ -30,29 +30,84 @@ #ifndef FORMWINDOWEDITOR_H #define FORMWINDOWEDITOR_H -#include "widgethost.h" +#include "designer_export.h" +#include <coreplugin/editormanager/ieditor.h> -#include <QtCore/QStringList> -#include <QtCore/QPointer> +QT_BEGIN_NAMESPACE +class QDesignerFormWindowInterface; +QT_END_NAMESPACE namespace Core { - class IFile; + class IMode; +} + +namespace TextEditor { + class BaseTextDocument; + class PlainTextEditorEditable; } namespace Designer { -// Master class maintaining a form window editor, -// containing file and widget host +namespace Internal { + class DesignerXmlEditor; +} +struct FormWindowEditorPrivate; + +// The actual Core::IEditor belonging to Qt Designer. Uses FormWindowFile +// as the Core::IFile to do the isModified() handling, +// which needs to be done by Qt Designer. +// However, to make the read-only XML text editor work, +// a TextEditor::PlainTextEditorEditable (IEditor) is also required. +// It is aggregated and some functions are delegated to it. -class FormWindowEditor : public SharedTools::WidgetHost +class DESIGNER_EXPORT FormWindowEditor : public Core::IEditor { + Q_PROPERTY(QString contents READ contents) Q_OBJECT public: - explicit FormWindowEditor(QDesignerFormWindowInterface *form, - QWidget *parent = 0); + explicit FormWindowEditor(Internal::DesignerXmlEditor *editor, + QDesignerFormWindowInterface *form, + QObject *parent = 0); + virtual ~FormWindowEditor(); + + // IEditor + virtual bool createNew(const QString &contents = QString()); + virtual bool open(const QString &fileName = QString()); + virtual Core::IFile *file(); + virtual QString id() const; + virtual QString displayName() const; + virtual void setDisplayName(const QString &title); + + virtual bool duplicateSupported() const; + virtual IEditor *duplicate(QWidget *parent); + + virtual QByteArray saveState() const; + virtual bool restoreState(const QByteArray &state); + + virtual bool isTemporary() const; + + virtual QWidget *toolBar(); + + // IContext + virtual QList<int> context() const; + virtual QWidget *widget(); + + // For uic code model support + QString contents() const; + + TextEditor::BaseTextDocument *textDocument(); + TextEditor::PlainTextEditorEditable *textEditable(); + +public slots: + void syncXmlEditor(); private slots: - void slotFormSizeChanged(int w, int h); + void slotOpen(const QString &fileName); + +private: + void syncXmlEditor(const QString &contents); + + FormWindowEditorPrivate *d; }; } // namespace Designer diff --git a/src/plugins/designer/formwindowfile.cpp b/src/plugins/designer/formwindowfile.cpp index 2cd65a1848be57339d2bbd5d70ff0babd8040ea2..4cb80925606440403f19d45730dd85f646d2e7ee 100644 --- a/src/plugins/designer/formwindowfile.cpp +++ b/src/plugins/designer/formwindowfile.cpp @@ -94,8 +94,6 @@ QString FormWindowFile::fileName() const bool FormWindowFile::isModified() const { - if (Designer::Constants::Internal::debug > 1) - qDebug() << Q_FUNC_INFO << m_formWindow->isDirty(); return m_formWindow && m_formWindow->isDirty(); } diff --git a/src/plugins/designer/formwindowfile.h b/src/plugins/designer/formwindowfile.h index e04d74a2a2e00df4b03918ae51a9da12f3aff084..36363f8fdb64144afb7f48f3579c7eca68e6f7ba 100644 --- a/src/plugins/designer/formwindowfile.h +++ b/src/plugins/designer/formwindowfile.h @@ -42,14 +42,12 @@ QT_END_NAMESPACE namespace Designer { namespace Internal { -class FormWindowSelection; - class FormWindowFile : public Core::IFile { Q_OBJECT public: - FormWindowFile(QDesignerFormWindowInterface *form, QObject *parent = 0); + explicit FormWindowFile(QDesignerFormWindowInterface *form, QObject *parent = 0); // IFile bool save(const QString &fileName = QString()); diff --git a/src/plugins/designer/qtcreatorintegration.cpp b/src/plugins/designer/qtcreatorintegration.cpp index 4cf1be7222eb9b2fa9bd4c03ae4c939e592d465c..82b0df1e21e8109be91ac088405c65d9107512ed 100644 --- a/src/plugins/designer/qtcreatorintegration.cpp +++ b/src/plugins/designer/qtcreatorintegration.cpp @@ -28,12 +28,12 @@ **************************************************************************/ #include "formeditorplugin.h" -#include "designerxmleditor.h" +#include "formwindoweditor.h" #include "qtcreatorintegration.h" #include "formeditorw.h" -#include "formwindoweditor.h" #include "editordata.h" #include "codemodelhelpers.h" +#include <widgethost.h> #include <cpptools/cppmodelmanagerinterface.h> #include <cplusplus/Symbols.h> @@ -99,14 +99,14 @@ QtCreatorIntegration::QtCreatorIntegration(QDesignerFormEditorInterface *core, F void QtCreatorIntegration::updateSelection() { if (const EditorData ed = m_few->activeEditor()) - ed.formEditor->updateFormWindowSelectionHandles(true); + ed.widgetHost->updateFormWindowSelectionHandles(true); qdesigner_internal::QDesignerIntegration::updateSelection(); } QWidget *QtCreatorIntegration::containerWindow(QWidget * /*widget*/) const { if (const EditorData ed = m_few->activeEditor()) - return ed.formEditor->integrationContainer(); + return ed.widgetHost->integrationContainer(); return 0; } @@ -574,7 +574,7 @@ bool QtCreatorIntegration::navigateToSlot(const QString &objectName, { const EditorData ed = m_few->activeEditor(); QTC_ASSERT(ed, return false) - const QString currentUiFile = ed.xmlEditor->file()->fileName(); + const QString currentUiFile = ed.formWindowEditor->file()->fileName(); #if 0 return Designer::Internal::navigateToSlot(currentUiFile, objectName, signalSignature, parameterNames, errorMessage); #endif @@ -613,7 +613,7 @@ bool QtCreatorIntegration::navigateToSlot(const QString &objectName, return false; } - QDesignerFormWindowInterface *fwi = ed.formEditor->formWindow(); + QDesignerFormWindowInterface *fwi = ed.widgetHost->formWindow(); const QString uiClass = uiClassName(fwi->mainContainer()->objectName()); diff --git a/src/plugins/qt4projectmanager/qt4projectmanager.cpp b/src/plugins/qt4projectmanager/qt4projectmanager.cpp index 4de77db29198db66b83a1fc044546509ff8b4653..48dcc2a74a353cc94863decc40bd3eff0b836f87 100644 --- a/src/plugins/qt4projectmanager/qt4projectmanager.cpp +++ b/src/plugins/qt4projectmanager/qt4projectmanager.cpp @@ -48,7 +48,7 @@ #include <projectexplorer/project.h> #include <projectexplorer/projectexplorerconstants.h> #include <utils/qtcassert.h> -#include <designer/designerxmleditor.h> +#include <designer/formwindoweditor.h> #include <QtCore/QCoreApplication> #include <QtCore/QDir> @@ -115,7 +115,7 @@ void Qt4Manager::init() void Qt4Manager::editorChanged(Core::IEditor *editor) { // Handle old editor - Designer::DesignerXmlEditorEditable *lastFormEditor = qobject_cast<Designer::DesignerXmlEditorEditable *>(m_lastEditor); + Designer::FormWindowEditor *lastFormEditor = qobject_cast<Designer::FormWindowEditor *>(m_lastEditor); if (lastFormEditor) { disconnect(lastFormEditor, SIGNAL(changed()), this, SLOT(uiEditorContentsChanged())); @@ -130,7 +130,7 @@ void Qt4Manager::editorChanged(Core::IEditor *editor) m_lastEditor = editor; // Handle new editor - if (Designer::DesignerXmlEditorEditable *fw = qobject_cast<Designer::DesignerXmlEditorEditable *>(editor)) + if (Designer::FormWindowEditor *fw = qobject_cast<Designer::FormWindowEditor *>(editor)) connect(fw, SIGNAL(changed()), this, SLOT(uiEditorContentsChanged())); } @@ -139,7 +139,7 @@ void Qt4Manager::editorAboutToClose(Core::IEditor *editor) if (m_lastEditor == editor) { // Oh no our editor is going to be closed // get the content first - Designer::DesignerXmlEditorEditable *lastEditor = qobject_cast<Designer::DesignerXmlEditorEditable *>(m_lastEditor); + Designer::FormWindowEditor *lastEditor = qobject_cast<Designer::FormWindowEditor *>(m_lastEditor); if (lastEditor) { disconnect(lastEditor, SIGNAL(changed()), this, SLOT(uiEditorContentsChanged())); if (m_dirty) { @@ -158,7 +158,7 @@ void Qt4Manager::uiEditorContentsChanged() // cast sender, get filename if (m_dirty) return; - Designer::DesignerXmlEditorEditable *fw = qobject_cast<Designer::DesignerXmlEditorEditable *>(sender()); + Designer::FormWindowEditor *fw = qobject_cast<Designer::FormWindowEditor *>(sender()); if (!fw) return; m_dirty = true; diff --git a/src/shared/designerintegrationv2/widgethost.h b/src/shared/designerintegrationv2/widgethost.h index 824972881a0d59094e54057730034578b50d4e4c..64125b65c1e10d3f5a88c07aa7e70553d20b199e 100644 --- a/src/shared/designerintegrationv2/widgethost.h +++ b/src/shared/designerintegrationv2/widgethost.h @@ -48,7 +48,7 @@ class WidgetHost : public QScrollArea { Q_OBJECT public: - WidgetHost(QWidget *parent = 0, QDesignerFormWindowInterface *formWindow = 0); + explicit WidgetHost(QWidget *parent = 0, QDesignerFormWindowInterface *formWindow = 0); virtual ~WidgetHost(); // Show handles if active and main container is selected. void updateFormWindowSelectionHandles(bool active);