Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 andreas 1
/*
89 andreas 2
 * Copyright (C) 2020 to 2022 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>
36 andreas 22
#ifdef __ANDROID__
23
#include <QtAndroidExtras/QAndroidJniObject>
24
#include <QtAndroid>
61 andreas 25
#include <android/log.h>
36 andreas 26
#endif
14 andreas 27
 
3 andreas 28
#include "tpagemanager.h"
4 andreas 29
#include "tcolor.h"
3 andreas 30
#include "terror.h"
8 andreas 31
#include "ticons.h"
14 andreas 32
#include "tbutton.h"
8 andreas 33
#include "tprjresources.h"
11 andreas 34
#include "tresources.h"
51 andreas 35
#include "tobject.h"
71 andreas 36
#include "tsystemsound.h"
37
#include "tvalidatefile.h"
3 andreas 38
 
39
using std::vector;
40
using std::string;
11 andreas 41
using std::map;
42
using std::pair;
43
using std::to_string;
14 andreas 44
using std::thread;
45
using std::atomic;
46
using std::mutex;
21 andreas 47
using std::bind;
3 andreas 48
 
8 andreas 49
TIcons *gIcons = nullptr;
50
TPrjResources *gPrjResources = nullptr;
14 andreas 51
TPageManager *gPageManager = nullptr;
52
extern amx::TAmxNet *gAmxNet;
90 andreas 53
extern std::atomic<bool> _netRunning;
92 andreas 54
extern bool _restart_;                          //!< If this is set to true then the whole program will start over.
8 andreas 55
 
14 andreas 56
mutex surface_mutex;
21 andreas 57
bool prg_stopped = false;
14 andreas 58
 
37 andreas 59
#ifdef __ANDROID__
38 andreas 60
JNIEXPORT void JNICALL Java_org_qtproject_theosys_BatteryState_informBatteryStatus(JNIEnv *, jclass, jint level, jboolean charging, jint chargeType)
61
{
61 andreas 62
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_BatteryState_informBatteryStatus(JNIEnv *, jclass, jint level, jboolean charging, jint chargeType)");
63
 
38 andreas 64
    if (gPageManager)
65
        gPageManager->informBatteryStatus(level, charging, chargeType);
66
}
67
 
36 andreas 68
JNIEXPORT void JNICALL Java_org_qtproject_theosys_NetworkStatus_informTPanelNetwork(JNIEnv */*env*/, jclass /*clazz*/, jboolean conn, jint level, jint type)
69
{
61 andreas 70
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_NetworkStatus_informTPanelNetwork(JNIEnv */*env*/, jclass /*clazz*/, jboolean conn, jint level, jint type)");
36 andreas 71
   //Call native side conterpart
72
   if (gPageManager)
73
        gPageManager->informTPanelNetwork(conn, level, type);
74
}
47 andreas 75
 
61 andreas 76
JNIEXPORT void JNICALL Java_org_qtproject_theosys_PhoneCallState_informPhoneState(JNIEnv *env, jclass, jboolean call, jstring pnumber)
47 andreas 77
{
61 andreas 78
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_PhoneCallState_informPhoneState(JNIEnv *env, jclass, jboolean call, jstring pnumber)");
79
 
80
    string phoneNumber;
81
 
82
    if (pnumber)
83
    {
84
        const jclass stringClass = env->GetObjectClass(pnumber);
85
        const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
86
        const jbyteArray stringJbytes = (jbyteArray) env->CallObjectMethod(pnumber, getBytes, env->NewStringUTF("UTF-8"));
87
 
88
        size_t length = (size_t) env->GetArrayLength(stringJbytes);
89
        jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL);
90
 
91
        phoneNumber = string((char *)pBytes, length);
92
        env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT);
93
 
94
        env->DeleteLocalRef(stringJbytes);
95
        env->DeleteLocalRef(stringClass);
96
    }
97
 
98
    if (gPageManager)
99
        gPageManager->informPhoneState(call, phoneNumber);
47 andreas 100
}
101
 
61 andreas 102
JNIEXPORT void JNICALL Java_org_qtproject_theosys_Logger_logger(JNIEnv *env, jclass, jint mode, jstring msg)
47 andreas 103
{
61 andreas 104
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_Logger_logger(JNIEnv *env, jclass cl, jint mode, jstring msg)");
105
 
47 andreas 106
    if (!msg)
107
        return;
108
 
109
    const jclass stringClass = env->GetObjectClass(msg);
110
    const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
111
    const jbyteArray stringJbytes = (jbyteArray) env->CallObjectMethod(msg, getBytes, env->NewStringUTF("UTF-8"));
112
 
113
    size_t length = (size_t) env->GetArrayLength(stringJbytes);
114
    jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL);
115
 
116
    string ret = std::string((char *)pBytes, length);
117
    env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT);
118
 
119
    env->DeleteLocalRef(stringJbytes);
120
    env->DeleteLocalRef(stringClass);
121
 
61 andreas 122
    try
123
    {
124
        TError::lock();
47 andreas 125
 
61 andreas 126
        if (TStreamError::checkFilter(mode))
127
            TError::Current()->logMsg(TError::append(mode, *TStreamError::getStream()) << ret << std::endl);
47 andreas 128
 
61 andreas 129
        TError::unlock();
130
    }
131
    catch (std::exception& e)
132
    {
133
        __android_log_print(ANDROID_LOG_ERROR, "tpanel", "%s", e.what());
134
    }
47 andreas 135
}
37 andreas 136
#endif
36 andreas 137
 
3 andreas 138
TPageManager::TPageManager()
139
{
14 andreas 140
    surface_mutex.lock();
3 andreas 141
    DECL_TRACER("TPageManager::TPageManager()");
142
 
14 andreas 143
    gPageManager = this;
43 andreas 144
    // Read the AMX panel settings.
3 andreas 145
    mTSettings = new TSettings(TConfig::getProjectPath());
146
 
147
    if (TError::isError())
14 andreas 148
    {
23 andreas 149
        MSG_ERROR("Settings were not read successfull!");
14 andreas 150
        surface_mutex.unlock();
3 andreas 151
        return;
14 andreas 152
    }
3 andreas 153
 
8 andreas 154
    gPrjResources = new TPrjResources(mTSettings->getResourcesList());
4 andreas 155
    mPalette = new TPalette();
156
    vector<PALETTE_SETUP> pal = mTSettings->getSettings().palettes;
157
 
83 andreas 158
    if (pal.size() > 0)
159
    {
160
        vector<PALETTE_SETUP>::iterator iterPal;
4 andreas 161
 
118 andreas 162
        for (iterPal = pal.begin(); iterPal != pal.end(); ++iterPal)
83 andreas 163
            mPalette->initialize(iterPal->file);
164
    }
165
 
4 andreas 166
    if (!TError::isError())
167
        TColor::setPalette(mPalette);
168
 
7 andreas 169
    mFonts = new TFont();
170
 
171
    if (TError::isError())
172
    {
173
        MSG_ERROR("Initializing fonts was not successfull!");
174
    }
175
 
8 andreas 176
    gIcons = new TIcons();
177
 
178
    if (TError::isError())
179
    {
180
        MSG_ERROR("Initializing icons was not successfull!");
181
    }
182
 
3 andreas 183
    mPageList = new TPageList();
32 andreas 184
    mExternal = new TExternal();
4 andreas 185
    PAGELIST_T page;
186
 
3 andreas 187
    if (!mTSettings->getSettings().powerUpPage.empty())
188
    {
88 andreas 189
        if (readPage(mTSettings->getSettings().powerUpPage))
14 andreas 190
        {
88 andreas 191
            MSG_TRACE("Found power up page " << mTSettings->getSettings().powerUpPage);
192
            page = findPage(mTSettings->getSettings().powerUpPage);
193
            mActualPage = page.pageID;
14 andreas 194
        }
3 andreas 195
    }
23 andreas 196
    else
197
    {
198
        MSG_WARNING("No power up page defined! Setting default page to 1.");
199
        mActualPage = 1;
200
    }
3 andreas 201
 
4 andreas 202
    TPage *pg = getPage(mActualPage);
203
 
3 andreas 204
    vector<string> popups = mTSettings->getSettings().powerUpPopup;
205
 
83 andreas 206
    if (popups.size() > 0)
3 andreas 207
    {
83 andreas 208
        vector<string>::iterator iter;
209
 
118 andreas 210
        for (iter = popups.begin(); iter != popups.end(); ++iter)
14 andreas 211
        {
88 andreas 212
            if (readSubPage(*iter))
83 andreas 213
            {
88 andreas 214
                MSG_TRACE("Found power up popup " << *iter);
3 andreas 215
 
88 andreas 216
                if (pg)
217
                {
218
                    TSubPage *spage = getSubPage(*iter);
219
                    pg->addSubPage(spage);
220
                }
83 andreas 221
            }
4 andreas 222
        }
3 andreas 223
    }
11 andreas 224
 
73 andreas 225
    // Here we initialize the system resources like borders, cursors, sliders, ...
226
    mSystemDraw = new TSystemDraw(TConfig::getSystemPath(TConfig::BASE));
227
 
228
    // Here are the commands supported by this emulation.
13 andreas 229
    MSG_INFO("Registering commands ...");
38 andreas 230
    REG_CMD(doAPG, "@APG");     // Add a specific popup page to a specified popup group.
231
    REG_CMD(doCPG, "@CPG");     // Clear all popup pages from specified popup group.
232
    REG_CMD(doDPG, "@DPG");     // Delete a specific popup page from specified popup group if it exists
233
//    REG_CMD(doPDR, "@PDR");     // Set the popup location reset flag.
234
    REG_CMD(doPHE, "@PHE");     // Set the hide effect for the specified popup page to the named hide effect.
235
    REG_CMD(doPHP, "@PHP");     // Set the hide effect position.
236
    REG_CMD(doPHT, "@PHT");     // Set the hide effect time for the specified popup page.
237
    REG_CMD(doPPA, "@PPA");     // Close all popups on a specified page.
104 andreas 238
    REG_CMD(doPPA, "^PPA");     // G5: Close all popups on a specified page.
38 andreas 239
    REG_CMD(doPPF, "@PPF");     // Deactivate a specific popup page on either a specified page or the current page.
104 andreas 240
    REG_CMD(doPPF, "^PPF");     // G5: Deactivate a specific popup page on either a specified page or the current page.
38 andreas 241
    REG_CMD(doPPF, "PPOF");     // Deactivate a specific popup page on either a specified page or the current page
242
    REG_CMD(doPPG, "@PPG");     // Toggle a specific popup page on either a specified page or the current page.
104 andreas 243
    REG_CMD(doPPG, "^PPG");     // G5: Toggle a specific popup page on either a specified page or the current page.
38 andreas 244
    REG_CMD(doPPG, "PPOG");     // Toggle a specific popup page on either a specified page or the current page.
245
    REG_CMD(doPPK, "@PPK");     // Kill a specific popup page from all pages.
104 andreas 246
    REG_CMD(doPPK, "^PPK");     // G5: Kill a specific popup page from all pages.
38 andreas 247
    REG_CMD(doPPM, "@PPM");     // Set the modality of a specific popup page to Modal or NonModal.
104 andreas 248
    REG_CMD(doPPM, "^PPM");     // G5: Set the modality of a specific popup page to Modal or NonModal.
38 andreas 249
    REG_CMD(doPPN, "@PPN");     // Activate a specific popup page to launch on either a specified page or the current page.
104 andreas 250
    REG_CMD(doPPN, "^PPN");     // G5: Activate a specific popup page to launch on either a specified page or the current page.
38 andreas 251
    REG_CMD(doPPN, "PPON");     // Activate a specific popup page to launch on either a specified page or the current page.
252
    REG_CMD(doPPT, "@PPT");     // Set a specific popup page to timeout within a specified time.
104 andreas 253
    REG_CMD(doPPT, "^PPT");     // G5: Set a specific popup page to timeout within a specified time.
38 andreas 254
    REG_CMD(doPPX, "@PPX");     // Close all popups on all pages.
104 andreas 255
    REG_CMD(doPPX, "^PPX");     // G5: Close all popups on all pages.
38 andreas 256
    REG_CMD(doPSE, "@PSE");     // Set the show effect for the specified popup page to the named show effect.
257
    REG_CMD(doPSP, "@PSP");     // Set the show effect position.
258
    REG_CMD(doPST, "@PST");     // Set the show effect time for the specified popup page.
259
    REG_CMD(doPAGE, "PAGE");    // Flip to a specified page.
104 andreas 260
    REG_CMD(doPAGE, "^PGE");    // G5: Flip to a specified page.
11 andreas 261
 
38 andreas 262
    REG_CMD(doANI, "^ANI");     // Run a button animation (in 1/10 second).
263
    REG_CMD(doAPF, "^APF");     // Add page flip action to a button if it does not already exist.
43 andreas 264
    REG_CMD(doBAT, "^BAT");     // Append non-unicode text.
60 andreas 265
    REG_CMD(doBAU, "^BAU");     // Append unicode text. Same format as ^UNI.
43 andreas 266
    REG_CMD(doBCB, "^BCB");     // Set the border color.
82 andreas 267
    REG_CMD(getBCB, "?BCB");    // Get the current border color.
60 andreas 268
    REG_CMD(doBCF, "^BCF");     // Set the fill color to the specified color.
82 andreas 269
    REG_CMD(getBCF, "?BCF");    // Get the current fill color.
60 andreas 270
    REG_CMD(doBCT, "^BCT");     // Set the text color to the specified color.
82 andreas 271
    REG_CMD(getBCT, "?BCT");    // Get the current text color.
60 andreas 272
    REG_CMD(doBDO, "^BDO");     // Set the button draw order
273
    REG_CMD(doBFB, "^BFB");     // Set the feedback type of the button.
106 andreas 274
    REG_CMD(doBMC, "^BMC");    // Button copy command.
275
//    REG_CMD(doBMI, "^BMI");    // Set the button mask image.
110 andreas 276
    REG_CMD(doBML, "^BML");    // Set the maximum length of the text area button.
38 andreas 277
    REG_CMD(doBMP, "^BMP");     // Assign a picture to those buttons with a defined addressrange.
82 andreas 278
    REG_CMD(getBMP, "?BMP");    // Get the current bitmap name.
38 andreas 279
    REG_CMD(doBOP, "^BOP");     // Set the button opacity.
106 andreas 280
    REG_CMD(getBOP, "?BOP");    // Get the button opacity.
60 andreas 281
    REG_CMD(doBOR, "^BOR");     // Set a border to a specific border style.
107 andreas 282
    REG_CMD(doBOS, "^BOS");     // Set the button to display either a Video or Non-Video window.
60 andreas 283
    REG_CMD(doBRD, "^BRD");     // Set the border of a button state/states.
107 andreas 284
    REG_CMD(getBRD, "?BRD");    // Get the border of a button state/states.
103 andreas 285
//    REG_CMD(doBSF, "^BSF");     // Set the focus to the text area.
38 andreas 286
    REG_CMD(doBSP, "^BSP");     // Set the button size and position.
107 andreas 287
    REG_CMD(doBSM, "^BSM");     // Submit text for text area buttons.
288
    REG_CMD(doBSO, "^BSO");     // Set the sound played when a button is pressed.
38 andreas 289
    REG_CMD(doBWW, "^BWW");     // Set the button word wrap feature to those buttons with a defined address range.
108 andreas 290
    REG_CMD(getBWW, "?BWW");    // Get the button word wrap feature to those buttons with a defined address range.
38 andreas 291
    REG_CMD(doCPF, "^CPF");     // Clear all page flips from a button.
292
    REG_CMD(doDPF, "^DPF");     // Delete page flips from button if it already exists.
293
    REG_CMD(doENA, "^ENA");     // Enable or disable buttons with a set variable text range.
294
    REG_CMD(doFON, "^FON");     // Set a font to a specific Font ID value for those buttons with a range.
108 andreas 295
    REG_CMD(getFON, "?FON");    // Get the current font index.
103 andreas 296
//    REG_CMD(doGDI, "^GDI");     // Change the bargraph drag increment.
297
//    REG_CMD(doGDV, "^GDV");     // Invert the joystick axis to move the origin to another corner.
60 andreas 298
    REG_CMD(doGLH, "^GLH");     // Change the bargraph upper limit.
299
    REG_CMD(doGLL, "^GLL");     // Change the bargraph lower limit.
108 andreas 300
    REG_CMD(doGSC, "^GSC");     // Change the bargraph slider color or joystick cursor color.
38 andreas 301
    REG_CMD(doICO, "^ICO");     // Set the icon to a button.
108 andreas 302
    REG_CMD(getICO, "?ICO");    // Get the current icon index.
303
    REG_CMD(doJSB, "^JSB");     // Set bitmap/picture alignment using a numeric keypad layout for those buttons with a defined address range.
304
    REG_CMD(getJSB, "?JSB");    // Get the current bitmap justification.
305
    REG_CMD(doJSI, "^JSI");     // Set icon alignment using a numeric keypad layout for those buttons with a defined address range.
306
    REG_CMD(getJSI, "?JSI");    // Get the current icon justification.
307
    REG_CMD(doJST, "^JST");     // Set text alignment using a numeric keypad layout for those buttons with a defined address range.
308
    REG_CMD(getJST, "?JST");    // Get the current text justification.
38 andreas 309
    REG_CMD(doSHO, "^SHO");     // Show or hide a button with a set variable text range.
108 andreas 310
    REG_CMD(doTEC, "^TEC");     // Set the text effect color for the specified addresses/states to the specified color.
311
    REG_CMD(getTEC, "?TEC");    // Get the current text effect color.
110 andreas 312
    REG_CMD(doTEF, "^TEF");     // Set the text effect. The Text Effect is specified by name and can be found in TPD4.
313
    REG_CMD(getTEF, "?TEF");    // Get the current text effect name.
103 andreas 314
//    REG_CMD(doTOP, "^TOP");     // Send events to the Master as string events.
38 andreas 315
    REG_CMD(doTXT, "^TXT");     // Assign a text string to those buttons with a defined address range.
110 andreas 316
    REG_CMD(getTXT, "?TXT");    // Get the current text information.
104 andreas 317
    REG_CMD(doUNI, "^UNI");     // Set Unicode text.
318
    REG_CMD(doUTF, "^UTF");     // G5: Set button state text using UTF-8 text command.
14 andreas 319
 
103 andreas 320
//    REG_CMD(doLPC, "^LPC");     // Clear all users from the User Access Passwords list on the Password Setup page.
321
//    REG_CMD(doLPR, "^LPR");     // Remove a given user from the User Access Passwords list on the Password Setup page.
322
//    REG_CMD(doLPS, "^LPS");     // Set the user name and password.
323
 
111 andreas 324
    REG_CMD(doKPS, "^KPS");     // Set the keyboard passthru.
325
    REG_CMD(doVKS, "^VKS");     // Send one or more virtual key strokes to the G4 application.
103 andreas 326
 
327
//    REG_CMD(doPWD, "@PWD");     // Set the page flip password.
328
//    REG_CMD(doPWD, "^PWD");     // Set the page flip password.
329
 
38 andreas 330
    REG_CMD(doBBR, "^BBR");     // Set the bitmap of a button to use a particular resource.
97 andreas 331
    REG_CMD(doRAF, "^RAF");     // Add new resources
332
    REG_CMD(doRFR, "^RFR");     // Force a refresh for a given resource.
38 andreas 333
    REG_CMD(doRMF, "^RMF");     // Modify an existing resource.
111 andreas 334
    REG_CMD(doRSR, "^RSR");     // Change the refresh rate for a given resource.
21 andreas 335
 
108 andreas 336
    REG_CMD(doABEEP, "ABEEP");  // Output a single beep even if beep is Off.
337
    REG_CMD(doADBEEP, "ADBEEP");// Output a double beep even if beep is Off.
62 andreas 338
    REG_CMD(doAKB, "@AKB");     // Pop up the keyboard icon and initialize the text string to that specified.
339
    REG_CMD(doAKEYB, "AKEYB");  // Pop up the keyboard icon and initialize the text string to that specified.
340
    REG_CMD(doAKP, "@AKP");     // Pop up the keypad icon and initialize the text string to that specified.
341
    REG_CMD(doAKEYP, "AKEYP");  // Pop up the keypad icon and initialize the text string to that specified.
63 andreas 342
    REG_CMD(doAKEYR, "AKEYR");  // Remove the Keyboard/Keypad.
343
    REG_CMD(doAKR, "@AKR");     // Remove the Keyboard/Keypad.
71 andreas 344
    REG_CMD(doBEEP, "BEEP");    // Play a single beep.
104 andreas 345
    REG_CMD(doBEEP, "^ABP");    // G5: Play a single beep.
71 andreas 346
    REG_CMD(doDBEEP, "DBEEP");  // Play a double beep.
104 andreas 347
    REG_CMD(doDBEEP, "^ADB");   // G5: Play a double beep.
62 andreas 348
    REG_CMD(doEKP, "@EKP");     // Pop up the keypad icon and initialize the text string to that specified.
63 andreas 349
    REG_CMD(doPKP, "@PKB");     // Present a private keyboard.
350
    REG_CMD(doPKP, "PKEYP");    // Present a private keypad.
351
    REG_CMD(doPKP, "@PKP");     // Present a private keypad.
64 andreas 352
    REG_CMD(doSetup, "SETUP");  // Send panel to SETUP page.
104 andreas 353
    REG_CMD(doSetup, "^STP");   // G5: Open setup page.
64 andreas 354
    REG_CMD(doShutdown, "SHUTDOWN");// Shut down the App
82 andreas 355
    REG_CMD(doSOU, "@SOU");     // Play a sound file.
104 andreas 356
    REG_CMD(doSOU, "^SOU");     // G5: Play a sound file.
63 andreas 357
    REG_CMD(doTKP, "@TKP");     // Present a telephone keypad.
104 andreas 358
    REG_CMD(doTKP, "^TKP");     // G5: Bring up a telephone keypad.
63 andreas 359
    REG_CMD(doTKP, "@VKB");     // Present a virtual keyboard
104 andreas 360
    REG_CMD(doTKP, "^VKB");     // G5: Bring up a virtual keyboard.
62 andreas 361
 
103 andreas 362
    // Here the SIP commands will take place
363
 
364
    // State commands
14 andreas 365
    REG_CMD(doON, "ON");
366
    REG_CMD(doOFF, "OFF");
15 andreas 367
    REG_CMD(doLEVEL, "LEVEL");
368
    REG_CMD(doBLINK, "BLINK");
14 andreas 369
 
26 andreas 370
    REG_CMD(doFTR, "#FTR");     // File transfer (virtual internal command)
23 andreas 371
 
88 andreas 372
    TError::clear();
14 andreas 373
    surface_mutex.unlock();
3 andreas 374
}
375
 
376
TPageManager::~TPageManager()
377
{
378
    DECL_TRACER("TPageManager::~TPageManager()");
379
 
380
    PCHAIN_T *p = mPchain;
381
    PCHAIN_T *next = nullptr;
37 andreas 382
#ifdef __ANDROID__
36 andreas 383
    stopNetworkState();
37 andreas 384
#endif
3 andreas 385
    try
386
    {
387
        while (p)
388
        {
389
            next = p->next;
390
 
391
            if (p->page)
392
                delete p->page;
393
 
394
            delete p;
395
            p = next;
396
        }
397
 
398
        SPCHAIN_T *sp = mSPchain;
399
        SPCHAIN_T *snext = nullptr;
400
 
401
        while (sp)
402
        {
403
            snext = sp->next;
404
 
405
            if (sp->page)
406
                delete sp->page;
407
 
408
            delete sp;
5 andreas 409
            sp = snext;
3 andreas 410
        }
411
 
412
        mPchain = nullptr;
413
        mSPchain = nullptr;
14 andreas 414
        setPChain(mPchain);
415
        setSPChain(mSPchain);
3 andreas 416
 
13 andreas 417
        if (mAmxNet)
418
        {
419
            delete mAmxNet;
420
            mAmxNet = nullptr;
421
        }
422
 
3 andreas 423
        if (mTSettings)
424
        {
425
            delete mTSettings;
426
            mTSettings = nullptr;
427
        }
428
 
429
        if (mPageList)
430
        {
431
            delete mPageList;
432
            mPageList = nullptr;
433
        }
5 andreas 434
 
435
        if (mPalette)
436
        {
437
            delete mPalette;
438
            mPalette = nullptr;
439
        }
7 andreas 440
 
441
        if (mFonts)
442
        {
443
            delete mFonts;
444
            mFonts = nullptr;
445
        }
8 andreas 446
 
447
        if (gIcons)
448
        {
449
            delete gIcons;
450
            gIcons = nullptr;
451
        }
452
 
453
        if (gPrjResources)
454
        {
455
            delete gPrjResources;
456
            gPrjResources = nullptr;
457
        }
40 andreas 458
 
33 andreas 459
        if (mExternal)
460
        {
461
            delete mExternal;
462
            mExternal = nullptr;
463
        }
3 andreas 464
    }
465
    catch (std::exception& e)
466
    {
467
        MSG_ERROR("Memory error: " << e.what());
468
    }
90 andreas 469
 
470
    gPageManager = nullptr;
3 andreas 471
}
472
 
11 andreas 473
void TPageManager::initialize()
474
{
475
    DECL_TRACER("TPageManager::initialize()");
476
 
14 andreas 477
    surface_mutex.lock();
11 andreas 478
    dropAllSubPages();
479
    dropAllPages();
480
 
90 andreas 481
    if (mAmxNet && mAmxNet->isConnected())
482
        mAmxNet->close();
88 andreas 483
 
11 andreas 484
    if (mTSettings)
485
        mTSettings->loadSettings();
486
    else
487
        mTSettings = new TSettings(TConfig::getProjectPath());
488
 
489
    if (TError::isError())
14 andreas 490
    {
491
        surface_mutex.unlock();
11 andreas 492
        return;
14 andreas 493
    }
11 andreas 494
 
88 andreas 495
    if (gPrjResources)
496
        delete gPrjResources;
11 andreas 497
 
88 andreas 498
    gPrjResources = new TPrjResources(mTSettings->getResourcesList());
11 andreas 499
 
88 andreas 500
    if (mPalette)
501
        delete mPalette;
502
 
503
    mPalette = new TPalette();
504
 
11 andreas 505
    vector<PALETTE_SETUP> pal = mTSettings->getSettings().palettes;
506
 
83 andreas 507
    if (pal.size() > 0)
508
    {
509
        vector<PALETTE_SETUP>::iterator iterPal;
11 andreas 510
 
118 andreas 511
        for (iterPal = pal.begin(); iterPal != pal.end(); ++iterPal)
83 andreas 512
            mPalette->initialize(iterPal->file);
513
    }
514
 
11 andreas 515
    if (!TError::isError())
516
        TColor::setPalette(mPalette);
517
 
88 andreas 518
    if (mFonts)
519
        delete mFonts;
11 andreas 520
 
88 andreas 521
    mFonts = new TFont();
522
 
11 andreas 523
    if (TError::isError())
524
    {
525
        MSG_ERROR("Initializing fonts was not successfull!");
14 andreas 526
        surface_mutex.unlock();
11 andreas 527
        return;
528
    }
529
 
88 andreas 530
    if (gIcons)
531
        delete gIcons;
11 andreas 532
 
88 andreas 533
    gIcons = new TIcons();
534
 
11 andreas 535
    if (TError::isError())
536
    {
537
        MSG_ERROR("Initializing icons was not successfull!");
14 andreas 538
        surface_mutex.unlock();
11 andreas 539
        return;
540
    }
541
 
88 andreas 542
    if (mPageList)
543
        delete mPageList;
11 andreas 544
 
88 andreas 545
    mPageList = new TPageList();
11 andreas 546
 
88 andreas 547
    if (mExternal)
548
        delete mExternal;
549
 
550
    mExternal = new TExternal();
551
 
11 andreas 552
    PAGELIST_T page;
553
 
554
    if (!mTSettings->getSettings().powerUpPage.empty())
555
    {
88 andreas 556
        if (readPage(mTSettings->getSettings().powerUpPage))
14 andreas 557
        {
88 andreas 558
            MSG_TRACE("Found power up page " << mTSettings->getSettings().powerUpPage);
559
            page = findPage(mTSettings->getSettings().powerUpPage);
560
            mActualPage = page.pageID;
14 andreas 561
        }
11 andreas 562
    }
563
 
564
    TPage *pg = getPage(mActualPage);
565
 
566
    vector<string> popups = mTSettings->getSettings().powerUpPopup;
567
 
83 andreas 568
    if (popups.size() > 0)
11 andreas 569
    {
83 andreas 570
        vector<string>::iterator iter;
571
 
118 andreas 572
        for (iter = popups.begin(); iter != popups.end(); ++iter)
14 andreas 573
        {
88 andreas 574
            if (readSubPage(*iter))
83 andreas 575
            {
88 andreas 576
                MSG_TRACE("Found power up popup " << *iter);
11 andreas 577
 
88 andreas 578
                if (pg)
579
                {
580
                    TSubPage *spage = getSubPage(*iter);
581
                    pg->addSubPage(spage);
582
                }
83 andreas 583
            }
11 andreas 584
        }
585
    }
586
 
88 andreas 587
    // Here we initialize the system resources like borders, cursors, sliders, ...
588
    if (mSystemDraw)
589
        delete mSystemDraw;
590
 
591
    mSystemDraw = new TSystemDraw(TConfig::getSystemPath(TConfig::BASE));
592
 
593
    TError::clear();        // Clear all errors who may be occured until here
594
 
11 andreas 595
    // Start the thread
92 andreas 596
    startComm();
597
 
598
    surface_mutex.unlock();
599
}
600
 
601
bool TPageManager::startComm()
602
{
603
    DECL_TRACER("TPageManager::startComm()");
604
 
605
    if (mAmxNet && mAmxNet->isNetRun())
606
        return true;
607
 
608
    try
11 andreas 609
    {
92 andreas 610
        if (!mAmxNet)
13 andreas 611
        {
92 andreas 612
            if (_netRunning)
13 andreas 613
            {
92 andreas 614
                // Wait until previous connection thread ended
615
                while (_netRunning)
616
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
13 andreas 617
            }
14 andreas 618
 
92 andreas 619
            mAmxNet = new amx::TAmxNet();
620
            mAmxNet->setCallback(bind(&TPageManager::doCommand, this, std::placeholders::_1));
621
            mAmxNet->setPanelID(TConfig::getChannel());
13 andreas 622
        }
90 andreas 623
 
624
        if (!mAmxNet->isNetRun())
625
            mAmxNet->Run();
85 andreas 626
    }
92 andreas 627
    catch (std::exception& e)
628
    {
629
        MSG_ERROR("Error starting the AmxNet thread: " << e.what());
630
        return false;
631
    }
14 andreas 632
 
92 andreas 633
    return true;
11 andreas 634
}
635
 
38 andreas 636
void TPageManager::startUp()
637
{
638
    DECL_TRACER("TPageManager::startUp()");
639
 
44 andreas 640
    if (mAmxNet)
90 andreas 641
    {
642
        MSG_WARNING("Communication with controller already initialized!");
44 andreas 643
        return;
90 andreas 644
    }
44 andreas 645
 
92 andreas 646
    if (!startComm())
647
        return;
90 andreas 648
 
38 andreas 649
#ifdef __ANDROID__
650
    initNetworkState();
651
#endif
652
}
89 andreas 653
 
654
void TPageManager::reset()
655
{
656
    DECL_TRACER("TPageManager::reset()");
657
 
100 andreas 658
    // Freshly initialize everything.
89 andreas 659
    initialize();
660
}
661
 
11 andreas 662
/*
663
 * The following method is called by the class TAmxNet whenever an event from
664
 * the controller occured.
665
 */
