Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 andreas 1
/*
21 andreas 2
 * Copyright (C) 2020, 2021 by Andreas Theofilu <andreas@theosys.at>
3 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 <vector>
14 andreas 20
#include <thread>
21
#include <mutex>
22
 
3 andreas 23
#include "tpagemanager.h"
4 andreas 24
#include "tcolor.h"
3 andreas 25
#include "terror.h"
8 andreas 26
#include "ticons.h"
14 andreas 27
#include "tbutton.h"
8 andreas 28
#include "tprjresources.h"
11 andreas 29
#include "tresources.h"
3 andreas 30
 
31
using std::vector;
32
using std::string;
11 andreas 33
using std::map;
34
using std::pair;
35
using std::to_string;
14 andreas 36
using std::thread;
37
using std::atomic;
38
using std::mutex;
21 andreas 39
using std::bind;
3 andreas 40
 
8 andreas 41
TIcons *gIcons = nullptr;
42
TPrjResources *gPrjResources = nullptr;
14 andreas 43
TPageManager *gPageManager = nullptr;
21 andreas 44
thread::id gPageManagerId;
14 andreas 45
extern amx::TAmxNet *gAmxNet;
8 andreas 46
 
14 andreas 47
mutex surface_mutex;
21 andreas 48
atomic<bool> runDoCommand;
49
bool prg_stopped = false;
14 andreas 50
 
3 andreas 51
TPageManager::TPageManager()
52
{
14 andreas 53
    surface_mutex.lock();
3 andreas 54
    DECL_TRACER("TPageManager::TPageManager()");
55
 
14 andreas 56
    gPageManager = this;
57
    gPageManagerId = thread::id();
21 andreas 58
    runDoCommand = false;
3 andreas 59
    mTSettings = new TSettings(TConfig::getProjectPath());
60
 
61
    if (TError::isError())
14 andreas 62
    {
63
        surface_mutex.unlock();
3 andreas 64
        return;
14 andreas 65
    }
3 andreas 66
 
8 andreas 67
    gPrjResources = new TPrjResources(mTSettings->getResourcesList());
68
 
4 andreas 69
    mPalette = new TPalette();
70
    vector<PALETTE_SETUP>::iterator iterPal;
71
    vector<PALETTE_SETUP> pal = mTSettings->getSettings().palettes;
72
 
73
    for (iterPal = pal.begin(); iterPal != pal.end(); iterPal++)
74
        mPalette->initialize(iterPal->file);
75
 
76
    if (!TError::isError())
77
        TColor::setPalette(mPalette);
78
 
7 andreas 79
    mFonts = new TFont();
80
 
81
    if (TError::isError())
82
    {
83
        MSG_ERROR("Initializing fonts was not successfull!");
14 andreas 84
        surface_mutex.unlock();
7 andreas 85
        return;
86
    }
87
 
8 andreas 88
    gIcons = new TIcons();
89
 
90
    if (TError::isError())
91
    {
92
        MSG_ERROR("Initializing icons was not successfull!");
14 andreas 93
        surface_mutex.unlock();
8 andreas 94
        return;
95
    }
96
 
3 andreas 97
    mPageList = new TPageList();
98
 
99
    if (TError::isError())
14 andreas 100
    {
101
        surface_mutex.unlock();
3 andreas 102
        return;
14 andreas 103
    }
3 andreas 104
 
4 andreas 105
    PAGELIST_T page;
106
 
3 andreas 107
    if (!mTSettings->getSettings().powerUpPage.empty())
108
    {
109
        if (readPage(mTSettings->getSettings().powerUpPage) == false)
14 andreas 110
        {
111
            surface_mutex.unlock();
3 andreas 112
            return;
14 andreas 113
        }
3 andreas 114
 
115
        MSG_TRACE("Found power up page " << mTSettings->getSettings().powerUpPage);
4 andreas 116
        page = findPage(mTSettings->getSettings().powerUpPage);
117
        mActualPage = page.pageID;
3 andreas 118
    }
119
 
4 andreas 120
    TPage *pg = getPage(mActualPage);
121
 
3 andreas 122
    vector<string> popups = mTSettings->getSettings().powerUpPopup;
123
    vector<string>::iterator iter;
124
 
125
    for (iter = popups.begin(); iter != popups.end(); iter++)
126
    {
127
        if (readSubPage(*iter) == false)
14 andreas 128
        {
129
            surface_mutex.unlock();
3 andreas 130
            return;
14 andreas 131
        }
3 andreas 132
 
133
        MSG_TRACE("Found power up popup " << *iter);
4 andreas 134
 
135
        if (pg)
136
        {
137
            TSubPage *spage = getSubPage(*iter);
138
            pg->addSubPage(spage);
139
        }
3 andreas 140
    }
11 andreas 141
 
13 andreas 142
    MSG_INFO("Registering commands ...");
14 andreas 143
    REG_CMD(doAPG, "@APG");
144
    REG_CMD(doCPG, "@CPG");
145
    REG_CMD(doDPG, "@DPG");
15 andreas 146
//    REG_CMD(doPDR, "@PDR");
147
    REG_CMD(doPHE, "@PHE");
148
    REG_CMD(doPHP, "@PHP");
149
    REG_CMD(doPHT, "@PHT");
14 andreas 150
    REG_CMD(doPPA, "@PPA");
151
    REG_CMD(doPPF, "@PPF");
152
    REG_CMD(doPPF, "PPOF");
153
    REG_CMD(doPPG, "@PPG");
154
    REG_CMD(doPPG, "PPOG");
155
    REG_CMD(doPPK, "@PPK");
156
    REG_CMD(doPPM, "@PPM");
157
    REG_CMD(doPPN, "@PPN");
158
    REG_CMD(doPPN, "PPON");
15 andreas 159
    REG_CMD(doPPT, "@PPT");
14 andreas 160
    REG_CMD(doPPX, "@PPX");
15 andreas 161
    REG_CMD(doPSE, "@PSE");
162
    REG_CMD(doPSP, "@PSP");
163
    REG_CMD(doPST, "@PSP");
14 andreas 164
    REG_CMD(doPAGE, "PAGE");
11 andreas 165
 
15 andreas 166
    REG_CMD(doAPF, "^APF");
167
    REG_CMD(doBMP, "^BMP");
16 andreas 168
    REG_CMD(doBOP, "^BOP");
169
    REG_CMD(doBSP, "^BSP");
170
    REG_CMD(doBWW, "^BWW");
171
    REG_CMD(doCPF, "^CPF");
172
    REG_CMD(doDPF, "^DPF");
173
    REG_CMD(doENA, "^ENA");
174
    REG_CMD(doFON, "^FON");
14 andreas 175
    REG_CMD(doICO, "^ICO");
16 andreas 176
    REG_CMD(doSHO, "^SHO");
14 andreas 177
    REG_CMD(doTXT, "^TXT");
178
 
21 andreas 179
    REG_CMD(doBBR, "^BBR");
180
    REG_CMD(doRMF, "^RMF");
181
 
14 andreas 182
    REG_CMD(doON, "ON");
183
    REG_CMD(doOFF, "OFF");
15 andreas 184
    REG_CMD(doLEVEL, "LEVEL");
185
    REG_CMD(doBLINK, "BLINK");
14 andreas 186
 
11 andreas 187
    // Registering callback to receive controller events.
13 andreas 188
    MSG_INFO("Starting communication with controller ...");
11 andreas 189
    mAmxNet = new amx::TAmxNet();
13 andreas 190
    MSG_INFO("Registering callback for received commands ...");
11 andreas 191
    mAmxNet->setCallback(bind(&TPageManager::doCommand, this, std::placeholders::_1));
13 andreas 192
    mAmxNet->setPanelID(TConfig::getChannel());
193
 
11 andreas 194
    try
195
    {
13 andreas 196
        MSG_INFO("Starting thread for communication with controller ...");
11 andreas 197
        mThreadAmxNet = std::thread([=] { mAmxNet->Run(); });
13 andreas 198
        MSG_INFO("Thread started. Detaching ...");
11 andreas 199
        mThreadAmxNet.detach();
13 andreas 200
        MSG_INFO("Thread is running and detached.");
11 andreas 201
    }
202
    catch (std::exception& e)
203
    {
204
        MSG_ERROR("Error starting the AmxNet thread: " << e.what());
205
    }
14 andreas 206
 
207
    surface_mutex.unlock();
3 andreas 208
}
209
 
210
TPageManager::~TPageManager()
211
{
212
    DECL_TRACER("TPageManager::~TPageManager()");
213
 
214
    PCHAIN_T *p = mPchain;
215
    PCHAIN_T *next = nullptr;
216
 
217
    try
218
    {
219
        while (p)
220
        {
221
            next = p->next;
222
 
223
            if (p->page)
224
                delete p->page;
225
 
226
            delete p;
227
            p = next;
228
        }
229
 
230
        SPCHAIN_T *sp = mSPchain;
231
        SPCHAIN_T *snext = nullptr;
232
 
233
        while (sp)
234
        {
235
            snext = sp->next;
236
 
237
            if (sp->page)
238
                delete sp->page;
239
 
240
            delete sp;
5 andreas 241
            sp = snext;
3 andreas 242
        }
243
 
244
        mPchain = nullptr;
245
        mSPchain = nullptr;
14 andreas 246
        setPChain(mPchain);
247
        setSPChain(mSPchain);
3 andreas 248
 
13 andreas 249
        if (mAmxNet)
250
        {
251
            delete mAmxNet;
252
            mAmxNet = nullptr;
253
        }
254
 
3 andreas 255
        if (mTSettings)
256
        {
257
            delete mTSettings;
258
            mTSettings = nullptr;
259
        }
260
 
261
        if (mPageList)
262
        {
263
            delete mPageList;
264
            mPageList = nullptr;
265
        }
5 andreas 266
 
267
        if (mPalette)
268
        {
269
            delete mPalette;
270
            mPalette = nullptr;
271
        }
7 andreas 272
 
273
        if (mFonts)
274
        {
275
            delete mFonts;
276
            mFonts = nullptr;
277
        }
8 andreas 278
 
279
        if (gIcons)
280
        {
281
            delete gIcons;
282
            gIcons = nullptr;
283
        }
284
 
285
        if (gPrjResources)
286
        {
287
            delete gPrjResources;
288
            gPrjResources = nullptr;
289
        }
3 andreas 290
    }
291
    catch (std::exception& e)
292
    {
293
        MSG_ERROR("Memory error: " << e.what());
294
    }
295
}
296
 
11 andreas 297
void TPageManager::initialize()
298
{
299
    DECL_TRACER("TPageManager::initialize()");
300
 
14 andreas 301
    surface_mutex.lock();
11 andreas 302
    dropAllSubPages();
303
    dropAllPages();
304
 
305
    if (mTSettings)
306
        mTSettings->loadSettings();
307
    else
308
        mTSettings = new TSettings(TConfig::getProjectPath());
309
 
310
    if (TError::isError())
14 andreas 311
    {
312
        surface_mutex.unlock();
11 andreas 313
        return;
14 andreas 314
    }
11 andreas 315
 
316
    if (!gPrjResources)
317
        gPrjResources = new TPrjResources(mTSettings->getResourcesList());
318
 
319
    if (!mPalette)
320
        mPalette = new TPalette();
321
    else
322
        mPalette->reset();
323
 
324
    vector<PALETTE_SETUP>::iterator iterPal;
325
    vector<PALETTE_SETUP> pal = mTSettings->getSettings().palettes;
326
 
327
    for (iterPal = pal.begin(); iterPal != pal.end(); iterPal++)
328
        mPalette->initialize(iterPal->file);
329
 
330
    if (!TError::isError())
331
        TColor::setPalette(mPalette);
332
 
333
    if (!mFonts)
334
        mFonts = new TFont();
335
    else
336
        mFonts->initialize();
337
 
338
    if (TError::isError())
339
    {
340
        MSG_ERROR("Initializing fonts was not successfull!");
14 andreas 341
        surface_mutex.unlock();
11 andreas 342
        return;
343
    }
344
 
345
    if (!gIcons)
346
        gIcons = new TIcons();
347
    else
348
        gIcons->initialize();
349
 
350
    if (TError::isError())
351
    {
352
        MSG_ERROR("Initializing icons was not successfull!");
14 andreas 353
        surface_mutex.unlock();
11 andreas 354
        return;
355
    }
356
 
357
    if (!mPageList)
358
        mPageList = new TPageList();
359
    else
360
        mPageList->initialize();
361
 
362
    if (TError::isError())
14 andreas 363
    {
364
        surface_mutex.unlock();
11 andreas 365
        return;
14 andreas 366
    }
11 andreas 367
 
368
    PAGELIST_T page;
369
 
370
    if (!mTSettings->getSettings().powerUpPage.empty())
371
    {
372
        if (readPage(mTSettings->getSettings().powerUpPage) == false)
14 andreas 373
        {
374
            surface_mutex.unlock();
11 andreas 375
            return;
14 andreas 376
        }
11 andreas 377
 
378
        MSG_TRACE("Found power up page " << mTSettings->getSettings().powerUpPage);
379
        page = findPage(mTSettings->getSettings().powerUpPage);
380
        mActualPage = page.pageID;
381
    }
382
 
383
    TPage *pg = getPage(mActualPage);
384
 
385
    vector<string> popups = mTSettings->getSettings().powerUpPopup;
386
    vector<string>::iterator iter;
387
 
388
    for (iter = popups.begin(); iter != popups.end(); iter++)
389
    {
390
        if (readSubPage(*iter) == false)
14 andreas 391
        {
392
            surface_mutex.unlock();
11 andreas 393
            return;
14 andreas 394
        }
11 andreas 395
 
396
        MSG_TRACE("Found power up popup " << *iter);
397
 
398
        if (pg)
399
        {
400
            TSubPage *spage = getSubPage(*iter);
401
            pg->addSubPage(spage);
402
        }
403
    }
404
 
405
    // Start the thread
13 andreas 406
    if (!mAmxNet || !mThreadAmxNet.joinable())
11 andreas 407
    {
13 andreas 408
        try
409
        {
410
            if (!mAmxNet)
411
            {
412
                mAmxNet = new amx::TAmxNet();
413
                mAmxNet->setCallback(bind(&TPageManager::doCommand, this, std::placeholders::_1));
414
            }
14 andreas 415
 
13 andreas 416
            if (!mThreadAmxNet.joinable())
417
            {
418
                MSG_INFO("Starting thread for communication with controller ...");
419
                mThreadAmxNet = std::thread([=] { mAmxNet->Run(); });
420
                MSG_INFO("Thread started. Detaching ...");
421
                mThreadAmxNet.detach();
422
                MSG_INFO("Thread is running and detached.");
423
            }
424
        }
425
        catch (std::exception& e)
426
        {
427
            MSG_ERROR("Error starting the AmxNet thread: " << e.what());
428
        }
11 andreas 429
    }
14 andreas 430
 
431
    surface_mutex.unlock();
11 andreas 432
}
433
 
434
/*
435
 * The following method is called by the class TAmxNet whenever an event from
436
 * the controller occured.
437
 */
