1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-07-03 23:50:33 +02:00

Create new ItemList component

This commit is contained in:
Laurent Cozic
2017-02-05 17:57:04 +00:00
parent 73be4d9527
commit a4116a4bf8
15 changed files with 649 additions and 187 deletions

View File

@ -0,0 +1,118 @@
import QtQuick 2.0
Item {
id: root
signal rowsRequested(int fromRowIndex, int toRowIndex)
property int blabla: 123456;
property variant items: [];
property int itemCount: 0;
property int itemHeight: 0;
function testing() {
console.info("WXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
}
function setItem(index, itemContent) {
if (index < 0 || index >= itemCount) {
console.error("ItemList::setItem: index out of bounds:", index);
return;
}
var item = itemComponent.createObject(scrollArea.contentItem)
item.title = itemContent.title;
item.invalidateDisplay();
if (!itemHeight) {
item.updateDisplay();
itemHeight = item.height;
}
items[index] = item;
this.invalidateDisplay();
}
function setItems(fromIndex, itemContents) {
for (var i = 0; i < itemContents.length; i++) {
setItem(fromIndex + i, itemContents[i]);
}
}
function addItem(title) {
var item = itemComponent.createObject(scrollArea.contentItem)
item.title = title;
item.updateDisplay();
items.push(item);
if (!itemHeight) itemHeight = item.height;
this.invalidateDisplay();
}
function setItemCount(count) {
this.itemCount = count;
this.invalidateDisplay();
}
function invalidateDisplay() {
updateDisplay();
}
function updateDisplay() {
var itemY = 0;
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (item) {
item.y = itemY;
}
itemY += itemHeight
}
scrollArea.contentHeight = itemCount * itemHeight;
// console.info("itemCount itemHeight", this.itemCount, this.itemHeight);
// console.info("scrollArea.contentHeight", scrollArea.contentHeight);
}
Component {
id: itemComponent
Item {
property alias title: label.text
function invalidateDisplay() {
this.updateDisplay();
}
function updateDisplay() {
this.height = label.height
}
Text {
id: label
anchors.left: parent.left
anchors.right: parent.right
verticalAlignment: Text.AlignVCenter
}
}
}
Flickable {
id: scrollArea
anchors.fill: parent
contentWidth: 800
contentHeight: 5000
// Rectangle {
// id: background
// color: "#ffffff"
// border.color: "#0000ff"
// width: 800
// height: 500
// }
}
}

View File

