Design mode/Qt Designer: clean-up Part II: Fix undo.

Re-introduce FormEditorFile that delegates dirty handling to the form
window. Change DesignerXmlEditable to be an IEditor that embeds
TextEditable so that the PlainTextEditor can work with it, but delegates
relevant functionality to FormEditorFile.
Centralize all form window creation code that was scattered around
in FormEditorW::createEditor() and have that return a struct Editor
data, which is passed to FormEditorStack.
Update the text editor only on open/createNew/switch away from design
mode.
This commit is contained in:
Friedemann Kleint
2010-03-09 15:48:01 +01:00
parent 403d755855
commit 1c78e200c2
17 changed files with 401 additions and 219 deletions

View File

@@ -39,7 +39,8 @@ HEADERS += formeditorplugin.h \
designerxmleditor.h \
designercontext.h \
faketoolbar.h \
formeditorstack.h
formeditorstack.h \
editordata.h
SOURCES += formeditorplugin.cpp \
formeditorfactory.cpp \

View File

@@ -36,6 +36,7 @@
#include <QtGui/QWidget>
#include <QtCore/QDebug>
#include <QtCore/QSettings>
enum { debug = 0 };

View File

@@ -29,64 +29,157 @@
#include "designerxmleditor.h"
#include "designerconstants.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 <QDebug>
#include <texteditor/basetextdocument.h>
#include <utils/qtcassert.h>
#include <QtDesigner/QDesignerFormWindowInterface>
#include <QtCore/QDebug>
#include <QtCore/QFileInfo>
#include <QtCore/QFile>
namespace Designer {
namespace Internal {
DesignerXmlEditor::DesignerXmlEditor(QWidget *parent) : TextEditor::PlainTextEditor(parent)
DesignerXmlEditorEditable::DesignerXmlEditorEditable(Internal::DesignerXmlEditor *editor,
QDesignerFormWindowInterface *form,
QObject *parent) :
Core::IEditor(parent),
m_textEditable(editor),
m_file(form)
{
setReadOnly(true);
connect(Core::ICore::instance()->editorManager(), SIGNAL(currentEditorChanged(Core::IEditor*)),
SLOT(updateEditorInfoBar(Core::IEditor*)));
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)));
}
DesignerXmlEditor::~DesignerXmlEditor()
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;
}
bool DesignerXmlEditor::open(const QString &fileName)
void DesignerXmlEditorEditable::slotOpen(const QString &fileName)
{
bool res = TextEditor::PlainTextEditor::open(fileName);
QPlainTextEdit::setReadOnly(true);
return res;
open(fileName);
}
void DesignerXmlEditor::updateEditorInfoBar(Core::IEditor *editor)
bool DesignerXmlEditorEditable::open(const QString &fileName)
{
if (editor == editableInterface()) {
Core::EditorManager::instance()->showEditorInfoBar(Constants::INFO_READ_ONLY,
tr("This file can only be edited in Design Mode."),
"Open Designer", this, SLOT(designerOpened()));
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;
}
if (!editor)
Core::EditorManager::instance()->hideEditorInfoBar(Constants::INFO_READ_ONLY);
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);
emit changed();
return true;
}
void DesignerXmlEditor::designerOpened()
void DesignerXmlEditorEditable::syncXmlEditor()
{
Core::ICore::instance()->modeManager()->activateMode(Core::Constants::MODE_DESIGN);
if (Designer::Constants::Internal::debug)
qDebug() << "DesignerXmlEditorEditable::syncXmlEditor" << m_file.fileName();
syncXmlEditor(contents());
}
} // namespace Internal
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);
}
DesignerXmlEditorEditable::DesignerXmlEditorEditable(Internal::DesignerXmlEditor *editor)
: TextEditor::PlainTextEditorEditable(editor)
QString DesignerXmlEditorEditable::displayName() const
{
Core::UniqueIDManager *uidm = Core::UniqueIDManager::instance();
m_context << uidm->uniqueIdentifier(Designer::Constants::K_DESIGNER_XML_EDITOR_ID);
m_context << uidm->uniqueIdentifier(Designer::Constants::C_DESIGNER_XML_EDITOR);
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
@@ -94,17 +187,78 @@ QList<int> DesignerXmlEditorEditable::context() const
return m_context;
}
Core::IEditor *DesignerXmlEditorEditable::duplicate(QWidget *parent)
QWidget *DesignerXmlEditorEditable::widget()
{
return m_textEditable.widget();
}
bool DesignerXmlEditorEditable::isTemporary() const
{
return false;
}
QWidget *DesignerXmlEditorEditable::toolBar()
{
Q_UNUSED(parent);
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))
{
setReadOnly(true);
connect(Core::EditorManager::instance(), SIGNAL(currentEditorChanged(Core::IEditor*)),
SLOT(updateEditorInfoBar(Core::IEditor*)));
}
TextEditor::BaseTextEditorEditable *DesignerXmlEditor::createEditableInterface()
{
return new DesignerXmlEditorEditable(this);
if (Designer::Constants::Internal::debug)
qDebug() << "DesignerXmlEditor::createEditableInterface()";
return m_editable->textEditable();
}
void DesignerXmlEditor::updateEditorInfoBar(Core::IEditor *editor)
{
if (editor == m_editable) {
Core::EditorManager::instance()->showEditorInfoBar(Constants::INFO_READ_ONLY,
tr("This file can only be edited in Design Mode."),
"Open Designer", this, SLOT(designerModeClicked()));
}
if (!editor)
Core::EditorManager::instance()->hideEditorInfoBar(Constants::INFO_READ_ONLY);
}
void DesignerXmlEditor::designerModeClicked()
{
Core::ICore::instance()->modeManager()->activateMode(QLatin1String(Core::Constants::MODE_DESIGN));
}
DesignerXmlEditorEditable *DesignerXmlEditor::designerEditable() const
{
return m_editable;
}
}
} // namespace Designer

