Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5 andreas 1
/*
101 andreas 2
 * Copyright (C) 2020 to 2022 by Andreas Theofilu <andreas@theosys.at>
5 andreas 3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software Foundation,
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
17
 */
18
 
19
#include <QTextObject>
20
#include <QLabel>
21
#include <QImage>
22
#include <QWidget>
41 andreas 23
#include <QPropertyAnimation>
181 andreas 24
#ifdef QT5_LINUX
21 andreas 25
#include <QtMultimedia/QMediaPlayer>
26
#include <QtMultimediaWidgets/QVideoWidget>
187 andreas 27
#else
28
#include <QTextLayout>
181 andreas 29
#endif
5 andreas 30
#include "tobject.h"
31
#include "terror.h"
32
 
107 andreas 33
using std::string;
34
 
35
std::mutex mutex_obj;
36
 
5 andreas 37
TObject::TObject()
38
{
39
    DECL_TRACER("TObject::TObject()");
40
}
41
 
42
TObject::~TObject()
43
{
44
    DECL_TRACER("TObject::~TObject()");
45
 
89 andreas 46
    clear();
47
}
48
 
49
void TObject::clear(bool force)
50
{
51
    DECL_TRACER("TObject::clear()");
52
 
5 andreas 53
    OBJECT_t *obj = mObject;
54
 
55
    while (obj)
56
    {
57
        OBJECT_t *next = obj->next;
89 andreas 58
 
59
        if (!force)
60
            dropContent(obj);
61
 
5 andreas 62
        delete obj;
63
        obj = next;
64
    }
89 andreas 65
 
66
    mObject = nullptr;
5 andreas 67
}
68
 
198 andreas 69
void TObject::dropContent(OBJECT_t* obj, bool lock)
14 andreas 70
{
198 andreas 71
    DECL_TRACER("TObject::dropContent(OBJECT_t* obj, bool lock)");
14 andreas 72
 
198 andreas 73
    if (lock)
74
        mutex_obj.lock();
107 andreas 75
 
89 andreas 76
    try
14 andreas 77
    {
89 andreas 78
        switch (obj->type)
79
        {
80
            case OBJ_TEXT:
81
            case OBJ_INPUT:
188 andreas 82
                if (obj->object.plaintext)
190 andreas 83
                {
84
                    obj->object.plaintext->close();
188 andreas 85
                    obj->object.plaintext = nullptr;
190 andreas 86
                }
198 andreas 87
 
89 andreas 88
                obj->wid = 0;
89
            break;
51 andreas 90
 
89 andreas 91
            case OBJ_BUTTON:
92
                if (obj->object.label)
93
                    obj->object.label = nullptr;
94
            break;
95
 
185 andreas 96
            // This are the parent widgets (windows) and must be deleted.
97
            // If this widgets are deleted, Qt deletes their children.
89 andreas 98
            case OBJ_PAGE:
99
            case OBJ_SUBPAGE:
100
                if (obj->object.widget)
101
                {
217 andreas 102
                    obj->object.widget->close();        // This deletes all childs and the widget itself
89 andreas 103
                    obj->object.widget = nullptr;
96 andreas 104
                }
198 andreas 105
            break;
14 andreas 106
 
89 andreas 107
            case OBJ_VIDEO:
108
                if (obj->object.vwidget)
109
                {
185 andreas 110
#ifdef QT5_LINUX
89 andreas 111
                    if (obj->player)
112
                        delete obj->player;
182 andreas 113
#endif
89 andreas 114
                    obj->object.vwidget = nullptr;
115
                    obj->player = nullptr;
116
                }
200 andreas 117
            break;
21 andreas 118
 
200 andreas 119
            case OBJ_LIST:
120
                if (obj->object.list)
121
                    obj->object.list = nullptr;
122
            break;
123
 
89 andreas 124
            default:
125
                break;
126
        }
14 andreas 127
    }
89 andreas 128
    catch (std::exception& e)
129
    {
130
        MSG_ERROR("Error freeing an object: " << e.what());
131
    }
107 andreas 132
 
198 andreas 133
    if (lock)
134
        mutex_obj.unlock();
14 andreas 135
}
136
 
5 andreas 137
TObject::OBJECT_t *TObject::addObject()
138
{
139
    DECL_TRACER("TObject::addObject()");
140
 
107 andreas 141
    mutex_obj.lock();
5 andreas 142
    OBJECT_t *obj = new OBJECT_t;
143
    obj->next = nullptr;
21 andreas 144
    obj->object.vwidget = nullptr;
145
    obj->player = nullptr;
6 andreas 146
    obj->object.label = nullptr;
188 andreas 147
    obj->object.plaintext = nullptr;
6 andreas 148
    obj->object.widget = nullptr;
200 andreas 149
    obj->object.list = nullptr;
5 andreas 150
 
151
    if (!mObject)
152
        mObject = obj;
153
    else
154
    {
155
        OBJECT_t *p = mObject;
156
 
157
        while (p->next)
158
            p = p->next;
159
 
160
        p->next = obj;
161
    }
162
 
107 andreas 163
    mutex_obj.unlock();
5 andreas 164
    return obj;
165
}
166
 
