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