438
void TPageManager::doCommand(const amx::ANET_COMMAND& cmd)
439
{
440
    DECL_TRACER("TPageManager::doCommand(const amx::ANET_COMMAND& cmd)");
441
 
442
    mCommands.push_back(cmd);
443
 
444
    if (mBusy)
445
        return;
446
 
447
    mBusy = true;
448
    string com;
449
 
450
    while (mCommands.size() > 0)
451
    {
452
        amx::ANET_COMMAND& bef = mCommands.at(0);
453
        mCommands.erase(mCommands.begin());
454
 
455
        switch (bef.MC)
456
        {
457
            case 0x0006:
458
            case 0x0018:	// feedback channel on
459
                com.assign("ON-");
460
                com.append(to_string(bef.data.chan_state.channel));
461
                parseCommand(bef.device1, bef.data.chan_state.port, com);
14 andreas 462
            break;
11 andreas 463
 
464
            case 0x0007:
465
            case 0x0019:	// feedback channel off
466
                com.assign("OFF-");
467
                com.append(to_string(bef.data.chan_state.channel));
468
                parseCommand(bef.device1, bef.data.chan_state.port, com);
14 andreas 469
            break;
11 andreas 470
 
471
            case 0x000a:	// level value change
472
                com = "LEVEL-";
473
                com += to_string(bef.data.message_value.value);
474
                com += ",";
475
 
476
                switch (bef.data.message_value.type)
477
                {
478
                    case 0x10: com += to_string(bef.data.message_value.content.byte); break;
479
                    case 0x11: com += to_string(bef.data.message_value.content.ch); break;
480
                    case 0x20: com += to_string(bef.data.message_value.content.integer); break;
481
                    case 0x21: com += to_string(bef.data.message_value.content.sinteger); break;
482
                    case 0x40: com += to_string(bef.data.message_value.content.dword); break;
483
                    case 0x41: com += to_string(bef.data.message_value.content.sdword); break;
484
                    case 0x4f: com += to_string(bef.data.message_value.content.fvalue); break;
485
                    case 0x8f: com += to_string(bef.data.message_value.content.dvalue); break;
486
                }
487
 
488
                parseCommand(bef.device1, bef.data.chan_state.port, com);
489
            break;
490
 
491
            case 0x000c:	// Command string
492
            {
493
                amx::ANET_MSG_STRING msg = bef.data.message_string;
494
 
495
                if (msg.length < strlen((char *)&msg.content))
496
                {
497
                    mCmdBuffer.append((char *)&msg.content);
498
                    break;
499
                }
500
                else if (mCmdBuffer.length() > 0)
501
                {
502
                    mCmdBuffer.append((char *)&msg.content);
503
                    size_t len = (mCmdBuffer.length() >= sizeof(msg.content)) ? (sizeof(msg.content)-1) : mCmdBuffer.length();
504
                    strncpy((char *)&msg.content, mCmdBuffer.c_str(), len);
505
                    msg.content[len] = 0;
506
                }
507
 
508
                com.assign(cp1250ToUTF8((char *)&msg.content));
14 andreas 509
                parseCommand( bef.device1, bef.data.chan_state.port, com);
11 andreas 510
                mCmdBuffer.clear();
511
            }
512
            break;
513
 
15 andreas 514
            case 0x0502:    // Blink message (contains date and time)
515
                com = "BLINK-" + to_string(bef.data.blinkMessage.hour) + ":";
516
                com += to_string(bef.data.blinkMessage.minute) + ":";
517
                com += to_string(bef.data.blinkMessage.second) + ",";
518
                com += to_string(bef.data.blinkMessage.year) + "-";
519
                com += to_string(bef.data.blinkMessage.month) + "-";
520
                com += to_string(bef.data.blinkMessage.day) + ",";
521
                com += to_string(bef.data.blinkMessage.weekday) + ",";
522
                com += ((bef.data.blinkMessage.LED & 0x0001) ? "ON" : "OFF");
523
                parseCommand(0, 0, com);
524
            break;
525
 
11 andreas 526
            case 0x1000:	// Filetransfer
527
            {
528
                amx::ANET_FILETRANSFER ftr = bef.data.filetransfer;
529
 
530
                if (ftr.ftype == 0)
531
                {
532
                    switch(ftr.function)
533
                    {
534
                        case 0x0100:	// Syncing directory
535
                            com = "#FTR-SYNC:0:";
536
                            com.append((char*)&ftr.data[0]);
537
                            parseCommand(bef.device1, bef.port1, com);
538
                        break;
539
 
540
                        case 0x0104:	// Delete file
541
                            com = "#FTR-SYNC:"+to_string(bef.count)+":Deleting files ... ("+to_string(bef.count)+"%)";
542
                            parseCommand(bef.device1, bef.port1, com);
543
                        break;
544
 
545
                        case 0x0105:	// start filetransfer
546
                            com = "#FTR-START";
547
                            parseCommand(bef.device1, bef.port1, com);
548
                        break;
549
                    }
550
                }
551
                else
552
                {
553
                    switch(ftr.function)
554
                    {
555
                        case 0x0003:	// Received part of file
556
                        case 0x0004:	// End of file
557
                            com = "#FTR-FTRPART:"+to_string(bef.count)+":"+to_string(ftr.info1);
558
                            parseCommand(bef.device1, bef.port1, com);
559
                        break;
560
 
561
                        case 0x0007:	// End of file transfer
562
                        {
563
                            initialize();
564
                            com = "#FTR-END";
565
                            parseCommand(bef.device1, bef.port1, com);
566
                        }
567
                        break;
568
 
569
                        case 0x0102:	// Receiving file
570
                            com = "#FTR-FTRSTART:"+to_string(bef.count)+":"+to_string(ftr.info1)+":";
571
                            com.append((char*)&ftr.data[0]);
572
                            parseCommand(bef.device1, bef.port1, com);
573
                        break;
574
                    }
575
                }
576
            }
577
            break;
578
        }
579
    }
580
 
14 andreas 581
    runDoCommand = false;
11 andreas 582
    mBusy = false;
583
}
584
 
585
/*
586
 * The following function must be called to start the "panel".
587
 */
5 andreas 588
bool TPageManager::run()
589
{
590
    DECL_TRACER("TPageManager::run()");
591
 
592
    if (mActualPage <= 0)
593
        return false;
594
 
14 andreas 595
    surface_mutex.lock();
5 andreas 596
    TPage *pg = getPage(mActualPage);
7 andreas 597
    pg->setFonts(mFonts);
5 andreas 598
    pg->registerCallback(_setBackground);
7 andreas 599
    pg->registerCallbackFT(_setText);
21 andreas 600
    pg->regCallPlayVideo(_callPlayVideo);
5 andreas 601
 
602
    if (!pg || !_setPage || !mTSettings)
14 andreas 603
    {
604
        surface_mutex.unlock();
5 andreas 605
        return false;
14 andreas 606
    }
5 andreas 607
 
608
    _setPage((pg->getNumber() << 16) & 0xffff0000, mTSettings->getWith(), mTSettings->getHeight());
609
    pg->show();
610
 
611
    TSubPage *subPg = pg->getFirstSubPage();
612
 
613
    while (subPg)
614
    {
7 andreas 615
        subPg->setFonts(mFonts);
616
        subPg->registerCallback(_setBackground);
617
        subPg->registerCallbackDB(_displayButton);
11 andreas 618
        subPg->regCallDropSubPage(_callDropSubPage);
7 andreas 619
        subPg->registerCallbackFT(_setText);
21 andreas 620
        subPg->regCallPlayVideo(_callPlayVideo);
7 andreas 621
 
5 andreas 622
        if (_setSubPage)
6 andreas 623
        {
624
            MSG_DEBUG("Drawing page " << subPg->getNumber() << ": " << subPg->getName() << "...");
7 andreas 625
            _setSubPage(((subPg->getNumber() << 16) & 0xffff0000), subPg->getLeft(), subPg->getTop(), subPg->getWidth(), subPg->getHeight());
6 andreas 626
            subPg->show();
627
        }
5 andreas 628
 
629
        subPg = pg->getNextSubPage();
630
    }
631
 
14 andreas 632
    surface_mutex.unlock();
5 andreas 633
    return true;
634
}
635
 
4 andreas 636
TPage *TPageManager::getPage(int pageID)
637
{
638
    DECL_TRACER("TPageManager::getPage(int pageID)");
639
 
640
    PCHAIN_T *p = mPchain;
641
 
642
    while (p)
643
    {
644
        if (p->page->getNumber() == pageID)
645
            return p->page;
646
 
647
        p = p->next;
648
    }
649
 
14 andreas 650
    MSG_DEBUG("Page " << pageID << " not found!");
4 andreas 651
    return nullptr;
652
}
653
 
654
TPage *TPageManager::getPage(const string& name)
655
{
656
    DECL_TRACER("TPageManager::getPage(const string& name)");
657
 
658
    PCHAIN_T *p = mPchain;
659
 
660
    while (p)
661
    {
662
        if (p->page->getName().compare(name) == 0)
663
            return p->page;
664
 
665
        p = p->next;
666
    }
667
 
14 andreas 668
    MSG_DEBUG("Page " << name << " not found!");
4 andreas 669
    return nullptr;
670
}
671
 
15 andreas 672
TPage *TPageManager::loadPage(PAGELIST_T& pl)
673
{
674
    DECL_TRACER("TPageManager::loadPage(PAGELIST_T& pl)");
675
 
676
    if (!pl.isValid)
677
        return nullptr;
678
 
679
    TPage *pg = getPage(pl.pageID);
680
 
681
    if (!pg)
682
    {
683
        if (!readPage(pl.pageID))
684
            return nullptr;
685
 
686
        pg = getPage(pl.pageID);
687
 
688
        if (!pg)
689
        {
690
            MSG_ERROR("Error loading page " << pl.pageID << ", " << pl.name << " from file " << pl.file << "!");
691
            return nullptr;
692
        }
693
    }
694
 
695
    return pg;
696
}
697
 
698
bool TPageManager::setPage(int PageID)
699
{
700
    DECL_TRACER("TPageManager::setPage(int PageID)");
701
 
702
    if (mActualPage == PageID)
703
        return true;
704
 
705
    TPage *pg = getPage(mActualPage);
706
    mPreviousPage = mActualPage;
707
 
708
    if (pg)
709
        pg->drop();
710
 
711
    mActualPage = 0;
712
    PAGELIST_T listPg = findPage(PageID);
713
 
714
    if ((pg = loadPage(listPg)) == nullptr)
715
        return false;
716
 
717
    mActualPage = PageID;
718
    pg->show();
719
    return true;
720
}
721
 
722
bool TPageManager::setPage(const string& name)
723
{
724
    DECL_TRACER("TPageManager::setPage(const string& name)");
725
 
726
    TPage *pg = getPage(mActualPage);
727
 
728
    if (pg && pg->getName().compare(name) == 0)
729
        return true;
730
 
731
    mPreviousPage = mActualPage;
732
 
733
    if (pg)
734
        pg->drop();
735
 
736
    mActualPage = 0;
737
    PAGELIST_T listPg = findPage(name);
738
 
739
    if ((pg = loadPage(listPg)) == nullptr)
740
        return false;
741
 
742
    mActualPage = pg->getNumber();
743
    pg->show();
744
    return true;
745
}
746
 
4 andreas 747
TSubPage *TPageManager::getSubPage(int pageID)
748
{
749
    DECL_TRACER("TPageManager::getSubPage(int pageID)");
750
 
751
    SPCHAIN_T *p = mSPchain;
752
 
753
    while(p)
754
    {
755
        if (p->page->getNumber() == pageID)
756
            return p->page;
757
 
758
        p = p->next;
759
    }
760
 
761
    return nullptr;
762
}
763
 
764
TSubPage *TPageManager::getSubPage(const std::string& name)
765
{
766
    DECL_TRACER("TPageManager::getSubPage(const std::string& name)");
767
 
768
    SPCHAIN_T *p = mSPchain;
769
 
770
    while (p)
771
    {
772
        if (p->page->getName().compare(name) == 0)
773
            return p->page;
774
 
775
        p = p->next;
776
    }
777
 
778
    return nullptr;
779
}
780
 
