forked from qt-creator/qt-creator
QmlDesigner: Polish error handling for integrated text editor
The integrated text editor requires a couple of fixes and features in the error handling. The errors are now handled by the model and not the document management anymore. The text editor does not get disabled if there is an error. Instead we show the error in a status bar. The form editor is blocked if there is a QML an error and we show the error message inside the form editor. Change-Id: I4bfb9b33b09e444ec1de31dd531ce83b32cbcf88 Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
committed by
Tim Jenssen
parent
8b67458a95
commit
759db2b7b6
@@ -264,6 +264,25 @@ void DebugView::auxiliaryDataChanged(const ModelNode &node, const PropertyName &
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DebugView::documentMessagesChanged(const QList<RewriterError> &errors, const QList<RewriterError> &warnings)
|
||||||
|
{
|
||||||
|
if (isDebugViewEnabled()) {
|
||||||
|
QTextStream message;
|
||||||
|
QString string;
|
||||||
|
message.setString(&string);
|
||||||
|
|
||||||
|
foreach (const RewriterError &error, errors) {
|
||||||
|
message << error.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (const RewriterError &warning, warnings) {
|
||||||
|
message << warning.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
log("::documentMessageChanged:", string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DebugView::rewriterBeginTransaction()
|
void DebugView::rewriterBeginTransaction()
|
||||||
{
|
{
|
||||||
if (isDebugViewEnabled())
|
if (isDebugViewEnabled())
|
||||||
|
@@ -65,6 +65,7 @@ public:
|
|||||||
void propertiesRemoved(const QList<AbstractProperty> &propertyList) override;
|
void propertiesRemoved(const QList<AbstractProperty> &propertyList) override;
|
||||||
|
|
||||||
void auxiliaryDataChanged(const ModelNode &node, const PropertyName &name, const QVariant &data) override;
|
void auxiliaryDataChanged(const ModelNode &node, const PropertyName &name, const QVariant &data) override;
|
||||||
|
void documentMessagesChanged(const QList<RewriterError> &errors, const QList<RewriterError> &warnings) override;
|
||||||
|
|
||||||
void rewriterBeginTransaction() override;
|
void rewriterBeginTransaction() override;
|
||||||
void rewriterEndTransaction() override;
|
void rewriterEndTransaction() override;
|
||||||
|
@@ -258,7 +258,7 @@ WidgetInfo FormEditorView::widgetInfo()
|
|||||||
if (!m_formEditorWidget)
|
if (!m_formEditorWidget)
|
||||||
createFormEditorWidget();
|
createFormEditorWidget();
|
||||||
|
|
||||||
return createWidgetInfo(m_formEditorWidget.data(), 0, "FormEditor", WidgetInfo::CentralPane, 0, tr("Form Editor"));
|
return createWidgetInfo(m_formEditorWidget.data(), 0, "FormEditor", WidgetInfo::CentralPane, 0, tr("Form Editor"), DesignerWidgetFlags::IgnoreErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
FormEditorWidget *FormEditorView::formEditorWidget()
|
FormEditorWidget *FormEditorView::formEditorWidget()
|
||||||
@@ -284,6 +284,17 @@ void FormEditorView::selectedNodesChanged(const QList<ModelNode> &selectedNodeLi
|
|||||||
m_scene->update();
|
m_scene->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FormEditorView::documentMessagesChanged(const QList<RewriterError> &errors, const QList<RewriterError> &warnings)
|
||||||
|
{
|
||||||
|
if (!errors.isEmpty())
|
||||||
|
formEditorWidget()->showErrorMessageBox(errors);
|
||||||
|
else
|
||||||
|
formEditorWidget()->hideErrorMessageBox();
|
||||||
|
|
||||||
|
if (!warnings.isEmpty())
|
||||||
|
formEditorWidget()->showWarningMessageBox(warnings);
|
||||||
|
}
|
||||||
|
|
||||||
void FormEditorView::customNotification(const AbstractView * /*view*/, const QString &identifier, const QList<ModelNode> &/*nodeList*/, const QList<QVariant> &/*data*/)
|
void FormEditorView::customNotification(const AbstractView * /*view*/, const QString &identifier, const QList<ModelNode> &/*nodeList*/, const QList<QVariant> &/*data*/)
|
||||||
{
|
{
|
||||||
if (identifier == QStringLiteral("puppet crashed"))
|
if (identifier == QStringLiteral("puppet crashed"))
|
||||||
@@ -511,6 +522,17 @@ double FormEditorView::spacing() const
|
|||||||
return m_formEditorWidget->spacing();
|
return m_formEditorWidget->spacing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FormEditorView::gotoError(int line, int column)
|
||||||
|
{
|
||||||
|
if (m_gotoErrorCallback)
|
||||||
|
m_gotoErrorCallback(line, column);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FormEditorView::setGotoErrorCallback(std::function<void (int, int)> gotoErrorCallback)
|
||||||
|
{
|
||||||
|
m_gotoErrorCallback = gotoErrorCallback;
|
||||||
|
}
|
||||||
|
|
||||||
QList<ModelNode> FormEditorView::adjustStatesForModelNodes(const QList<ModelNode> &nodeList) const
|
QList<ModelNode> FormEditorView::adjustStatesForModelNodes(const QList<ModelNode> &nodeList) const
|
||||||
{
|
{
|
||||||
QList<ModelNode> adjustedNodeList;
|
QList<ModelNode> adjustedNodeList;
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include <abstractview.h>
|
#include <abstractview.h>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@@ -74,6 +75,9 @@ public:
|
|||||||
|
|
||||||
void selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
|
void selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
|
||||||
const QList<ModelNode> &lastSelectedNodeList) override;
|
const QList<ModelNode> &lastSelectedNodeList) override;
|
||||||
|
|
||||||
|
virtual void documentMessagesChanged(const QList<RewriterError> &errors, const QList<RewriterError> &warnings) override;
|
||||||
|
|
||||||
void customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
void customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
||||||
|
|
||||||
// FormEditorView
|
// FormEditorView
|
||||||
@@ -109,6 +113,8 @@ public:
|
|||||||
double containerPadding() const;
|
double containerPadding() const;
|
||||||
double spacing() const;
|
double spacing() const;
|
||||||
void deActivateItemCreator();
|
void deActivateItemCreator();
|
||||||
|
void gotoError(int, int);
|
||||||
|
void setGotoErrorCallback(std::function<void(int, int)> gotoErrorCallback);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void reset();
|
void reset();
|
||||||
@@ -135,6 +141,7 @@ private: //variables
|
|||||||
std::unique_ptr<DragTool> m_dragTool;
|
std::unique_ptr<DragTool> m_dragTool;
|
||||||
AbstractFormEditorTool *m_currentTool;
|
AbstractFormEditorTool *m_currentTool;
|
||||||
int m_transactionCounter;
|
int m_transactionCounter;
|
||||||
|
std::function<void(int, int)> m_gotoErrorCallback;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -252,6 +252,34 @@ void FormEditorWidget::setFocus()
|
|||||||
m_graphicsView->setFocus(Qt::OtherFocusReason);
|
m_graphicsView->setFocus(Qt::OtherFocusReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FormEditorWidget::showErrorMessageBox(const QList<RewriterError> &errors)
|
||||||
|
{
|
||||||
|
errorWidget()->setErrors(errors);
|
||||||
|
errorWidget()->setVisible(true);
|
||||||
|
m_graphicsView->setDisabled(true);
|
||||||
|
m_toolBox->setDisabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FormEditorWidget::hideErrorMessageBox()
|
||||||
|
{
|
||||||
|
if (!m_documentErrorWidget.isNull())
|
||||||
|
errorWidget()->setVisible(false);
|
||||||
|
|
||||||
|
m_graphicsView->setDisabled(false);
|
||||||
|
m_toolBox->setDisabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FormEditorWidget::showWarningMessageBox(const QList<RewriterError> &warnings)
|
||||||
|
{
|
||||||
|
if (!errorWidget()->warningsEnabled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
errorWidget()->setWarnings(warnings);
|
||||||
|
errorWidget()->setVisible(true);
|
||||||
|
m_graphicsView->setDisabled(true);
|
||||||
|
m_toolBox->setDisabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
ZoomAction *FormEditorWidget::zoomAction() const
|
ZoomAction *FormEditorWidget::zoomAction() const
|
||||||
{
|
{
|
||||||
return m_zoomAction.data();
|
return m_zoomAction.data();
|
||||||
@@ -325,6 +353,19 @@ QRectF FormEditorWidget::rootItemRect() const
|
|||||||
return m_graphicsView->rootItemRect();
|
return m_graphicsView->rootItemRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DocumentWarningWidget *FormEditorWidget::errorWidget()
|
||||||
|
{
|
||||||
|
if (m_documentErrorWidget.isNull()) {
|
||||||
|
m_documentErrorWidget = new DocumentWarningWidget(this);
|
||||||
|
connect(m_documentErrorWidget.data(), &DocumentWarningWidget::gotoCodeClicked, [=]
|
||||||
|
(const QString &, int codeLine, int codeColumn) {
|
||||||
|
m_formEditorView->gotoError(codeLine, codeColumn);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return m_documentErrorWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -24,6 +24,8 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <documentwarningwidget.h>
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
|
||||||
@@ -72,9 +74,15 @@ public:
|
|||||||
|
|
||||||
void setFocus();
|
void setFocus();
|
||||||
|
|
||||||
|
void showErrorMessageBox(const QList<RewriterError> &errors);
|
||||||
|
void hideErrorMessageBox();
|
||||||
|
|
||||||
|
void showWarningMessageBox(const QList<RewriterError> &warnings);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void wheelEvent(QWheelEvent *event);
|
void wheelEvent(QWheelEvent *event);
|
||||||
QActionGroup *toolActionGroup() const;
|
QActionGroup *toolActionGroup() const;
|
||||||
|
DocumentWarningWidget *errorWidget();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void changeTransformTool(bool checked);
|
void changeTransformTool(bool checked);
|
||||||
@@ -99,6 +107,7 @@ private:
|
|||||||
QPointer<LineEditAction> m_rootHeightAction;
|
QPointer<LineEditAction> m_rootHeightAction;
|
||||||
QPointer<BackgroundAction> m_backgroundAction;
|
QPointer<BackgroundAction> m_backgroundAction;
|
||||||
QPointer<QAction> m_resetAction;
|
QPointer<QAction> m_resetAction;
|
||||||
|
QPointer<DocumentWarningWidget> m_documentErrorWidget;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
VPATH += $$PWD
|
VPATH += $$PWD
|
||||||
SOURCES += texteditorview.cpp \
|
SOURCES += texteditorview.cpp \
|
||||||
texteditorwidget.cpp
|
texteditorwidget.cpp \
|
||||||
|
$$PWD/texteditorstatusbar.cpp
|
||||||
HEADERS += texteditorview.h \
|
HEADERS += texteditorview.h \
|
||||||
texteditorwidget.h
|
texteditorwidget.h \
|
||||||
|
$$PWD/texteditorstatusbar.h
|
||||||
|
@@ -0,0 +1,56 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "texteditorstatusbar.h"
|
||||||
|
|
||||||
|
#include <utils/theme/theme.h>
|
||||||
|
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
TextEditorStatusBar::TextEditorStatusBar(QWidget *parent) : QToolBar(parent), m_label(new QLabel(this))
|
||||||
|
{
|
||||||
|
QWidget *spacer = new QWidget(this);
|
||||||
|
spacer->setMinimumWidth(50);
|
||||||
|
addWidget(spacer);
|
||||||
|
addWidget(m_label);
|
||||||
|
|
||||||
|
/* We have to set another .css, since the central widget has already a style sheet */
|
||||||
|
m_label->setStyleSheet(QString("QLabel { color :%1 }").arg(Utils::creatorTheme()->color(Utils::Theme::TextColorError).name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextEditorStatusBar::clearText()
|
||||||
|
{
|
||||||
|
m_label->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextEditorStatusBar::setText(const QString &text)
|
||||||
|
{
|
||||||
|
m_label->setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
||||||
|
|
@@ -0,0 +1,45 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QToolBar>
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class TextEditorStatusBar : public QToolBar
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit TextEditorStatusBar(QWidget *parent = 0);
|
||||||
|
void clearText();
|
||||||
|
void setText(const QString &text);
|
||||||
|
private:
|
||||||
|
QLabel *m_label;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
||||||
|
|
||||||
|
|
@@ -51,7 +51,6 @@ TextEditorView::TextEditorView(QObject *parent)
|
|||||||
: AbstractView(parent)
|
: AbstractView(parent)
|
||||||
, m_widget(new TextEditorWidget(this))
|
, m_widget(new TextEditorWidget(this))
|
||||||
{
|
{
|
||||||
// not completely sure that we need this to just call the right help method ->
|
|
||||||
Internal::TextEditorContext *textEditorContext = new Internal::TextEditorContext(m_widget.get());
|
Internal::TextEditorContext *textEditorContext = new Internal::TextEditorContext(m_widget.get());
|
||||||
Core::ICore::addContextObject(textEditorContext);
|
Core::ICore::addContextObject(textEditorContext);
|
||||||
}
|
}
|
||||||
@@ -96,7 +95,7 @@ void TextEditorView::nodeReparented(const ModelNode &/*node*/, const NodeAbstrac
|
|||||||
|
|
||||||
WidgetInfo TextEditorView::widgetInfo()
|
WidgetInfo TextEditorView::widgetInfo()
|
||||||
{
|
{
|
||||||
return createWidgetInfo(m_widget.get(), 0, "TextEditor", WidgetInfo::CentralPane, 0, tr("Text Editor"));
|
return createWidgetInfo(m_widget.get(), 0, "TextEditor", WidgetInfo::CentralPane, 0, tr("Text Editor"), DesignerWidgetFlags::IgnoreErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString TextEditorView::contextHelpId() const
|
QString TextEditorView::contextHelpId() const
|
||||||
@@ -123,6 +122,16 @@ void TextEditorView::customNotification(const AbstractView * /*view*/, const QSt
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextEditorView::documentMessagesChanged(const QList<RewriterError> &errors, const QList<RewriterError> &)
|
||||||
|
{
|
||||||
|
if (errors.isEmpty()) {
|
||||||
|
m_widget->clearStatusBar();
|
||||||
|
} else {
|
||||||
|
const RewriterError error = errors.first();
|
||||||
|
m_widget->setStatusText(QString("%1 (Line: %2)").arg(error.description()).arg(error.line()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool TextEditorView::changeToMoveTool()
|
bool TextEditorView::changeToMoveTool()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@@ -181,6 +190,12 @@ void TextEditorView::rewriterEndTransaction()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextEditorView::gotoCursorPosition(int line, int column)
|
||||||
|
{
|
||||||
|
if (m_widget)
|
||||||
|
m_widget->gotoCursorPosition(line, column);
|
||||||
|
}
|
||||||
|
|
||||||
void TextEditorView::instancePropertyChanged(const QList<QPair<ModelNode, PropertyName> > &/*propertyList*/)
|
void TextEditorView::instancePropertyChanged(const QList<QPair<ModelNode, PropertyName> > &/*propertyList*/)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@@ -59,6 +59,7 @@ public:
|
|||||||
void selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
|
void selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
|
||||||
const QList<ModelNode> &lastSelectedNodeList) override;
|
const QList<ModelNode> &lastSelectedNodeList) override;
|
||||||
void customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
void customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
||||||
|
void documentMessagesChanged(const QList<RewriterError> &errors, const QList<RewriterError> &warnings) override;
|
||||||
|
|
||||||
// TextEditorView
|
// TextEditorView
|
||||||
WidgetInfo widgetInfo() override;
|
WidgetInfo widgetInfo() override;
|
||||||
@@ -87,6 +88,8 @@ public:
|
|||||||
|
|
||||||
void deActivateItemCreator();
|
void deActivateItemCreator();
|
||||||
|
|
||||||
|
void gotoCursorPosition(int line, int column);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<TextEditorWidget> m_widget;
|
std::unique_ptr<TextEditorWidget> m_widget;
|
||||||
};
|
};
|
||||||
|
@@ -25,7 +25,9 @@
|
|||||||
|
|
||||||
#include "texteditorwidget.h"
|
#include "texteditorwidget.h"
|
||||||
|
|
||||||
|
#include <texteditorstatusbar.h>
|
||||||
#include <texteditorview.h>
|
#include <texteditorview.h>
|
||||||
|
|
||||||
#include <rewriterview.h>
|
#include <rewriterview.h>
|
||||||
|
|
||||||
#include <theming.h>
|
#include <theming.h>
|
||||||
@@ -38,10 +40,13 @@ namespace QmlDesigner {
|
|||||||
|
|
||||||
TextEditorWidget::TextEditorWidget(TextEditorView *textEditorView) : QWidget()
|
TextEditorWidget::TextEditorWidget(TextEditorView *textEditorView) : QWidget()
|
||||||
, m_textEditorView(textEditorView)
|
, m_textEditorView(textEditorView)
|
||||||
|
, m_statusBar(new TextEditorStatusBar(this))
|
||||||
|
|
||||||
{
|
{
|
||||||
QBoxLayout *layout = new QVBoxLayout(this);
|
QBoxLayout *layout = new QVBoxLayout(this);
|
||||||
layout->setMargin(0);
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
layout->setSpacing(0);
|
||||||
|
layout->addWidget(m_statusBar);
|
||||||
|
|
||||||
m_updateSelectionTimer.setSingleShot(true);
|
m_updateSelectionTimer.setSingleShot(true);
|
||||||
m_updateSelectionTimer.setInterval(200);
|
m_updateSelectionTimer.setInterval(200);
|
||||||
@@ -52,7 +57,9 @@ TextEditorWidget::TextEditorWidget(TextEditorView *textEditorView) : QWidget()
|
|||||||
|
|
||||||
void TextEditorWidget::setTextEditor(TextEditor::BaseTextEditor *textEditor) {
|
void TextEditorWidget::setTextEditor(TextEditor::BaseTextEditor *textEditor) {
|
||||||
m_textEditor.reset(textEditor);
|
m_textEditor.reset(textEditor);
|
||||||
|
layout()->removeWidget(m_statusBar);
|
||||||
layout()->addWidget(textEditor->editorWidget());
|
layout()->addWidget(textEditor->editorWidget());
|
||||||
|
layout()->addWidget(m_statusBar);
|
||||||
|
|
||||||
|
|
||||||
connect(textEditor->editorWidget(), &QPlainTextEdit::cursorPositionChanged,
|
connect(textEditor->editorWidget(), &QPlainTextEdit::cursorPositionChanged,
|
||||||
@@ -104,4 +111,22 @@ void TextEditorWidget::jumpTextCursorToSelectedModelNode()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextEditorWidget::gotoCursorPosition(int line, int column)
|
||||||
|
{
|
||||||
|
if (m_textEditor) {
|
||||||
|
m_textEditor->editorWidget()->gotoLine(line, column);
|
||||||
|
m_textEditor->editorWidget()->setFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextEditorWidget::setStatusText(const QString &text)
|
||||||
|
{
|
||||||
|
m_statusBar->setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextEditorWidget::clearStatusBar()
|
||||||
|
{
|
||||||
|
m_statusBar->clearText();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -34,6 +34,7 @@
|
|||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
class TextEditorView;
|
class TextEditorView;
|
||||||
|
class TextEditorStatusBar;
|
||||||
|
|
||||||
class TextEditorWidget : public QWidget {
|
class TextEditorWidget : public QWidget {
|
||||||
|
|
||||||
@@ -51,6 +52,10 @@ public:
|
|||||||
|
|
||||||
QString contextHelpId() const;
|
QString contextHelpId() const;
|
||||||
void jumpTextCursorToSelectedModelNode();
|
void jumpTextCursorToSelectedModelNode();
|
||||||
|
void gotoCursorPosition(int line, int column);
|
||||||
|
|
||||||
|
void setStatusText(const QString &text);
|
||||||
|
void clearStatusBar();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateSelectionByCursorPosition();
|
void updateSelectionByCursorPosition();
|
||||||
@@ -58,6 +63,7 @@ private:
|
|||||||
std::unique_ptr<TextEditor::BaseTextEditor> m_textEditor;
|
std::unique_ptr<TextEditor::BaseTextEditor> m_textEditor;
|
||||||
QPointer<TextEditorView> m_textEditorView;
|
QPointer<TextEditorView> m_textEditorView;
|
||||||
QTimer m_updateSelectionTimer;
|
QTimer m_updateSelectionTimer;
|
||||||
|
TextEditorStatusBar *m_statusBar;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
#include <model.h>
|
#include <model.h>
|
||||||
#include <modelnode.h>
|
#include <modelnode.h>
|
||||||
#include <abstractproperty.h>
|
#include <abstractproperty.h>
|
||||||
|
#include <rewritererror.h>
|
||||||
#include <rewritertransaction.h>
|
#include <rewritertransaction.h>
|
||||||
#include <commondefines.h>
|
#include <commondefines.h>
|
||||||
|
|
||||||
@@ -55,6 +56,11 @@ class NodeInstanceView;
|
|||||||
class RewriterView;
|
class RewriterView;
|
||||||
class QmlModelState;
|
class QmlModelState;
|
||||||
|
|
||||||
|
enum DesignerWidgetFlags {
|
||||||
|
DisableOnError,
|
||||||
|
IgnoreErrors
|
||||||
|
};
|
||||||
|
|
||||||
class WidgetInfo {
|
class WidgetInfo {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -93,18 +99,13 @@ public:
|
|||||||
CentralPane // not used
|
CentralPane // not used
|
||||||
};
|
};
|
||||||
|
|
||||||
WidgetInfo()
|
|
||||||
: widget(0),
|
|
||||||
toolBarWidgetFactory(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QString uniqueId;
|
QString uniqueId;
|
||||||
QString tabName;
|
QString tabName;
|
||||||
QWidget *widget;
|
QWidget *widget = nullptr;
|
||||||
int placementPriority;
|
int placementPriority;
|
||||||
PlacementHint placementHint;
|
PlacementHint placementHint;
|
||||||
ToolBarWidgetFactoryInterface *toolBarWidgetFactory;
|
ToolBarWidgetFactoryInterface *toolBarWidgetFactory = nullptr;
|
||||||
|
DesignerWidgetFlags widgetFlags = DesignerWidgetFlags::DisableOnError;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QMLDESIGNERCORE_EXPORT AbstractView : public QObject
|
class QMLDESIGNERCORE_EXPORT AbstractView : public QObject
|
||||||
@@ -162,6 +163,8 @@ public:
|
|||||||
|
|
||||||
QList<ModelNode> allModelNodes() const;
|
QList<ModelNode> allModelNodes() const;
|
||||||
|
|
||||||
|
void emitDocumentMessage(const QList<RewriterError> &errors, const QList<RewriterError> &warnings = QList<RewriterError>());
|
||||||
|
void emitDocumentMessage(const QString &error);
|
||||||
void emitCustomNotification(const QString &identifier);
|
void emitCustomNotification(const QString &identifier);
|
||||||
void emitCustomNotification(const QString &identifier, const QList<ModelNode> &nodeList);
|
void emitCustomNotification(const QString &identifier, const QList<ModelNode> &nodeList);
|
||||||
void emitCustomNotification(const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data);
|
void emitCustomNotification(const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data);
|
||||||
@@ -227,6 +230,8 @@ public:
|
|||||||
|
|
||||||
virtual void scriptFunctionsChanged(const ModelNode &node, const QStringList &scriptFunctionList);
|
virtual void scriptFunctionsChanged(const ModelNode &node, const QStringList &scriptFunctionList);
|
||||||
|
|
||||||
|
virtual void documentMessagesChanged(const QList<RewriterError> &errors, const QList<RewriterError> &warnings);
|
||||||
|
|
||||||
void changeRootNodeType(const TypeName &type, int majorVersion, int minorVersion);
|
void changeRootNodeType(const TypeName &type, int majorVersion, int minorVersion);
|
||||||
|
|
||||||
NodeInstanceView *nodeInstanceView() const;
|
NodeInstanceView *nodeInstanceView() const;
|
||||||
@@ -256,7 +261,7 @@ protected:
|
|||||||
const QString &uniqueId = QString(),
|
const QString &uniqueId = QString(),
|
||||||
WidgetInfo::PlacementHint placementHint = WidgetInfo::NoPane,
|
WidgetInfo::PlacementHint placementHint = WidgetInfo::NoPane,
|
||||||
int placementPriority = 0,
|
int placementPriority = 0,
|
||||||
const QString &tabName = QString());
|
const QString &tabName = QString(), DesignerWidgetFlags widgetFlags = DesignerWidgetFlags::DisableOnError);
|
||||||
|
|
||||||
private: //functions
|
private: //functions
|
||||||
QList<ModelNode> toModelNodeList(const QList<Internal::InternalNodePointer> &nodeList) const;
|
QList<ModelNode> toModelNodeList(const QList<Internal::InternalNodePointer> &nodeList) const;
|
||||||
|
@@ -26,6 +26,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <qmldesignercorelib_global.h>
|
#include <qmldesignercorelib_global.h>
|
||||||
|
|
||||||
|
#include <rewritererror.h>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QPair>
|
#include <QPair>
|
||||||
|
|
||||||
@@ -108,6 +111,7 @@ public:
|
|||||||
|
|
||||||
TextModifier *textModifier() const;
|
TextModifier *textModifier() const;
|
||||||
void setTextModifier(TextModifier *textModifier);
|
void setTextModifier(TextModifier *textModifier);
|
||||||
|
void setDocumentMessages(const QList<RewriterError> &errors, const QList<RewriterError> &warnings);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Model();
|
Model();
|
||||||
|
@@ -133,10 +133,6 @@ public:
|
|||||||
|
|
||||||
void sendToken(const QString &token, int number, const QVector<ModelNode> &nodeVector);
|
void sendToken(const QString &token, int number, const QVector<ModelNode> &nodeVector);
|
||||||
|
|
||||||
signals:
|
|
||||||
void qmlPuppetCrashed();
|
|
||||||
void qmlPuppetError(const QString &errorMessage);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void timerEvent(QTimerEvent *event) override;
|
void timerEvent(QTimerEvent *event) override;
|
||||||
|
|
||||||
|
@@ -34,6 +34,8 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
namespace QmlJS {
|
namespace QmlJS {
|
||||||
class Document;
|
class Document;
|
||||||
class ScopeChain;
|
class ScopeChain;
|
||||||
@@ -154,8 +156,7 @@ public:
|
|||||||
|
|
||||||
QList<CppTypeData> getCppTypes();
|
QList<CppTypeData> getCppTypes();
|
||||||
|
|
||||||
signals:
|
void setWidgetStatusCallback(std::function<void(bool)> setWidgetStatusCallback);
|
||||||
void errorsChanged(const QList<RewriterError> &errors);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void qmlTextChanged();
|
void qmlTextChanged();
|
||||||
@@ -172,6 +173,7 @@ protected: // functions
|
|||||||
void applyModificationGroupChanges();
|
void applyModificationGroupChanges();
|
||||||
void applyChanges();
|
void applyChanges();
|
||||||
void amendQmlText();
|
void amendQmlText();
|
||||||
|
void notifyErrorsAndWarnings(const QList<RewriterError> &errors);
|
||||||
|
|
||||||
private: //variables
|
private: //variables
|
||||||
TextModifier *m_textModifier = nullptr;
|
TextModifier *m_textModifier = nullptr;
|
||||||
@@ -190,6 +192,7 @@ private: //variables
|
|||||||
QString m_lastCorrectQmlSource;
|
QString m_lastCorrectQmlSource;
|
||||||
QTimer m_amendTimer;
|
QTimer m_amendTimer;
|
||||||
bool m_instantQmlTextUpdate = false;
|
bool m_instantQmlTextUpdate = false;
|
||||||
|
std::function<void(bool)> m_setWidgetStatusCallback;
|
||||||
};
|
};
|
||||||
|
|
||||||
} //QmlDesigner
|
} //QmlDesigner
|
||||||
|
@@ -84,14 +84,15 @@
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
static void showCannotConnectToPuppetWarningAndSwitchToEditMode()
|
void NodeInstanceServerProxy::showCannotConnectToPuppetWarningAndSwitchToEditMode()
|
||||||
{
|
{
|
||||||
#ifndef QMLDESIGNER_TEST
|
#ifndef QMLDESIGNER_TEST
|
||||||
Core::AsynchronousMessageBox::warning(QCoreApplication::translate("NodeInstanceServerProxy", "Cannot Connect to QML Emulation Layer (QML Puppet)"),
|
Core::AsynchronousMessageBox::warning(tr("Cannot Connect to QML Emulation Layer (QML Puppet)"),
|
||||||
QCoreApplication::translate("NodeInstanceServerProxy", "The executable of the QML emulation layer (QML Puppet) may not be responding. "
|
tr("The executable of the QML emulation layer (QML Puppet) may not be responding. "
|
||||||
"Switching to another kit might help."));
|
"Switching to another kit might help."));
|
||||||
|
|
||||||
QmlDesignerPlugin::instance()->switchToTextModeDeferred();
|
QmlDesignerPlugin::instance()->switchToTextModeDeferred();
|
||||||
|
m_nodeInstanceView->emitDocumentMessage(tr("Cannot Connect to QML Emulation Layer (QML Puppet)"));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -192,12 +193,7 @@ NodeInstanceServerProxy::NodeInstanceServerProxy(NodeInstanceView *nodeInstanceV
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Core::AsynchronousMessageBox::warning(tr("Cannot Start QML Emulation Layer (QML Puppet)"),
|
showCannotConnectToPuppetWarningAndSwitchToEditMode();
|
||||||
tr("The executable of the QML emulation layer (QML Puppet) process cannot be started or does not respond."));
|
|
||||||
|
|
||||||
#ifndef QMLDESIGNER_TEST
|
|
||||||
QmlDesignerPlugin::instance()->switchToTextModeDeferred();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_localServer->close();
|
m_localServer->close();
|
||||||
|
@@ -102,6 +102,7 @@ private slots:
|
|||||||
void printEditorProcessOutput();
|
void printEditorProcessOutput();
|
||||||
void printPreviewProcessOutput();
|
void printPreviewProcessOutput();
|
||||||
void printRenderProcessOutput();
|
void printRenderProcessOutput();
|
||||||
|
void showCannotConnectToPuppetWarningAndSwitchToEditMode();
|
||||||
private:
|
private:
|
||||||
QFile m_captureFileForTest;
|
QFile m_captureFileForTest;
|
||||||
QTimer m_firstTimer;
|
QTimer m_firstTimer;
|
||||||
|
@@ -191,13 +191,11 @@ void NodeInstanceView::handleCrash()
|
|||||||
if (elaspsedTimeSinceLastCrash > forceRestartTime)
|
if (elaspsedTimeSinceLastCrash > forceRestartTime)
|
||||||
restartProcess();
|
restartProcess();
|
||||||
else
|
else
|
||||||
emit qmlPuppetCrashed();
|
emitDocumentMessage(tr("Qt Quick emulation layer crashed."));
|
||||||
|
|
||||||
emitCustomNotification(QStringLiteral("puppet crashed"));
|
emitCustomNotification(QStringLiteral("puppet crashed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void NodeInstanceView::restartProcess()
|
void NodeInstanceView::restartProcess()
|
||||||
{
|
{
|
||||||
if (m_restartProcessTimerId)
|
if (m_restartProcessTimerId)
|
||||||
@@ -1266,14 +1264,14 @@ void NodeInstanceView::token(const TokenCommand &command)
|
|||||||
nodeVector.append(modelNodeForInternalId(instanceId));
|
nodeVector.append(modelNodeForInternalId(instanceId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
emitInstanceToken(command.tokenName(), command.tokenNumber(), nodeVector);
|
emitInstanceToken(command.tokenName(), command.tokenNumber(), nodeVector);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeInstanceView::debugOutput(const DebugOutputCommand & command)
|
void NodeInstanceView::debugOutput(const DebugOutputCommand & command)
|
||||||
{
|
{
|
||||||
|
RewriterError error(tr("Qt Quick emulation layer crashed."));
|
||||||
if (command.instanceIds().isEmpty()) {
|
if (command.instanceIds().isEmpty()) {
|
||||||
qmlPuppetError(command.text()); // TODO: connect that somewhere to show that to the user
|
emitDocumentMessage(command.text());
|
||||||
} else {
|
} else {
|
||||||
QVector<qint32> instanceIdsWithChangedErrors;
|
QVector<qint32> instanceIdsWithChangedErrors;
|
||||||
foreach (qint32 instanceId, command.instanceIds()) {
|
foreach (qint32 instanceId, command.instanceIds()) {
|
||||||
@@ -1282,7 +1280,7 @@ void NodeInstanceView::debugOutput(const DebugOutputCommand & command)
|
|||||||
if (instance.setError(command.text()))
|
if (instance.setError(command.text()))
|
||||||
instanceIdsWithChangedErrors.append(instanceId);
|
instanceIdsWithChangedErrors.append(instanceId);
|
||||||
} else {
|
} else {
|
||||||
qmlPuppetError(command.text()); // TODO: connect that somewhere to show that to the user
|
emitDocumentMessage(command.text());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
emitInstanceErrorChange(instanceIdsWithChangedErrors);
|
emitInstanceErrorChange(instanceIdsWithChangedErrors);
|
||||||
|
@@ -122,7 +122,8 @@ WidgetInfo AbstractView::createWidgetInfo(QWidget *widget,
|
|||||||
const QString &uniqueId,
|
const QString &uniqueId,
|
||||||
WidgetInfo::PlacementHint placementHint,
|
WidgetInfo::PlacementHint placementHint,
|
||||||
int placementPriority,
|
int placementPriority,
|
||||||
const QString &tabName)
|
const QString &tabName,
|
||||||
|
DesignerWidgetFlags widgetFlags)
|
||||||
{
|
{
|
||||||
WidgetInfo widgetInfo;
|
WidgetInfo widgetInfo;
|
||||||
|
|
||||||
@@ -132,6 +133,7 @@ WidgetInfo AbstractView::createWidgetInfo(QWidget *widget,
|
|||||||
widgetInfo.placementHint = placementHint;
|
widgetInfo.placementHint = placementHint;
|
||||||
widgetInfo.placementPriority = placementPriority;
|
widgetInfo.placementPriority = placementPriority;
|
||||||
widgetInfo.tabName = tabName;
|
widgetInfo.tabName = tabName;
|
||||||
|
widgetInfo.widgetFlags = widgetFlags;
|
||||||
|
|
||||||
return widgetInfo;
|
return widgetInfo;
|
||||||
}
|
}
|
||||||
@@ -346,6 +348,10 @@ void AbstractView::scriptFunctionsChanged(const ModelNode &/*node*/, const QStri
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AbstractView::documentMessagesChanged(const QList<RewriterError> &/*errors*/, const QList<RewriterError> &/*warnings*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
QList<ModelNode> AbstractView::toModelNodeList(const QList<Internal::InternalNode::Pointer> &nodeList) const
|
QList<ModelNode> AbstractView::toModelNodeList(const QList<Internal::InternalNode::Pointer> &nodeList) const
|
||||||
{
|
{
|
||||||
return QmlDesigner::toModelNodeList(nodeList, const_cast<AbstractView*>(this));
|
return QmlDesigner::toModelNodeList(nodeList, const_cast<AbstractView*>(this));
|
||||||
@@ -569,6 +575,16 @@ QList<ModelNode> AbstractView::allModelNodes() const
|
|||||||
return toModelNodeList(model()->d->allNodes());
|
return toModelNodeList(model()->d->allNodes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AbstractView::emitDocumentMessage(const QString &error)
|
||||||
|
{
|
||||||
|
emitDocumentMessage( { RewriterError(error) } );
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractView::emitDocumentMessage(const QList<RewriterError> &errors, const QList<RewriterError> &warnings)
|
||||||
|
{
|
||||||
|
model()->d->setDocumentMessages(errors, warnings);
|
||||||
|
}
|
||||||
|
|
||||||
void AbstractView::emitCustomNotification(const QString &identifier)
|
void AbstractView::emitCustomNotification(const QString &identifier)
|
||||||
{
|
{
|
||||||
emitCustomNotification(identifier, QList<ModelNode>());
|
emitCustomNotification(identifier, QList<ModelNode>());
|
||||||
|
@@ -174,6 +174,12 @@ QUrl ModelPrivate::fileUrl() const
|
|||||||
return m_fileUrl;
|
return m_fileUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModelPrivate::setDocumentMessages(const QList<RewriterError> &errors, const QList<RewriterError> &warnings)
|
||||||
|
{
|
||||||
|
foreach (const QPointer<AbstractView> &view, m_viewList)
|
||||||
|
view->documentMessagesChanged(errors, warnings);
|
||||||
|
}
|
||||||
|
|
||||||
void ModelPrivate::setFileUrl(const QUrl &fileUrl)
|
void ModelPrivate::setFileUrl(const QUrl &fileUrl)
|
||||||
{
|
{
|
||||||
QUrl oldPath = m_fileUrl;
|
QUrl oldPath = m_fileUrl;
|
||||||
@@ -1942,6 +1948,11 @@ void Model::setTextModifier(TextModifier *textModifier)
|
|||||||
d->m_textModifier = textModifier;
|
d->m_textModifier = textModifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Model::setDocumentMessages(const QList<RewriterError> &errors, const QList<RewriterError> &warnings)
|
||||||
|
{
|
||||||
|
d->setDocumentMessages(errors, warnings);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Returns the URL against which relative URLs within the model should be resolved.
|
\brief Returns the URL against which relative URLs within the model should be resolved.
|
||||||
\return The base URL.
|
\return The base URL.
|
||||||
|
@@ -158,6 +158,8 @@ public:
|
|||||||
|
|
||||||
void notifyCurrentStateChanged(const ModelNode &node);
|
void notifyCurrentStateChanged(const ModelNode &node);
|
||||||
|
|
||||||
|
void setDocumentMessages(const QList<RewriterError> &errors, const QList<RewriterError> &warnings);
|
||||||
|
|
||||||
void notifyRewriterBeginTransaction();
|
void notifyRewriterBeginTransaction();
|
||||||
void notifyRewriterEndTransaction();
|
void notifyRewriterEndTransaction();
|
||||||
|
|
||||||
|
@@ -82,6 +82,9 @@ void RewriterView::modelAttached(Model *model)
|
|||||||
const QString qmlSource = m_textModifier->text();
|
const QString qmlSource = m_textModifier->text();
|
||||||
if (m_textToModelMerger->load(qmlSource, differenceHandler))
|
if (m_textToModelMerger->load(qmlSource, differenceHandler))
|
||||||
m_lastCorrectQmlSource = qmlSource;
|
m_lastCorrectQmlSource = qmlSource;
|
||||||
|
|
||||||
|
if (!(m_errors.isEmpty() && m_warnings.isEmpty()))
|
||||||
|
notifyErrorsAndWarnings(m_errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RewriterView::modelAboutToBeDetached(Model * /*model*/)
|
void RewriterView::modelAboutToBeDetached(Model * /*model*/)
|
||||||
@@ -425,6 +428,14 @@ void RewriterView::amendQmlText()
|
|||||||
emitCustomNotification(EndRewriterAmend);
|
emitCustomNotification(EndRewriterAmend);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RewriterView::notifyErrorsAndWarnings(const QList<RewriterError> &errors)
|
||||||
|
{
|
||||||
|
if (m_setWidgetStatusCallback)
|
||||||
|
m_setWidgetStatusCallback(errors.isEmpty());
|
||||||
|
|
||||||
|
emitDocumentMessage(errors, m_warnings);
|
||||||
|
}
|
||||||
|
|
||||||
Internal::ModelNodePositionStorage *RewriterView::positionStorage() const
|
Internal::ModelNodePositionStorage *RewriterView::positionStorage() const
|
||||||
{
|
{
|
||||||
return m_positionStorage.data();
|
return m_positionStorage.data();
|
||||||
@@ -444,24 +455,25 @@ void RewriterView::clearErrorAndWarnings()
|
|||||||
{
|
{
|
||||||
m_errors.clear();
|
m_errors.clear();
|
||||||
m_warnings.clear();
|
m_warnings.clear();
|
||||||
emit errorsChanged(m_errors);
|
notifyErrorsAndWarnings(m_errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RewriterView::setWarnings(const QList<RewriterError> &warnings)
|
void RewriterView::setWarnings(const QList<RewriterError> &warnings)
|
||||||
{
|
{
|
||||||
m_warnings = warnings;
|
m_warnings = warnings;
|
||||||
|
notifyErrorsAndWarnings(m_errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RewriterView::setErrors(const QList<RewriterError> &errors)
|
void RewriterView::setErrors(const QList<RewriterError> &errors)
|
||||||
{
|
{
|
||||||
m_errors = errors;
|
m_errors = errors;
|
||||||
emit errorsChanged(m_errors);
|
notifyErrorsAndWarnings(m_errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RewriterView::addError(const RewriterError &error)
|
void RewriterView::addError(const RewriterError &error)
|
||||||
{
|
{
|
||||||
m_errors.append(error);
|
m_errors.append(error);
|
||||||
emit errorsChanged(m_errors);
|
notifyErrorsAndWarnings(m_errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RewriterView::enterErrorState(const QString &errorMessage)
|
void RewriterView::enterErrorState(const QString &errorMessage)
|
||||||
@@ -722,6 +734,11 @@ QList<CppTypeData> RewriterView::getCppTypes()
|
|||||||
return cppDataList;
|
return cppDataList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RewriterView::setWidgetStatusCallback(std::function<void (bool)> setWidgetStatusCallback)
|
||||||
|
{
|
||||||
|
m_setWidgetStatusCallback = setWidgetStatusCallback;
|
||||||
|
}
|
||||||
|
|
||||||
void RewriterView::qmlTextChanged()
|
void RewriterView::qmlTextChanged()
|
||||||
{
|
{
|
||||||
getCppTypes();
|
getCppTypes();
|
||||||
|
@@ -47,6 +47,8 @@
|
|||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
|
#include <QTabWidget>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
class ViewManagerData
|
class ViewManagerData
|
||||||
@@ -75,6 +77,12 @@ static CrumbleBar *crumbleBar() {
|
|||||||
ViewManager::ViewManager()
|
ViewManager::ViewManager()
|
||||||
: d(new ViewManagerData)
|
: d(new ViewManagerData)
|
||||||
{
|
{
|
||||||
|
d->formEditorView.setGotoErrorCallback([this](int line, int column) {
|
||||||
|
d->textEditorView.gotoCursorPosition(line, column);
|
||||||
|
Internal::DesignModeWidget *designModeWidget = QmlDesignerPlugin::instance()->mainWidget();
|
||||||
|
if (designModeWidget && designModeWidget->centralTabWidget())
|
||||||
|
designModeWidget->centralTabWidget()->setCurrentIndex(1);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewManager::~ViewManager()
|
ViewManager::~ViewManager()
|
||||||
@@ -99,6 +107,13 @@ void ViewManager::attachNodeInstanceView()
|
|||||||
void ViewManager::attachRewriterView()
|
void ViewManager::attachRewriterView()
|
||||||
{
|
{
|
||||||
if (currentDesignDocument()->rewriterView()) {
|
if (currentDesignDocument()->rewriterView()) {
|
||||||
|
currentDesignDocument()->rewriterView()->setWidgetStatusCallback([this](bool enable) {
|
||||||
|
if (enable)
|
||||||
|
enableWidgets();
|
||||||
|
else
|
||||||
|
disableWidgets();
|
||||||
|
});
|
||||||
|
|
||||||
currentModel()->setRewriterView(currentDesignDocument()->rewriterView());
|
currentModel()->setRewriterView(currentDesignDocument()->rewriterView());
|
||||||
currentDesignDocument()->rewriterView()->reactivateTextMofifierChangeSignals();
|
currentDesignDocument()->rewriterView()->reactivateTextMofifierChangeSignals();
|
||||||
}
|
}
|
||||||
@@ -263,12 +278,14 @@ QList<WidgetInfo> ViewManager::widgetInfos()
|
|||||||
void ViewManager::disableWidgets()
|
void ViewManager::disableWidgets()
|
||||||
{
|
{
|
||||||
foreach (const WidgetInfo &widgetInfo, widgetInfos())
|
foreach (const WidgetInfo &widgetInfo, widgetInfos())
|
||||||
|
if (widgetInfo.widgetFlags == DesignerWidgetFlags::DisableOnError)
|
||||||
widgetInfo.widget->setEnabled(false);
|
widgetInfo.widget->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewManager::enableWidgets()
|
void ViewManager::enableWidgets()
|
||||||
{
|
{
|
||||||
foreach (const WidgetInfo &widgetInfo, widgetInfos())
|
foreach (const WidgetInfo &widgetInfo, widgetInfos())
|
||||||
|
if (widgetInfo.widgetFlags == DesignerWidgetFlags::DisableOnError)
|
||||||
widgetInfo.widget->setEnabled(true);
|
widgetInfo.widget->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -132,12 +132,6 @@ DesignModeWidget::DesignModeWidget(QWidget *parent)
|
|||||||
, m_toolBar(new Core::EditorToolBar(this))
|
, m_toolBar(new Core::EditorToolBar(this))
|
||||||
, m_crumbleBar(new CrumbleBar(this))
|
, m_crumbleBar(new CrumbleBar(this))
|
||||||
{
|
{
|
||||||
connect(viewManager().nodeInstanceView(), &NodeInstanceView::qmlPuppetCrashed,
|
|
||||||
[=]() {
|
|
||||||
RewriterError error(tr("Qt Quick emulation layer crashed"));
|
|
||||||
updateErrorStatus(QList<RewriterError>() << error);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DesignModeWidget::~DesignModeWidget()
|
DesignModeWidget::~DesignModeWidget()
|
||||||
@@ -221,8 +215,6 @@ void DesignModeWidget::enableWidgets()
|
|||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
hideWarningWidget();
|
hideWarningWidget();
|
||||||
viewManager().enableWidgets();
|
viewManager().enableWidgets();
|
||||||
m_leftSideBar->setEnabled(true);
|
|
||||||
m_rightSideBar->setEnabled(true);
|
|
||||||
m_isDisabled = false;
|
m_isDisabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,8 +224,6 @@ void DesignModeWidget::disableWidgets()
|
|||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
viewManager().disableWidgets();
|
viewManager().disableWidgets();
|
||||||
m_leftSideBar->setEnabled(false);
|
|
||||||
m_rightSideBar->setEnabled(false);
|
|
||||||
m_isDisabled = true;
|
m_isDisabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,17 +232,18 @@ void DesignModeWidget::showTextEdit()
|
|||||||
m_centralTabWidget->setCurrentIndex(m_centralTabWidget->currentIndex() == 0 ? 1 : 0);
|
m_centralTabWidget->setCurrentIndex(m_centralTabWidget->currentIndex() == 0 ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignModeWidget::updateErrorStatus(const QList<RewriterError> &errors)
|
void DesignModeWidget::showWarningMessageBox(const QList<RewriterError> &warnings)
|
||||||
{
|
{
|
||||||
if (debug)
|
Q_ASSERT(!warnings.isEmpty());
|
||||||
qDebug() << Q_FUNC_INFO << errors.count();
|
warningWidget()->setWarnings(warnings);
|
||||||
|
warningWidget()->setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
if (m_isDisabled && errors.isEmpty()) {
|
bool DesignModeWidget::gotoCodeWasClicked()
|
||||||
enableWidgets();
|
{
|
||||||
} else if (!errors.isEmpty()) {
|
if (m_warningWidget)
|
||||||
disableWidgets();
|
return warningWidget()->gotoCodeWasClicked();
|
||||||
showErrorMessageBox(errors);
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hideToolButtons(QList<QToolButton*> &buttons)
|
static void hideToolButtons(QList<QToolButton*> &buttons)
|
||||||
@@ -576,27 +567,6 @@ void DesignModeWidget::hideWarningWidget()
|
|||||||
m_warningWidget->setVisible(false);
|
m_warningWidget->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignModeWidget::showErrorMessageBox(const QList<RewriterError> &errors)
|
|
||||||
{
|
|
||||||
Q_ASSERT(!errors.isEmpty());
|
|
||||||
warningWidget()->setErrors(errors);
|
|
||||||
warningWidget()->setVisible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DesignModeWidget::showWarningMessageBox(const QList<RewriterError> &warnings)
|
|
||||||
{
|
|
||||||
Q_ASSERT(!warnings.isEmpty());
|
|
||||||
warningWidget()->setWarnings(warnings);
|
|
||||||
warningWidget()->setVisible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DesignModeWidget::gotoCodeWasClicked()
|
|
||||||
{
|
|
||||||
if (m_warningWidget)
|
|
||||||
return warningWidget()->gotoCodeWasClicked();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
CrumbleBar *DesignModeWidget::crumbleBar() const
|
CrumbleBar *DesignModeWidget::crumbleBar() const
|
||||||
{
|
{
|
||||||
return m_crumbleBar;
|
return m_crumbleBar;
|
||||||
|
@@ -49,13 +49,13 @@ namespace QmlDesigner {
|
|||||||
|
|
||||||
class ItemLibraryWidget;
|
class ItemLibraryWidget;
|
||||||
class CrumbleBar;
|
class CrumbleBar;
|
||||||
|
class DocumentWarningWidget;
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class DesignMode;
|
class DesignMode;
|
||||||
class DocumentWidget;
|
class DocumentWidget;
|
||||||
class DesignModeWidget;
|
class DesignModeWidget;
|
||||||
class DocumentWarningWidget;
|
|
||||||
|
|
||||||
class DesignModeWidget : public QWidget
|
class DesignModeWidget : public QWidget
|
||||||
{
|
{
|
||||||
@@ -80,7 +80,7 @@ public:
|
|||||||
void enableWidgets();
|
void enableWidgets();
|
||||||
void disableWidgets();
|
void disableWidgets();
|
||||||
void showTextEdit();
|
void showTextEdit();
|
||||||
void showErrorMessageBox(const QList<RewriterError> &errors);
|
|
||||||
void showWarningMessageBox(const QList<RewriterError> &warnings);
|
void showWarningMessageBox(const QList<RewriterError> &warnings);
|
||||||
bool gotoCodeWasClicked();
|
bool gotoCodeWasClicked();
|
||||||
|
|
||||||
@@ -88,7 +88,6 @@ public:
|
|||||||
QTabWidget* centralTabWidget() const;
|
QTabWidget* centralTabWidget() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateErrorStatus(const QList<RewriterError> &errors);
|
|
||||||
void restoreDefaultView();
|
void restoreDefaultView();
|
||||||
void toggleSidebars();
|
void toggleSidebars();
|
||||||
void toggleLeftSidebar();
|
void toggleLeftSidebar();
|
||||||
|
@@ -46,8 +46,6 @@ static QString errorToString(const RewriterError &error)
|
|||||||
return QString("Line: %1: %2").arg(error.line()).arg(error.description());
|
return QString("Line: %1: %2").arg(error.line()).arg(error.description());
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
DocumentWarningWidget::DocumentWarningWidget(QWidget *parent)
|
DocumentWarningWidget::DocumentWarningWidget(QWidget *parent)
|
||||||
: Utils::FakeToolTip(parent)
|
: Utils::FakeToolTip(parent)
|
||||||
, m_headerLabel(new QLabel(this))
|
, m_headerLabel(new QLabel(this))
|
||||||
@@ -69,7 +67,6 @@ DocumentWarningWidget::DocumentWarningWidget(QWidget *parent)
|
|||||||
|
|
||||||
connect(m_navigateLabel, &QLabel::linkActivated, this, [=](const QString &link) {
|
connect(m_navigateLabel, &QLabel::linkActivated, this, [=](const QString &link) {
|
||||||
if (link == QLatin1String("goToCode")) {
|
if (link == QLatin1String("goToCode")) {
|
||||||
hide();
|
|
||||||
emitGotoCodeClicked(m_messages.at(m_currentMessage));
|
emitGotoCodeClicked(m_messages.at(m_currentMessage));
|
||||||
} else if (link == QLatin1String("previous")) {
|
} else if (link == QLatin1String("previous")) {
|
||||||
--m_currentMessage;
|
--m_currentMessage;
|
||||||
@@ -81,9 +78,10 @@ DocumentWarningWidget::DocumentWarningWidget(QWidget *parent)
|
|||||||
});
|
});
|
||||||
|
|
||||||
connect(m_continueButton, &QPushButton::clicked, this, [=]() {
|
connect(m_continueButton, &QPushButton::clicked, this, [=]() {
|
||||||
hide();
|
|
||||||
if (m_mode == ErrorMode)
|
if (m_mode == ErrorMode)
|
||||||
emitGotoCodeClicked(m_messages.at(m_currentMessage));
|
emitGotoCodeClicked(m_messages.at(m_currentMessage));
|
||||||
|
else
|
||||||
|
hide();
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(m_ignoreWarningsCheckBox, &QCheckBox::toggled, this, &DocumentWarningWidget::ignoreCheckBoxToggled);
|
connect(m_ignoreWarningsCheckBox, &QCheckBox::toggled, this, &DocumentWarningWidget::ignoreCheckBoxToggled);
|
||||||
@@ -233,5 +231,4 @@ void DocumentWarningWidget::setMessages(const QList<RewriterError> &messages)
|
|||||||
refreshContent();
|
refreshContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace Designer
|
} // namespace Designer
|
||||||
|
@@ -36,7 +36,6 @@ QT_END_NAMESPACE
|
|||||||
|
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
class DocumentWarningWidget : public Utils::FakeToolTip
|
class DocumentWarningWidget : public Utils::FakeToolTip
|
||||||
{
|
{
|
||||||
@@ -79,5 +78,4 @@ private:
|
|||||||
bool m_gotoCodeWasClicked = false;
|
bool m_gotoCodeWasClicked = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace Designer
|
} // namespace Designer
|
||||||
|
@@ -78,8 +78,6 @@ public:
|
|||||||
DocumentManager documentManager;
|
DocumentManager documentManager;
|
||||||
ShortCutManager shortCutManager;
|
ShortCutManager shortCutManager;
|
||||||
|
|
||||||
QMetaObject::Connection rewriterErrorConnection;
|
|
||||||
|
|
||||||
Internal::DesignModeWidget *mainWidget;
|
Internal::DesignModeWidget *mainWidget;
|
||||||
|
|
||||||
DesignerSettings settings;
|
DesignerSettings settings;
|
||||||
@@ -354,11 +352,11 @@ void QmlDesignerPlugin::hideDesigner()
|
|||||||
{
|
{
|
||||||
if (currentDesignDocument() && currentModel()) {
|
if (currentDesignDocument() && currentModel()) {
|
||||||
// the message box handle the cursor jump itself
|
// the message box handle the cursor jump itself
|
||||||
if (mainWidget()->gotoCodeWasClicked() == false)
|
|
||||||
jumpTextCursorToSelectedModelNode();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->documentManager.hasCurrentDesignDocument()) {
|
if (d->documentManager.hasCurrentDesignDocument()) {
|
||||||
|
if (currentModel() && !mainWidget()->gotoCodeWasClicked())
|
||||||
|
jumpTextCursorToSelectedModelNode();
|
||||||
deactivateAutoSynchronization();
|
deactivateAutoSynchronization();
|
||||||
d->mainWidget->saveSettings();
|
d->mainWidget->saveSettings();
|
||||||
}
|
}
|
||||||
@@ -426,6 +424,7 @@ void QmlDesignerPlugin::activateAutoSynchronization()
|
|||||||
|
|
||||||
currentDesignDocument()->updateActiveQtVersion();
|
currentDesignDocument()->updateActiveQtVersion();
|
||||||
currentDesignDocument()->updateCurrentProject();
|
currentDesignDocument()->updateCurrentProject();
|
||||||
|
d->mainWidget->enableWidgets();
|
||||||
currentDesignDocument()->attachRewriterToModel();
|
currentDesignDocument()->attachRewriterToModel();
|
||||||
|
|
||||||
resetModelSelection();
|
resetModelSelection();
|
||||||
@@ -433,22 +432,13 @@ void QmlDesignerPlugin::activateAutoSynchronization()
|
|||||||
viewManager().attachComponentView();
|
viewManager().attachComponentView();
|
||||||
viewManager().attachViewsExceptRewriterAndComponetView();
|
viewManager().attachViewsExceptRewriterAndComponetView();
|
||||||
|
|
||||||
QList<RewriterError> errors = currentDesignDocument()->qmlParseErrors();
|
|
||||||
if (errors.isEmpty()) {
|
|
||||||
selectModelNodeUnderTextCursor();
|
selectModelNodeUnderTextCursor();
|
||||||
d->mainWidget->enableWidgets();
|
|
||||||
d->mainWidget->setupNavigatorHistory(currentDesignDocument()->textEditor());
|
d->mainWidget->setupNavigatorHistory(currentDesignDocument()->textEditor());
|
||||||
if (showWarningsForFeaturesInDesigner() && currentDesignDocument()->hasQmlParseWarnings())
|
if (showWarningsForFeaturesInDesigner() && currentDesignDocument()->hasQmlParseWarnings())
|
||||||
d->mainWidget->showWarningMessageBox(currentDesignDocument()->qmlParseWarnings());
|
d->mainWidget->showWarningMessageBox(currentDesignDocument()->qmlParseWarnings());
|
||||||
} else {
|
|
||||||
d->mainWidget->disableWidgets();
|
|
||||||
d->mainWidget->showErrorMessageBox(errors);
|
|
||||||
}
|
|
||||||
|
|
||||||
currentDesignDocument()->updateSubcomponentManager();
|
currentDesignDocument()->updateSubcomponentManager();
|
||||||
|
|
||||||
d->rewriterErrorConnection = connect(rewriterView(), &RewriterView::errorsChanged,
|
|
||||||
d->mainWidget, &Internal::DesignModeWidget::updateErrorStatus);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlDesignerPlugin::deactivateAutoSynchronization()
|
void QmlDesignerPlugin::deactivateAutoSynchronization()
|
||||||
@@ -457,8 +447,6 @@ void QmlDesignerPlugin::deactivateAutoSynchronization()
|
|||||||
viewManager().detachComponentView();
|
viewManager().detachComponentView();
|
||||||
viewManager().detachRewriterView();
|
viewManager().detachRewriterView();
|
||||||
documentManager().currentDesignDocument()->resetToDocumentModel();
|
documentManager().currentDesignDocument()->resetToDocumentModel();
|
||||||
|
|
||||||
disconnect(d->rewriterErrorConnection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlDesignerPlugin::resetModelSelection()
|
void QmlDesignerPlugin::resetModelSelection()
|
||||||
|
Reference in New Issue
Block a user