Browse Source

- logs pane below the status pane

- retrieve javascript message
cl-refactor
yann300 10 years ago
parent
commit
1092518fe7
  1. 4
      mix/AppContext.cpp
  2. 6
      mix/CodeEditorExtensionManager.cpp
  3. 143
      mix/qml/LogsPane.qml
  4. 14
      mix/qml/MainContent.qml
  5. 93
      mix/qml/StatusPane.qml
  6. 11
      mix/qml/WebPreview.qml
  7. BIN
      mix/qml/img/broom.png
  8. BIN
      mix/qml/img/copy.png
  9. 4
      mix/res.qrc
  10. 170
      mix/sortfilterproxymodel.cpp
  11. 107
      mix/sortfilterproxymodel.h

4
mix/AppContext.cpp

@ -22,6 +22,7 @@
* - KeyEventManager * - KeyEventManager
*/ */
#include <QSortFilterProxyModel>
#include <QMessageBox> #include <QMessageBox>
#include <QClipboard> #include <QClipboard>
#include <QQmlComponent> #include <QQmlComponent>
@ -37,6 +38,7 @@
#include "QVariableDefinition.h" #include "QVariableDefinition.h"
#include "HttpServer.h" #include "HttpServer.h"
#include "AppContext.h" #include "AppContext.h"
#include "sortfilterproxymodel.h"
using namespace dev; using namespace dev;
using namespace dev::eth; using namespace dev::eth;
@ -74,6 +76,7 @@ void AppContext::load()
qmlRegisterType<QBoolType>("org.ethereum.qml.QBoolType", 1, 0, "QBoolType"); qmlRegisterType<QBoolType>("org.ethereum.qml.QBoolType", 1, 0, "QBoolType");
qmlRegisterType<QVariableDeclaration>("org.ethereum.qml.QVariableDeclaration", 1, 0, "QVariableDeclaration"); qmlRegisterType<QVariableDeclaration>("org.ethereum.qml.QVariableDeclaration", 1, 0, "QVariableDeclaration");
qmlRegisterType<RecordLogEntry>("org.ethereum.qml.RecordLogEntry", 1, 0, "RecordLogEntry"); qmlRegisterType<RecordLogEntry>("org.ethereum.qml.RecordLogEntry", 1, 0, "RecordLogEntry");
qmlRegisterType<SortFilterProxyModel>("org.ethereum.qml.SortFilterProxyModel", 1, 0, "SortFilterProxyModel");
QQmlComponent projectModelComponent(m_applicationEngine, QUrl("qrc:/qml/ProjectModel.qml")); QQmlComponent projectModelComponent(m_applicationEngine, QUrl("qrc:/qml/ProjectModel.qml"));
QObject* projectModel = projectModelComponent.create(); QObject* projectModel = projectModelComponent.create();
if (projectModelComponent.isError()) if (projectModelComponent.isError())
@ -86,6 +89,7 @@ void AppContext::load()
m_applicationEngine->rootContext()->setContextProperty("projectModel", projectModel); m_applicationEngine->rootContext()->setContextProperty("projectModel", projectModel);
qmlRegisterType<CodeEditorExtensionManager>("CodeEditorExtensionManager", 1, 0, "CodeEditorExtensionManager"); qmlRegisterType<CodeEditorExtensionManager>("CodeEditorExtensionManager", 1, 0, "CodeEditorExtensionManager");
qmlRegisterType<HttpServer>("HttpServer", 1, 0, "HttpServer"); qmlRegisterType<HttpServer>("HttpServer", 1, 0, "HttpServer");
m_applicationEngine->load(QUrl("qrc:/qml/main.qml")); m_applicationEngine->load(QUrl("qrc:/qml/main.qml"));
QWindow *window = qobject_cast<QWindow*>(m_applicationEngine->rootObjects().at(0)); QWindow *window = qobject_cast<QWindow*>(m_applicationEngine->rootObjects().at(0));
window->setIcon(QIcon(":/res/mix_256x256x32.png")); window->setIcon(QIcon(":/res/mix_256x256x32.png"));

6
mix/CodeEditorExtensionManager.cpp