@ -46,7 +46,9 @@ SOURCES += \
filters.cpp \
models/abstractlistmodel.cpp \
cliapplication.cpp \
command.cpp
command.cpp \
itemlistcontroller.cpp \
qmlutils.cpp
RESOURCES += qml.qrc \
database.qrc
@ -85,7 +87,9 @@ HEADERS += \
filters.h \
models/abstractlistmodel.h \
cliapplication.h \
command.h
command.h \
itemlistcontroller.h \
qmlutils.h
defined(JOP_FRONT_END_GUI, var) {
SOURCES += application.cpp

View File

@ -5,132 +5,260 @@ import QtQuick.Layouts 1.0
Item {
property Item appRoot
property alias currentFolderIndex: folderList.currentIndex
property alias currentNoteIndex: noteList.currentIndex
property alias itemList: itemList
function onShown() {}
// Component {
// id: rectangleComponent
// Rectangle { width: 80; height: 50; color: "red" }
// }
function handleAddItem(list) {
list.model.showVirtualItem();
list.startEditing(list.model.rowCount() - 1);
// function createRectangle() {
// var rect = rectangleComponent.createObject(parent);
// rect.x = 200;
// //console.info("aAAAAAAAAAAAAAAAAAAAAAAAA");
// }
ItemList2 {
id: itemList
width: 800
height: 600
}
function handleItemListEditingAccepted(list, index, text) {
if (list.model.virtualItemShown()) {
list.model.hideVirtualItem();
list.model.addData(text)
print("handleItemListEditingAccepted");
list.selectItemById(list.model.lastInsertId());
} else {
list.model.setData(index, text, "title")
}
}
function handleItemListStoppedEditing(list) {
if (list.model.virtualItemShown()) {
list.model.hideVirtualItem();
}
}
function handleItemListAction(list, action) {
if (action === "delete") {
if (list.currentIndex === undefined) return;
list.model.deleteData(list.currentIndex)
}
}
// RowLayout {
// id: layout
// anchors.fill: parent
// spacing: 0
RowLayout {
id: layout
anchors.fill: parent
spacing: 0
// ItemList {
// id: folderList
// model: folderListModel
// Layout.fillWidth: true
// Layout.fillHeight: true
// Layout.minimumWidth: 50
// Layout.preferredWidth: 100
// Layout.maximumWidth: 200
// Layout.minimumHeight: 150
ItemList {
id: folderList
model: folderListModel
Layout.fillWidth: true
Layout.fillHeight: true
Layout.minimumWidth: 50
Layout.preferredWidth: 100
Layout.maximumWidth: 200
Layout.minimumHeight: 150
// onCurrentItemChanged: {
// appRoot.currentFolderChanged()
// }
onCurrentItemChanged: {
appRoot.currentFolderChanged()
}
// onEditingAccepted: function(index, text) {
// handleItemListEditingAccepted(folderList, index, text);
// }
onEditingAccepted: function(index, text) {
handleItemListEditingAccepted(folderList, index, text);
}
// onStoppedEditing: {
// handleItemListStoppedEditing(folderList);
// }
onStoppedEditing: {
handleItemListStoppedEditing(folderList);
}
// onDeleteButtonClicked: {
// handleItemListAction(folderList, "delete");
// }
// }
onDeleteButtonClicked: {
handleItemListAction(folderList, "delete");
}
}
// ItemList {
// id: noteList
// model: noteListModel
// Layout.fillWidth: true
// Layout.fillHeight: true
// Layout.minimumWidth: 100
// Layout.maximumWidth: 200
// Layout.preferredWidth: 200
// Layout.preferredHeight: 100
ItemList {
id: noteList
model: noteListModel
Layout.fillWidth: true
Layout.fillHeight: true
Layout.minimumWidth: 100
Layout.maximumWidth: 200
Layout.preferredWidth: 200
Layout.preferredHeight: 100
// onCurrentItemChanged: {
// appRoot.currentNoteChanged()
// }
onCurrentItemChanged: {
appRoot.currentNoteChanged()
}
// onEditingAccepted: function(index, text) {
// handleItemListEditingAccepted(noteList, index, text);
// }
onEditingAccepted: function(index, text) {
handleItemListEditingAccepted(noteList, index, text);
}
// onStoppedEditing: {
// handleItemListStoppedEditing(noteList);
// }
onStoppedEditing: {
handleItemListStoppedEditing(noteList);
}
// onDeleteButtonClicked: {
// handleItemListAction(noteList, "delete");
// }
// }
onDeleteButtonClicked: {
handleItemListAction(noteList, "delete");
}
}
// NoteEditor {
// id: noteEditor
// model: noteModel
// Layout.fillWidth: true
// Layout.fillHeight: true
// Layout.minimumWidth: 100
// Layout.preferredHeight: 100
// }
NoteEditor {
id: noteEditor
model: noteModel
Layout.fillWidth: true
Layout.fillHeight: true
Layout.minimumWidth: 100
Layout.preferredHeight: 100
}
// }
}
// AddButton {
// id: addButton
// anchors.right: parent.right
// anchors.bottom: parent.bottom
// onAddFolderButtonClicked: handleAddItem(folderList)
// onAddNoteButtonClicked: handleAddItem(noteList)
// }
AddButton {
id: addButton
anchors.right: parent.right
anchors.bottom: parent.bottom
onAddFolderButtonClicked: handleAddItem(folderList)
onAddNoteButtonClicked: handleAddItem(noteList)
}
// Button {
// id: syncButton
// text: "Sync"
// anchors.right: parent.right
// anchors.top: parent.top
// onClicked: appRoot.syncButtonClicked()
// }
Button {
id: syncButton
text: "Sync"
anchors.right: parent.right
anchors.top: parent.top
onClicked: appRoot.syncButtonClicked()
}
Button {
id: logoutButton
text: "Logout"
anchors.right: syncButton.left
anchors.top: parent.top
onClicked: appRoot.logoutClicked()
}
// Button {
// id: logoutButton
// text: "Logout"
// anchors.right: syncButton.left
// anchors.top: parent.top
// onClicked: appRoot.logoutClicked()
// }
}
//import QtQuick 2.7
//import QtQuick.Controls 2.0
//import QtQuick.Layouts 1.0
//Item {
// property Item appRoot
// property alias currentFolderIndex: folderList.currentIndex
// property alias currentNoteIndex: noteList.currentIndex
// function onShown() {}
// function handleAddItem(list) {
// list.model.showVirtualItem();
// list.startEditing(list.model.rowCount() - 1);
// }
// function handleItemListEditingAccepted(list, index, text) {
// if (list.model.virtualItemShown()) {
// list.model.hideVirtualItem();
// list.model.addData(text)
// print("handleItemListEditingAccepted");
// list.selectItemById(list.model.lastInsertId());
// } else {
// list.model.setData(index, text, "title")
// }
// }
// function handleItemListStoppedEditing(list) {
// if (list.model.virtualItemShown()) {
// list.model.hideVirtualItem();
// }
// }
// function handleItemListAction(list, action) {
// if (action === "delete") {
// if (list.currentIndex === undefined) return;
// list.model.deleteData(list.currentIndex)
// }
// }
// RowLayout {
// id: layout
// anchors.fill: parent
// spacing: 0
// ItemList {
// id: folderList
// model: folderListModel
// Layout.fillWidth: true
// Layout.fillHeight: true
// Layout.minimumWidth: 50
// Layout.preferredWidth: 100
// Layout.maximumWidth: 200
// Layout.minimumHeight: 150
// onCurrentItemChanged: {
// appRoot.currentFolderChanged()
// }
// onEditingAccepted: function(index, text) {
// handleItemListEditingAccepted(folderList, index, text);
// }
// onStoppedEditing: {
// handleItemListStoppedEditing(folderList);
// }
// onDeleteButtonClicked: {
// handleItemListAction(folderList, "delete");
// }
// }
// ItemList {
// id: noteList
// model: noteListModel
// Layout.fillWidth: true
// Layout.fillHeight: true
// Layout.minimumWidth: 100
// Layout.maximumWidth: 200
// Layout.preferredWidth: 200
// Layout.preferredHeight: 100
// onCurrentItemChanged: {
// appRoot.currentNoteChanged()
// }
// onEditingAccepted: function(index, text) {
// handleItemListEditingAccepted(noteList, index, text);
// }
// onStoppedEditing: {
// handleItemListStoppedEditing(noteList);
// }
// onDeleteButtonClicked: {
// handleItemListAction(noteList, "delete");
// }
// }
// NoteEditor {
// id: noteEditor
// model: noteModel
// Layout.fillWidth: true
// Layout.fillHeight: true
// Layout.minimumWidth: 100
// Layout.preferredHeight: 100
// }
// }
// AddButton {
// id: addButton
// anchors.right: parent.right
// anchors.bottom: parent.bottom
// onAddFolderButtonClicked: handleAddItem(folderList)
// onAddNoteButtonClicked: handleAddItem(noteList)
// }
// Button {
// id: syncButton
// text: "Sync"
// anchors.right: parent.right
// anchors.top: parent.top
// onClicked: appRoot.syncButtonClicked()
// }
// Button {
// id: logoutButton
// text: "Logout"
// anchors.right: syncButton.left
// anchors.top: parent.top
// onClicked: appRoot.logoutClicked()
// }
//}

View File

@ -7,89 +7,122 @@ Item {
id: root
width: 800
height: 600
signal currentFolderChanged()
signal currentNoteChanged()
signal addNoteButtonClicked()
signal addFolderButtonClicked()
signal syncButtonClicked()
signal loginButtonClicked()
signal loginClicked(string apiBaseUrl, string email, string password)
signal loginStarted()
signal loginFailed()
signal loginSuccess()
signal logoutClicked()
property alias currentFolderIndex: mainPage.currentFolderIndex
property alias currentNoteIndex: mainPage.currentNoteIndex
property var pages : ({})
property alias itemList : mainPage.itemList
function pageByName(pageName) {
if (root.pages[pageName]) return root.pages[pageName];
function testing() {
var itemList = mainPage.itemList;
itemList.setItemCount(100);
var page = null;
if (pageName === "main") {
page = mainPage
} else if (pageName === "login") {
var s = '
LoginPage {
id: loginPage
anchors.fill: parent
visible: false
appRoot: root
}';
page = Qt.createQmlObject(s, root);
var items = [];
for (var i = 0; i < 100; i++) {
items.push({ title: "Item " + i });
}
root.pages[pageName] = page;
return page;
}
function showPage(pageName) {
for (var n in root.pages) {
root.pages[n].visible = false;
}
print("Switching to page: " + pageName);
var page = pageByName(pageName);
page.visible = true;
page.onShown();
}
function selectFolderbyId(id) {
mainPage.folderList.selectItemById(id);
}
function selectNoteById(id) {
mainPage.noteList.selectItemById(id);
}
function emitLoginStarted() {
root.loginStarted();
}
function emitLoginFailed() {
root.loginFailed();
}
function emitLoginSuccess() {
root.loginSuccess();
}
function emitLoginClicked(apiBaseUrl, email, password) {
root.loginClicked(apiBaseUrl, email, password);
}
function emitLogoutClicked() {
root.logoutClicked();
itemList.setItems(0, items);
}
MainPage {
id: mainPage
anchors.fill: parent
appRoot: root
visible: false
}
}
//import QtQuick 2.7
//import QtQuick.Controls 2.0
//import QtQuick.Controls 1.4
//import QtQuick.Layouts 1.0
//Item {
// id: root
// width: 800
// height: 600
// signal currentFolderChanged()
// signal currentNoteChanged()
// signal addNoteButtonClicked()
// signal addFolderButtonClicked()
// signal syncButtonClicked()
// signal loginButtonClicked()
// signal loginClicked(string apiBaseUrl, string email, string password)
// signal loginStarted()
// signal loginFailed()
// signal loginSuccess()
// signal logoutClicked()
// property alias currentFolderIndex: mainPage.currentFolderIndex
// property alias currentNoteIndex: mainPage.currentNoteIndex
// property var pages : ({})
// function pageByName(pageName) {
// if (root.pages[pageName]) return root.pages[pageName];
// var page = null;
// if (pageName === "main") {
// page = mainPage
// } else if (pageName === "login") {
// var s = '
// LoginPage {
// id: loginPage
// anchors.fill: parent
// visible: false
// appRoot: root
// }';
// page = Qt.createQmlObject(s, root);
// }
// root.pages[pageName] = page;
// return page;
// }
// function showPage(pageName) {
// for (var n in root.pages) {
// root.pages[n].visible = false;
// }
// print("Switching to page: " + pageName);
// var page = pageByName(pageName);
// page.visible = true;
// page.onShown();
// }
// function selectFolderbyId(id) {
// mainPage.folderList.selectItemById(id);
// }
// function selectNoteById(id) {
// mainPage.noteList.selectItemById(id);
// }
// function emitLoginStarted() {
// root.loginStarted();
// }
// function emitLoginFailed() {
// root.loginFailed();
// }
// function emitLoginSuccess() {
// root.loginSuccess();
// }
// function emitLoginClicked(apiBaseUrl, email, password) {
// root.loginClicked(apiBaseUrl, email, password);
// }
// function emitLogoutClicked() {
// root.logoutClicked();
// }
// MainPage {
// id: mainPage
// anchors.fill: parent
// appRoot: root
// visible: false
// }
//}

View File

@ -12,6 +12,10 @@
#include "constants.h"
#include "filters.h"
#include "qmlutils.h"
using namespace jop;
Application::Application(int &argc, char **argv) :
@ -56,13 +60,28 @@ Application::Application(int &argc, char **argv) :
QObject* rootObject = (QObject*)view_.rootObject();
connect(rootObject, SIGNAL(currentFolderChanged()), this, SLOT(view_currentFolderChanged()));
connect(rootObject, SIGNAL(currentNoteChanged()), this, SLOT(view_currentNoteChanged()));
connect(rootObject, SIGNAL(addFolderButtonClicked()), this, SLOT(view_addFolderButtonClicked()));
connect(rootObject, SIGNAL(addNoteButtonClicked()), this, SLOT(view_addNoteButtonClicked()));
connect(rootObject, SIGNAL(syncButtonClicked()), this, SLOT(view_syncButtonClicked()));
connect(rootObject, SIGNAL(loginClicked(QString,QString,QString)), this, SLOT(dispatcher_loginClicked(QString,QString,QString)));
connect(rootObject, SIGNAL(logoutClicked()), this, SLOT(dispatcher_logoutClicked()));
QObject* itemList = qmlUtils::childFromProperty(rootObject, "itemList");
qmlUtils::callQml(itemList, "testing");
//qDebug() << itemList;
// QObject* itemList = rootObject->findChild<QObject*>("itemList");
// qDebug() << "WWWWWWWWWW" << itemList;
//view_.callQml("testing");
// connect(rootObject, SIGNAL(currentFolderChanged()), this, SLOT(view_currentFolderChanged()));
// connect(rootObject, SIGNAL(currentNoteChanged()), this, SLOT(view_currentNoteChanged()));
// connect(rootObject, SIGNAL(addFolderButtonClicked()), this, SLOT(view_addFolderButtonClicked()));
// connect(rootObject, SIGNAL(addNoteButtonClicked()), this, SLOT(view_addNoteButtonClicked()));
// connect(rootObject, SIGNAL(syncButtonClicked()), this, SLOT(view_syncButtonClicked()));
// connect(rootObject, SIGNAL(loginClicked(QString,QString,QString)), this, SLOT(dispatcher_loginClicked(QString,QString,QString)));
// connect(rootObject, SIGNAL(logoutClicked()), this, SLOT(dispatcher_logoutClicked()));
view_.show();

View File

@ -0,0 +1,46 @@
#include "itemlist2.h"
ItemList2::ItemList2(QObject *parent)
: QAbstractItemModel(parent)
{
}
QVariant ItemList2::headerData(int section, Qt::Orientation orientation, int role) const
{
// FIXME: Implement me!
}
QModelIndex ItemList2::index(int row, int column, const QModelIndex &parent) const
{
// FIXME: Implement me!
}
QModelIndex ItemList2::parent(const QModelIndex &index) const
{
// FIXME: Implement me!
}
int ItemList2::rowCount(const QModelIndex &parent) const
{
if (!parent.isValid())
return 0;
// FIXME: Implement me!
}
int ItemList2::columnCount(const QModelIndex &parent) const
{
if (!parent.isValid())
return 0;
// FIXME: Implement me!
}
QVariant ItemList2::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
// FIXME: Implement me!
return QVariant();
}

View File

@ -0,0 +1,29 @@
#ifndef ITEMLIST2_H
#define ITEMLIST2_H
#include <QAbstractItemModel>
class ItemList2 : public QAbstractItemModel
{
Q_OBJECT
public:
explicit ItemList2(QObject *parent = 0);
// Header:
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
// Basic functionality:
QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &index) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
private:
};
#endif // ITEMLIST2_H

View File

@ -0,0 +1,10 @@
#include "itemlistcontroller.h"
namespace jop {
ItemListController::ItemListController()
{
}
}

View File

@ -0,0 +1,18 @@
#ifndef ITEMLISTCONTROLLER_H
#define ITEMLISTCONTROLLER_H
#include <stable.h>
namespace jop {
class ItemListController {
public:
ItemListController();
};
}
#endif // ITEMLISTCONTROLLER_H

View File

@ -8,5 +8,6 @@
<file>LoginPage.qml</file>
<file>LoginPageForm.ui.qml</file>
<file>MainPage.qml</file>
<file>ItemList2.qml</file>
</qresource>
</RCC>

View File

@ -0,0 +1,33 @@
#include "qmlutils.h"
namespace jop {
namespace qmlUtils {
QVariant callQml(QObject* o, const QString &name, const QVariantList &args) {
QVariant returnedValue;
qDebug() << "Going to call QML:" << name << args;
if (args.size() == 0) {
QMetaObject::invokeMethod(o, name.toStdString().c_str(), Q_RETURN_ARG(QVariant, returnedValue));
} else if (args.size() == 1) {
QMetaObject::invokeMethod(o, name.toStdString().c_str(), Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant, args[0]));
} else if (args.size() == 2) {
QMetaObject::invokeMethod(o, name.toStdString().c_str(), Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant, args[0]), Q_ARG(QVariant, args[1]));
} else if (args.size() == 3) {
QMetaObject::invokeMethod(o, name.toStdString().c_str(), Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant, args[0]), Q_ARG(QVariant, args[1]), Q_ARG(QVariant, args[2]));
} else {
qFatal("qmlUtils::callQml: add support for more args!");
}
return returnedValue;
}
QObject* childFromProperty(QObject *o, const QString &propertyName) {
QVariant p = QQmlProperty(o, propertyName).read();
if (!p.isValid()) {
qCritical() << "Invalid QML property" << propertyName;
return NULL;
}
return qvariant_cast<QObject*>(p);
}
}
}