View File

@@ -31,58 +31,106 @@
#define DESIGNERXMLEDITOR_H
#include "designer_export.h"
#include "formwindowfile.h"
#include <texteditor/plaintexteditor.h>
#include <texteditor/basetexteditor.h>
namespace Core {
class IEditor;
class IMode;
}
namespace TextEditor {
class BaseTextDocument;
}
namespace Designer {
namespace Internal {
class DesignerXmlEditor;
}
class DESIGNER_EXPORT DesignerXmlEditorEditable : public TextEditor::PlainTextEditorEditable
// 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);
QList<int> context() const;
explicit DesignerXmlEditorEditable(Internal::DesignerXmlEditor *editor,
QDesignerFormWindowInterface *form,
QObject *parent = 0);
bool duplicateSupported() const { return false; }
Core::IEditor *duplicate(QWidget *parent);
// 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
/* 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
* editable embedded in it. */
namespace Internal {
class DesignerXmlEditor : public TextEditor::PlainTextEditor
{
Q_OBJECT
public:
explicit DesignerXmlEditor(QWidget *parent = 0);
virtual ~DesignerXmlEditor();
bool open(const QString &fileName = QString());
explicit DesignerXmlEditor(QDesignerFormWindowInterface *form,
QWidget *parent = 0);
DesignerXmlEditorEditable *designerEditable() const;
private slots:
void designerOpened();
void designerModeClicked();
void updateEditorInfoBar(Core::IEditor *editor);
protected:
virtual TextEditor::BaseTextEditorEditable *createEditableInterface();
private:
DesignerXmlEditorEditable *m_editable;
};
} // Internal

View File

@@ -0,0 +1,49 @@
/**************************************************************************
**
** 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.
**
**************************************************************************/
#ifndef EDITORDATA_H
#define EDITORDATA_H
namespace Designer {
class FormWindowEditor;
class DesignerXmlEditorEditable;
namespace Internal {
// Associates XML and its form editor
struct EditorData {
EditorData() : xmlEditor(0), formEditor(0) {}
DesignerXmlEditorEditable *xmlEditor;
Designer::FormWindowEditor *formEditor;
};
} // namespace Internal
} // namespace Designer
#endif // EDITORDATA_H

View File

@@ -92,9 +92,9 @@ QDockWidget* const* EditorWidget::designerDockWidgets() const
return m_designerDockWidgets;
}
Designer::FormWindowEditor *EditorWidget::createFormWindowEditor(DesignerXmlEditorEditable *xmlEditor)
void EditorWidget::add(const EditorData &d)
{
return m_stack->createFormWindowEditor(xmlEditor);
m_stack->add(d);
}
bool EditorWidget::removeFormWindowEditor(Core::IEditor *xmlEditor)