167
TObject::OBJECT_t *TObject::findObject(ulong handle)
168
{
169
    DECL_TRACER("TObject::findObject(ulong handle)");
170
 
171
    OBJECT_t *obj = mObject;
172
 
173
    while (obj)
174
    {
175
        if (obj->handle == handle)
176
            return obj;
177
 
178
        obj = obj->next;
179
    }
180
 
181
    return nullptr;
182
}
183
 
51 andreas 184
TObject::OBJECT_t * TObject::findObject(WId id)
185
{
186
    DECL_TRACER("TObject::findObject(WId id)");
187
 
188
    OBJECT_t *obj = mObject;
189
 
190
    while (obj)
191
    {
192
        if (obj->wid == id)
193
            return obj;
194
 
195
        obj = obj->next;
196
    }
197
 
198
    return nullptr;
199
}
200
 
11 andreas 201
TObject::OBJECT_t *TObject::findFirstChild(ulong handle)
202
{
203
    DECL_TRACER("TObject::findFirstChild(ulong handle)");
204
 
205
    OBJECT_t *obj = mObject;
206
 
207
    while (obj)
208
    {
13 andreas 209
        if (obj->handle != (handle & 0xffff0000) && (obj->handle & 0xffff0000) == (handle & 0xffff0000))
11 andreas 210
            return obj;
211
 
212
        obj = obj->next;
213
    }
214
 
215
    return nullptr;
216
}
217
 
218
TObject::OBJECT_t *TObject::findNextChild(ulong handle)
219
{
220
    DECL_TRACER("TObject::findNextChild(ulong handle)");
221
 
222
    OBJECT_t *obj = mObject;
223
    bool next = false;
224
 
225
    while (obj)
226
    {
227
        if (next && (obj->handle & 0xffff0000) == (handle & 0xffff0000))
228
            return obj;
229
 
230
        if (obj->handle == handle)
231
            next = true;
232
 
233
        obj = obj->next;
234
    }
235
 
236
    return nullptr;
237
}
238
 
42 andreas 239
TObject::OBJECT_t * TObject::getMarkedRemove()
240
{
241
    DECL_TRACER("TObject::getMarkedRemove()");
51 andreas 242
 
42 andreas 243
    OBJECT_t *obj = mObject;
51 andreas 244
 
42 andreas 245
    while (obj)
246
    {
247
        if (obj->remove)
248
            return obj;
51 andreas 249
 
42 andreas 250
        obj = obj->next;
251
    }
51 andreas 252
 
42 andreas 253
    return nullptr;
254
}
255
 
256
TObject::OBJECT_t * TObject::getNextMarkedRemove(TObject::OBJECT_t* object)
257
{
258
    DECL_TRACER("TObject::getNextMarkedRemove(TObject::OBJECT_t* obj)");
51 andreas 259
 
42 andreas 260
    OBJECT_t *obj = nullptr;
51 andreas 261
 
42 andreas 262
    if (!object || !object->next)
263
        return nullptr;
51 andreas 264
 
42 andreas 265
    obj = object->next;
51 andreas 266
 
42 andreas 267
    while (obj)
268
    {
269
        if (obj->remove)
270
            return obj;
51 andreas 271
 
42 andreas 272
        obj = obj->next;
273
    }
51 andreas 274
 
42 andreas 275
    return nullptr;
276
}
277
 
142 andreas 278
TObject::OBJECT_t *TObject::findFirstWindow()
279
{
280
    DECL_TRACER("TObject::getFirstWindow()");
281
 
282
    OBJECT_t *obj = mObject;
283
 
284
    while (obj)
285
    {
286
        if (obj->type == OBJ_SUBPAGE)
287
            return obj;
288
 
289
        obj = obj->next;
290
    }
291
 
292
    return nullptr;
293
}
294
 
295
TObject::OBJECT_t *TObject::findNextWindow(TObject::OBJECT_t *obj)
296
{
297
    DECL_TRACER("TObject::findNextWindow()");
298
 
299
    if (!obj || !obj->next)
300
        return nullptr;
301
 
302
    OBJECT_t *o = obj->next;
303
 
304
    while (o)
305
    {
306
        if (o->type == OBJ_SUBPAGE)
307
            return o;
308
 
309
        o = o->next;
310
    }
311
 
312
    return nullptr;
313
}
314
 
198 andreas 315
void TObject::removeObject(ulong handle, bool drop)
5 andreas 316
{
198 andreas 317
    DECL_TRACER("TObject::removeObject(ulong handle, bool drop)");
5 andreas 318
 
215 andreas 319
    if (!handle)
320
        return;
321
 
107 andreas 322
    mutex_obj.lock();
5 andreas 323
    OBJECT_t *obj = mObject;
324
    OBJECT_t *prev = nullptr;
325
 
326
    while (obj)
327
    {
328
        if (obj->handle == handle)
329
        {
330
            if (!prev)
331
            {
332
                mObject = obj->next;
198 andreas 333
 
334
                if (drop)
335
                    dropContent(obj, false);
336
 
5 andreas 337
                delete obj;
338
            }
339
            else
340
            {
341
                prev->next = obj->next;
198 andreas 342
 
343
                if (drop)
344
                    dropContent(obj, false);
345
 
5 andreas 346
                delete obj;
347
            }
348
 
107 andreas 349
            mutex_obj.unlock();
5 andreas 350
            return;
351
        }
352
 
353
        prev = obj;
354
        obj = obj->next;
355
    }
107 andreas 356
 
357
    mutex_obj.unlock();
5 andreas 358
}
359
 
