diff options
Diffstat (limited to 'src/widgets')
-rw-r--r-- | src/widgets/status_info.cpp | 82 | ||||
-rw-r--r-- | src/widgets/status_info.h | 56 | ||||
-rw-r--r-- | src/widgets/status_info.ui | 44 |
3 files changed, 182 insertions, 0 deletions
diff --git a/src/widgets/status_info.cpp b/src/widgets/status_info.cpp new file mode 100644 index 0000000..847aec4 --- /dev/null +++ b/src/widgets/status_info.cpp @@ -0,0 +1,82 @@ +#include "status_info.h" +#include "src/list_item.h" +#include <QTimer> +#include <QDebug> +#include <QCloseEvent> + +StatusInfoWidget::StatusInfoWidget(QWidget* parent) + : QWidget(parent), ui(new Ui::StatusInfo) +{ + ui->setupUi(this); + + worker.moveToThread(&worker_thread); + connect(this, &StatusInfoWidget::do_process_item, &worker, &StatusInfoWidgetWorker::process_item, Qt::QueuedConnection); + connect(this, &StatusInfoWidget::do_process_activity, &worker, &StatusInfoWidgetWorker::process_activity, Qt::QueuedConnection); + connect(&worker, &StatusInfoWidgetWorker::itemProcessed, this, &StatusInfoWidget::postProcess, Qt::QueuedConnection); + worker_thread.start(); + + worker.set_text_zone_width(ui->statusInfoText->width()); +} + +StatusInfoWidget::~StatusInfoWidget() { + worker_thread.quit(); + worker_thread.wait(); + + delete displayed_activity; + delete ui; +} + +void StatusInfoWidget::resizeEvent(QResizeEvent* event) { + // TODO: probably create a template, define or inline function for this + static QTimer* differed_resize = new QTimer(this); + if (static bool timer_init_done = false; not timer_init_done) { + differed_resize->setTimerType(Qt::CoarseTimer); + differed_resize->setSingleShot(true); + differed_resize->setInterval(150); + connect(differed_resize, &QTimer::timeout, this, [=]() { + worker.set_text_zone_width(ui->statusInfoText->width()); + if (displayed_activity) + emit do_process_activity(displayed_activity); + }); + } + differed_resize->start(); + QWidget::resizeEvent(event); +} + +void StatusInfoWidget::show_list_item(StatusListItem* new_item) { + qDebug() << "got item" << new_item << "old is" << displayed_item << displayed_activity; + if (new_item != displayed_item) { + delete displayed_activity; displayed_activity = nullptr; + displayed_item = new_item; + emit do_process_item(new_item); + } +} + +// Update the GUI with the displayed Activity. +// Has to be done on the GUI thread, no other way in Qt +void StatusInfoWidget::postProcess(const QString &html, APActivity* activity) { + // Make sure to not delete the displayed_activity if we are reprocessing it after a resize event, else you get a crash that requires nasty debugging (don't ask how i found out ;) + if (activity != displayed_activity) { + // We are doing "double" deletion of old displayed_activity but sometimes that's important when really scrubbing the search results bar very quickly (we sometimes do reach that code and it hopefully helps against memory leaks) + if (displayed_activity) + delete displayed_activity; + displayed_activity = activity; + } + ui->statusInfoText->setHtml(html); +} + +/* + * ---------------- + * Worker functions. Ran on non-main, non-GUI, thread + * ---------------- + */ + +void StatusInfoWidgetWorker::process_item(StatusListItem* item) { + APActivity* activity = item->get_activity(); + process_activity(activity); +} + +void StatusInfoWidgetWorker::process_activity(APActivity* activity) { + QString html = activity->get_html_render(render_info); + emit itemProcessed(html, activity); +} diff --git a/src/widgets/status_info.h b/src/widgets/status_info.h new file mode 100644 index 0000000..988f930 --- /dev/null +++ b/src/widgets/status_info.h @@ -0,0 +1,56 @@ +#pragma once +#include <QWidget> +#include <QLocale> +#include <QThread> +#include "./ui_status_info.h" +#include "src/activitypub/apactivity.h" +#include "src/activitypub/apbase.h" +#include "src/list_item.h" + +class StatusInfoWidgetWorker : public QObject { + Q_OBJECT + +public slots: + void process_item(StatusListItem* item); + void process_activity(APActivity* activity); + void set_text_zone_width(int width) {render_info.text_zone_width = width;} + +signals: + void itemProcessed(const QString &html, APActivity* activity = nullptr); + +private: + QLocale locale_context; + HtmlRenderDetails render_info = {0, &locale_context}; +}; + +QT_BEGIN_NAMESPACE +namespace Ui { class StatusInfo; } +QT_END_NAMESPACE + +class StatusInfoWidget : public QWidget { + Q_OBJECT + +public: + StatusInfoWidget(QWidget *parent = nullptr); + ~StatusInfoWidget(); + + void resizeEvent(QResizeEvent* event); + +public slots: + void show_list_item(StatusListItem* status); // Call from GUI thread + void postProcess(const QString &html, APActivity* activity); + +signals: + // These signals are called privetely by StatusInfoWidget + void do_process_item(StatusListItem* item); + void do_process_activity(APActivity* activity); + +private: + Ui::StatusInfo* ui; + QThread worker_thread; + StatusInfoWidgetWorker worker; + + // Used for determining if we are dealing with a new list item or not + StatusListItem* displayed_item = nullptr; + APActivity* displayed_activity = nullptr; +}; diff --git a/src/widgets/status_info.ui b/src/widgets/status_info.ui new file mode 100644 index 0000000..b8b2586 --- /dev/null +++ b/src/widgets/status_info.ui @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>StatusInfo</class> + <widget class="QWidget" name="StatusInfo"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QTextEdit" name="statusInfoText"> + <property name="cursor" stdset="0"> + <cursorShape>IBeamCursor</cursorShape> + </property> + <property name="undoRedoEnabled"> + <bool>false</bool> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="html"> + <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">Select Status to display from list.</span></p></body></html></string> + </property> + <property name="textInteractionFlags"> + <set>Qt::TextBrowserInteraction</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> |