Rev 101 | Blame | Last modification | View Log | RSS feed
/*
* Copyright (C) 2020 to 2022 by Andreas Theofilu <andreas@theosys.at>
*
* 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, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <QTextObject>
#include <QLabel>
#include <QImage>
#include <QWidget>
#include <QPropertyAnimation>
#include <QtMultimedia/QMediaPlayer>
#include <QtMultimediaWidgets/QVideoWidget>
#include "tobject.h"
#include "terror.h"
using std::string;
std::mutex mutex_obj;
TObject::TObject()
{
DECL_TRACER("TObject::TObject()");
}
TObject::~TObject()
{
DECL_TRACER("TObject::~TObject()");
clear();
}
void TObject::clear(bool force)
{
DECL_TRACER("TObject::clear()");
OBJECT_t *obj = mObject;
while (obj)
{
OBJECT_t *next = obj->next;
if (!force)
dropContent(obj);
delete obj;
obj = next;
}
mObject = nullptr;
}
void TObject::dropContent(OBJECT_t* obj)
{
DECL_TRACER("TObject::dropContent(OBJECT_t* obj)");
mutex_obj.lock();
try
{
switch (obj->type)
{
case OBJ_TEXT:
case OBJ_INPUT:
if (obj->object.multitext)
{
obj->object.multitext = nullptr;
}
if (obj->object.linetext)
obj->object.linetext = nullptr;
obj->wid = 0;
break;
case OBJ_BUTTON:
if (obj->object.label)
{
obj->object.label = nullptr;
}
break;
case OBJ_PAGE:
case OBJ_SUBPAGE:
if (obj->object.widget)
{
delete obj->object.widget;
obj->object.widget = nullptr;
}
break;
case OBJ_VIDEO:
if (obj->object.vwidget)
{
delete obj->object.vwidget;
if (obj->player)
delete obj->player;
obj->object.vwidget = nullptr;
obj->player = nullptr;
}
default:
break;
}
}
catch (std::exception& e)
{
MSG_ERROR("Error freeing an object: " << e.what());
}
mutex_obj.unlock();
}
TObject::OBJECT_t *TObject::addObject()
{
DECL_TRACER("TObject::addObject()");
mutex_obj.lock();
OBJECT_t *obj = new OBJECT_t;
obj->next = nullptr;
obj->object.vwidget = nullptr;
obj->player = nullptr;
obj->object.label = nullptr;
obj->object.multitext = nullptr;
obj->object.linetext = nullptr;
obj->object.widget = nullptr;
if (!mObject)
mObject = obj;
else
{
OBJECT_t *p = mObject;
while (p->next)
p = p->next;
p->next = obj;
}
mutex_obj.unlock();
return obj;
}
TObject::OBJECT_t *TObject::findObject(ulong handle)
{
DECL_TRACER("TObject::findObject(ulong handle)");
OBJECT_t *obj = mObject;
while (obj)
{
if (obj->handle == handle)
return obj;
obj = obj->next;
}
return nullptr;
}
TObject::OBJECT_t * TObject::findObject(WId id)
{
DECL_TRACER("TObject::findObject(WId id)");
OBJECT_t *obj = mObject;
while (obj)
{
if (obj->wid == id)
return obj;
obj = obj->next;
}
return nullptr;
}
TObject::OBJECT_t *TObject::findFirstChild(ulong handle)
{
DECL_TRACER("TObject::findFirstChild(ulong handle)");
OBJECT_t *obj = mObject;
while (obj)
{
if (obj->handle != (handle & 0xffff0000) && (obj->handle & 0xffff0000) == (handle & 0xffff0000))
return obj;
obj = obj->next;
}
return nullptr;
}
TObject::OBJECT_t *TObject::findNextChild(ulong handle)
{
DECL_TRACER("TObject::findNextChild(ulong handle)");
OBJECT_t *obj = mObject;
bool next = false;
while (obj)
{
if (next && (obj->handle & 0xffff0000) == (handle & 0xffff0000))
return obj;
if (obj->handle == handle)
next = true;
obj = obj->next;
}
return nullptr;
}
TObject::OBJECT_t * TObject::getMarkedRemove()
{
DECL_TRACER("TObject::getMarkedRemove()");
OBJECT_t *obj = mObject;
while (obj)
{
if (obj->remove)
return obj;
obj = obj->next;
}
return nullptr;
}
TObject::OBJECT_t * TObject::getNextMarkedRemove(TObject::OBJECT_t* object)
{
DECL_TRACER("TObject::getNextMarkedRemove(TObject::OBJECT_t* obj)");
OBJECT_t *obj = nullptr;
if (!object || !object->next)
return nullptr;
obj = object->next;
while (obj)
{
if (obj->remove)
return obj;
obj = obj->next;
}
return nullptr;
}
void TObject::removeObject(ulong handle)
{
DECL_TRACER("TObject::removeObject(ulong handle)");
mutex_obj.lock();
OBJECT_t *obj = mObject;
OBJECT_t *prev = nullptr;
while (obj)
{
if (obj->handle == handle)
{
if (!prev)
{
mObject = obj->next;
delete obj;
}
else
{
prev->next = obj->next;
delete obj;
}
mutex_obj.unlock();
return;
}
prev = obj;
obj = obj->next;
}
mutex_obj.unlock();
}
void TObject::removeAllChilds(ulong handle)
{
DECL_TRACER("TObject::removeAllChilds(ulong handle)");
mutex_obj.lock();
OBJECT_t *obj = mObject;
OBJECT_t *prev = nullptr;
while (obj)
{
if ((obj->handle & 0xffff0000) == (handle & 0xffff0000) && obj->handle != (handle & 0xffff0000))
{
if (!prev)
{
mObject = obj->next;
delete obj;
obj = mObject;
continue;
}
else
{
prev->next = obj->next;
delete obj;
obj = prev;
}
}
prev = obj;
obj = obj->next;
}
mutex_obj.unlock();
}
void TObject::cleanMarked()
{
DECL_TRACER("TObject::cleanMarked()");
mutex_obj.lock();
OBJECT_t *obj = mObject;
OBJECT_t *prev = nullptr;
while (obj)
{
if (obj->remove && (!obj->animation || obj->animation->state() != QAbstractAnimation::Running))
{
if (obj->type == OBJ_SUBPAGE && obj->object.widget)
delete obj->object.widget;
if (!prev)
{
mObject = obj->next;
delete obj;
obj = mObject;
continue;
}
else
{
prev->next = obj->next;
delete obj;
obj = prev;
}
}
prev = obj;
obj = obj->next;
}
mutex_obj.unlock();
}
string TObject::objectToString(TObject::OBJECT_TYPE o)
{
switch(o)
{
case OBJ_BUTTON: return "BUTTON"; break;
case OBJ_INPUT: return "INPUT"; break;
case OBJ_NONE: return "undefined"; break;
case OBJ_PAGE: return "PAGE"; break;
case OBJ_SUBPAGE: return "SUBPAGE"; break;
case OBJ_TEXT: return "TEXT"; break;
case OBJ_VIDEO: return "VIDEO"; break;
}
return string(); // Should not happen but is needed to satisfy the compiler.
}