3 andreas 781
bool TPageManager::readPages()
782
{
783
    DECL_TRACER("TPageManager::readPages()");
784
 
785
    if (!mPageList)
786
    {
787
        MSG_ERROR("Page list is not initialized!");
788
        TError::setError();
789
        return false;
790
    }
791
 
792
    // Read all pages
793
    vector<PAGELIST_T>::iterator pgIter;
794
    vector<PAGELIST_T> pageList = mPageList->getPagelist();
795
 
796
    for (pgIter = pageList.begin(); pgIter != pageList.end(); pgIter++)
797
    {
798
        TPage *page = new TPage(pgIter->name+".xml");
14 andreas 799
 
800
        if (TError::isError())
801
        {
802
            delete page;
803
            return false;
804
        }
805
 
4 andreas 806
        page->setPalette(mPalette);
7 andreas 807
        page->setFonts(mFonts);
808
        page->registerCallback(_setBackground);
809
        page->registerCallbackDB(_displayButton);
810
        page->registerCallbackFT(_setText);
21 andreas 811
        page->regCallPlayVideo(_callPlayVideo);
3 andreas 812
 
813
        if (!addPage(page))
814
            return false;
815
    }
816
 
817
    vector<SUBPAGELIST_T>::iterator spgIter;
818
    vector<SUBPAGELIST_T> subPageList = mPageList->getSupPageList();
819
 
820
    for (spgIter = subPageList.begin(); spgIter != subPageList.end(); spgIter++)
821
    {
822
        TSubPage *page = new TSubPage(spgIter->name+".xml");
14 andreas 823
 
824
        if (TError::isError())
825
        {
826
            delete page;
827
            return false;
828
        }
829
 
4 andreas 830
        page->setPalette(mPalette);
7 andreas 831
        page->setFonts(mFonts);
832
        page->registerCallback(_setBackground);
833
        page->registerCallbackDB(_displayButton);
11 andreas 834
        page->regCallDropSubPage(_callDropSubPage);
7 andreas 835
        page->registerCallbackFT(_setText);
21 andreas 836
        page->regCallPlayVideo(_callPlayVideo);
11 andreas 837
        page->setGroup(spgIter->group);
3 andreas 838
 
839
        if (!addSubPage(page))
840
            return false;
841
    }
842
 
843
    return true;
844
}
845
 
846
bool TPageManager::readPage(const std::string& name)
847
{
848
    DECL_TRACER("TPageManager::readPage(const std::string& name)");
849
 
850
    PAGELIST_T page = findPage(name);
851
 
852
    if (page.pageID <= 0)
853
    {
854
        MSG_ERROR("Page " << name << " not found!");
855
        return false;
856
    }
857
 
858
    TPage *pg = new TPage(page.name+".xml");
14 andreas 859
 
860
    if (TError::isError())
861
    {
862
        delete pg;
863
        return false;
864
    }
865
 
4 andreas 866
    pg->setPalette(mPalette);
7 andreas 867
    pg->setFonts(mFonts);
868
    pg->registerCallback(_setBackground);
869
    pg->registerCallbackDB(_displayButton);
870
    pg->registerCallbackFT(_setText);
21 andreas 871
    pg->regCallPlayVideo(_callPlayVideo);
3 andreas 872
 
873
    if (!addPage(pg))
874
        return false;
875
 
876
    return true;
877
}
878
 
879
bool TPageManager::readPage(int ID)
880
{
881
    DECL_TRACER("TPageManager::readPage(int ID)");
882
 
16 andreas 883
    TError::clear();
3 andreas 884
    PAGELIST_T page = findPage(ID);
885
 
886
    if (page.pageID <= 0)
887
    {
888
        MSG_ERROR("Page with ID " << ID << " not found!");
889
        return false;
890
    }
891
 
892
    TPage *pg = new TPage(page.name+".xml");
14 andreas 893
 
894
    if (TError::isError())
895
    {
896
        delete pg;
897
        return false;
898
    }
899
 
4 andreas 900
    pg->setPalette(mPalette);
7 andreas 901
    pg->setFonts(mFonts);
902
    pg->registerCallback(_setBackground);
903
    pg->registerCallbackDB(_displayButton);
904
    pg->registerCallbackFT(_setText);
21 andreas 905
    pg->regCallPlayVideo(_callPlayVideo);
3 andreas 906
 
907
    if (!addPage(pg))
908
        return false;
909
 
910
    return true;
911
}
912
 
913
bool TPageManager::readSubPage(const std::string& name)
914
{
915
    DECL_TRACER("TPageManager::readSubPage(const std::string& name)");
916
 
16 andreas 917
    TError::clear();
3 andreas 918
    SUBPAGELIST_T page = findSubPage(name);
919
 
920
    if (page.pageID <= 0)
921
    {
922
        MSG_ERROR("Subpage " << name << " not found!");
923
        return false;
924
    }
925
 
14 andreas 926
    if (haveSubPage(name))
927
        return true;
928
 
3 andreas 929
    TSubPage *pg = new TSubPage(page.name+".xml");
14 andreas 930
 
931
    if (TError::isError())
932
    {
933
        delete pg;
934
        return false;
935
    }
936
 
4 andreas 937
    pg->setPalette(mPalette);
7 andreas 938
    pg->setFonts(mFonts);
939
    pg->registerCallback(_setBackground);
940
    pg->registerCallbackDB(_displayButton);
11 andreas 941
    pg->regCallDropSubPage(_callDropSubPage);
7 andreas 942
    pg->registerCallbackFT(_setText);
21 andreas 943
    pg->regCallPlayVideo(_callPlayVideo);
11 andreas 944
    pg->setGroup(page.group);
3 andreas 945
 
946
    if (!addSubPage(pg))
14 andreas 947
    {
948
        delete pg;
3 andreas 949
        return false;
14 andreas 950
    }
3 andreas 951
 
952
    return true;
953
}
954
 
955
bool TPageManager::readSubPage(int ID)
956
{
957
    DECL_TRACER("TPageManager::readSubPage(int ID)");
958
 
16 andreas 959
    TError::clear();
3 andreas 960
    SUBPAGELIST_T page = findSubPage(ID);
961
 
962
    if (page.pageID <= 0)
963
    {
964
        MSG_ERROR("Subpage with ID " << ID << " not found!");
965
        return false;
966
    }
967
 
968
    TSubPage *pg = new TSubPage(page.name+".xml");
14 andreas 969
 
970
    if (TError::isError())
971
    {
972
        delete pg;
973
        return false;
974
    }
975
 
4 andreas 976
    pg->setPalette(mPalette);
7 andreas 977
    pg->setFonts(mFonts);
978
    pg->registerCallback(_setBackground);
979
    pg->registerCallbackDB(_displayButton);
11 andreas 980
    pg->regCallDropSubPage(_callDropSubPage);
7 andreas 981
    pg->registerCallbackFT(_setText);
21 andreas 982
    pg->regCallPlayVideo(_callPlayVideo);
11 andreas 983
    pg->setGroup(page.group);
3 andreas 984
 
985
    if (!addSubPage(pg))
986
        return false;
987
 
988
    return true;
989
}
990
 
991
/******************** Internal private methods *********************/
992
 
993
PAGELIST_T TPageManager::findPage(const std::string& name)
994
{
995
    DECL_TRACER("TPageManager::findPage(const std::string& name)");
996
 
997
    vector<PAGELIST_T>::iterator pgIter;
998
    vector<PAGELIST_T> pageList = mPageList->getPagelist();
999
 
1000
    for (pgIter = pageList.begin(); pgIter != pageList.end(); pgIter++)
1001
    {
1002
        if (pgIter->name.compare(name) == 0)
1003
            return *pgIter;
1004
    }
1005
 
1006
    return PAGELIST_T();
1007
}
1008
 
1009
PAGELIST_T TPageManager::findPage(int ID)
1010
{
1011
    DECL_TRACER("TPageManager::findPage(int ID)");
1012
 
1013
    vector<PAGELIST_T>::iterator pgIter;
1014
    vector<PAGELIST_T> pageList = mPageList->getPagelist();
1015
 
1016
    for (pgIter = pageList.begin(); pgIter != pageList.end(); pgIter++)
1017
    {
1018
        if (pgIter->pageID == ID)
1019
            return *pgIter;
1020
    }
1021
 
1022
    return PAGELIST_T();
1023
}
1024
 
1025
SUBPAGELIST_T TPageManager::findSubPage(const std::string& name)
1026
{
1027
    DECL_TRACER("TPageManager::findSubPage(const std::string& name)");
1028
 
1029
    vector<SUBPAGELIST_T>::iterator pgIter;
1030
    vector<SUBPAGELIST_T> pageList = mPageList->getSupPageList();
1031
 
1032
    for (pgIter = pageList.begin(); pgIter != pageList.end(); pgIter++)
1033
    {
1034
        if (pgIter->name.compare(name) == 0)
1035
            return *pgIter;
1036
    }
1037
 
1038
    return SUBPAGELIST_T();
1039
}
1040
 
1041
SUBPAGELIST_T TPageManager::findSubPage(int ID)
1042
{
1043
    DECL_TRACER("TPageManager::findSubPage(int ID)");
1044
 
1045
    vector<SUBPAGELIST_T>::iterator pgIter;
1046
    vector<SUBPAGELIST_T> pageList = mPageList->getSupPageList();
1047
 
1048
    for (pgIter = pageList.begin(); pgIter != pageList.end(); pgIter++)
1049
    {
1050
        if (pgIter->pageID == ID)
1051
            return *pgIter;
1052
    }
1053
 
1054
    return SUBPAGELIST_T();
1055
}
1056
 
1057
bool TPageManager::addPage(TPage* pg)
1058
{
1059
    DECL_TRACER("TPageManager::addPage(TPage* pg)");
1060
 
1061
    if (!pg)
1062
    {
1063
        MSG_ERROR("Parameter is NULL!");
1064
        TError::setError();
1065
        return false;
1066
    }
1067
 
1068
    PCHAIN_T *chain = new PCHAIN_T;
1069
    chain->page = pg;
5 andreas 1070
    chain->next = nullptr;
3 andreas 1071
 
1072
    if (mPchain)
1073
    {
1074
        PCHAIN_T *p = mPchain;
1075
 
1076
        while (p->next)
1077
            p = p->next;
1078
 
1079
        p->next = chain;
1080
    }
1081
    else
14 andreas 1082
    {
3 andreas 1083
        mPchain = chain;
14 andreas 1084
        setPChain(mPchain);
1085
    }
3 andreas 1086
 
1087
    MSG_DEBUG("Added page " << chain->page->getName());
1088
    return true;
1089
}
1090
 
1091
bool TPageManager::addSubPage(TSubPage* pg)
1092
{
1093
    DECL_TRACER("TPageManager::addSubPage(TSubPage* pg)");
1094
 
1095
    if (!pg)
1096
    {
1097
        MSG_ERROR("Parameter is NULL!");
1098
        TError::setError();
1099
        return false;
1100
    }
1101
 
14 andreas 1102
    if (haveSubPage(pg->getNumber()))
1103
    {
1104
        MSG_ERROR("Subpage " << pg->getNumber() << ", " << pg->getName() << " is already in chain!");
1105
        return false;
1106
    }
1107
 
3 andreas 1108
    SPCHAIN_T *chain = new SPCHAIN_T;
1109
    chain->page = pg;
5 andreas 1110
    chain->next = nullptr;
3 andreas 1111
 
1112
    if (mSPchain)
1113
    {
1114
        SPCHAIN_T *p = mSPchain;
1115
 
1116
        while (p->next)
1117
            p = p->next;
1118
 
1119
        p->next = chain;
1120
    }
1121
    else
14 andreas 1122
    {
3 andreas 1123
        mSPchain = chain;
14 andreas 1124
        setSPChain(mSPchain);
1125
    }
3 andreas 1126
 
1127
    MSG_DEBUG("Added subpage " << chain->page->getName());
1128
    return true;
1129
}
4 andreas 1130
 
11 andreas 1131
void TPageManager::dropAllPages()
1132
{
1133
    DECL_TRACER("TPageManager::dropAllPages()");
1134
 
1135
    PCHAIN_T *pg = mPchain;
1136
    PCHAIN_T *next = nullptr;
1137
 
1138
    while (pg)
1139
    {
1140
        next = pg->next;
1141
 
1142
        if (pg->page)
1143
        {
1144
            if (_callDropPage)
1145
                _callDropPage((pg->page->getNumber() << 16) & 0xffff0000);
1146
 
1147
            delete pg->page;
1148
        }
1149
 
1150
        delete pg;
1151
        pg = next;
1152
    }
14 andreas 1153
 
1154
    mPchain = nullptr;
1155
    setPChain(mPchain);
11 andreas 1156
}
1157
 
1158
void TPageManager::dropAllSubPages()
1159
{
1160
    DECL_TRACER("TPageManager::dropAllSubPages()");
1161
 
1162
    SPCHAIN_T *spg = mSPchain;
1163
    SPCHAIN_T *next;
1164
 
1165
    while (spg)
1166
    {
1167
        next = spg->next;
1168
 
1169
        if (spg->page)
1170
        {
1171
            if (_callDropSubPage)
1172
                _callDropSubPage((spg->page->getNumber() << 16) & 0xffff0000);
1173
 
1174
            delete spg->page;
1175
        }
1176
 
1177
        delete spg;
1178
        spg = next;
1179
    }
14 andreas 1180
 
1181
    mSPchain = nullptr;
1182
    setSPChain(mSPchain);
11 andreas 1183
}
1184
 
4 andreas 1185
TPage *TPageManager::getActualPage()
1186
{
1187
    return getPage(mActualPage);
1188
}
1189
 
1190
TSubPage *TPageManager::getFirstSubPage()
1191
{
1192
    DECL_TRACER("TPageManager::getFirstSubPage()");
1193
    TPage *pg = getPage(mActualPage);
1194
 
1195
    if (!pg)
1196
        return nullptr;
1197
 
1198
    return pg->getFirstSubPage();
1199
}
1200
 
1201
TSubPage *TPageManager::getNextSubPage()
1202
{
1203
    DECL_TRACER("TPageManager::getNextSubPage()");
1204
 
1205
    TPage *pg = getPage(mActualPage);
1206
 
1207
    if (pg)
1208
        return pg->getNextSubPage();
1209
 
1210
    return nullptr;
1211
}
10 andreas 1212
 