@ -53,10 +53,10 @@ void CodeEditorExtensionManager::loadEditor(QQuickItem* _editor)
void CodeEditorExtensionManager::initExtensions() void CodeEditorExtensionManager::initExtensions()
{ {
std::shared_ptr<StatusPane> output = std::make_shared<StatusPane>(m_appContext); //std::shared_ptr<StatusPane> output = std::make_shared<StatusPane>(m_appContext);
QObject::connect(m_appContext->codeModel(), &CodeModel::compilationComplete, this, &CodeEditorExtensionManager::applyCodeHighlight); //QObject::connect(m_appContext->codeModel(), &CodeModel::compilationComplete, this, &CodeEditorExtensionManager::applyCodeHighlight);
initExtension(output); //initExtension(output);
} }
void CodeEditorExtensionManager::initExtension(std::shared_ptr<Extension> _ext) void CodeEditorExtensionManager::initExtension(std::shared_ptr<Extension> _ext)

143
mix/qml/LogsPane.qml

@ -0,0 +1,143 @@
import QtQuick 2.0
import QtQuick.Layouts 1.0
import QtQuick.Controls 1.1
import org.ethereum.qml.SortFilterProxyModel 1.0
import "."
Rectangle
{
function push(_level, _type, _content)
{
_content = _content.replace(/\n/g, " ")
logsModel.insert(0, { "type": _type, "date": Qt.formatDateTime(new Date(), "hh:mm:ss dd.MM.yyyy"), "content": _content, "level": _level });
}
anchors.fill: parent
radius: 5
color: "#f7f7f7"
border.color: "#808080"
border.width: 2
ColumnLayout {
height: parent.height - 4
width: parent.width - 2
spacing: 0
Row
{
id: rowAction
Layout.preferredHeight: 35
height: 35
anchors.leftMargin: 10
anchors.left: parent.left
spacing: 5
Button
{
height: 30
anchors.verticalCenter: parent.verticalCenter
action: clearAction
iconSource: "qrc:/qml/img/broom.png"
}
Action {
id: clearAction
enabled: logsModel.count > 0
tooltip: qsTr("Clear")
onTriggered: {
logsModel.clear()
}
}
Button
{
height: 30
anchors.verticalCenter: parent.verticalCenter
action: copytoClipBoardAction
iconSource: "qrc:/qml/img/copy.png"
}
Action {
id: copytoClipBoardAction
enabled: logsModel.count > 0
tooltip: qsTr("Copy to Clipboard")
onTriggered: {
var content = "";
for (var k = 0; k < logsModel.count; k++)
{
var log = logsModel.get(k);
content += log.type + "\t" + log.level + "\t" + log.date + "\t" + log.content;
}
appContext.toClipboard(content);
}
}
}
ListModel {
id: logsModel
}
TableView {
id: logsTable
clip: true
Layout.fillWidth: true
Layout.preferredHeight: parent.height - rowAction.height
headerVisible : false
onDoubleClicked:
{
var log = logsModel.get((logsTable.currentRow));
appContext.toClipboard(log.type + " " + log.level + " " + log.date + " " + log.content);
}
model: SortFilterProxyModel {
id: proxyModel
source: logsModel
filterRole: ""
filterString: ""
filterSyntax: SortFilterProxyModel.Wildcard
filterCaseSensitivity: Qt.CaseInsensitive
}
TableViewColumn
{
role: "date"
title: qsTr("date")
width: 150
delegate: itemDelegate
}
TableViewColumn
{
role: "type"
title: qsTr("type")
width: 100
delegate: itemDelegate
}
TableViewColumn
{
role: "content"
title: qsTr("content")
width: 700
delegate: itemDelegate
}
}
Component {
id: itemDelegate
DefaultLabel {
text: styleData.value;
font.family: "sans serif"
font.pointSize: Style.absoluteSize(-1)
color: {
if (styleData.row > -1)
{
var l = logsModel.get(styleData.row).level
if (l === "error")
return "red"
else if (l === "warning")
return "orange"
else if (l === "info")
return "#808080"
}
else
return "#808080"
}
}
}
}
}

14
mix/qml/MainContent.qml

@ -102,7 +102,7 @@ Rectangle {
} }
CodeEditorExtensionManager { CodeEditorExtensionManager {
headerView: headerPaneTabs; //headerView: headerPaneTabs;
} }
Settings { Settings {
@ -133,16 +133,10 @@ Rectangle {
} }
id: headerPaneContainer id: headerPaneContainer
anchors.fill: parent anchors.fill: parent
TabView { StatusPane
id: headerPaneTabs {
tabsVisible: false
antialiasing: true
anchors.fill: parent anchors.fill: parent
style: TabViewStyle { webPreview: webPreview
frameOverlap: 1
tab: Rectangle {}
frame: Rectangle { color: "transparent" }
}
} }
} }
} }

