diff --git a/main.cpp b/main.cpp
index ee65d0a..4c4b3ea 100644
--- a/main.cpp
+++ b/main.cpp
@@ -77,11 +77,6 @@ int main(int argc, char *argv[])
new Shared::Global(); //translates enums
- // QtQuickControls2 Style
- if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE")) {
- qputenv("QT_QUICK_CONTROLS_STYLE", "Material");
- }
-
Squawk w;
w.show();
diff --git a/resources/qml/feed.qml b/resources/qml/feed.qml
deleted file mode 100644
index 3fc0ba8..0000000
--- a/resources/qml/feed.qml
+++ /dev/null
@@ -1,79 +0,0 @@
-import QtQuick 2.14
-import QtQuick.Controls 2.14
-import QtQuick.Layouts 1.14
-
-ListView {
- id: list
- verticalLayoutDirection: ListView.BottomToTop
-
- required model
-
- delegate: RowLayout {
- id: root
- width: ListView.view.width
-
- // placeholder
- Item {
- Layout.preferredWidth: root.layoutDirection === Qt.LeftToRight ? 5 : 10
- }
-
-// Avatar {
-// id: avatar
-// visible: !sentByMe
-// avatarUrl: root.avatarUrl
-// Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
-// name: root.senderName
-// Layout.preferredHeight: Kirigami.Units.gridUnit * 2.2
-// Layout.preferredWidth: Kirigami.Units.gridUnit * 2.2
-// }
-
- Item {
- Layout.preferredWidth: content.width + 16
- Layout.preferredHeight: content.height + 16
-
- Rectangle {
- id: messageBubble
- anchors.fill: parent
-
- color: "blue"
- }
-
- ColumnLayout {
- id: content
- spacing: 5
- anchors.centerIn: parent
-
- Label {
- text: model.sender
- }
-
- Label {
- text: model.text
- wrapMode: Text.Wrap
- Layout.maximumWidth: root.width
- }
-
- // message meta data: date, deliveryState
- RowLayout {
- Layout.bottomMargin: -4
-
- Label {
- id: dateLabel
- text: model.date
- }
-
-// Icon {
-// source: "edit-symbolic"
-// visible: model.correction
-// Layout.preferredHeight: 10
-// Layout.preferredWidth: 10
-// }
- }
- }
- }
-
- Item {
- Layout.fillWidth: true
- }
- }
-}
diff --git a/resources/resources.qrc b/resources/resources.qrc
index 179b251..4fb3e5b 100644
--- a/resources/resources.qrc
+++ b/resources/resources.qrc
@@ -160,7 +160,5 @@
images/fallback/light/small/favorite.svg
images/fallback/light/small/unfavorite.svg
images/fallback/light/small/add.svg
-
- qml/feed.qml
diff --git a/ui/CMakeLists.txt b/ui/CMakeLists.txt
index 4fada80..23f5f39 100644
--- a/ui/CMakeLists.txt
+++ b/ui/CMakeLists.txt
@@ -39,6 +39,7 @@ set(squawkUI_SRC
utils/progress.cpp
utils/comboboxdelegate.cpp
utils/dropshadoweffect.cpp
+ utils/feedview.cpp
)
# Tell CMake to create the helloworld executable
diff --git a/ui/models/messagefeed.cpp b/ui/models/messagefeed.cpp
index a097693..f7e6b4b 100644
--- a/ui/models/messagefeed.cpp
+++ b/ui/models/messagefeed.cpp
@@ -85,6 +85,7 @@ QVariant MessageFeed::data(const QModelIndex& index, int role) const
const Shared::Message* msg = *itr;
switch (role) {
+ case Qt::DisplayRole:
case Text:
answer = msg->getBody();
break;
@@ -108,6 +109,7 @@ QVariant MessageFeed::data(const QModelIndex& index, int role) const
}
} else {
switch (role) {
+ case Qt::DisplayRole:
case Text:
answer = "loading...";
break;
diff --git a/ui/utils/feedview.cpp b/ui/utils/feedview.cpp
new file mode 100644
index 0000000..fa2adbb
--- /dev/null
+++ b/ui/utils/feedview.cpp
@@ -0,0 +1,125 @@
+/*
+ * Squawk messenger.
+ * Copyright (C) 2019 Yury Gubich
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "feedview.h"
+
+#include
+#include
+#include
+
+FeedView::FeedView(QWidget* parent):
+ QAbstractItemView(parent),
+ hints()
+{
+
+}
+
+FeedView::~FeedView()
+{
+}
+
+QModelIndex FeedView::indexAt(const QPoint& point) const
+{
+ return QModelIndex();
+}
+
+void FeedView::scrollTo(const QModelIndex& index, QAbstractItemView::ScrollHint hint)
+{
+}
+
+QRect FeedView::visualRect(const QModelIndex& index) const
+{
+ if (!index.isValid() || index.row() >= hints.size()) {
+ return QRect();
+ } else {
+ const Hint& hint = hints.at(index.row());
+ const QWidget* vp = viewport();
+ return QRect(0, vp->height() - hint.height - hint.offset, vp->width(), hint.height);
+ }
+}
+
+int FeedView::horizontalOffset() const
+{
+ return 0;
+}
+
+bool FeedView::isIndexHidden(const QModelIndex& index) const
+{
+ return true;
+}
+
+QModelIndex FeedView::moveCursor(QAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers modifiers)
+{
+ return QModelIndex();
+}
+
+void FeedView::setSelection(const QRect& rect, QItemSelectionModel::SelectionFlags command)
+{
+}
+
+int FeedView::verticalOffset() const
+{
+ return 0;
+}
+
+QRegion FeedView::visualRegionForSelection(const QItemSelection& selection) const
+{
+ return QRegion();
+}
+
+void FeedView::rowsInserted(const QModelIndex& parent, int start, int end)
+{
+ scheduleDelayedItemsLayout();
+ QAbstractItemView::rowsInserted(parent, start, end);
+}
+
+void FeedView::updateGeometries()
+{
+ qDebug() << "updateGeometries";
+ QAbstractItemView::updateGeometries();
+ const QAbstractItemModel* m = model();
+ QStyleOptionViewItem option = viewOptions();
+ uint32_t previousOffset = 0;
+
+ hints.clear();
+ for (int i = 0, size = m->rowCount(); i < size; ++i) {
+ QModelIndex index = m->index(i, 0, QModelIndex());
+ int height = itemDelegate(index)->sizeHint(option, index).height();
+ hints.emplace_back(Hint({
+ false,
+ previousOffset,
+ static_cast(height)
+ }));
+ previousOffset += height;
+ }
+}
+
+void FeedView::paintEvent(QPaintEvent* event)
+{
+ qDebug() << "paint";
+ const QAbstractItemModel* m = model();
+ QRect zone = event->rect().translated(horizontalOffset(), -verticalOffset());
+ QPainter painter(viewport());
+ QStyleOptionViewItem option = viewOptions();
+
+ for (int i = 0, size = m->rowCount(); i < size; ++i) {
+ QModelIndex index = m->index(i, 0, QModelIndex());
+ option.rect = visualRect(index);
+ itemDelegate(index)->paint(&painter, option, index);
+ }
+}
diff --git a/ui/utils/feedview.h b/ui/utils/feedview.h
new file mode 100644
index 0000000..8cba4f7
--- /dev/null
+++ b/ui/utils/feedview.h
@@ -0,0 +1,65 @@
+/*
+ * Squawk messenger.
+ * Copyright (C) 2019 Yury Gubich
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef FEEDVIEW_H
+#define FEEDVIEW_H
+
+#include
+
+#include
+
+#include
+
+/**
+ * @todo write docs
+ */
+class FeedView : public QAbstractItemView
+{
+ Q_OBJECT
+public:
+ FeedView(QWidget* parent = nullptr);
+ ~FeedView();
+
+ QModelIndex indexAt(const QPoint & point) const override;
+ void scrollTo(const QModelIndex & index, QAbstractItemView::ScrollHint hint) override;
+ QRect visualRect(const QModelIndex & index) const override;
+ bool isIndexHidden(const QModelIndex & index) const override;
+ QModelIndex moveCursor(QAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers modifiers) override;
+ void setSelection(const QRect & rect, QItemSelectionModel::SelectionFlags command) override;
+ QRegion visualRegionForSelection(const QItemSelection & selection) const override;
+
+protected slots:
+ void rowsInserted(const QModelIndex & parent, int start, int end) override;
+
+protected:
+ int verticalOffset() const override;
+ int horizontalOffset() const override;
+ void paintEvent(QPaintEvent * event) override;
+ void updateGeometries() override;
+
+private:
+ struct Hint {
+ bool dirty;
+ uint32_t offset;
+ uint32_t height;
+ };
+ std::deque hints;
+
+};
+
+#endif //FEEDVIEW_H
diff --git a/ui/widgets/CMakeLists.txt b/ui/widgets/CMakeLists.txt
index 0932100..0a21f04 100644
--- a/ui/widgets/CMakeLists.txt
+++ b/ui/widgets/CMakeLists.txt
@@ -7,7 +7,7 @@ set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
# Find the QtWidgets library
-find_package(Qt5Widgets CONFIG REQUIRED COMPONENTS Widgets Quick Qml QuickControls2 Core)
+find_package(Qt5Widgets CONFIG REQUIRED COMPONENTS Widgets Core)
add_subdirectory(vcard)
@@ -26,7 +26,5 @@ add_library(squawkWidgets ${squawkWidgets_SRC})
# Use the Widgets module from Qt 5.
target_link_libraries(squawkWidgets vCardUI)
target_link_libraries(squawkWidgets Qt5::Widgets)
-target_link_libraries(squawkWidgets Qt5::Qml)
-target_link_libraries(squawkWidgets Qt5::QuickControls2)
-qt5_use_modules(squawkWidgets Quick Qml QuickControls2 Core Widgets)
+qt5_use_modules(squawkWidgets Core Widgets)
diff --git a/ui/widgets/conversation.cpp b/ui/widgets/conversation.cpp
index 6643865..0326ed2 100644
--- a/ui/widgets/conversation.cpp
+++ b/ui/widgets/conversation.cpp
@@ -45,7 +45,7 @@ Conversation::Conversation(bool muc, Models::Account* acc, Models::Element* el,
filesLayout(0),
overlay(new QWidget()),
filesToAttach(),
- feed(new QQuickView()),
+ feed(new FeedView()),
scroll(down),
manualSliderChange(false),
requestingHistory(false),
@@ -54,13 +54,8 @@ Conversation::Conversation(bool muc, Models::Account* acc, Models::Element* el,
{
m_ui->setupUi(this);
- feed->setColor(QWidget::palette().color(QPalette::Base));
- feed->setInitialProperties({{"model", QVariant::fromValue(el->feed)}});
- feed->setResizeMode(QQuickView::SizeRootObjectToView);
- feed->setSource(QUrl("qrc:/qml/feed.qml"));
- QWidget *container = QWidget::createWindowContainer(feed, this);
- container->setAutoFillBackground(false);
- m_ui->widget->layout()->addWidget(container);
+ feed->setModel(el->feed);
+ m_ui->widget->layout()->addWidget(feed);
connect(acc, &Models::Account::childChanged, this, &Conversation::onAccountChanged);
diff --git a/ui/widgets/conversation.h b/ui/widgets/conversation.h
index b0e1b79..bc5863e 100644
--- a/ui/widgets/conversation.h
+++ b/ui/widgets/conversation.h
@@ -24,7 +24,6 @@
#include
#include
#include
-#include
#include "shared/message.h"
#include "order.h"
@@ -34,6 +33,7 @@
#include "ui/utils/resizer.h"
#include "ui/utils/flowlayout.h"
#include "ui/utils/badge.h"
+#include "ui/utils/feedview.h"
#include "shared/icons.h"
#include "shared/utils.h"
@@ -146,7 +146,7 @@ protected:
FlowLayout* filesLayout;
QWidget* overlay;
W::Order filesToAttach;
- QQuickView* feed;
+ FeedView* feed;
Scroll scroll;
bool manualSliderChange;
bool requestingHistory;