666
void TPageManager::doCommand(const amx::ANET_COMMAND& cmd)
667
{
668
    DECL_TRACER("TPageManager::doCommand(const amx::ANET_COMMAND& cmd)");
669
 
670
    mCommands.push_back(cmd);
671
 
672
    if (mBusy)
673
        return;
674
 
675
    mBusy = true;
676
    string com;
677
 
678
    while (mCommands.size() > 0)
679
    {
680
        amx::ANET_COMMAND& bef = mCommands.at(0);
681
        mCommands.erase(mCommands.begin());
682
 
683
        switch (bef.MC)
684
        {
685
            case 0x0006:
686
            case 0x0018:	// feedback channel on
687
                com.assign("ON-");
688
                com.append(to_string(bef.data.chan_state.channel));
689
                parseCommand(bef.device1, bef.data.chan_state.port, com);
14 andreas 690
            break;
11 andreas 691
 
692
            case 0x0007:
693
            case 0x0019:	// feedback channel off
694
                com.assign("OFF-");
695
                com.append(to_string(bef.data.chan_state.channel));
696
                parseCommand(bef.device1, bef.data.chan_state.port, com);
14 andreas 697
            break;
11 andreas 698
 
699
            case 0x000a:	// level value change
700
                com = "LEVEL-";
701
                com += to_string(bef.data.message_value.value);
702
                com += ",";
703
 
704
                switch (bef.data.message_value.type)
705
                {
706
                    case 0x10: com += to_string(bef.data.message_value.content.byte); break;
707
                    case 0x11: com += to_string(bef.data.message_value.content.ch); break;
708
                    case 0x20: com += to_string(bef.data.message_value.content.integer); break;
709
                    case 0x21: com += to_string(bef.data.message_value.content.sinteger); break;
710
                    case 0x40: com += to_string(bef.data.message_value.content.dword); break;
711
                    case 0x41: com += to_string(bef.data.message_value.content.sdword); break;
712
                    case 0x4f: com += to_string(bef.data.message_value.content.fvalue); break;
713
                    case 0x8f: com += to_string(bef.data.message_value.content.dvalue); break;
714
                }
715
 
716
                parseCommand(bef.device1, bef.data.chan_state.port, com);
717
            break;
718
 
719
            case 0x000c:	// Command string
720
            {
721
                amx::ANET_MSG_STRING msg = bef.data.message_string;
722
 
723
                if (msg.length < strlen((char *)&msg.content))
724
                {
725
                    mCmdBuffer.append((char *)&msg.content);
726
                    break;
727
                }
728
                else if (mCmdBuffer.length() > 0)
729
                {
730
                    mCmdBuffer.append((char *)&msg.content);
731
                    size_t len = (mCmdBuffer.length() >= sizeof(msg.content)) ? (sizeof(msg.content)-1) : mCmdBuffer.length();
732
                    strncpy((char *)&msg.content, mCmdBuffer.c_str(), len);
733
                    msg.content[len] = 0;
734
                }
735
 
104 andreas 736
                if (getCommand((char *)msg.content) == "^UTF")  // This is already UTF8!
737
                    com.assign((char *)msg.content);
738
                else
739
                    com.assign(cp1250ToUTF8((char *)&msg.content));
740
 
741
                parseCommand(bef.device1, bef.data.chan_state.port, com);
11 andreas 742
                mCmdBuffer.clear();
743
            }
744
            break;
745
 
15 andreas 746
            case 0x0502:    // Blink message (contains date and time)
747
                com = "BLINK-" + to_string(bef.data.blinkMessage.hour) + ":";
748
                com += to_string(bef.data.blinkMessage.minute) + ":";
749
                com += to_string(bef.data.blinkMessage.second) + ",";
750
                com += to_string(bef.data.blinkMessage.year) + "-";
751
                com += to_string(bef.data.blinkMessage.month) + "-";
752
                com += to_string(bef.data.blinkMessage.day) + ",";
753
                com += to_string(bef.data.blinkMessage.weekday) + ",";
754
                com += ((bef.data.blinkMessage.LED & 0x0001) ? "ON" : "OFF");
755
                parseCommand(0, 0, com);
756
            break;
757
 
11 andreas 758
            case 0x1000:	// Filetransfer
759
            {
760
                amx::ANET_FILETRANSFER ftr = bef.data.filetransfer;
761
 
762
                if (ftr.ftype == 0)
763
                {
764
                    switch(ftr.function)
765
                    {
766
                        case 0x0100:	// Syncing directory
767
                            com = "#FTR-SYNC:0:";
768
                            com.append((char*)&ftr.data[0]);
769
                            parseCommand(bef.device1, bef.port1, com);
770
                        break;
771
 
772
                        case 0x0104:	// Delete file
773
                            com = "#FTR-SYNC:"+to_string(bef.count)+":Deleting files ... ("+to_string(bef.count)+"%)";
774
                            parseCommand(bef.device1, bef.port1, com);
775
                        break;
776
 
777
                        case 0x0105:	// start filetransfer
778
                            com = "#FTR-START";
779
                            parseCommand(bef.device1, bef.port1, com);
780
                        break;
781
                    }
782
                }
783
                else
784
                {
785
                    switch(ftr.function)
786
                    {
787
                        case 0x0003:	// Received part of file
788
                        case 0x0004:	// End of file
789
                            com = "#FTR-FTRPART:"+to_string(bef.count)+":"+to_string(ftr.info1);
790
                            parseCommand(bef.device1, bef.port1, com);
791
                        break;
792
 
793
                        case 0x0007:	// End of file transfer
794
                        {
88 andreas 795
//                            initialize();
11 andreas 796
                            com = "#FTR-END";
797
                            parseCommand(bef.device1, bef.port1, com);
798
                        }
799
                        break;
800
 
801
                        case 0x0102:	// Receiving file
802
                            com = "#FTR-FTRSTART:"+to_string(bef.count)+":"+to_string(ftr.info1)+":";
803
                            com.append((char*)&ftr.data[0]);
804
                            parseCommand(bef.device1, bef.port1, com);
805
                        break;
806
                    }
807
                }
808
            }
809
            break;
810
        }
811
    }
812
 
813
    mBusy = false;
814
}
815
 
26 andreas 816
void TPageManager::deployCallbacks()
817
{
818
    DECL_TRACER("TPageManager::deployCallbacks()");
819
 
820
    PCHAIN_T *p = mPchain;
821
 
822
    while (p)
823
    {
824
        if (p->page)
825
        {
826
            if (_setBackground)
827
                p->page->registerCallback(_setBackground);
828
 
829
            if (_callPlayVideo)
830
                p->page->regCallPlayVideo(_callPlayVideo);
831
        }
832
 
833
        p = p->next;
834
    }
835
 
836
    SPCHAIN_T *sp = mSPchain;
837
 
838
    while (sp)
839
    {
840
        if (sp->page)
841
        {
842
            if (_setBackground)
843
                sp->page->registerCallback(_setBackground);
844
 
845
            if (_callPlayVideo)
846
                sp->page->regCallPlayVideo(_callPlayVideo);
847
        }
848
 
849
        sp = sp->next;
850
    }
851
}
36 andreas 852
 
853
void TPageManager::regCallbackNetState(std::function<void (int)> callNetState, ulong handle)
854
{
855
    DECL_TRACER("TPageManager::regCallbackNetState(std::function<void (int)> callNetState, ulong handle)");
856
 
857
    if (handle == 0)
858
        return;
859
 
860
    mNetCalls.insert(std::pair<int, std::function<void (int)> >(handle, callNetState));
861
}
862
 
863
void TPageManager::unregCallbackNetState(ulong handle)
864
{
865
    DECL_TRACER("TPageManager::unregCallbackNetState(ulong handle)");
866
 
83 andreas 867
    if (mNetCalls.size() == 0)
868
        return;
869
 
36 andreas 870
    std::map<int, std::function<void (int)> >::iterator iter = mNetCalls.find(handle);
871
 
872
    if (iter != mNetCalls.end())
873
        mNetCalls.erase(iter);
874
}
875
 
38 andreas 876
void TPageManager::regCallbackBatteryState(std::function<void (int, bool, int)> callBatteryState, ulong handle)
877
{
878
    DECL_TRACER("TPageManager::regCallbackBatteryState(std::function<void (int, bool, int)> callBatteryState, ulong handle)");
879
 
880
    if (handle == 0)
881
        return;
882
 
883
    mBatteryCalls.insert(std::pair<int, std::function<void (int, bool, int)> >(handle, callBatteryState));
884
}
885
 
886
void TPageManager::unregCallbackBatteryState(ulong handle)
887
{
888
    DECL_TRACER("TPageManager::unregCallbackBatteryState(ulong handle)");
889
 
83 andreas 890
    if (mBatteryCalls.size() == 0)
891
        return;
892
 
38 andreas 893
    std::map<int, std::function<void (int, bool, int)> >::iterator iter = mBatteryCalls.find(handle);
894
 
895
    if (iter != mBatteryCalls.end())
896
        mBatteryCalls.erase(iter);
897
}
898
 
11 andreas 899
/*
900
 * The following function must be called to start the "panel".
901
 */
5 andreas 902
bool TPageManager::run()
903
{
904
    DECL_TRACER("TPageManager::run()");
905
 
906
    if (mActualPage <= 0)
907
        return false;
908
 
14 andreas 909
    surface_mutex.lock();
5 andreas 910
    TPage *pg = getPage(mActualPage);
7 andreas 911
    pg->setFonts(mFonts);
5 andreas 912
    pg->registerCallback(_setBackground);
21 andreas 913
    pg->regCallPlayVideo(_callPlayVideo);
5 andreas 914
 
915
    if (!pg || !_setPage || !mTSettings)
14 andreas 916
    {
917
        surface_mutex.unlock();
5 andreas 918
        return false;
14 andreas 919
    }
5 andreas 920
 
26 andreas 921
    int width, height;
922
    width = mTSettings->getWith();
923
    height = mTSettings->getHeight();
43 andreas 924
#ifdef _SCALE_SKIA_
26 andreas 925
    if (mScaleFactor != 1.0)
926
    {
927
        width = (int)((double)width * mScaleFactor);
928
        height = (int)((double)height * mScaleFactor);
929
    }
43 andreas 930
#endif
26 andreas 931
    _setPage((pg->getNumber() << 16) & 0xffff0000, width, height);
5 andreas 932
    pg->show();
933
 
934
    TSubPage *subPg = pg->getFirstSubPage();
935
 
936
    while (subPg)
937
    {
7 andreas 938
        subPg->setFonts(mFonts);
939
        subPg->registerCallback(_setBackground);
940
        subPg->registerCallbackDB(_displayButton);
11 andreas 941
        subPg->regCallDropSubPage(_callDropSubPage);
21 andreas 942
        subPg->regCallPlayVideo(_callPlayVideo);
7 andreas 943
 
5 andreas 944
        if (_setSubPage)
6 andreas 945
        {
946
            MSG_DEBUG("Drawing page " << subPg->getNumber() << ": " << subPg->getName() << "...");
26 andreas 947
            width = subPg->getWidth();
948
            height = subPg->getHeight();
949
            int left = subPg->getLeft();
950
            int top = subPg->getTop();
43 andreas 951
#ifdef _SCALE_SKIA_
26 andreas 952
            if (mScaleFactor != 1.0)
953
            {
954
                width = (int)((double)width * mScaleFactor);
955
                height = (int)((double)height * mScaleFactor);
956
                left = (int)((double)left * mScaleFactor);
957
                top = (int)((double)top * mScaleFactor);
958
            }
43 andreas 959
#endif
41 andreas 960
            ANIMATION_t ani;
961
            ani.showEffect = subPg->getShowEffect();
962
            ani.showTime = subPg->getShowTime();
42 andreas 963
            ani.hideEffect = subPg->getHideEffect();
964
            ani.hideTime = subPg->getHideTime();
41 andreas 965
            _setSubPage(((subPg->getNumber() << 16) & 0xffff0000), left, top, width, height, ani);
6 andreas 966
            subPg->show();
967
        }
5 andreas 968
 
969
        subPg = pg->getNextSubPage();
970
    }
971
 
14 andreas 972
    surface_mutex.unlock();
5 andreas 973
    return true;
974
}
975
 
4 andreas 976
TPage *TPageManager::getPage(int pageID)
977
{
978
    DECL_TRACER("TPageManager::getPage(int pageID)");
979
 
980
    PCHAIN_T *p = mPchain;
981
 
982
    while (p)
983
    {
984
        if (p->page->getNumber() == pageID)
985
            return p->page;
986
 
987
        p = p->next;
988
    }
989
 
14 andreas 990
    MSG_DEBUG("Page " << pageID << " not found!");
4 andreas 991
    return nullptr;
992
}
993
 
994
TPage *TPageManager::getPage(const string& name)
995
{
996
    DECL_TRACER("TPageManager::getPage(const string& name)");
997
 
998
    PCHAIN_T *p = mPchain;
999
 
1000
    while (p)
1001
    {
1002
        if (p->page->getName().compare(name) == 0)
1003
            return p->page;
1004
 
1005
        p = p->next;
1006
    }
1007
 
14 andreas 1008
    MSG_DEBUG("Page " << name << " not found!");
4 andreas 1009
    return nullptr;
1010
}
1011
 
15 andreas 1012
TPage *TPageManager::loadPage(PAGELIST_T& pl)
1013
{
1014
    DECL_TRACER("TPageManager::loadPage(PAGELIST_T& pl)");
1015
 
1016
    if (!pl.isValid)
1017
        return nullptr;
1018
 
1019
    TPage *pg = getPage(pl.pageID);
1020
 
1021
    if (!pg)
1022
    {
1023
        if (!readPage(pl.pageID))
1024
            return nullptr;
1025
 
1026
        pg = getPage(pl.pageID);
1027
 
1028
        if (!pg)
1029
        {
1030
            MSG_ERROR("Error loading page " << pl.pageID << ", " << pl.name << " from file " << pl.file << "!");
1031
            return nullptr;
1032
        }
1033
    }
1034
 
1035
    return pg;
1036
}
1037
 
1038
bool TPageManager::setPage(int PageID)
1039
{
1040
    DECL_TRACER("TPageManager::setPage(int PageID)");
1041
 
1042
    if (mActualPage == PageID)
1043
        return true;
1044
 
1045
    TPage *pg = getPage(mActualPage);
43 andreas 1046
    // FIXME: Make this a vector array to hold a larger history!
15 andreas 1047
    mPreviousPage = mActualPage;
1048
 
1049
    if (pg)
1050
        pg->drop();
1051
 
1052
    mActualPage = 0;
1053
    PAGELIST_T listPg = findPage(PageID);
1054
 
1055
    if ((pg = loadPage(listPg)) == nullptr)
1056
        return false;
1057
 
1058
    mActualPage = PageID;
1059
    pg->show();
1060
    return true;
1061
}
1062
 
1063
bool TPageManager::setPage(const string& name)
1064
{
1065
    DECL_TRACER("TPageManager::setPage(const string& name)");
1066
 
1067
    TPage *pg = getPage(mActualPage);
1068
 
1069
    if (pg && pg->getName().compare(name) == 0)
1070
        return true;
1071
 
43 andreas 1072
    // FIXME: Make this a vector array to hold a larger history!
1073
    mPreviousPage = mActualPage;    // Necessary to be able to jump back to at least the last previous page
15 andreas 1074
 
1075
    if (pg)
1076
        pg->drop();
1077
 
1078
    mActualPage = 0;
1079
    PAGELIST_T listPg = findPage(name);
1080
 
1081
    if ((pg = loadPage(listPg)) == nullptr)
1082
        return false;
1083
 
1084
    mActualPage = pg->getNumber();
1085
    pg->show();
1086
    return true;
1087
}
1088
 
4 andreas 1089
TSubPage *TPageManager::getSubPage(int pageID)
1090
{
1091
    DECL_TRACER("TPageManager::getSubPage(int pageID)");
1092
 
1093
    SPCHAIN_T *p = mSPchain;
1094
 
1095
    while(p)
1096
    {
1097
        if (p->page->getNumber() == pageID)
1098
            return p->page;
1099
 
1100
        p = p->next;
1101
    }
1102
 
1103
    return nullptr;
1104
}
1105
 
1106
TSubPage *TPageManager::getSubPage(const std::string& name)
1107
{
1108
    DECL_TRACER("TPageManager::getSubPage(const std::string& name)");
1109
 
1110
    SPCHAIN_T *p = mSPchain;
1111
 
1112
    while (p)
1113
    {
1114
        if (p->page->getName().compare(name) == 0)
1115
            return p->page;
1116
 
1117
        p = p->next;
1118
    }
1119
 
1120
    return nullptr;
1121
}
1122
 
96 andreas 1123
TSubPage *TPageManager::deliverSubPage(const string& name, TPage **pg)
1124
{
1125
    DECL_TRACER("TPageManager::deliverSubPage(const string& name)");
1126
 
1127
    TPage *page = getActualPage();
1128
 
1129
    if (!page)
1130
    {
1131
        MSG_ERROR("No actual page loaded!");
1132
        return nullptr;
1133
    }
1134
 
1135
    if (pg)
1136
        *pg = page;
1137
 
1138
    TSubPage *subPage = getSubPage(name);
1139
 
1140
    if (!subPage)
1141
    {
1142
        if (!readSubPage(name))
1143
        {
1144
            MSG_ERROR("Error reading subpage " << name);
1145
            return nullptr;
1146
        }
1147
 
1148
        subPage = getSubPage(name);
1149
 
1150
        if (!subPage)
1151
        {
1152
            MSG_ERROR("Fatal: A page with name " << name << " does not exist!");
1153
            return nullptr;
1154
        }
1155
 
1156
        page->addSubPage(subPage);
1157
    }
1158
 
1159
    return subPage;
1160
}
1161
 
3 andreas 1162
bool TPageManager::readPages()
1163
{
1164
    DECL_TRACER("TPageManager::readPages()");
1165
 
1166
    if (!mPageList)
1167
    {
1168
        MSG_ERROR("Page list is not initialized!");
1169
        TError::setError();
1170
        return false;
1171
    }
1172
 
1173
    // Read all pages
1174
    vector<PAGELIST_T> pageList = mPageList->getPagelist();
1175
 
83 andreas 1176
    if (pageList.size() > 0)
3 andreas 1177
    {
83 andreas 1178
        vector<PAGELIST_T>::iterator pgIter;
14 andreas 1179
 
118 andreas 1180
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
14 andreas 1181
        {
83 andreas 1182
            TPage *page = new TPage(pgIter->name+".xml");
14 andreas 1183
 
83 andreas 1184
            if (TError::isError())
1185
            {
1186
                delete page;
1187
                return false;
1188
            }
3 andreas 1189
 
83 andreas 1190
            page->setPalette(mPalette);
1191
            page->setFonts(mFonts);
1192
            page->registerCallback(_setBackground);
1193
            page->registerCallbackDB(_displayButton);
1194
            page->regCallPlayVideo(_callPlayVideo);
1195
 
1196
            if (!addPage(page))
1197
                return false;
1198
        }
3 andreas 1199
    }
1200
 
1201
    vector<SUBPAGELIST_T> subPageList = mPageList->getSupPageList();
1202
 
83 andreas 1203
    if (subPageList.size() > 0)
3 andreas 1204
    {
83 andreas 1205
        vector<SUBPAGELIST_T>::iterator spgIter;
14 andreas 1206
 
118 andreas 1207
        for (spgIter = subPageList.begin(); spgIter != subPageList.end(); ++spgIter)
14 andreas 1208
        {
83 andreas 1209
            TSubPage *page = new TSubPage(spgIter->name+".xml");
14 andreas 1210
 
83 andreas 1211
            if (TError::isError())
1212
            {
1213
                delete page;
1214
                return false;
1215
            }
3 andreas 1216
 
83 andreas 1217
            page->setPalette(mPalette);
1218
            page->setFonts(mFonts);
1219
            page->registerCallback(_setBackground);
1220
            page->registerCallbackDB(_displayButton);
1221
            page->regCallDropSubPage(_callDropSubPage);
1222
            page->regCallPlayVideo(_callPlayVideo);
1223
            page->setGroup(spgIter->group);
1224
 
1225
            if (!addSubPage(page))
1226
                return false;
1227
        }
3 andreas 1228
    }
1229
 
1230
    return true;
1231
}
1232
 
1233
bool TPageManager::readPage(const std::string& name)
1234
{
1235
    DECL_TRACER("TPageManager::readPage(const std::string& name)");
1236
 
1237
    PAGELIST_T page = findPage(name);
1238
 
1239
    if (page.pageID <= 0)
1240
    {
1241
        MSG_ERROR("Page " << name << " not found!");
1242
        return false;
1243
    }
1244
 
43 andreas 1245
    TPage *pg;
14 andreas 1246
 
43 andreas 1247
    if (name.compare("_progress") == 0)
1248
        pg = new TPage(name);
1249
    else
1250
        pg = new TPage(page.name+".xml");
1251
 
14 andreas 1252
    if (TError::isError())
1253
    {
1254
        delete pg;
1255
        return false;
1256
    }
1257
 
4 andreas 1258
    pg->setPalette(mPalette);
7 andreas 1259
    pg->setFonts(mFonts);
1260
    pg->registerCallback(_setBackground);
1261
    pg->registerCallbackDB(_displayButton);
21 andreas 1262
    pg->regCallPlayVideo(_callPlayVideo);
3 andreas 1263
 
1264
    if (!addPage(pg))
1265
        return false;
1266
 
1267
    return true;
1268
}
1269
 
1270
bool TPageManager::readPage(int ID)
1271
{
1272
    DECL_TRACER("TPageManager::readPage(int ID)");
1273
 
16 andreas 1274
    TError::clear();
3 andreas 1275
    PAGELIST_T page = findPage(ID);
1276
 
1277
    if (page.pageID <= 0)
1278
    {
1279
        MSG_ERROR("Page with ID " << ID << " not found!");
1280
        return false;
1281
    }
1282
 
43 andreas 1283
    TPage *pg;
14 andreas 1284
 
43 andreas 1285
    if (ID == 300)      // Progress page of system?
1286
        pg = new TPage("_progress");
1287
    else
1288
        pg = new TPage(page.name+".xml");
1289
 
14 andreas 1290
    if (TError::isError())
1291
    {
1292
        delete pg;
1293
        return false;
1294
    }
1295
 
4 andreas 1296
    pg->setPalette(mPalette);
7 andreas 1297
    pg->setFonts(mFonts);
1298
    pg->registerCallback(_setBackground);
1299
    pg->registerCallbackDB(_displayButton);
21 andreas 1300
    pg->regCallPlayVideo(_callPlayVideo);
3 andreas 1301
 
1302
    if (!addPage(pg))
1303
        return false;
1304
 
1305
    return true;
1306
}
1307
 
1308
bool TPageManager::readSubPage(const std::string& name)
1309
{
1310
    DECL_TRACER("TPageManager::readSubPage(const std::string& name)");
1311
 
16 andreas 1312
    TError::clear();
3 andreas 1313
    SUBPAGELIST_T page = findSubPage(name);
1314
 
1315
    if (page.pageID <= 0)
1316
    {
1317
        MSG_ERROR("Subpage " << name << " not found!");
1318
        return false;
1319
    }
1320
 
14 andreas 1321
    if (haveSubPage(name))
1322
        return true;
1323
 
3 andreas 1324
    TSubPage *pg = new TSubPage(page.name+".xml");
14 andreas 1325
 
1326
    if (TError::isError())
1327
    {
1328
        delete pg;
1329
        return false;
1330
    }
1331
 
4 andreas 1332
    pg->setPalette(mPalette);
7 andreas 1333
    pg->setFonts(mFonts);
1334
    pg->registerCallback(_setBackground);
1335
    pg->registerCallbackDB(_displayButton);
11 andreas 1336
    pg->regCallDropSubPage(_callDropSubPage);
21 andreas 1337
    pg->regCallPlayVideo(_callPlayVideo);
11 andreas 1338
    pg->setGroup(page.group);
3 andreas 1339
 
1340
    if (!addSubPage(pg))
14 andreas 1341
    {
1342
        delete pg;
3 andreas 1343
        return false;
14 andreas 1344
    }
3 andreas 1345
 
1346
    return true;
1347
}
1348
 
1349
bool TPageManager::readSubPage(int ID)
1350
{
1351
    DECL_TRACER("TPageManager::readSubPage(int ID)");
1352
 
16 andreas 1353
    TError::clear();
3 andreas 1354
    SUBPAGELIST_T page = findSubPage(ID);
1355
 
1356
    if (page.pageID <= 0)
1357
    {
1358
        MSG_ERROR("Subpage with ID " << ID << " not found!");
1359
        return false;
1360
    }
1361
 
1362
    TSubPage *pg = new TSubPage(page.name+".xml");
14 andreas 1363
 
1364
    if (TError::isError())
1365
    {
1366
        delete pg;
1367
        return false;
1368
    }
1369
 
4 andreas 1370
    pg->setPalette(mPalette);
7 andreas 1371
    pg->setFonts(mFonts);
1372
    pg->registerCallback(_setBackground);
1373
    pg->registerCallbackDB(_displayButton);
11 andreas 1374
    pg->regCallDropSubPage(_callDropSubPage);
21 andreas 1375
    pg->regCallPlayVideo(_callPlayVideo);
11 andreas 1376
    pg->setGroup(page.group);
3 andreas 1377
 
1378
    if (!addSubPage(pg))
1379
        return false;
1380
 
1381
    return true;
1382
}
1383
 
1384
/******************** Internal private methods *********************/
1385
 
1386
PAGELIST_T TPageManager::findPage(const std::string& name)
1387
{
1388
    DECL_TRACER("TPageManager::findPage(const std::string& name)");
1389
 
1390
    vector<PAGELIST_T> pageList = mPageList->getPagelist();
1391
 
83 andreas 1392
    if (pageList.size() > 0)
3 andreas 1393
    {
83 andreas 1394
        vector<PAGELIST_T>::iterator pgIter;
1395
 
118 andreas 1396
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 1397
        {
1398
            if (pgIter->name.compare(name) == 0)
1399
                return *pgIter;
1400
        }
3 andreas 1401
    }
1402
 
1403
    return PAGELIST_T();
1404
}
1405
 
1406
PAGELIST_T TPageManager::findPage(int ID)
1407
{
1408
    DECL_TRACER("TPageManager::findPage(int ID)");
1409
 
1410
    vector<PAGELIST_T> pageList = mPageList->getPagelist();
1411
 
83 andreas 1412
    if (pageList.size() > 0)
3 andreas 1413
    {
83 andreas 1414
        vector<PAGELIST_T>::iterator pgIter;
1415
 
118 andreas 1416
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 1417
        {
1418
            if (pgIter->pageID == ID)
1419
                return *pgIter;
1420
        }
3 andreas 1421
    }
1422
 
1423
    return PAGELIST_T();
1424
}
1425
 
1426
SUBPAGELIST_T TPageManager::findSubPage(const std::string& name)
1427
{
1428
    DECL_TRACER("TPageManager::findSubPage(const std::string& name)");
1429
 
1430
    vector<SUBPAGELIST_T> pageList = mPageList->getSupPageList();
1431
 
83 andreas 1432
    if (pageList.size() > 0)
3 andreas 1433
    {
83 andreas 1434
        vector<SUBPAGELIST_T>::iterator pgIter;
1435
 
118 andreas 1436
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 1437
        {
1438
            if (pgIter->name.compare(name) == 0)
1439
                return *pgIter;
1440
        }
3 andreas 1441
    }
1442
 
1443
    return SUBPAGELIST_T();
1444
}
1445
 
1446
SUBPAGELIST_T TPageManager::findSubPage(int ID)
1447
{
1448
    DECL_TRACER("TPageManager::findSubPage(int ID)");
1449
 
1450
    vector<SUBPAGELIST_T> pageList = mPageList->getSupPageList();
1451
 
83 andreas 1452
    if (pageList.size() > 0)
3 andreas 1453
    {
83 andreas 1454
        vector<SUBPAGELIST_T>::iterator pgIter;
1455
 
118 andreas 1456
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 1457
        {
1458
            if (pgIter->pageID == ID)
1459
                return *pgIter;
1460
        }
3 andreas 1461
    }
1462
 
1463
    return SUBPAGELIST_T();
1464
}
1465
 
1466
bool TPageManager::addPage(TPage* pg)
1467
{
1468
    DECL_TRACER("TPageManager::addPage(TPage* pg)");
1469
 
1470
    if (!pg)
1471
    {
1472
        MSG_ERROR("Parameter is NULL!");
1473
        TError::setError();
1474
        return false;
1475
    }
1476
 
1477
    PCHAIN_T *chain = new PCHAIN_T;
1478
    chain->page = pg;
5 andreas 1479
    chain->next = nullptr;
3 andreas 1480
 
1481
    if (mPchain)
1482
    {
1483
        PCHAIN_T *p = mPchain;
1484
 
1485
        while (p->next)
1486
            p = p->next;
1487
 
1488
        p->next = chain;
1489
    }
1490
    else
14 andreas 1491
    {
3 andreas 1492
        mPchain = chain;
14 andreas 1493
        setPChain(mPchain);
1494
    }
3 andreas 1495
 
1496
    MSG_DEBUG("Added page " << chain->page->getName());
1497
    return true;
1498
}
1499
 
1500
bool TPageManager::addSubPage(TSubPage* pg)
1501
{
1502
    DECL_TRACER("TPageManager::addSubPage(TSubPage* pg)");
1503
 
1504
    if (!pg)
1505
    {
1506
        MSG_ERROR("Parameter is NULL!");
1507
        TError::setError();
1508
        return false;
1509
    }
1510
 
14 andreas 1511
    if (haveSubPage(pg->getNumber()))
1512
    {
1513
        MSG_ERROR("Subpage " << pg->getNumber() << ", " << pg->getName() << " is already in chain!");
1514
        return false;
1515
    }
1516
 
3 andreas 1517
    SPCHAIN_T *chain = new SPCHAIN_T;
1518
    chain->page = pg;
5 andreas 1519
    chain->next = nullptr;
3 andreas 1520
 
1521
    if (mSPchain)
1522
    {
1523
        SPCHAIN_T *p = mSPchain;
1524
 
1525
        while (p->next)
1526
            p = p->next;
1527
 
1528
        p->next = chain;
1529
    }
1530
    else
14 andreas 1531
    {
3 andreas 1532
        mSPchain = chain;
14 andreas 1533
        setSPChain(mSPchain);
1534
    }
3 andreas 1535
 
1536
    MSG_DEBUG("Added subpage " << chain->page->getName());
1537
    return true;
1538
}
4 andreas 1539
 
11 andreas 1540
void TPageManager::dropAllPages()
1541
{
1542
    DECL_TRACER("TPageManager::dropAllPages()");
1543
 
1544
    PCHAIN_T *pg = mPchain;
1545
    PCHAIN_T *next = nullptr;
1546
 
1547
    while (pg)
1548
    {
1549
        next = pg->next;
1550
 
1551
        if (pg->page)
1552
        {
1553
            if (_callDropPage)
1554
                _callDropPage((pg->page->getNumber() << 16) & 0xffff0000);
1555
 
1556
            delete pg->page;
1557
        }
1558
 
1559
        delete pg;
1560
        pg = next;
1561
    }
14 andreas 1562
 
1563
    mPchain = nullptr;
1564
    setPChain(mPchain);
11 andreas 1565
}
1566
 