198 andreas 360
void TObject::removeAllChilds(ulong handle, bool drop)
11 andreas 361
{
198 andreas 362
    DECL_TRACER("TObject::removeAllChilds(ulong handle, bool drop)");
11 andreas 363
 
215 andreas 364
    if (!handle)
365
        return;
366
 
107 andreas 367
    mutex_obj.lock();
14 andreas 368
    OBJECT_t *obj = mObject;
369
    OBJECT_t *prev = nullptr;
11 andreas 370
 
371
    while (obj)
372
    {
14 andreas 373
        if ((obj->handle & 0xffff0000) == (handle & 0xffff0000) && obj->handle != (handle & 0xffff0000))
374
        {
375
            if (!prev)
376
            {
377
                mObject = obj->next;
198 andreas 378
 
379
                if (drop)
380
                    dropContent(obj, false);
381
 
14 andreas 382
                delete obj;
383
                obj = mObject;
384
                continue;
385
            }
386
            else
387
            {
388
                prev->next = obj->next;
198 andreas 389
 
390
                if (drop)
391
                    dropContent(obj, false);
392
 
14 andreas 393
                delete obj;
394
                obj = prev;
395
            }
396
        }
397
 
398
        prev = obj;
399
        obj = obj->next;
11 andreas 400
    }
107 andreas 401
 
402
    mutex_obj.unlock();
11 andreas 403
}
14 andreas 404
 
107 andreas 405
void TObject::cleanMarked()
14 andreas 406
{
107 andreas 407
    DECL_TRACER("TObject::cleanMarked()");
408
 
409
    mutex_obj.lock();
410
    OBJECT_t *obj = mObject;
411
    OBJECT_t *prev = nullptr;
412
 
413
    while (obj)
414
    {
415
        if (obj->remove && (!obj->animation || obj->animation->state() != QAbstractAnimation::Running))
416
        {
417
            if (obj->type == OBJ_SUBPAGE && obj->object.widget)
198 andreas 418
            {
217 andreas 419
                obj->object.widget->close();
198 andreas 420
                obj->object.widget = nullptr;
421
            }
107 andreas 422
 
423
            if (!prev)
424
            {
425
                mObject = obj->next;
426
                delete obj;
427
                obj = mObject;
428
                continue;
429
            }
430
            else
431
            {
432
                prev->next = obj->next;
433
                delete obj;
434
                obj = prev;
435
            }
436
        }
437
 
438
        prev = obj;
439
        obj = obj->next;
440
    }
441
 
442
    mutex_obj.unlock();
443
}
444
 
217 andreas 445
void TObject::invalidateAllObjects()
446
{
447
    DECL_TRACER("TObject::invalidateAllObjects()");
448
 
449
    mutex_obj.lock();
450
    OBJECT_t *obj = mObject;
451
 
452
    while (obj)
453
    {
454
        obj->object.vwidget = nullptr;      // Because it's a union all types will be NULL
455
        obj->remove = true;
456
        obj->animation = nullptr;
457
 
458
        obj = obj->next;
459
    }
460
 
461
    mutex_obj.unlock();
462
}
463
 
464
void TObject::invalidateAllSubObjects(ulong handle)
465
{
466
    DECL_TRACER("::invalidateAllSubObjects(ulong handle)");
467
 
468
    mutex_obj.lock();
469
    OBJECT_t *obj = mObject;
470
 
471
    while (obj)
472
    {
473
        if (obj->handle != handle && (obj->handle & 0xffff0000) == handle)
474
        {
475
            obj->object.vwidget = nullptr;  // Because it's a union all types will be NULL
476
            obj->remove = true;
477
            obj->animation = nullptr;
478
        }
479
 
480
        obj = obj->next;
481
    }
482
 
483
    mutex_obj.unlock();
484
}
485
 
107 andreas 486
string TObject::objectToString(TObject::OBJECT_TYPE o)
487
{
14 andreas 488
    switch(o)
489
    {
490
        case OBJ_BUTTON:  return "BUTTON"; break;
491
        case OBJ_INPUT:   return "INPUT"; break;
492
        case OBJ_NONE:    return "undefined"; break;
493
        case OBJ_PAGE:    return "PAGE"; break;
494
        case OBJ_SUBPAGE: return "SUBPAGE"; break;
495
        case OBJ_TEXT:    return "TEXT"; break;
21 andreas 496
        case OBJ_VIDEO:   return "VIDEO"; break;
200 andreas 497
        case OBJ_LIST:    return "LIST"; break;
14 andreas 498
    }
78 andreas 499
 
107 andreas 500
    return string();   // Should not happen but is needed to satisfy the compiler.
14 andreas 501
}