11 andreas 1213
TSubPage *TPageManager::getFirstSubPageGroup(const string& group)
1214
{
1215
    DECL_TRACER("TPageManager::getFirstSubPageGroup(const string& group)");
1216
 
14 andreas 1217
    if (group.empty())
1218
    {
1219
        MSG_WARNING("Empty group name is invalid. Ignoring it!");
1220
        mActualGroupName.clear();
1221
        mActualGroupPage = nullptr;
1222
        return nullptr;
1223
    }
1224
 
11 andreas 1225
    mActualGroupName = group;
1226
    TSubPage *pg = getFirstSubPage();
1227
 
1228
    while (pg)
1229
    {
14 andreas 1230
        MSG_DEBUG("Evaluating group " << pg->getGroupName() << " with " << group);
1231
 
11 andreas 1232
        if (pg->getGroupName().compare(group) == 0)
1233
        {
1234
            mActualGroupPage = pg;
1235
            return pg;
1236
        }
1237
 
1238
        pg = getNextSubPage();
1239
    }
1240
 
1241
    mActualGroupName.clear();
1242
    mActualGroupPage = nullptr;
1243
    return nullptr;
1244
}
1245
 
1246
TSubPage *TPageManager::getNextSubPageGroup()
1247
{
1248
    DECL_TRACER("TPageManager::getNextSubPageGroup()");
1249
 
1250
    if (mActualGroupName.empty())
1251
        return nullptr;
1252
 
1253
    TSubPage *pg = getFirstSubPage();
1254
    bool found = false;
1255
 
1256
    while (pg)
1257
    {
14 andreas 1258
        MSG_DEBUG("Evaluating group " << pg->getGroupName() << " with " << mActualGroupName);
1259
 
1260
        if (!found && pg == mActualGroupPage)
11 andreas 1261
        {
1262
            pg = getNextSubPage();
14 andreas 1263
            found = true;
11 andreas 1264
            continue;
1265
        }
1266
 
14 andreas 1267
        if (found && pg->getGroupName().compare(mActualGroupName) == 0)
11 andreas 1268
        {
1269
            mActualGroupPage = pg;
1270
            return pg;
1271
        }
1272
 
1273
        pg = getNextSubPage();
1274
    }
1275
 
1276
    mActualGroupName.clear();
1277
    mActualGroupPage = nullptr;
1278
    return nullptr;
1279
}
1280
 
1281
TSubPage *TPageManager::getNextSubPageGroup(const string& group, TSubPage* pg)
1282
{
1283
    DECL_TRACER("TPageManager::getNextSubPageGroup(const string& group, TSubPage* pg)");
1284
 
1285
    if (group.empty() || !pg)
1286
        return nullptr;
1287
 
1288
    TSubPage *page = getFirstSubPage();
1289
    bool found = false;
1290
 
1291
    while (page)
1292
    {
14 andreas 1293
        MSG_DEBUG("Evaluating group " << pg->getGroupName() << " with " << group);
1294
 
1295
        if (!found && pg == page)
11 andreas 1296
        {
1297
            page = getNextSubPage();
14 andreas 1298
            found = true;
11 andreas 1299
            continue;
1300
        }
1301
 
14 andreas 1302
        if (found && page->getGroupName().compare(group) == 0)
11 andreas 1303
            return page;
1304
 
1305
        page = getNextSubPage();
1306
    }
1307
 
1308
    return nullptr;
1309
}
1310
 
1311
TSubPage *TPageManager::getTopPage()
1312
{
1313
    DECL_TRACER("TPageManager::getTopPage()");
1314
 
1315
    // Scan for all occupied regions
1316
    vector<RECT_T> regions;
1317
 
1318
    TSubPage *pg = getFirstSubPage();
1319
 
1320
    while (pg)
1321
    {
1322
        RECT_T r = pg->getRegion();
1323
        regions.push_back(r);
1324
        pg = getNextSubPage();
1325
    }
1326
 
1327
    // Now scan all pages against all regions to find the top most
1328
    pg = getFirstSubPage();
1329
    TSubPage *top = nullptr;
1330
    int zPos = 0;
1331
 
1332
    while (pg)
1333
    {
1334
        RECT_T r = pg->getRegion();
1335
        vector<RECT_T>::iterator iter;
1336
        int zo = 0;
1337
 
1338
        for (iter = regions.begin(); iter != regions.end(); iter++)
1339
        {
1340
            if (doOverlap(*iter, r) && zPos > zo)
1341
                top = pg;
1342
 
1343
            zo++;
1344
        }
1345
 
1346
        pg = getNextSubPage();
1347
        zPos++;
1348
    }
1349
 
1350
    return top;
1351
}
1352
 
1353
TSubPage *TPageManager::getCoordMatch(int x, int y)
1354
{
1355
    DECL_TRACER("TPageManager::getCoordMatch(int x, int y)");
1356
 
1357
    // Reverse order of pages
1358
    map<int, TSubPage *> zOrder;
1359
    TSubPage *pg = getFirstSubPage();
1360
 
1361
    while (pg)
1362
    {
14 andreas 1363
        if (pg->isVisible())
1364
            zOrder.insert(pair<int, TSubPage *>(pg->getZOrder(), pg));
1365
 
11 andreas 1366
        pg = getNextSubPage();
1367
    }
1368
 
1369
    // Iterate in reverse order through array
1370
    map<int, TSubPage *>::reverse_iterator iter;
1371
 
1372
    for (iter = zOrder.rbegin(); iter != zOrder.rend(); iter++)
1373
    {
1374
        RECT_T r = iter->second->getRegion();
1375
 
1376
        if (r.left <= x && (r.left + r.width) >= x &&
1377
            r.top <= y && (r.top + r.height) >= y)
1378
        {
1379
            MSG_DEBUG("Click matches subpage " << iter->second->getNumber() << " (" << iter->second->getName() << ")");
1380
            return iter->second;
1381
        }
1382
    }
1383
 
1384
    return nullptr;
1385
}
1386
 
1387
bool TPageManager::doOverlap(RECT_T r1, RECT_T r2)
1388
{
1389
    DECL_TRACER("TPageManager::doOverlap(RECT_T r1, RECT_T r2)");
1390
 
1391
    // If one rectangle is on left side of other
1392
    if (r1.left >= r2.left || r2.left >= r1.left)
1393
        return false;
1394
 
1395
    // If one rectangle is above other
1396
    if (r1.top <= r2.top || r2.top <= r1.top)
1397
        return false;
1398
 
1399
    return true;
1400
}
1401
 
14 andreas 1402
bool TPageManager::havePage(const string& name)
11 andreas 1403
{
14 andreas 1404
    DECL_TRACER("TPageManager::havePage(const string& name)");
11 andreas 1405
 
14 andreas 1406
    if (name.empty())
1407
        return false;
1408
 
1409
    PCHAIN_T *pg = mPchain;
1410
 
1411
    while (pg)
1412
    {
1413
        if (pg->page && pg->page->getName().compare(name) == 0)
1414
            return true;
1415
 
1416
        pg = pg->next;
1417
    }
1418
 
1419
    return false;
1420
}
1421
 
1422
bool TPageManager::haveSubPage(const string& name)
1423
{
1424
    DECL_TRACER("TPageManager::haveSubPage(const string& name)");
1425
 
1426
    if (name.empty())
1427
        return false;
1428
 
11 andreas 1429
    SPCHAIN_T *pg = mSPchain;
1430
 
1431
    while (pg)
1432
    {
14 andreas 1433
        if (pg->page && pg->page->getName().compare(name) == 0)
1434
        {
1435
            MSG_DEBUG("Subpage " << pg->page->getNumber() << ", " << name << " found.");
1436
            return true;
1437
        }
1438
 
1439
        pg = pg->next;
1440
    }
1441
 
1442
    MSG_DEBUG("Subpage " << name << " not found.");
1443
    return false;
1444
}
1445
 
1446
bool TPageManager::haveSubPage(int id)
1447
{
1448
    DECL_TRACER("TPageManager::haveSubPage(int id)");
1449
 
1450
    SPCHAIN_T *pg = mSPchain;
1451
 
1452
    while (pg)
1453
    {
1454
        if (pg->page && pg->page->getNumber() == id)
1455
        {
1456
            MSG_DEBUG("Subpage " << pg->page->getNumber() << ", " << pg->page->getName() << " found.");
1457
            return true;
1458
        }
1459
 
1460
        pg = pg->next;
1461
    }
1462
 
1463
    MSG_DEBUG("Subpage " << id << " not found.");
1464
    return false;
1465
}
1466
 
1467
bool TPageManager::haveSubPage(const string& page, const string& name)
1468
{
1469
    DECL_TRACER("TPageManager::haveSubPage(const string& page, const string& name)");
1470
 
1471
    TPage *pg = getPage(page);
1472
 
1473
    if (!pg)
1474
        return false;
1475
 
1476
    TSubPage *spg = pg->getFirstSubPage();
1477
 
1478
    while (spg)
1479
    {
1480
        if (spg->getName().compare(name) == 0)
1481
        {
1482
            MSG_DEBUG("Subpage " << spg->getNumber() << ", " << name << " found.");
1483
            return true;
1484
        }
1485
 
1486
        spg = pg->getNextSubPage();
1487
    }
1488
 
1489
    MSG_DEBUG("Subpage " << name << " not found on page " << page << ".");
1490
    return false;
1491
}
1492
 
1493
bool TPageManager::haveSubPage(const string& page, int id)
1494
{
1495
    DECL_TRACER("TPageManager::haveSubPage(const string& page, int id)");
1496
 
1497
    TPage *pg = getPage(page);
1498
 
1499
    if (!pg)
1500
        return false;
1501
 
1502
    TSubPage *spg = pg->getFirstSubPage();
1503
 
1504
    while (spg)
1505
    {
1506
        if (spg->getNumber() == id)
1507
        {
1508
            MSG_DEBUG("Subpage " << spg->getNumber() << ", " << spg->getName() << " found.");
1509
            return true;
1510
        }
1511
 
1512
        spg = pg->getNextSubPage();
1513
    }
1514
 
1515
    MSG_DEBUG("Subpage " << id << " on page " << page << " not found.");
1516
    return false;
1517
}
1518
 
1519
void TPageManager::closeGroup(const string& group)
1520
{
1521
    DECL_TRACER("TPageManager::closeGroup(const string& group)");
1522
 
1523
    SPCHAIN_T *pg = mSPchain;
1524
 
1525
    while (pg)
1526
    {
11 andreas 1527
        if (pg->page->getGroupName().compare(group) == 0 && pg->page->isVisible())
1528
        {
1529
            pg->page->regCallDropSubPage(_callDropSubPage);
1530
            pg->page->drop();
1531
            break;
1532
        }
1533
 
1534
        pg = pg->next;
1535
    }
1536
}
1537
 
14 andreas 1538
void TPageManager::showSubPage(const string& name)
1539
{
1540
    DECL_TRACER("TPageManager::showSubPage(const string& name)");
1541
 
1542
    if (name.empty())
1543
        return;
1544
 
1545
    TPage *page = getActualPage();
1546
 
1547
    if (!page)
1548
    {
1549
        MSG_ERROR("No actual page loaded!");
1550
        return;
1551
    }
1552
 
1553
    TSubPage *pg = getSubPage(name);
1554
 
1555
    if (!pg)
1556
    {
1557
        MSG_DEBUG("Subpage " << name << " not in memory. Reading it ...");
1558
 
1559
        if (!readSubPage(name))
1560
            return;
1561
 
1562
        if ((pg = getSubPage(name)) == nullptr)
1563
            return;
1564
 
1565
        page->addSubPage(pg);
1566
    }
1567
 
1568
    string group = pg->getGroupName();
1569
 
1570
    if (!group.empty())
1571
    {
1572
        TSubPage *sub = getFirstSubPageGroup(group);
1573
 
1574
        while(sub)
1575
        {
1576
            if (sub->isVisible() && sub->getNumber() != pg->getNumber())
1577
                sub->drop();
1578
 
1579
            sub = getNextSubPageGroup(group, sub);
1580
        }
1581
    }
1582
 
1583
    if (!pg->isVisible())
1584
    {
1585
        TPage *page = getPage(mActualPage);
1586
 
1587
        if (!page)
1588
        {
1589
            MSG_ERROR("No active page found! Internal error.");
1590
            return;
1591
        }
1592
 
1593
        if (!haveSubPage(pg->getNumber()) && !page->addSubPage(pg))
1594
            return;
1595
 
1596
        pg->setZOrder(page->getNextZOrder());
1597
 
1598
        if (_setSubPage)
1599
            _setSubPage((pg->getNumber() << 16) & 0xffff0000, pg->getLeft(), pg->getTop(), pg->getWidth(), pg->getHeight());
1600
    }
1601
 
1602
    pg->show();
1603
}
1604
 
1605
void TPageManager::hideSubPage(const string& name)
1606
{
1607
    DECL_TRACER("TPageManager::hideSubPage(const string& name)");
1608
 
1609
    if (name.empty())
1610
        return;
1611
 
1612
    TPage *page = getPage(mActualPage);
1613
 
1614
    if (!page)
1615
    {
1616
        MSG_ERROR("No active page found! Internal error.");
1617
        return;
1618
    }
1619
 
1620
    TSubPage *pg = getSubPage(name);
1621
 
1622
    if (pg)
1623
    {
1624
        if (pg->getZOrder() == page->getActZOrder())
1625
            page->decZOrder();
1626
 
1627
        pg->drop();
1628
    }
1629
}
1630
 
11 andreas 1631
/*
1632
 * Catch the mouse presses and scan all pages and subpages for an element to
1633
 * receive the klick.
1634
 */