93
mix/qml/StatusPane.qml

@ -8,6 +8,7 @@ import "."
Rectangle { Rectangle {
id: statusHeader id: statusHeader
objectName: "statusPane" objectName: "statusPane"
property variant webPreview
function updateStatus(message) function updateStatus(message)
{ {
@ -15,7 +16,6 @@ Rectangle {
{ {
status.state = ""; status.state = "";
status.text = qsTr("Compile successfully."); status.text = qsTr("Compile successfully.");
logslink.visible = false;
debugImg.state = "active"; debugImg.state = "active";
} }
else else
@ -23,39 +23,52 @@ Rectangle {
status.state = "error"; status.state = "error";
var errorInfo = ErrorLocationFormater.extractErrorInfo(message, true); var errorInfo = ErrorLocationFormater.extractErrorInfo(message, true);
status.text = errorInfo.errorLocation + " " + errorInfo.errorDetail; status.text = errorInfo.errorLocation + " " + errorInfo.errorDetail;
logslink.visible = true;
debugImg.state = ""; debugImg.state = "";
} }
debugRunActionIcon.enabled = codeModel.hasContract; debugRunActionIcon.enabled = codeModel.hasContract;
} }
function infoMessage(text) function infoMessage(text, type)
{ {
status.state = ""; status.state = "";
status.text = text status.text = text
logslink.visible = false; logPane.push("info",type, text);
} }
function errorMessage(text) function warningMessage(text, type)
{
status.state = "";
status.text = text
logPane.push("warning", type, text);
}
function errorMessage(text, type)
{ {
status.state = "error"; status.state = "error";
status.text = text status.text = text
logslink.visible = false; logPane.push("error", type, text);
}
Connections {
target: webPreview
onJavaScriptErrorMessage: errorMessage(_content, "javascript")
onJavaScriptWarningMessage: warningMessage(_content, "javascript")
onJavaScriptInfoMessage: infoMessage(_content, "javascript")
} }
Connections { Connections {
target:clientModel target:clientModel
onRunStarted: infoMessage(qsTr("Running transactions...")); onRunStarted: infoMessage(qsTr("Running transactions..."), "run");
onRunFailed: errorMessage(qsTr("Error running transactions: " + _message)); onRunFailed: errorMessage(qsTr("Error running transactions: " + _message), "run");
onRunComplete: infoMessage(qsTr("Run complete")); onRunComplete: infoMessage(qsTr("Run complete"), "run");
onNewBlock: infoMessage(qsTr("New block created")); onNewBlock: infoMessage(qsTr("New block created"), "state");
} }
Connections { Connections {
target:projectModel target:projectModel
onDeploymentStarted: infoMessage(qsTr("Running deployment...")); onDeploymentStarted: infoMessage(qsTr("Running deployment..."), "deployment");
onDeploymentError: errorMessage(error); onDeploymentError: errorMessage(error, "deployment");
onDeploymentComplete: infoMessage(qsTr("Deployment complete")); onDeploymentComplete: infoMessage(qsTr("Deployment complete"), "deployment");
onDeploymentStepChanged: infoMessage(message); onDeploymentStepChanged: infoMessage(message, "deployment");
} }
Connections { Connections {
target: codeModel target: codeModel
@ -133,6 +146,53 @@ Rectangle {
id: toolTipInfo id: toolTipInfo
tooltip: "" tooltip: ""
} }
Rectangle
{
function toggle()
{
if (logsContainer.state === "opened")
logsContainer.state = "closed"
else
logsContainer.state = "opened";
}
id: logsContainer
width: 1000
height: 0
anchors.topMargin: 2
anchors.top: statusContainer.bottom
anchors.horizontalCenter: parent.horizontalCenter
visible: false
Component.onCompleted:
{
var top = logsContainer;
while (top.parent)
top = top.parent
var coordinates = logsContainer.mapToItem(top, 0, 0)
logsContainer.parent = top;
logsContainer.x = coordinates.x
logsContainer.y = coordinates.y
}
LogsPane
{
id: logPane
}
states: [
State {
name: "opened";
PropertyChanges { target: logsContainer; height: 500; visible: true }
},
State {
name: "closed";
PropertyChanges { target: logsContainer; height: 0; visible: false }
}
]
transitions: Transition {
NumberAnimation { properties: "height"; easing.type: Easing.InOutQuad; duration: 200 }
NumberAnimation { properties: "visible"; easing.type: Easing.InOutQuad; duration: 200 }
}
}
} }
Button Button
@ -140,7 +200,6 @@ Rectangle {
id: logslink id: logslink
anchors.left: statusContainer.right anchors.left: statusContainer.right
anchors.leftMargin: 9 anchors.leftMargin: 9
visible: false
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
action: displayLogAction action: displayLogAction
iconSource: "qrc:/qml/img/search_filled.png" iconSource: "qrc:/qml/img/search_filled.png"
@ -150,7 +209,9 @@ Rectangle {
id: displayLogAction id: displayLogAction
tooltip: qsTr("Display Log") tooltip: qsTr("Display Log")
onTriggered: { onTriggered: {
mainContent.displayCompilationErrorIfAny(); logsContainer.toggle();
//if (status.state === "error" && logPane.front().type === "run")
// mainContent.displayCompilationErrorIfAny();
} }
} }

11
mix/qml/WebPreview.qml

@ -12,6 +12,9 @@ Item {
id: webPreview id: webPreview
property string pendingPageUrl: "" property string pendingPageUrl: ""
property bool initialized: false property bool initialized: false
signal javaScriptErrorMessage(string _content)
signal javaScriptWarningMessage(string _content)
signal javaScriptInfoMessage(string _content)
function setPreviewUrl(url) { function setPreviewUrl(url) {
if (!initialized) if (!initialized)
@ -240,7 +243,13 @@ Item {
id: webView id: webView
experimental.settings.localContentCanAccessRemoteUrls: true experimental.settings.localContentCanAccessRemoteUrls: true
onJavaScriptConsoleMessage: { onJavaScriptConsoleMessage: {
console.log(sourceID + ":" + lineNumber + ":" + message); var info = sourceID + ":" + lineNumber + ":" + message;
if (level === 0)
webPreview.javaScriptInfoMessage(info);
else if (level === 1)
webPreview.javaScriptErrorMessage(info);
else if (level === 2)
webPreview.javaScriptErrorMessage(info);
} }
onLoadingChanged: { onLoadingChanged: {
if (!loading) { if (!loading) {

BIN
mix/qml/img/broom.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 501 B

BIN
mix/qml/img/copy.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 B

4
mix/res.qrc

@ -109,5 +109,9 @@
<file>qml/img/exit.png</file> <file>qml/img/exit.png</file>
<file>qml/img/run.png</file> <file>qml/img/run.png</file>
<file>qml/img/note.png</file> <file>qml/img/note.png</file>
<file>qml/LogsPane.qml</file>
<file>qml/LogsWindow.qml</file>
<file>qml/img/copy.png</file>
<file>qml/img/broom.png</file>
</qresource> </qresource>
</RCC> </RCC>

170
mix/sortfilterproxymodel.cpp

@ -0,0 +1,170 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "sortfilterproxymodel.h"
#include <QtDebug>
#include <QtQml>
using namespace dev::mix;
SortFilterProxyModel::SortFilterProxyModel(QObject *parent) : QSortFilterProxyModel(parent)
{
connect(this, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SIGNAL(countChanged()));
connect(this, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SIGNAL(countChanged()));
}
int SortFilterProxyModel::count() const
{
return rowCount();
}
QObject *SortFilterProxyModel::source() const
{
return sourceModel();
}
void SortFilterProxyModel::setSource(QObject *source)
{
setSourceModel(qobject_cast<QAbstractItemModel *>(source));
}
QByteArray SortFilterProxyModel::sortRole() const
{
return roleNames().value(QSortFilterProxyModel::sortRole());
}
void SortFilterProxyModel::setSortRole(const QByteArray &role)
{
QSortFilterProxyModel::setSortRole(roleKey(role));
}
void SortFilterProxyModel::setSortOrder(Qt::SortOrder order)
{
QSortFilterProxyModel::sort(0, order);
}
QByteArray SortFilterProxyModel::filterRole() const
{
return roleNames().value(QSortFilterProxyModel::filterRole());
}
void SortFilterProxyModel::setFilterRole(const QByteArray &role)
{
QSortFilterProxyModel::setFilterRole(roleKey(role));
}
QString SortFilterProxyModel::filterString() const
{
return filterRegExp().pattern();
}
void SortFilterProxyModel::setFilterString(const QString &filter)
{
setFilterRegExp(QRegExp(filter, filterCaseSensitivity(), static_cast<QRegExp::PatternSyntax>(filterSyntax())));
}
SortFilterProxyModel::FilterSyntax SortFilterProxyModel::filterSyntax() const
{
return static_cast<FilterSyntax>(filterRegExp().patternSyntax());
}
void SortFilterProxyModel::setFilterSyntax(SortFilterProxyModel::FilterSyntax syntax)
{
setFilterRegExp(QRegExp(filterString(), filterCaseSensitivity(), static_cast<QRegExp::PatternSyntax>(syntax)));
}
QJSValue SortFilterProxyModel::get(int idx) const
{
QJSEngine *engine = qmlEngine(this);
QJSValue value = engine->newObject();
if (idx >= 0 && idx < count()) {
QHash<int, QByteArray> roles = roleNames();
QHashIterator<int, QByteArray> it(roles);
while (it.hasNext()) {
it.next();
value.setProperty(QString::fromUtf8(it.value()), data(index(idx, 0), it.key()).toString());
}
}
return value;
}
int SortFilterProxyModel::roleKey(const QByteArray &role) const
{
QHash<int, QByteArray> roles = roleNames();
QHashIterator<int, QByteArray> it(roles);
while (it.hasNext()) {
it.next();
if (it.value() == role)
return it.key();
}
return -1;
}
QHash<int, QByteArray> SortFilterProxyModel::roleNames() const
{
if (QAbstractItemModel *source = sourceModel())
return source->roleNames();
return QHash<int, QByteArray>();
}
bool SortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
QRegExp rx = filterRegExp();
if (rx.isEmpty())
return true;
QAbstractItemModel *model = sourceModel();
if (filterRole().isEmpty()) {
QHash<int, QByteArray> roles = roleNames();
QHashIterator<int, QByteArray> it(roles);
while (it.hasNext()) {
it.next();
QModelIndex sourceIndex = model->index(sourceRow, 0, sourceParent);
QString key = model->data(sourceIndex, it.key()).toString();
if (key.contains(rx))
return true;
}
return false;
}
QModelIndex sourceIndex = model->index(sourceRow, 0, sourceParent);
if (!sourceIndex.isValid())
return true;
QString key = model->data(sourceIndex, roleKey(filterRole())).toString();
return key.contains(rx);
}

107
mix/sortfilterproxymodel.h

@ -0,0 +1,107 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef SORTFILTERPROXYMODEL_H
#define SORTFILTERPROXYMODEL_H
#include <QtCore/qsortfilterproxymodel.h>
#include <QtQml/qjsvalue.h>
namespace dev
{
namespace mix
{
class SortFilterProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
Q_PROPERTY(int count READ count NOTIFY countChanged)
Q_PROPERTY(QObject *source READ source WRITE setSource)
Q_PROPERTY(QByteArray sortRole READ sortRole WRITE setSortRole)
Q_PROPERTY(Qt::SortOrder sortOrder READ sortOrder WRITE setSortOrder)
Q_PROPERTY(QByteArray filterRole READ filterRole WRITE setFilterRole)
Q_PROPERTY(QString filterString READ filterString WRITE setFilterString)
Q_PROPERTY(FilterSyntax filterSyntax READ filterSyntax WRITE setFilterSyntax)
Q_ENUMS(FilterSyntax)
public:
explicit SortFilterProxyModel(QObject *parent = 0);
QObject *source() const;
void setSource(QObject *source);
QByteArray sortRole() const;
void setSortRole(const QByteArray &role);
void setSortOrder(Qt::SortOrder order);
QByteArray filterRole() const;
void setFilterRole(const QByteArray &role);
QString filterString() const;
void setFilterString(const QString &filter);
enum FilterSyntax {
RegExp,
Wildcard,
FixedString
};
FilterSyntax filterSyntax() const;
void setFilterSyntax(FilterSyntax syntax);
int count() const;
Q_INVOKABLE QJSValue get(int index) const;
signals:
void countChanged();
protected:
int roleKey(const QByteArray &role) const;
QHash<int, QByteArray> roleNames() const;
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
};
}
}
#endif // SORTFILTERPROXYMODEL_H
Loading…
Cancel
Save