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