10 andreas 1635
void TPageManager::mouseEvent(int x, int y, bool pressed)
1636
{
14 andreas 1637
    surface_mutex.lock();
10 andreas 1638
    DECL_TRACER("TPageManager::mouseEvent(int x, int y, bool pressed)");
1639
 
16 andreas 1640
    TError::clear();
11 andreas 1641
    int realX = x - mFirstLeftPixel;
1642
    int realY = y - mFirstTopPixel;
14 andreas 1643
    MSG_DEBUG("Mouse at " << realX << ", " << realY << ", state " << ((pressed) ? "PRESSED" : "RELEASED"));
12 andreas 1644
    TSubPage *subPage = getCoordMatch(realX, realY);
11 andreas 1645
 
1646
    if (!subPage)
14 andreas 1647
    {
1648
        surface_mutex.unlock();
11 andreas 1649
        return;
14 andreas 1650
    }
11 andreas 1651
 
1652
    MSG_DEBUG("Subpage " << subPage->getNumber() << ": size: left=" << subPage->getLeft() << ", top=" << subPage->getTop() << ", width=" << subPage->getWidth() << ", height=" << subPage->getHeight());
1653
    subPage->doClick(realX - subPage->getLeft(), realY - subPage->getTop(), pressed);
14 andreas 1654
    surface_mutex.unlock();
10 andreas 1655
}
11 andreas 1656
 
14 andreas 1657
vector<Button::TButton *> TPageManager::collectButtons(vector<MAP_T>& map)
1658
{
1659
    DECL_TRACER("TPageManager::collectButtons(vector<MAP_T>& map)");
1660
 
1661
    vector<Button::TButton *> buttons;
1662
    vector<MAP_T>::iterator iter;
1663
 
1664
    for (iter = map.begin(); iter != map.end(); iter++)
1665
    {
1666
        if (iter->pg < 500)     // Main page?
1667
        {
1668
            TPage *page;
1669
 
1670
            if ((page = getPage(iter->pg)) == nullptr)
1671
            {
1672
                MSG_TRACE("Page " << iter->pg << ", " << iter->pn << " not found in memory. Reading it ...");
1673
 
1674
                if (!readPage(iter->pg))
1675
                    return buttons;
1676
 
1677
                page = getPage(iter->pg);
1678
                addPage(page);
1679
            }
1680
 
1681
            Button::TButton *bt = page->getButton(iter->bt);
1682
 
1683
            if (bt)
1684
                buttons.push_back(bt);
1685
        }
1686
        else
1687
        {
1688
            TSubPage *subpage;
1689
 
1690
            if ((subpage = getSubPage(iter->pg)) == nullptr)
1691
            {
1692
                MSG_TRACE("Subpage " << iter->pg << ", " << iter->pn << " not found in memory. Reading it ...");
1693
 
1694
                if (!readSubPage(iter->pg))
1695
                    return buttons;
1696
 
1697
                subpage = getSubPage(iter->pg);
1698
                TPage *page = getActualPage();
1699
 
1700
                if (!page)
1701
                {
1702
                    MSG_ERROR("No actual page loaded!");
1703
                    return buttons;
1704
                }
1705
 
1706
                page->addSubPage(subpage);
1707
            }
1708
 
1709
            Button::TButton *bt = subpage->getButton(iter->bt);
1710
 
1711
            if (bt)
1712
                buttons.push_back(bt);
1713
        }
1714
    }
1715
 
1716
    return buttons;
1717
}
1718
 
11 andreas 1719
/****************************************************************************
1720
 * The following functions implements one of the commands the panel accepts.
1721
 ****************************************************************************/
14 andreas 1722
 
1723
void TPageManager::doON(int port, vector<int>& channels, vector<string>& pars)
1724
{
1725
    DECL_TRACER("TPageManager::doON(int port, vector<int>& channels, vector<string>& pars)");
1726
 
1727
    if (pars.empty())
1728
    {
1729
        MSG_WARNING("Command ON needs 1 parameter! Ignoring command.");
1730
        return;
1731
    }
1732
 
16 andreas 1733
    TError::clear();
14 andreas 1734
    int c = atoi(pars[0].c_str());
1735
 
1736
    if (c <= 0)
1737
    {
1738
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
1739
        return;
1740
    }
1741
 
1742
    vector<int> chans = { c };
19 andreas 1743
    vector<MAP_T> map = findButtons(port, chans, TYPE_CM);
14 andreas 1744
 
1745
    if (TError::isError() || map.empty())
1746
        return;
1747
 
1748
    vector<Button::TButton *> buttons = collectButtons(map);
1749
    vector<Button::TButton *>::iterator mapIter;
1750
 
1751
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
1752
    {
1753
        Button::TButton *bt = *mapIter;
1754
 
1755
        if (bt->getButtonType() == Button::GENERAL)
1756
            bt->setActive(1);
1757
    }
1758
}
1759
 
1760
void TPageManager::doOFF(int port, vector<int>& channels, vector<string>& pars)
1761
{
1762
    DECL_TRACER("TPageManager::doOFF(int port, vector<int>& channels, vector<string>& pars)");
1763
 
1764
    if (pars.empty())
1765
    {
1766
        MSG_WARNING("Command OFF needs 1 parameter! Ignoring command.");
1767
        return;
1768
    }
1769
 
16 andreas 1770
    TError::clear();
14 andreas 1771
    int c = atoi(pars[0].c_str());
1772
 
1773
    if (c <= 0)
1774
    {
1775
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
1776
        return;
1777
    }
1778
 
1779
    vector<int> chans = { c };
19 andreas 1780
    vector<MAP_T> map = findButtons(port, chans, TYPE_CM);
14 andreas 1781
 
1782
    if (TError::isError() || map.empty())
1783
        return;
1784
 
1785
    vector<Button::TButton *> buttons = collectButtons(map);
1786
    vector<Button::TButton *>::iterator mapIter;
1787
 
1788
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
1789
    {
1790
        Button::TButton *bt = *mapIter;
1791
 
1792
        if (bt->getButtonType() == Button::GENERAL)
1793
            bt->setActive(0);
1794
    }
1795
}
1796
 
15 andreas 1797
void TPageManager::doLEVEL(int port, vector<int>& channels, vector<string>& pars)
1798
{
1799
    DECL_TRACER("TPageManager::doLEVEL(int port, vector<int>& channels, vector<string>& pars)");
1800
 
1801
    if (pars.size() < 2)
1802
    {
1803
        MSG_WARNING("Command LEVEL needs 2 parameters! Ignoring command.");
1804
        return;
1805
    }
1806
 
16 andreas 1807
    TError::clear();
15 andreas 1808
    int c = atoi(pars[0].c_str());
1809
    int level = atoi(pars[1].c_str());
1810
 
1811
    if (c <= 0)
1812
    {
1813
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
1814
        return;
1815
    }
1816
 
1817
    vector<int> chans = { c };
1818
    vector<MAP_T> map = findBargraphs(port, chans);
1819
 
1820
    if (TError::isError() || map.empty())
1821
    {
1822
        MSG_WARNING("No bargraphs found!");
1823
        return;
1824
    }
1825
 
1826
    vector<Button::TButton *> buttons = collectButtons(map);
1827
    vector<Button::TButton *>::iterator mapIter;
1828
 
1829
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
1830
    {
1831
        Button::TButton *bt = *mapIter;
1832
 
1833
        if (bt->getButtonType() == Button::BARGRAPH)
1834
            bt->drawBargraph(bt->getActiveInstance(), level);
1835
        else if (bt->getButtonType() == Button::MULTISTATE_BARGRAPH)
1836
        {
1837
            int state = (int)((double)bt->getStateCount() / (double)(bt->getRangeHigh() - bt->getRangeLow()) * (double)level);
1838
            bt->setActive(state);
1839
        }
1840
    }
1841
}
1842
 
1843
void TPageManager::doBLINK(int port, vector<int>& channels, vector<string>& pars)
1844
{
1845
    DECL_TRACER("TPageManager::doBLINK(int port, vector<int>& channels, vector<string>& pars)");
1846
 
1847
    if (pars.size() < 4)
1848
    {
1849
        MSG_WARNING("Command BLINK expects 4 parameters! Command ignored.");
1850
        return;
1851
    }
1852
 
16 andreas 1853
    TError::clear();
15 andreas 1854
    vector<int> sysButtons = { 141, 142, 143, 151, 152, 153, 154, 155, 156, 157, 158 };
1855
    vector<MAP_T> map = findButtons(0, sysButtons);
1856
 
1857
    if (TError::isError() || map.empty())
1858
    {
1859
        MSG_WARNING("No system buttons found.");
1860
        return;
1861
    }
1862
 
1863
    vector<Button::TButton *> buttons = collectButtons(map);
1864
    vector<Button::TButton *>::iterator mapIter;
1865
 
1866
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
1867
    {
1868
        Button::TButton *bt = *mapIter;
1869
        bt->setActive(0);
1870
    }
1871
}
1872
 
14 andreas 1873
/**
1874
 * Add a specific popup page to a specified popup group if it does not already
1875
 * exist. If the new popup is added to a group which has a popup displayed on
1876
 * the current page along with the new pop-up, the displayed popup will be
1877
 * hidden and the new popup will be displayed.
1878
 */