View File

@@ -34,9 +34,6 @@
#include <utils/fancymainwindow.h>
#include <QtCore/QHash>
#include <QtCore/QVariant>
QT_BEGIN_NAMESPACE
class QDesignerFormWindowInterface;
QT_END_NAMESPACE
@@ -49,10 +46,11 @@ class FormWindowEditor;
class DesignerXmlEditorEditable;
namespace Internal {
struct EditorData;
class FormEditorStack;
class FormEditorW;
/* Form editor splitter used as editor window. Contains the shared designer
* windows. */
// Design mode main view.
class EditorWidget : public Utils::FancyMainWindow
{
Q_OBJECT
@@ -63,7 +61,7 @@ public:
QDockWidget* const* designerDockWidgets() const;
// Form editor stack API
Designer::FormWindowEditor *createFormWindowEditor(DesignerXmlEditorEditable *xmlEditor);
void add(const EditorData &d);
bool removeFormWindowEditor(Core::IEditor *xmlEditor);
bool setVisibleEditor(Core::IEditor *xmlEditor);
Designer::FormWindowEditor *formWindowEditorForXmlEditor(const Core::IEditor *xmlEditor) const;

View File

@@ -30,32 +30,34 @@
#include "formeditorfactory.h"
#include "formeditorw.h"
#include "formwindoweditor.h"
#include "editordata.h"
#include "designerconstants.h"
#include "designerxmleditor.h"
#include <coreplugin/icore.h>
#include <coreplugin/fileiconprovider.h>
#include <coreplugin/editormanager/editormanager.h>
#include <texteditor/texteditorsettings.h>
#include <QtCore/QFileInfo>
#include <QtCore/QDebug>
using namespace Designer::Internal;
using namespace Designer::Constants;
namespace Designer {
namespace Internal {
FormEditorFactory::FormEditorFactory()
: Core::IEditorFactory(Core::ICore::instance()),
m_mimeTypes(QLatin1String(FORM_MIMETYPE))
{
Core::FileIconProvider *iconProvider = Core::FileIconProvider::instance();
iconProvider->registerIconOverlayForSuffix(QIcon(":/formeditor/images/qt_ui.png"),
QLatin1String("ui"));
iconProvider->registerIconOverlayForSuffix(QIcon(QLatin1String(":/formeditor/images/qt_ui.png")),
QLatin1String("ui"));
}
QString FormEditorFactory::id() const
{
return QLatin1String(DESIGNER_XML_EDITOR_ID); //FORMEDITOR_ID);
return QLatin1String(DESIGNER_XML_EDITOR_ID);
}
QString FormEditorFactory::displayName() const
@@ -71,12 +73,16 @@ Core::IFile *FormEditorFactory::open(const QString &fileName)
Core::IEditor *FormEditorFactory::createEditor(QWidget *parent)
{
DesignerXmlEditor *xmlEditor = new DesignerXmlEditor(parent);
TextEditor::TextEditorSettings::instance()->initializeEditor(xmlEditor);
return xmlEditor->editableInterface();
const EditorData data = FormEditorW::instance()->createEditor(parent);
return data.xmlEditor;
}
QStringList FormEditorFactory::mimeTypes() const
{
return m_mimeTypes;
}
} // namespace Internal
} // namespace Designer

View File

@@ -45,7 +45,6 @@ namespace Internal {
class FormEditorFactory : public Core::IEditorFactory
{
Q_OBJECT
public:
FormEditorFactory();

View File

@@ -33,28 +33,21 @@
#include "formeditorw.h"
#include "designerconstants.h"
#include <texteditor/basetextdocument.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/modemanager.h>
#include <coreplugin/imode.h>
#include <utils/qtcassert.h>
#include <QDesignerFormWindowInterface>
#include <QDesignerFormWindowManagerInterface>
#include <QDesignerFormEditorInterface>
#include "qt_private/formwindowbase_p.h"
#include <QtCore/QDebug>
namespace Designer {
namespace Internal {
FormEditorStack::FormXmlData::FormXmlData() :
xmlEditor(0), formEditor(0)
{
}
FormEditorStack::FormEditorStack(QWidget *parent) :
QStackedWidget(parent),
m_designerCore(0)
@@ -62,28 +55,24 @@ FormEditorStack::FormEditorStack(QWidget *parent) :
setObjectName(QLatin1String("FormEditorStack"));
}
Designer::FormWindowEditor *FormEditorStack::createFormWindowEditor(DesignerXmlEditorEditable *xmlEditor)
void FormEditorStack::add(const EditorData &data)
{
FormEditorW *few = FormEditorW::instance();
if (m_designerCore == 0) { // Initialize first time here
m_designerCore = few->designerEditor();
m_designerCore = data.formEditor->formWindow()->core();
connect(m_designerCore->formWindowManager(), SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface*)),
this, SLOT(updateFormWindowSelectionHandles()));
connect(Core::ModeManager::instance(), SIGNAL(currentModeAboutToChange(Core::IMode*)),
this, SLOT(modeAboutToChange(Core::IMode*)));
}
FormXmlData data;
data.formEditor = few->createFormWindowEditor(this);
data.formEditor->setFile(xmlEditor->file());
data.xmlEditor = xmlEditor;
addWidget(data.formEditor);
m_formEditors.append(data);
setFormEditorData(data.formEditor, xmlEditor->contents());
TextEditor::BaseTextDocument *document = qobject_cast<TextEditor::BaseTextDocument*>(xmlEditor->file());
connect(document, SIGNAL(reloaded()), SLOT(reloadDocument()));
if (Designer::Constants::Internal::debug)
qDebug() << "FormEditorStack::createFormWindowEditor" << data.formEditor;
return data.formEditor;
qDebug() << "FormEditorStack::add" << data.xmlEditor << data.formEditor;
m_formEditors.append(data);
addWidget(data.formEditor);
if (Designer::Constants::Internal::debug)
qDebug() << "FormEditorStack::add" << data.formEditor;
}
int FormEditorStack::indexOf(const QDesignerFormWindowInterface *fw) const
@@ -125,7 +114,6 @@ 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;
disconnect(m_formEditors[i].formEditor->formWindow(), SIGNAL(changed()), this, SLOT(formChanged()));
removeWidget(m_formEditors[i].formEditor->widget());
delete m_formEditors[i].formEditor;
m_formEditors.removeAt(i);
@@ -150,7 +138,7 @@ void FormEditorStack::updateFormWindowSelectionHandles()
if (Designer::Constants::Internal::debug)
qDebug() << "updateFormWindowSelectionHandles";
QDesignerFormWindowInterface *activeFormWindow = m_designerCore->formWindowManager()->activeFormWindow();
foreach(const FormXmlData &fdm, m_formEditors) {
foreach(const EditorData &fdm, m_formEditors) {
const bool active = activeFormWindow == fdm.formEditor->formWindow();
fdm.formEditor->updateFormWindowSelectionHandles(active);
}
@@ -162,39 +150,15 @@ Designer::FormWindowEditor *FormEditorStack::formWindowEditorForXmlEditor(const
return i != -1 ? m_formEditors.at(i).formEditor : static_cast<Designer::FormWindowEditor *>(0);
}
void FormEditorStack::reloadDocument()
void FormEditorStack::modeAboutToChange(Core::IMode *m)
{
if (Designer::Constants::Internal::debug)
qDebug() << "FormEditorStack::reloadDocument()";
const int index = currentIndex();
if (index >= 0)
setFormEditorData(m_formEditors[index].formEditor, m_formEditors[index].xmlEditor->contents());
}
if (Designer::Constants::Internal::debug && m)
qDebug() << "FormEditorStack::modeAboutToChange" << m->id();
void FormEditorStack::setFormEditorData(Designer::FormWindowEditor *formEditor, const QString &contents)
{
if (Designer::Constants::Internal::debug)
qDebug() << "FormEditorStack::setFormEditorData()";
disconnect(formEditor->formWindow(), SIGNAL(changed()), this, SLOT(formChanged()));
formEditor->createNew(contents);
connect(formEditor->formWindow(), SIGNAL(changed()), SLOT(formChanged()));
}
void FormEditorStack::formChanged()
{
const int index = currentIndex();
if (index < 0)
return;
if (Core::IEditor *currentEditor = Core::EditorManager::instance()->currentEditor()) {
if (m_formEditors[index].xmlEditor == currentEditor) {
FormXmlData &xmlData = m_formEditors[index];
TextEditor::BaseTextDocument *doc = qobject_cast<TextEditor::BaseTextDocument*>(xmlData.xmlEditor->file());
QTC_ASSERT(doc, return);
if (doc) // Save quietly (without spacer's warning).
if (const qdesigner_internal::FormWindowBase *fwb = qobject_cast<const qdesigner_internal::FormWindowBase *>(xmlData.formEditor->formWindow()))
doc->document()->setPlainText(fwb->fileContents());
}
}
// 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();
}
} // Internal

View File

@@ -30,6 +30,8 @@
#ifndef FORMEDITORSTACK_H
#define FORMEDITORSTACK_H
#include "editordata.h"
#include <QtGui/QStackedWidget>
#include <QtCore/QList>
#include <QtCore/QString>
@@ -41,6 +43,7 @@ QT_END_NAMESPACE
namespace Core {
class IEditor;
class IMode;
}
namespace Designer {
@@ -49,11 +52,11 @@ class DesignerXmlEditorEditable;
namespace Internal {
/**
* A wrapper for Qt Designer form editors, so that they can be used in Design mode.
* FormEditorW owns an instance of this class, and creates new form editors when
* needed.
*/
/* FormEditorStack: Maintains a stack of Qt Designer form windows embedded
* into a scrollarea and their associated XML editors.
* Takes care of updating the XML editor once design mode is left.
* Also updates the maincontainer resize handles when the active form
* window changes. */
class FormEditorStack : public QStackedWidget
{
Q_OBJECT
@@ -61,29 +64,23 @@ class FormEditorStack : public QStackedWidget
public:
explicit FormEditorStack(QWidget *parent = 0);
Designer::FormWindowEditor *createFormWindowEditor(DesignerXmlEditorEditable *xmlEditor);
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;
FormWindowEditor *activeFormWindow() const;
private slots:
void formChanged();
void reloadDocument();
void updateFormWindowSelectionHandles();
void modeAboutToChange(Core::IMode *);
private:
inline int indexOf(const QDesignerFormWindowInterface *) const;
inline int indexOf(const Core::IEditor *xmlEditor) const;
void setFormEditorData(Designer::FormWindowEditor *formEditor, const QString &contents);
struct FormXmlData {
FormXmlData();
DesignerXmlEditorEditable *xmlEditor;
Designer::FormWindowEditor *formEditor;
};
QList<FormXmlData> m_formEditors;
QList<EditorData> m_formEditors;
QDesignerFormEditorInterface *m_designerCore;
};

View File

@@ -34,12 +34,12 @@
#include "settingsmanager.h"
#include "settingspage.h"
#include "editorwidget.h"
#include "editordata.h"
#include "qtcreatorintegration.h"
#include "designerxmleditor.h"
#include "designercontext.h"
#include "editorwidget.h"
#include <texteditor/basetextdocument.h>
#include <coreplugin/modemanager.h>
#include <coreplugin/designmode.h>
#include <coreplugin/coreconstants.h>
@@ -47,6 +47,7 @@
#include <coreplugin/uniqueidmanager.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/editormanager/editormanager.h>
#include <texteditor/texteditorsettings.h>
#include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h>
@@ -213,7 +214,7 @@ FormEditorW::~FormEditorW()
m_self = 0;
}
// Add an action to toggle the view state of a dock window
// Add an actioon to toggle the view state of a dock window
void FormEditorW::addDockViewAction(Core::ActionManager *am,
int index, const QList<int> &context,
const QString &title, const QString &id)
@@ -651,13 +652,27 @@ void FormEditorW::addToolAction(QAction *a,
c1->addAction(command);
}
FormWindowEditor *FormEditorW::createFormWindowEditor(QWidget* parentWidget)
EditorData FormEditorW::createEditor(QWidget *parent)
{
if (Designer::Constants::Internal::debug)
qDebug() << "FormEditorW::createEditor";
// Create and associate form and text editor.
EditorData data;
m_fwm->closeAllPreviews();
QDesignerFormWindowInterface *form = m_fwm->createFormWindow(0);
qdesigner_internal::FormWindowBase *form = qobject_cast<qdesigner_internal::FormWindowBase *>(m_fwm->createFormWindow(0));
QTC_ASSERT(form, return data);
connect(form, SIGNAL(toolChanged(int)), this, SLOT(toolChanged(int)));
form->setDesignerGrid(qdesigner_internal::FormWindowBase::defaultDesignerGrid());
qdesigner_internal::FormWindowBase::setupDefaultAction(form);
return new FormWindowEditor(form, parentWidget);
data.formEditor = new FormWindowEditor(form);
DesignerXmlEditor *xmlEditor = new DesignerXmlEditor(form, parent);
TextEditor::TextEditorSettings::instance()->initializeEditor(xmlEditor);
data.xmlEditor = xmlEditor->designerEditable();
data.formEditor->setFile(data.xmlEditor->file());
connect(data.formEditor, SIGNAL(formWindowSizeChanged(int,int)),
xmlEditor, SIGNAL(changed()));
m_editorWidget->add(data);
return data;
}
void FormEditorW::updateShortcut(QObject *command)
@@ -681,11 +696,8 @@ void FormEditorW::currentEditorChanged(Core::IEditor *editor)
QTC_ASSERT(xmlEditor, return);
ensureInitStage(FullyInitialized);
FormWindowEditor *fw = m_editorWidget->formWindowEditorForXmlEditor(xmlEditor);
if (fw) {
m_editorWidget->setVisibleEditor(xmlEditor);
} else {
fw = m_editorWidget->createFormWindowEditor(xmlEditor);
}
QTC_ASSERT(fw, return)
m_editorWidget->setVisibleEditor(xmlEditor);
m_fwm->setActiveFormWindow(fw->formWindow());
m_actionGroupEditMode->setVisible(true);
m_modeActionSeparator->setVisible(true);

View File

@@ -31,7 +31,6 @@
#define FORMEDITORW_H
#include <QtCore/QObject>
#include <QtCore/QPointer>
#include <QtCore/QStringList>
#include <QtCore/QMap>
@@ -45,9 +44,6 @@ class QDesignerFormWindowInterface;
class QAction;
class QActionGroup;
class QFocusEvent;
class QWidget;
class QSignalMapper;
class QSettings;
class QToolBar;
@@ -64,7 +60,6 @@ class ActionContainer;
class ICore;
class IEditor;
class Command;
class IMode;
class DesignMode;
}
@@ -73,6 +68,7 @@ class FormWindowEditor;
namespace Internal {
struct EditorData;
class EditorWidget;
class SettingsPage;
class DesignerContext;
@@ -113,11 +109,11 @@ public:
// Deletes an existing instance if there is one.
static void deleteInstance();
EditorData createEditor(QWidget *parent);
inline QDesignerFormEditorInterface *designerEditor() const { return m_formeditor; }
inline QWidget * const*designerSubWindows() const { return m_designerSubWindows; }
FormWindowEditor *createFormWindowEditor(QWidget* parentWidget);
FormWindowEditor *activeFormWindow() const;
private slots:

View File

@@ -96,26 +96,12 @@ FormWindowEditor::FormWindowEditor(QDesignerFormWindowInterface *form,
m_sessionNode(0),
m_sessionWatcher(0)
{
connect(formWindow(), SIGNAL(selectionChanged()), this, SIGNAL(changed()));
connect(this, SIGNAL(formWindowSizeChanged(int,int)), this, SLOT(slotFormSizeChanged(int,int)));
connect(formWindow(), SIGNAL(changed()), this, SIGNAL(changed()));
}
void FormWindowEditor::setFile(Core::IFile *file)
{
if (m_file) {
disconnect(m_file, SIGNAL(changed()), this, SIGNAL(changed()));
disconnect(m_file, SIGNAL(changed()), this, SLOT(updateResources()));
}
m_file = file;
formWindow()->setFileName(file->fileName());
if (m_file) {
connect(m_file, SIGNAL(changed()), this, SIGNAL(changed()));
connect(m_file, SIGNAL(changed()), this, SLOT(updateResources()));
}
m_file = file;
}
FormWindowEditor::~FormWindowEditor()
@@ -127,26 +113,6 @@ FormWindowEditor::~FormWindowEditor()
}
}
bool FormWindowEditor::createNew(const QString &contents)
{
if (Designer::Constants::Internal::debug)
qDebug() << Q_FUNC_INFO << contents.size() << "chars";
if (!formWindow())
return false;
formWindow()->setContents(contents);
if (!formWindow()->mainContainer())
return false;
if (qdesigner_internal::FormWindowBase *fw = qobject_cast<qdesigner_internal::FormWindowBase *>(formWindow()))
fw->setDesignerGrid(qdesigner_internal::FormWindowBase::defaultDesignerGrid());
initializeResources();
return true;
}
void FormWindowEditor::initializeResources(const QString & /* fileName */)
{
ProjectExplorer::ProjectExplorerPlugin *pe = ProjectExplorer::ProjectExplorerPlugin::instance();
@@ -167,11 +133,6 @@ void FormWindowEditor::initializeResources(const QString & /* fileName */)
}
updateResources();
QDesignerFormWindowManagerInterface *fwm = FormEditorW::instance()->designerEditor()->formWindowManager();
fwm->setActiveFormWindow(formWindow());
emit changed();
}
void FormWindowEditor::updateResources()
@@ -202,13 +163,6 @@ Core::IFile *FormWindowEditor::file() const
return m_file;
}
QString FormWindowEditor::contents() const
{
if (!formWindow())
return QString();
return formWindow()->contents();
}
void FormWindowEditor::slotFormSizeChanged(int w, int h)
{
if (Designer::Constants::Internal::debug)
@@ -217,5 +171,4 @@ void FormWindowEditor::slotFormSizeChanged(int w, int h)
formWindow()->setDirty(true);
static const QString geometry = QLatin1String("geometry");
FormEditorW::instance()->designerEditor()->propertyEditor()->setPropertyValue(geometry, QRect(0,0,w,h) );
emit changed();
}

View File

@@ -30,7 +30,6 @@
#ifndef FORMWINDOWEDITOR_H
#define FORMWINDOWEDITOR_H
#include "designer_export.h"
#include "widgethost.h"
#include <QtCore/QStringList>
@@ -58,15 +57,10 @@ public:
QWidget *parent = 0);
~FormWindowEditor();
// IEditor
bool createNew(const QString &contents);
void setFile(Core::IFile *file);
QString contents() const;
Core::IFile *file() const;
signals:
void changed();
private slots:
void updateResources();
void slotFormSizeChanged(int w, int h);
@@ -74,8 +68,6 @@ private slots:
private:
void initializeResources(const QString &fileName = QString());
QWidget *m_containerWidget;
QString m_displayName;
QPointer<Core::IFile> m_file;
QStringList m_originalUiQrcPaths;
ProjectExplorer::SessionNode *m_sessionNode;