1567
void TPageManager::dropAllSubPages()
1568
{
1569
    DECL_TRACER("TPageManager::dropAllSubPages()");
1570
 
1571
    SPCHAIN_T *spg = mSPchain;
1572
    SPCHAIN_T *next;
1573
 
1574
    while (spg)
1575
    {
1576
        next = spg->next;
1577
 
1578
        if (spg->page)
1579
        {
1580
            if (_callDropSubPage)
1581
                _callDropSubPage((spg->page->getNumber() << 16) & 0xffff0000);
1582
 
1583
            delete spg->page;
1584
        }
1585
 
1586
        delete spg;
1587
        spg = next;
1588
    }
14 andreas 1589
 
1590
    mSPchain = nullptr;
1591
    setSPChain(mSPchain);
11 andreas 1592
}
1593
 
44 andreas 1594
bool TPageManager::destroyAll()
1595
{
1596
    DECL_TRACER("TPageManager::destroyAll()");
1597
 
1598
    dropAllSubPages();
1599
    dropAllPages();
1600
    mActualPage = 0;
1601
    mPreviousPage = 0;
1602
    mActualGroupName.clear();
1603
 
1604
    if (mPageList)
1605
    {
1606
        delete mPageList;
1607
        mPageList = nullptr;
1608
    }
1609
 
1610
    if (mTSettings)
1611
    {
1612
        delete mTSettings;
1613
        mTSettings = nullptr;
1614
    }
1615
 
1616
    if (mPalette)
1617
    {
1618
        delete mPalette;
1619
        mPalette = nullptr;
1620
    }
1621
 
1622
    if (mFonts)
1623
    {
1624
        delete mFonts;
1625
        mFonts = nullptr;
1626
    }
1627
 
1628
    if (mExternal)
1629
    {
1630
        delete mExternal;
1631
        mExternal = nullptr;
1632
    }
1633
 
1634
    if (gPrjResources)
1635
    {
1636
        delete gPrjResources;
1637
        gPrjResources = nullptr;
1638
    }
1639
 
1640
    if (gIcons)
1641
    {
1642
        delete gIcons;
1643
        gIcons = nullptr;
1644
    }
1645
 
1646
    if (TError::isError())
1647
        return false;
1648
 
1649
    return true;
1650
}
1651
 
51 andreas 1652
Button::TButton *TPageManager::findButton(ulong handle)
1653
{
1654
    DECL_TRACER("TPageManager::findButton(ulong handle)");
1655
 
1656
    TPage *pg = getPage(mActualPage);
1657
 
1658
    if (!pg)
1659
        return nullptr;
1660
 
1661
    vector<Button::TButton *> pgBtList = pg->getAllButtons();
1662
    vector<Button::TButton *>::iterator iter;
83 andreas 1663
 
1664
    if (pgBtList.size() > 0)
51 andreas 1665
    {
83 andreas 1666
        // First we look into the elements of the page
1667
        for (iter = pgBtList.begin(); iter != pgBtList.end(); ++iter)
1668
        {
1669
            Button::TButton *bt = *iter;
51 andreas 1670
 
83 andreas 1671
            if (bt->getHandle() == handle)
1672
                return bt;
1673
        }
51 andreas 1674
    }
1675
 
1676
    // We've not found the wanted element in the elements of the page. So
1677
    // we're looking at the elements of the subpages.
1678
    TSubPage *sp = pg->getFirstSubPage();
1679
 
1680
    if (!sp)
1681
        return nullptr;
1682
 
1683
    while (sp)
1684
    {
1685
        vector<Button::TButton *> spBtList = sp->getAllButtons();
1686
 
83 andreas 1687
        if (spBtList.size() > 0)
51 andreas 1688
        {
83 andreas 1689
            for (iter = spBtList.begin(); iter != spBtList.end(); ++iter)
1690
            {
1691
                Button::TButton *bt = *iter;
51 andreas 1692
 
83 andreas 1693
                if (bt->getHandle() == handle)
1694
                    return bt;
1695
            }
51 andreas 1696
        }
1697
 
1698
        sp = pg->getNextSubPage();
1699
    }
1700
 
1701
    return nullptr;
1702
}
1703
 
4 andreas 1704
TPage *TPageManager::getActualPage()
1705
{
1706
    return getPage(mActualPage);
1707
}
1708
 
1709
TSubPage *TPageManager::getFirstSubPage()
1710
{
1711
    DECL_TRACER("TPageManager::getFirstSubPage()");
1712
    TPage *pg = getPage(mActualPage);
1713
 
1714
    if (!pg)
1715
        return nullptr;
1716
 
1717
    return pg->getFirstSubPage();
1718
}
1719
 
1720
TSubPage *TPageManager::getNextSubPage()
1721
{
1722
    DECL_TRACER("TPageManager::getNextSubPage()");
1723
 
1724
    TPage *pg = getPage(mActualPage);
1725
 
1726
    if (pg)
1727
        return pg->getNextSubPage();
1728
 
1729
    return nullptr;
1730
}
10 andreas 1731
 
11 andreas 1732
TSubPage *TPageManager::getFirstSubPageGroup(const string& group)
1733
{
1734
    DECL_TRACER("TPageManager::getFirstSubPageGroup(const string& group)");
1735
 
14 andreas 1736
    if (group.empty())
1737
    {
1738
        MSG_WARNING("Empty group name is invalid. Ignoring it!");
1739
        mActualGroupName.clear();
1740
        mActualGroupPage = nullptr;
1741
        return nullptr;
1742
    }
1743
 
11 andreas 1744
    mActualGroupName = group;
1745
    TSubPage *pg = getFirstSubPage();
1746
 
1747
    while (pg)
1748
    {
14 andreas 1749
        MSG_DEBUG("Evaluating group " << pg->getGroupName() << " with " << group);
1750
 
11 andreas 1751
        if (pg->getGroupName().compare(group) == 0)
1752
        {
1753
            mActualGroupPage = pg;
1754
            return pg;
1755
        }
1756
 
1757
        pg = getNextSubPage();
1758
    }
1759
 
1760
    mActualGroupName.clear();
1761
    mActualGroupPage = nullptr;
1762
    return nullptr;
1763
}
1764
 
1765
TSubPage *TPageManager::getNextSubPageGroup()
1766
{
1767
    DECL_TRACER("TPageManager::getNextSubPageGroup()");
1768
 
1769
    if (mActualGroupName.empty())
1770
        return nullptr;
1771
 
1772
    TSubPage *pg = getFirstSubPage();
1773
    bool found = false;
1774
 
1775
    while (pg)
1776
    {
14 andreas 1777
        MSG_DEBUG("Evaluating group " << pg->getGroupName() << " with " << mActualGroupName);
1778
 
1779
        if (!found && pg == mActualGroupPage)
11 andreas 1780
        {
1781
            pg = getNextSubPage();
14 andreas 1782
            found = true;
11 andreas 1783
            continue;
1784
        }
1785
 
14 andreas 1786
        if (found && pg->getGroupName().compare(mActualGroupName) == 0)
11 andreas 1787
        {
1788
            mActualGroupPage = pg;
1789
            return pg;
1790
        }
1791
 
1792
        pg = getNextSubPage();
1793
    }
1794
 
1795
    mActualGroupName.clear();
1796
    mActualGroupPage = nullptr;
1797
    return nullptr;
1798
}
1799
 
1800
TSubPage *TPageManager::getNextSubPageGroup(const string& group, TSubPage* pg)
1801
{
1802
    DECL_TRACER("TPageManager::getNextSubPageGroup(const string& group, TSubPage* pg)");
1803
 
1804
    if (group.empty() || !pg)
1805
        return nullptr;
1806
 
1807
    TSubPage *page = getFirstSubPage();
1808
    bool found = false;
1809
 
1810
    while (page)
1811
    {
14 andreas 1812
        MSG_DEBUG("Evaluating group " << pg->getGroupName() << " with " << group);
1813
 
1814
        if (!found && pg == page)
11 andreas 1815
        {
1816
            page = getNextSubPage();
14 andreas 1817
            found = true;
11 andreas 1818
            continue;
1819
        }
1820
 
14 andreas 1821
        if (found && page->getGroupName().compare(group) == 0)
11 andreas 1822
            return page;
1823
 
1824
        page = getNextSubPage();
1825
    }
1826
 
1827
    return nullptr;
1828
}
1829
 
1830
TSubPage *TPageManager::getTopPage()
1831
{
1832
    DECL_TRACER("TPageManager::getTopPage()");
1833
 
1834
    // Scan for all occupied regions
1835
    vector<RECT_T> regions;
1836
 
1837
    TSubPage *pg = getFirstSubPage();
1838
 
1839
    while (pg)
1840
    {
1841
        RECT_T r = pg->getRegion();
1842
        regions.push_back(r);
1843
        pg = getNextSubPage();
1844
    }
1845
 
1846
    // Now scan all pages against all regions to find the top most
1847
    pg = getFirstSubPage();
1848
    TSubPage *top = nullptr;
1849
    int zPos = 0;
1850
 
1851
    while (pg)
1852
    {
1853
        RECT_T r = pg->getRegion();
1854
 
83 andreas 1855
        if (regions.size() > 0)
11 andreas 1856
        {
83 andreas 1857
            vector<RECT_T>::iterator iter;
1858
            int zo = 0;
11 andreas 1859
 
118 andreas 1860
            for (iter = regions.begin(); iter != regions.end(); ++iter)
83 andreas 1861
            {
1862
                if (doOverlap(*iter, r) && zPos > zo)
1863
                    top = pg;
1864
 
1865
                zo++;
1866
            }
11 andreas 1867
        }
1868
 
1869
        pg = getNextSubPage();
1870
        zPos++;
1871
    }
1872
 
1873
    return top;
1874
}
1875
 
1876
TSubPage *TPageManager::getCoordMatch(int x, int y)
1877
{
1878
    DECL_TRACER("TPageManager::getCoordMatch(int x, int y)");
1879
 
26 andreas 1880
    int realX = x;
1881
    int realY = y;
1882
 
11 andreas 1883
    // Reverse order of pages
1884
    map<int, TSubPage *> zOrder;
1885
    TSubPage *pg = getFirstSubPage();
1886
 
1887
    while (pg)
1888
    {
14 andreas 1889
        if (pg->isVisible())
1890
            zOrder.insert(pair<int, TSubPage *>(pg->getZOrder(), pg));
1891
 
11 andreas 1892
        pg = getNextSubPage();
1893
    }
1894
 
1895
    // Iterate in reverse order through array
83 andreas 1896
    if (zOrder.size() > 0)
11 andreas 1897
    {
83 andreas 1898
        map<int, TSubPage *>::reverse_iterator iter;
11 andreas 1899
 
118 andreas 1900
        for (iter = zOrder.rbegin(); iter != zOrder.rend(); ++iter)
11 andreas 1901
        {
83 andreas 1902
            RECT_T r = iter->second->getRegion();
1903
 
1904
            if (r.left <= realX && (r.left + r.width) >= realX &&
1905
                r.top <= realY && (r.top + r.height) >= realY)
1906
            {
1907
                MSG_DEBUG("Click matches subpage " << iter->second->getNumber() << " (" << iter->second->getName() << ")");
1908
                return iter->second;
1909
            }
11 andreas 1910
        }
1911
    }
1912
 
1913
    return nullptr;
1914
}
1915
 
40 andreas 1916
Button::TButton *TPageManager::getCoordMatchPage(int x, int y)
1917
{
1918
    DECL_TRACER("TPageManager::getCoordMatchPage(int x, int y)");
1919
 
1920
    TPage *page = getActualPage();
1921
 
1922
    if (page)
1923
    {
1924
        Button::TButton *bt = page->getFirstButton();
1925
 
1926
        while (bt)
1927
        {
1928
            MSG_DEBUG("Button: " << bt->getButtonIndex() << ", l: " << bt->getLeftPosition() << ", t: " << bt->getTopPosition() << ", w: " << bt->getWidth() << ", h: " << bt->getHeight() << ", x: " << x << ", y: " << y);
1929
 
1930
            if (bt->getLeftPosition() <= x && (bt->getLeftPosition() + bt->getWidth()) >= x &&
1931
                bt->getTopPosition() <= y && (bt->getTopPosition() + bt->getHeight()) >= y)
1932
            {
1933
                MSG_DEBUG("Click matches button " << bt->getButtonIndex() << " (" << bt->getButtonName() << ")");
1934
                return bt;
1935
            }
1936
 
1937
            bt = page->getNextButton();
1938
        }
1939
    }
1940
 
1941
    return nullptr;
1942
}
1943
 
11 andreas 1944
bool TPageManager::doOverlap(RECT_T r1, RECT_T r2)
1945
{
1946
    DECL_TRACER("TPageManager::doOverlap(RECT_T r1, RECT_T r2)");
1947
 
1948
    // If one rectangle is on left side of other
1949
    if (r1.left >= r2.left || r2.left >= r1.left)
1950
        return false;
1951
 
1952
    // If one rectangle is above other
1953
    if (r1.top <= r2.top || r2.top <= r1.top)
1954
        return false;
1955
 
1956
    return true;
1957
}
1958
 
14 andreas 1959
bool TPageManager::havePage(const string& name)
11 andreas 1960
{
14 andreas 1961
    DECL_TRACER("TPageManager::havePage(const string& name)");
11 andreas 1962
 
14 andreas 1963
    if (name.empty())
1964
        return false;
1965
 
1966
    PCHAIN_T *pg = mPchain;
1967
 
1968
    while (pg)
1969
    {
1970
        if (pg->page && pg->page->getName().compare(name) == 0)
1971
            return true;
1972
 
1973
        pg = pg->next;
1974
    }
1975
 
1976
    return false;
1977
}
1978
 
1979
bool TPageManager::haveSubPage(const string& name)
1980
{
1981
    DECL_TRACER("TPageManager::haveSubPage(const string& name)");
1982
 
1983
    if (name.empty())
1984
        return false;
1985
 
11 andreas 1986
    SPCHAIN_T *pg = mSPchain;
1987
 
1988
    while (pg)
1989
    {
14 andreas 1990
        if (pg->page && pg->page->getName().compare(name) == 0)
1991
        {
1992
            MSG_DEBUG("Subpage " << pg->page->getNumber() << ", " << name << " found.");
1993
            return true;
1994
        }
1995
 
1996
        pg = pg->next;
1997
    }
1998
 
1999
    MSG_DEBUG("Subpage " << name << " not found.");
2000
    return false;
2001
}
2002
 
2003
bool TPageManager::haveSubPage(int id)
2004
{
2005
    DECL_TRACER("TPageManager::haveSubPage(int id)");
2006
 
2007
    SPCHAIN_T *pg = mSPchain;
2008
 
2009
    while (pg)
2010
    {
2011
        if (pg->page && pg->page->getNumber() == id)
2012
        {
2013
            MSG_DEBUG("Subpage " << pg->page->getNumber() << ", " << pg->page->getName() << " found.");
2014
            return true;
2015
        }
2016
 
2017
        pg = pg->next;
2018
    }
2019
 
2020
    MSG_DEBUG("Subpage " << id << " not found.");
2021
    return false;
2022
}
2023
 
2024
bool TPageManager::haveSubPage(const string& page, const string& name)
2025
{
2026
    DECL_TRACER("TPageManager::haveSubPage(const string& page, const string& name)");
2027
 
2028
    TPage *pg = getPage(page);
2029
 
2030
    if (!pg)
2031
        return false;
2032
 
2033
    TSubPage *spg = pg->getFirstSubPage();
2034
 
2035
    while (spg)
2036
    {
2037
        if (spg->getName().compare(name) == 0)
2038
        {
2039
            MSG_DEBUG("Subpage " << spg->getNumber() << ", " << name << " found.");
2040
            return true;
2041
        }
2042
 
2043
        spg = pg->getNextSubPage();
2044
    }
2045
 
2046
    MSG_DEBUG("Subpage " << name << " not found on page " << page << ".");
2047
    return false;
2048
}
2049
 
2050
bool TPageManager::haveSubPage(const string& page, int id)
2051
{
2052
    DECL_TRACER("TPageManager::haveSubPage(const string& page, int id)");
2053
 
2054
    TPage *pg = getPage(page);
2055
 
2056
    if (!pg)
2057
        return false;
2058
 
2059
    TSubPage *spg = pg->getFirstSubPage();
2060
 
2061
    while (spg)
2062
    {
2063
        if (spg->getNumber() == id)
2064
        {
2065
            MSG_DEBUG("Subpage " << spg->getNumber() << ", " << spg->getName() << " found.");
2066
            return true;
2067
        }
2068
 
2069
        spg = pg->getNextSubPage();
2070
    }
2071
 
2072
    MSG_DEBUG("Subpage " << id << " on page " << page << " not found.");
2073
    return false;
2074
}
2075
 
2076
void TPageManager::closeGroup(const string& group)
2077
{
2078
    DECL_TRACER("TPageManager::closeGroup(const string& group)");
2079
 
2080
    SPCHAIN_T *pg = mSPchain;
2081
 
2082
    while (pg)
2083
    {
11 andreas 2084
        if (pg->page->getGroupName().compare(group) == 0 && pg->page->isVisible())
2085
        {
2086
            pg->page->regCallDropSubPage(_callDropSubPage);
2087
            pg->page->drop();
2088
            break;
2089
        }
2090
 
2091
        pg = pg->next;
2092
    }
2093
}
2094
 
14 andreas 2095
void TPageManager::showSubPage(const string& name)
2096
{
2097
    DECL_TRACER("TPageManager::showSubPage(const string& name)");
2098
 
2099
    if (name.empty())
2100
        return;
2101
 
96 andreas 2102
    TSubPage *pg = deliverSubPage(name);
14 andreas 2103
 
96 andreas 2104
    if (!pg)
14 andreas 2105
        return;
2106
 
2107
    string group = pg->getGroupName();
2108
 
2109
    if (!group.empty())
2110
    {
2111
        TSubPage *sub = getFirstSubPageGroup(group);
2112
 
2113
        while(sub)
2114
        {
2115
            if (sub->isVisible() && sub->getNumber() != pg->getNumber())
2116
                sub->drop();
2117
 
2118
            sub = getNextSubPageGroup(group, sub);
2119
        }
2120
    }
2121
 
2122
    if (!pg->isVisible())
2123
    {
2124
        TPage *page = getPage(mActualPage);
2125
 
2126
        if (!page)
2127
        {
2128
            MSG_ERROR("No active page found! Internal error.");
2129
            return;
2130
        }
2131
 
2132
        if (!haveSubPage(pg->getNumber()) && !page->addSubPage(pg))
2133
            return;
2134
 
2135
        pg->setZOrder(page->getNextZOrder());
2136
 
2137
        if (_setSubPage)
26 andreas 2138
        {
2139
            int left = pg->getLeft();
2140
            int top = pg->getTop();
2141
            int width = pg->getWidth();
2142
            int height = pg->getHeight();
43 andreas 2143
#ifdef _SCALE_SKIA_
26 andreas 2144
            if (mScaleFactor != 1.0)
2145
            {
2146
                left = (int)((double)left * mScaleFactor);
2147
                top = (int)((double)top * mScaleFactor);
2148
                width = (int)((double)width * mScaleFactor);
2149
                height = (int)((double)height * mScaleFactor);
28 andreas 2150
                MSG_DEBUG("Scaled subpage: left=" << left << ", top=" << top << ", width=" << width << ", height=" << height);
26 andreas 2151
            }
43 andreas 2152
#endif
41 andreas 2153
            ANIMATION_t ani;
2154
            ani.showEffect = pg->getShowEffect();
2155
            ani.showTime = pg->getShowTime();
42 andreas 2156
            ani.hideEffect = pg->getHideEffect();
2157
            ani.hideTime = pg->getHideTime();
54 andreas 2158
            // Test for a timer on the page
2159
            if (pg->getTimeout() > 0)
2160
                pg->startTimer();
2161
 
41 andreas 2162
            _setSubPage((pg->getNumber() << 16) & 0xffff0000, left, top, width, height, ani);
26 andreas 2163
        }
14 andreas 2164
    }
2165
 
2166
    pg->show();
2167
}
2168
 
2169
void TPageManager::hideSubPage(const string& name)
2170
{
2171
    DECL_TRACER("TPageManager::hideSubPage(const string& name)");
2172
 
2173
    if (name.empty())
2174
        return;
2175
 
2176
    TPage *page = getPage(mActualPage);
2177
 
2178
    if (!page)
2179
    {
2180
        MSG_ERROR("No active page found! Internal error.");
2181
        return;
2182
    }
2183
 
2184
    TSubPage *pg = getSubPage(name);
2185
 
2186
    if (pg)
2187
    {
2188
        if (pg->getZOrder() == page->getActZOrder())
2189
            page->decZOrder();
2190
 
2191
        pg->drop();
2192
    }
2193
}
2194
 
11 andreas 2195
/*
2196
 * Catch the mouse presses and scan all pages and subpages for an element to
2197
 * receive the klick.
2198
 */
10 andreas 2199
void TPageManager::mouseEvent(int x, int y, bool pressed)
2200
{
2201
    DECL_TRACER("TPageManager::mouseEvent(int x, int y, bool pressed)");
2202
 
16 andreas 2203
    TError::clear();
11 andreas 2204
    int realX = x - mFirstLeftPixel;
2205
    int realY = y - mFirstTopPixel;
31 andreas 2206
    MSG_DEBUG("Mouse at " << realX << ", " << realY << ", state " << ((pressed) ? "PRESSED" : "RELEASED") << ", [ " << x << " | " << y << " ]");
43 andreas 2207
#ifdef _SCALE_SKIA_
100 andreas 2208
    if (mScaleFactor != 1.0 && mScaleFactor > 0.0)
26 andreas 2209
    {
2210
        realX = (int)((double)realX / mScaleFactor);
2211
        realY = (int)((double)realY / mScaleFactor);
31 andreas 2212
        MSG_DEBUG("Scaled coordinates: x=" << realX << ", y=" << realY);
26 andreas 2213
    }
43 andreas 2214
#endif
70 andreas 2215
 
12 andreas 2216
    TSubPage *subPage = getCoordMatch(realX, realY);
11 andreas 2217
 
2218
    if (!subPage)
14 andreas 2219
    {
40 andreas 2220
        Button::TButton *bt = getCoordMatchPage(x, y);
2221
 
2222
        if (bt)
2223
        {
2224
            MSG_DEBUG("Button on page " << bt->getButtonIndex() << ": size: left=" << bt->getLeftPosition() << ", top=" << bt->getTopPosition() << ", width=" << bt->getWidth() << ", height=" << bt->getHeight());
76 andreas 2225
            TSystemSound sysSound(TConfig::getSystemPath(TConfig::SOUNDS));
71 andreas 2226
 
2227
            if (pressed && _playSound && sysSound.getSystemSoundState())
2228
                _playSound(sysSound.getTouchFeedbackSound());
2229
 
40 andreas 2230
            bt->doClick(x - bt->getLeftPosition(), y - bt->getTopPosition(), pressed);
2231
        }
2232
 
11 andreas 2233
        return;
14 andreas 2234
    }
11 andreas 2235
 
26 andreas 2236
    MSG_DEBUG("Subpage " << subPage->getNumber() << ": size: left=" << subPage->getLeft() << ", top=" << subPage->getTop() << ", width=" << subPage->getWidth() << ", height=" << subPage->getHeight());
11 andreas 2237
    subPage->doClick(realX - subPage->getLeft(), realY - subPage->getTop(), pressed);
10 andreas 2238
}
11 andreas 2239
 
51 andreas 2240
void TPageManager::setTextToButton(ulong handle, const string& txt)
2241
{
2242
    DECL_TRACER("TPageManager::setTextToButton(ulong handle, const string& txt)");
2243
 
2244
    // First we search for the button the handle points to
2245
    Button::TButton *button = findButton(handle);
2246
 
2247
    if (!button)
2248
    {
2249
        MSG_ERROR("No button with handle " << TObject::handleToString(handle) << " found!");
2250
        return;
2251
    }
2252
 
2253
    // Now we search for all buttons with the same channel and port number
2254
    vector<int> channels;
2255
    channels.push_back(button->getAddressChannel());
2256
    vector<MAP_T> map = findButtons(button->getAddressPort(), channels);
2257
 
2258
    if (TError::isError() || map.empty())
2259
        return;
2260
 
2261
    // Here we load all buttons found.
2262
    vector<Button::TButton *> buttons = collectButtons(map);
83 andreas 2263
 
2264
    if (buttons.size() > 0)
51 andreas 2265
    {
83 andreas 2266
        vector<Button::TButton *>::iterator mapIter;
2267
        // Finaly we iterate through all found buttons and set the text
118 andreas 2268
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
83 andreas 2269
        {
2270
            Button::TButton *bt = *mapIter;
51 andreas 2271
 
83 andreas 2272
            int bst = bt->getNumberInstances();
51 andreas 2273
 
83 andreas 2274
            for (int i = 0; i < bst; i++)
2275
                bt->setTextOnly(txt, i);
2276
        }
51 andreas 2277
    }
2278
}
2279
 
14 andreas 2280
vector<Button::TButton *> TPageManager::collectButtons(vector<MAP_T>& map)
2281
{
2282
    DECL_TRACER("TPageManager::collectButtons(vector<MAP_T>& map)");
2283
 
2284
    vector<Button::TButton *> buttons;
83 andreas 2285
 
2286
    if (map.size() == 0)
2287
        return buttons;
2288
 
14 andreas 2289
    vector<MAP_T>::iterator iter;
2290
 
118 andreas 2291
    for (iter = map.begin(); iter != map.end(); ++iter)
14 andreas 2292
    {
2293
        if (iter->pg < 500)     // Main page?
2294
        {
2295
            TPage *page;
2296
 
2297
            if ((page = getPage(iter->pg)) == nullptr)
2298
            {
2299
                MSG_TRACE("Page " << iter->pg << ", " << iter->pn << " not found in memory. Reading it ...");
2300
 
2301
                if (!readPage(iter->pg))
2302
                    return buttons;
2303
 
2304
                page = getPage(iter->pg);
2305
                addPage(page);
2306
            }
2307
 
2308
            Button::TButton *bt = page->getButton(iter->bt);
2309
 
2310
            if (bt)
2311
                buttons.push_back(bt);
2312
        }
2313
        else
2314
        {
2315
            TSubPage *subpage;
2316
 
2317
            if ((subpage = getSubPage(iter->pg)) == nullptr)
2318
            {
2319
                MSG_TRACE("Subpage " << iter->pg << ", " << iter->pn << " not found in memory. Reading it ...");
2320
 
2321
                if (!readSubPage(iter->pg))
2322
                    return buttons;
2323
 
2324
                subpage = getSubPage(iter->pg);
2325
                TPage *page = getActualPage();
2326
 
2327
                if (!page)
2328
                {
2329
                    MSG_ERROR("No actual page loaded!");
2330
                    return buttons;
2331
                }
2332
 
2333
                page->addSubPage(subpage);
2334
            }
2335
 
2336
            Button::TButton *bt = subpage->getButton(iter->bt);
2337
 
2338
            if (bt)
2339
                buttons.push_back(bt);
2340
        }
2341
    }
2342
 
2343
    return buttons;
2344
}
2345
 
11 andreas 2346
/****************************************************************************
36 andreas 2347
 * Calls from a Java activity. This is only available for Android OS.
2348
 ****************************************************************************/
2349
#ifdef __ANDROID__
2350
void TPageManager::initNetworkState()
2351
{
2352
    DECL_TRACER("TPageManager::initNetworkState()");
2353
 
2354
    QAndroidJniObject activity = QtAndroid::androidActivity();
2355
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "Init", "(Landroid/app/Activity;)V", activity.object());
2356
    activity.callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "InstallNetworkListener", "()V");
2357
}
2358
 
2359
void TPageManager::stopNetworkState()
2360
{
2361
    DECL_TRACER("TPageManager::stopNetworkState()");
2362
 
2363
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "destroyNetworkListener", "()V");
2364
}
38 andreas 2365
 
2366
void TPageManager::initBatteryState()
2367
{
2368
    DECL_TRACER("TPageManager::initBatteryState()");
2369
 
2370
    QAndroidJniObject activity = QtAndroid::androidActivity();
2371
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "Init", "(Landroid/app/Activity;)V", activity.object());
2372
    activity.callStaticMethod<void>("org/qtproject/theosys/BatteryState", "InstallBatteryListener", "()V");
2373
}
2374
 
61 andreas 2375
void TPageManager::initPhoneState()
2376
{
2377
    DECL_TRACER("TPageManager::initPhoneState()");
2378
 
2379
    QAndroidJniObject activity = QtAndroid::androidActivity();
2380
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/PhoneCallState", "Init", "(Landroid/app/Activity;)V", activity.object());
2381
    activity.callStaticMethod<void>("org/qtproject/theosys/PhoneCallState", "InstallPhoneListener", "()V");
2382
}
2383
 
38 andreas 2384
void TPageManager::stopBatteryState()
2385
{
2386
    DECL_TRACER("TPageManager::stopBatteryState()");
2387
 
2388
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "destroyBatteryListener", "()V");
2389
}
2390
 
36 andreas 2391
void TPageManager::informTPanelNetwork(jboolean conn, jint level, jint type)
2392
{
2393
    DECL_TRACER("TPageManager::informTPanelNetwork(jboolean conn)");
2394
 
2395
    int l = 0;
2396
    string sType;
2397
 
2398
    switch (type)
2399
    {
2400
        case 1: sType = "Wifi"; break;
2401
        case 2: sType = "Mobile"; break;
2402
 
2403
        default:
2404
            sType = "Unknown"; break;
2405
    }
2406
 
2407
    if (conn)
2408
        l = level;
2409
 
93 andreas 2410
    if (mNetState && mNetState != type)     // Has the connection type changed?
2411
    {
2412
        if (gAmxNet)
2413
            gAmxNet->reconnect();
2414
    }
2415
 
2416
    mNetState = type;
2417
 
36 andreas 2418
    MSG_INFO("Connection status: " << (conn ? "Connected" : "Disconnected") << ", level: " << level << ", type: " << sType);
2419
 
83 andreas 2420
    if (mNetCalls.size() > 0)
36 andreas 2421
    {
83 andreas 2422
        std::map<int, std::function<void (int level)> >::iterator iter;
2423
 
2424
        for (iter = mNetCalls.begin(); iter != mNetCalls.end(); ++iter)
2425
            iter->second(l);
36 andreas 2426
    }
2427
}
38 andreas 2428
 
2429
void TPageManager::informBatteryStatus(jint level, jboolean charging, jint chargeType)
2430
{
2431
    DECL_TRACER("TPageManager::informBatteryStatus(jint level, jboolean charging, jint chargeType)");
2432
 
59 andreas 2433
    MSG_INFO("Battery status: level: " << level << ", " << (charging ? "Charging" : "not charging") << ", type: " << chargeType << ", Elements: " << mBatteryCalls.size());
38 andreas 2434
 
83 andreas 2435
    if (mBatteryCalls.size() > 0)
38 andreas 2436
    {
83 andreas 2437
        std::map<int, std::function<void (int, bool, int)> >::iterator iter;
2438
 
2439
        for (iter = mBatteryCalls.begin(); iter != mBatteryCalls.end(); ++iter)
2440
            iter->second(level, charging, chargeType);
38 andreas 2441
    }
2442
}
61 andreas 2443
 
2444
void TPageManager::informPhoneState(bool call, const string &pnumber)
2445
{
2446
    DECL_TRACER("TPageManager::informPhoneState(bool call, const string &pnumber)");
2447
 
2448
    MSG_INFO("Call state: " << (call ? "Call in progress" : "No call") << ", phone number: " << pnumber);
2449
 
2450
    if (!gAmxNet)
2451
    {
2452
        MSG_WARNING("The network manager for the AMX controller is not initialized!");
2453
        return;
2454
    }
2455
 
2456
    // If a call is in progress (in or out) then stop network connection to controller.
70 andreas 2457
    // TODO: Fix the stop and start of the network!
2458
 /*
61 andreas 2459
    if (call)
2460
        gAmxNet->stop();
2461
    else
2462
        gAmxNet->Run();
70 andreas 2463
*/
61 andreas 2464
}
59 andreas 2465
#endif  // __ANDROID__
36 andreas 2466
 