View File

@ -0,0 +1,15 @@
#ifndef QMLUTILS_H
#define QMLUTILS_H
#include <stable.h>
namespace jop {
namespace qmlUtils {
QVariant callQml(QObject* o, const QString &name, const QVariantList &args = QVariantList());
QObject* childFromProperty(QObject* o, const QString& propertyName);
}
}
#endif // QMLUTILS_H

View File

@ -35,6 +35,7 @@
#include <QDir>
#include <QCommandLineParser>
#include <QProcess>
#include <QQmlProperty>
#endif // __cplusplus

View File

@ -5,6 +5,9 @@ using namespace jop;
Window::Window() : QQuickView() {}
void Window::showPage(const QString &pageName) {
qWarning() << "Window::showPage() disabled";
return;
QVariant pageNameV(pageName);
QVariant returnedValue;
QMetaObject::invokeMethod((QObject*)rootObject(), "showPage", Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant, pageNameV));

View File

@ -22,6 +22,10 @@
"name": "Build evernote-import",
"shell_cmd": "D:\\Programmes\\cygwin\\bin\\bash.exe --login D:\\Web\\www\\joplin\\QtClient\\evernote-import\\build.sh"
},
{
"name": "Qt Creator - Build and run",
"shell_cmd": "D:\\NonPortableApps\\AutoHotkey\\AutoHotkey.exe D:\\Docs\\PROGS\\AutoHotKey\\QtRun\\QtRun.ahk"
},
{
"name": "Build QtClient CLI - Linux",
"shell_cmd": "/home/laurent/src/notes/QtClient/JoplinQtClient/build.sh"