View File

@@ -31,8 +31,8 @@
#include "designerconstants.h"
#include <coreplugin/icore.h>
#include <coreplugin/editormanager/editormanager.h>
#include <utils/reloadpromptutils.h>
#include <utils/qtcassert.h>
#include <QtDesigner/QDesignerFormWindowInterface>
#include <QtDesigner/QDesignerFormEditorInterface>
@@ -42,17 +42,15 @@
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QDir>
#include <QtCore/QByteArray>
#include <QtCore/QDebug>
using namespace Designer::Internal;
using namespace Designer::Constants;
using namespace SharedTools;
namespace Designer {
namespace Internal {
FormWindowFile::FormWindowFile(QDesignerFormWindowInterface *form, QObject *parent)
: Core::IFile(parent),
m_mimeType(QLatin1String(FORM_MIMETYPE)),
m_mimeType(QLatin1String(Designer::Constants::FORM_MIMETYPE)),
m_formWindow(form)
{
}
@@ -64,6 +62,8 @@ bool FormWindowFile::save(const QString &name /*= QString()*/)
if (Designer::Constants::Internal::debug)
qDebug() << Q_FUNC_INFO << name << "->" << actualName;
QTC_ASSERT(m_formWindow, return false);
if (actualName.isEmpty())
return false;
@@ -94,9 +94,9 @@ QString FormWindowFile::fileName() const
bool FormWindowFile::isModified() const
{
if (Designer::Constants::Internal::debug)
if (Designer::Constants::Internal::debug > 1)
qDebug() << Q_FUNC_INFO << m_formWindow->isDirty();
return m_formWindow->isDirty();
return m_formWindow && m_formWindow->isDirty();
}
bool FormWindowFile::isReadOnly() const
@@ -204,3 +204,11 @@ void FormWindowFile::setFileName(const QString &fname)
{
m_fileName = fname;
}
QDesignerFormWindowInterface *FormWindowFile::formWindow() const
{
return m_formWindow;
}
} // namespace Internal
} // namespace Designer

View File

@@ -32,8 +32,7 @@
#include <coreplugin/ifile.h>
#include "widgethost.h"
#include "designerconstants.h"
#include <QtCore/QPointer>
QT_BEGIN_NAMESPACE
class QDesignerFormWindowInterface;
@@ -65,9 +64,12 @@ public:
// Internal
void setSuggestedFileName(const QString &fileName);
bool writeFile(const QString &fileName, QString &errorString) const;
bool writeFile(QFile &file, QString &errorString) const;
QDesignerFormWindowInterface *formWindow() const;
signals:
// Internal
void reload(const QString &);
@@ -78,10 +80,12 @@ public slots:
private:
const QString m_mimeType;
QString m_fileName;
QString m_suggestedName;
QDesignerFormWindowInterface *m_formWindow;
// Might actually go out of scope before the IEditor due
// to deleting the WidgetHost which owns it.
QPointer<QDesignerFormWindowInterface> m_formWindow;
};
} // namespace Internal