11 andreas 1879
void TPageManager::doAPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)
1880
{
1881
    DECL_TRACER("TPageManager::doAPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
1882
 
1883
    if (pars.size() < 2)
1884
    {
1885
        MSG_ERROR("Less than 2 parameters!");
1886
        return;
1887
    }
1888
 
16 andreas 1889
    TError::clear();
11 andreas 1890
    closeGroup(pars[1]);
14 andreas 1891
    TPage *page = getActualPage();
1892
 
1893
    if (!page)
1894
    {
1895
        MSG_ERROR("No actual page loaded!");
1896
        return;
1897
    }
1898
 
11 andreas 1899
    TSubPage *subPage = getSubPage(pars[0]);
1900
 
1901
    if (!subPage)
1902
    {
1903
        if (!readSubPage(pars[0]))
1904
        {
1905
            MSG_ERROR("Error reading subpage " << pars[0]);
1906
            return;
1907
        }
1908
 
1909
        subPage = getSubPage(pars[0]);
14 andreas 1910
        page->addSubPage(subPage);
11 andreas 1911
    }
1912
 
1913
    if (!subPage)
1914
    {
1915
        MSG_ERROR("Subpage " << pars[0] << " couldn't either found or created!");
1916
        return;
1917
    }
1918
 
1919
    subPage->setGroup(pars[1]);
14 andreas 1920
    subPage->setZOrder(page->getNextZOrder());
11 andreas 1921
    subPage->show();
1922
}
1923
 
14 andreas 1924
/**
1925
 * Clear all popup pages from specified popup group.
1926
 */
11 andreas 1927
void TPageManager::doCPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)
1928
{
1929
    DECL_TRACER("TPageManager::doCPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
1930
 
1931
    if (pars.size() < 1)
1932
    {
1933
        MSG_ERROR("Expecting 1 parameter but got only 1!");
1934
        return;
1935
    }
1936
 
16 andreas 1937
    TError::clear();
11 andreas 1938
    vector<SUBPAGELIST_T>::iterator pgIter;
1939
    vector<SUBPAGELIST_T> pageList = mPageList->getSupPageList();
1940
 
1941
    for (pgIter = pageList.begin(); pgIter != pageList.end(); pgIter++)
1942
    {
1943
        if (pgIter->group.compare(pars[0]) == 0)
1944
        {
1945
            pgIter->group.clear();
1946
            TSubPage *pg = getSubPage(pgIter->pageID);
1947
 
1948
            if (pg)
1949
                pg->setGroup(pgIter->group);
1950
        }
1951
    }
1952
}
1953
 
14 andreas 1954
/**
1955
 * Delete a specific popup page from specified popup group if it exists.
1956
 */
11 andreas 1957
void TPageManager::doDPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)
1958
{
1959
    DECL_TRACER("TPageManager::doDPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
1960
 
1961
    if (pars.size() < 2)
1962
    {
1963
        MSG_ERROR("Less than 2 parameters!");
1964
        return;
1965
    }
1966
 
16 andreas 1967
    TError::clear();
11 andreas 1968
    SUBPAGELIST_T listPg = findSubPage(pars[0]);
1969
 
1970
    if (!listPg.isValid)
1971
        return;
1972
 
1973
    if (listPg.group.compare(pars[1]) == 0)
1974
    {
1975
        listPg.group.clear();
1976
        TSubPage *pg = getSubPage(listPg.pageID);
1977
 
1978
        if (pg)
1979
            pg->setGroup(listPg.group);
1980
    }
1981
}
1982
 
14 andreas 1983
/**
15 andreas 1984
 * Set the hide effect for the specified popup page to the named hide effect.
1985
 */
1986
void TPageManager::doPHE(int port, vector<int>& channels, vector<string>& pars)
1987
{
1988
    DECL_TRACER("TPageManager::doPHE(int port, vector<int>& channels, vector<string>& pars)");
1989
 
1990
    if (pars.size() < 2)
1991
    {
1992
        MSG_ERROR("Less than 2 parameters!");
1993
        return;
1994
    }
1995
 
16 andreas 1996
    TError::clear();
15 andreas 1997
    TSubPage *pg = getSubPage(pars[0]);
1998
 
1999
    if (!pg)
2000
    {
2001
        if (!readSubPage(pars[0]))
2002
            return;
2003
 
2004
        if ((pg = getSubPage(pars[0])) == nullptr)
2005
            return;
2006
 
2007
        TPage *page = getActualPage();
2008
 
2009
        if (page)
2010
            page->addSubPage(pg);
2011
    }
2012
 
2013
    if (pars[1].compare("fade") == 0)
2014
        pg->setHideEffect(SE_FADE);
2015
    else if (pars[1].compare("slide to left") == 0)
2016
        pg->setHideEffect(SE_SLIDE_LEFT);
2017
    else if (pars[1].compare("slide to right") == 0)
2018
        pg->setHideEffect(SE_SLIDE_RIGHT);
2019
    else if (pars[1].compare("slide to top") == 0)
2020
        pg->setHideEffect(SE_SLIDE_TOP);
2021
    else if (pars[1].compare("slide to bottom") == 0)
2022
        pg->setHideEffect(SE_SLIDE_BOTTOM);
2023
    else if (pars[1].compare("slide to left fade") == 0)
2024
        pg->setHideEffect(SE_SLIDE_LEFT_FADE);
2025
    else if (pars[1].compare("slide to right fade") == 0)
2026
        pg->setHideEffect(SE_SLIDE_RIGHT_FADE);
2027
    else if (pars[1].compare("slide to top fade") == 0)
2028
        pg->setHideEffect(SE_SLIDE_TOP_FADE);
2029
    else if (pars[1].compare("slide to bottom fade") == 0)
2030
        pg->setHideEffect(SE_SLIDE_BOTTOM_FADE);
2031
    else
2032
        pg->setHideEffect(SE_NONE);
2033
}
2034
 
2035
/**
2036
 * Set the hide effect position. Only 1 coordinate is ever needed for an effect;
2037
 * however, the command will specify both. This command sets the location at
2038
 * which the effect will end at.
2039
 */
2040
void TPageManager::doPHP(int port, vector<int>& channels, vector<string>& pars)
2041
{
2042
    DECL_TRACER("TPageManager::doPHP(int port, vector<int>& channels, vector<string>& pars)");
2043
 
2044
    if (pars.size() < 2)
2045
    {
2046
        MSG_ERROR("Less than 2 parameters!");
2047
        return;
2048
    }
2049
 
16 andreas 2050
    TError::clear();
15 andreas 2051
    size_t pos = pars[1].find(",");
2052
    int x, y;
2053
 
2054
    if (pos == string::npos)
2055
    {
2056
        x = atoi(pars[1].c_str());
2057
        y = 0;
2058
    }
2059
    else
2060
    {
2061
        x = atoi(pars[1].substr(0, pos).c_str());
2062
        y = atoi(pars[1].substr(pos+1).c_str());
2063
    }
2064
 
2065
    TSubPage *pg = getSubPage(pars[0]);
2066
 
2067
    if (!pg)
2068
    {
2069
        if (!readSubPage(pars[0]))
2070
            return;
2071
 
2072
        if ((pg = getSubPage(pars[0])) == nullptr)
2073
            return;
2074
 
2075
        TPage *page = getActualPage();
2076
 
2077
        if (page)
2078
            page->addSubPage(pg);
2079
    }
2080
 
2081
    pg->setHideEndPosition(x, y);
2082
}
2083
 
2084
/**
2085
 * Set the hide effect time for the specified popup page.
2086
 */
2087
void TPageManager::doPHT(int port, vector<int>& channels, vector<string>& pars)
2088
{
2089
    DECL_TRACER("TPageManager::doPHT(int port, vector<int>& channels, vector<string>& pars)");
2090
 
2091
    if (pars.size() < 2)
2092
    {
2093
        MSG_ERROR("Less than 2 parameters!");
2094
        return;
2095
    }
2096
 
16 andreas 2097
    TError::clear();
15 andreas 2098
    TSubPage *pg = getSubPage(pars[0]);
2099
 
2100
    if (!pg)
2101
    {
2102
        if (!readSubPage(pars[0]))
2103
            return;
2104
 
2105
        if ((pg = getSubPage(pars[0])) == nullptr)
2106
            return;
2107
 
2108
        TPage *page = getActualPage();
2109
 
2110
        if (page)
2111
            page->addSubPage(pg);
2112
    }
2113
 
2114
    pg->setHideTime(atoi(pars[1].c_str()));
2115
}
2116
 
2117
/**
14 andreas 2118
 * Close all popups on a specified page. If the page name is empty, the current
2119
 * page is used. Same as the ’Clear Page’ command in TPDesign4.
2120
 */
11 andreas 2121
void TPageManager::doPPA(int port, std::vector<int>& channels, std::vector<std::string>& pars)
2122
{
2123
    DECL_TRACER("TPageManager::doPPA(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
2124
 
16 andreas 2125
    TError::clear();
11 andreas 2126
    TPage *pg;
2127
 
2128
    if (pars.size() == 0)
2129
        pg = getPage(mActualPage);
2130
    else
2131
        pg = getPage(pars[0]);
2132
 
2133
    if (!pg)
2134
        return;
2135
 
12 andreas 2136
    pg->drop();
14 andreas 2137
    pg->resetZOrder();
11 andreas 2138
}
2139
 
14 andreas 2140
/**
2141
 * Deactivate a specific popup page on either a specified page or the current
2142
 * page. If the page name is empty, the current page is used. If the popup page
2143
 * is part of a group, the whole group is deactivated. This command works in
2144
 * the same way as the ’Hide Popup’ command in TPDesign4.
2145
 */
12 andreas 2146
void TPageManager::doPPF(int port, std::vector<int>& channels, std::vector<std::string>& pars)
2147
{
2148
    DECL_TRACER("TPageManager::doPPF(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
2149
 
2150
    if (pars.size() < 1)
2151
    {
2152
        MSG_ERROR("At least 1 parameter is expected!");
2153
        return;
2154
    }
2155
 
16 andreas 2156
    TError::clear();
14 andreas 2157
    hideSubPage(pars[0]);
12 andreas 2158
}
2159
 
14 andreas 2160
/**
2161
 * Toggle a specific popup page on either a specified page or the current page.
2162
 * If the page name is empty, the current page is used. Toggling refers to the
2163
 * activating/deactivating (On/Off) of a popup page. This command works in the
2164
 * same way as the ’Toggle Popup’ command in TPDesign4.
2165
 */
12 andreas 2166
void TPageManager::doPPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)
2167
{
2168
    DECL_TRACER("TPageManager::doPPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 2169
 
12 andreas 2170
    if (pars.size() < 1)
2171
    {
2172
        MSG_ERROR("At least 1 parameter is expected!");
2173
        return;
2174
    }
2175
 
16 andreas 2176
    TError::clear();
14 andreas 2177
    TPage *page = getPage(mActualPage);
2178
 
2179
    if (!page)
2180
    {
2181
        MSG_ERROR("No active page found! Internal error.");
2182
        return;
2183
    }
2184
 
12 andreas 2185
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 2186
 
12 andreas 2187
    if (!pg)
2188
        return;
14 andreas 2189
 
12 andreas 2190
    if (pg->isVisible())
2191
    {
14 andreas 2192
        if (pg->getZOrder() == page->getActZOrder())
2193
            page->decZOrder();
2194
 
12 andreas 2195
        pg->drop();
2196
        return;
2197
    }
2198
 
2199
    TSubPage *sub = getFirstSubPageGroup(pg->getGroupName());
14 andreas 2200
 
12 andreas 2201
    while(sub)
2202
    {
2203
        if (sub->getGroupName().compare(pg->getGroupName()) == 0 && sub->isVisible())
2204
            sub->drop();
14 andreas 2205
 
12 andreas 2206
        sub = getNextSubPageGroup(pg->getGroupName(), sub);
2207
    }
2208
 
2209
    pg->show();
14 andreas 2210
    pg->setZOrder(page->getNextZOrder());
12 andreas 2211
}
2212
 
14 andreas 2213
/**
2214
 * Kill refers to the deactivating (Off) of a popup window from all pages. If
2215
 * the pop-up page is part of a group, the whole group is deactivated. This
2216
 * command works in the same way as the 'Clear Group' command in TPDesign 4.
2217
 */
12 andreas 2218
void TPageManager::doPPK(int port, std::vector<int>& channels, std::vector<std::string>& pars)
2219
{
2220
    DECL_TRACER("TPageManager::doPPK(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 2221
 
12 andreas 2222
    if (pars.size() < 1)
2223
    {
2224
        MSG_ERROR("At least 1 parameter is expected!");
2225
        return;
2226
    }
2227
 
16 andreas 2228
    TError::clear();
14 andreas 2229
    TPage *page = getPage(mActualPage);
2230
 
2231
    if (!page)
2232
    {
2233
        MSG_ERROR("No active page found! Internal error.");
2234
        return;
2235
    }
2236
 
12 andreas 2237
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 2238
 
12 andreas 2239
    if (pg)
14 andreas 2240
    {
2241
        if (pg->getZOrder() == page->getActZOrder())
2242
            page->decZOrder();
2243
 
2244
        pg->drop();
2245
    }
12 andreas 2246
}
2247
 
14 andreas 2248
/**
2249
 * Set the modality of a specific popup page to Modal or NonModal.
2250
 * A Modal popup page, when active, only allows you to use the buttons and
2251
 * features on that popup page. All other buttons on the panel page are
2252
 * inactivated.
2253
 */
12 andreas 2254
void TPageManager::doPPM(int port, std::vector<int>& channels, std::vector<std::string>& pars)
2255
{
2256
    DECL_TRACER("TPageManager::doPPM(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 2257
 
12 andreas 2258
    if (pars.size() < 2)
2259
    {
2260
        MSG_ERROR("Expecting 2 parameters!");
2261
        return;
2262
    }
14 andreas 2263
 
16 andreas 2264
    TError::clear();
12 andreas 2265
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 2266
 
12 andreas 2267
    if (pg)
2268
    {
2269
        if (pars[1] == "1" || pars[1].compare("modal") == 0 || pars[1].compare("MODAL") == 0)
2270
            pg->setModal(1);
2271
        else
2272
            pg->setModal(0);
2273
    }
2274
}
2275
 
14 andreas 2276
/**
2277
 * Activate a specific popup page to launch on either a specified page or the
2278
 * current page. If the page name is empty, the current page is used. If the
2279
 * popup page is already on, do not re-draw it. This command works in the same
2280
 * way as the ’Show Popup’ command in TPDesign4.
2281
 */
12 andreas 2282
void TPageManager::doPPN(int port, std::vector<int>& channels, std::vector<std::string>& pars)
2283
{
2284
    DECL_TRACER("TPageManager::doPPN(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
2285
 
2286
    if (pars.size() < 1)
2287
    {
2288
        MSG_ERROR("At least 1 parameter is expected!");
2289
        return;
2290
    }
2291
 
16 andreas 2292
    TError::clear();
14 andreas 2293
    showSubPage(pars[0]);
12 andreas 2294
}
2295
 
14 andreas 2296
/**
15 andreas 2297
 * Set a specific popup page to timeout within a specified time. If timeout is
2298
 * empty, popup page will clear the timeout.
2299
 */
2300
void TPageManager::doPPT(int port, vector<int>& channels, vector<string>& pars)
2301
{
2302
    DECL_TRACER("TPageManager::doPPT(int port, vector<int>& channels, vector<string>& pars)");
2303
 
2304
    if (pars.size() < 2)
2305
    {
2306
        MSG_ERROR("Expecting 2 parameters!");
2307
        return;
2308
    }
2309
 
16 andreas 2310
    TError::clear();
15 andreas 2311
    TSubPage *pg = getSubPage(pars[0]);
2312
 
2313
    if (!pg)
2314
    {
2315
        if (!readSubPage(pars[0]))
2316
            return;
2317
 
2318
        if ((pg = getSubPage(pars[0])) == nullptr)
2319
            return;
2320
 
2321
        TPage *page = getActualPage();
2322
 
2323
        if (page)
2324
            page->addSubPage(pg);
2325
    }
2326
 
2327
    pg->setTimeout(atoi(pars[1].c_str()));
2328
}
2329
 
2330
/**
14 andreas 2331
 * Close all popups on all pages. This command works in the same way as the
2332
 * 'Clear All' command in TPDesign 4.
2333
 */
12 andreas 2334
void TPageManager::doPPX(int port, std::vector<int>& channels, std::vector<std::string>& pars)
2335
{
2336
    DECL_TRACER("TPageManager::doPPX(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
2337
 
16 andreas 2338
    TError::clear();
12 andreas 2339
    PCHAIN_T *chain = mPchain;
14 andreas 2340
 
12 andreas 2341
    while(chain)
2342
    {
2343
        TSubPage *sub = chain->page->getFirstSubPage();
14 andreas 2344
 
12 andreas 2345
        while (sub)
2346
        {
14 andreas 2347
            MSG_DEBUG("Dopping subpage " << sub->getNumber() << ", \"" << sub->getName() << "\".");
12 andreas 2348
            sub->drop();
2349
            sub = chain->page->getNextSubPage();
2350
        }
14 andreas 2351
 
12 andreas 2352
        chain = chain->next;
2353
    }
14 andreas 2354
 
2355
    TPage *page = getPage(mActualPage);
2356
 
2357
    if (!page)
2358
    {
2359
        MSG_ERROR("No active page found! Internal error.");
2360
        return;
2361
    }
2362
 
2363
    page->resetZOrder();
12 andreas 2364
}
2365
 
14 andreas 2366
/**
15 andreas 2367
 * Set the show effect for the specified popup page to the named show effect.
2368
 */
2369
void TPageManager::doPSE(int port, vector<int>& channels, vector<string>& pars)
2370
{
2371
    DECL_TRACER("TPageManager::doPSE(int port, vector<int>& channels, vector<string>& pars)");
2372
 
2373
    if (pars.size() < 2)
2374
    {
2375
        MSG_ERROR("Less than 2 parameters!");
2376
        return;
2377
    }
2378
 
16 andreas 2379
    TError::clear();
15 andreas 2380
    TSubPage *pg = getSubPage(pars[0]);
2381
 
2382
    if (!pg)
2383
    {
2384
        if (!readSubPage(pars[0]))
2385
            return;
2386
 
2387
        if ((pg = getSubPage(pars[0])) == nullptr)
2388
            return;
2389
 
2390
        TPage *page = getActualPage();
2391
 
2392
        if (page)
2393
            page->addSubPage(pg);
2394
    }
2395
 
2396
    if (pars[1].compare("fade") == 0)
2397
        pg->setShowEffect(SE_FADE);
2398
    else if (pars[1].compare("slide to left") == 0)
2399
        pg->setShowEffect(SE_SLIDE_LEFT);
2400
    else if (pars[1].compare("slide to right") == 0)
2401
        pg->setShowEffect(SE_SLIDE_RIGHT);
2402
    else if (pars[1].compare("slide to top") == 0)
2403
        pg->setShowEffect(SE_SLIDE_TOP);
2404
    else if (pars[1].compare("slide to bottom") == 0)
2405
        pg->setShowEffect(SE_SLIDE_BOTTOM);
2406
    else if (pars[1].compare("slide to left fade") == 0)
2407
        pg->setShowEffect(SE_SLIDE_LEFT_FADE);
2408
    else if (pars[1].compare("slide to right fade") == 0)
2409
        pg->setShowEffect(SE_SLIDE_RIGHT_FADE);
2410
    else if (pars[1].compare("slide to top fade") == 0)
2411
        pg->setShowEffect(SE_SLIDE_TOP_FADE);
2412
    else if (pars[1].compare("slide to bottom fade") == 0)
2413
        pg->setShowEffect(SE_SLIDE_BOTTOM_FADE);
2414
    else
2415
        pg->setShowEffect(SE_NONE);
2416
}
2417
 
2418
void TPageManager::doPSP(int port, vector<int>& channels, vector<string>& pars)
2419
{
2420
    DECL_TRACER("TPageManager::doPSP(int port, vector<int>& channels, vector<string>& pars)");
2421
 
2422
    if (pars.size() < 2)
2423
    {
2424
        MSG_ERROR("Less than 2 parameters!");
2425
        return;
2426
    }
2427
 
16 andreas 2428
    TError::clear();
15 andreas 2429
    size_t pos = pars[1].find(",");
2430
    int x, y;
2431
 
2432
    if (pos == string::npos)
2433
    {
2434
        x = atoi(pars[1].c_str());
2435
        y = 0;
2436
    }
2437
    else
2438
    {
2439
        x = atoi(pars[1].substr(0, pos).c_str());
2440
        y = atoi(pars[1].substr(pos+1).c_str());
2441
    }
2442
 
2443
    TSubPage *pg = getSubPage(pars[0]);
2444
 
2445
    if (!pg)
2446
    {
2447
        if (!readSubPage(pars[0]))
2448
            return;
2449
 
2450
        if ((pg = getSubPage(pars[0])) == nullptr)
2451
            return;
2452
 
2453
        TPage *page = getActualPage();
2454
 
2455
        if (page)
2456
            page->addSubPage(pg);
2457
    }
2458
 
2459
    pg->setShowEndPosition(x, y);
2460
}
2461
 
2462
/**
2463
 * Set the show effect time for the specified popup page.
2464
 */
2465
void TPageManager::doPST(int port, vector<int>& channels, vector<string>& pars)
2466
{
2467
    DECL_TRACER("TPageManager::doPST(int port, vector<int>& channels, vector<string>& pars)");
2468
 
2469
    if (pars.size() < 2)
2470
    {
2471
        MSG_ERROR("Less than 2 parameters!");
2472
        return;
2473
    }
2474
 
16 andreas 2475
    TError::clear();
15 andreas 2476
    size_t pos = pars[1].find(",");
2477
    int x, y;
2478
 
2479
    if (pos == string::npos)
2480
    {
2481
        x = atoi(pars[1].c_str());
2482
        y = 0;
2483
    }
2484
    else
2485
    {
2486
        x = atoi(pars[1].substr(0, pos).c_str());
2487
        y = atoi(pars[1].substr(pos+1).c_str());
2488
    }
2489
 
2490
    TSubPage *pg = getSubPage(pars[0]);
2491
 
2492
    if (!pg)
2493
    {
2494
        if (!readSubPage(pars[0]))
2495
            return;
2496
 
2497
        if ((pg = getSubPage(pars[0])) == nullptr)
2498
            return;
2499
 
2500
        TPage *page = getActualPage();
2501
 
2502
        if (page)
2503
            page->addSubPage(pg);
2504
    }
2505
 
2506
    pg->setShowTime(atoi(pars[1].c_str()));
2507
}
2508
 
2509
/**
14 andreas 2510
 * Flips to a page with a specified page name. If the page is currently active,
2511
 * it will not redraw the page.
2512
 */
12 andreas 2513
void TPageManager::doPAGE(int port, std::vector<int>& channels, std::vector<std::string>& pars)
2514
{
2515
    DECL_TRACER("TPageManager::doPAGE(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 2516
 
15 andreas 2517
    if (pars.empty())
2518
    {
2519
        MSG_WARNING("Got no page parameter!");
2520
        return;
2521
    }
14 andreas 2522
 
16 andreas 2523
    TError::clear();
15 andreas 2524
    setPage(pars[0]);
2525
}
2526
 
2527
/**
2528
 * Add page flip action to a button if it does not already exist.
2529
 */
2530
void TPageManager::doAPF(int port, vector<int>& channels, vector<string>& pars)
2531
{
2532
    DECL_TRACER("TPageManager::doAPF(int port, vector<int>& channels, vector<string>& pars)");
2533
 
2534
    if (pars.size() < 2)
2535
    {
2536
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
14 andreas 2537
        return;
15 andreas 2538
    }
14 andreas 2539
 
16 andreas 2540
    TError::clear();
15 andreas 2541
    string action = pars[0];
2542
    string pname = pars[1];
14 andreas 2543
 
15 andreas 2544
    vector<MAP_T> map = findButtons(port, channels);
14 andreas 2545
 
15 andreas 2546
    if (TError::isError() || map.empty())
2547
        return;
2548
 
2549
    vector<Button::TButton *> buttons = collectButtons(map);
2550
    vector<Button::TButton *>::iterator mapIter;
2551
 
2552
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
12 andreas 2553
    {
15 andreas 2554
        Button::TButton *bt = *mapIter;
18 andreas 2555
        setButtonCallbacks(bt);
15 andreas 2556
        bt->addPushFunction(action, pname);
2557
    }
2558
}
12 andreas 2559
 
15 andreas 2560
/**
2561
 * Assign a picture to those buttons with a defined address range.
2562
 */
2563
void TPageManager::doBMP(int port, vector<int>& channels, vector<string>& pars)
2564
{
2565
    DECL_TRACER("TPageManager::doBMP(int port, vector<int>& channels, vector<string>& pars)");
2566
 
2567
    if (pars.size() < 2)
2568
    {
2569
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
12 andreas 2570
        return;
2571
    }
14 andreas 2572
 
16 andreas 2573
    TError::clear();
15 andreas 2574
    int btState = atoi(pars[0].c_str());
2575
    string bitmap = pars[1];
14 andreas 2576
 
15 andreas 2577
    vector<MAP_T> map = findButtons(port, channels);
2578
 
2579
    if (TError::isError() || map.empty())
2580
        return;
2581
 
2582
    vector<Button::TButton *> buttons = collectButtons(map);
2583
    vector<Button::TButton *>::iterator mapIter;
2584
 
2585
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
2586
    {
2587
        Button::TButton *bt = *mapIter;
18 andreas 2588
        setButtonCallbacks(bt);
15 andreas 2589
 
2590
        if (btState == 0)       // All instances?
2591
        {
2592
            int bst = bt->getNumberInstances();
2593
            MSG_DEBUG("Setting bitmal " << bitmap << " on all " << bst << " instances...");
2594
 
2595
            for (int i = 0; i < bst; i++)
2596
                bt->setBitmap(bitmap, i);
2597
        }
2598
        else
2599
            bt->setBitmap(bitmap, btState);
2600
    }
12 andreas 2601
}
2602
 
18 andreas 2603
void TPageManager::setButtonCallbacks(Button::TButton *bt)
2604
{
2605
    bt->registerCallback(_displayButton);
2606
    bt->registerCallbackFT(_setText);
21 andreas 2607
    bt->regCallPlayVideo(_callPlayVideo);
18 andreas 2608
    bt->setFonts(mFonts);
2609
    bt->setPalette(mPalette);
2610
}
2611
 
14 andreas 2612
/**
16 andreas 2613
 * Set the button opacity. The button opacity can be specified as a decimal
2614
 * between 0 - 255, where zero (0) is invisible and 255 is opaque, or as a
2615
 * HEX code, as used in the color commands by preceding the HEX code with
2616
 * the # sign. In this case, #00 becomes invisible and #FF becomes opaque.
2617
 * If the opacity is set to zero (0), this does not make the button inactive,
2618
 * only invisible.
2619
 */
2620
void TPageManager::doBOP(int port, vector<int>& channels, vector<string>& pars)
2621
{
2622
    DECL_TRACER("TPageManager::doBOP(int port, vector<int>& channels, vector<string>& pars)");
2623
 
2624
    if (pars.size() < 2)
2625
    {
2626
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
2627
        return;
2628
    }
2629
 
2630
    TError::clear();
2631
    int btState = atoi(pars[0].c_str());
2632
    int btOpacity = 0;
2633
 
2634
    if (pars[1].at(0) == '#')
2635
        btOpacity = (int)strtol(pars[1].substr(1).c_str(), NULL, 16);
2636
    else
2637
        btOpacity = atoi(pars[1].c_str());
2638
 
2639
    vector<MAP_T> map = findButtons(port, channels);
2640
 
2641
    if (TError::isError() || map.empty())
2642
        return;
2643
 
2644
    vector<Button::TButton *> buttons = collectButtons(map);
2645
    vector<Button::TButton *>::iterator mapIter;
2646
 
2647
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
2648
    {
2649
        Button::TButton *bt = *mapIter;
18 andreas 2650
        setButtonCallbacks(bt);
16 andreas 2651
 
2652
        if (btState == 0)       // All instances?
2653
        {
2654
            int bst = bt->getNumberInstances();
2655
            MSG_DEBUG("Setting opacity " << btOpacity << " on all " << bst << " instances...");
2656
 
2657
            for (int i = 0; i < bst; i++)
2658
                bt->setOpacity(btOpacity, i);
2659
        }
2660
        else
2661
            bt->setOpacity(btOpacity, btState);
2662
    }
2663
}
2664
 
2665
/**
2666
 * Set the button size and its position on the page.
2667
 */
2668
void TPageManager::doBSP(int port, vector<int>& channels, vector<string>& pars)
2669
{
2670
    DECL_TRACER("TPageManager::doBSP(int port, vector<int>& channels, vector<string>& pars)");
2671
 
2672
    if (pars.size() < 1)
2673
    {
2674
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
2675
        return;
2676
    }
2677
 
2678
    TError::clear();
2679
    bool bLeft = false, bTop = false, bRight = false, bBottom = false;
2680
    int x, y;
2681
    vector<string>::iterator iter;
2682
 
2683
    for (iter = pars.begin(); iter != pars.end(); iter++)
2684
    {
2685
        if (iter->compare("left") == 0)
2686
            bLeft = true;
2687
        else if (iter->compare("top") == 0)
2688
            bTop = true;
2689
        else if (iter->compare("right") == 0)
2690
            bRight = true;
2691
        else if (iter->compare("bottom") == 0)
2692
            bBottom = true;
2693
    }
2694
 
2695
 
2696
    vector<MAP_T> map = findButtons(port, channels);
2697
 
2698
    if (TError::isError() || map.empty())
2699
        return;
2700
 
2701
    vector<Button::TButton *> buttons = collectButtons(map);
2702
    vector<Button::TButton *>::iterator mapIter;
2703
 
2704
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
2705
    {
2706
        Button::TButton *bt = *mapIter;
18 andreas 2707
        setButtonCallbacks(bt);
16 andreas 2708
 
2709
        if (bLeft)
2710
            x = 0;
2711
 
2712
        if (bTop)
2713
            y = 0;
2714
 
2715
        if (bRight)
2716
        {
2717
            ulong handle = bt->getHandle();
2718
            int parentID = (handle >> 16) & 0x0000ffff;
2719
            int pwidth = 0;
2720
 
2721
            if (parentID < 500)
2722
            {
2723
                TPage *pg = getPage(parentID);
2724
 
2725
                if (!pg)
2726
                {
2727
                    MSG_ERROR("Internal error: Page " << parentID << " not found!");
2728
                    return;
2729
                }
2730
 
2731
                pwidth = pg->getWidth();
2732
            }
2733
            else
2734
            {
2735
                TSubPage *spg = getSubPage(parentID);
2736
 
2737
                if (!spg)
2738
                {
2739
                    MSG_ERROR("Internal error: Subpage " << parentID << " not found!");
2740
                    return;
2741
                }
2742
 
2743
                pwidth = spg->getWidth();
2744
            }
2745
 
2746
            x = pwidth - bt->getWidth();
2747
        }
2748
 
2749
        if (bBottom)
2750
        {
2751
            ulong handle = bt->getHandle();
2752
            int parentID = (handle >> 16) & 0x0000ffff;
2753
            int pheight = 0;
2754
 
2755
            if (parentID < 500)
2756
            {
2757
                TPage *pg = getPage(parentID);
2758
 
2759
                if (!pg)
2760
                {
2761
                    MSG_ERROR("Internal error: Page " << parentID << " not found!");
2762
                    return;
2763
                }
2764
 
2765
                pheight = pg->getHeight();
2766
            }
2767
            else
2768
            {
2769
                TSubPage *spg = getSubPage(parentID);
2770
 
2771
                if (!spg)
2772
                {
2773
                    MSG_ERROR("Internal error: Subpage " << parentID << " not found!");
2774
                    return;
2775
                }
2776
 
2777
                pheight = spg->getHeight();
2778
            }
2779
 
2780
            y = pheight - bt->getHeight();
2781
        }
2782
 
2783
        bt->setLeftTop(x, y);
2784
    }
2785
}
2786
 
2787
/**
2788
 * Set the button word wrap feature to those buttons with a defined address
2789
 * range. By default, word-wrap is Off.
2790
 */
2791
void TPageManager::doBWW(int port, vector<int>& channels, vector<string>& pars)
2792
{
2793
    DECL_TRACER("TPageManager::doBWW(int port, vector<int>& channels, vector<string>& pars)");
2794
 
2795
    if (pars.size() < 1)
2796
    {
2797
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
2798
        return;
2799
    }
2800
 
2801
    TError::clear();
2802
    int btState = atoi(pars[0].c_str());
2803
 
2804
    vector<MAP_T> map = findButtons(port, channels);
2805
 
2806
    if (TError::isError() || map.empty())
2807
        return;
2808
 
2809
    vector<Button::TButton *> buttons = collectButtons(map);
2810
    vector<Button::TButton *>::iterator mapIter;
2811
 
2812
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
2813
    {
2814
        Button::TButton *bt = *mapIter;
18 andreas 2815
        setButtonCallbacks(bt);
16 andreas 2816
 
2817
        if (btState == 0)       // All instances?
2818
        {
2819
            int bst = bt->getNumberInstances();
2820
            MSG_DEBUG("Setting word wrap on all " << bst << " instances...");
2821
 
2822
            for (int i = 0; i < bst; i++)
2823
                bt->setWorWrap(true, i);
2824
        }
2825
        else
2826
            bt->setWorWrap(true, btState - 1);
2827
    }
2828
}
2829
 
2830
/**
2831
 * Clear all page flips from a button.
2832
 */
2833
void TPageManager::doCPF(int port, vector<int>& channels, vector<string>& pars)
2834
{
2835
    DECL_TRACER("TPageManager::doCPF(int port, vector<int>& channels, vector<string>& pars)");
2836
 
2837
    TError::clear();
2838
    vector<MAP_T> map = findButtons(port, channels);
2839
 
2840
    if (TError::isError() || map.empty())
2841
        return;
2842
 
2843
    vector<Button::TButton *> buttons = collectButtons(map);
2844
    vector<Button::TButton *>::iterator mapIter;
2845
 
2846
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
2847
    {
2848
        Button::TButton *bt = *mapIter;
18 andreas 2849
        setButtonCallbacks(bt);
16 andreas 2850
        bt->clearPushFunctions();
2851
    }
2852
}
2853
 
2854
/**
2855
 * Delete page flips from button if it already exists.
2856
 */
2857
void TPageManager::doDPF(int port, vector<int>& channels, vector<string>& pars)
2858
{
2859
    DECL_TRACER("TPageManager::doDPF(int port, vector<int>& channels, vector<string>& pars)");
2860
 
2861
    if (pars.size() < 1)
2862
    {
2863
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
2864
        return;
2865
    }
2866
 
2867
    TError::clear();
2868
    string action = pars[0];
2869
    string pname;
2870
 
2871
    if (pars.size() >= 2)
2872
    {
2873
        pname = pars[1];
2874
        vector<Button::TButton *> list;
2875
        // First we search for a subpage because this is more likely
2876
        TSubPage *spg = getSubPage(pname);
2877
 
2878
        if (spg)
2879
            list = spg->getButtons(port, channels[0]);
2880
        else    // Then for a page
2881
        {
2882
            TPage *pg = getPage(pname);
2883
 
2884
            if (pg)
2885
                list = pg->getButtons(port, channels[0]);
2886
            else
2887
            {
2888
                MSG_WARNING("The name " << pname << " doesn't name either a page or a subpage!");
2889
                return;
2890
            }
2891
        }
2892
 
2893
        if (list.empty())
2894
            return;
2895
 
2896
        vector<Button::TButton *>::iterator it;
2897
 
2898
        for (it = list.begin(); it != list.end(); it++)
2899
        {
2900
            Button::TButton *bt = *it;
18 andreas 2901
            setButtonCallbacks(bt);
16 andreas 2902
            bt->clearPushFunction(action);
2903
        }
2904
 
2905
        return;
2906
    }
2907
 
2908
    // Here we don't have a page name
2909
    vector<MAP_T> map = findButtons(port, channels);
2910
 
2911
    if (TError::isError() || map.empty())
2912
        return;
2913
 
2914
    vector<Button::TButton *> buttons = collectButtons(map);
2915
    vector<Button::TButton *>::iterator mapIter;
2916
 
2917
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
2918
    {
2919
        Button::TButton *bt = *mapIter;
18 andreas 2920
        setButtonCallbacks(bt);
16 andreas 2921
        bt->clearPushFunction(action);
2922
    }
2923
}
2924
 
2925
/**
2926
 * Enable or disable buttons with a set variable text range.
2927
 */
2928
void TPageManager::doENA(int port, vector<int>& channels, vector<string>& pars)
2929
{
2930
    DECL_TRACER("TPageManager::doENA(int port, vector<int>& channels, vector<string>& pars)");
2931
 
2932
    if (pars.empty())
2933
    {
2934
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
2935
        return;
2936
    }
2937
 
2938
    TError::clear();
2939
    int cvalue = atoi(pars[0].c_str());
2940
 
2941
    vector<MAP_T> map = findButtons(port, channels);
2942
 
2943
    if (TError::isError() || map.empty())
2944
        return;
2945
 
2946
    vector<Button::TButton *> buttons = collectButtons(map);
2947
    vector<Button::TButton *>::iterator mapIter;
2948
 
2949
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
2950
    {
2951
        Button::TButton *bt = *mapIter;
18 andreas 2952
        setButtonCallbacks(bt);
16 andreas 2953
        bt->setEnable(((cvalue)?true:false));
2954
    }
2955
}
2956
 
2957
/**
2958
 * Set a font to a specific Font ID value for those buttons with a defined
2959
 * address range. Font ID numbers are generated by the TPDesign4 programmers
2960
 * report.
2961
 */
2962
void TPageManager::doFON(int port, vector<int>& channels, vector<string>& pars)
2963
{
2964
    DECL_TRACER("TPageManager::doFON(int port, vector<int>& channels, vector<string>& pars)");
2965
 
2966
    if (pars.size() < 2)
2967
    {
2968
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
2969
        return;
2970
    }
2971
 
2972
    TError::clear();
2973
    int btState = atoi(pars[0].c_str());
2974
    int fvalue = atoi(pars[1].c_str());
2975
 
2976
    vector<MAP_T> map = findButtons(port, channels);
2977
 
2978
    if (TError::isError() || map.empty())
2979
        return;
2980
 
2981
    vector<Button::TButton *> buttons = collectButtons(map);
2982
    vector<Button::TButton *>::iterator mapIter;
2983
 
2984
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
2985
    {
2986
        Button::TButton *bt = *mapIter;
18 andreas 2987
        setButtonCallbacks(bt);
16 andreas 2988
 
2989
        if (btState == 0)       // All instances?
2990
        {
2991
            int bst = bt->getNumberInstances();
2992
            MSG_DEBUG("Setting font " << fvalue << " on all " << bst << " instances...");
2993
 
2994
            for (int i = 0; i < bst; i++)
2995
                bt->setFont(fvalue, i);
2996
        }
2997
        else
2998
            bt->setFont(fvalue, btState - 1);
2999
    }
3000
}
3001
 
3002
/**
14 andreas 3003
 * Set the icon to a button.
3004
 */
3005
void TPageManager::doICO(int port, vector<int>& channels, vector<string>& pars)
3006
{
3007
    DECL_TRACER("TPageManager::doICO(int port, vector<int>& channels, vector<string>& pars)");
3008
 
3009
    if (pars.size() < 2)
3010
    {
3011
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
3012
        return;
3013
    }
3014
 
16 andreas 3015
    TError::clear();
14 andreas 3016
    int btState = atoi(pars[0].c_str());
3017
    int iconIdx = atoi(pars[1].c_str());
3018
 
3019
    vector<MAP_T> map = findButtons(port, channels);
3020
 
3021
    if (TError::isError() || map.empty())
3022
        return;
3023
 
3024
    vector<Button::TButton *> buttons = collectButtons(map);
3025
    vector<Button::TButton *>::iterator mapIter;
3026
 
3027
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
3028
    {
3029
        Button::TButton *bt = *mapIter;
18 andreas 3030
        setButtonCallbacks(bt);
14 andreas 3031
 
3032
        if (btState == 0)       // All instances?
3033
        {
3034
            int bst = bt->getNumberInstances();
3035
            MSG_DEBUG("Setting Icon on all " << bst << " instances...");
3036
 
3037
            for (int i = 0; i < bst; i++)
3038
            {
3039
                if (iconIdx > 0)
3040
                    bt->setIcon(iconIdx, i);
3041
                else
3042
                    bt->revokeIcon(i);
3043
            }
3044
        }
3045
        else if (iconIdx > 0)
3046
            bt->setIcon(iconIdx, btState - 1);
3047
        else
3048
            bt->revokeIcon(btState - 1);
3049
    }
3050
}
3051
 
3052
/**
16 andreas 3053
 * Show or hide a button with a set variable text range.
3054
 */
3055
void TPageManager::doSHO(int port, vector<int>& channels, vector<string>& pars)
3056
{
3057
    DECL_TRACER("TPageManager::doSHO(int port, vector<int>& channels, vector<string>& pars)");
3058
 
3059
    if (pars.empty())
3060
    {
3061
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
3062
        return;
3063
    }
3064
 
3065
    TError::clear();
3066
    int cvalue = atoi(pars[0].c_str());
3067
 
3068
    vector<MAP_T> map = findButtons(port, channels);
3069
 
3070
    if (TError::isError() || map.empty())
3071
        return;
3072
 
3073
    vector<Button::TButton *> buttons = collectButtons(map);
3074
    vector<Button::TButton *>::iterator mapIter;
3075
 
3076
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
3077
    {
3078
        Button::TButton *bt = *mapIter;
18 andreas 3079
        setButtonCallbacks(bt);
16 andreas 3080
        bt->setVisible(((cvalue)?true:false));
3081
        bt->refresh();
3082
    }
3083
}
3084
 
3085
/**
14 andreas 3086
 * Assign a text string to those buttons with a defined address range.
3087
 * Sets Non-Unicode text.
3088
 */
3089
void TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)
3090
{
3091
    DECL_TRACER("TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)");
3092
 
3093
    if (pars.size() < 1)
3094
    {
3095
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
3096
        return;
3097
    }
3098
 
16 andreas 3099
    TError::clear();
14 andreas 3100
    int btState = atoi(pars[0].c_str());
3101
    string text;
3102
 
3103
    if (pars.size() > 1)
3104
        text = pars[1];
3105
 
3106
    vector<MAP_T> map = findButtons(port, channels);
3107
 
3108
    if (TError::isError() || map.empty())
3109
        return;
3110
 
3111
    vector<Button::TButton *> buttons = collectButtons(map);
3112
    vector<Button::TButton *>::iterator mapIter;
3113
 
3114
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
3115
    {
3116
        Button::TButton *bt = *mapIter;
18 andreas 3117
        setButtonCallbacks(bt);
14 andreas 3118
 
3119
        if (btState == 0)       // All instances?
3120
        {
3121
            int bst = bt->getNumberInstances();
3122
            MSG_DEBUG("Setting TXT on all " << bst << " instances...");
3123
 
3124
            for (int i = 0; i < bst; i++)
3125
                bt->setText(text, i);
3126
        }
3127
        else
3128
            bt->setText(text, btState - 1);
3129
    }
3130
}
21 andreas 3131
 
3132
void TPageManager::doBBR(int port, vector<int>& channels, vector<string>& pars)
3133
{
3134
    DECL_TRACER("TPageManager::doBBR(int port, vector<int>& channels, vector<string>& pars)");
3135
 
3136
    if (pars.size() < 2)
3137
    {
3138
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
3139
        return;
3140
    }
3141
 
3142
    TError::clear();
3143
    int btState = atoi(pars[0].c_str());
3144
    string resName = pars[1];
3145
 
3146
    vector<MAP_T> map = findButtons(port, channels);
3147
 
3148
    if (TError::isError() || map.empty())
3149
        return;
3150
 
3151
    vector<Button::TButton *> buttons = collectButtons(map);
3152
    vector<Button::TButton *>::iterator mapIter;
3153
 
3154
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
3155
    {
3156
        Button::TButton *bt = *mapIter;
3157
        setButtonCallbacks(bt);
3158
 
3159
        if (btState == 0)       // All instances?
3160
        {
3161
            int bst = bt->getNumberInstances();
3162
            MSG_DEBUG("Setting BBR on all " << bst << " instances...");
3163
 
3164
            for (int i = 0; i < bst; i++)
3165
                bt->setResourceName(resName, i);
3166
        }
3167
        else
3168
            bt->setResourceName(resName, btState - 1);
3169
    }
3170
}
3171
 
3172
void TPageManager::doRMF(int port, vector<int>& channels, vector<string>& pars)
3173
{
3174
    DECL_TRACER("TPageManager::doRMF(int port, vector<int>& channels, vector<string>& pars)");
3175
 
3176
    if (pars.size() < 2)
3177
    {
3178
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
3179
        return;
3180
    }
3181
 
3182
    string name = pars[0];
3183
    string data = pars[1];
3184
 
3185
    vector<string> parts = StrSplit(data, "%");
3186
    RESOURCE_T res;
3187
    vector<string>::iterator sIter;
3188
 
3189
    for (sIter = parts.begin(); sIter != parts.end(); sIter++)
3190
    {
3191
        const char *s = sIter->c_str();
3192
        MSG_DEBUG("Parsing \"" << s << "\" with token << " << *s);
3193
 
3194
        switch(*s)
3195
        {
3196
            case 'P':
3197
                if (*(s+1) == '0')
3198
                    res.protocol = "HTTP";
3199
                else
3200
                    res.protocol = "FTP";
3201
            break;
3202
 
3203
            case 'U': res.user = sIter->substr(1); break;
3204
            case 'S': res.password = sIter->substr(1); break;
3205
            case 'H': res.host = sIter->substr(1); break;
3206
            case 'F': res.file = sIter->substr(1); break;
3207
            case 'A': res.path = sIter->substr(1); break;
3208
            case 'R': res.refresh = atoi(sIter->substr(1).c_str()); break;
3209
 
3210
            default:
3211
                MSG_WARNING("Option " << sIter->at(0) << " is currently not implemented!");
3212
        }
3213
    }
3214
 
3215
    if (gPrjResources)
3216
        gPrjResources->setResource(name, res.protocol, res.host, res.path, res.file, res.user, res.password, res.refresh);
3217
}