#include "status_info.h" #include "src/list_item.h" #include #include #include StatusInfoWidget::StatusInfoWidget(QWidget* parent) : QWidget(parent), ui(new Ui::StatusInfo) { ui->setupUi(this); // QGridLayouts have margins around each element, but here we already have margins outside of the element, so these ones are not welcome ui->gridLayout->setContentsMargins(0, 0, 0, 0); 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); }