60 andreas 2467
void TPageManager::setButtonCallbacks(Button::TButton *bt)
2468
{
2469
    bt->registerCallback(_displayButton);
2470
    bt->regCallPlayVideo(_callPlayVideo);
2471
    bt->setFonts(mFonts);
2472
    bt->setPalette(mPalette);
2473
}
2474
 
2475
void TPageManager::externalButton(extButtons_t bt, bool checked)
2476
{
2477
    DECL_TRACER("TPageManager::externalButton(extButtons_t bt)");
2478
 
2479
    if (!mExternal)
2480
        return;
2481
 
2482
    EXTBUTTON_t button = mExternal->getButton(bt);
2483
 
2484
    if (button.type == EXT_NOBUTTON)
2485
        return;
2486
 
2487
    if (button.cp && button.ch)
2488
    {
2489
        amx::ANET_SEND scmd;
2490
 
2491
        scmd.device = TConfig::getChannel();
2492
        scmd.port = button.cp;
2493
        scmd.channel = button.ch;
2494
 
2495
        if (checked)
2496
            scmd.MC = 0x0084;   // push button
2497
            else
2498
                scmd.MC = 0x0085;   // release button
2499
 
2500
                MSG_DEBUG("Sending to device <" << scmd.device << ":" << scmd.port << ":0> channel " << scmd.channel << " value 0x" << std::setw(2) << std::setfill('0') << std::hex << scmd.MC << " (" << (checked?"PUSH":"RELEASE") << ")");
2501
 
2502
            if (gAmxNet)
2503
                gAmxNet->sendCommand(scmd);
2504
            else
2505
            {
2506
                MSG_WARNING("Missing global class TAmxNet. Can't send a message!");
2507
            }
2508
    }
2509
 
2510
}
2511
 
62 andreas 2512
void TPageManager::sendKeyboard(const std::string& text)
2513
{
2514
    DECL_TRACER("TPageManager::sendKeyboard(const std::string& text)");
2515
 
2516
    amx::ANET_SEND scmd;
2517
    scmd.port = 1;
2518
    scmd.channel = 0;
2519
    scmd.msg = UTF8ToCp1250(text);
2520
    scmd.MC = 0x008b;
2521
 
2522
    if (gAmxNet)
2523
        gAmxNet->sendCommand(scmd);
2524
    else
2525
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
2526
}
2527
 
2528
void TPageManager::sendKeypad(const std::string& text)
2529
{
2530
    DECL_TRACER("TPageManager::sendKeypad(const std::string& text)");
2531
 
2532
    amx::ANET_SEND scmd;
2533
    scmd.port = 1;
2534
    scmd.channel = 0;
2535
    scmd.msg = UTF8ToCp1250(text);
2536
    scmd.MC = 0x008b;
2537
 
2538
    if (gAmxNet)
2539
        gAmxNet->sendCommand(scmd);
2540
    else
2541
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
2542
}
2543
 
2544
void TPageManager::sendString(uint handle, const std::string& text)
2545
{
2546
    DECL_TRACER("TPageManager::sendString(uint handle, const std::string& text)");
2547
 
2548
    Button::TButton *bt = findButton(handle);
2549
 
2550
    if (!bt)
2551
    {
2552
        MSG_WARNING("Button " << TObject::handleToString(handle) << " not found!");
2553
        return;
2554
    }
2555
 
2556
    amx::ANET_SEND scmd;
2557
    scmd.port = bt->getAddressPort();
2558
    scmd.channel = bt->getAddressChannel();
2559
    scmd.msg = UTF8ToCp1250(text);
2560
    scmd.MC = 0x008b;
2561
 
2562
    if (gAmxNet)
2563
        gAmxNet->sendCommand(scmd);
2564
    else
2565
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
2566
}
2567
 
111 andreas 2568
void TPageManager::sendKeyStroke(char key)
2569
{
2570
    DECL_TRACER("TPageManager::sendKeyStroke(char key)");
2571
 
2572
    if (!key)
2573
        return;
2574
 
2575
    char msg[2];
2576
    msg[0] = key;
2577
    msg[1] = 0;
2578
 
2579
    amx::ANET_SEND scmd;
2580
    scmd.port = 1;
2581
    scmd.channel = 0;
2582
    scmd.msg.assign(msg);
2583
    scmd.MC = 0x008b;
2584
 
2585
    if (gAmxNet)
2586
        gAmxNet->sendCommand(scmd);
2587
    else
2588
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
2589
 
2590
}
2591
 
110 andreas 2592
/**
2593
 * Sending a custom event is identical in all cases. Because of this I
2594
 * implemented this method to send a custom event. This is called in all cases
2595
 * where a ?XXX command is received.
2596
 *
2597
 * @param value1    The instance of the button.
2598
 * @param value2    The value of a numeric request or the length of the string.
2599
 * @param value3    Always 0
2600
 * @param msg       In case of a string this contains the string.
2601
 * @param evType    This is the event type, a number between 1001 and 1099.
2602
 * @param cp        Channel port of button.
2603
 * @param cn        Channel number. of button.
2604
 *
2605
 * @return If all parameters are valid it returns TRUE.
2606
 */
2607
bool TPageManager::sendCustomEvent(int value1, int value2, int value3, const string& msg, int evType, int cp, int cn)
2608
{
2609
    DECL_TRACER("TPageManager::sendCustomEvent(int value1, int value2, int value3, const string& msg, int evType)");
2610
 
2611
    if (value1 < 1)
2612
        return false;
2613
 
2614
    amx::ANET_SEND scmd;
2615
    scmd.port = cp;
2616
    scmd.channel = cn;
2617
    scmd.ID = scmd.channel;
2618
    scmd.flag = 0;
2619
    scmd.type = evType;
2620
    scmd.value1 = value1;   // instance
2621
    scmd.value2 = value2;
2622
    scmd.value3 = value3;
2623
    scmd.msg = msg;
2624
 
2625
    if (!msg.empty())
2626
        scmd.dtype = 0x0001;// Char array
2627
 
2628
    scmd.MC = 0x008d;       // custom event
2629
 
2630
    if (gAmxNet)
2631
        gAmxNet->sendCommand(scmd);
2632
    else
2633
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
2634
 
2635
    return true;
2636
}
2637
 
36 andreas 2638
/****************************************************************************
11 andreas 2639
 * The following functions implements one of the commands the panel accepts.
2640
 ****************************************************************************/
43 andreas 2641
 
2642
/**
2643
 * This is a special function handling the progress bars when the files of the
2644
 * panel are updated. Instead of simply displaying a ready page, it fakes one
2645
 * with the actual dimensions of the main page. This is possible, because we've
2646
 * always a main page even if the panel is started for the first time.
2647
 */
2648
void TPageManager::doFTR(int port, vector<int>& channels, vector<string>& pars)
23 andreas 2649
{
43 andreas 2650
    DECL_TRACER("TPageManager::doFTR(int, vector<int>&, vector<string>& pars)");
14 andreas 2651
 
23 andreas 2652
    if (pars.empty())
2653
    {
2654
        MSG_WARNING("Command #FTR needs at least 1 parameter! Ignoring command.");
2655
        return;
2656
    }
2657
 
96 andreas 2658
    if (TStreamError::checkFilter(HLOG_DEBUG))
23 andreas 2659
    {
96 andreas 2660
        for (size_t i = 0; i < pars.size(); i++)
2661
        {
2662
            MSG_DEBUG("[" << i << "]: " << pars.at(i));
2663
        }
23 andreas 2664
    }
43 andreas 2665
 
2666
    if (pars.at(0).compare("START") == 0)
2667
    {
2668
        // Here we have to drop all pages and subpages first and then display
2669
        // the faked page with the progress bars.
2670
        MSG_DEBUG("Starting file transfer ...");
2671
        doPPX(port, channels, pars);
2672
        TPage *pg = getPage("_progress");
2673
 
2674
        if (!pg)
2675
        {
2676
            if (!readPage("_progress"))
2677
            {
2678
                MSG_ERROR("Error creating the system page _progress!");
2679
                return;
2680
            }
2681
 
2682
            pg = getPage("_progress");
2683
 
2684
            if (!pg)
2685
            {
2686
                MSG_ERROR("Error getting system page _progress!");
2687
                return;
2688
            }
2689
        }
2690
 
2691
        pg->setFonts(mFonts);
2692
        pg->registerCallback(_setBackground);
2693
        pg->regCallPlayVideo(_callPlayVideo);
2694
 
2695
        if (!pg || !_setPage || !mTSettings)
2696
            return;
2697
 
2698
        int width, height;
2699
        width = mTSettings->getWith();
2700
        height = mTSettings->getHeight();
2701
#ifdef _SCALE_SKIA_
2702
        if (mScaleFactor != 1.0)
2703
        {
2704
            width = (int)((double)width * mScaleFactor);
2705
            height = (int)((double)height * mScaleFactor);
2706
        }
2707
#endif
2708
        _setPage((pg->getNumber() << 16) & 0xffff0000, width, height);
2709
        pg->show();
2710
        MSG_DEBUG("Page _progress on screen");
2711
    }
2712
    else if (pars.at(0).compare("SYNC") == 0)
2713
    {
2714
        TPage *pg = getPage("_progress");
2715
 
2716
        if (!pg)
2717
        {
2718
            MSG_ERROR("Page _progress not found!");
2719
            return;
2720
        }
2721
 
2722
        Button::TButton *bt = pg->getButton(1);   // Line 1
2723
 
2724
        if (!bt)
2725
        {
2726
            MSG_ERROR("Button 160 of page _progress not found!");
2727
            return;
2728
        }
2729
 
2730
        bt->setText(pars.at(2), 0);
2731
        bt->show();
2732
    }
2733
    else if (pars.at(0).compare("FTRSTART") == 0)
2734
    {
2735
        TPage *pg = getPage("_progress");
2736
 
2737
        if (!pg)
2738
        {
2739
            MSG_ERROR("Page _progress not found!");
2740
            return;
2741
        }
2742
 
2743
        Button::TButton *bt1 = pg->getButton(1);   // Line 1
2744
        Button::TButton *bt2 = pg->getButton(2);   // Line 2
2745
        Button::TButton *bt3 = pg->getButton(3);   // Bargraph 1
2746
        Button::TButton *bt4 = pg->getButton(4);   // Bargraph 2
2747
 
2748
        if (!bt1 || !bt2 || !bt3 || !bt4)
2749
        {
2750
            MSG_ERROR("Buttons of page _progress not found!");
2751
            return;
2752
        }
2753
 
2754
        bt1->setText("Transfering files ...", 0);
2755
        bt1->show();
2756
        bt2->setText(pars.at(3), 0);
2757
        bt2->show();
2758
        bt3->drawBargraph(0, atoi(pars.at(1).c_str()), true);
2759
        bt4->drawBargraph(0, atoi(pars.at(2).c_str()), true);
2760
    }
2761
    else if (pars.at(0).compare("FTRPART") == 0)
2762
    {
2763
        TPage *pg = getPage("_progress");
2764
 
2765
        if (!pg)
2766
        {
2767
            MSG_ERROR("Page _progress not found!");
2768
            return;
2769
        }
2770
 
2771
        Button::TButton *bt = pg->getButton(4);   // Bargraph 2
2772
 
2773
        if (!bt)
2774
        {
2775
            MSG_ERROR("Buttons of page _progress not found!");
2776
            return;
2777
        }
2778
 
2779
        bt->drawBargraph(0, atoi(pars.at(2).c_str()), true);
2780
    }
2781
    else if (pars.at(0).compare("END") == 0)
2782
    {
2783
        MSG_TRACE("End of file transfer reached.");
44 andreas 2784
 
2785
        if (_resetSurface)
2786
            _resetSurface();
2787
        else
2788
        {
2789
            MSG_WARNING("Missing callback function \"resetSurface\"!");
2790
        }
43 andreas 2791
    }
23 andreas 2792
}
2793
 
22 andreas 2794
void TPageManager::doON(int port, vector<int>&, vector<string>& pars)
14 andreas 2795
{
2796
    DECL_TRACER("TPageManager::doON(int port, vector<int>& channels, vector<string>& pars)");
2797
 
2798
    if (pars.empty())
2799
    {
2800
        MSG_WARNING("Command ON needs 1 parameter! Ignoring command.");
2801
        return;
2802
    }
2803
 
16 andreas 2804
    TError::clear();
14 andreas 2805
    int c = atoi(pars[0].c_str());
2806
 
2807
    if (c <= 0)
2808
    {
2809
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
2810
        return;
2811
    }
2812
 
2813
    vector<int> chans = { c };
19 andreas 2814
    vector<MAP_T> map = findButtons(port, chans, TYPE_CM);
14 andreas 2815
 
2816
    if (TError::isError() || map.empty())
2817
        return;
2818
 
2819
    vector<Button::TButton *> buttons = collectButtons(map);
2820
 
83 andreas 2821
    if (buttons.size() > 0)
14 andreas 2822
    {
83 andreas 2823
        vector<Button::TButton *>::iterator mapIter;
14 andreas 2824
 
118 andreas 2825
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
83 andreas 2826
        {
2827
            Button::TButton *bt = *mapIter;
2828
 
2829
            if (bt->getButtonType() == Button::GENERAL)
2830
                bt->setActive(1);
2831
        }
14 andreas 2832
    }
2833
}
2834
 
22 andreas 2835
void TPageManager::doOFF(int port, vector<int>&, vector<string>& pars)
14 andreas 2836
{
2837
    DECL_TRACER("TPageManager::doOFF(int port, vector<int>& channels, vector<string>& pars)");
2838
 
2839
    if (pars.empty())
2840
    {
2841
        MSG_WARNING("Command OFF needs 1 parameter! Ignoring command.");
2842
        return;
2843
    }
2844
 
16 andreas 2845
    TError::clear();
14 andreas 2846
    int c = atoi(pars[0].c_str());
2847
 
2848
    if (c <= 0)
2849
    {
2850
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
2851
        return;
2852
    }
2853
 
2854
    vector<int> chans = { c };
19 andreas 2855
    vector<MAP_T> map = findButtons(port, chans, TYPE_CM);
14 andreas 2856
 
2857
    if (TError::isError() || map.empty())
2858
        return;
2859
 
2860
    vector<Button::TButton *> buttons = collectButtons(map);
2861
 
83 andreas 2862
    if (buttons.size() > 0)
14 andreas 2863
    {
83 andreas 2864
        vector<Button::TButton *>::iterator mapIter;
14 andreas 2865
 
118 andreas 2866
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
83 andreas 2867
        {
2868
            Button::TButton *bt = *mapIter;
2869
 
2870
            if (bt->getButtonType() == Button::GENERAL)
2871
                bt->setActive(0);
2872
        }
14 andreas 2873
    }
2874
}
2875
 
22 andreas 2876
void TPageManager::doLEVEL(int port, vector<int>&, vector<string>& pars)
15 andreas 2877
{
2878
    DECL_TRACER("TPageManager::doLEVEL(int port, vector<int>& channels, vector<string>& pars)");
2879
 
2880
    if (pars.size() < 2)
2881
    {
2882
        MSG_WARNING("Command LEVEL needs 2 parameters! Ignoring command.");
2883
        return;
2884
    }
2885
 
16 andreas 2886
    TError::clear();
15 andreas 2887
    int c = atoi(pars[0].c_str());
2888
    int level = atoi(pars[1].c_str());
2889
 
2890
    if (c <= 0)
2891
    {
2892
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
2893
        return;
2894
    }
2895
 
2896
    vector<int> chans = { c };
2897
    vector<MAP_T> map = findBargraphs(port, chans);
2898
 
2899
    if (TError::isError() || map.empty())
2900
    {
2901
        MSG_WARNING("No bargraphs found!");
2902
        return;
2903
    }
2904
 
2905
    vector<Button::TButton *> buttons = collectButtons(map);
2906
 
83 andreas 2907
    if (buttons.size() > 0)
15 andreas 2908
    {
83 andreas 2909
        vector<Button::TButton *>::iterator mapIter;
15 andreas 2910
 
118 andreas 2911
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
15 andreas 2912
        {
83 andreas 2913
            Button::TButton *bt = *mapIter;
2914
 
2915
            if (bt->getButtonType() == Button::BARGRAPH)
2916
                bt->drawBargraph(bt->getActiveInstance(), level);
2917
            else if (bt->getButtonType() == Button::MULTISTATE_BARGRAPH)
2918
            {
2919
                int state = (int)((double)bt->getStateCount() / (double)(bt->getRangeHigh() - bt->getRangeLow()) * (double)level);
2920
                bt->setActive(state);
2921
            }
15 andreas 2922
        }
2923
    }
2924
}
2925
 
22 andreas 2926
void TPageManager::doBLINK(int, vector<int>&, vector<string>& pars)
15 andreas 2927
{
2928
    DECL_TRACER("TPageManager::doBLINK(int port, vector<int>& channels, vector<string>& pars)");
2929
 
2930
    if (pars.size() < 4)
2931
    {
2932
        MSG_WARNING("Command BLINK expects 4 parameters! Command ignored.");
2933
        return;
2934
    }
2935
 
16 andreas 2936
    TError::clear();
15 andreas 2937
    vector<int> sysButtons = { 141, 142, 143, 151, 152, 153, 154, 155, 156, 157, 158 };
2938
    vector<MAP_T> map = findButtons(0, sysButtons);
2939
 
2940
    if (TError::isError() || map.empty())
2941
    {
2942
        MSG_WARNING("No system buttons found.");
2943
        return;
2944
    }
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;
2952
        bt->setActive(0);
2953
    }
2954
}
2955
 
14 andreas 2956
/**
2957
 * Add a specific popup page to a specified popup group if it does not already
2958
 * exist. If the new popup is added to a group which has a popup displayed on
2959
 * the current page along with the new pop-up, the displayed popup will be
2960
 * hidden and the new popup will be displayed.
2961
 */
