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