22 andreas 2962
void TPageManager::doAPG(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 2963
{
2964
    DECL_TRACER("TPageManager::doAPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
2965
 
2966
    if (pars.size() < 2)
2967
    {
2968
        MSG_ERROR("Less than 2 parameters!");
2969
        return;
2970
    }
2971
 
16 andreas 2972
    TError::clear();
11 andreas 2973
    closeGroup(pars[1]);
14 andreas 2974
 
96 andreas 2975
    TPage *page = nullptr;
2976
    TSubPage *subPage = deliverSubPage(pars[0], &page);
14 andreas 2977
 
11 andreas 2978
    if (!subPage)
2979
    {
2980
        MSG_ERROR("Subpage " << pars[0] << " couldn't either found or created!");
2981
        return;
2982
    }
2983
 
2984
    subPage->setGroup(pars[1]);
14 andreas 2985
    subPage->setZOrder(page->getNextZOrder());
11 andreas 2986
    subPage->show();
2987
}
2988
 
14 andreas 2989
/**
2990
 * Clear all popup pages from specified popup group.
2991
 */
22 andreas 2992
void TPageManager::doCPG(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 2993
{
2994
    DECL_TRACER("TPageManager::doCPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
2995
 
2996
    if (pars.size() < 1)
2997
    {
2998
        MSG_ERROR("Expecting 1 parameter but got only 1!");
2999
        return;
3000
    }
3001
 
16 andreas 3002
    TError::clear();
11 andreas 3003
    vector<SUBPAGELIST_T> pageList = mPageList->getSupPageList();
3004
 
83 andreas 3005
    if (pageList.size() > 0)
11 andreas 3006
    {
83 andreas 3007
        vector<SUBPAGELIST_T>::iterator pgIter;
3008
 
3009
        for (pgIter = pageList.begin(); pgIter != pageList.end(); pgIter++)
11 andreas 3010
        {
83 andreas 3011
            if (pgIter->group.compare(pars[0]) == 0)
3012
            {
3013
                pgIter->group.clear();
3014
                TSubPage *pg = getSubPage(pgIter->pageID);
11 andreas 3015
 
83 andreas 3016
                if (pg)
3017
                    pg->setGroup(pgIter->group);
3018
            }
11 andreas 3019
        }
3020
    }
3021
}
3022
 
14 andreas 3023
/**
3024
 * Delete a specific popup page from specified popup group if it exists.
3025
 */
22 andreas 3026
void TPageManager::doDPG(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 3027
{
3028
    DECL_TRACER("TPageManager::doDPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
3029
 
3030
    if (pars.size() < 2)
3031
    {
3032
        MSG_ERROR("Less than 2 parameters!");
3033
        return;
3034
    }
3035
 
16 andreas 3036
    TError::clear();
11 andreas 3037
    SUBPAGELIST_T listPg = findSubPage(pars[0]);
3038
 
3039
    if (!listPg.isValid)
3040
        return;
3041
 
3042
    if (listPg.group.compare(pars[1]) == 0)
3043
    {
3044
        listPg.group.clear();
3045
        TSubPage *pg = getSubPage(listPg.pageID);
3046
 
3047
        if (pg)
3048
            pg->setGroup(listPg.group);
3049
    }
3050
}
3051
 
14 andreas 3052
/**
15 andreas 3053
 * Set the hide effect for the specified popup page to the named hide effect.
3054
 */
22 andreas 3055
void TPageManager::doPHE(int, vector<int>&, vector<string>& pars)
15 andreas 3056
{
3057
    DECL_TRACER("TPageManager::doPHE(int port, vector<int>& channels, vector<string>& pars)");
3058
 
3059
    if (pars.size() < 2)
3060
    {
3061
        MSG_ERROR("Less than 2 parameters!");
3062
        return;
3063
    }
3064
 
16 andreas 3065
    TError::clear();
96 andreas 3066
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 3067
 
3068
    if (!pg)
96 andreas 3069
        return;
15 andreas 3070
 
3071
    if (pars[1].compare("fade") == 0)
3072
        pg->setHideEffect(SE_FADE);
3073
    else if (pars[1].compare("slide to left") == 0)
3074
        pg->setHideEffect(SE_SLIDE_LEFT);
3075
    else if (pars[1].compare("slide to right") == 0)
3076
        pg->setHideEffect(SE_SLIDE_RIGHT);
3077
    else if (pars[1].compare("slide to top") == 0)
3078
        pg->setHideEffect(SE_SLIDE_TOP);
3079
    else if (pars[1].compare("slide to bottom") == 0)
3080
        pg->setHideEffect(SE_SLIDE_BOTTOM);
3081
    else if (pars[1].compare("slide to left fade") == 0)
3082
        pg->setHideEffect(SE_SLIDE_LEFT_FADE);
3083
    else if (pars[1].compare("slide to right fade") == 0)
3084
        pg->setHideEffect(SE_SLIDE_RIGHT_FADE);
3085
    else if (pars[1].compare("slide to top fade") == 0)
3086
        pg->setHideEffect(SE_SLIDE_TOP_FADE);
3087
    else if (pars[1].compare("slide to bottom fade") == 0)
3088
        pg->setHideEffect(SE_SLIDE_BOTTOM_FADE);
3089
    else
3090
        pg->setHideEffect(SE_NONE);
3091
}
3092
 
3093
/**
3094
 * Set the hide effect position. Only 1 coordinate is ever needed for an effect;
3095
 * however, the command will specify both. This command sets the location at
3096
 * which the effect will end at.
3097
 */
22 andreas 3098
void TPageManager::doPHP(int, vector<int>&, vector<string>& pars)
15 andreas 3099
{
3100
    DECL_TRACER("TPageManager::doPHP(int port, vector<int>& channels, vector<string>& pars)");
3101
 
3102
    if (pars.size() < 2)
3103
    {
3104
        MSG_ERROR("Less than 2 parameters!");
3105
        return;
3106
    }
3107
 
16 andreas 3108
    TError::clear();
15 andreas 3109
    size_t pos = pars[1].find(",");
3110
    int x, y;
3111
 
3112
    if (pos == string::npos)
3113
    {
3114
        x = atoi(pars[1].c_str());
3115
        y = 0;
3116
    }
3117
    else
3118
    {
3119
        x = atoi(pars[1].substr(0, pos).c_str());
3120
        y = atoi(pars[1].substr(pos+1).c_str());
3121
    }
3122
 
96 andreas 3123
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 3124
 
3125
    if (!pg)
96 andreas 3126
        return;
15 andreas 3127
 
3128
    pg->setHideEndPosition(x, y);
3129
}
3130
 
3131
/**
3132
 * Set the hide effect time for the specified popup page.
3133
 */
22 andreas 3134
void TPageManager::doPHT(int, vector<int>&, vector<string>& pars)
15 andreas 3135
{
3136
    DECL_TRACER("TPageManager::doPHT(int port, vector<int>& channels, vector<string>& pars)");
3137
 
3138
    if (pars.size() < 2)
3139
    {
3140
        MSG_ERROR("Less than 2 parameters!");
3141
        return;
3142
    }
3143
 
16 andreas 3144
    TError::clear();
96 andreas 3145
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 3146
 
3147
    if (!pg)
96 andreas 3148
        return;
15 andreas 3149
 
3150
    pg->setHideTime(atoi(pars[1].c_str()));
3151
}
3152
 
3153
/**
14 andreas 3154
 * Close all popups on a specified page. If the page name is empty, the current
3155
 * page is used. Same as the ’Clear Page’ command in TPDesign4.
3156
 */
22 andreas 3157
void TPageManager::doPPA(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 3158
{
3159
    DECL_TRACER("TPageManager::doPPA(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
3160
 
16 andreas 3161
    TError::clear();
11 andreas 3162
    TPage *pg;
3163
 
3164
    if (pars.size() == 0)
3165
        pg = getPage(mActualPage);
3166
    else
3167
        pg = getPage(pars[0]);
3168
 
3169
    if (!pg)
3170
        return;
3171
 
12 andreas 3172
    pg->drop();
14 andreas 3173
    pg->resetZOrder();
11 andreas 3174
}
3175
 
14 andreas 3176
/**
3177
 * Deactivate a specific popup page on either a specified page or the current
3178
 * page. If the page name is empty, the current page is used. If the popup page
3179
 * is part of a group, the whole group is deactivated. This command works in
3180
 * the same way as the ’Hide Popup’ command in TPDesign4.
3181
 */
22 andreas 3182
void TPageManager::doPPF(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 3183
{
3184
    DECL_TRACER("TPageManager::doPPF(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
3185
 
3186
    if (pars.size() < 1)
3187
    {
3188
        MSG_ERROR("At least 1 parameter is expected!");
3189
        return;
3190
    }
3191
 
16 andreas 3192
    TError::clear();
14 andreas 3193
    hideSubPage(pars[0]);
12 andreas 3194
}
3195
 
14 andreas 3196
/**
3197
 * Toggle a specific popup page on either a specified page or the current page.
3198
 * If the page name is empty, the current page is used. Toggling refers to the
3199
 * activating/deactivating (On/Off) of a popup page. This command works in the
3200
 * same way as the ’Toggle Popup’ command in TPDesign4.
3201
 */
22 andreas 3202
void TPageManager::doPPG(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 3203
{
3204
    DECL_TRACER("TPageManager::doPPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 3205
 
12 andreas 3206
    if (pars.size() < 1)
3207
    {
3208
        MSG_ERROR("At least 1 parameter is expected!");
3209
        return;
3210
    }
3211
 
16 andreas 3212
    TError::clear();
14 andreas 3213
    TPage *page = getPage(mActualPage);
3214
 
3215
    if (!page)
3216
    {
3217
        MSG_ERROR("No active page found! Internal error.");
3218
        return;
3219
    }
3220
 
12 andreas 3221
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 3222
 
12 andreas 3223
    if (!pg)
3224
        return;
14 andreas 3225
 
12 andreas 3226
    if (pg->isVisible())
3227
    {
14 andreas 3228
        if (pg->getZOrder() == page->getActZOrder())
3229
            page->decZOrder();
3230
 
12 andreas 3231
        pg->drop();
3232
        return;
3233
    }
3234
 
3235
    TSubPage *sub = getFirstSubPageGroup(pg->getGroupName());
14 andreas 3236
 
12 andreas 3237
    while(sub)
3238
    {
3239
        if (sub->getGroupName().compare(pg->getGroupName()) == 0 && sub->isVisible())
3240
            sub->drop();
14 andreas 3241
 
12 andreas 3242
        sub = getNextSubPageGroup(pg->getGroupName(), sub);
3243
    }
3244
 
3245
    pg->show();
14 andreas 3246
    pg->setZOrder(page->getNextZOrder());
12 andreas 3247
}
3248
 
14 andreas 3249
/**
3250
 * Kill refers to the deactivating (Off) of a popup window from all pages. If
3251
 * the pop-up page is part of a group, the whole group is deactivated. This
3252
 * command works in the same way as the 'Clear Group' command in TPDesign 4.
3253
 */
22 andreas 3254
void TPageManager::doPPK(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 3255
{
3256
    DECL_TRACER("TPageManager::doPPK(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 3257
 
12 andreas 3258
    if (pars.size() < 1)
3259
    {
3260
        MSG_ERROR("At least 1 parameter is expected!");
3261
        return;
3262
    }
3263
 
16 andreas 3264
    TError::clear();
14 andreas 3265
    TPage *page = getPage(mActualPage);
3266
 
3267
    if (!page)
3268
    {
3269
        MSG_ERROR("No active page found! Internal error.");
3270
        return;
3271
    }
3272
 
12 andreas 3273
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 3274
 
12 andreas 3275
    if (pg)
14 andreas 3276
    {
3277
        if (pg->getZOrder() == page->getActZOrder())
3278
            page->decZOrder();
3279
 
3280
        pg->drop();
3281
    }
12 andreas 3282
}
3283
 
14 andreas 3284
/**
3285
 * Set the modality of a specific popup page to Modal or NonModal.
3286
 * A Modal popup page, when active, only allows you to use the buttons and
3287
 * features on that popup page. All other buttons on the panel page are
3288
 * inactivated.
3289
 */
22 andreas 3290
void TPageManager::doPPM(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 3291
{
3292
    DECL_TRACER("TPageManager::doPPM(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 3293
 
12 andreas 3294
    if (pars.size() < 2)
3295
    {
3296
        MSG_ERROR("Expecting 2 parameters!");
3297
        return;
3298
    }
14 andreas 3299
 
16 andreas 3300
    TError::clear();
12 andreas 3301
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 3302
 
12 andreas 3303
    if (pg)
3304
    {
3305
        if (pars[1] == "1" || pars[1].compare("modal") == 0 || pars[1].compare("MODAL") == 0)
3306
            pg->setModal(1);
3307
        else
3308
            pg->setModal(0);
3309
    }
3310
}
3311
 
14 andreas 3312
/**
3313
 * Activate a specific popup page to launch on either a specified page or the
3314
 * current page. If the page name is empty, the current page is used. If the
3315
 * popup page is already on, do not re-draw it. This command works in the same
3316
 * way as the ’Show Popup’ command in TPDesign4.
3317
 */
22 andreas 3318
void TPageManager::doPPN(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 3319
{
3320
    DECL_TRACER("TPageManager::doPPN(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
3321
 
3322
    if (pars.size() < 1)
3323
    {
3324
        MSG_ERROR("At least 1 parameter is expected!");
3325
        return;
3326
    }
3327
 
16 andreas 3328
    TError::clear();
14 andreas 3329
    showSubPage(pars[0]);
12 andreas 3330
}
3331
 
14 andreas 3332
/**
15 andreas 3333
 * Set a specific popup page to timeout within a specified time. If timeout is
3334
 * empty, popup page will clear the timeout.
3335
 */
22 andreas 3336
void TPageManager::doPPT(int, vector<int>&, vector<string>& pars)
15 andreas 3337
{
3338
    DECL_TRACER("TPageManager::doPPT(int port, vector<int>& channels, vector<string>& pars)");
3339
 
3340
    if (pars.size() < 2)
3341
    {
3342
        MSG_ERROR("Expecting 2 parameters!");
3343
        return;
3344
    }
3345
 
16 andreas 3346
    TError::clear();
96 andreas 3347
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 3348
 
3349
    if (!pg)
96 andreas 3350
        return;
15 andreas 3351
 
3352
    pg->setTimeout(atoi(pars[1].c_str()));
3353
}
3354
 
3355
/**
14 andreas 3356
 * Close all popups on all pages. This command works in the same way as the
3357
 * 'Clear All' command in TPDesign 4.
3358
 */
22 andreas 3359
void TPageManager::doPPX(int, std::vector<int>&, std::vector<std::string>&)
12 andreas 3360
{
3361
    DECL_TRACER("TPageManager::doPPX(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
3362
 
16 andreas 3363
    TError::clear();
12 andreas 3364
    PCHAIN_T *chain = mPchain;
14 andreas 3365
 
12 andreas 3366
    while(chain)
3367
    {
3368
        TSubPage *sub = chain->page->getFirstSubPage();
14 andreas 3369
 
12 andreas 3370
        while (sub)
3371
        {
14 andreas 3372
            MSG_DEBUG("Dopping subpage " << sub->getNumber() << ", \"" << sub->getName() << "\".");
12 andreas 3373
            sub->drop();
3374
            sub = chain->page->getNextSubPage();
3375
        }
14 andreas 3376
 
12 andreas 3377
        chain = chain->next;
3378
    }
14 andreas 3379
 
3380
    TPage *page = getPage(mActualPage);
3381
 
3382
    if (!page)
3383
    {
3384
        MSG_ERROR("No active page found! Internal error.");
3385
        return;
3386
    }
3387
 
3388
    page->resetZOrder();
12 andreas 3389
}
3390
 
14 andreas 3391
/**
15 andreas 3392
 * Set the show effect for the specified popup page to the named show effect.
3393
 */
22 andreas 3394
void TPageManager::doPSE(int, vector<int>&, vector<string>& pars)
15 andreas 3395
{
3396
    DECL_TRACER("TPageManager::doPSE(int port, vector<int>& channels, vector<string>& pars)");
3397
 
3398
    if (pars.size() < 2)
3399
    {
3400
        MSG_ERROR("Less than 2 parameters!");
3401
        return;
3402
    }
3403
 
16 andreas 3404
    TError::clear();
96 andreas 3405
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 3406
 
3407
    if (!pg)
96 andreas 3408
        return;
15 andreas 3409
 
3410
    if (pars[1].compare("fade") == 0)
3411
        pg->setShowEffect(SE_FADE);
3412
    else if (pars[1].compare("slide to left") == 0)
3413
        pg->setShowEffect(SE_SLIDE_LEFT);
3414
    else if (pars[1].compare("slide to right") == 0)
3415
        pg->setShowEffect(SE_SLIDE_RIGHT);
3416
    else if (pars[1].compare("slide to top") == 0)
3417
        pg->setShowEffect(SE_SLIDE_TOP);
3418
    else if (pars[1].compare("slide to bottom") == 0)
3419
        pg->setShowEffect(SE_SLIDE_BOTTOM);
3420
    else if (pars[1].compare("slide to left fade") == 0)
3421
        pg->setShowEffect(SE_SLIDE_LEFT_FADE);
3422
    else if (pars[1].compare("slide to right fade") == 0)
3423
        pg->setShowEffect(SE_SLIDE_RIGHT_FADE);
3424
    else if (pars[1].compare("slide to top fade") == 0)
3425
        pg->setShowEffect(SE_SLIDE_TOP_FADE);
3426
    else if (pars[1].compare("slide to bottom fade") == 0)
3427
        pg->setShowEffect(SE_SLIDE_BOTTOM_FADE);
3428
    else
3429
        pg->setShowEffect(SE_NONE);
3430
}
3431
 
22 andreas 3432
void TPageManager::doPSP(int, vector<int>&, vector<string>& pars)
15 andreas 3433
{
3434
    DECL_TRACER("TPageManager::doPSP(int port, vector<int>& channels, vector<string>& pars)");
3435
 
3436
    if (pars.size() < 2)
3437
    {
3438
        MSG_ERROR("Less than 2 parameters!");
3439
        return;
3440
    }
3441
 
16 andreas 3442
    TError::clear();
15 andreas 3443
    size_t pos = pars[1].find(",");
3444
    int x, y;
3445
 
3446
    if (pos == string::npos)
3447
    {
3448
        x = atoi(pars[1].c_str());
3449
        y = 0;
3450
    }
3451
    else
3452
    {
3453
        x = atoi(pars[1].substr(0, pos).c_str());
3454
        y = atoi(pars[1].substr(pos+1).c_str());
3455
    }
3456
 
96 andreas 3457
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 3458
 
3459
    if (!pg)
96 andreas 3460
        return;
15 andreas 3461
 
3462
    pg->setShowEndPosition(x, y);
3463
}
3464
 
3465
/**
3466
 * Set the show effect time for the specified popup page.
3467
 */
22 andreas 3468
void TPageManager::doPST(int, vector<int>&, vector<string>& pars)
15 andreas 3469
{
3470
    DECL_TRACER("TPageManager::doPST(int port, vector<int>& channels, vector<string>& pars)");
3471
 
3472
    if (pars.size() < 2)
3473
    {
3474
        MSG_ERROR("Less than 2 parameters!");
3475
        return;
3476
    }
3477
 
16 andreas 3478
    TError::clear();
96 andreas 3479
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 3480
 
3481
    if (!pg)
96 andreas 3482
        return;
15 andreas 3483
 
3484
    pg->setShowTime(atoi(pars[1].c_str()));
3485
}
3486
 
3487
/**
14 andreas 3488
 * Flips to a page with a specified page name. If the page is currently active,
3489
 * it will not redraw the page.
3490
 */
22 andreas 3491
void TPageManager::doPAGE(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 3492
{
3493
    DECL_TRACER("TPageManager::doPAGE(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 3494
 
15 andreas 3495
    if (pars.empty())
3496
    {
3497
        MSG_WARNING("Got no page parameter!");
3498
        return;
3499
    }
14 andreas 3500
 
16 andreas 3501
    TError::clear();
15 andreas 3502
    setPage(pars[0]);
3503
}
3504
 
3505
/**
38 andreas 3506
 * @brief TPageManager::doANI Run a button animation (in 1/10 second).
3507
 * Syntax:
3508
 *      ^ANI-<vt addr range>,<start state>,<end state>,<time>
3509
 * Variable:
3510
 *      variable text address range = 1 - 4000.
3511
 *      start state = Beginning of button state (0= current state).
3512
 *      end state = End of button state.
3513
 *      time = In 1/10 second intervals.
3514
 * Example:
3515
 *      SEND_COMMAND Panel,"'^ANI-500,1,25,100'"
3516
 * Runs a button animation at text range 500 from state 1 to state 25 for 10 seconds.
3517
 *
3518
 * @param port      The port number
3519
 * @param channels  The channels of the buttons
3520
 * @param pars      The parameters
3521
 */
3522
void TPageManager::doANI(int port, std::vector<int> &channels, std::vector<std::string> &pars)
3523
{
3524
    DECL_TRACER("TPageManager::doANI(int port, std::vector<int> &channels, std::vector<std::string> &pars)");
3525
 
3526
    if (pars.size() < 3)
3527
    {
3528
        MSG_ERROR("Expecting 3 parameters but got " << pars.size() << "! Ignoring command.");
3529
        return;
3530
    }
3531
 
3532
    TError::clear();
3533
    int stateStart = atoi(pars[0].c_str());
3534
    int endState = atoi(pars[1].c_str());
3535
    int runTime = atoi(pars[2].c_str());
3536
 
3537
    vector<MAP_T> map = findButtons(port, channels);
3538
 
3539
    if (TError::isError() || map.empty())
3540
        return;
3541
 
3542
    vector<Button::TButton *> buttons = collectButtons(map);
3543
 
83 andreas 3544
    if (buttons.size() > 0)
38 andreas 3545
    {
83 andreas 3546
        vector<Button::TButton *>::iterator mapIter;
3547
 
3548
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
3549
        {
3550
            Button::TButton *bt = *mapIter;
3551
            bt->startAnimation(stateStart, endState, runTime);
3552
        }
38 andreas 3553
    }
3554
}
3555
 
3556
/**
15 andreas 3557
 * Add page flip action to a button if it does not already exist.
3558
 */
3559
void TPageManager::doAPF(int port, vector<int>& channels, vector<string>& pars)
3560
{
3561
    DECL_TRACER("TPageManager::doAPF(int port, vector<int>& channels, vector<string>& pars)");
3562
 
3563
    if (pars.size() < 2)
3564
    {
3565
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
14 andreas 3566
        return;
15 andreas 3567
    }
14 andreas 3568
 
16 andreas 3569
    TError::clear();
15 andreas 3570
    string action = pars[0];
3571
    string pname = pars[1];
14 andreas 3572
 
15 andreas 3573
    vector<MAP_T> map = findButtons(port, channels);
14 andreas 3574
 
15 andreas 3575
    if (TError::isError() || map.empty())
3576
        return;
3577
 
3578
    vector<Button::TButton *> buttons = collectButtons(map);
3579
 
83 andreas 3580
    if (buttons.size() > 0)
12 andreas 3581
    {
83 andreas 3582
        vector<Button::TButton *>::iterator mapIter;
3583
 
3584
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
3585
        {
3586
            Button::TButton *bt = *mapIter;
3587
            setButtonCallbacks(bt);
3588
            bt->addPushFunction(action, pname);
3589
        }
15 andreas 3590
    }
3591
}
12 andreas 3592
 
15 andreas 3593
/**
43 andreas 3594
 * Append non-unicode text.
3595
 */
3596
void TPageManager::doBAT(int port, vector<int> &channels, vector<string> &pars)
3597
{
3598
    DECL_TRACER("TPageManager::doBAT(int port, vector<int> &channels, vector<string> &pars)");
3599
 
3600
    if (pars.size() < 1)
3601
    {
3602
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
3603
        return;
3604
    }
3605
 
3606
    TError::clear();
3607
    int btState = atoi(pars[0].c_str());
3608
    string text;
3609
 
3610
    if (pars.size() > 1)
3611
        text = pars[1];
3612
 
3613
    vector<MAP_T> map = findButtons(port, channels);
3614
 
3615
    if (TError::isError() || map.empty())
3616
        return;
3617
 
3618
    vector<Button::TButton *> buttons = collectButtons(map);
3619
 
83 andreas 3620
    if (buttons.size() > 0)
43 andreas 3621
    {
83 andreas 3622
        vector<Button::TButton *>::iterator mapIter;
43 andreas 3623
 
83 andreas 3624
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
43 andreas 3625
        {
83 andreas 3626
            Button::TButton *bt = *mapIter;
3627
            setButtonCallbacks(bt);
43 andreas 3628
 
83 andreas 3629
            if (btState == 0)       // All instances?
3630
            {
3631
                int bst = bt->getNumberInstances();
3632
 
3633
                for (int i = 0; i < bst; i++)
3634
                    bt->appendText(text, i);
3635
            }
3636
            else
3637
                bt->appendText(text, btState - 1);
43 andreas 3638
        }
3639
    }
3640
}
3641
 
3642
/**
60 andreas 3643
 * @brief Append unicode text. Same format as ^UNI.
3644
 * This command allows to set up to 50 characters of ASCII code. The unicode
3645
 * characters must be set as hex numbers.
3646
 */
3647
void TPageManager::doBAU(int port, vector<int>& channels, vector<string>& pars)
3648
{
3649
    DECL_TRACER("TPageManager::doBAU(int port, vector<int>& channels, vector<string>& pars)");
3650
 
3651
    if (pars.size() < 1)
3652
    {
3653
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
3654
        return;
3655
    }
3656
 
3657
    TError::clear();
3658
    int btState = atoi(pars[0].c_str());
3659
    string text;
3660
    char ch[3];
3661
 
3662
    if (pars.size() > 1)
3663
    {
3664
        text = pars[1];
3665
        // Because the unicode characters are hex numbers, we scan the text
3666
        // and convert the hex numbers into real numbers.
3667
        size_t len = text.length();
3668
        string t;
3669
        bool inHex = false;
3670
        int lastChar = 0;
3671
 
3672
        for (size_t i = 0; i < len; i++)
3673
        {
3674
            if (!inHex && isHex(text.at(i)))
3675
            {
3676
                inHex = true;
3677
                lastChar = text.at(i);
3678
                continue;
3679
            }
3680
 
3681
            if (inHex && !isHex(text.at(i)))
3682
            {
3683
                inHex = false;
3684
                ch[0] = lastChar;
3685
                ch[1] = 0;
3686
                t.append(ch);
3687
            }
3688
 
3689
            if (inHex && isHex(text.at(i)))
3690
            {
3691
                ch[0] = lastChar;
3692
                ch[1] = text.at(i);
3693
                ch[2] = 0;
3694
                int num = (int)strtol(ch, NULL, 16);
3695
                ch[0] = num;
3696
                ch[1] = 0;
3697
                t.append(ch);
3698
                inHex = false;
3699
                continue;
3700
            }
3701
 
3702
            ch[0] = text.at(i);
3703
            ch[1] = 0;
3704
            t.append(ch);
3705
        }
3706
 
3707
        text = t;
3708
    }
3709
 
3710
    vector<MAP_T> map = findButtons(port, channels);
3711
 
3712
    if (TError::isError() || map.empty())
3713
        return;
3714
 
3715
    vector<Button::TButton *> buttons = collectButtons(map);
3716
 
83 andreas 3717
    if (buttons.size() > 0)
60 andreas 3718
    {
83 andreas 3719
        vector<Button::TButton *>::iterator mapIter;
60 andreas 3720
 
83 andreas 3721
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 3722
        {
83 andreas 3723
            Button::TButton *bt = *mapIter;
3724
            setButtonCallbacks(bt);
60 andreas 3725
 
83 andreas 3726
            if (btState == 0)       // All instances?
3727
            {
3728
                int bst = bt->getNumberInstances();
3729
 
3730
                for (int i = 0; i < bst; i++)
3731
                    bt->appendText(text, i);
3732
            }
3733
            else
3734
                bt->appendText(text, btState - 1);
60 andreas 3735
        }
3736
    }
3737
}
3738
 
3739
/**
43 andreas 3740
 * @brief TPageManager::doBCB Set the border color.
3741
 * Set the border color to the specified color. Only if the specified border
3742
 * color is not the same as the current color.
3743
 * Note: Color can be assigned by color name (without spaces), number or
3744
 * R,G,B value (RRGGBB or RRGGBBAA).
3745
 */
3746
void TPageManager::doBCB(int port, vector<int> &channels, vector<string> &pars)
3747
{
3748
    DECL_TRACER("TPageManager::doBCB(int port, vector<int> &channels, vector<string> &pars)");
3749
 
3750
    if (pars.size() < 1)
3751
    {
3752
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
3753
        return;
3754
    }
3755
 
3756
    TError::clear();
3757
    int btState = atoi(pars[0].c_str());
3758
    string color;
3759
 
3760
    if (pars.size() > 1)
3761
        color = pars[1];
3762
 
3763
    vector<MAP_T> map = findButtons(port, channels);
3764
 
3765
    if (TError::isError() || map.empty())
3766
        return;
3767
 
3768
    vector<Button::TButton *> buttons = collectButtons(map);
3769
 
83 andreas 3770
    if (buttons.size() > 0)
43 andreas 3771
    {
83 andreas 3772
        vector<Button::TButton *>::iterator mapIter;
43 andreas 3773
 
83 andreas 3774
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
43 andreas 3775
        {
83 andreas 3776
            Button::TButton *bt = *mapIter;
3777
            setButtonCallbacks(bt);
43 andreas 3778
 
83 andreas 3779
            if (btState == 0)       // All instances?
3780
            {
3781
                int bst = bt->getNumberInstances();
3782
 
3783
                for (int i = 0; i < bst; i++)
3784
                    bt->setBorderColor(color, i);
3785
            }
3786
            else
3787
                bt->setBorderColor(color, btState - 1);
43 andreas 3788
        }
3789
    }
3790
}
60 andreas 3791
 
82 andreas 3792
void TPageManager::getBCB(int port, vector<int> &channels, vector<string> &pars)
3793
{
3794
    DECL_TRACER("TPageManager::getBCB(int port, vector<int> &channels, vector<string> &pars)");
3795
 
3796
    if (pars.size() < 1)
3797
    {
3798
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
3799
        return;
3800
    }
3801
 
3802
    TError::clear();
3803
    int btState = atoi(pars[0].c_str());
3804
    string color;
3805
 
3806
    vector<MAP_T> map = findButtons(port, channels);
3807
 
3808
    if (TError::isError() || map.empty())
3809
        return;
3810
 
3811
    vector<Button::TButton *> buttons = collectButtons(map);
3812
 
83 andreas 3813
    if (buttons.size() > 0)
82 andreas 3814
    {
110 andreas 3815
        Button::TButton *bt = buttons[0];
82 andreas 3816
 
110 andreas 3817
        if (btState == 0)       // All instances?
82 andreas 3818
        {
110 andreas 3819
            int bst = bt->getNumberInstances();
82 andreas 3820
 
110 andreas 3821
            for (int i = 0; i < bst; i++)
82 andreas 3822
            {
110 andreas 3823
                color = bt->getBorderColor(i);
82 andreas 3824
 
110 andreas 3825
                if (color.empty())
3826
                    continue;
83 andreas 3827
 
110 andreas 3828
                sendCustomEvent(i + 1, color.length(), 0, color, 1011, bt->getChannelPort(), bt->getChannelNumber());
83 andreas 3829
            }
110 andreas 3830
        }
3831
        else
3832
        {
3833
            color = bt->getBorderColor(btState - 1);
83 andreas 3834
 
110 andreas 3835
            if (color.empty())
3836
                return;
82 andreas 3837
 
110 andreas 3838
            sendCustomEvent(btState, color.length(), 0, color, 1011, bt->getChannelPort(), bt->getChannelNumber());
82 andreas 3839
        }
3840
    }
3841
}
3842
 
43 andreas 3843
/**
60 andreas 3844
 * @brief Set the fill color to the specified color.
3845
 * Only if the specified fill color is not the same as the current color.
3846
 * Note: Color can be assigned by color name (without spaces), number or R,G,B value (RRGGBB or RRGGBBAA).
15 andreas 3847
 */
60 andreas 3848
void TPageManager::doBCF(int port, vector<int>& channels, vector<std::string>& pars)
15 andreas 3849
{
60 andreas 3850
    DECL_TRACER("TPageManager::doBCF(int port, vector<int>& channels, vector<std::string>& pars)");
15 andreas 3851
 
60 andreas 3852
    if (pars.size() < 1)
15 andreas 3853
    {
60 andreas 3854
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
12 andreas 3855
        return;
3856
    }
14 andreas 3857
 
16 andreas 3858
    TError::clear();
15 andreas 3859
    int btState = atoi(pars[0].c_str());
60 andreas 3860
    string color;
14 andreas 3861
 
60 andreas 3862
    if (pars.size() > 1)
3863
        color = pars[1];
3864
 
15 andreas 3865
    vector<MAP_T> map = findButtons(port, channels);
3866
 
3867
    if (TError::isError() || map.empty())
3868
        return;
3869
 
3870
    vector<Button::TButton *> buttons = collectButtons(map);
3871
 
83 andreas 3872
    if (buttons.size() > 0)
15 andreas 3873
    {
83 andreas 3874
        vector<Button::TButton *>::iterator mapIter;
15 andreas 3875
 
83 andreas 3876
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
15 andreas 3877
        {
83 andreas 3878
            Button::TButton *bt = *mapIter;
3879
            setButtonCallbacks(bt);
15 andreas 3880
 
83 andreas 3881
            if (btState == 0)       // All instances?
3882
            {
3883
                int bst = bt->getNumberInstances();
3884
 
3885
                for (int i = 0; i < bst; i++)
3886
                    bt->setFillColor(color, i);
3887
            }
3888
            else
3889
                bt->setFillColor(color, btState - 1);
15 andreas 3890
        }
3891
    }
12 andreas 3892
}
3893
 
82 andreas 3894
void TPageManager::getBCF(int port, vector<int> &channels, vector<string> &pars)
3895
{
3896
    DECL_TRACER("TPageManager::getBCF(int port, vector<int> &channels, vector<string> &pars)");
3897
 
3898
    if (pars.size() < 1)
3899
    {
3900
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
3901
        return;
3902
    }
3903
 
3904
    TError::clear();
3905
    int btState = atoi(pars[0].c_str());
3906
    string color;
3907
 
3908
    vector<MAP_T> map = findButtons(port, channels);
3909
 
3910
    if (TError::isError() || map.empty())
3911
        return;
3912
 
3913
    vector<Button::TButton *> buttons = collectButtons(map);
3914
 
83 andreas 3915
    if (buttons.size() > 0)
82 andreas 3916
    {
110 andreas 3917
        Button::TButton *bt = buttons[0];
82 andreas 3918
 
110 andreas 3919
        if (btState == 0)       // All instances?
82 andreas 3920
        {
110 andreas 3921
            int bst = bt->getNumberInstances();
82 andreas 3922
 
110 andreas 3923
            for (int i = 0; i < bst; i++)
82 andreas 3924
            {
110 andreas 3925
                color = bt->getFillColor(i);
82 andreas 3926
 
110 andreas 3927
                if (color.empty())
3928
                    continue;
82 andreas 3929
 
110 andreas 3930
                sendCustomEvent(i + 1, color.length(), 0, color, 1012, bt->getChannelPort(), bt->getChannelNumber());
83 andreas 3931
            }
82 andreas 3932
        }
110 andreas 3933
        else
3934
        {
3935
            color = bt->getFillColor(btState-1);
3936
            sendCustomEvent(btState, color.length(), 0, color, 1012, bt->getChannelPort(), bt->getChannelNumber());
3937
        }
82 andreas 3938
    }
3939
}
3940
 
60 andreas 3941
/**
3942
 * @brief Set the text color to the specified color.
3943
 * Only if the specified text color is not the same as the current color.
3944
 * Note: Color can be assigned by color name (without spaces), number or R,G,B value (RRGGBB or RRGGBBAA).
3945
 */
3946
void TPageManager::doBCT(int port, vector<int>& channels, vector<string>& pars)
18 andreas 3947
{
60 andreas 3948
    DECL_TRACER("TPageManager::doBCT(int port, vector<int>& channels, vector<string>& pars)");
3949
 
3950
    if (pars.size() < 1)
3951
    {
3952
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
3953
        return;
3954
    }
3955
 
3956
    TError::clear();
3957
    int btState = atoi(pars[0].c_str());
3958
    string color;
3959
 
3960
    if (pars.size() > 1)
3961
        color = pars[1];
3962
 
3963
    vector<MAP_T> map = findButtons(port, channels);
3964
 
3965
    if (TError::isError() || map.empty())
3966
        return;
3967
 
3968
    vector<Button::TButton *> buttons = collectButtons(map);
3969
 
83 andreas 3970
    if (buttons.size() > 0)
60 andreas 3971
    {
83 andreas 3972
        vector<Button::TButton *>::iterator mapIter;
60 andreas 3973
 
83 andreas 3974
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 3975
        {
83 andreas 3976
            Button::TButton *bt = *mapIter;
3977
            setButtonCallbacks(bt);
60 andreas 3978
 
83 andreas 3979
            if (btState == 0)       // All instances?
3980
            {
3981
                int bst = bt->getNumberInstances();
3982
 
3983
                for (int i = 0; i < bst; i++)
3984
                    bt->setTextColor(color, i);
3985
            }
3986
            else
3987
                bt->setTextColor(color, btState - 1);
60 andreas 3988
        }
3989
    }
18 andreas 3990
}
3991
 
82 andreas 3992
void TPageManager::getBCT(int port, vector<int> &channels, vector<string> &pars)
3993
{
3994
    DECL_TRACER("TPageManager::getBCT(int port, vector<int> &channels, vector<string> &pars)");
3995
 
3996
    if (pars.size() < 1)
3997
    {
3998
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
3999
        return;
4000
    }
4001
 
4002
    TError::clear();
4003
    int btState = atoi(pars[0].c_str());
4004
    string color;
4005
 
4006
    vector<MAP_T> map = findButtons(port, channels);
4007
 
4008
    if (TError::isError() || map.empty())
4009
        return;
4010
 
4011
    vector<Button::TButton *> buttons = collectButtons(map);
4012
 
83 andreas 4013
    if (buttons.size() > 0)
82 andreas 4014
    {
110 andreas 4015
        Button::TButton *bt = buttons[0];
82 andreas 4016
 
110 andreas 4017
        if (btState == 0)       // All instances?
82 andreas 4018
        {
110 andreas 4019
            int bst = bt->getNumberInstances();
82 andreas 4020
 
110 andreas 4021
            for (int i = 0; i < bst; i++)
82 andreas 4022
            {
110 andreas 4023
                color = bt->getTextColor(i);
82 andreas 4024
 
110 andreas 4025
                if (color.empty())
4026
                    continue;
82 andreas 4027
 
110 andreas 4028
                sendCustomEvent(i + 1, color.length(), 0, color, 1013, bt->getChannelPort(), bt->getChannelNumber());
83 andreas 4029
            }
82 andreas 4030
        }
110 andreas 4031
        else
4032
        {
4033
            color = bt->getTextColor(btState - 1);
4034
            sendCustomEvent(btState, color.length(), 0, color, 1013, bt->getChannelPort(), bt->getChannelNumber());
4035
        }
82 andreas 4036
    }
4037
}
4038
 
60 andreas 4039
/**
4040
 * Set the button draw order
4041
 * Determines what order each layer of the button is drawn.
4042
 */
4043
void TPageManager::doBDO(int port, vector<int>& channels, vector<std::string>& pars)
32 andreas 4044
{
60 andreas 4045
    DECL_TRACER("TPageManager::doBDO(int port, vector<int>& channels, vector<std::string>& pars)");
32 andreas 4046
 
60 andreas 4047
    if (pars.size() < 1)
4048
    {
4049
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
32 andreas 4050
        return;
60 andreas 4051
    }
32 andreas 4052
 
60 andreas 4053
    TError::clear();
4054
    int btState = atoi(pars[0].c_str());
4055
    string order;
32 andreas 4056
 
60 andreas 4057
    if (pars.size() > 1)
4058
    {
4059
        string ord = pars[1];
4060
        // Convert the numbers into the expected draw order
4061
        for (size_t i = 0; i < ord.length(); i++)
4062
        {
4063
            if (ord.at(i) >= '1' && ord.at(i) <= '5')
4064
            {
4065
                char hv0[32];
4066
                snprintf(hv0, sizeof(hv0), "%02d", (int)(ord.at(i) - '0'));
4067
                order.append(hv0);
4068
            }
4069
            else
4070
            {
4071
                MSG_ERROR("Illegal order number " << ord.substr(i, 1) << "!");
4072
                return;
4073
            }
4074
        }
4075
 
4076
        if (order.length() != 10)
4077
        {
4078
            MSG_ERROR("Expected 5 order numbers but got " << (order.length() / 2)<< "!");
4079
            return;
4080
        }
4081
    }
4082
 
4083
    vector<MAP_T> map = findButtons(port, channels);
4084
 
4085
    if (TError::isError() || map.empty())
32 andreas 4086
        return;
4087
 
60 andreas 4088
    vector<Button::TButton *> buttons = collectButtons(map);
4089
 
83 andreas 4090
    if (buttons.size() > 0)
32 andreas 4091
    {
83 andreas 4092
        vector<Button::TButton *>::iterator mapIter;
32 andreas 4093
 
83 andreas 4094
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 4095
        {
83 andreas 4096
            Button::TButton *bt = *mapIter;
4097
            setButtonCallbacks(bt);
32 andreas 4098
 
83 andreas 4099
            if (btState == 0)       // All instances?
4100
            {
4101
                int bst = bt->getNumberInstances();
4102
 
4103
                for (int i = 0; i < bst; i++)
4104
                    bt->setDrawOrder(order, i);
4105
            }
4106
            else
4107
                bt->setDrawOrder(order, btState - 1);
60 andreas 4108
        }
4109
    }
4110
}
32 andreas 4111
 
60 andreas 4112
/**
4113
 * Set the feedback type of the button.
4114
 * ONLY works on General-type buttons.
4115
 */
4116
void TPageManager::doBFB(int port, vector<int>& channels, vector<std::string>& pars)
4117
{
4118
    DECL_TRACER("TPageManager::doBFB(int port, vector<int>& channels, vector<std::string>& pars)");
32 andreas 4119
 
60 andreas 4120
    if (pars.size() < 1)
4121
    {
4122
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
4123
        return;
4124
    }
4125
 
4126
    TError::clear();
4127
    Button::FEEDBACK type = Button::FB_NONE;
4128
    string stype = pars[0];
4129
    vector<string> stypes = { "None", "Channel", "Invert", "On", "Momentary", "Blink" };
4130
    vector<string>::iterator iter;
4131
    int i = 0;
4132
 
4133
    for (iter = stypes.begin(); iter != stypes.end(); ++iter)
4134
    {
4135
        if (strCaseCompare(stype, *iter) == 0)
33 andreas 4136
        {
60 andreas 4137
            type = (Button::FEEDBACK)i;
4138
            break;
32 andreas 4139
        }
60 andreas 4140
 
4141
        i++;
32 andreas 4142
    }
4143
 
60 andreas 4144
    vector<MAP_T> map = findButtons(port, channels);
4145
 
4146
    if (TError::isError() || map.empty())
4147
        return;
4148
 
4149
    vector<Button::TButton *> buttons = collectButtons(map);
4150
 
83 andreas 4151
    if (buttons.size() > 0)
60 andreas 4152
    {
83 andreas 4153
        vector<Button::TButton *>::iterator mapIter;
4154
 
4155
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
4156
        {
4157
            Button::TButton *bt = *mapIter;
4158
            setButtonCallbacks(bt);
4159
            bt->setFeedback(type);
4160
        }
60 andreas 4161
    }
32 andreas 4162
}
4163
 
106 andreas 4164
void TPageManager::doBMC(int port, vector<int>& channels, vector<std::string>& pars)
4165
{
4166
    DECL_TRACER("TPageManager::doBMC(int port, vector<int>& channels, vector<std::string>& pars)");
4167
 
4168
    if (pars.size() < 5)
4169
    {
4170
        MSG_ERROR("Expecting 5 parameters but got " << pars.size() << ". Ignoring command.");
4171
        return;
4172
    }
4173
 
4174
    TError::clear();
4175
    int btState = atoi(pars[0].c_str());
4176
    int src_port = atoi(pars[1].c_str());
4177
    int src_addr = atoi(pars[2].c_str());
4178
    int src_state = atoi(pars[3].c_str());
4179
    string src_codes = pars[4];
4180
    vector<int> src_channel;
4181
    src_channel.push_back(src_addr);
4182
 
4183
    vector<MAP_T> src_map = findButtons(src_port, src_channel);
4184
 
4185
    if (src_map.size() == 0)
4186
    {
4187
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " does not exist!");
4188
        return;
4189
    }
4190
 
4191
    vector<Button::TButton *>src_buttons = collectButtons(src_map);
4192
 
4193
    if (src_buttons.size() == 0)
4194
    {
4195
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " does not exist!");
4196
        return;
4197
    }
4198
 
4199
    if (src_buttons[0]->getNumberInstances() < src_state)
4200
    {
4201
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " has less then " << src_state << " elements.");
4202
        return;
4203
    }
4204
 
4205
    if (src_state < 1)
4206
    {
4207
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " has invalid source state " << src_state << ".");
4208
        return;
4209
    }
4210
 
4211
    src_state--;
4212
 
4213
    if (btState > 0)
4214
        btState--;
4215
 
4216
    vector<MAP_T> map = findButtons(port, channels);
4217
    vector<Button::TButton *> buttons = collectButtons(map);
4218
    //                        0     1     2     3     4     5     6     7
4219
    vector<string>codes = { "BM", "BR", "CB", "CF", "CT", "EC", "EF", "FT",
4220
                            "IC", "JB", "JI", "JT", "LN", "OP", "SO", "TX", // 8 - 15
4221
                            "VI", "WW" };   // 16, 17
4222
 
4223
    for (size_t ibuttons = 0; ibuttons < buttons.size(); ibuttons++)
4224
    {
4225
        vector<string>::iterator iter;
4226
        int idx = 0;
4227
 
4228
        for (iter = codes.begin(); iter != codes.end(); ++iter)
4229
        {
4230
            if (src_codes.find(*iter) != string::npos)
4231
            {
4232
                int j, x, y;
4233
 
4234
                switch(idx)
4235
                {
4236
                    case 0: buttons[ibuttons]->setBitmap(src_buttons[0]->getBitmapName(src_state), btState); break;
4237
                    case 1: buttons[ibuttons]->setBorderStyle(src_buttons[0]->getBorderStyle(src_state), btState); break;
4238
                    case 2: buttons[ibuttons]->setBorderColor(src_buttons[0]->getBorderColor(src_state), btState); break;
4239
                    case 3: buttons[ibuttons]->setFillColor(src_buttons[0]->getFillColor(src_state), btState); break;
4240
                    case 4: buttons[ibuttons]->setTextColor(src_buttons[0]->getTextColor(src_state), btState); break;
4241
                    case 5: buttons[ibuttons]->setTextEffectColor(src_buttons[0]->getTextEffectColor(src_state), btState); break;
4242
                    case 6: buttons[ibuttons]->setTextEffect(src_buttons[0]->getTextEffect(src_state), btState); break;
4243
                    case 7: buttons[ibuttons]->setFontIndex(src_buttons[0]->getFontIndex(src_state), btState); break;
110 andreas 4244
                    case 8: buttons[ibuttons]->setIcon(src_buttons[0]->getIconIndex(src_state), btState); break;
106 andreas 4245
 
4246
                    case 9:
4247
                        j = src_buttons[0]->getBitmapJustification(&x, &y, src_state);
4248
                        buttons[ibuttons]->setBitmapJustification(j, x, y, btState);
4249
                    break;
4250
 
4251
                    case 10:
4252
                        j = src_buttons[0]->getIconJustification(&x, &y, src_state);
4253
                        buttons[ibuttons]->setIconJustification(j, x, y, btState);
4254
                    break;
4255
 
4256
                    case 11:
4257
                        j = src_buttons[0]->getTextJustification(&x, &y, src_state);
4258
                        buttons[ibuttons]->setTextJustification(j, x, y, btState);
4259
                    break;
4260
 
4261
                    case 12: MSG_INFO("\"Lines of video removed\" not supported!"); break;
4262
                    case 13: buttons[ibuttons]->setOpacity(src_buttons[0]->getOpacity(src_state), btState); break;
4263
                    case 14: buttons[ibuttons]->setSound(src_buttons[0]->getSound(src_state), btState); break;
4264
                    case 15: buttons[ibuttons]->setText(src_buttons [0]->getText(src_state), btState); break;
4265
                    case 16: MSG_INFO("\"Video slot ID\" not supported!"); break;
4266
                    case 17: buttons[ibuttons]->setTextWordWrap(src_buttons[0]->getTextWordWrap(src_state), btState); break;
4267
                }
4268
            }
4269
 
4270
            idx++;
4271
        }
4272
    }
4273
}
4274
 
14 andreas 4275
/**
110 andreas 4276
 * Set the maximum length of the text area button. If this value is set to
4277
 * zero (0), the text area has no max length. The maximum length available is
4278
 * 2000. This is only for a Text area input button and not for a Text area input
4279
 * masking button.
4280
 */
4281
void TPageManager::doBML(int port, vector<int>& channels, vector<string>& pars)
4282
{
4283
    DECL_TRACER("TPageManager::doBML(int port, vector<int>& channels, vector<string>& pars)");
4284
 
4285
    if (pars.size() < 1)
4286
    {
4287
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
4288
        return;
4289
    }
4290
 
4291
    TError::clear();
4292
    int maxLen = atoi(pars[0].c_str());
4293
 
4294
    if (maxLen < 0 || maxLen > 2000)
4295
    {
4296
        MSG_WARNING("Got illegal length of text area! [" << maxLen << "]");
4297
        return;
4298
    }
4299
 
4300
    vector<MAP_T> map = findButtons(port, channels);
4301
 
4302
    if (TError::isError() || map.empty())
4303
        return;
4304
 
4305
    vector<Button::TButton *> buttons = collectButtons(map);
4306
 
4307
    if (buttons.size() > 0)
4308
    {
4309
        vector<Button::TButton *>::iterator mapIter;
4310
 
4311
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
4312
        {
4313
            Button::TButton *bt = *mapIter;
4314
            bt->setTextMaxChars(maxLen);
4315
        }
4316
    }
4317
}
4318
 
4319
/**
60 andreas 4320
 * Assign a picture to those buttons with a defined address range.
4321
 */
4322
void TPageManager::doBMP(int port, vector<int>& channels, vector<string>& pars)
4323
{
4324
    DECL_TRACER("TPageManager::doBMP(int port, vector<int>& channels, vector<string>& pars)");
4325
 
4326
    if (pars.size() < 2)
4327
    {
4328
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
4329
        return;
4330
    }
4331
 
4332
    TError::clear();
4333
    int btState = atoi(pars[0].c_str());
4334
    string bitmap = pars[1];
104 andreas 4335
    // If this is a G5 command, we may have up to 2 additional parameters.
4336
    int slot = -1, justify = -1, jx = 0, jy = 0;
60 andreas 4337
 
104 andreas 4338
    if (pars.size() > 2)
4339
    {
4340
        slot = atoi(pars[2].c_str());
4341
 
4342
        if (pars.size() >= 4)
4343
        {
4344
            justify = atoi(pars[4].c_str());
4345
 
4346
            if (justify == 0)
4347
            {
4348
                if (pars.size() >= 5)
4349
                    jx = atoi(pars[5].c_str());
4350
 
4351
                if (pars.size() >= 6)
4352
                    jy = atoi(pars[6].c_str());
4353
            }
4354
        }
4355
    }
4356
 
60 andreas 4357
    vector<MAP_T> map = findButtons(port, channels);
4358
 
4359
    if (TError::isError() || map.empty())
4360
        return;
4361
 
4362
    vector<Button::TButton *> buttons = collectButtons(map);
4363
 
83 andreas 4364
    if (buttons.size() > 0)
60 andreas 4365
    {
83 andreas 4366
        vector<Button::TButton *>::iterator mapIter;
60 andreas 4367
 
83 andreas 4368
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 4369
        {
83 andreas 4370
            Button::TButton *bt = *mapIter;
4371
            setButtonCallbacks(bt);
60 andreas 4372
 
83 andreas 4373
            if (btState == 0)       // All instances?
4374
            {
4375
                int bst = bt->getNumberInstances();
96 andreas 4376
                MSG_DEBUG("Setting bitmap " << bitmap << " on all " << bst << " instances...");
83 andreas 4377
 
4378
                for (int i = 0; i < bst; i++)
104 andreas 4379
                {
4380
                    if (justify >= 0)
4381
                    {
4382
                        if (slot == 2)
4383
                            bt->setIconJustification(justify, jx, jy, i);
4384
                        else
106 andreas 4385
                            bt->setBitmapJustification(justify, jx, jy, i);
104 andreas 4386
                    }
4387
 
4388
                    if (slot >= 0)
4389
                    {
4390
                        switch(slot)
4391
                        {
4392
                            case 0: bt->setCameleon(bitmap, i); break;
4393
                            case 2: bt->setIcon(bitmap, i); break;  // On G4 we have no bitmap layer. Therefor we use layer 2 as icon layer.
4394
                            default:
4395
                                bt->setBitmap(bitmap, i);
4396
                        }
4397
                    }
4398
                    else
4399
                        bt->setBitmap(bitmap, i);
4400
                }
83 andreas 4401
            }
4402
            else
104 andreas 4403
            {
4404
                if (justify >= 0)
4405
                {
4406
                    if (slot == 2)
4407
                        bt->setIconJustification(justify, jx, jy, btState);
4408
                    else
106 andreas 4409
                        bt->setBitmapJustification(justify, jx, jy, btState);
104 andreas 4410
                }
4411
 
4412
                if (slot >= 0)
4413
                {
4414
                    switch(slot)
4415
                    {
4416
                        case 0: bt->setCameleon(bitmap, btState); break;
4417
                        case 2: bt->setIcon(bitmap, btState); break;      // On G4 we have no bitmap layer. Therefor we use layer 2 as icon layer.
4418
                        default:
4419
                            bt->setBitmap(bitmap, btState);
4420
                    }
4421
                }
4422
                else
4423
                    bt->setBitmap(bitmap, btState);
4424
            }
60 andreas 4425
        }
4426
    }
4427
}
4428
 
82 andreas 4429
void TPageManager::getBMP(int port, vector<int> &channels, vector<string> &pars)
4430
{
4431
    DECL_TRACER("TPageManager::getBMP(int port, vector<int> &channels, vector<string> &pars)");
4432
 
4433
    if (pars.size() < 1)
4434
    {
4435
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
4436
        return;
4437
    }
4438
 
4439
    TError::clear();
4440
    int btState = atoi(pars[0].c_str());
4441
    string bmp;
4442
 
4443
    vector<MAP_T> map = findButtons(port, channels);
4444
 
4445
    if (TError::isError() || map.empty())
4446
        return;
4447
 
4448
    vector<Button::TButton *> buttons = collectButtons(map);
4449
 
83 andreas 4450
    if (buttons.size() > 0)
82 andreas 4451
    {
110 andreas 4452
        Button::TButton *bt = buttons[0];
82 andreas 4453
 
110 andreas 4454
        if (btState == 0)       // All instances?
82 andreas 4455
        {
110 andreas 4456
            int bst = bt->getNumberInstances();
82 andreas 4457
 
110 andreas 4458
            for (int i = 0; i < bst; i++)
82 andreas 4459
            {
110 andreas 4460
                bmp = bt->getBitmapName(i);
82 andreas 4461
 
110 andreas 4462
                if (bmp.empty())
4463
                    continue;
82 andreas 4464
 
110 andreas 4465
                sendCustomEvent(i + 1, bmp.length(), 0, bmp, 1002, bt->getChannelPort(), bt->getChannelNumber());
83 andreas 4466
            }
82 andreas 4467
        }
110 andreas 4468
        else
4469
        {
4470
            bmp = bt->getTextColor(btState-1);
4471
            sendCustomEvent(btState, bmp.length(), 0, bmp, 1002, bt->getChannelPort(), bt->getChannelNumber());
4472
        }
82 andreas 4473
    }
4474
}
4475
 
60 andreas 4476
/**
16 andreas 4477
 * Set the button opacity. The button opacity can be specified as a decimal
4478
 * between 0 - 255, where zero (0) is invisible and 255 is opaque, or as a
4479
 * HEX code, as used in the color commands by preceding the HEX code with
4480
 * the # sign. In this case, #00 becomes invisible and #FF becomes opaque.
4481
 * If the opacity is set to zero (0), this does not make the button inactive,
4482
 * only invisible.
4483
 */
4484
void TPageManager::doBOP(int port, vector<int>& channels, vector<string>& pars)
4485
{
4486
    DECL_TRACER("TPageManager::doBOP(int port, vector<int>& channels, vector<string>& pars)");
4487
 
4488
    if (pars.size() < 2)
4489
    {
4490
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
4491
        return;
4492
    }
4493
 
4494
    TError::clear();
4495
    int btState = atoi(pars[0].c_str());
4496
    int btOpacity = 0;
4497
 
4498
    if (pars[1].at(0) == '#')
4499
        btOpacity = (int)strtol(pars[1].substr(1).c_str(), NULL, 16);
4500
    else
4501
        btOpacity = atoi(pars[1].c_str());
4502
 
4503
    vector<MAP_T> map = findButtons(port, channels);
4504
 
4505
    if (TError::isError() || map.empty())
4506
        return;
4507
 
4508
    vector<Button::TButton *> buttons = collectButtons(map);
4509
 
83 andreas 4510
    if (buttons.size() > 0)
16 andreas 4511
    {
83 andreas 4512
        vector<Button::TButton *>::iterator mapIter;
16 andreas 4513
 
83 andreas 4514
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
16 andreas 4515
        {
83 andreas 4516
            Button::TButton *bt = *mapIter;
4517
            setButtonCallbacks(bt);
16 andreas 4518
 
83 andreas 4519
            if (btState == 0)       // All instances?
4520
            {
4521
                int bst = bt->getNumberInstances();
4522
                MSG_DEBUG("Setting opacity " << btOpacity << " on all " << bst << " instances...");
4523
 
4524
                for (int i = 0; i < bst; i++)
4525
                    bt->setOpacity(btOpacity, i);
4526
            }
4527
            else
4528
                bt->setOpacity(btOpacity, btState);
16 andreas 4529
        }
4530
    }
4531
}
4532
 
106 andreas 4533
void TPageManager::getBOP(int port, vector<int>& channels, vector<string>& pars)
4534
{
4535
    DECL_TRACER("TPageManager::getBOP(int port, vector<int>& channels, vector<string>& pars)");
4536
 
4537
    if (pars.size() < 1)
4538
    {
4539
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
4540
        return;
4541
    }
4542
 
4543
    TError::clear();
4544
    int btState = atoi(pars[0].c_str());
4545
 
4546
    vector<MAP_T> map = findButtons(port, channels);
4547
 
4548
    if (TError::isError() || map.empty())
4549
        return;
4550
 
4551
    vector<Button::TButton *> buttons = collectButtons(map);
4552
 
4553
    if (buttons.size() > 0)
4554
    {
110 andreas 4555
        Button::TButton *bt = buttons[0];
106 andreas 4556
 
110 andreas 4557
        if (btState == 0)       // All instances?
106 andreas 4558
        {
110 andreas 4559
            int bst = bt->getNumberInstances();
106 andreas 4560
 
110 andreas 4561
            for (int i = 0; i < bst; i++)
106 andreas 4562
            {
110 andreas 4563
                int oo = bt->getOpacity(i);
4564
                sendCustomEvent(i + 1, oo, 0, "", 1015, bt->getChannelPort(), bt->getChannelNumber());
106 andreas 4565
            }
4566
        }
110 andreas 4567
        else
4568
        {
4569
            int oo = bt->getOpacity(btState-1);
4570
            sendCustomEvent(btState, oo, 0, "", 1015, bt->getChannelPort(), bt->getChannelNumber());
4571
        }
106 andreas 4572
    }
4573
}
4574
 
60 andreas 4575
void TPageManager::doBOR(int port, vector<int>& channels, vector<string>& pars)
4576
{
4577
    DECL_TRACER("TPageManager::doBOR(int port, vector<int>& channels, vector<string>& pars)");
4578
 
4579
    if (pars.size() < 1)
4580
    {
4581
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
4582
        return;
4583
    }
4584
 
4585
    TError::clear();
4586
    // Numbers of styles from 0 to 41
4587
    vector<string> styles = { "No border", "No border", "Single line", "Double line", "Quad line",
4588
                              "Circle 15", "Circle 25", "Single line", "Double line",
4589
                              "Quad line", "Picture frame", "Picture frame", "Double line",
4590
                              "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A",
4591
                              "Bevel-S", "Bevel-M", "Circle 15", "Circle 25", "Neon inactive-S",
4592
                              "Neon inactive-M", "Neon inactive-L", "Neon inactive-L",
4593
                              "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A",
4594
                              "Diamond 55", "Diamond 56" };
4595
    string bor = pars[0];
4596
    string border = "None";
4597
    int ibor = -1;
4598
 
4599
    if (bor.at(0) >= '0' && bor.at(0) <= '9')
4600
        ibor = atoi(bor.c_str());
4601
    else
4602
    {
4603
        vector<string>::iterator iter;
4604
        int i = 0;
4605
 
4606
        for (iter = styles.begin(); iter != styles.end(); ++iter)
4607
        {
4608
            if (strCaseCompare(*iter, bor) == 0)
4609
            {
4610
                ibor = i;
4611
                break;
4612
            }
4613
 
4614
            i++;
4615
        }
4616
    }
4617
 
4618
    if (ibor < 0 || ibor > 41)
4619
    {
4620
        MSG_ERROR("Invalid border type " << bor << "!");
4621
        return;
4622
    }
4623
 
4624
    switch (ibor)
4625
    {
4626
        case 20: border = "Bevel Raised -S"; break;
4627
        case 21: border = "Bevel Raised -M"; break;
4628
        case 24: border = "AMX Elite Raised -S"; break;
4629
        case 25: border = "AMX Elite Inset -S"; break;
4630
        case 26: border = "AMX Elite Raised -M"; break;
4631
        case 27: border = "AMX Elite Inset -M"; break;
4632
        case 28: border = "AMX Elite Raised -L"; break;
4633
        case 29: border = "AMX Elite Inset -L"; break;
4634
        case 30: border = "Circle 35"; break;
4635
        case 31: border = "Circle 45"; break;
4636
        case 32: border = "Circle 55"; break;
4637
        case 33: border = "Circle 65"; break;
4638
        case 34: border = "Circle 75"; break;
4639
        case 35: border = "Circle 85"; break;
4640
        case 36: border = "Circle 95"; break;
4641
        case 37: border = "Circle 105"; break;
4642
        case 38: border = "Circle 115"; break;
4643
        case 39: border = "Circle 125"; break;
4644
        default:
4645
            border = styles[ibor];
4646
    }
4647
 
4648
    vector<MAP_T> map = findButtons(port, channels);
4649
 
4650
    if (TError::isError() || map.empty())
4651
        return;
4652
 
4653
    vector<Button::TButton *> buttons = collectButtons(map);
4654
 
83 andreas 4655
    if (buttons.size() > 0)
60 andreas 4656
    {
83 andreas 4657
        vector<Button::TButton *>::iterator mapIter;
4658
 
4659
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
4660
        {
4661
            Button::TButton *bt = *mapIter;
4662
            setButtonCallbacks(bt);
4663
            bt->setBorderStyle(border);
4664
        }
60 andreas 4665
    }
4666
}
4667
 
107 andreas 4668
void TPageManager::doBOS(int port, vector<int>& channels, vector<string>& pars)
4669
{
4670
    DECL_TRACER("TPageManager::doBOS(int port, vector<int>& channels, vector<string>& pars)");
4671
 
4672
    if (pars.size() < 2)
4673
    {
4674
        MSG_ERROR("Expecting at least 2 parameters but got " << pars.size() << "! Ignoring command.");
4675
        return;
4676
    }
4677
 
4678
    TError::clear();
4679
    int btState = atoi(pars[0].c_str());
4680
    int videoState = atoi(pars[1].c_str());
4681
 
4682
    vector<MAP_T> map = findButtons(port, channels);
4683
 
4684
    if (TError::isError() || map.empty())
4685
        return;
4686
 
4687
    vector<Button::TButton *> buttons = collectButtons(map);
4688
 
4689
    if (buttons.size() > 0)
4690
    {
4691
        vector<Button::TButton *>::iterator mapIter;
4692
 
4693
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
4694
        {
4695
            Button::TButton *bt = *mapIter;
4696
 
4697
            if (btState == 0)       // All instances?
4698
                bt->setDynamic(videoState);
4699
            else
4700
                bt->setDynamic(videoState, btState-1);
4701
        }
4702
    }
4703
}
4704
 
16 andreas 4705
/**
60 andreas 4706
 * Set the border of a button state/states.
4707
 * The border names are available through the TPDesign4 border-name drop-down
4708
 * list.
4709
 */
4710
void TPageManager::doBRD(int port, vector<int>& channels, vector<string>& pars)
4711
{
4712
    DECL_TRACER("TPageManager::doBRD(int port, vector<int>& channels, vector<string>& pars)");
4713
 
4714
    if (pars.size() < 1)
4715
    {
4716
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
4717
        return;
4718
    }
4719
 
4720
    TError::clear();
4721
    int btState = atoi(pars[0].c_str());
4722
    string border = "None";
4723
 
4724
    if (pars.size() > 1)
4725
        border = pars[1];
4726
 
4727
    vector<MAP_T> map = findButtons(port, channels);
4728
 
4729
    if (TError::isError() || map.empty())
4730
        return;
4731
 
4732
    vector<Button::TButton *> buttons = collectButtons(map);
4733
 
83 andreas 4734
    if (buttons.size() > 0)
60 andreas 4735
    {
83 andreas 4736
        vector<Button::TButton *>::iterator mapIter;
60 andreas 4737
 
83 andreas 4738
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 4739
        {
83 andreas 4740
            Button::TButton *bt = *mapIter;
4741
            setButtonCallbacks(bt);
60 andreas 4742
 
83 andreas 4743
            if (btState == 0)       // All instances?
4744
            {
4745
                int bst = bt->getNumberInstances();
4746
 
4747
                for (int i = 0; i < bst; i++)
106 andreas 4748
                    bt->setBorderStyle(border, i+1);
83 andreas 4749
            }
4750
            else
106 andreas 4751
                bt->setBorderStyle(border, btState);
60 andreas 4752
        }
4753
    }
4754
}
4755
 
107 andreas 4756
void TPageManager::getBRD(int port, vector<int>& channels, vector<string>& pars)
4757
{
4758
    DECL_TRACER("TPageManager::getBRD(int port, vector<int>& channels, vector<string>& pars)");
4759
 
4760
    if (pars.size() < 1)
4761
    {
4762
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
4763
        return;
4764
    }
4765
 
4766
    TError::clear();
4767
    int btState = atoi(pars[0].c_str());
4768
 
4769
    vector<MAP_T> map = findButtons(port, channels);
4770
 
4771
    if (TError::isError() || map.empty())
4772
        return;
4773
 
4774
    vector<Button::TButton *> buttons = collectButtons(map);
4775
 
4776
    if (buttons.size() > 0)
4777
    {
110 andreas 4778
        Button::TButton *bt = buttons[0];
107 andreas 4779
 
110 andreas 4780
        if (btState == 0)       // All instances?
107 andreas 4781
        {
110 andreas 4782
            int bst = bt->getNumberInstances();
107 andreas 4783
 
110 andreas 4784
            for (int i = 0; i < bst; i++)
107 andreas 4785
            {
110 andreas 4786
                string bname = bt->getBorderStyle(i);
4787
                sendCustomEvent(i + 1, bname.length(), 0, bname, 1014, bt->getChannelPort(), bt->getChannelNumber());
107 andreas 4788
            }
4789
        }
110 andreas 4790
        else
4791
        {
4792
            string bname = bt->getBorderStyle(btState-1);
4793
            sendCustomEvent(btState, bname.length(), 0, bname, 1014, bt->getChannelPort(), bt->getChannelNumber());
4794
        }
107 andreas 4795
    }
4796
}
4797
 
60 andreas 4798
/**
16 andreas 4799
 * Set the button size and its position on the page.
4800
 */
4801
void TPageManager::doBSP(int port, vector<int>& channels, vector<string>& pars)
4802
{
4803
    DECL_TRACER("TPageManager::doBSP(int port, vector<int>& channels, vector<string>& pars)");
4804
 
4805
    if (pars.size() < 1)
4806
    {
4807
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
4808
        return;
4809
    }
4810
 
4811
    TError::clear();
4812
    bool bLeft = false, bTop = false, bRight = false, bBottom = false;
4813
    int x, y;
4814
 
83 andreas 4815
    if (pars.size() > 0)
16 andreas 4816
    {
83 andreas 4817
        vector<string>::iterator iter;
4818
 
4819
        for (iter = pars.begin(); iter != pars.end(); iter++)
4820
        {
4821
            if (iter->compare("left") == 0)
4822
                bLeft = true;
4823
            else if (iter->compare("top") == 0)
4824
                bTop = true;
4825
            else if (iter->compare("right") == 0)
4826
                bRight = true;
4827
            else if (iter->compare("bottom") == 0)
4828
                bBottom = true;
4829
        }
16 andreas 4830
    }
4831
 
4832
    vector<MAP_T> map = findButtons(port, channels);
4833
 
4834
    if (TError::isError() || map.empty())
4835
        return;
4836
 
4837
    vector<Button::TButton *> buttons = collectButtons(map);
4838
 
83 andreas 4839
    if (buttons.size() > 0)
16 andreas 4840
    {
83 andreas 4841
        vector<Button::TButton *>::iterator mapIter;
16 andreas 4842
 
83 andreas 4843
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
4844
        {
4845
            Button::TButton *bt = *mapIter;
4846
            setButtonCallbacks(bt);
16 andreas 4847
 
83 andreas 4848
            if (bLeft)
4849
                x = 0;
16 andreas 4850
 
83 andreas 4851
            if (bTop)
4852
                y = 0;
16 andreas 4853
 
83 andreas 4854
            if (bRight)
16 andreas 4855
            {
83 andreas 4856
                ulong handle = bt->getHandle();
4857
                int parentID = (handle >> 16) & 0x0000ffff;
4858
                int pwidth = 0;
16 andreas 4859
 
83 andreas 4860
                if (parentID < 500)
16 andreas 4861
                {
83 andreas 4862
                    TPage *pg = getPage(parentID);
4863
 
4864
                    if (!pg)
4865
                    {
4866
                        MSG_ERROR("Internal error: Page " << parentID << " not found!");
4867
                        return;
4868
                    }
4869
 
4870
                    pwidth = pg->getWidth();
16 andreas 4871
                }
83 andreas 4872
                else
4873
                {
4874
                    TSubPage *spg = getSubPage(parentID);
16 andreas 4875
 
83 andreas 4876
                    if (!spg)
4877
                    {
4878
                        MSG_ERROR("Internal error: Subpage " << parentID << " not found!");
4879
                        return;
4880
                    }
16 andreas 4881
 
83 andreas 4882
                    pwidth = spg->getWidth();
16 andreas 4883
                }
4884
 
83 andreas 4885
                x = pwidth - bt->getWidth();
16 andreas 4886
            }
4887
 
83 andreas 4888
            if (bBottom)
4889
            {
4890
                ulong handle = bt->getHandle();
4891
                int parentID = (handle >> 16) & 0x0000ffff;
4892
                int pheight = 0;
16 andreas 4893
 
83 andreas 4894
                if (parentID < 500)
4895
                {
4896
                    TPage *pg = getPage(parentID);
16 andreas 4897
 
83 andreas 4898
                    if (!pg)
4899
                    {
4900
                        MSG_ERROR("Internal error: Page " << parentID << " not found!");
4901
                        return;
4902
                    }
16 andreas 4903
 
83 andreas 4904
                    pheight = pg->getHeight();
4905
                }
4906
                else
16 andreas 4907
                {
83 andreas 4908
                    TSubPage *spg = getSubPage(parentID);
16 andreas 4909
 
83 andreas 4910
                    if (!spg)
4911
                    {
4912
                        MSG_ERROR("Internal error: Subpage " << parentID << " not found!");
4913
                        return;
4914
                    }
16 andreas 4915
 
83 andreas 4916
                    pheight = spg->getHeight();
16 andreas 4917
                }
4918
 
83 andreas 4919
                y = pheight - bt->getHeight();
16 andreas 4920
            }
4921
 
83 andreas 4922
            bt->setLeftTop(x, y);
16 andreas 4923
        }
4924
    }
4925
}
4926
 
4927
/**
107 andreas 4928
 * Submit text for text area buttons. This command causes the text areas to
4929
 * send their text as strings to the NetLinx Master.
4930
 */
4931
void TPageManager::doBSM(int port, vector<int>& channels, vector<string>&)
4932
{
4933
    DECL_TRACER("TPageManager::doBSM(int port, vector<int>& channels, vector<string>& pars)");
4934
 
4935
    TError::clear();
4936
    vector<MAP_T> map = findButtons(port, channels);
4937
 
4938
    if (TError::isError() || map.empty())
4939
        return;
4940
 
4941
    vector<Button::TButton *> buttons = collectButtons(map);
4942
 
4943
    if (buttons.size() > 0)
4944
    {
4945
        vector<Button::TButton *>::iterator mapIter;
4946
 
4947
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
4948
        {
4949
            Button::TButton *bt = *mapIter;
4950
 
4951
            if (bt->getButtonType() != Button::TEXT_INPUT && bt->getButtonType() != Button::GENERAL)
4952
                return;
4953
 
4954
            amx::ANET_SEND scmd;
4955
            scmd.port = bt->getChannelPort();
4956
            scmd.channel = bt->getChannelNumber();
4957
            scmd.ID = scmd.channel;
4958
            scmd.msg = bt->getText(0);
4959
            scmd.MC = 0x008b;       // string value
4960
 
4961
            if (gAmxNet)
4962
                gAmxNet->sendCommand(scmd);
4963
            else
4964
                MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4965
 
4966
        }
4967
    }
4968
}
4969
 
4970
/**
4971
 * Set the sound played when a button is pressed. If the sound name is blank
4972
 * the sound is then cleared. If the sound name is not matched, the button
4973
 * sound is not changed.
4974
 */
4975
void TPageManager::doBSO(int port, vector<int>& channels, vector<string>& pars)
4976
{
4977
    DECL_TRACER("TPageManager::doBSO(int port, vector<int>& channels, vector<string>& pars)");
4978
 
4979
    if (pars.size() < 2)
4980
    {
4981
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
4982
        return;
4983
    }
4984
 
4985
    if (!gPrjResources)
4986
        return;
4987
 
4988
    TError::clear();
4989
    int btState = atoi(pars[0].c_str());
4990
    string sound = pars[1];
4991
 
4992
    if (!soundExist(sound))
4993
        return;
4994
 
4995
    vector<MAP_T> map = findButtons(port, channels);
4996
 
4997
    if (TError::isError() || map.empty())
4998
        return;
4999
 
5000
    vector<Button::TButton *> buttons = collectButtons(map);
5001
 
5002
    if (buttons.size() > 0)
5003
    {
5004
        vector<Button::TButton *>::iterator mapIter;
5005
 
5006
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
5007
        {
5008
            Button::TButton *bt = *mapIter;
5009
 
5010
            if (btState == 0)
5011
            {
5012
                int bst = bt->getNumberInstances();
5013
 
5014
                for (int i = 0; i < bst; i++)
5015
                    bt->setSound(sound, i);
5016
            }
5017
            else
5018
                bt->setSound(sound, btState-1);
5019
        }
5020
    }
5021
}
5022
 
5023
/**
16 andreas 5024
 * Set the button word wrap feature to those buttons with a defined address
5025
 * range. By default, word-wrap is Off.
5026
 */
5027
void TPageManager::doBWW(int port, vector<int>& channels, vector<string>& pars)
5028
{
5029
    DECL_TRACER("TPageManager::doBWW(int port, vector<int>& channels, vector<string>& pars)");
5030
 
5031
    if (pars.size() < 1)
5032
    {
5033
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
5034
        return;
5035
    }
5036
 
5037
    TError::clear();
5038
    int btState = atoi(pars[0].c_str());
5039
 
5040
    vector<MAP_T> map = findButtons(port, channels);
5041
 
5042
    if (TError::isError() || map.empty())
5043
        return;
5044
 
5045
    vector<Button::TButton *> buttons = collectButtons(map);
5046
 
83 andreas 5047
    if (buttons.size() > 0)
16 andreas 5048
    {
83 andreas 5049
        vector<Button::TButton *>::iterator mapIter;
16 andreas 5050
 
83 andreas 5051
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
16 andreas 5052
        {
83 andreas 5053
            Button::TButton *bt = *mapIter;
5054
            setButtonCallbacks(bt);
16 andreas 5055
 
83 andreas 5056
            if (btState == 0)       // All instances?
5057
            {
5058
                int bst = bt->getNumberInstances();
5059
                MSG_DEBUG("Setting word wrap on all " << bst << " instances...");
5060
 
5061
                for (int i = 0; i < bst; i++)
110 andreas 5062
                    bt->setTextWordWrap(true, i);
83 andreas 5063
            }
5064
            else
110 andreas 5065
                bt->setTextWordWrap(true, btState - 1);
16 andreas 5066
        }
5067
    }
5068
}
5069
 
108 andreas 5070
void TPageManager::getBWW(int port, vector<int>& channels, vector<string>& pars)
5071
{
5072
    DECL_TRACER("TPageManager::getBWW(int port, vector<int>& channels, vector<string>& pars)");
5073
 
5074
    if (pars.size() < 1)
5075
    {
5076
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
5077
        return;
5078
    }
5079
 
5080
    TError::clear();
5081
    int btState = atoi(pars[0].c_str());
5082
 
5083
    vector<MAP_T> map = findButtons(port, channels);
5084
 
5085
    if (TError::isError() || map.empty())
5086
        return;
5087
 
5088
    vector<Button::TButton *> buttons = collectButtons(map);
5089
 
5090
    if (buttons.size() > 0)
5091
    {
110 andreas 5092
        Button::TButton *bt = buttons[0];
108 andreas 5093
 
110 andreas 5094
        if (btState == 0)       // All instances?
108 andreas 5095
        {
110 andreas 5096
            int bst = bt->getNumberInstances();
108 andreas 5097
 
110 andreas 5098
            for (int i = 0; i < bst; i++)
5099
                sendCustomEvent(i + 1, bt->getTextWordWrap(i), 0, "", 1010, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 5100
        }
110 andreas 5101
        else
5102
            sendCustomEvent(btState, bt->getTextWordWrap(btState-1), 0, "", 1010, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 5103
    }
5104
}
5105
 
16 andreas 5106
/**
5107
 * Clear all page flips from a button.
5108
 */
22 andreas 5109
void TPageManager::doCPF(int port, vector<int>& channels, vector<string>&)
16 andreas 5110
{
5111
    DECL_TRACER("TPageManager::doCPF(int port, vector<int>& channels, vector<string>& pars)");
5112
 
5113
    TError::clear();
5114
    vector<MAP_T> map = findButtons(port, channels);
5115
 
5116
    if (TError::isError() || map.empty())
5117
        return;
5118
 
5119
    vector<Button::TButton *> buttons = collectButtons(map);
5120
 
83 andreas 5121
    if (buttons.size() > 0)
16 andreas 5122
    {
83 andreas 5123
        vector<Button::TButton *>::iterator mapIter;
5124
 
5125
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
5126
        {
5127
            Button::TButton *bt = *mapIter;
5128
            setButtonCallbacks(bt);
5129
            bt->clearPushFunctions();
5130
        }
16 andreas 5131
    }
5132
}
5133
 
5134
/**
5135
 * Delete page flips from button if it already exists.
5136
 */
5137
void TPageManager::doDPF(int port, vector<int>& channels, vector<string>& pars)
5138
{
5139
    DECL_TRACER("TPageManager::doDPF(int port, vector<int>& channels, vector<string>& pars)");
5140
 
5141
    if (pars.size() < 1)
5142
    {
5143
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
5144
        return;
5145
    }
5146
 
5147
    TError::clear();
5148
    string action = pars[0];
5149
    string pname;
5150
 
5151
    if (pars.size() >= 2)
5152
    {
5153
        pname = pars[1];
5154
        vector<Button::TButton *> list;
5155
        // First we search for a subpage because this is more likely
5156
        TSubPage *spg = getSubPage(pname);
5157
 
5158
        if (spg)
5159
            list = spg->getButtons(port, channels[0]);
5160
        else    // Then for a page
5161
        {
5162
            TPage *pg = getPage(pname);
5163
 
5164
            if (pg)
5165
                list = pg->getButtons(port, channels[0]);
5166
            else
5167
            {
5168
                MSG_WARNING("The name " << pname << " doesn't name either a page or a subpage!");
5169
                return;
5170
            }
5171
        }
5172
 
5173
        if (list.empty())
5174
            return;
5175
 
5176
        vector<Button::TButton *>::iterator it;
5177
 
5178
        for (it = list.begin(); it != list.end(); it++)
5179
        {
5180
            Button::TButton *bt = *it;
18 andreas 5181
            setButtonCallbacks(bt);
16 andreas 5182
            bt->clearPushFunction(action);
5183
        }
5184
 
5185
        return;
5186
    }
5187
 
5188
    // Here we don't have a page name
5189
    vector<MAP_T> map = findButtons(port, channels);
5190
 
5191
    if (TError::isError() || map.empty())
5192
        return;
5193
 
5194
    vector<Button::TButton *> buttons = collectButtons(map);
5195
 
83 andreas 5196
    if (buttons.size() > 0)
16 andreas 5197
    {
83 andreas 5198
        vector<Button::TButton *>::iterator mapIter;
5199
 
5200
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
5201
        {
5202
            Button::TButton *bt = *mapIter;
5203
            setButtonCallbacks(bt);
5204
            bt->clearPushFunction(action);
5205
        }
16 andreas 5206
    }
5207
}
5208
 
5209
/**
5210
 * Enable or disable buttons with a set variable text range.
5211
 */
5212
void TPageManager::doENA(int port, vector<int>& channels, vector<string>& pars)
5213
{
5214
    DECL_TRACER("TPageManager::doENA(int port, vector<int>& channels, vector<string>& pars)");
5215
 
5216
    if (pars.empty())
5217
    {
5218
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
5219
        return;
5220
    }
5221
 
5222
    TError::clear();
5223
    int cvalue = atoi(pars[0].c_str());
5224
 
5225
    vector<MAP_T> map = findButtons(port, channels);
5226
 
5227
    if (TError::isError() || map.empty())
5228
        return;
5229
 
5230
    vector<Button::TButton *> buttons = collectButtons(map);
5231
 
83 andreas 5232
    if (buttons.size() > 0)
16 andreas 5233
    {
83 andreas 5234
        vector<Button::TButton *>::iterator mapIter;
5235
 
5236
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
5237
        {
5238
            Button::TButton *bt = *mapIter;
5239
            setButtonCallbacks(bt);
5240
            bt->setEnable(((cvalue)?true:false));
5241
        }
16 andreas 5242
    }
5243
}
5244
 
5245
/**
5246
 * Set a font to a specific Font ID value for those buttons with a defined
5247
 * address range. Font ID numbers are generated by the TPDesign4 programmers
5248
 * report.
5249
 */
5250
void TPageManager::doFON(int port, vector<int>& channels, vector<string>& pars)
5251
{
5252
    DECL_TRACER("TPageManager::doFON(int port, vector<int>& channels, vector<string>& pars)");
5253
 
5254
    if (pars.size() < 2)
5255
    {
5256
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
5257
        return;
5258
    }
5259
 
5260
    TError::clear();
5261
    int btState = atoi(pars[0].c_str());
5262
    int fvalue = atoi(pars[1].c_str());
5263
 
5264
    vector<MAP_T> map = findButtons(port, channels);
5265
 
5266
    if (TError::isError() || map.empty())
5267
        return;
5268
 
5269
    vector<Button::TButton *> buttons = collectButtons(map);
5270
 
83 andreas 5271
    if (buttons.size() > 0)
16 andreas 5272
    {
83 andreas 5273
        vector<Button::TButton *>::iterator mapIter;
16 andreas 5274
 
83 andreas 5275
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
16 andreas 5276
        {
83 andreas 5277
            Button::TButton *bt = *mapIter;
5278
            setButtonCallbacks(bt);
16 andreas 5279
 
83 andreas 5280
            if (btState == 0)       // All instances?
5281
            {
5282
                int bst = bt->getNumberInstances();
5283
                MSG_DEBUG("Setting font " << fvalue << " on all " << bst << " instances...");
5284
 
5285
                for (int i = 0; i < bst; i++)
5286
                    bt->setFont(fvalue, i);
5287
            }
5288
            else
5289
                bt->setFont(fvalue, btState - 1);
16 andreas 5290
        }
5291
    }
5292
}
5293
 
108 andreas 5294
void TPageManager::getFON(int port, vector<int>& channels, vector<string>& pars)
5295
{
5296
    DECL_TRACER("TPageManager::getFON(int port, vector<int>& channels, vector<string>& pars)");
5297
 
5298
    if (pars.size() < 1)
5299
    {
5300
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
5301
        return;
5302
    }
5303
 
5304
    TError::clear();
5305
    int btState = atoi(pars[0].c_str());
5306
 
5307
    vector<MAP_T> map = findButtons(port, channels);
5308
 
5309
    if (TError::isError() || map.empty())
5310
        return;
5311
 
5312
    vector<Button::TButton *> buttons = collectButtons(map);
5313
 
5314
    if (buttons.size() > 0)
5315
    {
110 andreas 5316
        Button::TButton *bt = buttons[0];
108 andreas 5317
 
110 andreas 5318
        if (btState == 0)       // All instances?
108 andreas 5319
        {
110 andreas 5320
            int bst = bt->getNumberInstances();
108 andreas 5321
 
110 andreas 5322
            for (int i = 0; i < bst; i++)
5323
                sendCustomEvent(i + 1, bt->getFontIndex(i), 0, "", 1007, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 5324
        }
110 andreas 5325
        else
5326
            sendCustomEvent(btState, bt->getFontIndex(btState - 1), 0, "", 1007, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 5327
    }
5328
}
5329
 
16 andreas 5330
/**
60 andreas 5331
 * Change the bargraph upper limit.
5332
 */
5333
void TPageManager::doGLH(int port, vector<int>& channels, vector<std::string>& pars)
5334
{
5335
    DECL_TRACER("TPageManager::doGLH(int port, vector<int>& channels, vector<std::string>& pars)");
5336
 
5337
    if (pars.size() < 1)
5338
    {
5339
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
5340
        return;
5341
    }
5342
 
5343
    TError::clear();
5344
    int limit = atoi(pars[0].c_str());
5345
 
5346
    if (limit < 1)
5347
    {
5348
        MSG_ERROR("Invalid upper limit " << limit << "!");
5349
        return;
5350
    }
5351
 
5352
    vector<MAP_T> map = findButtons(port, channels);
5353
 
5354
    if (TError::isError() || map.empty())
5355
        return;
5356
 
5357
    vector<Button::TButton *> buttons = collectButtons(map);
5358
 
83 andreas 5359
    if (buttons.size() > 0)
60 andreas 5360
    {
83 andreas 5361
        vector<Button::TButton *>::iterator mapIter;
5362
 
5363
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
5364
        {
5365
            Button::TButton *bt = *mapIter;
5366
            setButtonCallbacks(bt);
5367
            bt->setBargraphUpperLimit(limit);
5368
        }
60 andreas 5369
    }
5370
}
5371
 
5372
/**
5373
 * Change the bargraph lower limit.
5374
 */
5375
void TPageManager::doGLL(int port, vector<int>& channels, vector<std::string>& pars)
5376
{
5377
    DECL_TRACER("TPageManager::doGLL(int port, vector<int>& channels, vector<std::string>& pars)");
5378
 
5379
    if (pars.size() < 1)
5380
    {
5381
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
5382
        return;
5383
    }
5384
 
5385
    TError::clear();
5386
    int limit = atoi(pars[0].c_str());
5387
 
5388
    if (limit < 1)
5389
    {
5390
        MSG_ERROR("Invalid lower limit " << limit << "!");
5391
        return;
5392
    }
5393
 
5394
    vector<MAP_T> map = findButtons(port, channels);
5395
 
5396
    if (TError::isError() || map.empty())
5397
        return;
5398
 
5399
    vector<Button::TButton *> buttons = collectButtons(map);
5400
 
83 andreas 5401
    if (buttons.size() > 0)
60 andreas 5402
    {
83 andreas 5403
        vector<Button::TButton *>::iterator mapIter;
5404
 
5405
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
5406
        {
5407
            Button::TButton *bt = *mapIter;
5408
            setButtonCallbacks(bt);
5409
            bt->setBargraphLowerLimit(limit);
5410
        }
60 andreas 5411
    }
5412
}
5413
 
108 andreas 5414
void TPageManager::doGSC(int port, vector<int>& channels, vector<string>& pars)
5415
{
5416
    DECL_TRACER("TPageManager::doGSC(int port, vector<int>& channels, vector<string>& pars)");
5417
 
5418
    if (pars.size() < 1)
5419
    {
5420
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
5421
        return;
5422
    }
5423
 
5424
    TError::clear();
5425
    string color = pars[0];
5426
    vector<MAP_T> map = findButtons(port, channels);
5427
 
5428
    if (TError::isError() || map.empty())
5429
        return;
5430
 
5431
    vector<Button::TButton *> buttons = collectButtons(map);
5432
 
5433
    if (buttons.size() > 0)
5434
    {
5435
        vector<Button::TButton *>::iterator mapIter;
5436
 
5437
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
5438
        {
5439
            Button::TButton *bt = *mapIter;
5440
            setButtonCallbacks(bt);
5441
            bt->setBargraphSliderColor(color);
5442
        }
5443
    }
5444
}
5445
 
60 andreas 5446
/**
14 andreas 5447
 * Set the icon to a button.
5448
 */
5449
void TPageManager::doICO(int port, vector<int>& channels, vector<string>& pars)
5450
{
5451
    DECL_TRACER("TPageManager::doICO(int port, vector<int>& channels, vector<string>& pars)");
5452
 
5453
    if (pars.size() < 2)
5454
    {
5455
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
5456
        return;
5457
    }
5458
 
16 andreas 5459
    TError::clear();
14 andreas 5460
    int btState = atoi(pars[0].c_str());
5461
    int iconIdx = atoi(pars[1].c_str());
5462
 
5463
    vector<MAP_T> map = findButtons(port, channels);
5464
 
5465
    if (TError::isError() || map.empty())
5466
        return;
5467
 
5468
    vector<Button::TButton *> buttons = collectButtons(map);
5469
 
83 andreas 5470
    if (buttons.size() > 0)
14 andreas 5471
    {
83 andreas 5472
        vector<Button::TButton *>::iterator mapIter;
14 andreas 5473
 
83 andreas 5474
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
14 andreas 5475
        {
83 andreas 5476
            Button::TButton *bt = *mapIter;
5477
            setButtonCallbacks(bt);
14 andreas 5478
 
83 andreas 5479
            if (btState == 0)       // All instances?
14 andreas 5480
            {
83 andreas 5481
                int bst = bt->getNumberInstances();
5482
                MSG_DEBUG("Setting Icon on all " << bst << " instances...");
5483
 
5484
                for (int i = 0; i < bst; i++)
5485
                {
5486
                    if (iconIdx > 0)
5487
                        bt->setIcon(iconIdx, i);
5488
                    else
5489
                        bt->revokeIcon(i);
5490
                }
14 andreas 5491
            }
83 andreas 5492
            else if (iconIdx > 0)
5493
                bt->setIcon(iconIdx, btState - 1);
5494
            else
5495
                bt->revokeIcon(btState - 1);
14 andreas 5496
        }
5497
    }
5498
}
5499
 
108 andreas 5500
void TPageManager::getICO(int port, vector<int>& channels, vector<string>& pars)
5501
{
5502
    DECL_TRACER("TPageManager::getICO(int port, vector<int>& channels, vector<string>& pars)");
5503
 
5504
    if (pars.size() < 1)
5505
    {
5506
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
5507
        return;
5508
    }
5509
 
5510
    TError::clear();
5511
    int btState = atoi(pars[0].c_str());
5512
 
5513
    vector<MAP_T> map = findButtons(port, channels);
5514
 
5515
    if (TError::isError() || map.empty())
5516
        return;
5517
 
5518
    vector<Button::TButton *> buttons = collectButtons(map);
5519
 
5520
    if (buttons.size() > 0)
5521
    {
110 andreas 5522
        Button::TButton *bt = buttons[0];
108 andreas 5523
 
110 andreas 5524
        if (btState == 0)       // All instances?
108 andreas 5525
        {
110 andreas 5526
            int bst = bt->getNumberInstances();
108 andreas 5527
 
110 andreas 5528
            for (int i = 0; i < bst; i++)
5529
                sendCustomEvent(i + 1, bt->getIconIndex(i), 0, "", 1003, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 5530
        }
110 andreas 5531
        else
5532
            sendCustomEvent(btState, bt->getIconIndex(btState - 1), 0, "", 1003, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 5533
    }
5534
}
5535
 
14 andreas 5536
/**
108 andreas 5537
 * Set bitmap/picture alignment using a numeric keypad layout for those buttons
5538
 * with a defined address range. The alignment of 0 is followed by
5539
 * ',<left>,<top>'. The left and top coordinates are relative to the upper left
5540
 * corner of the button.
5541
 */
5542
void TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)
5543
{
5544
    DECL_TRACER("TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)");
5545
 
5546
    if (pars.size() < 2)
5547
    {
5548
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
5549
        return;
5550
    }
5551
 
5552
    TError::clear();
5553
    int btState = atoi(pars[0].c_str());
5554
    int align = atoi(pars[1].c_str());
5555
    int x = 0, y = 0;
5556
 
5557
    if (!align && pars.size() >= 3)
5558
    {
5559
        x = atoi(pars[2].c_str());
5560
 
5561
        if (pars.size() >= 4)
5562
            y = atoi(pars[3].c_str());
5563
    }
5564
 
5565
    vector<MAP_T> map = findButtons(port, channels);
5566
 
5567
    if (TError::isError() || map.empty())
5568
        return;
5569
 
5570
    vector<Button::TButton *> buttons = collectButtons(map);
5571
 
5572
    if (buttons.size() > 0)
5573
    {
5574
        vector<Button::TButton *>::iterator mapIter;
5575
 
5576
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
5577
        {
5578
            Button::TButton *bt = *mapIter;
5579
 
5580
            if (btState == 0)
5581
                bt->setBitmapJustification(align, x, y, -1);
5582
            else
5583
                bt->setBitmapJustification(align, x, y, btState-1);
5584
        }
5585
    }
5586
}
5587
 
5588
void TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)
5589
{
5590
    DECL_TRACER("TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)");
5591
 
5592
    if (pars.size() < 1)
5593
    {
5594
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
5595
        return;
5596
    }
5597
 
5598
    TError::clear();
5599
    int btState = atoi(pars[0].c_str());
5600
    int j, x, y;
5601
 
5602
    vector<MAP_T> map = findButtons(port, channels);
5603
 
5604
    if (TError::isError() || map.empty())
5605
        return;
5606
 
5607
    vector<Button::TButton *> buttons = collectButtons(map);
5608
 
5609
    if (buttons.size() > 0)
5610
    {
110 andreas 5611
        Button::TButton *bt = buttons[0];
108 andreas 5612
 
110 andreas 5613
        if (btState == 0)       // All instances?
108 andreas 5614
        {
110 andreas 5615
            int bst = bt->getNumberInstances();
108 andreas 5616
 
110 andreas 5617
            for (int i = 0; i < bst; i++)
108 andreas 5618
            {
110 andreas 5619
                j = bt->getBitmapJustification(&x, &y, i);
5620
                sendCustomEvent(i + 1, j, 0, "", 1005, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 5621
            }
5622
        }
110 andreas 5623
        else
5624
        {
5625
            j = bt->getBitmapJustification(&x, &y, btState-1);
5626
            sendCustomEvent(btState, j, 0, "", 1005, bt->getChannelPort(), bt->getChannelNumber());
5627
        }
108 andreas 5628
    }
5629
}
5630
 
5631
/**
5632
 * Set icon alignment using a numeric keypad layout for those buttons with a
5633
 * defined address range. The alignment of 0 is followed by ',<left>,<top>'.
5634
 * The left and top coordinates are relative to the upper left corner of the
5635
 * button.
5636
 */
5637
void TPageManager::doJSI(int port, vector<int>& channels, vector<string>& pars)
5638
{
5639
    DECL_TRACER("TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)");
5640
 
5641
    if (pars.size() < 2)
5642
    {
5643
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
5644
        return;
5645
    }
5646
 
5647
    TError::clear();
5648
    int btState = atoi(pars[0].c_str());
5649
    int align = atoi(pars[1].c_str());
5650
    int x = 0, y = 0;
5651
 
5652
    if (!align && pars.size() >= 3)
5653
    {
5654
        x = atoi(pars[2].c_str());
5655
 
5656
        if (pars.size() >= 4)
5657
            y = atoi(pars[3].c_str());
5658
    }
5659
 
5660
    vector<MAP_T> map = findButtons(port, channels);
5661
 
5662
    if (TError::isError() || map.empty())
5663
        return;
5664
 
5665
    vector<Button::TButton *> buttons = collectButtons(map);
5666
 
5667
    if (buttons.size() > 0)
5668
    {
5669
        vector<Button::TButton *>::iterator mapIter;
5670
 
5671
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
5672
        {
5673
            Button::TButton *bt = *mapIter;
5674
 
5675
            if (btState == 0)
5676
                bt->setIconJustification(align, x, y, -1);
5677
            else
5678
                bt->setIconJustification(align, x, y, btState-1);
5679
        }
5680
    }
5681
}
5682
 
5683
void TPageManager::getJSI(int port, vector<int>& channels, vector<string>& pars)
5684
{
5685
    DECL_TRACER("TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)");
5686
 
5687
    if (pars.size() < 1)
5688
    {
5689
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
5690
        return;
5691
    }
5692
 
5693
    TError::clear();
5694
    int btState = atoi(pars[0].c_str());
5695
    int j, x, y;
5696
 
5697
    vector<MAP_T> map = findButtons(port, channels);
5698
 
5699
    if (TError::isError() || map.empty())
5700
        return;
5701
 
5702
    vector<Button::TButton *> buttons = collectButtons(map);
5703
 
5704
    if (buttons.size() > 0)
5705
    {
110 andreas 5706
        Button::TButton *bt = buttons[0];
108 andreas 5707
 
110 andreas 5708
        if (btState == 0)       // All instances?
108 andreas 5709
        {
110 andreas 5710
            int bst = bt->getNumberInstances();
108 andreas 5711
 
110 andreas 5712
            for (int i = 0; i < bst; i++)
108 andreas 5713
            {
110 andreas 5714
                j = bt->getIconJustification(&x, &y, i);
5715
                sendCustomEvent(i + 1, j, 0, "", 1006, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 5716
            }
5717
        }
110 andreas 5718
        else
5719
        {
5720
            j = bt->getIconJustification(&x, &y, btState-1);
5721
            sendCustomEvent(btState, j, 0, "", 1006, bt->getChannelPort(), bt->getChannelNumber());
5722
        }
108 andreas 5723
    }
5724
}
5725
 
5726
void TPageManager::doJST(int port, vector<int>& channels, vector<string>& pars)
5727
{
5728
    DECL_TRACER("TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)");
5729
 
5730
    if (pars.size() < 2)
5731
    {
5732
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
5733
        return;
5734
    }
5735
 
5736
    TError::clear();
5737
    int btState = atoi(pars[0].c_str());
5738
    int align = atoi(pars[1].c_str());
5739
    int x = 0, y = 0;
5740
 
5741
    if (!align && pars.size() >= 3)
5742
    {
5743
        x = atoi(pars[2].c_str());
5744
 
5745
        if (pars.size() >= 4)
5746
            y = atoi(pars[3].c_str());
5747
    }
5748
 
5749
    vector<MAP_T> map = findButtons(port, channels);
5750
 
5751
    if (TError::isError() || map.empty())
5752
        return;
5753
 
5754
    vector<Button::TButton *> buttons = collectButtons(map);
5755
 
5756
    if (buttons.size() > 0)
5757
    {
5758
        vector<Button::TButton *>::iterator mapIter;
5759
 
5760
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
5761
        {
5762
            Button::TButton *bt = *mapIter;
5763
 
5764
            if (btState == 0)
5765
                bt->setTextJustification(align, x, y, -1);
5766
            else
5767
                bt->setTextJustification(align, x, y, btState-1);
5768
        }
5769
    }
5770
}
5771
 
5772
void TPageManager::getJST(int port, vector<int>& channels, vector<string>& pars)
5773
{
5774
    DECL_TRACER("TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)");
5775
 
5776
    if (pars.size() < 1)
5777
    {
5778
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
5779
        return;
5780
    }
5781
 
5782
    TError::clear();
5783
    int btState = atoi(pars[0].c_str());
5784
    int j, x, y;
5785
 
5786
    vector<MAP_T> map = findButtons(port, channels);
5787
 
5788
    if (TError::isError() || map.empty())
5789
        return;
5790
 
5791
    vector<Button::TButton *> buttons = collectButtons(map);
5792
 
5793
    if (buttons.size() > 0)
5794
    {
110 andreas 5795
        Button::TButton *bt = buttons[0];
108 andreas 5796
 
110 andreas 5797
        if (btState == 0)       // All instances?
108 andreas 5798
        {
110 andreas 5799
            int bst = bt->getNumberInstances();
108 andreas 5800
 
110 andreas 5801
            for (int i = 0; i < bst; i++)
108 andreas 5802
            {
110 andreas 5803
                j = bt->getTextJustification(&x, &y, i);
5804
                sendCustomEvent(i + 1, j, 0, "", 1004, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 5805
            }
5806
        }
110 andreas 5807
        else
5808
        {
5809
            j = bt->getTextJustification(&x, &y, btState-1);
5810
            sendCustomEvent(btState, j, 0, "", 1004, bt->getChannelPort(), bt->getChannelNumber());
5811
        }
108 andreas 5812
    }
5813
}
5814
 
5815
/**
16 andreas 5816
 * Show or hide a button with a set variable text range.
5817
 */
5818
void TPageManager::doSHO(int port, vector<int>& channels, vector<string>& pars)
5819
{
5820
    DECL_TRACER("TPageManager::doSHO(int port, vector<int>& channels, vector<string>& pars)");
5821
 
5822
    if (pars.empty())
5823
    {
5824
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
5825
        return;
5826
    }
5827
 
5828
    TError::clear();
5829
    int cvalue = atoi(pars[0].c_str());
5830
 
5831
    vector<MAP_T> map = findButtons(port, channels);
5832
 
5833
    if (TError::isError() || map.empty())
5834
        return;
5835
 
5836
    vector<Button::TButton *> buttons = collectButtons(map);
5837
 
83 andreas 5838
    if (buttons.size() > 0)
16 andreas 5839
    {
83 andreas 5840
        vector<Button::TButton *>::iterator mapIter;
5841
 
5842
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
5843
        {
5844
            Button::TButton *bt = *mapIter;
100 andreas 5845
            int pgID = (bt->getParent() >> 16) & 0x0000ffff;
5846
            bool pVisible = false;
5847
 
5848
            if (pgID < 500)
5849
            {
5850
                TPage *pg = getPage(pgID);
5851
 
5852
                if (pg && pg->isVisilble())
5853
                    pVisible = true;
5854
            }
5855
            else
5856
            {
5857
                TSubPage *pg = getSubPage(pgID);
5858
 
5859
                if (pg && pg->isVisible())
5860
                    pVisible = true;
5861
            }
5862
 
98 andreas 5863
            bt->setVisible((cvalue ? true : false));
5864
 
100 andreas 5865
            if (pVisible)
5866
            {
5867
                setButtonCallbacks(bt);
5868
 
5869
                if (_setVisible)
5870
                    _setVisible(bt->getHandle(), (cvalue ? true : false));
5871
                else
5872
                    bt->refresh();
5873
            }
83 andreas 5874
        }
16 andreas 5875
    }
5876
}
5877
 
108 andreas 5878
void TPageManager::doTEC(int port, vector<int>& channels, vector<string>& pars)
5879
{
5880
    DECL_TRACER("TPageManager::doTEC(int port, vector<int>& channels, vector<string>& pars)");
5881
 
5882
    if (pars.size() < 2)
5883
    {
5884
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
5885
        return;
5886
    }
5887
 
5888
    TError::clear();
5889
    int btState = atoi(pars[0].c_str());
5890
    string color = pars[1];
5891
 
5892
    vector<MAP_T> map = findButtons(port, channels);
5893
 
5894
    if (TError::isError() || map.empty())
5895
        return;
5896
 
5897
    vector<Button::TButton *> buttons = collectButtons(map);
5898
 
5899
    if (buttons.size() > 0)
5900
    {
5901
        vector<Button::TButton *>::iterator mapIter;
5902
 
5903
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
5904
        {
5905
            Button::TButton *bt = *mapIter;
5906
 
5907
            if (btState == 0)
5908
                bt->setTextEffectColor(color);
5909
            else
5910
                bt->setTextEffectColor(color, btState-1);
5911
        }
5912
    }
5913
}
5914
 
5915
void TPageManager::getTEC(int port, vector<int>& channels, vector<string>& pars)
5916
{
5917
    DECL_TRACER("TPageManager::getTEC(int port, vector<int>& channels, vector<string>& pars)");
5918
 
5919
    if (pars.size() < 1)
5920
    {
5921
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
5922
        return;
5923
    }
5924
 
5925
    TError::clear();
5926
    int btState = atoi(pars[0].c_str());
5927
 
5928
    vector<MAP_T> map = findButtons(port, channels);
5929
 
5930
    if (TError::isError() || map.empty())
5931
        return;
5932
 
5933
    vector<Button::TButton *> buttons = collectButtons(map);
5934
 
5935
    if (buttons.size() > 0)
5936
    {
110 andreas 5937
        Button::TButton *bt = buttons[0];
5938
 
5939
        if (btState == 0)       // All instances?
5940
        {
5941
            int bst = bt->getNumberInstances();
5942
 
5943
            for (int i = 0; i < bst; i++)
5944
            {
5945
                string c = bt->getTextEffectColor(i);
5946
                sendCustomEvent(i + 1, c.length(), 0, c, 1009, bt->getChannelPort(), bt->getChannelNumber());
5947
            }
5948
        }
5949
        else
5950
        {
5951
            string c = bt->getTextEffectColor(btState-1);
5952
            sendCustomEvent(btState, c.length(), 0, c, 1009, bt->getChannelPort(), bt->getChannelNumber());
5953
        }
5954
    }
5955
}
5956
 
5957
void TPageManager::doTEF(int port, vector<int>& channels, vector<string>& pars)
5958
{
5959
    DECL_TRACER("TPageManager::doTEF(int port, vector<int>& channels, vector<string>& pars)");
5960
 
5961
    if (pars.size() < 2)
5962
    {
5963
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
5964
        return;
5965
    }
5966
 
5967
    TError::clear();
5968
    int btState = atoi(pars[0].c_str());
5969
    string tef = pars[1];
5970
 
5971
    vector<MAP_T> map = findButtons(port, channels);
5972
 
5973
    if (TError::isError() || map.empty())
5974
        return;
5975
 
5976
    vector<Button::TButton *> buttons = collectButtons(map);
5977
 
5978
    if (buttons.size() > 0)
5979
    {
108 andreas 5980
        vector<Button::TButton *>::iterator mapIter;
5981
 
5982
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
5983
        {
5984
            Button::TButton *bt = *mapIter;
5985
 
110 andreas 5986
            if (btState == 0)
5987
                bt->setTextEffectName(tef);
5988
            else
5989
                bt->setTextEffectName(tef, btState-1);
5990
        }
5991
    }
5992
}
108 andreas 5993
 
110 andreas 5994
void TPageManager::getTEF(int port, vector<int>& channels, vector<string>& pars)
5995
{
5996
    DECL_TRACER("TPageManager::getTEF(int port, vector<int>& channels, vector<string>& pars)");
108 andreas 5997
 
110 andreas 5998
    if (pars.size() < 1)
5999
    {
6000
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
6001
        return;
6002
    }
108 andreas 6003
 
110 andreas 6004
    TError::clear();
6005
    int btState = atoi(pars[0].c_str());
6006
 
6007
    vector<MAP_T> map = findButtons(port, channels);
6008
 
6009
    if (TError::isError() || map.empty())
6010
        return;
6011
 
6012
    vector<Button::TButton *> buttons = collectButtons(map);
6013
 
6014
    if (buttons.size() > 0)
6015
    {
6016
        Button::TButton *bt = buttons[0];
6017
 
6018
        if (btState == 0)       // All instances?
6019
        {
6020
            int bst = bt->getNumberInstances();
6021
 
6022
            for (int i = 0; i < bst; i++)
108 andreas 6023
            {
110 andreas 6024
                string c = bt->getTextEffectName(i);
6025
                sendCustomEvent(i + 1, c.length(), 0, c, 1008, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 6026
            }
6027
        }
110 andreas 6028
        else
6029
        {
6030
            string c = bt->getTextEffectName(btState-1);
6031
            sendCustomEvent(btState, c.length(), 0, c, 1008, bt->getChannelPort(), bt->getChannelNumber());
6032
        }
108 andreas 6033
    }
6034
}
6035
 
16 andreas 6036
/**
14 andreas 6037
 * Assign a text string to those buttons with a defined address range.
6038
 * Sets Non-Unicode text.
6039
 */
6040
void TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)
6041
{
6042
    DECL_TRACER("TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)");
6043
 
6044
    if (pars.size() < 1)
6045
    {
6046
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
6047
        return;
6048
    }
6049
 
16 andreas 6050
    TError::clear();
14 andreas 6051
    int btState = atoi(pars[0].c_str());
6052
    string text;
6053
 
6054
    if (pars.size() > 1)
6055
        text = pars[1];
6056
 
6057
    vector<MAP_T> map = findButtons(port, channels);
6058
 
6059
    if (TError::isError() || map.empty())
6060
        return;
6061
 
6062
    vector<Button::TButton *> buttons = collectButtons(map);
6063
 
83 andreas 6064
    if (buttons.size() > 0)
14 andreas 6065
    {
83 andreas 6066
        vector<Button::TButton *>::iterator mapIter;
14 andreas 6067
 
83 andreas 6068
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
14 andreas 6069
        {
83 andreas 6070
            Button::TButton *bt = *mapIter;
6071
            setButtonCallbacks(bt);
14 andreas 6072
 
83 andreas 6073
            if (btState == 0)       // All instances?
6074
            {
6075
                int bst = bt->getNumberInstances();
6076
                MSG_DEBUG("Setting TXT on all " << bst << " instances...");
6077
 
6078
                for (int i = 0; i < bst; i++)
6079
                    bt->setText(text, i);
6080
            }
6081
            else
6082
                bt->setText(text, btState - 1);
14 andreas 6083
        }
6084
    }
6085
}
21 andreas 6086
 
110 andreas 6087
void TPageManager::getTXT(int port, vector<int>& channels, vector<string>& pars)
6088
{
6089
    DECL_TRACER("TPageManager::getTXT(int port, vector<int>& channels, vector<string>& pars)");
6090
 
6091
    if (pars.size() < 1)
6092
    {
6093
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
6094
        return;
6095
    }
6096
 
6097
    TError::clear();
6098
    int btState = atoi(pars[0].c_str());
6099
 
6100
    vector<MAP_T> map = findButtons(port, channels);
6101
 
6102
    if (TError::isError() || map.empty())
6103
        return;
6104
 
6105
    vector<Button::TButton *> buttons = collectButtons(map);
6106
 
6107
    if (buttons.size() > 0)
6108
    {
6109
        Button::TButton *bt = buttons[0];
6110
 
6111
        if (btState == 0)       // All instances?
6112
        {
6113
            int bst = bt->getNumberInstances();
6114
 
6115
            for (int i = 0; i < bst; i++)
6116
            {
6117
                string c = bt->getText(i);
6118
                sendCustomEvent(i + 1, c.length(), 0, c, 1001, bt->getChannelPort(), bt->getChannelNumber());
6119
            }
6120
        }
6121
        else
6122
        {
6123
            string c = bt->getText(btState-1);
6124
            sendCustomEvent(btState, c.length(), 0, c, 1001, bt->getChannelPort(), bt->getChannelNumber());
6125
        }
6126
    }
6127
}
6128
 
97 andreas 6129
/*
104 andreas 6130
 * Set button state legacy unicode text command.
6131
 *
6132
 * Set Unicode text in the legacy G4 format. For the ^UNI command, the Unicode
6133
 * text is sent as ASCII-HEX nibbles.
6134
 */
6135
void TPageManager::doUNI(int port, vector<int>& channels, vector<string>& pars)
6136
{
6137
    DECL_TRACER("TPageManager::doUNI(int port, vector<int>& channels, vector<string>& pars)");
6138
 
6139
    if (pars.size() < 1)
6140
    {
6141
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
6142
        return;
6143
    }
6144
 
6145
    TError::clear();
6146
    int btState = atoi(pars[0].c_str());
6147
    string text;
6148
 
6149
    // Because UTF8 is not supported out of the box from Windows and NetLinx
6150
    // Studio has no native support for it, any UTF8 text must be encoded in
6151
    // bytes. Because of this we must decode the bytes into real bytes here.
6152
    if (pars.size() > 1)
6153
    {
6154
        string byte;
6155
        size_t pos = 0;
6156
 
6157
        while (pos < pars[1].length())
6158
        {
6159
            byte = pars[1].substr(pos, 2);
6160
            char ch = (char)strtol(byte.c_str(), NULL, 16);
6161
            text += ch;
6162
            pos += 2;
6163
        }
6164
    }
6165
 
6166
    vector<MAP_T> map = findButtons(port, channels);
6167
 
6168
    if (TError::isError() || map.empty())
6169
        return;
6170
 
6171
    vector<Button::TButton *> buttons = collectButtons(map);
6172
 
6173
    if (buttons.size() > 0)
6174
    {
6175
        vector<Button::TButton *>::iterator mapIter;
6176
 
6177
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
6178
        {
6179
            Button::TButton *bt = *mapIter;
6180
            setButtonCallbacks(bt);
6181
 
6182
            if (btState == 0)       // All instances?
6183
            {
6184
                int bst = bt->getNumberInstances();
6185
                MSG_DEBUG("Setting UNI on all " << bst << " instances...");
6186
 
6187
                for (int i = 0; i < bst; i++)
6188
                    bt->setText(text, i);
6189
            }
6190
            else
6191
                bt->setText(text, btState - 1);
6192
        }
6193
    }
6194
}
6195
 
6196
void TPageManager::doUTF(int port, vector<int>& channels, vector<string>& pars)
6197
{
6198
    DECL_TRACER("TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)");
6199
 
6200
    if (pars.size() < 1)
6201
    {
6202
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
6203
        return;
6204
    }
6205
 
6206
    TError::clear();
6207
    int btState = atoi(pars[0].c_str());
6208
    string text;
6209
 
6210
    if (pars.size() > 1)
6211
        text = pars[1];
6212
 
6213
    vector<MAP_T> map = findButtons(port, channels);
6214
 
6215
    if (TError::isError() || map.empty())
6216
        return;
6217
 
6218
    vector<Button::TButton *> buttons = collectButtons(map);
6219
 
6220
    if (buttons.size() > 0)
6221
    {
6222
        vector<Button::TButton *>::iterator mapIter;
6223
 
6224
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
6225
        {
6226
            Button::TButton *bt = *mapIter;
6227
            setButtonCallbacks(bt);
6228
 
6229
            if (btState == 0)       // All instances?
6230
            {
6231
                int bst = bt->getNumberInstances();
6232
                MSG_DEBUG("Setting TXT on all " << bst << " instances...");
6233
 
6234
                for (int i = 0; i < bst; i++)
6235
                    bt->setText(text, i);
6236
            }
6237
            else
6238
                bt->setText(text, btState - 1);
6239
        }
6240
    }
6241
}
111 andreas 6242
 
6243
/**
6244
 * Set the keyboard passthru.
6245
 */
6246
void TPageManager::doKPS(int, vector<int>&, vector<string>& pars)
6247
{
6248
    DECL_TRACER("TPageManager::doKPS(int, vector<int>&, vector<string>& pars)");
6249
 
6250
    if (pars.size() < 1)
6251
    {
6252
        MSG_ERROR("Got no parameter. Ignoring command!");
6253
        return;
6254
    }
6255
 
6256
    int state = atoi(pars[0].c_str());
6257
 
6258
    if (state == 0)
6259
        mPassThrough = false;
6260
    else if (state == 5)
6261
        mPassThrough = true;
6262
}
6263
 
6264
void TPageManager::doVKS(int, std::vector<int>&, vector<string>& pars)
6265
{
6266
    DECL_TRACER("TPageManager::doVKS(int, std::vector<int>&, vector<string>& pars)");
6267
 
6268
    if (pars.size() < 1)
6269
    {
6270
        MSG_ERROR("Got no parameter. Ignoring command!");
6271
        return;
6272
    }
6273
 
6274
    if (_sendVirtualKeys)
6275
        _sendVirtualKeys(pars[0]);
6276
}
6277
 
104 andreas 6278
/*
97 andreas 6279
 * Set the bitmap of a button to use a particular resource.
6280
 * Syntax:
6281
 *    "'^BBR-<vt addr range>,<button states range>,<resource name>'"
6282
 * Variable:
6283
 *    variable text address range = 1 - 4000.
6284
 *    button states range = 1 - 256 for multi-state buttons (0 = All states, for General buttons 1 = Off state and 2 = On state).
6285
 *    resource name = 1 - 50 ASCII characters.
6286
 * Example:
6287
 *    SEND_COMMAND Panel,"'^BBR-700,1,Sports_Image'"
6288
 *    Sets the resource name of the button to ’Sports_Image’.
6289
 */
21 andreas 6290
void TPageManager::doBBR(int port, vector<int>& channels, vector<string>& pars)
6291
{
6292
    DECL_TRACER("TPageManager::doBBR(int port, vector<int>& channels, vector<string>& pars)");
6293
 
6294
    if (pars.size() < 2)
6295
    {
6296
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
6297
        return;
6298
    }
6299
 
6300
    TError::clear();
6301
    int btState = atoi(pars[0].c_str());
6302
    string resName = pars[1];
6303
 
6304
    vector<MAP_T> map = findButtons(port, channels);
6305
 
6306
    if (TError::isError() || map.empty())
6307
        return;
6308
 
6309
    vector<Button::TButton *> buttons = collectButtons(map);
6310
 
83 andreas 6311
    if (buttons.size() > 0)
21 andreas 6312
    {
83 andreas 6313
        vector<Button::TButton *>::iterator mapIter;
21 andreas 6314
 
83 andreas 6315
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
21 andreas 6316
        {
83 andreas 6317
            Button::TButton *bt = *mapIter;
6318
            setButtonCallbacks(bt);
21 andreas 6319
 
83 andreas 6320
            if (btState == 0)       // All instances?
6321
            {
6322
                int bst = bt->getNumberInstances();
6323
                MSG_DEBUG("Setting BBR on all " << bst << " instances...");
6324
 
6325
                for (int i = 0; i < bst; i++)
6326
                    bt->setResourceName(resName, i);
6327
            }
6328
            else
6329
                bt->setResourceName(resName, btState - 1);
97 andreas 6330
 
6331
            if (bt->isVisible())
6332
                bt->refresh();
99 andreas 6333
            else if (_setVisible)
6334
                _setVisible(bt->getHandle(), false);
21 andreas 6335
        }
6336
    }
6337
}
6338
 
97 andreas 6339
/*
6340
 * Add new resources
6341
 * Adds any and all resource parameters by sending embedded codes and data.
6342
 * Since the embedded codes are preceded by a '%' character, any '%' character
6343
 * contained in* the URL must be escaped with a second '%' character (see
6344
 * example).
6345
 * The file name field (indicated by a %F embedded code) may contain special
6346
 * escape sequences as shown in the ^RAF, ^RMF.
6347
 * Syntax:
6348
 *    "'^RAF-<resource name>,<data>'"
6349
 * Variables:
6350
 *    resource name = 1 - 50 ASCII characters.
6351
 *    data = Refers to the embedded codes, see the ^RAF, ^RMF.
6352
 * Example:
6353
 *    SEND_COMMAND Panel,"'^RAF-New Image,%P0%HAMX.COM%ALab/Test%%5Ffile%Ftest.jpg'"
6354
 *    Adds a new resource.
6355
 *    The resource name is ’New Image’
6356
 *    %P (protocol) is an HTTP
6357
 *    %H (host name) is AMX.COM
6358
 *    %A (file path) is Lab/Test_f ile
6359
 *    %F (file name) is test.jpg.
6360
 *    Note that the %%5F in the file path is actually encoded as %5F.
6361
 */
6362
void TPageManager::doRAF(int, vector<int>&, vector<string>& pars)
6363
{
6364
    DECL_TRACER("TPageManager::doRAF(int port, vector<int>& channels, vector<string>& pars)");
6365
 
6366
    if (pars.size() < 2)
6367
    {
6368
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
6369
        return;
6370
    }
6371
 
6372
    string name = pars[0];
6373
    string data = pars[1];
6374
 
6375
    vector<string> parts = StrSplit(data, "%");
6376
    RESOURCE_T res;
6377
 
6378
    if (parts.size() > 0)
6379
    {
6380
        vector<string>::iterator sIter;
6381
 
6382
        for (sIter = parts.begin(); sIter != parts.end(); sIter++)
6383
        {
6384
            const char *s = sIter->c_str();
6385
            string ss = *sIter;
6386
            MSG_DEBUG("Parsing \"" << ss << "\" with token << " << ss[0]);
6387
 
6388
            switch(*s)
6389
            {
6390
                case 'P':
6391
                    if (*(s+1) == '0')
6392
                        res.protocol = "HTTP";
6393
                    else
6394
                        res.protocol = "FTP";
6395
                    break;
6396
 
6397
                case 'U': res.user = sIter->substr(1); break;
6398
                case 'S': res.password = sIter->substr(1); break;
6399
                case 'H': res.host = sIter->substr(1); break;
6400
                case 'F': res.file = sIter->substr(1); break;
6401
                case 'A': res.path = sIter->substr(1); break;
6402
                case 'R': res.refresh = atoi(sIter->substr(1).c_str()); break;
6403
 
6404
                default:
6405
                    MSG_WARNING("Option " << sIter->at(0) << " is currently not implemented!");
6406
            }
6407
        }
6408
 
6409
        if (gPrjResources)
6410
            gPrjResources->addResource(name, res.protocol, res.host, res.path, res.file, res.user, res.password, res.refresh);
6411
    }
6412
}
6413
 
111 andreas 6414
void TPageManager::doRFR(int, vector<int>&, vector<string>& pars)
97 andreas 6415
{
6416
    DECL_TRACER("TPageManager::doRFR(int port, vector<int>& channels, vector<string>& pars)");
6417
 
6418
    if (pars.size() < 1)
6419
    {
6420
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
6421
        return;
6422
    }
6423
 
6424
    string name = pars[0];
6425
    vector<MAP_T> map = findButtonByName(name);
6426
 
6427
    if (TError::isError() || map.empty())
6428
        return;
6429
 
6430
    vector<Button::TButton *> buttons = collectButtons(map);
6431
 
6432
    if (buttons.size() > 0)
6433
    {
6434
        vector<Button::TButton *>::iterator mapIter;
6435
 
6436
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
6437
        {
6438
            Button::TButton *bt = *mapIter;
6439
 
6440
            if (bt->isVisible())
6441
            {
6442
                setButtonCallbacks(bt);
6443
                bt->refresh();
6444
            }
6445
        }
6446
    }
6447
}
6448
 
6449
/*
6450
 * Modify an existing resource
6451
 *
6452
 * Modifies any and all resource parameters by sending embedded codes and data.
6453
 * Since the embedded codes are preceded by a '%' character, any '%' character
6454
 * contained in the URL must be escaped with a second '%' character (see
6455
 * example).
6456
 * The file name field (indicated by a %F embedded code) may contain special
6457
 * escape sequences as shown in the ^RAF.
6458
 *
6459
 * Syntax:
6460
 * "'^RMF-<resource name>,<data>'"
6461
 * Variables:
6462
 *   • resource name = 1 - 50 ASCII characters
6463
 *   • data = Refers to the embedded codes, see the ^RAF, ^RMF.
6464
 * Example:
6465
 *   SEND_COMMAND Panel,"'^RMF-Sports_Image,%ALab%%5FTest/Images%Ftest.jpg'"
6466
 * Changes the resource ’Sports_Image’ file name to ’test.jpg’ and the path to
6467
 * ’Lab_Test/Images’.
6468
 * Note that the %%5F in the file path is actually encoded as %5F.
6469
 */
22 andreas 6470
void TPageManager::doRMF(int, vector<int>&, vector<string>& pars)
21 andreas 6471
{
6472
    DECL_TRACER("TPageManager::doRMF(int port, vector<int>& channels, vector<string>& pars)");
6473
 
6474
    if (pars.size() < 2)
6475
    {
6476
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
6477
        return;
6478
    }
6479
 
6480
    string name = pars[0];
6481
    string data = pars[1];
6482
 
6483
    vector<string> parts = StrSplit(data, "%");
6484
    RESOURCE_T res;
6485
 
83 andreas 6486
    if (parts.size() > 0)
21 andreas 6487
    {
83 andreas 6488
        vector<string>::iterator sIter;
21 andreas 6489
 
83 andreas 6490
        for (sIter = parts.begin(); sIter != parts.end(); sIter++)
21 andreas 6491
        {
83 andreas 6492
            const char *s = sIter->c_str();
6493
            string ss = *sIter;
6494
            MSG_DEBUG("Parsing \"" << ss << "\" with token << " << ss[0]);
21 andreas 6495
 
83 andreas 6496
            switch(*s)
6497
            {
6498
                case 'P':
6499
                    if (*(s+1) == '0')
6500
                        res.protocol = "HTTP";
6501
                    else
6502
                        res.protocol = "FTP";
6503
                break;
21 andreas 6504
 
83 andreas 6505
                case 'U': res.user = sIter->substr(1); break;
6506
                case 'S': res.password = sIter->substr(1); break;
6507
                case 'H': res.host = sIter->substr(1); break;
6508
                case 'F': res.file = sIter->substr(1); break;
6509
                case 'A': res.path = sIter->substr(1); break;
6510
                case 'R': res.refresh = atoi(sIter->substr(1).c_str()); break;
6511
 
6512
                default:
6513
                    MSG_WARNING("Option " << sIter->at(0) << " is currently not implemented!");
6514
            }
21 andreas 6515
        }
83 andreas 6516
 
6517
        if (gPrjResources)
6518
            gPrjResources->setResource(name, res.protocol, res.host, res.path, res.file, res.user, res.password, res.refresh);
21 andreas 6519
    }
6520
}
62 andreas 6521
 
6522
/**
111 andreas 6523
 * Change the refresh rate for a given resource.
6524
 */
6525
void TPageManager::doRSR(int, vector<int>&, vector<string>& pars)
6526
{
6527
    DECL_TRACER("TPageManager::doRSR(int, vector<int>&, vector<string>& pars)");
6528
 
6529
    if (pars.size() < 2)
6530
    {
6531
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
6532
        return;
6533
    }
6534
 
6535
    string resName = pars[0];
6536
    int resRefresh = atoi(pars[1].c_str());
6537
 
6538
    if (!gPrjResources)
6539
    {
6540
        MSG_ERROR("Missing the resource module. Ignoring command!");
6541
        return;
6542
    }
6543
 
6544
    RESOURCE_T res = gPrjResources->findResource(resName);
6545
 
6546
    if (res.name.empty() || res.refresh == resRefresh)
6547
        return;
6548
 
6549
    gPrjResources->setResource(resName, res.protocol, res.host, res.path, res.file, res.user, res.password, resRefresh);
6550
}
6551
 
6552
/**
62 andreas 6553
 * @brief TPageManager::doAKB - Pop up the keyboard icon
6554
 * Pop up the keyboard icon and initialize the text string to that specified.
6555
 * Keyboard string is set to null on power up and is stored until power is lost.
6556
 * The Prompt Text is optional.
6557
 */
6558
void TPageManager::doAKB(int, vector<int>&, vector<string> &pars)
6559
{
6560
    DECL_TRACER("TPageManager::doAKB(int, vector<int>&, vector<string> &pars)");
6561
 
6562
    if (pars.size() < 1)
6563
    {
6564
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
6565
        return;
6566
    }
6567
 
6568
    string initText = pars[0];
6569
    string promptText;
6570
 
6571
    if (pars.size() > 1)
6572
        promptText = pars[1];
6573
 
63 andreas 6574
    if (initText.empty())
6575
        initText = mAkbText;
6576
    else
6577
        mAkbText = initText;
62 andreas 6578
 
6579
    if (_callKeyboard)
63 andreas 6580
        _callKeyboard(initText, promptText, false);
62 andreas 6581
}
6582
 
63 andreas 6583
/**
6584
 * Pop up the keyboard icon and initialize the text string to that
6585
 * specified.
6586
 */
62 andreas 6587
void TPageManager::doAKEYB(int port, vector<int>& channels, vector<string>& pars)
6588
{
6589
    DECL_TRACER("TPageManager::doAKEYB(int port, vector<int>& channels, vector<string>& pars)");
6590
 
6591
    doAKB(port, channels, pars);
6592
}
6593
 
63 andreas 6594
void TPageManager::doAKEYP(int port, std::vector<int>& channels, std::vector<std::string>& pars)
6595
{
6596
    DECL_TRACER("TPageManager::doAKEYP(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
6597
 
6598
    doAKP(port, channels, pars);
6599
}
6600
 
62 andreas 6601
/**
63 andreas 6602
 * Remove keyboard or keypad that was displayed using 'AKEYB', 'AKEYP', 'PKEYP',
6603
 * @AKB, @AKP, @PKP, @EKP, or @TKP commands.
6604
 */
6605
void TPageManager::doAKEYR(int, vector<int>&, vector<string>&)
6606
{
6607
    DECL_TRACER("TPageManager::doAKEYR(int, vector<int>&, vector<string>&)");
6608
 
6609
    if (_callResetKeyboard)
6610
        _callResetKeyboard();
6611
}
6612
 
6613
/**
62 andreas 6614
 * @brief TPageManager::doAKP - Pop up the keypad icon
6615
 * Pop up the keypad icon and initialize the text string to that specified.
6616
 * Keypad string is set to null on power up and is stored until power is lost.
6617
 * The Prompt Text is optional.
6618
 */
6619
void TPageManager::doAKP(int, std::vector<int>&, std::vector<std::string> &pars)
6620
{
6621
    DECL_TRACER("TPageManager::doAKP(int, vector<int>&, vector<string> &pars)");
6622
 
6623
    if (pars.size() < 1)
6624
    {
6625
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
6626
        return;
6627
    }
6628
 
6629
    string initText = pars[0];
6630
    string promptText;
6631
 
6632
    if (pars.size() > 1)
6633
        promptText = pars[1];
6634
 
63 andreas 6635
    if (initText.empty())
6636
        initText = mAkpText;
6637
    else
6638
        mAkpText = initText;
62 andreas 6639
 
6640
    if (_callKeypad)
63 andreas 6641
        _callKeypad(initText, promptText, false);
62 andreas 6642
}
6643
 
63 andreas 6644
/**
6645
 * Remove keyboard or keypad that was displayed using 'AKEYB', 'AKEYP', 'PKEYP',
6646
 * @AKB, @AKP, @PKP, @EKP, or @TKP commands.
6647
 */
6648
void TPageManager::doAKR(int port, vector<int>& channels, vector<string>& pars)
62 andreas 6649
{
63 andreas 6650
    DECL_TRACER("TPageManager::doAKR(int, vector<int>&, vector<string>&)");
62 andreas 6651
 
63 andreas 6652
    doAKEYR(port, channels, pars);
62 andreas 6653
}
6654
 
108 andreas 6655
void TPageManager::doABEEP(int, std::vector<int>&, vector<string>&)
6656
{
6657
    DECL_TRACER("TPageManager::doBEEP(int, std::vector<int>&, vector<string>&)");
6658
 
6659
    if (!_playSound)
6660
        return;
6661
 
6662
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getSingleBeepSound();
6663
    TValidateFile vf;
6664
 
6665
    if (_playSound && vf.isValidFile(snd))
6666
        _playSound(snd);
6667
}
6668
 
6669
void TPageManager::doADBEEP(int, std::vector<int>&, vector<string>&)
6670
{
6671
    DECL_TRACER("TPageManager::doDBEEP(int, std::vector<int>&, vector<string>&)");
6672
 
6673
    if (!_playSound)
6674
        return;
6675
 
6676
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getDoubleBeepSound();
6677
    TValidateFile vf;
6678
 
6679
    if (_playSound && vf.isValidFile(snd))
6680
        _playSound(snd);
6681
}
6682
 
71 andreas 6683
void TPageManager::doBEEP(int, std::vector<int>&, vector<string>&)
6684
{
6685
    DECL_TRACER("TPageManager::doBEEP(int, std::vector<int>&, vector<string>&)");
6686
 
6687
    if (!_playSound)
6688
        return;
6689
 
6690
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getSingleBeepSound();
6691
    TValidateFile vf;
108 andreas 6692
    TSystemSound sysSound(TConfig::getSystemPath(TConfig::SOUNDS));
71 andreas 6693
 
108 andreas 6694
    if (_playSound && sysSound.getSystemSoundState() && vf.isValidFile(snd))
71 andreas 6695
        _playSound(snd);
6696
}
6697
 
6698
void TPageManager::doDBEEP(int, std::vector<int>&, vector<string>&)
6699
{
6700
    DECL_TRACER("TPageManager::doDBEEP(int, std::vector<int>&, vector<string>&)");
6701
 
6702
    if (!_playSound)
6703
        return;
6704
 
6705
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getDoubleBeepSound();
6706
    TValidateFile vf;
108 andreas 6707
    TSystemSound sysSound(TConfig::getSystemPath(TConfig::SOUNDS));
71 andreas 6708
 
108 andreas 6709
    if (_playSound && sysSound.getSystemSoundState() && vf.isValidFile(snd))
71 andreas 6710
        _playSound(snd);
6711
}
6712
 
63 andreas 6713
/**
6714
 * @brief Pop up the keypad icon and initialize the text string to that specified.
6715
 * Keypad string is set to null on power up and is stored until power is lost.
6716
 * The Prompt Text is optional.
6717
 */
62 andreas 6718
void TPageManager::doEKP(int port, std::vector<int>& channels, std::vector<std::string>& pars)
6719
{
6720
    DECL_TRACER("TPageManager::doEKP(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
6721
 
6722
    doAKP(port, channels, pars);
6723
}
63 andreas 6724
 
6725
/**
6726
 * @brief Present a private keyboard.
6727
 * Pops up the keyboard icon and initializes the text string to that specified.
6728
 * Keyboard displays a '*' instead of the letters typed. The Prompt Text is optional.
6729
 */
6730
void TPageManager::doPKB(int, vector<int>&, vector<string>& pars)
6731
{
6732
    DECL_TRACER("TPageManager::doPKB(int, vector<int>&, vector<string>& pars)");
6733
 
6734
    if (pars.size() < 1)
6735
    {
6736
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
6737
        return;
6738
    }
6739
 
6740
    string initText = pars[0];
6741
    string promptText;
6742
 
6743
    if (pars.size() > 1)
6744
        promptText = pars[1];
6745
 
6746
    if (_callKeyboard)
6747
        _callKeyboard(initText, promptText, true);
6748
}
6749
 
6750
/**
6751
 * @brief Present a private keypad.
6752
 * Pops up the keypad icon and initializes the text string to that specified.
6753
 * Keypad displays a '*' instead of the numbers typed. The Prompt Text is optional.
6754
 */
6755
void TPageManager::doPKP(int, vector<int>&, vector<string>& pars)
6756
{
6757
    DECL_TRACER("TPageManager::doPKP(int, vector<int>&, vector<string>& pars)");
6758
 
6759
    if (pars.size() < 1)
6760
    {
6761
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
6762
        return;
6763
    }
6764
 
6765
    string initText = pars[0];
6766
    string promptText;
6767
 
6768
    if (pars.size() > 1)
6769
        promptText = pars[1];
6770
 
6771
    if (_callKeypad)
6772
        _callKeypad(initText, promptText, true);
6773
}
6774
 
6775
/**
64 andreas 6776
 * Send panel to SETUP page.
6777
 */
6778
void TPageManager::doSetup(int, vector<int>&, vector<string>&)
6779
{
6780
    DECL_TRACER("TPageManager::doSetup(int, vector<int>&, vector<string>&)");
6781
 
97 andreas 6782
    MSG_PROTOCOL("Received command to show setup ...");
64 andreas 6783
 
6784
    if (_callShowSetup)
6785
        _callShowSetup();
6786
}
6787
 
6788
/**
6789
 * Shut down the App
6790
 */
6791
void TPageManager::doShutdown(int, vector<int>&, vector<string>&)
6792
{
6793
    DECL_TRACER("TPageManager::doShutdown(int, vector<int>&, vector<string>&)");
6794
 
97 andreas 6795
    MSG_PROTOCOL("Received shutdown ...");
64 andreas 6796
#ifdef __ANDROID__
6797
    stopNetworkState();
6798
#endif
6799
    prg_stopped = true;
6800
    killed = true;
6801
 
6802
    if (_shutdown)
6803
        _shutdown();
6804
}
6805
 
82 andreas 6806
void TPageManager::doSOU(int, vector<int>&, vector<string>& pars)
6807
{
6808
    DECL_TRACER("TPageManager::doSOU(int, vector<int>&, vector<string>& pars)");
6809
 
6810
    if (pars.size() < 1)
6811
    {
6812
        MSG_ERROR("@SOU: Expecting a sound file as parameter! Ignoring command.");
6813
        return;
6814
    }
6815
 
6816
    if (!_playSound)
6817
    {
6818
        MSG_ERROR("@SOU: Missing sound module!");
6819
        return;
6820
    }
6821
 
6822
    _playSound(pars[0]);
6823
}
6824
 
64 andreas 6825
/**
63 andreas 6826
 * @brief Present a telephone keypad.
6827
 * Pops up the keypad icon and initializes the text string to that specified.
6828
 * The Prompt Text is optional.
6829
 */
6830
void TPageManager::doTKP(int port, vector<int>& channels, vector<string>& pars)
6831
{
6832
    DECL_TRACER("TPageManager::doTKP(int port, vector<int>& channels, vector<string>& pars)");
6833
 
6834
    // TODO: Implement a real telefone keypad.
6835
    doAKP(port, channels, pars);
6836
}
6837
 
6838
/**
6839
 * Popup the virtual keyboard
6840
 */
6841
void TPageManager::doVKB(int port, std::vector<int>& channels, std::vector<std::string>& pars)
6842
{
6843
    DECL_TRACER("TPageManager::doVKB(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
6844
 
6845
    doAKP(port, channels, pars);
6846
}
6847