Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 andreas 1
/*
269 andreas 2
 * Copyright (C) 2020 to 2023 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
 
270 andreas 19
#include <QtGlobal>
20
 
3 andreas 21
#include <vector>
14 andreas 22
#include <thread>
23
#include <mutex>
186 andreas 24
 
36 andreas 25
#ifdef __ANDROID__
264 andreas 26
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
183 andreas 27
#       include <QtAndroidExtras/QAndroidJniObject>
28
#       include <QtAndroidExtras/QtAndroid>
216 andreas 29
#   else
30
#       include <QJniObject>
31
#       include <QCoreApplication>
183 andreas 32
#   endif
33
#   include <android/log.h>
182 andreas 34
#endif
134 andreas 35
#include <unistd.h>
36
#ifndef __ANDROID__
183 andreas 37
#   include <fstab.h>
134 andreas 38
#endif
14 andreas 39
 
186 andreas 40
#if __cplusplus < 201402L
41
#   error "This module requires at least C++14 standard!"
42
#else
43
#   if __cplusplus < 201703L
44
#       include <experimental/filesystem>
45
namespace fs = std::experimental::filesystem;
46
#       warning "Support for C++14 and experimental filesystem will be removed in a future version!"
47
#   else
48
#       include <filesystem>
49
#       ifdef __ANDROID__
50
namespace fs = std::__fs::filesystem;
51
#       else
52
namespace fs = std::filesystem;
53
#       endif
54
#   endif
55
#endif
56
 
235 andreas 57
#ifdef __APPLE__
58
#   include <unistd.h>
59
#   ifndef HOST_NAME_MAX
60
#       ifdef MAXHOSTNAMELEN
61
#           define HOST_NAME_MAX    MAXHOSTNAMELEN
62
#       else
63
#           define HOST_NAME_MAX    64
64
#       endif   // MAXHOSTNAMELEN
65
#   endif       // HOST_NAME_MAX
66
#endif          // __APPLE__
67
 
3 andreas 68
#include "tpagemanager.h"
4 andreas 69
#include "tcolor.h"
3 andreas 70
#include "terror.h"
8 andreas 71
#include "ticons.h"
14 andreas 72
#include "tbutton.h"
8 andreas 73
#include "tprjresources.h"
11 andreas 74
#include "tresources.h"
271 andreas 75
#include "tresources.h"
71 andreas 76
#include "tsystemsound.h"
77
#include "tvalidatefile.h"
122 andreas 78
#include "ttpinit.h"
211 andreas 79
#include "tconfig.h"
299 andreas 80
#include "tlock.h"
336 andreas 81
#include "tintborder.h"
264 andreas 82
#ifdef Q_OS_IOS
83
#include "ios/tiosbattery.h"
84
#endif
326 andreas 85
#if TESTMODE == 1
86
#include "testmode.h"
87
#endif
3 andreas 88
 
89
using std::vector;
90
using std::string;
11 andreas 91
using std::map;
92
using std::pair;
93
using std::to_string;
14 andreas 94
using std::thread;
95
using std::atomic;
96
using std::mutex;
21 andreas 97
using std::bind;
3 andreas 98
 
8 andreas 99
TIcons *gIcons = nullptr;
100
TPrjResources *gPrjResources = nullptr;
14 andreas 101
TPageManager *gPageManager = nullptr;
169 andreas 102
//std::vector<amx::ANET_COMMAND> TPageManager::mCommands;
103
 
14 andreas 104
extern amx::TAmxNet *gAmxNet;
90 andreas 105
extern std::atomic<bool> _netRunning;
92 andreas 106
extern bool _restart_;                          //!< If this is set to true then the whole program will start over.
8 andreas 107
 
21 andreas 108
bool prg_stopped = false;
14 andreas 109
 
37 andreas 110
#ifdef __ANDROID__
255 andreas 111
string javaJStringToString(JNIEnv *env, jstring str)
112
{
113
    if (!str)
114
        return string();
115
 
116
    const jclass stringClass = env->GetObjectClass(str);
117
    const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
118
    const jbyteArray stringJbytes = (jbyteArray) env->CallObjectMethod(str, 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
    return ret;
129
}
130
 
38 andreas 131
JNIEXPORT void JNICALL Java_org_qtproject_theosys_BatteryState_informBatteryStatus(JNIEnv *, jclass, jint level, jboolean charging, jint chargeType)
132
{
61 andreas 133
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_BatteryState_informBatteryStatus(JNIEnv *, jclass, jint level, jboolean charging, jint chargeType)");
134
 
38 andreas 135
    if (gPageManager)
136
        gPageManager->informBatteryStatus(level, charging, chargeType);
137
}
138
 
36 andreas 139
JNIEXPORT void JNICALL Java_org_qtproject_theosys_NetworkStatus_informTPanelNetwork(JNIEnv */*env*/, jclass /*clazz*/, jboolean conn, jint level, jint type)
140
{
61 andreas 141
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_NetworkStatus_informTPanelNetwork(JNIEnv */*env*/, jclass /*clazz*/, jboolean conn, jint level, jint type)");
365 andreas 142
 
143
    //Call native side conterpart
144
    if (gPageManager)
36 andreas 145
        gPageManager->informTPanelNetwork(conn, level, type);
146
}
47 andreas 147
 
61 andreas 148
JNIEXPORT void JNICALL Java_org_qtproject_theosys_PhoneCallState_informPhoneState(JNIEnv *env, jclass, jboolean call, jstring pnumber)
47 andreas 149
{
61 andreas 150
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_PhoneCallState_informPhoneState(JNIEnv *env, jclass, jboolean call, jstring pnumber)");
151
 
152
    string phoneNumber;
153
 
154
    if (pnumber)
255 andreas 155
        phoneNumber = javaJStringToString(env, pnumber);
61 andreas 156
 
157
    if (gPageManager)
158
        gPageManager->informPhoneState(call, phoneNumber);
47 andreas 159
}
160
 
61 andreas 161
JNIEXPORT void JNICALL Java_org_qtproject_theosys_Logger_logger(JNIEnv *env, jclass, jint mode, jstring msg)
47 andreas 162
{
163
    if (!msg)
164
        return;
165
 
255 andreas 166
    string ret = javaJStringToString(env, msg);
47 andreas 167
 
61 andreas 168
    try
169
    {
170
        if (TStreamError::checkFilter(mode))
260 andreas 171
        {
172
            *TError::Current()->getStream() << TError::append(mode) << ret << std::endl;
173
            TStreamError::resetFlags();
174
        }
61 andreas 175
    }
176
    catch (std::exception& e)
177
    {
178
        __android_log_print(ANDROID_LOG_ERROR, "tpanel", "%s", e.what());
179
    }
47 andreas 180
}
130 andreas 181
 
182
JNIEXPORT void JNICALL Java_org_qtproject_theosys_Orientation_informTPanelOrientation(JNIEnv */*env*/, jclass /*clazz*/, jint orientation)
183
{
184
    DECL_TRACER("Java_org_qtproject_theosys_Orientation_informTPanelOrientation(JNIEnv */*env*/, jclass /*clazz*/, jint orientation)");
185
 
134 andreas 186
    if (!gPageManager)
187
        return;
188
 
189
    if (gPageManager->onOrientationChange())
130 andreas 190
        gPageManager->onOrientationChange()(orientation);
134 andreas 191
 
192
    gPageManager->setOrientation(orientation);
193
 
194
    if (gPageManager->getInformOrientation())
195
        gPageManager->sendOrientation();
130 andreas 196
}
255 andreas 197
 
198
/* -------- Settings -------- */
256 andreas 199
 
200
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_saveSettings(JNIEnv *env, jclass clazz)
255 andreas 201
{
256 andreas 202
    DECL_TRACER("Java_org_qtproject_theosys_SettingsActivity_saveSettings(JNIEnv *env, jclass clazz)");
255 andreas 203
 
256 andreas 204
    Q_UNUSED(env);
255 andreas 205
    Q_UNUSED(clazz);
206
 
259 andreas 207
    TConfig::setTemporary(true);
208
    string oldNetlinx = TConfig::getController();
209
    int oldPort = TConfig::getPort();
210
    int oldChannelID = TConfig::getChannel();
211
    string oldSurface = TConfig::getFtpSurface();
212
    bool oldToolbarSuppress = TConfig::getToolbarSuppress();
213
    bool oldToolbarForce = TConfig::getToolbarForce();
214
    TConfig::setTemporary(false);
215
    MSG_DEBUG("Old values:\n" <<
216
              "   NetLinx: " << oldNetlinx << "\n" <<
217
              "   Port:    " << oldPort << "\n" <<
218
              "   Channel: " << oldChannelID << "\n" <<
219
              "   Surface: " << oldSurface << "\n" <<
220
              "   TB suppr:" << oldToolbarSuppress << "\n" <<
221
              "   TB force:" << oldToolbarForce);
256 andreas 222
    TConfig::saveSettings();
259 andreas 223
 
224
    MSG_DEBUG("New values:\n" <<
225
              "   NetLinx: " << TConfig::getController() << "\n" <<
226
              "   Port:    " << TConfig::getPort() << "\n" <<
227
              "   Channel: " << TConfig::getChannel() << "\n" <<
228
              "   Surface: " << TConfig::getFtpSurface() << "\n" <<
229
              "   TB suppr:" << TConfig::getToolbarSuppress() << "\n" <<
230
              "   TB force:" << TConfig::getToolbarForce());
231
 
232
    if (gPageManager && gPageManager->onSettingsChanged())
233
        gPageManager->onSettingsChanged()(oldNetlinx, oldPort, oldChannelID, oldSurface, oldToolbarSuppress, oldToolbarForce);
256 andreas 234
}
235
 
236
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxIp(JNIEnv *env, jclass clazz, jstring ip)
237
{
238
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxIp(JNIEnv *env, jclass clazz, jstring ip)");
239
 
240
    Q_UNUSED(clazz);
241
 
255 andreas 242
    string netlinxIp = javaJStringToString(env, ip);
243
 
244
    if (TConfig::getController() != netlinxIp)
245
        TConfig::saveController(netlinxIp);
246
}
247
 
256 andreas 248
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxPort(JNIEnv *env, jclass clazz, jint port)
255 andreas 249
{
256 andreas 250
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxPort(JNIEnv *env, jclass clazz, jint port)");
255 andreas 251
 
252
    Q_UNUSED(env);
253
    Q_UNUSED(clazz);
254
 
255
    if (port > 0 && port < 65535 && TConfig::getPort() != port)
256
        TConfig::savePort(port);
257
}
258
 
256 andreas 259
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxChannel(JNIEnv *env, jclass clazz, jint channel)
255 andreas 260
{
256 andreas 261
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxChannel(JNIEnv *env, jclass clazz, jint channel)");
255 andreas 262
 
263
    Q_UNUSED(env);
264
    Q_UNUSED(clazz);
265
 
266
    if (channel >= 10000 && channel < 20000 && TConfig::getChannel() != channel)
271 andreas 267
        TConfig::saveChannel(channel);
255 andreas 268
}
256 andreas 269
 
270
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxType(JNIEnv *env, jclass clazz, jstring type)
271
{
272
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxType(JNIEnv *env, jclass clazz, jstring type)");
273
 
274
    Q_UNUSED(clazz);
275
 
276
    string netlinxType = javaJStringToString(env, type);
277
 
278
    if (TConfig::getPanelType() != netlinxType)
279
        TConfig::savePanelType(netlinxType);
280
}
281
 
282
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxFtpUser(JNIEnv *env, jclass clazz, jstring user)
283
{
284
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxFtpUser(JNIEnv *env, jclass clazz, jstring user)");
285
 
286
    Q_UNUSED(clazz);
287
 
288
    string netlinxFtpUser = javaJStringToString(env, user);
289
 
290
    if (TConfig::getFtpUser() != netlinxFtpUser)
291
        TConfig::saveFtpUser(netlinxFtpUser);
292
}
293
 
294
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxFtpPassword(JNIEnv *env, jclass clazz, jstring pw)
295
{
296
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxFtpPassword(JNIEnv *env, jclass clazz, jstring pw)");
297
 
298
    Q_UNUSED(clazz);
299
 
300
    string netlinxPw = javaJStringToString(env, pw);
301
 
302
    if (TConfig::getFtpPassword() != netlinxPw)
303
        TConfig::saveFtpPassword(netlinxPw);
304
}
305
 
306
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxSurface(JNIEnv *env, jclass clazz, jstring surface)
307
{
308
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxIp(JNIEnv *env, jclass clazz, jstring surface)");
309
 
310
    Q_UNUSED(clazz);
311
 
312
    string netlinxSurface = javaJStringToString(env, surface);
313
 
314
    if (TConfig::getFtpSurface() != netlinxSurface)
315
        TConfig::saveFtpSurface(netlinxSurface);
316
}
317
 
318
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxFtpPassive(JNIEnv *env, jclass clazz, jboolean passive)
319
{
320
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxIp(JNIEnv *env, jclass clazz, jboolean passive)");
321
 
322
    Q_UNUSED(env);
323
    Q_UNUSED(clazz);
324
 
325
    if (TConfig::getFtpPassive() != passive)
326
        TConfig::saveFtpPassive(passive);
327
}
328
 
329
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setViewScale(JNIEnv *env, jclass clazz, jboolean scale)
330
{
331
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setViewScale(JNIEnv *env, jclass clazz, jboolean scale)");
332
 
333
    Q_UNUSED(env);
334
    Q_UNUSED(clazz);
335
 
336
    if (TConfig::getScale() != scale)
337
        TConfig::saveScale(scale);
338
}
339
 
340
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setViewToolbar(JNIEnv *env, jclass clazz, jboolean bar)
341
{
342
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setViewToolbar(JNIEnv *env, jclass clazz, jboolean bar)");
343
 
344
    Q_UNUSED(env);
345
    Q_UNUSED(clazz);
346
 
260 andreas 347
    if (TConfig::getToolbarSuppress() == bar)
348
        TConfig::saveToolbarSuppress(!bar);
256 andreas 349
}
350
 
351
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setViewToolbarForce(JNIEnv *env, jclass clazz, jboolean bar)
352
{
353
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setViewToolbarForce(JNIEnv *env, jclass clazz, jboolean bar)");
354
 
355
    Q_UNUSED(env);
356
    Q_UNUSED(clazz);
357
 
358
    if (TConfig::getToolbarForce() != bar)
359
        TConfig::saveToolbarForce(bar);
360
}
361
 
362
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setViewRotation(JNIEnv *env, jclass clazz, jboolean rotate)
363
{
364
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setViewRotation(JNIEnv *env, jclass clazz, jboolean rotate)");
365
 
366
    Q_UNUSED(env);
367
    Q_UNUSED(clazz);
368
 
369
    if (TConfig::getRotationFixed() != rotate)
370
        TConfig::setRotationFixed(rotate);
371
}
372
 
373
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundSystem(JNIEnv *env, jclass clazz, jstring sound)
374
{
375
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundSystem(JNIEnv *env, jclass clazz, jstring sound)");
376
 
377
    Q_UNUSED(clazz);
378
 
379
    string s = javaJStringToString(env, sound);
380
 
381
    if (TConfig::getSystemSound() != s)
382
        TConfig::saveSystemSoundFile(s);
383
}
384
 
385
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundSingle(JNIEnv *env, jclass clazz, jstring sound)
386
{
387
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundSingle(JNIEnv *env, jclass clazz, jstring sound)");
388
 
389
    Q_UNUSED(clazz);
390
 
391
    string s = javaJStringToString(env, sound);
392
 
393
    if (TConfig::getSingleBeepSound() != s)
394
        TConfig::saveSingleBeepFile(s);
395
}
396
 
397
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundDouble(JNIEnv *env, jclass clazz, jstring sound)
398
{
399
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundDouble(JNIEnv *env, jclass clazz, jstring sound)");
400
 
401
    Q_UNUSED(clazz);
402
 
403
    string s = javaJStringToString(env, sound);
404
 
405
    if (TConfig::getDoubleBeepSound() != s)
406
        TConfig::saveDoubleBeepFile(s);
407
}
408
 
409
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundEnable(JNIEnv *env, jclass clazz, jboolean sound)
410
{
411
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundEnable(JNIEnv *env, jclass clazz, jboolean sound)");
412
 
413
    Q_UNUSED(env);
414
    Q_UNUSED(clazz);
415
 
416
    if (TConfig::getSystemSoundState() != sound)
417
        TConfig::saveSystemSoundState(sound);
418
}
419
 
420
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundVolume(JNIEnv *env, jclass clazz, jint sound)
421
{
422
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundVolume(JNIEnv *env, jclass clazz, jint sound)");
423
 
424
    Q_UNUSED(env);
425
    Q_UNUSED(clazz);
426
 
427
    if (TConfig::getSystemVolume() != sound)
428
        TConfig::saveSystemVolume(sound);
429
}
430
 
431
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundGain(JNIEnv *env, jclass clazz, jint sound)
432
{
433
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundGain(JNIEnv *env, jclass clazz, jint sound)");
434
 
435
    Q_UNUSED(env);
436
    Q_UNUSED(clazz);
437
 
438
    if (TConfig::getSystemGain() != sound)
439
        TConfig::saveSystemGain(sound);
440
}
257 andreas 441
 
442
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipProxy(JNIEnv *env, jclass clazz, jstring sip)
443
{
444
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipProxy(JNIEnv *env, jclass clazz, jstring sip)");
445
 
446
    Q_UNUSED(clazz);
447
 
448
    string sipStr = javaJStringToString(env, sip);
449
 
450
    if (TConfig::getSIPproxy() != sipStr)
451
        TConfig::setSIPproxy(sipStr);
452
}
453
 
454
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipPort(JNIEnv *env, jclass clazz, jint sip)
455
{
456
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipPort(JNIEnv *env, jclass clazz, jint sip)");
457
 
458
    Q_UNUSED(env);
459
    Q_UNUSED(clazz);
460
 
461
    if (TConfig::getSIPport() != sip)
462
        TConfig::setSIPport(sip);
463
}
464
 
465
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipTlsPort(JNIEnv *env, jclass clazz, jint sip)
466
{
467
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipTlsPort(JNIEnv *env, jclass clazz, jint sip)");
468
 
469
    Q_UNUSED(env);
470
    Q_UNUSED(clazz);
471
 
472
    if (TConfig::getSIPportTLS() != sip)
473
        TConfig::setSIPportTLS(sip);
474
}
475
 
476
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipStun(JNIEnv *env, jclass clazz, jstring sip)
477
{
478
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipStun(JNIEnv *env, jclass clazz, jstring sip)");
479
 
480
    Q_UNUSED(clazz);
481
 
482
    string sipStr = javaJStringToString(env, sip);
483
 
484
    if (TConfig::getSIPstun() != sipStr)
485
        TConfig::setSIPstun(sipStr);
486
}
487
 
488
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipDomain(JNIEnv *env, jclass clazz, jstring sip)
489
{
490
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipDomain(JNIEnv *env, jclass clazz, jstring sip)");
491
 
492
    Q_UNUSED(clazz);
493
 
494
    string sipStr = javaJStringToString(env, sip);
495
 
496
    if (TConfig::getSIPdomain() != sipStr)
497
        TConfig::setSIPdomain(sipStr);
498
}
499
 
500
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipUser(JNIEnv *env, jclass clazz, jstring sip)
501
{
502
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipUser(JNIEnv *env, jclass clazz, jstring sip)");
503
 
504
    Q_UNUSED(clazz);
505
 
506
    string sipStr = javaJStringToString(env, sip);
507
 
508
    if (TConfig::getSIPuser() != sipStr)
509
        TConfig::setSIPuser(sipStr);
510
}
511
 
512
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipPassword(JNIEnv *env, jclass clazz, jstring sip)
513
{
514
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipPassword(JNIEnv *env, jclass clazz, jstring sip)");
515
 
516
    Q_UNUSED(clazz);
517
 
518
    string sipStr = javaJStringToString(env, sip);
519
 
520
    if (TConfig::getSIPpassword() != sipStr)
521
        TConfig::setSIPpassword(sipStr);
522
}
523
 
524
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipIpv4(JNIEnv *env, jclass clazz, jboolean sip)
525
{
526
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipIpv4(JNIEnv *env, jclass clazz, jboolean sip)");
527
 
528
    Q_UNUSED(env);
529
    Q_UNUSED(clazz);
530
 
531
    if (TConfig::getSIPnetworkIPv4() != sip)
532
        TConfig::setSIPnetworkIPv4(sip);
533
}
534
 
535
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipIpv6(JNIEnv *env, jclass clazz, jboolean sip)
536
{
537
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipIpv6(JNIEnv *env, jclass clazz, jboolean sip)");
538
 
539
    Q_UNUSED(env);
540
    Q_UNUSED(clazz);
541
 
542
    if (TConfig::getSIPnetworkIPv6() != sip)
543
        TConfig::setSIPnetworkIPv6(sip);
544
}
545
 
546
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipEnabled(JNIEnv *env, jclass clazz, jboolean sip)
547
{
548
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipEnabled(JNIEnv *env, jclass clazz, jboolean sip)");
549
 
550
    Q_UNUSED(env);
551
    Q_UNUSED(clazz);
552
 
553
    if (TConfig::getSIPstatus() != sip)
554
        TConfig::setSIPstatus(sip);
555
}
556
 
557
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipIphone(JNIEnv *env, jclass clazz, jboolean sip)
558
{
559
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipIphone(JNIEnv *env, jclass clazz, jboolean sip)");
560
 
561
    Q_UNUSED(env);
562
    Q_UNUSED(clazz);
563
 
564
    if (TConfig::getSIPiphone() != sip)
565
        TConfig::setSIPiphone(sip);
566
}
567
 
568
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogInfo(JNIEnv *env, jclass clazz, jboolean log)
569
{
570
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogInfo(JNIEnv *env, jclass clazz, jboolean log)");
571
 
572
    Q_UNUSED(env);
573
    Q_UNUSED(clazz);
574
 
575
    uint logSwitch = (log ? HLOG_INFO : 0);
576
 
577
    if ((TConfig::getLogLevelBits() & HLOG_INFO) != logSwitch)
578
    {
579
        if (!(TConfig::getLogLevelBits() & HLOG_INFO))
580
            TConfig::saveLogLevel(TConfig::getLogLevelBits() | HLOG_INFO);
581
        else
582
            TConfig::saveLogLevel(TConfig::getLogLevelBits() ^ HLOG_INFO);
583
    }
584
}
585
 
586
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogWarning(JNIEnv *env, jclass clazz, jboolean log)
587
{
588
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogWarning(JNIEnv *env, jclass clazz, jboolean log)");
589
 
590
    Q_UNUSED(env);
591
    Q_UNUSED(clazz);
592
 
593
    uint logSwitch = (log ? HLOG_WARNING : 0);
594
 
595
    if ((TConfig::getLogLevelBits() & HLOG_WARNING) != logSwitch)
596
    {
597
        if (!(TConfig::getLogLevelBits() & HLOG_INFO))
598
            TConfig::saveLogLevel(TConfig::getLogLevelBits() | HLOG_WARNING);
599
        else
600
            TConfig::saveLogLevel(TConfig::getLogLevelBits() ^ HLOG_WARNING);
601
    }
602
}
603
 
604
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogError(JNIEnv *env, jclass clazz, jboolean log)
605
{
606
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogError(JNIEnv *env, jclass clazz, jboolean log)");
607
 
608
    Q_UNUSED(env);
609
    Q_UNUSED(clazz);
610
 
611
    uint logSwitch = (log ? HLOG_ERROR : 0);
612
 
613
    if ((TConfig::getLogLevelBits() & HLOG_ERROR) != logSwitch)
614
    {
615
        if (!(TConfig::getLogLevelBits() & HLOG_ERROR))
616
            TConfig::saveLogLevel(TConfig::getLogLevelBits() | HLOG_ERROR);
617
        else
618
            TConfig::saveLogLevel(TConfig::getLogLevelBits() ^ HLOG_ERROR);
619
    }
620
}
621
 
622
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogTrace(JNIEnv *env, jclass clazz, jboolean log)
623
{
624
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogTrace(JNIEnv *env, jclass clazz, jboolean log)");
625
 
626
    Q_UNUSED(env);
627
    Q_UNUSED(clazz);
628
 
629
    uint logSwitch = (log ? HLOG_TRACE : 0);
630
 
631
    if ((TConfig::getLogLevelBits() & HLOG_TRACE) != logSwitch)
632
    {
633
        if (!(TConfig::getLogLevelBits() & HLOG_TRACE))
634
            TConfig::saveLogLevel(TConfig::getLogLevelBits() | HLOG_TRACE);
635
        else
636
            TConfig::saveLogLevel(TConfig::getLogLevelBits() ^ HLOG_TRACE);
637
    }
638
}
639
 
640
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogDebug(JNIEnv *env, jclass clazz, jboolean log)
641
{
642
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogDebug(JNIEnv *env, jclass clazz, jboolean log)");
643
 
644
    Q_UNUSED(env);
645
    Q_UNUSED(clazz);
646
 
647
    uint logSwitch = (log ? HLOG_DEBUG : 0);
648
 
649
    if ((TConfig::getLogLevelBits() & HLOG_DEBUG) != logSwitch)
650
    {
651
        if (!(TConfig::getLogLevelBits() & HLOG_DEBUG))
652
            TConfig::saveLogLevel(TConfig::getLogLevelBits() | HLOG_DEBUG);
653
        else
654
            TConfig::saveLogLevel(TConfig::getLogLevelBits() ^ HLOG_DEBUG);
655
    }
656
}
657
 
658
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogProfile(JNIEnv *env, jclass clazz, jboolean log)
659
{
660
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogProfile(JNIEnv *env, jclass clazz, jboolean log)");
661
 
662
    Q_UNUSED(env);
663
    Q_UNUSED(clazz);
664
 
665
    if (TConfig::getProfiling() != log)
666
        TConfig::saveProfiling(log);
667
}
668
 
669
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogLongFormat(JNIEnv *env, jclass clazz, jboolean log)
670
{
671
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogLongFormat(JNIEnv *env, jclass clazz, jboolean log)");
672
 
673
    Q_UNUSED(env);
674
    Q_UNUSED(clazz);
675
 
676
    if (TConfig::isLongFormat() != log)
677
        TConfig::saveFormat(log);
678
}
679
 
680
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogEnableFile(JNIEnv *env, jclass clazz, jboolean log)
681
{
682
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogEnableFile(JNIEnv *env, jclass clazz, jboolean log)");
683
 
684
    Q_UNUSED(env);
685
    Q_UNUSED(clazz);
686
 
383 andreas 687
    TConfig::setLogFileEnabled(log);
385 andreas 688
    TStreamError::setLogFileEnabled(log);
689
    string logFile = TConfig::getLogFile();
383 andreas 690
 
385 andreas 691
    if (log && !logFile.empty() && fs::is_regular_file(logFile))
692
        TStreamError::setLogFile(logFile);
693
    else if (!log)
694
        TStreamError::setLogFile("");
383 andreas 695
 
385 andreas 696
    __android_log_print(ANDROID_LOG_DEBUG, "tpanel", "JAVA::setLogEnableFile: Logfile was %s", (log ? "ENABLED" : "DISABLED"));
257 andreas 697
}
698
 
699
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogFile(JNIEnv *env, jclass clazz, jstring log)
700
{
701
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogFile(JNIEnv *env, jclass clazz, jstring sip)");
702
 
703
    Q_UNUSED(clazz);
704
 
705
    string logStr = javaJStringToString(env, log);
706
 
707
    if (TConfig::getLogFile() != logStr)
385 andreas 708
    {
257 andreas 709
        TConfig::saveLogFile(logStr);
385 andreas 710
        __android_log_print(ANDROID_LOG_DEBUG, "tpanel", "JAVA::setLogFile: Logfile set to: %s", logStr.c_str());
711
 
712
        if (fs::is_regular_file(logStr))
713
            TStreamError::setLogFile(logStr);
714
        else
715
        {
716
            TStreamError::setLogFile("");
717
            __android_log_print(ANDROID_LOG_WARN, "tpanel", "JAVA::setLogFile: Logfile \"%s\" is not accessible!", logStr.c_str());
718
        }
719
    }
257 andreas 720
}
397 andreas 721
 
722
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setPassword1(JNIEnv *env, jclass clazz, jstring pw)
723
{
724
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_SettingsActivity_setPassword1(JNIEnv *env, jclass clazz, jstring pw)");
725
 
726
    Q_UNUSED(clazz);
727
 
728
    string password = javaJStringToString(env, pw);
729
    TConfig::savePassword1(password);
730
}
731
 
732
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setPassword2(JNIEnv *env, jclass clazz, jstring pw)
733
{
734
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_SettingsActivity_setPassword2(JNIEnv *env, jclass clazz, jstring pw)");
735
 
736
    Q_UNUSED(clazz);
737
 
738
    string password = javaJStringToString(env, pw);
739
    TConfig::savePassword2(password);
740
}
741
 
742
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setPassword3(JNIEnv *env, jclass clazz, jstring pw)
743
{
744
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_SettingsActivity_setPassword3(JNIEnv *env, jclass clazz, jstring pw)");
745
 
746
    Q_UNUSED(clazz);
747
 
748
    string password = javaJStringToString(env, pw);
749
    TConfig::savePassword3(password);
750
}
751
 
752
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setPassword4(JNIEnv *env, jclass clazz, jstring pw)
753
{
754
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_SettingsActivity_setPassword4(JNIEnv *env, jclass clazz, jstring pw)");
755
 
756
    Q_UNUSED(clazz);
757
 
758
    string password = javaJStringToString(env, pw);
759
    TConfig::savePassword4(password);
760
}
37 andreas 761
#endif
36 andreas 762
 
3 andreas 763
TPageManager::TPageManager()
764
{
299 andreas 765
    TLOCKER(surface_mutex);
3 andreas 766
    DECL_TRACER("TPageManager::TPageManager()");
767
 
14 andreas 768
    gPageManager = this;
122 andreas 769
    TTPInit *tinit = new TTPInit;
186 andreas 770
    string projectPath = TConfig::getProjectPath();
197 andreas 771
    string pp = projectPath + "/prj.xma";
186 andreas 772
 
773
    tinit->setPath(projectPath);
156 andreas 774
    bool haveSurface = false;
122 andreas 775
 
776
    if (tinit->isVirgin())
156 andreas 777
        haveSurface = tinit->loadSurfaceFromController();
778
    else
779
        haveSurface = true;
122 andreas 780
 
197 andreas 781
    if (!fs::exists(pp))
193 andreas 782
    {
197 andreas 783
        projectPath = TConfig::getSystemProjectPath();
784
        pp = projectPath + "/prj.xma";
193 andreas 785
        mSetupActive = true;
786
    }
186 andreas 787
 
156 andreas 788
    if (!haveSurface)
789
    {
271 andreas 790
        if (!isValidFile(pp))
791
            tinit->reinitialize();
156 andreas 792
    }
159 andreas 793
    else
794
        tinit->makeSystemFiles();
156 andreas 795
 
122 andreas 796
    delete tinit;
156 andreas 797
 
43 andreas 798
    // Read the AMX panel settings.
186 andreas 799
    mTSettings = new TSettings(projectPath);
3 andreas 800
 
801
    if (TError::isError())
14 andreas 802
    {
23 andreas 803
        MSG_ERROR("Settings were not read successfull!");
3 andreas 804
        return;
14 andreas 805
    }
3 andreas 806
 
193 andreas 807
    if (!mSetupActive)
808
    {
197 andreas 809
        mSystemSettings = new TSettings(TConfig::getSystemProjectPath());
193 andreas 810
 
811
        if (TError::isError())
812
        {
813
            MSG_ERROR("System settings were not read successfull!");
814
            delete mTSettings;
815
            mTSettings = nullptr;
816
            return;
817
        }
818
    }
819
    else
820
        mSystemSettings = mTSettings;
821
 
178 andreas 822
    // Set the panel type from the project information
193 andreas 823
    if (!mSetupActive)
824
        TConfig::savePanelType(mTSettings->getPanelType());
178 andreas 825
 
122 andreas 826
    readMap();  // Start the initialisation of the AMX part.
827
 
8 andreas 828
    gPrjResources = new TPrjResources(mTSettings->getResourcesList());
4 andreas 829
    mPalette = new TPalette();
830
    vector<PALETTE_SETUP> pal = mTSettings->getSettings().palettes;
831
 
83 andreas 832
    if (pal.size() > 0)
833
    {
834
        vector<PALETTE_SETUP>::iterator iterPal;
4 andreas 835
 
118 andreas 836
        for (iterPal = pal.begin(); iterPal != pal.end(); ++iterPal)
83 andreas 837
            mPalette->initialize(iterPal->file);
838
    }
839
 
4 andreas 840
    if (!TError::isError())
841
        TColor::setPalette(mPalette);
842
 
7 andreas 843
    mFonts = new TFont();
844
 
845
    if (TError::isError())
846
    {
847
        MSG_ERROR("Initializing fonts was not successfull!");
848
    }
849
 
8 andreas 850
    gIcons = new TIcons();
851
 
852
    if (TError::isError())
853
    {
854
        MSG_ERROR("Initializing icons was not successfull!");
855
    }
856
 
3 andreas 857
    mPageList = new TPageList();
32 andreas 858
    mExternal = new TExternal();
4 andreas 859
    PAGELIST_T page;
860
 
194 andreas 861
    if (!mSetupActive)
3 andreas 862
    {
194 andreas 863
        if (!mTSettings->getSettings().powerUpPage.empty())
14 andreas 864
        {
194 andreas 865
            if (readPage(mTSettings->getSettings().powerUpPage))
866
            {
867
                MSG_TRACE("Found power up page " << mTSettings->getSettings().powerUpPage);
868
                page = findPage(mTSettings->getSettings().powerUpPage);
869
                mActualPage = page.pageID;
870
            }
14 andreas 871
        }
194 andreas 872
        else
873
        {
874
            MSG_WARNING("No power up page defined! Setting default page to 1.");
875
            mActualPage = 1;
876
        }
3 andreas 877
    }
23 andreas 878
    else
879
    {
194 andreas 880
        if (!mSystemSettings->getSettings().powerUpPage.empty())
881
        {
882
            if (readPage(mSystemSettings->getSettings().powerUpPage))
883
            {
884
                MSG_TRACE("Found power up page " << mSystemSettings->getSettings().powerUpPage);
885
                page = findPage(mSystemSettings->getSettings().powerUpPage);
886
                mActualPage = page.pageID;
887
            }
888
        }
889
        else
890
        {
891
            MSG_WARNING("No power up page defined! Setting default page to 5001.");
892
            mActualPage = 5001;
893
        }
23 andreas 894
    }
3 andreas 895
 
4 andreas 896
    TPage *pg = getPage(mActualPage);
897
 
194 andreas 898
    vector<string> popups;
3 andreas 899
 
194 andreas 900
    if (!mSetupActive)
901
        popups = mTSettings->getSettings().powerUpPopup;
902
    else
903
        popups = mSystemSettings->getSettings().powerUpPopup;
904
 
83 andreas 905
    if (popups.size() > 0)
3 andreas 906
    {
83 andreas 907
        vector<string>::iterator iter;
908
 
118 andreas 909
        for (iter = popups.begin(); iter != popups.end(); ++iter)
14 andreas 910
        {
88 andreas 911
            if (readSubPage(*iter))
83 andreas 912
            {
88 andreas 913
                MSG_TRACE("Found power up popup " << *iter);
3 andreas 914
 
88 andreas 915
                if (pg)
916
                {
917
                    TSubPage *spage = getSubPage(*iter);
350 andreas 918
                    spage->setParent(pg->getHandle());
88 andreas 919
                    pg->addSubPage(spage);
920
                }
83 andreas 921
            }
4 andreas 922
        }
3 andreas 923
    }
11 andreas 924
 
73 andreas 925
    // Here we initialize the system resources like borders, cursors, sliders, ...
926
    mSystemDraw = new TSystemDraw(TConfig::getSystemPath(TConfig::BASE));
927
 
928
    // Here are the commands supported by this emulation.
13 andreas 929
    MSG_INFO("Registering commands ...");
318 andreas 930
    REG_CMD(doLEVON, "LEVON");  // Enable device to send level changes to the master.
931
    REG_CMD(doLEVOF, "LEVOF");  // Disable the device from sending level changes to the master.
932
    REG_CMD(doRXON, "RXON");    // Enable device to send STRING changes to the master.
933
    REG_CMD(doRXOF, "RXOF");    // Disable the device from sending STRING changes to the master.
147 andreas 934
    REG_CMD(doAFP, "@AFP");     // Flips to a page with the specified page name using an animated transition.
935
    REG_CMD(doAFP, "^AFP");     // Flips to a page with the specified page name using an animated transition.
38 andreas 936
    REG_CMD(doAPG, "@APG");     // Add a specific popup page to a specified popup group.
937
    REG_CMD(doCPG, "@CPG");     // Clear all popup pages from specified popup group.
938
    REG_CMD(doDPG, "@DPG");     // Delete a specific popup page from specified popup group if it exists
939
//    REG_CMD(doPDR, "@PDR");     // Set the popup location reset flag.
940
    REG_CMD(doPHE, "@PHE");     // Set the hide effect for the specified popup page to the named hide effect.
941
    REG_CMD(doPHP, "@PHP");     // Set the hide effect position.
942
    REG_CMD(doPHT, "@PHT");     // Set the hide effect time for the specified popup page.
943
    REG_CMD(doPPA, "@PPA");     // Close all popups on a specified page.
104 andreas 944
    REG_CMD(doPPA, "^PPA");     // G5: Close all popups on a specified page.
38 andreas 945
    REG_CMD(doPPF, "@PPF");     // Deactivate a specific popup page on either a specified page or the current page.
104 andreas 946
    REG_CMD(doPPF, "^PPF");     // G5: Deactivate a specific popup page on either a specified page or the current page.
38 andreas 947
    REG_CMD(doPPF, "PPOF");     // Deactivate a specific popup page on either a specified page or the current page
948
    REG_CMD(doPPG, "@PPG");     // Toggle a specific popup page on either a specified page or the current page.
104 andreas 949
    REG_CMD(doPPG, "^PPG");     // G5: Toggle a specific popup page on either a specified page or the current page.
38 andreas 950
    REG_CMD(doPPG, "PPOG");     // Toggle a specific popup page on either a specified page or the current page.
951
    REG_CMD(doPPK, "@PPK");     // Kill a specific popup page from all pages.
104 andreas 952
    REG_CMD(doPPK, "^PPK");     // G5: Kill a specific popup page from all pages.
38 andreas 953
    REG_CMD(doPPM, "@PPM");     // Set the modality of a specific popup page to Modal or NonModal.
104 andreas 954
    REG_CMD(doPPM, "^PPM");     // G5: Set the modality of a specific popup page to Modal or NonModal.
38 andreas 955
    REG_CMD(doPPN, "@PPN");     // Activate a specific popup page to launch on either a specified page or the current page.
104 andreas 956
    REG_CMD(doPPN, "^PPN");     // G5: Activate a specific popup page to launch on either a specified page or the current page.
38 andreas 957
    REG_CMD(doPPN, "PPON");     // Activate a specific popup page to launch on either a specified page or the current page.
958
    REG_CMD(doPPT, "@PPT");     // Set a specific popup page to timeout within a specified time.
104 andreas 959
    REG_CMD(doPPT, "^PPT");     // G5: Set a specific popup page to timeout within a specified time.
38 andreas 960
    REG_CMD(doPPX, "@PPX");     // Close all popups on all pages.
104 andreas 961
    REG_CMD(doPPX, "^PPX");     // G5: Close all popups on all pages.
38 andreas 962
    REG_CMD(doPSE, "@PSE");     // Set the show effect for the specified popup page to the named show effect.
963
    REG_CMD(doPSP, "@PSP");     // Set the show effect position.
964
    REG_CMD(doPST, "@PST");     // Set the show effect time for the specified popup page.
965
    REG_CMD(doPAGE, "PAGE");    // Flip to a specified page.
104 andreas 966
    REG_CMD(doPAGE, "^PGE");    // G5: Flip to a specified page.
11 andreas 967
 
38 andreas 968
    REG_CMD(doANI, "^ANI");     // Run a button animation (in 1/10 second).
969
    REG_CMD(doAPF, "^APF");     // Add page flip action to a button if it does not already exist.
43 andreas 970
    REG_CMD(doBAT, "^BAT");     // Append non-unicode text.
60 andreas 971
    REG_CMD(doBAU, "^BAU");     // Append unicode text. Same format as ^UNI.
43 andreas 972
    REG_CMD(doBCB, "^BCB");     // Set the border color.
82 andreas 973
    REG_CMD(getBCB, "?BCB");    // Get the current border color.
60 andreas 974
    REG_CMD(doBCF, "^BCF");     // Set the fill color to the specified color.
82 andreas 975
    REG_CMD(getBCF, "?BCF");    // Get the current fill color.
60 andreas 976
    REG_CMD(doBCT, "^BCT");     // Set the text color to the specified color.
82 andreas 977
    REG_CMD(getBCT, "?BCT");    // Get the current text color.
60 andreas 978
    REG_CMD(doBDO, "^BDO");     // Set the button draw order
979
    REG_CMD(doBFB, "^BFB");     // Set the feedback type of the button.
224 andreas 980
    REG_CMD(doBIM, "^BIM");     // Set the input mask for the specified address
149 andreas 981
    REG_CMD(doBMC, "^BMC");     // Button copy command.
982
    REG_CMD(doBMF, "^BMF");     // Button Modify Command - Set any/all button parameters by sending embedded codes and data.
106 andreas 983
//    REG_CMD(doBMI, "^BMI");    // Set the button mask image.
149 andreas 984
    REG_CMD(doBML, "^BML");     // Set the maximum length of the text area button.
38 andreas 985
    REG_CMD(doBMP, "^BMP");     // Assign a picture to those buttons with a defined addressrange.
82 andreas 986
    REG_CMD(getBMP, "?BMP");    // Get the current bitmap name.
38 andreas 987
    REG_CMD(doBOP, "^BOP");     // Set the button opacity.
106 andreas 988
    REG_CMD(getBOP, "?BOP");    // Get the button opacity.
60 andreas 989
    REG_CMD(doBOR, "^BOR");     // Set a border to a specific border style.
107 andreas 990
    REG_CMD(doBOS, "^BOS");     // Set the button to display either a Video or Non-Video window.
60 andreas 991
    REG_CMD(doBRD, "^BRD");     // Set the border of a button state/states.
107 andreas 992
    REG_CMD(getBRD, "?BRD");    // Get the border of a button state/states.
103 andreas 993
//    REG_CMD(doBSF, "^BSF");     // Set the focus to the text area.
38 andreas 994
    REG_CMD(doBSP, "^BSP");     // Set the button size and position.
107 andreas 995
    REG_CMD(doBSM, "^BSM");     // Submit text for text area buttons.
996
    REG_CMD(doBSO, "^BSO");     // Set the sound played when a button is pressed.
38 andreas 997
    REG_CMD(doBWW, "^BWW");     // Set the button word wrap feature to those buttons with a defined address range.
108 andreas 998
    REG_CMD(getBWW, "?BWW");    // Get the button word wrap feature to those buttons with a defined address range.
38 andreas 999
    REG_CMD(doCPF, "^CPF");     // Clear all page flips from a button.
1000
    REG_CMD(doDPF, "^DPF");     // Delete page flips from button if it already exists.
1001
    REG_CMD(doENA, "^ENA");     // Enable or disable buttons with a set variable text range.
1002
    REG_CMD(doFON, "^FON");     // Set a font to a specific Font ID value for those buttons with a range.
108 andreas 1003
    REG_CMD(getFON, "?FON");    // Get the current font index.
388 andreas 1004
    REG_CMD(doGDI, "^GDI");     // Change the bargraph drag increment.
103 andreas 1005
//    REG_CMD(doGDV, "^GDV");     // Invert the joystick axis to move the origin to another corner.
60 andreas 1006
    REG_CMD(doGLH, "^GLH");     // Change the bargraph upper limit.
1007
    REG_CMD(doGLL, "^GLL");     // Change the bargraph lower limit.
388 andreas 1008
    REG_CMD(doGRD, "^GRD");     // Change the bargraph ramp down time.
1009
    REG_CMD(doGRU, "^GRU");     // Change the bargraph ramp up time.
361 andreas 1010
    REG_CMD(doGSN, "^GSN");     // Set slider/cursor name.
108 andreas 1011
    REG_CMD(doGSC, "^GSC");     // Change the bargraph slider color or joystick cursor color.
38 andreas 1012
    REG_CMD(doICO, "^ICO");     // Set the icon to a button.
108 andreas 1013
    REG_CMD(getICO, "?ICO");    // Get the current icon index.
1014
    REG_CMD(doJSB, "^JSB");     // Set bitmap/picture alignment using a numeric keypad layout for those buttons with a defined address range.
1015
    REG_CMD(getJSB, "?JSB");    // Get the current bitmap justification.
1016
    REG_CMD(doJSI, "^JSI");     // Set icon alignment using a numeric keypad layout for those buttons with a defined address range.
1017
    REG_CMD(getJSI, "?JSI");    // Get the current icon justification.
1018
    REG_CMD(doJST, "^JST");     // Set text alignment using a numeric keypad layout for those buttons with a defined address range.
1019
    REG_CMD(getJST, "?JST");    // Get the current text justification.
395 andreas 1020
    REG_CMD(doMSP, "^MSP");     // Set marquee line speed.
38 andreas 1021
    REG_CMD(doSHO, "^SHO");     // Show or hide a button with a set variable text range.
108 andreas 1022
    REG_CMD(doTEC, "^TEC");     // Set the text effect color for the specified addresses/states to the specified color.
1023
    REG_CMD(getTEC, "?TEC");    // Get the current text effect color.
110 andreas 1024
    REG_CMD(doTEF, "^TEF");     // Set the text effect. The Text Effect is specified by name and can be found in TPD4.
1025
    REG_CMD(getTEF, "?TEF");    // Get the current text effect name.
103 andreas 1026
//    REG_CMD(doTOP, "^TOP");     // Send events to the Master as string events.
38 andreas 1027
    REG_CMD(doTXT, "^TXT");     // Assign a text string to those buttons with a defined address range.
110 andreas 1028
    REG_CMD(getTXT, "?TXT");    // Get the current text information.
104 andreas 1029
    REG_CMD(doUNI, "^UNI");     // Set Unicode text.
1030
    REG_CMD(doUTF, "^UTF");     // G5: Set button state text using UTF-8 text command.
148 andreas 1031
    REG_CMD(doVTP, "^VTP");     // Simulates a touch/release/pulse at the given coordinate
14 andreas 1032
 
400 andreas 1033
    REG_CMD(doLPB, "^LPB");     // Assigns a user name to a button.
1034
    REG_CMD(doLPC, "^LPC");     // Clear all users from the User Access Passwords list on the Password Setup page.
1035
    REG_CMD(doLPR, "^LPR");     // Remove a given user from the User Access Passwords list on the Password Setup page.
1036
    REG_CMD(doLPS, "^LPS");     // Set the user name and password.
103 andreas 1037
 
111 andreas 1038
    REG_CMD(doKPS, "^KPS");     // Set the keyboard passthru.
1039
    REG_CMD(doVKS, "^VKS");     // Send one or more virtual key strokes to the G4 application.
103 andreas 1040
 
400 andreas 1041
    REG_CMD(doAPWD, "@PWD");    // Set the page flip password.
1042
    REG_CMD(doPWD, "^PWD");     // Set the page flip password. Password level is required and must be 1 - 4.
103 andreas 1043
 
38 andreas 1044
    REG_CMD(doBBR, "^BBR");     // Set the bitmap of a button to use a particular resource.
97 andreas 1045
    REG_CMD(doRAF, "^RAF");     // Add new resources
1046
    REG_CMD(doRFR, "^RFR");     // Force a refresh for a given resource.
38 andreas 1047
    REG_CMD(doRMF, "^RMF");     // Modify an existing resource.
111 andreas 1048
    REG_CMD(doRSR, "^RSR");     // Change the refresh rate for a given resource.
21 andreas 1049
 
108 andreas 1050
    REG_CMD(doABEEP, "ABEEP");  // Output a single beep even if beep is Off.
1051
    REG_CMD(doADBEEP, "ADBEEP");// Output a double beep even if beep is Off.
62 andreas 1052
    REG_CMD(doAKB, "@AKB");     // Pop up the keyboard icon and initialize the text string to that specified.
1053
    REG_CMD(doAKEYB, "AKEYB");  // Pop up the keyboard icon and initialize the text string to that specified.
1054
    REG_CMD(doAKP, "@AKP");     // Pop up the keypad icon and initialize the text string to that specified.
1055
    REG_CMD(doAKEYP, "AKEYP");  // Pop up the keypad icon and initialize the text string to that specified.
63 andreas 1056
    REG_CMD(doAKEYR, "AKEYR");  // Remove the Keyboard/Keypad.
1057
    REG_CMD(doAKR, "@AKR");     // Remove the Keyboard/Keypad.
71 andreas 1058
    REG_CMD(doBEEP, "BEEP");    // Play a single beep.
104 andreas 1059
    REG_CMD(doBEEP, "^ABP");    // G5: Play a single beep.
71 andreas 1060
    REG_CMD(doDBEEP, "DBEEP");  // Play a double beep.
104 andreas 1061
    REG_CMD(doDBEEP, "^ADB");   // G5: Play a double beep.
62 andreas 1062
    REG_CMD(doEKP, "@EKP");     // Pop up the keypad icon and initialize the text string to that specified.
63 andreas 1063
    REG_CMD(doPKP, "@PKB");     // Present a private keyboard.
1064
    REG_CMD(doPKP, "PKEYP");    // Present a private keypad.
1065
    REG_CMD(doPKP, "@PKP");     // Present a private keypad.
408 andreas 1066
    REG_CMD(doRPP, "^RPP");     // Reset protected password command
64 andreas 1067
    REG_CMD(doSetup, "SETUP");  // Send panel to SETUP page.
104 andreas 1068
    REG_CMD(doSetup, "^STP");   // G5: Open setup page.
64 andreas 1069
    REG_CMD(doShutdown, "SHUTDOWN");// Shut down the App
82 andreas 1070
    REG_CMD(doSOU, "@SOU");     // Play a sound file.
104 andreas 1071
    REG_CMD(doSOU, "^SOU");     // G5: Play a sound file.
326 andreas 1072
    REG_CMD(doMUT, "^MUT");     // G5: Panel Volume Mute
63 andreas 1073
    REG_CMD(doTKP, "@TKP");     // Present a telephone keypad.
104 andreas 1074
    REG_CMD(doTKP, "^TKP");     // G5: Bring up a telephone keypad.
63 andreas 1075
    REG_CMD(doTKP, "@VKB");     // Present a virtual keyboard
104 andreas 1076
    REG_CMD(doTKP, "^VKB");     // G5: Bring up a virtual keyboard.
129 andreas 1077
#ifndef _NOSIP_
103 andreas 1078
    // Here the SIP commands will take place
123 andreas 1079
    REG_CMD(doPHN, "^PHN");     // SIP commands
127 andreas 1080
    REG_CMD(getPHN, "?PHN");    // SIP state commands
129 andreas 1081
#endif
300 andreas 1082
    // SubView commands
1083
//    REG_CMD(doEPR, "^EPR");     // Execute Push on Release.
1084
//    REG_CMD(doSCE, "^SCE");     // Configures subpage custom events.
1085
//    REG_CMD(doSDR, "^SDR");     // Enabling subpage dynamic reordering.
318 andreas 1086
    REG_CMD(doSHA, "^SHA");     // Subpage Hide All Command
1087
    REG_CMD(doSHD, "^SHD");     // Hides subpage
1088
    REG_CMD(doSPD, "^SPD");     //  Set the padding between subpages on a subpage viewer button
300 andreas 1089
    REG_CMD(doSSH, "^SSH");     // Subpage show command.
318 andreas 1090
    REG_CMD(doSTG, "^STG");     // Subpage toggle command
300 andreas 1091
 
225 andreas 1092
    // ListView commands (G5)
1093
    REG_CMD(doLVD, "^LVD");     // G5: Set Listview Data Source
230 andreas 1094
    REG_CMD(doLVE, "^LVE");     // G5: Set ListView custom event number
227 andreas 1095
    REG_CMD(doLVF, "^LVF");     // G5: Listview Filter
230 andreas 1096
    REG_CMD(doLVL, "^LVL");     // G5: ListView layout
233 andreas 1097
    REG_CMD(doLVM, "^LVM");     // G5: ListView map fields
1098
    REG_CMD(doLVN, "^LVN");     // G5: ListView navigate
1099
    REG_CMD(doLVR, "^LVR");     // G5: ListView refresh data
1100
    REG_CMD(doLVS, "^LVS");     // G5: ListView sort data
225 andreas 1101
 
103 andreas 1102
    // State commands
14 andreas 1103
    REG_CMD(doON, "ON");
1104
    REG_CMD(doOFF, "OFF");
15 andreas 1105
    REG_CMD(doLEVEL, "LEVEL");
1106
    REG_CMD(doBLINK, "BLINK");
127 andreas 1107
    REG_CMD(doVER, "^VER?");    // Return version string to master
279 andreas 1108
#ifndef _NOSIP_
127 andreas 1109
    REG_CMD(doWCN, "^WCN?");    // Return SIP phone number
279 andreas 1110
#endif
134 andreas 1111
    // TPControl commands
1112
    REG_CMD(doTPCCMD, "TPCCMD");    // Profile related options
1113
    REG_CMD(doTPCACC, "TPCACC");    // Device orientation
279 andreas 1114
#ifndef _NOSIP_
153 andreas 1115
    REG_CMD(doTPCSIP, "TPCSIP");    // Show the built in SIP phone
279 andreas 1116
#endif
134 andreas 1117
    // Virtual internal commands
26 andreas 1118
    REG_CMD(doFTR, "#FTR");     // File transfer (virtual internal command)
23 andreas 1119
 
123 andreas 1120
    // At least we must add the SIP client
129 andreas 1121
#ifndef _NOSIP_
127 andreas 1122
    mSIPClient = new TSIPClient;
123 andreas 1123
 
1124
    if (TError::isError())
1125
    {
1126
        MSG_ERROR("Error initializing the SIP client!");
1127
        TConfig::setSIPstatus(false);
1128
    }
129 andreas 1129
#endif
88 andreas 1130
    TError::clear();
299 andreas 1131
    runClickQueue();
303 andreas 1132
    runUpdateSubViewItem();
3 andreas 1133
}
1134
 
1135
TPageManager::~TPageManager()
1136
{
1137
    DECL_TRACER("TPageManager::~TPageManager()");
129 andreas 1138
#ifndef _NOSIP_
127 andreas 1139
    if (mSIPClient)
1140
    {
1141
        delete mSIPClient;
1142
        mSIPClient = nullptr;
1143
    }
129 andreas 1144
#endif
3 andreas 1145
    PCHAIN_T *p = mPchain;
1146
    PCHAIN_T *next = nullptr;
37 andreas 1147
#ifdef __ANDROID__
36 andreas 1148
    stopNetworkState();
37 andreas 1149
#endif
3 andreas 1150
    try
1151
    {
1152
        while (p)
1153
        {
1154
            next = p->next;
1155
 
1156
            if (p->page)
1157
                delete p->page;
1158
 
1159
            delete p;
1160
            p = next;
1161
        }
1162
 
1163
        SPCHAIN_T *sp = mSPchain;
1164
        SPCHAIN_T *snext = nullptr;
1165
 
1166
        while (sp)
1167
        {
1168
            snext = sp->next;
1169
 
1170
            if (sp->page)
1171
                delete sp->page;
1172
 
1173
            delete sp;
5 andreas 1174
            sp = snext;
3 andreas 1175
        }
1176
 
1177
        mPchain = nullptr;
1178
        mSPchain = nullptr;
14 andreas 1179
        setPChain(mPchain);
1180
        setSPChain(mSPchain);
3 andreas 1181
 
13 andreas 1182
        if (mAmxNet)
1183
        {
1184
            delete mAmxNet;
1185
            mAmxNet = nullptr;
1186
        }
1187
 
3 andreas 1188
        if (mTSettings)
1189
        {
1190
            delete mTSettings;
1191
            mTSettings = nullptr;
1192
        }
1193
 
1194
        if (mPageList)
1195
        {
1196
            delete mPageList;
1197
            mPageList = nullptr;
1198
        }
5 andreas 1199
 
1200
        if (mPalette)
1201
        {
1202
            delete mPalette;
1203
            mPalette = nullptr;
1204
        }
7 andreas 1205
 
1206
        if (mFonts)
1207
        {
1208
            delete mFonts;
1209
            mFonts = nullptr;
1210
        }
8 andreas 1211
 
1212
        if (gIcons)
1213
        {
1214
            delete gIcons;
1215
            gIcons = nullptr;
1216
        }
1217
 
1218
        if (gPrjResources)
1219
        {
1220
            delete gPrjResources;
1221
            gPrjResources = nullptr;
1222
        }
40 andreas 1223
 
33 andreas 1224
        if (mExternal)
1225
        {
1226
            delete mExternal;
1227
            mExternal = nullptr;
1228
        }
3 andreas 1229
    }
1230
    catch (std::exception& e)
1231
    {
1232
        MSG_ERROR("Memory error: " << e.what());
1233
    }
90 andreas 1234
 
1235
    gPageManager = nullptr;
3 andreas 1236
}
1237
 
11 andreas 1238
void TPageManager::initialize()
1239
{
1240
    DECL_TRACER("TPageManager::initialize()");
1241
 
14 andreas 1242
    surface_mutex.lock();
11 andreas 1243
    dropAllSubPages();
1244
    dropAllPages();
1245
 
186 andreas 1246
    string projectPath = TConfig::getProjectPath();
1247
 
1248
    if (!fs::exists(projectPath + "/prj.xma"))
1249
        projectPath += "/__system";
1250
 
90 andreas 1251
    if (mAmxNet && mAmxNet->isConnected())
1252
        mAmxNet->close();
88 andreas 1253
 
11 andreas 1254
    if (mTSettings)
1255
        mTSettings->loadSettings();
1256
    else
186 andreas 1257
        mTSettings = new TSettings(projectPath);
11 andreas 1258
 
1259
    if (TError::isError())
14 andreas 1260
    {
1261
        surface_mutex.unlock();
11 andreas 1262
        return;
14 andreas 1263
    }
11 andreas 1264
 
178 andreas 1265
    // Set the panel type from the project information
1266
    TConfig::savePanelType(mTSettings->getPanelType());
1267
 
88 andreas 1268
    if (gPrjResources)
1269
        delete gPrjResources;
11 andreas 1270
 
88 andreas 1271
    gPrjResources = new TPrjResources(mTSettings->getResourcesList());
11 andreas 1272
 
88 andreas 1273
    if (mPalette)
1274
        delete mPalette;
1275
 
1276
    mPalette = new TPalette();
1277
 
11 andreas 1278
    vector<PALETTE_SETUP> pal = mTSettings->getSettings().palettes;
1279
 
83 andreas 1280
    if (pal.size() > 0)
1281
    {
1282
        vector<PALETTE_SETUP>::iterator iterPal;
11 andreas 1283
 
118 andreas 1284
        for (iterPal = pal.begin(); iterPal != pal.end(); ++iterPal)
83 andreas 1285
            mPalette->initialize(iterPal->file);
1286
    }
1287
 
11 andreas 1288
    if (!TError::isError())
1289
        TColor::setPalette(mPalette);
1290
 
88 andreas 1291
    if (mFonts)
1292
        delete mFonts;
11 andreas 1293
 
88 andreas 1294
    mFonts = new TFont();
1295
 
11 andreas 1296
    if (TError::isError())
1297
    {
1298
        MSG_ERROR("Initializing fonts was not successfull!");
14 andreas 1299
        surface_mutex.unlock();
11 andreas 1300
        return;
1301
    }
1302
 
88 andreas 1303
    if (gIcons)
1304
        delete gIcons;
11 andreas 1305
 
88 andreas 1306
    gIcons = new TIcons();
1307
 
11 andreas 1308
    if (TError::isError())
1309
    {
1310
        MSG_ERROR("Initializing icons was not successfull!");
14 andreas 1311
        surface_mutex.unlock();
11 andreas 1312
        return;
1313
    }
1314
 
88 andreas 1315
    if (mPageList)
1316
        delete mPageList;
11 andreas 1317
 
88 andreas 1318
    mPageList = new TPageList();
11 andreas 1319
 
88 andreas 1320
    if (mExternal)
1321
        delete mExternal;
1322
 
1323
    mExternal = new TExternal();
1324
 
11 andreas 1325
    PAGELIST_T page;
1326
 
1327
    if (!mTSettings->getSettings().powerUpPage.empty())
1328
    {
88 andreas 1329
        if (readPage(mTSettings->getSettings().powerUpPage))
14 andreas 1330
        {
88 andreas 1331
            MSG_TRACE("Found power up page " << mTSettings->getSettings().powerUpPage);
1332
            page = findPage(mTSettings->getSettings().powerUpPage);
1333
            mActualPage = page.pageID;
14 andreas 1334
        }
11 andreas 1335
    }
1336
 
1337
    TPage *pg = getPage(mActualPage);
1338
 
1339
    vector<string> popups = mTSettings->getSettings().powerUpPopup;
1340
 
83 andreas 1341
    if (popups.size() > 0)
11 andreas 1342
    {
83 andreas 1343
        vector<string>::iterator iter;
1344
 
118 andreas 1345
        for (iter = popups.begin(); iter != popups.end(); ++iter)
14 andreas 1346
        {
88 andreas 1347
            if (readSubPage(*iter))
83 andreas 1348
            {
88 andreas 1349
                MSG_TRACE("Found power up popup " << *iter);
11 andreas 1350
 
88 andreas 1351
                if (pg)
1352
                {
1353
                    TSubPage *spage = getSubPage(*iter);
350 andreas 1354
                    spage->setParent(pg->getHandle());
88 andreas 1355
                    pg->addSubPage(spage);
1356
                }
83 andreas 1357
            }
11 andreas 1358
        }
1359
    }
1360
 
88 andreas 1361
    // Here we initialize the system resources like borders, cursors, sliders, ...
1362
    if (mSystemDraw)
1363
        delete mSystemDraw;
1364
 
1365
    mSystemDraw = new TSystemDraw(TConfig::getSystemPath(TConfig::BASE));
1366
 
1367
    TError::clear();        // Clear all errors who may be occured until here
1368
 
11 andreas 1369
    // Start the thread
92 andreas 1370
    startComm();
1371
 
1372
    surface_mutex.unlock();
1373
}
1374
 
1375
bool TPageManager::startComm()
1376
{
1377
    DECL_TRACER("TPageManager::startComm()");
1378
 
1379
    if (mAmxNet && mAmxNet->isNetRun())
1380
        return true;
1381
 
1382
    try
11 andreas 1383
    {
92 andreas 1384
        if (!mAmxNet)
13 andreas 1385
        {
92 andreas 1386
            if (_netRunning)
13 andreas 1387
            {
92 andreas 1388
                // Wait until previous connection thread ended
1389
                while (_netRunning)
1390
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
13 andreas 1391
            }
14 andreas 1392
 
92 andreas 1393
            mAmxNet = new amx::TAmxNet();
1394
            mAmxNet->setCallback(bind(&TPageManager::doCommand, this, std::placeholders::_1));
1395
            mAmxNet->setPanelID(TConfig::getChannel());
134 andreas 1396
            mAmxNet->setSerialNum(V_SERIAL);
13 andreas 1397
        }
90 andreas 1398
 
1399
        if (!mAmxNet->isNetRun())
1400
            mAmxNet->Run();
85 andreas 1401
    }
92 andreas 1402
    catch (std::exception& e)
1403
    {
1404
        MSG_ERROR("Error starting the AmxNet thread: " << e.what());
1405
        return false;
1406
    }
14 andreas 1407
 
92 andreas 1408
    return true;
11 andreas 1409
}
1410
 
38 andreas 1411
void TPageManager::startUp()
1412
{
1413
    DECL_TRACER("TPageManager::startUp()");
1414
 
44 andreas 1415
    if (mAmxNet)
90 andreas 1416
    {
1417
        MSG_WARNING("Communication with controller already initialized!");
44 andreas 1418
        return;
90 andreas 1419
    }
44 andreas 1420
 
92 andreas 1421
    if (!startComm())
1422
        return;
90 andreas 1423
 
38 andreas 1424
#ifdef __ANDROID__
130 andreas 1425
    initOrientation();
38 andreas 1426
    initNetworkState();
1427
#endif
1428
}
89 andreas 1429
 
1430
void TPageManager::reset()
1431
{
1432
    DECL_TRACER("TPageManager::reset()");
1433
 
100 andreas 1434
    // Freshly initialize everything.
89 andreas 1435
    initialize();
1436
}
1437
 
169 andreas 1438
void TPageManager::runCommands()
1439
{
1440
    DECL_TRACER("TPageManager::runCommands()");
1441
 
1442
    if (mBusy || cmdLoop_busy)
1443
        return;
1444
 
1445
    try
1446
    {
1447
        mThreadCommand = std::thread([=] { this->commandLoop(); });
1448
        mThreadCommand.detach();
1449
    }
1450
    catch (std::exception& e)
1451
    {
1452
        MSG_ERROR("Error starting thread for command loop: " << e.what());
1453
        _netRunning = false;
1454
    }
1455
}
1456
 
197 andreas 1457
void TPageManager::showSetup()
1458
{
1459
    DECL_TRACER("TPageManager::showSetup()");
251 andreas 1460
#ifdef Q_OS_ANDROID
260 andreas 1461
    // Scan Netlinx for TP4 files and update the list of setup.
1462
    if (TConfig::getController().compare("0.0.0.0") != 0)
1463
    {
1464
        if (_startWait)
1465
            _startWait(string("Please wait while I try to load the list of surface files from Netlinx (") + TConfig::getController() + ")");
1466
 
1467
        TTPInit tpinit;
1468
        std::vector<TTPInit::FILELIST_t> fileList;
1469
        tpinit.setPath(TConfig::getProjectPath());
1470
        fileList = tpinit.getFileList(".tp4");
1471
 
1472
        if (fileList.size() > 0)
1473
        {
1474
            vector<TTPInit::FILELIST_t>::iterator iter;
264 andreas 1475
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
260 andreas 1476
            QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "clearSurfaces");
1477
#else
1478
            QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "clearSurfaces");
1479
#endif
1480
            for (iter = fileList.begin(); iter != fileList.end(); ++iter)
1481
            {
264 andreas 1482
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
260 andreas 1483
                QAndroidJniObject str = QAndroidJniObject::fromString(iter->fname.c_str());
1484
                QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "addSurface", "(Ljava/lang/String;)V", str.object<jstring>());
1485
#else
1486
                QJniObject str = QJniObject::fromString(iter->fname.c_str());
1487
                QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "addSurface", "(Ljava/lang/String;)V", str.object<jstring>());
1488
#endif
1489
            }
1490
        }
1491
 
1492
        if (_stopWait)
1493
            _stopWait();
1494
    }
1495
 
367 andreas 1496
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1497
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogLevel", "(Ljava/lang/Integer;)V", TConfig::getLogLevelBits());
383 andreas 1498
    QAndroidJniObject strPath = QAndroidJniObject::fromString(TConfig::getLogFile().c_str());
385 andreas 1499
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogEnableFile", "(Z)V", TConfig::getLogFileEnabled());
383 andreas 1500
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogPath", "(Ljava/lang/String;)V", strPath.object<jstring>());
406 andreas 1501
 
1502
    QAndroidJniObject pw1 = QAndroidJniObject::fromString(TConfig::getPassword1().c_str());
1503
    QAndroidJniObject pw2 = QAndroidJniObject::fromString(TConfig::getPassword2().c_str());
1504
    QAndroidJniObject pw3 = QAndroidJniObject::fromString(TConfig::getPassword3().c_str());
1505
    QAndroidJniObject pw4 = QAndroidJniObject::fromString(TConfig::getPassword4().c_str());
1506
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setPassword", "(ILjava/lang/String;)V", 1, pw1.object<jstring>());
1507
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setPassword", "(ILjava/lang/String;)V", 2, pw2.object<jstring>());
1508
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setPassword", "(ILjava/lang/String;)V", 3, pw3.object<jstring>());
1509
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setPassword", "(ILjava/lang/String;)V", 4, pw4.object<jstring>());
367 andreas 1510
#else
1511
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogLevel", "(I)V", TConfig::getLogLevelBits());
385 andreas 1512
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogEnableFile", "(I)V", (TConfig::getLogFileEnabled() ? 1 : 0));
383 andreas 1513
    QJniObject strPath = QJniObject::fromString(TConfig::getLogFile().c_str());
1514
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogPath", "(Ljava/lang/String;)V", strPath.object<jstring>());
397 andreas 1515
 
1516
    QJniObject pw1 = QJniObject::fromString(TConfig::getPassword1().c_str());
1517
    QJniObject pw2 = QJniObject::fromString(TConfig::getPassword2().c_str());
1518
    QJniObject pw3 = QJniObject::fromString(TConfig::getPassword3().c_str());
1519
    QJniObject pw4 = QJniObject::fromString(TConfig::getPassword4().c_str());
1520
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setPassword", "(ILjava/lang/String;)V", 1, pw1.object<jstring>());
1521
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setPassword", "(ILjava/lang/String;)V", 2, pw2.object<jstring>());
1522
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setPassword", "(ILjava/lang/String;)V", 3, pw3.object<jstring>());
1523
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setPassword", "(ILjava/lang/String;)V", 4, pw4.object<jstring>());
367 andreas 1524
#endif
1525
 
255 andreas 1526
    enterSetup();
250 andreas 1527
#else
1528
        if (_callShowSetup)
1529
            _callShowSetup();
1530
#endif
197 andreas 1531
}
1532
 
1533
void TPageManager::hideSetup()
1534
{
1535
    DECL_TRACER("TPageManager::hideSetup()");
1536
 
206 andreas 1537
    if (!mSetupActive || mSavedPage >= SYSTEM_PAGE_START)
197 andreas 1538
        return;
1539
 
198 andreas 1540
    mSetupActive = false;
197 andreas 1541
 
198 andreas 1542
    if (!mSavedPage)
1543
    {
1544
        string sPage = mTSettings->getPowerUpPage();
197 andreas 1545
 
198 andreas 1546
        if (!setPage(sPage, true))
1547
            setPage(1, true);
197 andreas 1548
 
1549
        return;
1550
    }
1551
 
198 andreas 1552
    setPage(mSavedPage, true);
213 andreas 1553
    MSG_PROTOCOL("Activated page: " << mSavedPage);
197 andreas 1554
 
198 andreas 1555
    if (mSavedSubpages.size() > 0)
197 andreas 1556
    {
198 andreas 1557
        vector<int>::iterator iter;
197 andreas 1558
 
198 andreas 1559
        for (iter = mSavedSubpages.begin(); iter != mSavedSubpages.end(); ++iter)
1560
        {
1561
            showSubPage(*iter);
213 andreas 1562
            MSG_PROTOCOL("Activated subpage: " << *iter);
198 andreas 1563
        }
217 andreas 1564
 
1565
        mSavedSubpages.clear();
197 andreas 1566
    }
1567
}
1568
 
205 andreas 1569
int TPageManager::getSelectedRow(ulong handle)
1570
{
1571
    DECL_TRACER("TPageManager::getSelectedRow(ulong handle)");
1572
 
300 andreas 1573
    int nPage = (handle >> 16) & 0x0000ffff;
205 andreas 1574
 
206 andreas 1575
    if ((nPage && TPage::isRegularPage(nPage)) || TPage::isSystemPage(nPage)) // Do we have a page?
205 andreas 1576
    {                                                   // Yes, then look on page
1577
        TPage *pg = getPage(nPage);
1578
 
1579
        if (!pg)
1580
            return -1;
1581
 
1582
        return pg->getSelectedRow(handle);
1583
    }
206 andreas 1584
    else if (TPage::isRegularSubPage(nPage) || TPage::isSystemSubPage(nPage))
205 andreas 1585
    {
1586
        TSubPage *subPg = getSubPage(nPage);
1587
 
1588
        if (!subPg)
1589
            return -1;
1590
 
1591
        return subPg->getSelectedRow(handle);
1592
    }
1593
 
271 andreas 1594
    MSG_WARNING("Invalid handle " << handleToString(handle) << " detected!");
205 andreas 1595
    return -1;
1596
}
1597
 
1598
string TPageManager::getSelectedItem(ulong handle)
1599
{
1600
    DECL_TRACER("TPageManager::getSelectedItem(ulong handle)");
1601
 
300 andreas 1602
    int nPage = (handle >> 16) & 0x0000ffff;
205 andreas 1603
 
206 andreas 1604
    if ((nPage && TPage::isRegularPage(nPage)) || TPage::isSystemPage(nPage)) // Do we have a page?
205 andreas 1605
    {                                                   // Yes, then look on page
1606
        TPage *pg = getPage(nPage);
1607
 
1608
        if (!pg)
1609
            return string();
1610
 
1611
        return pg->getSelectedItem(handle);
1612
    }
206 andreas 1613
    else if (TPage::isRegularSubPage(nPage) || TPage::isSystemSubPage(nPage))
205 andreas 1614
    {
1615
        TSubPage *subPg = getSubPage(nPage);
1616
 
1617
        if (!subPg)
1618
            return string();
1619
 
1620
        return subPg->getSelectedItem(handle);
1621
    }
1622
 
271 andreas 1623
    MSG_WARNING("Invalid handle " << handleToString(handle) << " detected!");
205 andreas 1624
    return string();
1625
}
1626
 
206 andreas 1627
void TPageManager::setSelectedRow(ulong handle, int row, const std::string& text)
205 andreas 1628
{
1629
    DECL_TRACER("TPageManager::setSelectedRow(ulong handle, int row)");
1630
 
300 andreas 1631
    int nPage = (handle >> 16) & 0x0000ffff;
205 andreas 1632
 
206 andreas 1633
    if (TPage::isRegularPage(nPage) || TPage::isSystemPage(nPage)) // Do we have a page?
205 andreas 1634
    {                                                   // Yes, then look on page
1635
        TPage *pg = getPage(nPage);
1636
 
1637
        if (!pg)
1638
            return;
1639
 
1640
        pg->setSelectedRow(handle, row);
1641
    }
206 andreas 1642
    else if (TPage::isRegularSubPage(nPage) || TPage::isSystemSubPage(nPage))   // Do we have a subpage?
1643
    {                                                   // Yes, then look on subpage
205 andreas 1644
        TSubPage *subPg = getSubPage(nPage);
1645
 
1646
        if (!subPg)
1647
            return;
1648
 
1649
        subPg->setSelectedRow(handle, row);
206 andreas 1650
        // Check if this is a system list. If so we must set the selected
1651
        // text to the input line or "label".
1652
        TPage *mainPage = nullptr;
1653
 
1654
        if (nPage >= SYSTEM_SUBPAGE_START)  // System subpage?
1655
        {
1656
            switch(nPage)
1657
            {
1658
                case SYSTEM_SUBPAGE_SYSTEMSOUND:
1659
                case SYSTEM_SUBPAGE_SINGLEBEEP:
1660
                case SYSTEM_SUBPAGE_DOUBLEBEEP:
1661
                    mainPage = getPage(SYSTEM_PAGE_SOUND);
1662
                break;
1663
 
1664
                case SYSTEM_SUBPAGE_SURFACE:
1665
                    mainPage = getPage(SYSTEM_PAGE_CONTROLLER);
1666
                break;
1667
            }
1668
        }
1669
 
1670
        if (mainPage)
1671
        {
1672
            if (nPage == SYSTEM_SUBPAGE_SYSTEMSOUND)  // System sound beep
1673
            {
1674
                Button::TButton *bt = mainPage->getButton(SYSTEM_PAGE_SOUND_TXSYSSOUND);
1675
 
1676
                if (bt)
1677
                {
1678
                    bt->setText(text, -1);
1679
                    TConfig::setTemporary(true);
1680
                    TConfig::saveSystemSoundFile(text);
1681
                }
1682
            }
1683
            else if (nPage == SYSTEM_SUBPAGE_SINGLEBEEP) // System sound single beep
1684
            {
1685
                Button::TButton *bt = mainPage->getButton(SYSTEM_PAGE_SOUND_TXSINGLEBEEP);
1686
 
1687
                if (bt)
1688
                {
1689
                    bt->setText(text, -1);
1690
                    TConfig::setTemporary(true);
1691
                    TConfig::saveSingleBeepFile(text);
1692
                }
1693
            }
1694
            else if (nPage == SYSTEM_SUBPAGE_DOUBLEBEEP) // System sound double beep
1695
            {
1696
                Button::TButton *bt = mainPage->getButton(SYSTEM_PAGE_SOUND_TXDOUBLEBEEP);
1697
 
1698
                if (bt)
1699
                {
1700
                    bt->setText(text, -1);
1701
                    TConfig::setTemporary(true);
1702
                    TConfig::saveDoubleBeepFile(text);
1703
                }
1704
            }
1705
            else if (nPage == SYSTEM_SUBPAGE_SURFACE)   // System TP4 files (surface files)
1706
            {
1707
                Button::TButton *bt = mainPage->getButton(SYSTEM_PAGE_CTRL_SURFACE);
1708
 
1709
                if (bt)
1710
                {
1711
                    MSG_DEBUG("Setting text: " << text);
1712
                    bt->setText(text, -1);
1713
                    TConfig::setTemporary(true);
1714
                    TConfig::saveFtpSurface(text);
1715
                }
1716
            }
1717
 
1718
            // Close the list subpage
1719
            subPg->drop();
1720
        }
205 andreas 1721
    }
1722
}
1723
 
383 andreas 1724
void TPageManager::redrawObject(ulong handle)
1725
{
1726
    DECL_TRACER("TPageManager::redrawObject(ulong handle)");
1727
 
1728
    int pnumber = (int)((handle >> 16) & 0x0000ffff);
1729
    int btnumber = (int)(handle & 0x0000ffff);
1730
 
1731
    if (pnumber < REGULAR_SUBPAGE_START)    // Is it a page?
1732
    {
1733
        TPage *page = getPage(pnumber);
1734
 
1735
        if (!page)
1736
        {
1737
            MSG_WARNING("Page " << pnumber << " not found!");
1738
            return;
1739
        }
1740
 
1741
        if (!page->isVisilble())
1742
            return;
1743
 
1744
        if (btnumber == 0)
1745
        {
1746
            page->show();
1747
            return;
1748
        }
1749
 
1750
        Button::TButton *button = page->getButton(btnumber);
1751
 
1752
        if (!button)
1753
        {
1754
            MSG_WARNING("Button " << btnumber << " on page " << pnumber << " not found!");
1755
            return;
1756
        }
1757
 
1758
        button->showLastButton();
1759
    }
1760
    else if (pnumber >= REGULAR_SUBPAGE_START && pnumber < SYSTEM_PAGE_START)
1761
    {
1762
        TSubPage *spage = getSubPage(pnumber);
1763
 
1764
        if (!spage)
1765
        {
1766
            MSG_WARNING("Subpage " << pnumber << " not found!");
1767
            return;
1768
        }
1769
 
1770
        if (!spage->isVisible())
1771
            return;
1772
 
1773
        if (btnumber == 0)
1774
        {
1775
            spage->show();
1776
            return;
1777
        }
1778
 
1779
        Button::TButton *button = spage->getButton(btnumber);
1780
 
1781
        if (!button)
1782
        {
1783
            MSG_WARNING("Button " << btnumber << " on subpage " << pnumber << " not found!");
1784
            return;
1785
        }
1786
 
1787
        button->showLastButton();
1788
    }
1789
    else
1790
    {
1791
        MSG_WARNING("System pages are not handled by redraw method! Ignoring page " << pnumber << ".");
1792
    }
1793
}
1794
 
198 andreas 1795
#ifdef _SCALE_SKIA_
197 andreas 1796
void TPageManager::setSetupScaleFactor(double scale, double sw, double sh)
1797
{
1798
    DECL_TRACER("TPageManager::setSetupScaleFactor(double scale, double sw, double sh)");
1799
 
1800
    mScaleSystem = scale;
1801
    mScaleSystemWidth = sw;
1802
    mScaleSystemHeight = sh;
1803
}
198 andreas 1804
#endif
197 andreas 1805
 
11 andreas 1806
/*
1807
 * The following method is called by the class TAmxNet whenever an event from
169 andreas 1808
 * the Netlinx occured.
11 andreas 1809
 */
1810
void TPageManager::doCommand(const amx::ANET_COMMAND& cmd)
1811
{
1812
    DECL_TRACER("TPageManager::doCommand(const amx::ANET_COMMAND& cmd)");
1813
 
169 andreas 1814
    if (!cmdLoop_busy)
1815
        runCommands();
1816
 
11 andreas 1817
    mCommands.push_back(cmd);
169 andreas 1818
}
11 andreas 1819
 
169 andreas 1820
void TPageManager::commandLoop()
1821
{
1822
    DECL_TRACER("TPageManager::commandLoop()");
1823
 
1824
    if (mBusy || cmdLoop_busy)
11 andreas 1825
        return;
1826
 
169 andreas 1827
    mBusy = cmdLoop_busy = true;
11 andreas 1828
    string com;
1829
 
169 andreas 1830
    while (cmdLoop_busy && !killed && !_restart_)
11 andreas 1831
    {
169 andreas 1832
        while (mCommands.size() > 0)
11 andreas 1833
        {
169 andreas 1834
            amx::ANET_COMMAND bef = mCommands.at(0);
1835
            mCommands.erase(mCommands.begin());
11 andreas 1836
 
169 andreas 1837
            switch (bef.MC)
1838
            {
1839
                case 0x0006:
1840
                case 0x0018:	// feedback channel on
1841
                    com.assign("ON-");
1842
                    com.append(to_string(bef.data.chan_state.channel));
1843
                    parseCommand(bef.device1, bef.data.chan_state.port, com);
1844
                break;
11 andreas 1845
 
169 andreas 1846
                case 0x0007:
1847
                case 0x0019:	// feedback channel off
1848
                    com.assign("OFF-");
1849
                    com.append(to_string(bef.data.chan_state.channel));
1850
                    parseCommand(bef.device1, bef.data.chan_state.port, com);
1851
                break;
11 andreas 1852
 
169 andreas 1853
                case 0x000a:	// level value change
1854
                    com = "LEVEL-";
1855
                    com += to_string(bef.data.message_value.value);
1856
                    com += ",";
11 andreas 1857
 
169 andreas 1858
                    switch (bef.data.message_value.type)
1859
                    {
1860
                        case 0x10: com += to_string(bef.data.message_value.content.byte); break;
1861
                        case 0x11: com += to_string(bef.data.message_value.content.ch); break;
1862
                        case 0x20: com += to_string(bef.data.message_value.content.integer); break;
1863
                        case 0x21: com += to_string(bef.data.message_value.content.sinteger); break;
1864
                        case 0x40: com += to_string(bef.data.message_value.content.dword); break;
1865
                        case 0x41: com += to_string(bef.data.message_value.content.sdword); break;
1866
                        case 0x4f: com += to_string(bef.data.message_value.content.fvalue); break;
1867
                        case 0x8f: com += to_string(bef.data.message_value.content.dvalue); break;
1868
                    }
11 andreas 1869
 
169 andreas 1870
                    parseCommand(bef.device1, bef.data.message_value.port, com);
1871
                break;
11 andreas 1872
 
169 andreas 1873
                case 0x000c:	// Command string
11 andreas 1874
                {
169 andreas 1875
                    amx::ANET_MSG_STRING msg = bef.data.message_string;
11 andreas 1876
 
169 andreas 1877
                    if (msg.length < strlen((char *)&msg.content))
1878
                    {
1879
                        mCmdBuffer.append((char *)&msg.content);
1880
                        break;
1881
                    }
1882
                    else if (mCmdBuffer.length() > 0)
1883
                    {
1884
                        mCmdBuffer.append((char *)&msg.content);
1885
                        size_t len = (mCmdBuffer.length() >= sizeof(msg.content)) ? (sizeof(msg.content)-1) : mCmdBuffer.length();
1886
                        strncpy((char *)&msg.content, mCmdBuffer.c_str(), len);
1887
                        msg.content[len] = 0;
1888
                    }
104 andreas 1889
 
169 andreas 1890
                    if (getCommand((char *)msg.content) == "^UTF")  // This is already UTF8!
1891
                        com.assign((char *)msg.content);
1892
                    else
1893
                        com.assign(cp1250ToUTF8((char *)&msg.content));
11 andreas 1894
 
169 andreas 1895
                    parseCommand(bef.device1, msg.port, com);
1896
                    mCmdBuffer.clear();
1897
                }
1898
                break;
15 andreas 1899
 
169 andreas 1900
                case 0x0502:    // Blink message (contains date and time)
1901
                    com = "BLINK-" + to_string(bef.data.blinkMessage.hour) + ":";
1902
                    com += to_string(bef.data.blinkMessage.minute) + ":";
1903
                    com += to_string(bef.data.blinkMessage.second) + ",";
1904
                    com += to_string(bef.data.blinkMessage.year) + "-";
1905
                    com += to_string(bef.data.blinkMessage.month) + "-";
1906
                    com += to_string(bef.data.blinkMessage.day) + ",";
1907
                    com += to_string(bef.data.blinkMessage.weekday) + ",";
1908
                    com += ((bef.data.blinkMessage.LED & 0x0001) ? "ON" : "OFF");
1909
                    parseCommand(0, 0, com);
1910
                break;
11 andreas 1911
 
169 andreas 1912
                case 0x1000:	// Filetransfer
11 andreas 1913
                {
169 andreas 1914
                    amx::ANET_FILETRANSFER ftr = bef.data.filetransfer;
1915
 
1916
                    if (ftr.ftype == 0)
11 andreas 1917
                    {
169 andreas 1918
                        switch(ftr.function)
1919
                        {
1920
                            case 0x0100:	// Syncing directory
1921
                                com = "#FTR-SYNC:0:";
1922
                                com.append((char*)&ftr.data[0]);
1923
                                parseCommand(bef.device1, bef.port1, com);
1924
                            break;
11 andreas 1925
 
169 andreas 1926
                            case 0x0104:	// Delete file
1927
                                com = "#FTR-SYNC:"+to_string(bef.count)+":Deleting files ... ("+to_string(bef.count)+"%)";
1928
                                parseCommand(bef.device1, bef.port1, com);
1929
                            break;
11 andreas 1930
 
169 andreas 1931
                            case 0x0105:	// start filetransfer
1932
                                com = "#FTR-START";
1933
                                parseCommand(bef.device1, bef.port1, com);
1934
                            break;
1935
                        }
11 andreas 1936
                    }
169 andreas 1937
                    else
11 andreas 1938
                    {
169 andreas 1939
                        switch(ftr.function)
1940
                        {
1941
                            case 0x0003:	// Received part of file
1942
                            case 0x0004:	// End of file
1943
                                com = "#FTR-FTRPART:"+to_string(bef.count)+":"+to_string(ftr.info1);
1944
                                parseCommand(bef.device1, bef.port1, com);
1945
                            break;
11 andreas 1946
 
169 andreas 1947
                            case 0x0007:	// End of file transfer
1948
                            {
1949
                                com = "#FTR-END";
1950
                                parseCommand(bef.device1, bef.port1, com);
1951
                            }
1952
                            break;
1953
 
1954
                            case 0x0102:	// Receiving file
1955
                                com = "#FTR-FTRSTART:"+to_string(bef.count)+":"+to_string(ftr.info1)+":";
1956
                                com.append((char*)&ftr.data[0]);
1957
                                parseCommand(bef.device1, bef.port1, com);
1958
                            break;
11 andreas 1959
                        }
1960
                    }
1961
                }
169 andreas 1962
                break;
11 andreas 1963
            }
1964
        }
169 andreas 1965
 
1966
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
11 andreas 1967
    }
1968
 
1969
    mBusy = false;
169 andreas 1970
    cmdLoop_busy = false;
11 andreas 1971
}
1972
 
26 andreas 1973
void TPageManager::deployCallbacks()
1974
{
1975
    DECL_TRACER("TPageManager::deployCallbacks()");
1976
 
1977
    PCHAIN_T *p = mPchain;
1978
 
1979
    while (p)
1980
    {
1981
        if (p->page)
1982
        {
1983
            if (_setBackground)
1984
                p->page->registerCallback(_setBackground);
1985
 
1986
            if (_callPlayVideo)
1987
                p->page->regCallPlayVideo(_callPlayVideo);
1988
        }
1989
 
1990
        p = p->next;
1991
    }
1992
 
1993
    SPCHAIN_T *sp = mSPchain;
1994
 
1995
    while (sp)
1996
    {
1997
        if (sp->page)
1998
        {
1999
            if (_setBackground)
2000
                sp->page->registerCallback(_setBackground);
2001
 
2002
            if (_callPlayVideo)
2003
                sp->page->regCallPlayVideo(_callPlayVideo);
2004
        }
2005
 
2006
        sp = sp->next;
2007
    }
2008
}
36 andreas 2009
 
2010
void TPageManager::regCallbackNetState(std::function<void (int)> callNetState, ulong handle)
2011
{
2012
    DECL_TRACER("TPageManager::regCallbackNetState(std::function<void (int)> callNetState, ulong handle)");
2013
 
2014
    if (handle == 0)
2015
        return;
2016
 
2017
    mNetCalls.insert(std::pair<int, std::function<void (int)> >(handle, callNetState));
2018
}
2019
 
2020
void TPageManager::unregCallbackNetState(ulong handle)
2021
{
2022
    DECL_TRACER("TPageManager::unregCallbackNetState(ulong handle)");
2023
 
83 andreas 2024
    if (mNetCalls.size() == 0)
2025
        return;
2026
 
300 andreas 2027
    std::map<int, std::function<void (int)> >::iterator iter = mNetCalls.find((int)handle);
36 andreas 2028
 
2029
    if (iter != mNetCalls.end())
2030
        mNetCalls.erase(iter);
2031
}
247 andreas 2032
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
251 andreas 2033
#ifdef Q_OS_ANDROID
38 andreas 2034
void TPageManager::regCallbackBatteryState(std::function<void (int, bool, int)> callBatteryState, ulong handle)
2035
{
2036
    DECL_TRACER("TPageManager::regCallbackBatteryState(std::function<void (int, bool, int)> callBatteryState, ulong handle)");
2037
 
2038
    if (handle == 0)
2039
        return;
2040
 
2041
    mBatteryCalls.insert(std::pair<int, std::function<void (int, bool, int)> >(handle, callBatteryState));
2042
}
247 andreas 2043
#endif
2044
#ifdef Q_OS_IOS
2045
void TPageManager::regCallbackBatteryState(std::function<void (int, int)> callBatteryState, ulong handle)
2046
{
2047
    DECL_TRACER("TPageManager::regCallbackBatteryState(std::function<void (int, int)> callBatteryState, ulong handle)");
38 andreas 2048
 
247 andreas 2049
    if (handle == 0)
2050
        return;
2051
 
2052
    mBatteryCalls.insert(std::pair<int, std::function<void (int, int)> >(handle, callBatteryState));
264 andreas 2053
#ifdef Q_OS_IOS
2054
    mLastBatteryLevel = TIOSBattery::getBatteryLeft();
2055
    mLastBatteryState = TIOSBattery::getBatteryState();
247 andreas 2056
 
264 andreas 2057
#endif
247 andreas 2058
    if (mLastBatteryLevel > 0 || mLastBatteryState > 0)
2059
        informBatteryStatus(mLastBatteryLevel, mLastBatteryState);
2060
}
2061
#endif
38 andreas 2062
void TPageManager::unregCallbackBatteryState(ulong handle)
2063
{
2064
    DECL_TRACER("TPageManager::unregCallbackBatteryState(ulong handle)");
2065
 
83 andreas 2066
    if (mBatteryCalls.size() == 0)
2067
        return;
247 andreas 2068
#ifdef Q_OS_ANDROID
38 andreas 2069
    std::map<int, std::function<void (int, bool, int)> >::iterator iter = mBatteryCalls.find(handle);
247 andreas 2070
#endif
2071
#ifdef Q_OS_IOS
300 andreas 2072
    std::map<int, std::function<void (int, int)> >::iterator iter = mBatteryCalls.find((int)handle);
247 andreas 2073
#endif
38 andreas 2074
    if (iter != mBatteryCalls.end())
2075
        mBatteryCalls.erase(iter);
2076
}
247 andreas 2077
#endif  // defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
11 andreas 2078
/*
2079
 * The following function must be called to start the "panel".
2080
 */
5 andreas 2081
bool TPageManager::run()
2082
{
2083
    DECL_TRACER("TPageManager::run()");
2084
 
2085
    if (mActualPage <= 0)
2086
        return false;
2087
 
154 andreas 2088
    TPage *pg = getPage(mActualPage);
2089
 
2090
    if (!pg || !_setPage || !mTSettings)
2091
        return false;
2092
 
14 andreas 2093
    surface_mutex.lock();
7 andreas 2094
    pg->setFonts(mFonts);
5 andreas 2095
    pg->registerCallback(_setBackground);
21 andreas 2096
    pg->regCallPlayVideo(_callPlayVideo);
5 andreas 2097
 
26 andreas 2098
    int width, height;
217 andreas 2099
    width = mTSettings->getWidth();
26 andreas 2100
    height = mTSettings->getHeight();
43 andreas 2101
#ifdef _SCALE_SKIA_
26 andreas 2102
    if (mScaleFactor != 1.0)
2103
    {
2104
        width = (int)((double)width * mScaleFactor);
2105
        height = (int)((double)height * mScaleFactor);
2106
    }
43 andreas 2107
#endif
26 andreas 2108
    _setPage((pg->getNumber() << 16) & 0xffff0000, width, height);
5 andreas 2109
    pg->show();
2110
 
2111
    TSubPage *subPg = pg->getFirstSubPage();
2112
 
2113
    while (subPg)
2114
    {
7 andreas 2115
        subPg->setFonts(mFonts);
2116
        subPg->registerCallback(_setBackground);
2117
        subPg->registerCallbackDB(_displayButton);
11 andreas 2118
        subPg->regCallDropSubPage(_callDropSubPage);
21 andreas 2119
        subPg->regCallPlayVideo(_callPlayVideo);
7 andreas 2120
 
5 andreas 2121
        if (_setSubPage)
6 andreas 2122
        {
2123
            MSG_DEBUG("Drawing page " << subPg->getNumber() << ": " << subPg->getName() << "...");
26 andreas 2124
            width = subPg->getWidth();
2125
            height = subPg->getHeight();
2126
            int left = subPg->getLeft();
2127
            int top = subPg->getTop();
43 andreas 2128
#ifdef _SCALE_SKIA_
26 andreas 2129
            if (mScaleFactor != 1.0)
2130
            {
2131
                width = (int)((double)width * mScaleFactor);
2132
                height = (int)((double)height * mScaleFactor);
2133
                left = (int)((double)left * mScaleFactor);
2134
                top = (int)((double)top * mScaleFactor);
2135
            }
43 andreas 2136
#endif
41 andreas 2137
            ANIMATION_t ani;
2138
            ani.showEffect = subPg->getShowEffect();
2139
            ani.showTime = subPg->getShowTime();
42 andreas 2140
            ani.hideEffect = subPg->getHideEffect();
2141
            ani.hideTime = subPg->getHideTime();
162 andreas 2142
 
2143
            subPg->setZOrder(pg->getNextZOrder());
217 andreas 2144
            _setSubPage(subPg->getHandle(), pg->getHandle(), left, top, width, height, ani);
6 andreas 2145
            subPg->show();
2146
        }
5 andreas 2147
 
2148
        subPg = pg->getNextSubPage();
2149
    }
2150
 
14 andreas 2151
    surface_mutex.unlock();
5 andreas 2152
    return true;
2153
}
2154
 
4 andreas 2155
TPage *TPageManager::getPage(int pageID)
2156
{
2157
    DECL_TRACER("TPageManager::getPage(int pageID)");
2158
 
209 andreas 2159
    if (pageID <= 0)
2160
        return nullptr;
2161
 
4 andreas 2162
    PCHAIN_T *p = mPchain;
2163
 
2164
    while (p)
2165
    {
349 andreas 2166
        if (p->page && p->page->getNumber() == pageID)
4 andreas 2167
            return p->page;
2168
 
2169
        p = p->next;
2170
    }
2171
 
2172
    return nullptr;
2173
}
2174
 
2175
TPage *TPageManager::getPage(const string& name)
2176
{
2177
    DECL_TRACER("TPageManager::getPage(const string& name)");
2178
 
349 andreas 2179
    if (name.empty())
2180
        return nullptr;
2181
 
4 andreas 2182
    PCHAIN_T *p = mPchain;
2183
 
2184
    while (p)
2185
    {
349 andreas 2186
        if (p->page && p->page->getName().compare(name) == 0)
4 andreas 2187
            return p->page;
2188
 
2189
        p = p->next;
2190
    }
2191
 
2192
    return nullptr;
2193
}
2194
 
209 andreas 2195
TPage *TPageManager::loadPage(PAGELIST_T& pl, bool *refresh)
15 andreas 2196
{
209 andreas 2197
    DECL_TRACER("TPageManager::loadPage(PAGELIST_T& pl, bool *refresh)");
15 andreas 2198
 
209 andreas 2199
    if (refresh)
2200
        *refresh = false;
2201
 
15 andreas 2202
    if (!pl.isValid)
2203
        return nullptr;
2204
 
2205
    TPage *pg = getPage(pl.pageID);
2206
 
2207
    if (!pg)
2208
    {
2209
        if (!readPage(pl.pageID))
2210
            return nullptr;
2211
 
2212
        pg = getPage(pl.pageID);
2213
 
2214
        if (!pg)
2215
        {
2216
            MSG_ERROR("Error loading page " << pl.pageID << ", " << pl.name << " from file " << pl.file << "!");
2217
            return nullptr;
2218
        }
209 andreas 2219
 
2220
        if (refresh)
213 andreas 2221
            *refresh = true;        // Indicate that the page was freshly loaded
15 andreas 2222
    }
2223
 
2224
    return pg;
2225
}
2226
 
209 andreas 2227
void TPageManager::reloadSystemPage(TPage *page)
2228
{
2229
    DECL_TRACER("TPageManager::reloadSystemPage(TPage *page)");
2230
 
2231
    if (!page)
2232
        return;
2233
 
2234
    vector<Button::TButton *> buttons = page->getAllButtons();
2235
    vector<Button::TButton *>::iterator iter;
210 andreas 2236
    TConfig::setTemporary(false);
209 andreas 2237
 
2238
    for (iter = buttons.begin(); iter != buttons.end(); ++iter)
2239
    {
2240
        Button::TButton *bt = *iter;
2241
 
2242
        if (bt->getAddressPort() == 0 && bt->getAddressChannel() > 0)
2243
        {
2244
            switch(bt->getAddressChannel())
2245
            {
2246
                case SYSTEM_ITEM_LOGLOGFILE:        bt->setTextOnly(TConfig::getLogFile(), -1); break;
2247
 
2248
                case SYSTEM_ITEM_NETLINX_IP:        bt->setTextOnly(TConfig::getController(), -1); break;
2249
                case SYSTEM_ITEM_NETLINX_PORT:      bt->setTextOnly(std::to_string(TConfig::getPort()), -1); break;
2250
                case SYSTEM_ITEM_NETLINX_CHANNEL:   bt->setTextOnly(std::to_string(TConfig::getChannel()), -1); break;
2251
                case SYSTEM_ITEM_NETLINX_PTYPE:     bt->setTextOnly(TConfig::getPanelType(), -1); break;
2252
                case SYSTEM_ITEM_FTPUSER:           bt->setTextOnly(TConfig::getFtpUser(), -1); break;
2253
                case SYSTEM_ITEM_FTPPASSWORD:       bt->setTextOnly(TConfig::getFtpPassword(), -1); break;
2254
                case SYSTEM_ITEM_FTPSURFACE:        bt->setTextOnly(TConfig::getFtpSurface(), -1); break;
210 andreas 2255
 
2256
                case SYSTEM_ITEM_SIPPROXY:          bt->setTextOnly(TConfig::getSIPproxy(), -1); break;
2257
                case SYSTEM_ITEM_SIPPORT:           bt->setTextOnly(std::to_string(TConfig::getSIPport()), -1); break;
2258
                case SYSTEM_ITEM_SIPSTUN:           bt->setTextOnly(TConfig::getSIPstun(), -1); break;
2259
                case SYSTEM_ITEM_SIPDOMAIN:         bt->setTextOnly(TConfig::getSIPdomain(), -1); break;
2260
                case SYSTEM_ITEM_SIPUSER:           bt->setTextOnly(TConfig::getSIPuser(), -1); break;
2261
                case SYSTEM_ITEM_SIPPASSWORD:       bt->setTextOnly(TConfig::getSIPpassword(), -1); break;
2262
 
2263
                case SYSTEM_ITEM_SYSTEMSOUND:       bt->setTextOnly(TConfig::getSystemSound(), -1); break;
2264
                case SYSTEM_ITEM_SINGLEBEEP:        bt->setTextOnly(TConfig::getSingleBeepSound(), -1); break;
2265
                case SYSTEM_ITEM_DOUBLEBEEP:        bt->setTextOnly(TConfig::getDoubleBeepSound(), -1); break;
209 andreas 2266
            }
2267
        }
210 andreas 2268
        else if (bt->getChannelPort() == 0 && bt->getChannelNumber() > 0)
2269
        {
2270
            switch(bt->getChannelNumber())
2271
            {
2272
                case SYSTEM_ITEM_DEBUGINFO:         bt->setActiveInstance(IS_LOG_INFO() ? 1 : 0); break;
2273
                case SYSTEM_ITEM_DEBUGWARNING:      bt->setActiveInstance(IS_LOG_WARNING() ? 1 : 0); break;
2274
                case SYSTEM_ITEM_DEBUGERROR:        bt->setActiveInstance(IS_LOG_ERROR() ? 1 : 0); break;
2275
                case SYSTEM_ITEM_DEBUGTRACE:        bt->setActiveInstance(IS_LOG_TRACE() ? 1 : 0); break;
2276
                case SYSTEM_ITEM_DEBUGDEBUG:        bt->setActiveInstance(IS_LOG_DEBUG() ? 1 : 0); break;
2277
                case SYSTEM_ITEM_DEBUGPROTOCOL:     bt->setActiveInstance(IS_LOG_PROTOCOL() ? 1 : 0); break;
2278
                case SYSTEM_ITEM_DEBUGALL:          bt->setActiveInstance(IS_LOG_ALL() ? 1 : 0); break;
2279
                case SYSTEM_ITEM_DEBUGLONG:         bt->setActiveInstance(TConfig::isLongFormat() ? 1 : 0); break;
2280
                case SYSTEM_ITEM_DEBUGPROFILE:      bt->setActiveInstance(TConfig::getProfiling() ? 1 : 0); break;
2281
 
2282
                case SYSTEM_ITEM_FTPPASSIVE:        bt->setActiveInstance(TConfig::getFtpPassive() ? 1 : 0); break;
2283
 
2284
                case SYSTEM_ITEM_SIPIPV4:           bt->setActiveInstance(TConfig::getSIPnetworkIPv4() ? 1 : 0); break;
2285
                case SYSTEM_ITEM_SIPIPV6:           bt->setActiveInstance(TConfig::getSIPnetworkIPv6() ? 1 : 0); break;
2286
                case SYSTEM_ITEM_SIPENABLE:         bt->setActiveInstance(TConfig::getSIPstatus() ? 1 : 0); break;
2287
                case SYSTEM_ITEM_SIPIPHONE:         bt->setActiveInstance(TConfig::getSIPiphone() ? 1 : 0); break;
2288
 
2289
                case SYSTEM_ITEM_SOUNDSWITCH:       bt->setActiveInstance(TConfig::getSystemSoundState() ? 1 : 0); break;
2290
 
2291
                case SYSTEM_ITEM_VIEWSCALEFIT:      bt->setActiveInstance(TConfig::getScale() ? 1 : 0); break;
2292
                case SYSTEM_ITEM_VIEWBANNER:        bt->setActiveInstance(TConfig::showBanner() ? 1 : 0); break;
2293
                case SYSTEM_ITEM_VIEWNOTOOLBAR:     bt->setActiveInstance(TConfig::getToolbarSuppress() ? 1 : 0); break;
2294
                case SYSTEM_ITEM_VIEWTOOLBAR:       bt->setActiveInstance(TConfig::getToolbarForce() ? 1 : 0); break;
2295
                case SYSTEM_ITEM_VIEWROTATE:        bt->setActiveInstance(TConfig::getRotationFixed() ? 1 : 0); break;
2296
            }
2297
        }
2298
        else if (bt->getLevelPort() == 0 && bt->getLevelValue() > 0)
2299
        {
2300
            switch(bt->getLevelValue())
2301
            {
2302
                case SYSTEM_ITEM_SYSVOLUME:         bt->drawBargraph(0, TConfig::getSystemVolume(), false); break;
2303
                case SYSTEM_ITEM_SYSGAIN:           bt->drawBargraph(0, TConfig::getSystemGain(), false); break;
2304
            }
2305
        }
209 andreas 2306
    }
2307
}
2308
 
198 andreas 2309
bool TPageManager::setPage(int PageID, bool forget)
15 andreas 2310
{
198 andreas 2311
    DECL_TRACER("TPageManager::setPage(int PageID, bool forget)");
15 andreas 2312
 
295 andreas 2313
    return _setPageDo(PageID, "", forget);
15 andreas 2314
}
2315
 
168 andreas 2316
bool TPageManager::setPage(const string& name, bool forget)
15 andreas 2317
{
190 andreas 2318
    DECL_TRACER("TPageManager::setPage(const string& name, bool forget)");
15 andreas 2319
 
295 andreas 2320
    return _setPageDo(0, name, forget);
15 andreas 2321
}
2322
 
295 andreas 2323
bool TPageManager::_setPageDo(int pageID, const string& name, bool forget)
2324
{
2325
    DECL_TRACER("TPageManager::_setPageDo(int pageID, const string& name, bool forget)");
2326
 
2327
    TPage *pg = nullptr;
2328
 
2329
    if (pageID > 0 && mActualPage == pageID)
343 andreas 2330
    {
2331
#if TESTMODE == 1
2332
        __success = true;
2333
        setScreenDone();
2334
#endif
295 andreas 2335
        return true;
343 andreas 2336
    }
295 andreas 2337
    else if (!name.empty())
2338
    {
2339
        pg = getPage(mActualPage);
2340
 
2341
        if (pg && pg->getName().compare(name) == 0)
343 andreas 2342
        {
2343
#if TESTMODE == 1
2344
            __success = true;
2345
            setScreenDone();
2346
#endif
295 andreas 2347
            return true;
343 andreas 2348
        }
295 andreas 2349
    }
2350
    else if (pageID > 0)
2351
        pg = getPage(mActualPage);
2352
    else
343 andreas 2353
    {
2354
#if TESTMODE == 1
2355
        setScreenDone();
2356
#endif
295 andreas 2357
        return false;
343 andreas 2358
    }
295 andreas 2359
 
2360
    // FIXME: Make this a vector array to hold a larger history!
2361
    if (!forget)
2362
        mPreviousPage = mActualPage;    // Necessary to be able to jump back to at least the last previous page
2363
 
2364
    if (pg)
2365
        pg->drop();
2366
 
2367
    mActualPage = 0;
2368
    PAGELIST_T listPg;
2369
 
2370
    if (pageID > 0)
2371
        listPg = findPage(pageID);
2372
    else
2373
        listPg = findPage(name);
2374
 
2375
    bool refresh = false;
2376
 
2377
    if ((pg = loadPage(listPg, &refresh)) == nullptr)
343 andreas 2378
    {
2379
#if TESTMODE == 1
2380
        setScreenDone();
2381
#endif
295 andreas 2382
        return false;
343 andreas 2383
    }
295 andreas 2384
 
2385
    mActualPage = pg->getNumber();
2386
 
2387
    if (mActualPage >= SYSTEM_PAGE_START && !refresh)
2388
        reloadSystemPage(pg);
2389
 
2390
    int width = (mActualPage >= SYSTEM_PAGE_START ? mSystemSettings->getWidth() : mTSettings->getWidth());
2391
    int height = (mActualPage >= SYSTEM_PAGE_START ? mSystemSettings->getHeight() : mTSettings->getHeight());
2392
 
2393
    if (_setPage)
2394
        _setPage((mActualPage << 16) & 0xffff0000, width, height);
2395
 
2396
    pg->show();
2397
    return true;
2398
}
2399
 
2400
 
4 andreas 2401
TSubPage *TPageManager::getSubPage(int pageID)
2402
{
2403
    DECL_TRACER("TPageManager::getSubPage(int pageID)");
2404
 
2405
    SPCHAIN_T *p = mSPchain;
2406
 
2407
    while(p)
2408
    {
2409
        if (p->page->getNumber() == pageID)
2410
            return p->page;
2411
 
2412
        p = p->next;
2413
    }
2414
 
2415
    return nullptr;
2416
}
2417
 
2418
TSubPage *TPageManager::getSubPage(const std::string& name)
2419
{
2420
    DECL_TRACER("TPageManager::getSubPage(const std::string& name)");
2421
 
2422
    SPCHAIN_T *p = mSPchain;
2423
 
2424
    while (p)
2425
    {
2426
        if (p->page->getName().compare(name) == 0)
2427
            return p->page;
2428
 
2429
        p = p->next;
2430
    }
2431
 
146 andreas 2432
    MSG_DEBUG("Page " << name << " not found in cache.");
4 andreas 2433
    return nullptr;
2434
}
2435
 
96 andreas 2436
TSubPage *TPageManager::deliverSubPage(const string& name, TPage **pg)
2437
{
198 andreas 2438
    DECL_TRACER("TPageManager::deliverSubPage(const string& name, TPage **pg)");
96 andreas 2439
 
2440
    TPage *page = getActualPage();
2441
 
2442
    if (!page)
2443
    {
2444
        MSG_ERROR("No actual page loaded!");
2445
        return nullptr;
2446
    }
2447
 
2448
    if (pg)
2449
        *pg = page;
2450
 
2451
    TSubPage *subPage = getSubPage(name);
2452
 
2453
    if (!subPage)
2454
    {
2455
        if (!readSubPage(name))
2456
        {
2457
            MSG_ERROR("Error reading subpage " << name);
2458
            return nullptr;
2459
        }
2460
 
2461
        subPage = getSubPage(name);
2462
 
2463
        if (!subPage)
2464
        {
2465
            MSG_ERROR("Fatal: A page with name " << name << " does not exist!");
2466
            return nullptr;
2467
        }
350 andreas 2468
 
2469
        subPage->setParent(page->getHandle());
96 andreas 2470
    }
2471
 
2472
    return subPage;
2473
}
2474
 
198 andreas 2475
TSubPage *TPageManager::deliverSubPage(int number, TPage **pg)
2476
{
2477
    DECL_TRACER("TPageManager::deliverSubPage(int number, TPage **pg)");
2478
 
2479
    TPage *page = getActualPage();
2480
 
2481
    if (!page)
2482
    {
2483
        MSG_ERROR("No actual page loaded!");
2484
        return nullptr;
2485
    }
2486
 
2487
    if (pg)
2488
        *pg = page;
2489
 
2490
    TSubPage *subPage = getSubPage(number);
2491
 
2492
    if (!subPage)
2493
    {
2494
        if (!readSubPage(number))
2495
        {
2496
            MSG_ERROR("Error reading subpage " << number);
2497
            return nullptr;
2498
        }
2499
 
2500
        subPage = getSubPage(number);
2501
 
2502
        if (!subPage)
2503
        {
2504
            MSG_ERROR("Fatal: A page with name " << number << " does not exist!");
2505
            return nullptr;
2506
        }
350 andreas 2507
 
2508
        subPage->setParent(page->getHandle());
198 andreas 2509
    }
2510
 
2511
    return subPage;
2512
}
2513
 
3 andreas 2514
bool TPageManager::readPages()
2515
{
2516
    DECL_TRACER("TPageManager::readPages()");
2517
 
2518
    if (!mPageList)
2519
    {
2520
        MSG_ERROR("Page list is not initialized!");
2521
        TError::setError();
2522
        return false;
2523
    }
2524
 
2525
    // Read all pages
2526
    vector<PAGELIST_T> pageList = mPageList->getPagelist();
2527
 
83 andreas 2528
    if (pageList.size() > 0)
3 andreas 2529
    {
83 andreas 2530
        vector<PAGELIST_T>::iterator pgIter;
14 andreas 2531
 
118 andreas 2532
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
14 andreas 2533
        {
83 andreas 2534
            TPage *page = new TPage(pgIter->name+".xml");
14 andreas 2535
 
83 andreas 2536
            if (TError::isError())
2537
            {
2538
                delete page;
2539
                return false;
2540
            }
3 andreas 2541
 
83 andreas 2542
            page->setPalette(mPalette);
2543
            page->setFonts(mFonts);
2544
            page->registerCallback(_setBackground);
2545
            page->registerCallbackDB(_displayButton);
2546
            page->regCallPlayVideo(_callPlayVideo);
2547
 
2548
            if (!addPage(page))
2549
                return false;
2550
        }
3 andreas 2551
    }
2552
 
348 andreas 2553
    vector<SUBPAGELIST_T> subPageList = mPageList->getSubPageList();
3 andreas 2554
 
83 andreas 2555
    if (subPageList.size() > 0)
3 andreas 2556
    {
83 andreas 2557
        vector<SUBPAGELIST_T>::iterator spgIter;
14 andreas 2558
 
118 andreas 2559
        for (spgIter = subPageList.begin(); spgIter != subPageList.end(); ++spgIter)
14 andreas 2560
        {
83 andreas 2561
            TSubPage *page = new TSubPage(spgIter->name+".xml");
14 andreas 2562
 
83 andreas 2563
            if (TError::isError())
2564
            {
2565
                delete page;
2566
                return false;
2567
            }
3 andreas 2568
 
83 andreas 2569
            page->setPalette(mPalette);
2570
            page->setFonts(mFonts);
2571
            page->registerCallback(_setBackground);
2572
            page->registerCallbackDB(_displayButton);
2573
            page->regCallDropSubPage(_callDropSubPage);
2574
            page->regCallPlayVideo(_callPlayVideo);
2575
            page->setGroup(spgIter->group);
2576
 
2577
            if (!addSubPage(page))
2578
                return false;
2579
        }
3 andreas 2580
    }
2581
 
2582
    return true;
2583
}
2584
 
2585
bool TPageManager::readPage(const std::string& name)
2586
{
2587
    DECL_TRACER("TPageManager::readPage(const std::string& name)");
2588
 
2589
    PAGELIST_T page = findPage(name);
2590
 
206 andreas 2591
    if ((page.pageID <= 0 || page.pageID >= MAX_PAGE_ID) && page.pageID < SYSTEM_PAGE_START && page.pageID >= SYSTEM_SUBPAGE_START)
3 andreas 2592
    {
2593
        MSG_ERROR("Page " << name << " not found!");
2594
        return false;
2595
    }
2596
 
43 andreas 2597
    TPage *pg;
14 andreas 2598
 
43 andreas 2599
    if (name.compare("_progress") == 0)
2600
        pg = new TPage(name);
2601
    else
2602
        pg = new TPage(page.name+".xml");
2603
 
14 andreas 2604
    if (TError::isError())
2605
    {
2606
        delete pg;
2607
        return false;
2608
    }
2609
 
4 andreas 2610
    pg->setPalette(mPalette);
7 andreas 2611
    pg->setFonts(mFonts);
2612
    pg->registerCallback(_setBackground);
2613
    pg->registerCallbackDB(_displayButton);
21 andreas 2614
    pg->regCallPlayVideo(_callPlayVideo);
3 andreas 2615
 
2616
    if (!addPage(pg))
2617
        return false;
2618
 
2619
    return true;
2620
}
2621
 
2622
bool TPageManager::readPage(int ID)
2623
{
2624
    DECL_TRACER("TPageManager::readPage(int ID)");
2625
 
16 andreas 2626
    TError::clear();
3 andreas 2627
    PAGELIST_T page = findPage(ID);
2628
 
2629
    if (page.pageID <= 0)
2630
    {
2631
        MSG_ERROR("Page with ID " << ID << " not found!");
2632
        return false;
2633
    }
2634
 
43 andreas 2635
    TPage *pg;
14 andreas 2636
 
43 andreas 2637
    if (ID == 300)      // Progress page of system?
2638
        pg = new TPage("_progress");
2639
    else
2640
        pg = new TPage(page.name+".xml");
2641
 
14 andreas 2642
    if (TError::isError())
2643
    {
2644
        delete pg;
2645
        return false;
2646
    }
2647
 
4 andreas 2648
    pg->setPalette(mPalette);
7 andreas 2649
    pg->setFonts(mFonts);
2650
    pg->registerCallback(_setBackground);
2651
    pg->registerCallbackDB(_displayButton);
21 andreas 2652
    pg->regCallPlayVideo(_callPlayVideo);
3 andreas 2653
 
2654
    if (!addPage(pg))
2655
        return false;
2656
 
2657
    return true;
2658
}
2659
 
2660
bool TPageManager::readSubPage(const std::string& name)
2661
{
2662
    DECL_TRACER("TPageManager::readSubPage(const std::string& name)");
2663
 
16 andreas 2664
    TError::clear();
3 andreas 2665
    SUBPAGELIST_T page = findSubPage(name);
2666
 
206 andreas 2667
    if (page.pageID < MAX_PAGE_ID || (page.pageID >= SYSTEM_PAGE_START && page.pageID < SYSTEM_SUBPAGE_START))
3 andreas 2668
    {
2669
        MSG_ERROR("Subpage " << name << " not found!");
2670
        return false;
2671
    }
2672
 
14 andreas 2673
    if (haveSubPage(name))
2674
        return true;
2675
 
3 andreas 2676
    TSubPage *pg = new TSubPage(page.name+".xml");
14 andreas 2677
 
2678
    if (TError::isError())
2679
    {
2680
        delete pg;
2681
        return false;
2682
    }
2683
 
4 andreas 2684
    pg->setPalette(mPalette);
7 andreas 2685
    pg->setFonts(mFonts);
2686
    pg->registerCallback(_setBackground);
2687
    pg->registerCallbackDB(_displayButton);
11 andreas 2688
    pg->regCallDropSubPage(_callDropSubPage);
21 andreas 2689
    pg->regCallPlayVideo(_callPlayVideo);
11 andreas 2690
    pg->setGroup(page.group);
3 andreas 2691
 
2692
    if (!addSubPage(pg))
14 andreas 2693
    {
2694
        delete pg;
3 andreas 2695
        return false;
14 andreas 2696
    }
3 andreas 2697
 
2698
    return true;
2699
}
2700
 
2701
bool TPageManager::readSubPage(int ID)
2702
{
2703
    DECL_TRACER("TPageManager::readSubPage(int ID)");
2704
 
16 andreas 2705
    TError::clear();
3 andreas 2706
    SUBPAGELIST_T page = findSubPage(ID);
2707
 
154 andreas 2708
    if (page.pageID <= MAX_PAGE_ID)
3 andreas 2709
    {
2710
        MSG_ERROR("Subpage with ID " << ID << " not found!");
2711
        return false;
2712
    }
2713
 
2714
    TSubPage *pg = new TSubPage(page.name+".xml");
14 andreas 2715
 
2716
    if (TError::isError())
2717
    {
2718
        delete pg;
2719
        return false;
2720
    }
2721
 
4 andreas 2722
    pg->setPalette(mPalette);
7 andreas 2723
    pg->setFonts(mFonts);
2724
    pg->registerCallback(_setBackground);
2725
    pg->registerCallbackDB(_displayButton);
11 andreas 2726
    pg->regCallDropSubPage(_callDropSubPage);
21 andreas 2727
    pg->regCallPlayVideo(_callPlayVideo);
11 andreas 2728
    pg->setGroup(page.group);
3 andreas 2729
 
2730
    if (!addSubPage(pg))
2731
        return false;
2732
 
2733
    return true;
2734
}
2735
 
279 andreas 2736
vector<TSubPage *> TPageManager::createSubViewList(int id)
2737
{
2738
    DECL_TRACER("TPageManager::createSubViewList(int id)");
2739
 
2740
    vector<TSubPage *> subviews;
2741
 
2742
    if (id <= 0)
2743
        return subviews;
2744
 
2745
    if (!mPageList)
2746
    {
2747
        MSG_WARNING("Missing page list and because of this can't make a subview list!");
2748
        return subviews;
2749
    }
2750
 
2751
    SUBVIEWLIST_T slist = mPageList->findSubViewList(id);
2752
 
2753
    if (slist.id <= 0 || slist.items.empty())
2754
    {
2755
        if (slist.id <= 0)
2756
        {
2757
            MSG_WARNING("Found no subview list with ID " << id);
2758
        }
2759
        else
2760
        {
300 andreas 2761
            MSG_WARNING("Subview list " << id << " has no items!");
279 andreas 2762
        }
2763
 
2764
        return subviews;
2765
    }
2766
 
2767
    vector<SUBVIEWITEM_T>::iterator iter;
2768
 
2769
    for (iter = slist.items.begin(); iter != slist.items.end(); ++iter)
2770
    {
2771
        if (!haveSubPage(iter->pageID))
2772
        {
2773
            if (!readSubPage(iter->pageID))
2774
                return vector<TSubPage *>();
2775
        }
2776
 
284 andreas 2777
        TSubPage *pg = getSubPage(iter->pageID);
279 andreas 2778
 
2779
        if (pg)
2780
            subviews.push_back(pg);
284 andreas 2781
        else
2782
        {
2783
            MSG_DEBUG("No subpage with ID " << id);
2784
        }
279 andreas 2785
    }
2786
 
300 andreas 2787
    MSG_DEBUG("Found " << subviews.size() << " subview items.");
279 andreas 2788
    return subviews;
2789
}
2790
 
280 andreas 2791
void TPageManager::showSubViewList(int id, Button::TButton *bt)
279 andreas 2792
{
280 andreas 2793
    DECL_TRACER("TPageManager::showSubViewList(int id, Button::TButton *bt)");
279 andreas 2794
 
2795
    vector<TSubPage *> subviews = createSubViewList(id);
2796
 
303 andreas 2797
    if (subviews.empty() || !_addViewButtonItems || !bt)
284 andreas 2798
    {
2799
        MSG_DEBUG("Number views: " << subviews.size() << (_addViewButtonItems ? ", addView" : ", NO addView") << (_displayViewButton ? " display" : " NO display"));
279 andreas 2800
        return;
284 andreas 2801
    }
279 andreas 2802
 
293 andreas 2803
    ulong btHandle = bt->getHandle();
2804
    MSG_DEBUG("Working on button " << handleToString(btHandle) << " (" << bt->getName() << ") with " << subviews.size() << " pages.");
289 andreas 2805
    TBitmap bm = bt->getLastBitmap();
2806
    TColor::COLOR_T fillColor = TColor::getAMXColor(bt->getFillColor());
293 andreas 2807
    _displayViewButton(btHandle, bt->getParent(), bt->isSubViewVertical(), bm, bt->getWidth(), bt->getHeight(), bt->getLeftPosition(), bt->getTopPosition(), bt->getSubViewSpace(), fillColor);
280 andreas 2808
 
2809
    vector<PGSUBVIEWITEM_T> items;
2810
    PGSUBVIEWITEM_T svItem;
2811
    PGSUBVIEWATOM_T svAtom;
279 andreas 2812
    vector<TSubPage *>::iterator iter;
2813
 
2814
    for (iter = subviews.begin(); iter != subviews.end(); ++iter)
2815
    {
280 andreas 2816
        TSubPage *sub = *iter;
306 andreas 2817
        sub->setParent(btHandle);
279 andreas 2818
 
289 andreas 2819
        svItem.clear();
2820
        Button::TButton *button = sub->getFirstButton();
2821
        SkBitmap bitmap = sub->getBgImage();
280 andreas 2822
 
2823
        svItem.handle = sub->getHandle();
289 andreas 2824
        svItem.parent = btHandle;
280 andreas 2825
        svItem.width = sub->getWidth();
2826
        svItem.height = sub->getHeight();
281 andreas 2827
        svItem.bgcolor = TColor::getAMXColor(sub->getFillColor());
300 andreas 2828
        svItem.scrollbar = bt->getSubViewScrollbar();
2829
        svItem.scrollbarOffset = bt->getSubViewScrollbarOffset();
2830
        svItem.position = bt->getSubViewAnchor();
302 andreas 2831
        svItem.wrap = bt->getWrapSubViewPages();
280 andreas 2832
 
289 andreas 2833
        if (!bitmap.empty())
2834
            svItem.image.setBitmap((unsigned char *)bitmap.getPixels(), bitmap.info().width(), bitmap.info().height(), bitmap.info().bytesPerPixel());
280 andreas 2835
 
289 andreas 2836
        while (button)
280 andreas 2837
        {
300 andreas 2838
            button->drawButton(0, false, true);
289 andreas 2839
            svAtom.clear();
2840
            svAtom.handle = button->getHandle();
280 andreas 2841
            svAtom.parent = sub->getHandle();
289 andreas 2842
            svAtom.width = button->getWidth();
2843
            svAtom.height = button->getHeight();
2844
            svAtom.left = button->getLeftPosition();
2845
            svAtom.top = button->getTopPosition();
300 andreas 2846
            svAtom.bgcolor = TColor::getAMXColor(button->getFillColor(button->getActiveInstance()));
293 andreas 2847
            svAtom.bounding = button->getBounding();
289 andreas 2848
            Button::BITMAP_t bmap = button->getLastImage();
280 andreas 2849
 
289 andreas 2850
            if (bmap.buffer)
300 andreas 2851
                svAtom.image.setBitmap(bmap.buffer, bmap.width, bmap.height, (int)(bmap.rowBytes / bmap.width));
289 andreas 2852
 
280 andreas 2853
            svItem.atoms.push_back(svAtom);
289 andreas 2854
            button = sub->getNextButton();
280 andreas 2855
        }
2856
 
2857
        items.push_back(svItem);
279 andreas 2858
    }
281 andreas 2859
 
285 andreas 2860
    _addViewButtonItems(bt->getHandle(), items);
284 andreas 2861
 
2862
    if (_pageFinished)
306 andreas 2863
        _pageFinished(bt->getHandle());
279 andreas 2864
}
2865
 
300 andreas 2866
void TPageManager::updateSubViewItem(Button::TButton *bt)
2867
{
2868
    DECL_TRACER("TPageManager::updateSubViewItem(Button::TButton *bt)");
2869
 
303 andreas 2870
    if (!bt)
300 andreas 2871
        return;
2872
 
303 andreas 2873
    updview_mutex.lock();
2874
    mUpdateViews.push_back(bt);
2875
    updview_mutex.unlock();
2876
}
2877
 
2878
void TPageManager::_updateSubViewItem(Button::TButton *bt)
2879
{
2880
    DECL_TRACER("TPageManager::_updateSubViewItem(Button::TButton *bt)");
2881
 
2882
    if (!mPageList || !_updateViewButtonItem)
2883
        return;
2884
 
300 andreas 2885
    // The parent of this kind of button is always the button of type subview.
2886
    // If we take the parent handle and extract the page ID (upper 16 bits)
2887
    // we get the page ID of the subpage or page ID of the page the button is
2888
    // ordered to.
2889
    int pageID = (bt->getParent() >> 16) & 0x0000ffff;
306 andreas 2890
    ulong parent = 0;
300 andreas 2891
    Button::TButton *button = nullptr;
2892
    PGSUBVIEWITEM_T item;
2893
    PGSUBVIEWATOM_T atom;
2894
    SkBitmap bitmap;
2895
    TPage *pg = nullptr;
2896
    TSubPage *sub = nullptr;
2897
 
2898
    if (pageID < REGULAR_SUBPAGE_START)     // Is it a page?
2899
    {
2900
        pg = getPage(pageID);
2901
 
2902
        if (!pg)
2903
        {
2904
            MSG_WARNING("Invalid page " << pageID << "!");
2905
            return;
2906
        }
2907
 
2908
        button = pg->getFirstButton();
2909
        bitmap = pg->getBgImage();
2910
 
2911
        item.handle = pg->getHandle();
2912
        item.parent = bt->getParent();
2913
        item.width = pg->getWidth();
2914
        item.height = pg->getHeight();
2915
        item.bgcolor = TColor::getAMXColor(pg->getFillColor());
2916
    }
2917
    else
2918
    {
2919
        sub = getSubPage(pageID);
2920
 
2921
        if (!sub)
2922
        {
2923
            MSG_WARNING("Couldn't find the subpage " << pageID << "!");
2924
            return;
2925
        }
2926
 
306 andreas 2927
        parent = sub->getParent();
300 andreas 2928
        button = sub->getFirstButton();
2929
        bitmap = sub->getBgImage();
2930
 
2931
        item.handle = sub->getHandle();
2932
        item.parent = bt->getParent();
2933
        item.width = sub->getWidth();
2934
        item.height = sub->getHeight();
303 andreas 2935
        item.position = bt->getSubViewAnchor();
300 andreas 2936
        item.bgcolor = TColor::getAMXColor(sub->getFillColor());
2937
    }
2938
 
2939
 
2940
    if (!bitmap.empty())
2941
        item.image.setBitmap((unsigned char *)bitmap.getPixels(), bitmap.info().width(), bitmap.info().height(), bitmap.info().bytesPerPixel());
2942
 
2943
    while (button)
2944
    {
2945
        atom.clear();
2946
        atom.handle = button->getHandle();
303 andreas 2947
        atom.parent = item.handle;
300 andreas 2948
        atom.width = button->getWidth();
2949
        atom.height = button->getHeight();
2950
        atom.left = button->getLeftPosition();
2951
        atom.top = button->getTopPosition();
2952
        atom.bgcolor = TColor::getAMXColor(button->getFillColor(button->getActiveInstance()));
2953
        atom.bounding = button->getBounding();
2954
        Button::BITMAP_t bmap = button->getLastImage();
2955
 
2956
        if (bmap.buffer)
2957
            atom.image.setBitmap(bmap.buffer, bmap.width, bmap.height, (int)(bmap.rowBytes / bmap.width));
2958
 
2959
        item.atoms.push_back(atom);
2960
        button = (pg ? pg->getNextButton() : sub->getNextButton());
2961
    }
2962
 
306 andreas 2963
    _updateViewButtonItem(item, parent);
300 andreas 2964
}
2965
 
192 andreas 2966
void TPageManager::updateActualPage()
2967
{
2968
    DECL_TRACER("TPageManager::updateActualPage()");
2969
 
2970
    if (!mActualPage)
2971
        return;
2972
 
2973
    TPage *pg = getPage(mActualPage);
2974
    Button::TButton *bt = pg->getFirstButton();
2975
 
2976
    while (bt)
2977
    {
2978
        bt->refresh();
2979
        bt = pg->getNextButton();
2980
    }
2981
}
2982
 
2983
void TPageManager::updateSubpage(int ID)
2984
{
2985
    DECL_TRACER("TPageManager::updateSubpage(int ID)");
2986
 
2987
    TSubPage *pg = getSubPage(ID);
2988
 
2989
    if (!pg)
2990
        return;
2991
 
2992
    vector<Button::TButton *> blist = pg->getAllButtons();
2993
    vector<Button::TButton *>::iterator iter;
2994
 
2995
    if (blist.empty())
2996
        return;
2997
 
2998
    for (iter = blist.begin(); iter != blist.end(); ++iter)
2999
    {
3000
        Button::TButton *bt = *iter;
3001
        bt->refresh();
3002
    }
3003
}
3004
 
3005
void TPageManager::updateSubpage(const std::string &name)
3006
{
3007
    DECL_TRACER("TPageManager::updateSubpage(const std::string &name)");
3008
 
3009
    TSubPage *pg = getSubPage(name);
3010
 
3011
    if (!pg)
3012
        return;
3013
 
3014
    vector<Button::TButton *> blist = pg->getAllButtons();
3015
    vector<Button::TButton *>::iterator iter;
3016
 
3017
    if (blist.empty())
3018
        return;
3019
 
3020
    for (iter = blist.begin(); iter != blist.end(); ++iter)
3021
    {
3022
        Button::TButton *bt = *iter;
3023
        bt->refresh();
3024
    }
3025
}
3026
 
3 andreas 3027
/******************** Internal private methods *********************/
3028
 
3029
PAGELIST_T TPageManager::findPage(const std::string& name)
3030
{
3031
    DECL_TRACER("TPageManager::findPage(const std::string& name)");
3032
 
194 andreas 3033
    vector<PAGELIST_T> pageList;
3 andreas 3034
 
194 andreas 3035
    if (!mSetupActive)
3036
        pageList = mPageList->getPagelist();
3037
    else
3038
        pageList = mPageList->getSystemPagelist();
3039
 
83 andreas 3040
    if (pageList.size() > 0)
3 andreas 3041
    {
83 andreas 3042
        vector<PAGELIST_T>::iterator pgIter;
3043
 
118 andreas 3044
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 3045
        {
3046
            if (pgIter->name.compare(name) == 0)
3047
                return *pgIter;
3048
        }
3 andreas 3049
    }
3050
 
194 andreas 3051
    MSG_WARNING("Page " << name << " not found!");
3 andreas 3052
    return PAGELIST_T();
3053
}
3054
 
3055
PAGELIST_T TPageManager::findPage(int ID)
3056
{
3057
    DECL_TRACER("TPageManager::findPage(int ID)");
3058
 
206 andreas 3059
    vector<PAGELIST_T> pageList = (ID < SYSTEM_PAGE_START ? mPageList->getPagelist() : mPageList->getSystemPagelist());
3 andreas 3060
 
83 andreas 3061
    if (pageList.size() > 0)
3 andreas 3062
    {
83 andreas 3063
        vector<PAGELIST_T>::iterator pgIter;
3064
 
118 andreas 3065
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 3066
        {
3067
            if (pgIter->pageID == ID)
3068
                return *pgIter;
3069
        }
3 andreas 3070
    }
3071
 
3072
    return PAGELIST_T();
3073
}
3074
 
3075
SUBPAGELIST_T TPageManager::findSubPage(const std::string& name)
3076
{
3077
    DECL_TRACER("TPageManager::findSubPage(const std::string& name)");
3078
 
348 andreas 3079
    vector<SUBPAGELIST_T> pageList = (mSetupActive ? mPageList->getSystemSupPageList() : mPageList->getSubPageList());
3 andreas 3080
 
83 andreas 3081
    if (pageList.size() > 0)
3 andreas 3082
    {
83 andreas 3083
        vector<SUBPAGELIST_T>::iterator pgIter;
3084
 
118 andreas 3085
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 3086
        {
3087
            if (pgIter->name.compare(name) == 0)
3088
                return *pgIter;
3089
        }
3 andreas 3090
    }
3091
 
3092
    return SUBPAGELIST_T();
3093
}
3094
 
3095
SUBPAGELIST_T TPageManager::findSubPage(int ID)
3096
{
3097
    DECL_TRACER("TPageManager::findSubPage(int ID)");
3098
 
348 andreas 3099
    vector<SUBPAGELIST_T> pageList = (ID < SYSTEM_PAGE_START ? mPageList->getSubPageList() : mPageList->getSystemSupPageList());
3 andreas 3100
 
83 andreas 3101
    if (pageList.size() > 0)
3 andreas 3102
    {
83 andreas 3103
        vector<SUBPAGELIST_T>::iterator pgIter;
3104
 
118 andreas 3105
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 3106
        {
3107
            if (pgIter->pageID == ID)
3108
                return *pgIter;
3109
        }
3 andreas 3110
    }
3111
 
3112
    return SUBPAGELIST_T();
3113
}
3114
 
3115
bool TPageManager::addPage(TPage* pg)
3116
{
3117
    DECL_TRACER("TPageManager::addPage(TPage* pg)");
3118
 
3119
    if (!pg)
3120
    {
3121
        MSG_ERROR("Parameter is NULL!");
3122
        TError::setError();
3123
        return false;
3124
    }
3125
 
3126
    PCHAIN_T *chain = new PCHAIN_T;
3127
    chain->page = pg;
5 andreas 3128
    chain->next = nullptr;
3 andreas 3129
 
3130
    if (mPchain)
3131
    {
3132
        PCHAIN_T *p = mPchain;
3133
 
3134
        while (p->next)
3135
            p = p->next;
3136
 
3137
        p->next = chain;
3138
    }
3139
    else
14 andreas 3140
    {
3 andreas 3141
        mPchain = chain;
14 andreas 3142
        setPChain(mPchain);
3143
    }
3 andreas 3144
 
156 andreas 3145
//    MSG_DEBUG("Added page " << chain->page->getName());
3 andreas 3146
    return true;
3147
}
3148
 
3149
bool TPageManager::addSubPage(TSubPage* pg)
3150
{
3151
    DECL_TRACER("TPageManager::addSubPage(TSubPage* pg)");
3152
 
3153
    if (!pg)
3154
    {
3155
        MSG_ERROR("Parameter is NULL!");
3156
        TError::setError();
3157
        return false;
3158
    }
3159
 
14 andreas 3160
    if (haveSubPage(pg->getNumber()))
3161
    {
3162
        MSG_ERROR("Subpage " << pg->getNumber() << ", " << pg->getName() << " is already in chain!");
3163
        return false;
3164
    }
3165
 
3 andreas 3166
    SPCHAIN_T *chain = new SPCHAIN_T;
3167
    chain->page = pg;
5 andreas 3168
    chain->next = nullptr;
3 andreas 3169
 
3170
    if (mSPchain)
3171
    {
3172
        SPCHAIN_T *p = mSPchain;
3173
 
3174
        while (p->next)
3175
            p = p->next;
3176
 
3177
        p->next = chain;
3178
    }
3179
    else
14 andreas 3180
    {
3 andreas 3181
        mSPchain = chain;
14 andreas 3182
        setSPChain(mSPchain);
3183
    }
3 andreas 3184
 
3185
    return true;
3186
}
4 andreas 3187
 
11 andreas 3188
void TPageManager::dropAllPages()
3189
{
3190
    DECL_TRACER("TPageManager::dropAllPages()");
3191
 
3192
    PCHAIN_T *pg = mPchain;
3193
    PCHAIN_T *next = nullptr;
3194
 
3195
    while (pg)
3196
    {
3197
        next = pg->next;
3198
 
3199
        if (pg->page)
3200
        {
3201
            if (_callDropPage)
3202
                _callDropPage((pg->page->getNumber() << 16) & 0xffff0000);
3203
 
3204
            delete pg->page;
3205
        }
3206
 
3207
        delete pg;
3208
        pg = next;
3209
    }
14 andreas 3210
 
3211
    mPchain = nullptr;
3212
    setPChain(mPchain);
11 andreas 3213
}
3214
 
3215
void TPageManager::dropAllSubPages()
3216
{
3217
    DECL_TRACER("TPageManager::dropAllSubPages()");
3218
 
3219
    SPCHAIN_T *spg = mSPchain;
3220
    SPCHAIN_T *next;
3221
 
3222
    while (spg)
3223
    {
3224
        next = spg->next;
3225
 
3226
        if (spg->page)
3227
        {
3228
            if (_callDropSubPage)
350 andreas 3229
                _callDropSubPage((spg->page->getNumber() << 16) & 0xffff0000, spg->page->getParent());
11 andreas 3230
 
3231
            delete spg->page;
3232
        }
3233
 
3234
        delete spg;
3235
        spg = next;
3236
    }
14 andreas 3237
 
3238
    mSPchain = nullptr;
3239
    setSPChain(mSPchain);
11 andreas 3240
}
3241
 
44 andreas 3242
bool TPageManager::destroyAll()
3243
{
3244
    DECL_TRACER("TPageManager::destroyAll()");
3245
 
3246
    dropAllSubPages();
3247
    dropAllPages();
3248
    mActualPage = 0;
3249
    mPreviousPage = 0;
3250
    mActualGroupName.clear();
3251
 
3252
    if (mPageList)
3253
    {
3254
        delete mPageList;
3255
        mPageList = nullptr;
3256
    }
3257
 
3258
    if (mTSettings)
3259
    {
3260
        delete mTSettings;
3261
        mTSettings = nullptr;
3262
    }
3263
 
194 andreas 3264
    if (mSystemSettings)
3265
    {
3266
        delete mSystemSettings;
3267
        mSystemSettings = nullptr;
3268
    }
3269
 
44 andreas 3270
    if (mPalette)
3271
    {
3272
        delete mPalette;
3273
        mPalette = nullptr;
3274
    }
3275
 
3276
    if (mFonts)
3277
    {
3278
        delete mFonts;
3279
        mFonts = nullptr;
3280
    }
3281
 
3282
    if (mExternal)
3283
    {
3284
        delete mExternal;
3285
        mExternal = nullptr;
3286
    }
3287
 
3288
    if (gPrjResources)
3289
    {
3290
        delete gPrjResources;
3291
        gPrjResources = nullptr;
3292
    }
3293
 
3294
    if (gIcons)
3295
    {
3296
        delete gIcons;
3297
        gIcons = nullptr;
3298
    }
3299
 
3300
    if (TError::isError())
3301
        return false;
3302
 
3303
    return true;
3304
}
3305
 
150 andreas 3306
bool TPageManager::overlap(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2)
3307
{
3308
    DECL_TRACER("TPageManager::overlap(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2)");
3309
 
3310
    struct point
3311
    {
3312
        int x;
3313
        int y;
3314
    };
3315
 
3316
    struct point l1, r1, l2, r2;
3317
 
3318
    l1.x = x1;
3319
    l1.y = y1;
3320
    r1.x = x1 + w1;
3321
    r1.y = y1 + h1;
3322
 
3323
    l2.x = x2;
3324
    l2.y = y2;
3325
    r2.x = x2 + w2;
3326
    r2.y = y2 + h2;
3327
 
3328
    if (l1.x == r1.x || l1.y == r1.y || l2.x == r2.x || l2.y == r2.y)
3329
    {
3330
        // the line cannot have positive overlap
3331
        return false;
3332
    }
3333
 
183 andreas 3334
    return std::max(l1.x, l2.x) < std::min(r1.x, r2.x) &&
150 andreas 3335
           std::max(l1.y, l2.y) < std::min(r1.y, r2.y);
3336
}
3337
 
51 andreas 3338
Button::TButton *TPageManager::findButton(ulong handle)
3339
{
3340
    DECL_TRACER("TPageManager::findButton(ulong handle)");
3341
 
209 andreas 3342
    if (!handle)
3343
        return nullptr;
3344
 
51 andreas 3345
    TPage *pg = getPage(mActualPage);
3346
 
3347
    if (!pg)
3348
        return nullptr;
3349
 
3350
    vector<Button::TButton *> pgBtList = pg->getAllButtons();
3351
    vector<Button::TButton *>::iterator iter;
83 andreas 3352
 
3353
    if (pgBtList.size() > 0)
51 andreas 3354
    {
83 andreas 3355
        // First we look into the elements of the page
3356
        for (iter = pgBtList.begin(); iter != pgBtList.end(); ++iter)
3357
        {
3358
            Button::TButton *bt = *iter;
51 andreas 3359
 
83 andreas 3360
            if (bt->getHandle() == handle)
3361
                return bt;
3362
        }
51 andreas 3363
    }
3364
 
3365
    // We've not found the wanted element in the elements of the page. So
3366
    // we're looking at the elements of the subpages.
3367
    TSubPage *sp = pg->getFirstSubPage();
3368
 
3369
    if (!sp)
3370
        return nullptr;
3371
 
3372
    while (sp)
3373
    {
3374
        vector<Button::TButton *> spBtList = sp->getAllButtons();
3375
 
83 andreas 3376
        if (spBtList.size() > 0)
51 andreas 3377
        {
83 andreas 3378
            for (iter = spBtList.begin(); iter != spBtList.end(); ++iter)
3379
            {
3380
                Button::TButton *bt = *iter;
51 andreas 3381
 
83 andreas 3382
                if (bt->getHandle() == handle)
3383
                    return bt;
3384
            }
51 andreas 3385
        }
3386
 
3387
        sp = pg->getNextSubPage();
3388
    }
3389
 
3390
    return nullptr;
3391
}
3392
 
4 andreas 3393
TPage *TPageManager::getActualPage()
3394
{
168 andreas 3395
    DECL_TRACER("TPageManager::getActualPage()");
3396
 
4 andreas 3397
    return getPage(mActualPage);
3398
}
3399
 
3400
TSubPage *TPageManager::getFirstSubPage()
3401
{
3402
    DECL_TRACER("TPageManager::getFirstSubPage()");
168 andreas 3403
 
349 andreas 3404
    mLastSubPage = 0;
4 andreas 3405
    TPage *pg = getPage(mActualPage);
3406
 
3407
    if (!pg)
3408
        return nullptr;
3409
 
349 andreas 3410
    map<int, TSubPage *> sp = pg->getSortedSubpages(true);
3411
 
3412
    if (!sp.empty())
3413
    {
3414
        map<int, TSubPage *>::iterator iter = sp.begin();
3415
        mLastSubPage = iter->first;
3416
        return iter->second;
3417
    }
3418
 
3419
    return nullptr;
4 andreas 3420
}
3421
 
3422
TSubPage *TPageManager::getNextSubPage()
3423
{
3424
    DECL_TRACER("TPageManager::getNextSubPage()");
3425
 
3426
    TPage *pg = getPage(mActualPage);
3427
 
3428
    if (pg)
349 andreas 3429
    {
3430
        map<int, TSubPage *> sp = pg->getSortedSubpages();
4 andreas 3431
 
349 andreas 3432
        if (sp.empty())
3433
        {
3434
            mLastSubPage = 0;
3435
            return nullptr;
3436
        }
3437
        else
3438
        {
3439
            map<int, TSubPage *>::iterator iter = sp.find(mLastSubPage);
3440
 
3441
            if (iter != sp.end())
3442
            {
3443
                iter++;
3444
 
3445
                if (iter != sp.end())
3446
                {
3447
                    mLastSubPage = iter->first;
3448
                    return iter->second;
3449
                }
3450
            }
3451
        }
3452
    }
3453
 
3454
    mLastSubPage = 0;
4 andreas 3455
    return nullptr;
3456
}
10 andreas 3457
 
154 andreas 3458
TSubPage *TPageManager::getPrevSubPage()
3459
{
3460
    DECL_TRACER("TPageManager::getPrevSubPage()");
3461
 
3462
    TPage *pg = getPage(mActualPage);
3463
 
3464
    if (pg)
349 andreas 3465
    {
3466
        map<int, TSubPage *> sp = pg->getSortedSubpages();
154 andreas 3467
 
349 andreas 3468
        if (sp.empty())
3469
        {
3470
            mLastSubPage = 0;
3471
            return nullptr;
3472
        }
3473
        else
3474
        {
3475
            map<int, TSubPage *>::iterator iter = sp.find(mLastSubPage);
3476
 
3477
            if (iter != sp.end() && iter != sp.begin())
3478
            {
3479
                iter--;
3480
                mLastSubPage = iter->first;
3481
                return iter->second;
3482
            }
3483
 
3484
            MSG_DEBUG("Page " << mLastSubPage << " not found!");
3485
        }
3486
    }
3487
 
3488
    mLastSubPage = 0;
154 andreas 3489
    return nullptr;
3490
}
3491
 
3492
TSubPage *TPageManager::getLastSubPage()
3493
{
3494
    DECL_TRACER("TPageManager::getLastSubPage()");
3495
 
349 andreas 3496
    mLastSubPage = 0;
154 andreas 3497
    TPage *pg = getPage(mActualPage);
3498
 
3499
    if (pg)
3500
    {
349 andreas 3501
        map<int, TSubPage *> sp = pg->getSortedSubpages(true);
3502
 
3503
        if (sp.empty())
3504
            return nullptr;
3505
        else
3506
        {
3507
            map<int, TSubPage *>::iterator iter = sp.end();
3508
            iter--;
3509
            mLastSubPage = iter->first;
3510
            return iter->second;
3511
        }
154 andreas 3512
    }
3513
    else
3514
    {
3515
        MSG_WARNING("Actual page " << mActualPage << " not found!");
3516
    }
3517
 
3518
    return nullptr;
3519
}
3520
 
11 andreas 3521
TSubPage *TPageManager::getFirstSubPageGroup(const string& group)
3522
{
3523
    DECL_TRACER("TPageManager::getFirstSubPageGroup(const string& group)");
3524
 
14 andreas 3525
    if (group.empty())
3526
    {
3527
        MSG_WARNING("Empty group name is invalid. Ignoring it!");
3528
        mActualGroupName.clear();
3529
        mActualGroupPage = nullptr;
3530
        return nullptr;
3531
    }
3532
 
11 andreas 3533
    mActualGroupName = group;
3534
    TSubPage *pg = getFirstSubPage();
3535
 
3536
    while (pg)
3537
    {
14 andreas 3538
        MSG_DEBUG("Evaluating group " << pg->getGroupName() << " with " << group);
3539
 
11 andreas 3540
        if (pg->getGroupName().compare(group) == 0)
3541
        {
3542
            mActualGroupPage = pg;
3543
            return pg;
3544
        }
3545
 
3546
        pg = getNextSubPage();
3547
    }
3548
 
3549
    mActualGroupName.clear();
3550
    mActualGroupPage = nullptr;
3551
    return nullptr;
3552
}
3553
 
3554
TSubPage *TPageManager::getNextSubPageGroup()
3555
{
3556
    DECL_TRACER("TPageManager::getNextSubPageGroup()");
3557
 
3558
    if (mActualGroupName.empty())
3559
        return nullptr;
3560
 
3561
    TSubPage *pg = getFirstSubPage();
3562
    bool found = false;
3563
 
3564
    while (pg)
3565
    {
14 andreas 3566
        MSG_DEBUG("Evaluating group " << pg->getGroupName() << " with " << mActualGroupName);
3567
 
3568
        if (!found && pg == mActualGroupPage)
11 andreas 3569
        {
3570
            pg = getNextSubPage();
14 andreas 3571
            found = true;
11 andreas 3572
            continue;
3573
        }
3574
 
14 andreas 3575
        if (found && pg->getGroupName().compare(mActualGroupName) == 0)
11 andreas 3576
        {
3577
            mActualGroupPage = pg;
3578
            return pg;
3579
        }
3580
 
3581
        pg = getNextSubPage();
3582
    }
3583
 
3584
    mActualGroupName.clear();
3585
    mActualGroupPage = nullptr;
3586
    return nullptr;
3587
}
3588
 
3589
TSubPage *TPageManager::getNextSubPageGroup(const string& group, TSubPage* pg)
3590
{
3591
    DECL_TRACER("TPageManager::getNextSubPageGroup(const string& group, TSubPage* pg)");
3592
 
3593
    if (group.empty() || !pg)
3594
        return nullptr;
3595
 
3596
    TSubPage *page = getFirstSubPage();
3597
    bool found = false;
3598
 
3599
    while (page)
3600
    {
14 andreas 3601
        MSG_DEBUG("Evaluating group " << pg->getGroupName() << " with " << group);
3602
 
3603
        if (!found && pg == page)
11 andreas 3604
        {
3605
            page = getNextSubPage();
14 andreas 3606
            found = true;
11 andreas 3607
            continue;
3608
        }
3609
 
14 andreas 3610
        if (found && page->getGroupName().compare(group) == 0)
11 andreas 3611
            return page;
3612
 
3613
        page = getNextSubPage();
3614
    }
3615
 
3616
    return nullptr;
3617
}
3618
 
3619
TSubPage *TPageManager::getTopPage()
3620
{
3621
    DECL_TRACER("TPageManager::getTopPage()");
3622
 
3623
    // Scan for all occupied regions
3624
    vector<RECT_T> regions;
3625
 
3626
    TSubPage *pg = getFirstSubPage();
3627
 
3628
    while (pg)
3629
    {
3630
        RECT_T r = pg->getRegion();
3631
        regions.push_back(r);
3632
        pg = getNextSubPage();
3633
    }
3634
 
3635
    // Now scan all pages against all regions to find the top most
3636
    pg = getFirstSubPage();
3637
    TSubPage *top = nullptr;
3638
    int zPos = 0;
3639
 
3640
    while (pg)
3641
    {
3642
        RECT_T r = pg->getRegion();
3643
 
83 andreas 3644
        if (regions.size() > 0)
11 andreas 3645
        {
83 andreas 3646
            vector<RECT_T>::iterator iter;
3647
            int zo = 0;
11 andreas 3648
 
118 andreas 3649
            for (iter = regions.begin(); iter != regions.end(); ++iter)
83 andreas 3650
            {
3651
                if (doOverlap(*iter, r) && zPos > zo)
3652
                    top = pg;
3653
 
3654
                zo++;
3655
            }
11 andreas 3656
        }
3657
 
3658
        pg = getNextSubPage();
3659
        zPos++;
3660
    }
3661
 
3662
    return top;
3663
}
3664
 
3665
TSubPage *TPageManager::getCoordMatch(int x, int y)
3666
{
3667
    DECL_TRACER("TPageManager::getCoordMatch(int x, int y)");
3668
 
26 andreas 3669
    int realX = x;
3670
    int realY = y;
3671
 
11 andreas 3672
    // Reverse order of pages
154 andreas 3673
    TSubPage *pg = getLastSubPage();
11 andreas 3674
 
154 andreas 3675
    // Iterate in reverse order through array
11 andreas 3676
    while (pg)
3677
    {
154 andreas 3678
        if (!pg->isVisible() || pg->getZOrder() == ZORDER_INVALID)
151 andreas 3679
        {
154 andreas 3680
            pg = getPrevSubPage();
3681
            continue;
151 andreas 3682
        }
14 andreas 3683
 
154 andreas 3684
        MSG_DEBUG("Scanning subpage (Z: " << pg->getZOrder() << "): " << pg->getNumber() << ", " << pg->getName());
3685
        RECT_T r = pg->getRegion();
11 andreas 3686
 
154 andreas 3687
        if (r.left <= realX && (r.left + r.width) >= realX &&
3688
            r.top <= realY && (r.top + r.height) >= realY)
11 andreas 3689
        {
154 andreas 3690
            MSG_DEBUG("Click matches subpage " << pg->getNumber() << " (" << pg->getName() << ")");
3691
            return pg;
3692
        }
83 andreas 3693
 
154 andreas 3694
        pg = getPrevSubPage();
11 andreas 3695
    }
3696
 
3697
    return nullptr;
3698
}
3699
 
40 andreas 3700
Button::TButton *TPageManager::getCoordMatchPage(int x, int y)
3701
{
3702
    DECL_TRACER("TPageManager::getCoordMatchPage(int x, int y)");
3703
 
3704
    TPage *page = getActualPage();
3705
 
3706
    if (page)
3707
    {
150 andreas 3708
        Button::TButton *bt = page->getLastButton();
40 andreas 3709
 
3710
        while (bt)
3711
        {
150 andreas 3712
            bool clickable = bt->isClickable();
3713
            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 3714
 
150 andreas 3715
            if (!clickable)
146 andreas 3716
            {
150 andreas 3717
                bt = page->getPreviousButton();
146 andreas 3718
                continue;
3719
            }
3720
 
40 andreas 3721
            if (bt->getLeftPosition() <= x && (bt->getLeftPosition() + bt->getWidth()) >= x &&
3722
                bt->getTopPosition() <= y && (bt->getTopPosition() + bt->getHeight()) >= y)
3723
            {
154 andreas 3724
                if (!bt->isClickable(x - bt->getLeftPosition(), y - bt->getTopPosition()))
3725
                {
3726
                    bt = page->getPreviousButton();
3727
                    continue;
3728
                }
3729
 
40 andreas 3730
                MSG_DEBUG("Click matches button " << bt->getButtonIndex() << " (" << bt->getButtonName() << ")");
3731
                return bt;
3732
            }
3733
 
150 andreas 3734
            bt = page->getPreviousButton();
40 andreas 3735
        }
3736
    }
3737
 
3738
    return nullptr;
3739
}
3740
 
11 andreas 3741
bool TPageManager::doOverlap(RECT_T r1, RECT_T r2)
3742
{
3743
    DECL_TRACER("TPageManager::doOverlap(RECT_T r1, RECT_T r2)");
3744
 
3745
    // If one rectangle is on left side of other
3746
    if (r1.left >= r2.left || r2.left >= r1.left)
3747
        return false;
3748
 
3749
    // If one rectangle is above other
3750
    if (r1.top <= r2.top || r2.top <= r1.top)
3751
        return false;
3752
 
3753
    return true;
3754
}
3755
 
14 andreas 3756
bool TPageManager::havePage(const string& name)
11 andreas 3757
{
14 andreas 3758
    DECL_TRACER("TPageManager::havePage(const string& name)");
11 andreas 3759
 
14 andreas 3760
    if (name.empty())
3761
        return false;
3762
 
3763
    PCHAIN_T *pg = mPchain;
3764
 
3765
    while (pg)
3766
    {
3767
        if (pg->page && pg->page->getName().compare(name) == 0)
3768
            return true;
3769
 
3770
        pg = pg->next;
3771
    }
3772
 
3773
    return false;
3774
}
3775
 
3776
bool TPageManager::haveSubPage(const string& name)
3777
{
3778
    DECL_TRACER("TPageManager::haveSubPage(const string& name)");
3779
 
3780
    if (name.empty())
3781
        return false;
3782
 
11 andreas 3783
    SPCHAIN_T *pg = mSPchain;
3784
 
3785
    while (pg)
3786
    {
14 andreas 3787
        if (pg->page && pg->page->getName().compare(name) == 0)
3788
        {
3789
            MSG_DEBUG("Subpage " << pg->page->getNumber() << ", " << name << " found.");
3790
            return true;
3791
        }
3792
 
3793
        pg = pg->next;
3794
    }
3795
 
3796
    MSG_DEBUG("Subpage " << name << " not found.");
3797
    return false;
3798
}
3799
 
3800
bool TPageManager::haveSubPage(int id)
3801
{
3802
    DECL_TRACER("TPageManager::haveSubPage(int id)");
3803
 
3804
    SPCHAIN_T *pg = mSPchain;
3805
 
3806
    while (pg)
3807
    {
3808
        if (pg->page && pg->page->getNumber() == id)
3809
        {
3810
            MSG_DEBUG("Subpage " << pg->page->getNumber() << ", " << pg->page->getName() << " found.");
3811
            return true;
3812
        }
3813
 
3814
        pg = pg->next;
3815
    }
3816
 
3817
    MSG_DEBUG("Subpage " << id << " not found.");
3818
    return false;
3819
}
3820
 
3821
bool TPageManager::haveSubPage(const string& page, const string& name)
3822
{
3823
    DECL_TRACER("TPageManager::haveSubPage(const string& page, const string& name)");
3824
 
3825
    TPage *pg = getPage(page);
3826
 
3827
    if (!pg)
3828
        return false;
3829
 
3830
    TSubPage *spg = pg->getFirstSubPage();
3831
 
3832
    while (spg)
3833
    {
3834
        if (spg->getName().compare(name) == 0)
3835
        {
3836
            MSG_DEBUG("Subpage " << spg->getNumber() << ", " << name << " found.");
3837
            return true;
3838
        }
3839
 
3840
        spg = pg->getNextSubPage();
3841
    }
3842
 
3843
    MSG_DEBUG("Subpage " << name << " not found on page " << page << ".");
3844
    return false;
3845
}
3846
 
3847
bool TPageManager::haveSubPage(const string& page, int id)
3848
{
3849
    DECL_TRACER("TPageManager::haveSubPage(const string& page, int id)");
3850
 
3851
    TPage *pg = getPage(page);
3852
 
3853
    if (!pg)
3854
        return false;
3855
 
3856
    TSubPage *spg = pg->getFirstSubPage();
3857
 
3858
    while (spg)
3859
    {
3860
        if (spg->getNumber() == id)
3861
        {
3862
            MSG_DEBUG("Subpage " << spg->getNumber() << ", " << spg->getName() << " found.");
3863
            return true;
3864
        }
3865
 
3866
        spg = pg->getNextSubPage();
3867
    }
3868
 
3869
    MSG_DEBUG("Subpage " << id << " on page " << page << " not found.");
3870
    return false;
3871
}
3872
 
3873
void TPageManager::closeGroup(const string& group)
3874
{
3875
    DECL_TRACER("TPageManager::closeGroup(const string& group)");
3876
 
3877
    SPCHAIN_T *pg = mSPchain;
3878
 
3879
    while (pg)
3880
    {
11 andreas 3881
        if (pg->page->getGroupName().compare(group) == 0 && pg->page->isVisible())
3882
        {
3883
            pg->page->regCallDropSubPage(_callDropSubPage);
3884
            pg->page->drop();
3885
            break;
3886
        }
3887
 
3888
        pg = pg->next;
3889
    }
3890
}
3891
 
14 andreas 3892
void TPageManager::showSubPage(const string& name)
3893
{
3894
    DECL_TRACER("TPageManager::showSubPage(const string& name)");
3895
 
3896
    if (name.empty())
349 andreas 3897
    {
3898
#if TESTMODE == 1
3899
        setScreenDone();
3900
#endif
14 andreas 3901
        return;
349 andreas 3902
    }
275 andreas 3903
 
152 andreas 3904
    TPage *page = nullptr;
3905
    TSubPage *pg = deliverSubPage(name, &page);
14 andreas 3906
 
96 andreas 3907
    if (!pg)
349 andreas 3908
    {
3909
#if TESTMODE == 1
3910
        setScreenDone();
3911
#endif
14 andreas 3912
        return;
349 andreas 3913
    }
14 andreas 3914
 
152 andreas 3915
    if (page)
350 andreas 3916
    {
3917
        pg->setParent(page->getHandle());
152 andreas 3918
        page->addSubPage(pg);
350 andreas 3919
    }
152 andreas 3920
 
14 andreas 3921
    string group = pg->getGroupName();
3922
 
3923
    if (!group.empty())
3924
    {
3925
        TSubPage *sub = getFirstSubPageGroup(group);
3926
 
3927
        while(sub)
3928
        {
3929
            if (sub->isVisible() && sub->getNumber() != pg->getNumber())
3930
                sub->drop();
3931
 
3932
            sub = getNextSubPageGroup(group, sub);
3933
        }
3934
    }
3935
 
150 andreas 3936
    if (pg->isVisible())
3937
    {
152 andreas 3938
        MSG_DEBUG("Page " << pg->getName() << " is already visible but maybe not on top.");
150 andreas 3939
 
3940
        TSubPage *sub = getFirstSubPage();
3941
        bool redraw = false;
3942
 
3943
        while (sub)
3944
        {
151 andreas 3945
            if (sub->isVisible() && pg->getZOrder() < sub->getZOrder() &&
3946
                overlap(sub->getLeft(), sub->getTop(), sub->getWidth(), sub->getHeight(),
150 andreas 3947
                pg->getLeft(), pg->getTop(), pg->getWidth(), pg->getHeight()))
3948
            {
3949
                MSG_DEBUG("Page " << sub->getName() << " is overlapping page " << pg->getName());
3950
                redraw = true;
3951
                break;
3952
            }
3953
 
3954
            sub = getNextSubPage();
3955
        }
3956
 
151 andreas 3957
        if (redraw && _toFront)
3958
        {
300 andreas 3959
            _toFront((uint)pg->getHandle());
151 andreas 3960
            pg->setZOrder(page->getNextZOrder());
349 andreas 3961
//            page->sortSubpages();
154 andreas 3962
            MSG_DEBUG("Setting new Z-order " << page->getActZOrder() << " on subpage " << pg->getName());
151 andreas 3963
        }
154 andreas 3964
        else if (redraw && !_toFront)
150 andreas 3965
            pg->drop();
3966
    }
3967
 
14 andreas 3968
    if (!pg->isVisible())
3969
    {
3970
        if (!page)
3971
        {
198 andreas 3972
            page = getPage(mActualPage);
3973
 
3974
            if (!page)
3975
            {
3976
                MSG_ERROR("No active page found! Internal error.");
3977
                return;
3978
            }
14 andreas 3979
        }
3980
 
3981
        if (!haveSubPage(pg->getNumber()) && !page->addSubPage(pg))
3982
            return;
3983
 
3984
        pg->setZOrder(page->getNextZOrder());
3985
 
3986
        if (_setSubPage)
26 andreas 3987
        {
3988
            int left = pg->getLeft();
3989
            int top = pg->getTop();
3990
            int width = pg->getWidth();
3991
            int height = pg->getHeight();
43 andreas 3992
#ifdef _SCALE_SKIA_
26 andreas 3993
            if (mScaleFactor != 1.0)
3994
            {
3995
                left = (int)((double)left * mScaleFactor);
3996
                top = (int)((double)top * mScaleFactor);
3997
                width = (int)((double)width * mScaleFactor);
3998
                height = (int)((double)height * mScaleFactor);
28 andreas 3999
                MSG_DEBUG("Scaled subpage: left=" << left << ", top=" << top << ", width=" << width << ", height=" << height);
26 andreas 4000
            }
43 andreas 4001
#endif
41 andreas 4002
            ANIMATION_t ani;
4003
            ani.showEffect = pg->getShowEffect();
4004
            ani.showTime = pg->getShowTime();
42 andreas 4005
            ani.hideEffect = pg->getHideEffect();
4006
            ani.hideTime = pg->getHideTime();
54 andreas 4007
            // Test for a timer on the page
4008
            if (pg->getTimeout() > 0)
4009
                pg->startTimer();
4010
 
217 andreas 4011
            _setSubPage(pg->getHandle(), page->getHandle(), left, top, width, height, ani);
26 andreas 4012
        }
293 andreas 4013
 
4014
        pg->show();
14 andreas 4015
    }
4016
}
4017
 
198 andreas 4018
void TPageManager::showSubPage(int number, bool force)
4019
{
4020
    DECL_TRACER("TPageManager::showSubPage(int number, bool force)");
4021
 
4022
    if (number <= 0)
4023
        return;
4024
 
4025
    TPage *page = nullptr;
4026
    TSubPage *pg = deliverSubPage(number, &page);
4027
 
4028
    if (!pg)
4029
        return;
4030
 
4031
    if (page)
350 andreas 4032
    {
4033
        pg->setParent(page->getHandle());
198 andreas 4034
        page->addSubPage(pg);
350 andreas 4035
    }
198 andreas 4036
 
4037
    string group = pg->getGroupName();
4038
 
4039
    if (!group.empty())
4040
    {
4041
        TSubPage *sub = getFirstSubPageGroup(group);
4042
 
4043
        while(sub)
4044
        {
4045
            if (sub->isVisible() && sub->getNumber() != pg->getNumber())
4046
                sub->drop();
4047
 
4048
            sub = getNextSubPageGroup(group, sub);
4049
        }
4050
    }
4051
 
4052
    if (pg->isVisible() && !force)
4053
    {
4054
        MSG_DEBUG("Page " << pg->getName() << " is already visible but maybe not on top.");
4055
 
4056
        TSubPage *sub = getFirstSubPage();
4057
        bool redraw = false;
4058
 
4059
        while (sub)
4060
        {
4061
            if (sub->isVisible() && pg->getZOrder() < sub->getZOrder() &&
4062
                overlap(sub->getLeft(), sub->getTop(), sub->getWidth(), sub->getHeight(),
4063
                        pg->getLeft(), pg->getTop(), pg->getWidth(), pg->getHeight()))
4064
            {
4065
                MSG_DEBUG("Page " << sub->getName() << " is overlapping page " << pg->getName());
4066
                redraw = true;
4067
                break;
4068
            }
4069
 
4070
            sub = getNextSubPage();
4071
        }
4072
 
4073
        if (redraw && _toFront)
4074
        {
300 andreas 4075
            _toFront((uint)pg->getHandle());
198 andreas 4076
            pg->setZOrder(page->getNextZOrder());
4077
            page->sortSubpages();
4078
            MSG_DEBUG("Setting new Z-order " << page->getActZOrder() << " on subpage " << pg->getName());
4079
        }
4080
        else if (redraw && !_toFront)
4081
            pg->drop();
4082
    }
4083
 
4084
    if (!pg->isVisible() || force)
4085
    {
4086
        if (!page)
4087
        {
4088
            MSG_ERROR("No active page found! Internal error.");
4089
            return;
4090
        }
4091
 
4092
        if (!haveSubPage(pg->getNumber()) && !page->addSubPage(pg))
4093
            return;
4094
 
4095
        if (!pg->isVisible())
4096
            pg->setZOrder(page->getNextZOrder());
4097
 
4098
        if (_setSubPage)
4099
        {
4100
            int left = pg->getLeft();
4101
            int top = pg->getTop();
4102
            int width = pg->getWidth();
4103
            int height = pg->getHeight();
262 andreas 4104
#ifdef _SCALE_SKIA_
198 andreas 4105
            if (mScaleFactor != 1.0)
4106
            {
4107
                left = (int)((double)left * mScaleFactor);
4108
                top = (int)((double)top * mScaleFactor);
4109
                width = (int)((double)width * mScaleFactor);
4110
                height = (int)((double)height * mScaleFactor);
4111
                MSG_DEBUG("Scaled subpage: left=" << left << ", top=" << top << ", width=" << width << ", height=" << height);
4112
            }
262 andreas 4113
#endif
198 andreas 4114
            ANIMATION_t ani;
4115
            ani.showEffect = pg->getShowEffect();
4116
            ani.showTime = pg->getShowTime();
4117
            ani.hideEffect = pg->getHideEffect();
4118
            ani.hideTime = pg->getHideTime();
4119
            // Test for a timer on the page
4120
            if (pg->getTimeout() > 0)
4121
                pg->startTimer();
4122
 
217 andreas 4123
            _setSubPage(pg->getHandle(), page->getHandle(), left, top, width, height, ani);
198 andreas 4124
        }
4125
    }
4126
 
4127
    pg->show();
4128
}
4129
 
14 andreas 4130
void TPageManager::hideSubPage(const string& name)
4131
{
4132
    DECL_TRACER("TPageManager::hideSubPage(const string& name)");
4133
 
4134
    if (name.empty())
335 andreas 4135
    {
4136
#if TESTMODE == 1
4137
        setScreenDone();
4138
#endif
14 andreas 4139
        return;
335 andreas 4140
    }
14 andreas 4141
 
4142
    TPage *page = getPage(mActualPage);
4143
 
4144
    if (!page)
4145
    {
4146
        MSG_ERROR("No active page found! Internal error.");
335 andreas 4147
#if TESTMODE == 1
4148
        setScreenDone();
4149
#endif
14 andreas 4150
        return;
4151
    }
4152
 
4153
    TSubPage *pg = getSubPage(name);
4154
 
4155
    if (pg)
4156
    {
4157
        pg->drop();
154 andreas 4158
        page->decZOrder();
14 andreas 4159
    }
4160
}
4161
 
299 andreas 4162
/**
4163
 * @brief TPageManager::runClickQueue - Processing mouse clicks
4164
 * The following method is starting a thread which tests a queue containing
4165
 * the mouse clicks. To not drain the CPU, it sleeps for a short time if there
4166
 * are no more events in the queue.
4167
 * If there is an entry in the queue, it copies it to a local struct and
4168
 * deletes it from the queue. It take always the oldest antry (first entry)
4169
 * and removes this entry from the queue until the queue is empty. This makes
4170
 * it to a FIFO (first in, first out).
4171
 * Depending on the state of the variable "coords" the method for mouse
4172
 * coordinate click is executed or the method for a handle.
4173
 * The thread runs as long as the variable "mClickQueueRun" is TRUE and the
4174
 * variable "prg_stopped" is FALSE.
4175
 */
4176
void TPageManager::runClickQueue()
4177
{
4178
    DECL_TRACER("TPageManager::runClickQueue()");
4179
 
4180
    if (mClickQueueRun)
4181
        return;
4182
 
4183
    mClickQueueRun = true;
4184
 
4185
    try
4186
    {
4187
        std::thread thr = std::thread([=] {
300 andreas 4188
            MSG_PROTOCOL("Thread \"TPageManager::runClickQueue()\" was started.");
4189
 
299 andreas 4190
            while (mClickQueueRun && !prg_stopped)
4191
            {
300 andreas 4192
                while (!mClickQueue.empty())
299 andreas 4193
                {
4194
#ifdef QT_DEBUG
300 andreas 4195
                    if (mClickQueue[0].coords)
4196
                        MSG_TRACE("TPageManager::runClickQueue() -- executing: _mouseEvent(" << mClickQueue[0].x << ", " << mClickQueue[0].y << ", " << (mClickQueue[0].pressed ? "TRUE" : "FALSE") << ")")
299 andreas 4197
                    else
300 andreas 4198
                        MSG_TRACE("TPageManager::runClickQueue() -- executing: _mouseEvent(" << handleToString(mClickQueue[0].handle) << ", " << (mClickQueue[0].pressed ? "TRUE" : "FALSE") << ")")
299 andreas 4199
#endif
300 andreas 4200
                    if (mClickQueue[0].coords)
4201
                        _mouseEvent(mClickQueue[0].x, mClickQueue[0].y, mClickQueue[0].pressed);
4202
                    else
4203
                        _mouseEvent(mClickQueue[0].handle, mClickQueue[0].handle);
4204
 
299 andreas 4205
                    mClickQueue.erase(mClickQueue.begin()); // Remove first entry
4206
                }
4207
 
4208
                std::this_thread::sleep_for(std::chrono::microseconds(10));
4209
            }
4210
 
303 andreas 4211
            mClickQueueRun = false;
299 andreas 4212
            return;
4213
        });
4214
 
4215
        thr.detach();
4216
    }
4217
    catch (std::exception& e)
4218
    {
300 andreas 4219
        MSG_ERROR("Error starting a thread to handle the click queue: " << e.what());
299 andreas 4220
        mClickQueueRun = false;
4221
    }
4222
}
4223
 
303 andreas 4224
void TPageManager::runUpdateSubViewItem()
4225
{
4226
    DECL_TRACER("TPageManager::runUpdateSubViewItem()");
299 andreas 4227
 
303 andreas 4228
    if (mUpdateViewsRun)
4229
        return;
4230
 
4231
    mUpdateViewsRun = true;
4232
 
4233
    try
4234
    {
4235
        std::thread thr = std::thread([=] {
4236
            MSG_PROTOCOL("Thread \"TPageManager::runUpdateSubViewItem()\" was started.");
4237
 
4238
            while (mUpdateViewsRun && !prg_stopped)
4239
            {
4240
                while (!mUpdateViews.empty())
4241
                {
4242
                    _updateSubViewItem(mUpdateViews[0]);
4243
                    mUpdateViews.erase(mUpdateViews.begin()); // Remove first entry
4244
                }
4245
 
4246
                std::this_thread::sleep_for(std::chrono::microseconds(10));
4247
            }
4248
 
4249
            mUpdateViewsRun = false;
4250
            return;
4251
        });
4252
 
4253
        thr.detach();
4254
    }
4255
    catch (std::exception& e)
4256
    {
4257
        MSG_ERROR("Error starting a thread to handle the click queue: " << e.what());
4258
        mUpdateViewsRun = false;
4259
    }
4260
}
4261
 
11 andreas 4262
/*
4263
 * Catch the mouse presses and scan all pages and subpages for an element to
4264
 * receive the klick.
4265
 */
10 andreas 4266
void TPageManager::mouseEvent(int x, int y, bool pressed)
4267
{
4268
    DECL_TRACER("TPageManager::mouseEvent(int x, int y, bool pressed)");
4269
 
316 andreas 4270
    TTRYLOCK(click_mutex);
299 andreas 4271
 
4272
    _CLICK_QUEUE_t cq;
4273
    cq.x = x;
4274
    cq.y = y;
4275
    cq.pressed = pressed;
4276
    cq.coords = true;
4277
    mClickQueue.push_back(cq);
334 andreas 4278
#if TESTMODE == 1
4279
    setScreenDone();
4280
#endif
299 andreas 4281
}
4282
 
4283
void TPageManager::_mouseEvent(int x, int y, bool pressed)
4284
{
4285
    DECL_TRACER("TPageManager::_mouseEvent(int x, int y, bool pressed)");
4286
 
16 andreas 4287
    TError::clear();
334 andreas 4288
#if TESTMODE == 1
4289
    if (_gTestMode)
4290
        _gTestMode->setMouseClick(x, y, pressed);
4291
#endif
11 andreas 4292
    int realX = x - mFirstLeftPixel;
4293
    int realY = y - mFirstTopPixel;
263 andreas 4294
 
31 andreas 4295
    MSG_DEBUG("Mouse at " << realX << ", " << realY << ", state " << ((pressed) ? "PRESSED" : "RELEASED") << ", [ " << x << " | " << y << " ]");
43 andreas 4296
#ifdef _SCALE_SKIA_
100 andreas 4297
    if (mScaleFactor != 1.0 && mScaleFactor > 0.0)
26 andreas 4298
    {
4299
        realX = (int)((double)realX / mScaleFactor);
4300
        realY = (int)((double)realY / mScaleFactor);
31 andreas 4301
        MSG_DEBUG("Scaled coordinates: x=" << realX << ", y=" << realY);
26 andreas 4302
    }
43 andreas 4303
#endif
70 andreas 4304
 
154 andreas 4305
    TSubPage *subPage = nullptr;
11 andreas 4306
 
154 andreas 4307
    if (pressed)
4308
        subPage = getCoordMatch(realX, realY);
318 andreas 4309
    else if (mLastPagePush)
154 andreas 4310
        subPage = getSubPage(mLastPagePush);
4311
    else
4312
        subPage = getCoordMatch(realX, realY);
4313
 
11 andreas 4314
    if (!subPage)
14 andreas 4315
    {
146 andreas 4316
        Button::TButton *bt = getCoordMatchPage(realX, realY);
40 andreas 4317
 
4318
        if (bt)
4319
        {
4320
            MSG_DEBUG("Button on page " << bt->getButtonIndex() << ": size: left=" << bt->getLeftPosition() << ", top=" << bt->getTopPosition() << ", width=" << bt->getWidth() << ", height=" << bt->getHeight());
4321
            bt->doClick(x - bt->getLeftPosition(), y - bt->getTopPosition(), pressed);
4322
        }
4323
 
11 andreas 4324
        return;
14 andreas 4325
    }
11 andreas 4326
 
154 andreas 4327
    MSG_DEBUG("Subpage " << subPage->getNumber() << " [" << subPage->getName() << "]: size: left=" << subPage->getLeft() << ", top=" << subPage->getTop() << ", width=" << subPage->getWidth() << ", height=" << subPage->getHeight());
4328
 
4329
    if (pressed)
4330
        mLastPagePush = subPage->getNumber();
4331
    else
4332
        mLastPagePush = 0;
4333
 
11 andreas 4334
    subPage->doClick(realX - subPage->getLeft(), realY - subPage->getTop(), pressed);
10 andreas 4335
}
11 andreas 4336
 
289 andreas 4337
void TPageManager::mouseEvent(ulong handle, bool pressed)
4338
{
4339
    DECL_TRACER("TPageManager::mouseEvent(ulong handle, bool pressed)");
4340
 
320 andreas 4341
    if (!mClickQueue.empty() && mClickQueue.back().handle == handle && mClickQueue.back().pressed == pressed)
4342
        return;
4343
 
299 andreas 4344
    TLOCKER(click_mutex);
293 andreas 4345
 
299 andreas 4346
    _CLICK_QUEUE_t cq;
4347
    cq.handle = handle;
4348
    cq.pressed = pressed;
4349
    mClickQueue.push_back(cq);
4350
    MSG_DEBUG("Queued click for handle " << handleToString(cq.handle) << " state " << (cq.pressed ? "PRESSED" : "RELEASED"));
4351
}
4352
 
4353
void TPageManager::_mouseEvent(ulong handle, bool pressed)
4354
{
4355
    DECL_TRACER("TPageManager::_mouseEvent(ulong handle, bool pressed)");
4356
 
293 andreas 4357
    MSG_DEBUG("Doing click for handle " << handleToString(handle) << " state " << (pressed ? "PRESSED" : "RELEASED"));
4358
 
289 andreas 4359
    if (!handle)
4360
        return;
4361
 
4362
    int pageID = (handle >> 16) & 0x0000ffff;
4363
    int buttonID = (handle & 0x0000ffff);
4364
 
318 andreas 4365
    if (pageID < REGULAR_SUBPAGE_START || buttonID == 0)
289 andreas 4366
        return;
4367
 
4368
    TSubPage *subPage = getSubPage(pageID);
4369
 
4370
    if (subPage)
4371
    {
4372
        Button::TButton *bt = subPage->getButton(buttonID);
4373
 
4374
        if (bt)
4375
        {
318 andreas 4376
            MSG_DEBUG("Button on subpage " << pageID << ": " << buttonID);
289 andreas 4377
            bt->doClick(bt->getLeftPosition() + bt->getWidth() / 2, bt->getTopPosition() + bt->getHeight() / 2, pressed);
4378
        }
4379
    }
4380
}
4381
 
192 andreas 4382
void TPageManager::inputButtonFinished(ulong handle, const std::string &content)
4383
{
4384
    DECL_TRACER("TPageManager::inputButtonFinished(ulong handle, const std::string &content)");
4385
 
4386
    Button::TButton *bt = findButton(handle);
4387
 
4388
    if (!bt)
4389
    {
271 andreas 4390
        MSG_WARNING("Invalid button handle " << handleToString(handle));
192 andreas 4391
        return;
4392
    }
4393
 
4394
    bt->setTextOnly(content, -1);
4395
}
4396
 
309 andreas 4397
void TPageManager::inputCursorPositionChanged(ulong handle, int oldPos, int newPos)
4398
{
4399
    DECL_TRACER("TPageManager::inputCursorPositionChanged(ulong handle, int oldPos, int newPos)");
4400
 
4401
    Button::TButton *bt = findButton(handle);
4402
 
4403
    if (!bt)
4404
    {
4405
        MSG_WARNING("Invalid button handle " << handleToString(handle));
4406
        return;
4407
    }
4408
 
310 andreas 4409
    ulong pageID = (bt->getHandle() >> 16) & 0x0000ffff;
309 andreas 4410
 
4411
    if (pageID < REGULAR_SUBPAGE_START)
4412
    {
368 andreas 4413
        TPage *pg = getPage((int)pageID);
309 andreas 4414
 
4415
        if (!pg)
4416
            return;
4417
 
4418
        pg->setCursorPosition(handle, oldPos, newPos);
4419
    }
4420
    else
4421
    {
368 andreas 4422
        TSubPage *pg = getSubPage((int)pageID);
309 andreas 4423
 
4424
        if (!pg)
4425
            return;
4426
 
4427
        pg->setCursorPosition(handle, oldPos, newPos);
4428
    }
4429
}
4430
 
4431
void TPageManager::inputFocusChanged(ulong handle, bool in)
4432
{
4433
    DECL_TRACER("TPageManager::inputFocusChanged(ulong handle, bool in)");
4434
 
4435
    Button::TButton *bt = findButton(handle);
4436
 
4437
    if (!bt)
4438
    {
4439
        MSG_WARNING("Invalid button handle " << handleToString(handle));
4440
        return;
4441
    }
4442
 
310 andreas 4443
    ulong pageID = (bt->getHandle() >> 16) & 0x0000ffff;
4444
    MSG_DEBUG("Searching for page " << pageID);
309 andreas 4445
 
4446
    if (pageID < REGULAR_SUBPAGE_START)
4447
    {
368 andreas 4448
        TPage *pg = getPage((int)pageID);
309 andreas 4449
 
4450
        if (!pg)
4451
            return;
4452
 
4453
        pg->setInputFocus(handle, in);
4454
    }
4455
    else
4456
    {
368 andreas 4457
        TSubPage *pg = getSubPage((int)pageID);
309 andreas 4458
 
4459
        if (!pg)
4460
            return;
4461
 
4462
        pg->setInputFocus(handle, in);
4463
    }
4464
}
4465
 
208 andreas 4466
void TPageManager::setTextToButton(ulong handle, const string& txt, bool redraw)
51 andreas 4467
{
208 andreas 4468
    DECL_TRACER("TPageManager::setTextToButton(ulong handle, const string& txt, bool redraw)");
51 andreas 4469
 
4470
    // First we search for the button the handle points to
4471
    Button::TButton *button = findButton(handle);
4472
 
4473
    if (!button)
4474
    {
271 andreas 4475
        MSG_ERROR("No button with handle " << handleToString(handle) << " found!");
51 andreas 4476
        return;
4477
    }
4478
 
4479
    // Now we search for all buttons with the same channel and port number
4480
    vector<int> channels;
4481
    channels.push_back(button->getAddressChannel());
193 andreas 4482
    vector<TMap::MAP_T> map = findButtons(button->getAddressPort(), channels);
51 andreas 4483
 
4484
    if (TError::isError() || map.empty())
4485
        return;
4486
 
4487
    // Here we load all buttons found.
4488
    vector<Button::TButton *> buttons = collectButtons(map);
83 andreas 4489
 
4490
    if (buttons.size() > 0)
51 andreas 4491
    {
83 andreas 4492
        vector<Button::TButton *>::iterator mapIter;
4493
        // Finaly we iterate through all found buttons and set the text
118 andreas 4494
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
83 andreas 4495
        {
4496
            Button::TButton *bt = *mapIter;
51 andreas 4497
 
208 andreas 4498
            if (redraw)
4499
                bt->setText(txt, -1);
4500
            else
4501
                bt->setTextOnly(txt, -1);
83 andreas 4502
        }
51 andreas 4503
    }
4504
}
4505
 
193 andreas 4506
vector<Button::TButton *> TPageManager::collectButtons(vector<TMap::MAP_T>& map)
14 andreas 4507
{
193 andreas 4508
    DECL_TRACER("TPageManager::collectButtons(vector<TMap::MAP_T>& map)");
14 andreas 4509
 
4510
    vector<Button::TButton *> buttons;
83 andreas 4511
 
4512
    if (map.size() == 0)
4513
        return buttons;
4514
 
193 andreas 4515
    vector<TMap::MAP_T>::iterator iter;
14 andreas 4516
 
118 andreas 4517
    for (iter = map.begin(); iter != map.end(); ++iter)
14 andreas 4518
    {
209 andreas 4519
        if (iter->pg < REGULAR_SUBPAGE_START || (iter->pg >= SYSTEM_PAGE_START && iter->pg < SYSTEM_SUBPAGE_START))     // Main page?
14 andreas 4520
        {
4521
            TPage *page;
4522
 
4523
            if ((page = getPage(iter->pg)) == nullptr)
4524
            {
4525
                MSG_TRACE("Page " << iter->pg << ", " << iter->pn << " not found in memory. Reading it ...");
4526
 
4527
                if (!readPage(iter->pg))
4528
                    return buttons;
4529
 
4530
                page = getPage(iter->pg);
4531
            }
4532
 
4533
            Button::TButton *bt = page->getButton(iter->bt);
4534
 
4535
            if (bt)
4536
                buttons.push_back(bt);
4537
        }
4538
        else
4539
        {
4540
            TSubPage *subpage;
4541
 
4542
            if ((subpage = getSubPage(iter->pg)) == nullptr)
4543
            {
4544
                MSG_TRACE("Subpage " << iter->pg << ", " << iter->pn << " not found in memory. Reading it ...");
4545
 
4546
                if (!readSubPage(iter->pg))
4547
                    return buttons;
4548
 
4549
                subpage = getSubPage(iter->pg);
4550
                TPage *page = getActualPage();
4551
 
4552
                if (!page)
4553
                {
4554
                    MSG_ERROR("No actual page loaded!");
4555
                    return buttons;
4556
                }
4557
            }
4558
 
4559
            Button::TButton *bt = subpage->getButton(iter->bt);
4560
 
4561
            if (bt)
4562
                buttons.push_back(bt);
4563
        }
4564
    }
4565
 
4566
    return buttons;
4567
}
4568
 
11 andreas 4569
/****************************************************************************
36 andreas 4570
 * Calls from a Java activity. This is only available for Android OS.
4571
 ****************************************************************************/
182 andreas 4572
#ifdef Q_OS_ANDROID
36 andreas 4573
void TPageManager::initNetworkState()
4574
{
4575
    DECL_TRACER("TPageManager::initNetworkState()");
264 andreas 4576
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
36 andreas 4577
    QAndroidJniObject activity = QtAndroid::androidActivity();
4578
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "Init", "(Landroid/app/Activity;)V", activity.object());
4579
    activity.callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "InstallNetworkListener", "()V");
182 andreas 4580
#else
4581
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4582
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "Init", "(Landroid/app/Activity;)V", activity.object());
4583
    activity.callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "InstallNetworkListener", "()V");
4584
#endif
36 andreas 4585
}
4586
 
4587
void TPageManager::stopNetworkState()
4588
{
4589
    DECL_TRACER("TPageManager::stopNetworkState()");
264 andreas 4590
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
36 andreas 4591
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "destroyNetworkListener", "()V");
182 andreas 4592
#else
4593
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "destroyNetworkListener", "()V");
4594
#endif
36 andreas 4595
}
38 andreas 4596
 
4597
void TPageManager::initBatteryState()
4598
{
4599
    DECL_TRACER("TPageManager::initBatteryState()");
264 andreas 4600
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
38 andreas 4601
    QAndroidJniObject activity = QtAndroid::androidActivity();
4602
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "Init", "(Landroid/app/Activity;)V", activity.object());
182 andreas 4603
#else
4604
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4605
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "Init", "(Landroid/app/Activity;)V", activity.object());
4606
#endif
38 andreas 4607
    activity.callStaticMethod<void>("org/qtproject/theosys/BatteryState", "InstallBatteryListener", "()V");
4608
}
4609
 
61 andreas 4610
void TPageManager::initPhoneState()
4611
{
4612
    DECL_TRACER("TPageManager::initPhoneState()");
264 andreas 4613
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
61 andreas 4614
    QAndroidJniObject activity = QtAndroid::androidActivity();
4615
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/PhoneCallState", "Init", "(Landroid/app/Activity;)V", activity.object());
182 andreas 4616
#else
4617
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4618
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/PhoneCallState", "Init", "(Landroid/app/Activity;)V", activity.object());
4619
#endif
61 andreas 4620
    activity.callStaticMethod<void>("org/qtproject/theosys/PhoneCallState", "InstallPhoneListener", "()V");
4621
}
4622
 
38 andreas 4623
void TPageManager::stopBatteryState()
4624
{
4625
    DECL_TRACER("TPageManager::stopBatteryState()");
264 andreas 4626
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
38 andreas 4627
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "destroyBatteryListener", "()V");
182 andreas 4628
#else
4629
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "destroyBatteryListener", "()V");
4630
#endif
38 andreas 4631
}
4632
 
36 andreas 4633
void TPageManager::informTPanelNetwork(jboolean conn, jint level, jint type)
4634
{
250 andreas 4635
    DECL_TRACER("TPageManager::informTPanelNetwork(jboolean conn, jint level, jint type)");
36 andreas 4636
 
4637
    int l = 0;
4638
    string sType;
4639
 
4640
    switch (type)
4641
    {
4642
        case 1: sType = "Wifi"; break;
4643
        case 2: sType = "Mobile"; break;
4644
 
4645
        default:
4646
            sType = "Unknown"; break;
4647
    }
4648
 
4649
    if (conn)
4650
        l = level;
4651
 
93 andreas 4652
    if (mNetState && mNetState != type)     // Has the connection type changed?
4653
    {
4654
        if (gAmxNet)
4655
            gAmxNet->reconnect();
4656
    }
4657
 
4658
    mNetState = type;
4659
 
36 andreas 4660
    MSG_INFO("Connection status: " << (conn ? "Connected" : "Disconnected") << ", level: " << level << ", type: " << sType);
4661
 
83 andreas 4662
    if (mNetCalls.size() > 0)
36 andreas 4663
    {
83 andreas 4664
        std::map<int, std::function<void (int level)> >::iterator iter;
4665
 
4666
        for (iter = mNetCalls.begin(); iter != mNetCalls.end(); ++iter)
4667
            iter->second(l);
36 andreas 4668
    }
4669
}
38 andreas 4670
 
4671
void TPageManager::informBatteryStatus(jint level, jboolean charging, jint chargeType)
4672
{
4673
    DECL_TRACER("TPageManager::informBatteryStatus(jint level, jboolean charging, jint chargeType)");
4674
 
59 andreas 4675
    MSG_INFO("Battery status: level: " << level << ", " << (charging ? "Charging" : "not charging") << ", type: " << chargeType << ", Elements: " << mBatteryCalls.size());
38 andreas 4676
 
83 andreas 4677
    if (mBatteryCalls.size() > 0)
38 andreas 4678
    {
83 andreas 4679
        std::map<int, std::function<void (int, bool, int)> >::iterator iter;
4680
 
4681
        for (iter = mBatteryCalls.begin(); iter != mBatteryCalls.end(); ++iter)
4682
            iter->second(level, charging, chargeType);
38 andreas 4683
    }
4684
}
61 andreas 4685
 
4686
void TPageManager::informPhoneState(bool call, const string &pnumber)
4687
{
4688
    DECL_TRACER("TPageManager::informPhoneState(bool call, const string &pnumber)");
4689
 
4690
    MSG_INFO("Call state: " << (call ? "Call in progress" : "No call") << ", phone number: " << pnumber);
4691
 
4692
    if (!gAmxNet)
4693
    {
4694
        MSG_WARNING("The network manager for the AMX controller is not initialized!");
4695
        return;
4696
    }
4697
}
130 andreas 4698
 
4699
void TPageManager::initOrientation()
4700
{
4701
    DECL_TRACER("TPageManager::initOrientation()");
4702
 
131 andreas 4703
    int rotate = getSettings()->getRotate();
264 andreas 4704
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
130 andreas 4705
    QAndroidJniObject activity = QtAndroid::androidActivity();
131 andreas 4706
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Orientation", "Init", "(Landroid/app/Activity;I)V", activity.object(), rotate);
182 andreas 4707
#else
4708
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4709
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Orientation", "Init", "(Landroid/app/Activity;I)V", activity.object(), rotate);
4710
#endif
130 andreas 4711
    activity.callStaticMethod<void>("org/qtproject/theosys/Orientation", "InstallOrientationListener", "()V");
4712
}
255 andreas 4713
 
4714
void TPageManager::enterSetup()
4715
{
260 andreas 4716
    DECL_TRACER("TPageManager::enterSetup()");
264 andreas 4717
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
255 andreas 4718
    QAndroidJniObject activity = QtAndroid::androidActivity();
4719
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "callSettings", "(Landroid/app/Activity;)V", activity.object());
4720
#else
4721
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4722
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "callSettings", "(Landroid/app/Activity;)V", activity.object());
4723
#endif
4724
}
59 andreas 4725
#endif  // __ANDROID__
247 andreas 4726
#ifdef Q_OS_IOS
4727
void TPageManager::informBatteryStatus(int level, int state)
4728
{
4729
    DECL_TRACER("TPageManager::informBatteryStatus(int level, int state)");
36 andreas 4730
 
247 andreas 4731
    MSG_INFO("Battery status: level: " << level << ", " << state);
4732
 
4733
    if (mBatteryCalls.size() > 0)
4734
    {
4735
        std::map<int, std::function<void (int, int)> >::iterator iter;
4736
 
4737
        for (iter = mBatteryCalls.begin(); iter != mBatteryCalls.end(); ++iter)
4738
            iter->second(level, state);
4739
    }
4740
}
250 andreas 4741
 
4742
void TPageManager::informTPanelNetwork(bool conn, int level, int type)
4743
{
4744
    DECL_TRACER("TPageManager::informTPanelNetwork(bool conn, int level, int type)");
4745
 
4746
    int l = 0;
4747
    string sType;
4748
 
4749
    switch (type)
4750
    {
4751
        case 1: sType = "Ethernet"; break;
4752
        case 2: sType = "Mobile"; break;
4753
        case 3: sType = "WiFi"; break;
4754
        case 4: sType = "Bluetooth"; break;
4755
 
4756
        default:
4757
            sType = "Unknown"; break;
4758
    }
4759
 
4760
    if (conn)
4761
        l = level;
4762
 
4763
    if (mNetState && mNetState != type)     // Has the connection type changed?
4764
    {
4765
        if (gAmxNet)
4766
            gAmxNet->reconnect();
4767
    }
4768
 
4769
    mNetState = type;
4770
 
4771
    MSG_INFO("Connection status: " << (conn ? "Connected" : "Disconnected") << ", level: " << level << ", type: " << sType);
4772
 
4773
    if (mNetCalls.size() > 0)
4774
    {
4775
        std::map<int, std::function<void (int level)> >::iterator iter;
4776
 
4777
        for (iter = mNetCalls.begin(); iter != mNetCalls.end(); ++iter)
4778
            iter->second(l);
4779
    }
4780
}
4781
 
247 andreas 4782
#endif
4783
 
60 andreas 4784
void TPageManager::setButtonCallbacks(Button::TButton *bt)
4785
{
227 andreas 4786
    DECL_TRACER("TPageManager::setButtonCallbacks(Button::TButton *bt)");
4787
 
162 andreas 4788
    if (!bt)
4789
        return;
4790
 
60 andreas 4791
    bt->registerCallback(_displayButton);
4792
    bt->regCallPlayVideo(_callPlayVideo);
4793
    bt->setFonts(mFonts);
4794
    bt->setPalette(mPalette);
4795
}
4796
 
4797
void TPageManager::externalButton(extButtons_t bt, bool checked)
4798
{
4799
    DECL_TRACER("TPageManager::externalButton(extButtons_t bt)");
4800
 
4801
    if (!mExternal)
4802
        return;
4803
 
4804
    EXTBUTTON_t button = mExternal->getButton(bt);
4805
 
4806
    if (button.type == EXT_NOBUTTON)
4807
        return;
4808
 
4809
    if (button.cp && button.ch)
4810
    {
4811
        amx::ANET_SEND scmd;
4812
 
4813
        scmd.device = TConfig::getChannel();
4814
        scmd.port = button.cp;
4815
        scmd.channel = button.ch;
4816
 
4817
        if (checked)
4818
            scmd.MC = 0x0084;   // push button
134 andreas 4819
        else
4820
            scmd.MC = 0x0085;   // release button
60 andreas 4821
 
134 andreas 4822
        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 4823
 
134 andreas 4824
        if (gAmxNet)
4825
            gAmxNet->sendCommand(scmd);
4826
        else
4827
        {
4828
            MSG_WARNING("Missing global class TAmxNet. Can't send a message!");
4829
        }
60 andreas 4830
    }
4831
}
4832
 
62 andreas 4833
void TPageManager::sendKeyboard(const std::string& text)
4834
{
4835
    DECL_TRACER("TPageManager::sendKeyboard(const std::string& text)");
4836
 
4837
    amx::ANET_SEND scmd;
4838
    scmd.port = 1;
4839
    scmd.channel = 0;
4840
    scmd.msg = UTF8ToCp1250(text);
4841
    scmd.MC = 0x008b;
4842
 
4843
    if (gAmxNet)
4844
        gAmxNet->sendCommand(scmd);
4845
    else
4846
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4847
}
4848
 
4849
void TPageManager::sendKeypad(const std::string& text)
4850
{
4851
    DECL_TRACER("TPageManager::sendKeypad(const std::string& text)");
4852
 
269 andreas 4853
    sendKeyboard(text);
62 andreas 4854
}
4855
 
4856
void TPageManager::sendString(uint handle, const std::string& text)
4857
{
4858
    DECL_TRACER("TPageManager::sendString(uint handle, const std::string& text)");
4859
 
4860
    Button::TButton *bt = findButton(handle);
4861
 
4862
    if (!bt)
4863
    {
271 andreas 4864
        MSG_WARNING("Button " << handleToString(handle) << " not found!");
62 andreas 4865
        return;
4866
    }
4867
 
4868
    amx::ANET_SEND scmd;
4869
    scmd.port = bt->getAddressPort();
4870
    scmd.channel = bt->getAddressChannel();
4871
    scmd.msg = UTF8ToCp1250(text);
4872
    scmd.MC = 0x008b;
4873
 
4874
    if (gAmxNet)
4875
        gAmxNet->sendCommand(scmd);
4876
    else
4877
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4878
}
4879
 
134 andreas 4880
void TPageManager::sendGlobalString(const string& text)
4881
{
4882
    DECL_TRACER("TPageManager::sendGlobalString(const string& text)");
4883
 
4884
    if (text.empty() || text.find("-") == string::npos)
4885
        return;
4886
 
4887
    amx::ANET_SEND scmd;
4888
    scmd.port = 1;
4889
    scmd.channel = 0;
4890
    scmd.msg = text;
4891
    scmd.MC = 0x008b;
4892
 
4893
    if (gAmxNet)
4894
        gAmxNet->sendCommand(scmd);
4895
    else
4896
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4897
}
4898
 
147 andreas 4899
void TPageManager::sendCommandString(int port, const string& cmd)
4900
{
4901
    DECL_TRACER("TPageManager::sendGlobalString(const string& text)");
4902
 
4903
    if (cmd.empty())
4904
        return;
4905
 
4906
    amx::ANET_SEND scmd;
4907
    scmd.port = port;
4908
    scmd.channel = 0;
4909
    scmd.msg = cmd;
4910
    scmd.MC = 0x008c;
4911
 
4912
    if (gAmxNet)
4913
        gAmxNet->sendCommand(scmd);
4914
    else
4915
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4916
}
4917
 
123 andreas 4918
void TPageManager::sendPHNcommand(const std::string& cmd)
4919
{
4920
    DECL_TRACER("TPageManager::sendPHNcommand(const std::string& cmd)");
4921
 
4922
    amx::ANET_SEND scmd;
144 andreas 4923
    scmd.port = mTSettings->getSettings().voipCommandPort;
123 andreas 4924
    scmd.channel = TConfig::getChannel();
4925
    scmd.msg = "^PHN-" + cmd;
127 andreas 4926
    scmd.MC = 0x008c;
4927
    MSG_DEBUG("Sending PHN command: ^PHN-" << cmd);
123 andreas 4928
 
4929
    if (gAmxNet)
4930
        gAmxNet->sendCommand(scmd);
4931
    else
4932
        MSG_WARNING("Missing global class TAmxNet. Can't send ^PHN command!");
4933
}
4934
 
111 andreas 4935
void TPageManager::sendKeyStroke(char key)
4936
{
4937
    DECL_TRACER("TPageManager::sendKeyStroke(char key)");
4938
 
4939
    if (!key)
4940
        return;
4941
 
4942
    char msg[2];
4943
    msg[0] = key;
4944
    msg[1] = 0;
4945
 
4946
    amx::ANET_SEND scmd;
4947
    scmd.port = 1;
4948
    scmd.channel = 0;
4949
    scmd.msg.assign(msg);
127 andreas 4950
    scmd.MC = 0x008c;
111 andreas 4951
 
4952
    if (gAmxNet)
4953
        gAmxNet->sendCommand(scmd);
4954
    else
4955
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4956
}
4957
 
110 andreas 4958
/**
4959
 * Sending a custom event is identical in all cases. Because of this I
4960
 * implemented this method to send a custom event. This is called in all cases
4961
 * where a ?XXX command is received.
4962
 *
4963
 * @param value1    The instance of the button.
4964
 * @param value2    The value of a numeric request or the length of the string.
4965
 * @param value3    Always 0
4966
 * @param msg       In case of a string this contains the string.
4967
 * @param evType    This is the event type, a number between 1001 and 1099.
4968
 * @param cp        Channel port of button.
4969
 * @param cn        Channel number. of button.
4970
 *
4971
 * @return If all parameters are valid it returns TRUE.
4972
 */
4973
bool TPageManager::sendCustomEvent(int value1, int value2, int value3, const string& msg, int evType, int cp, int cn)
4974
{
4975
    DECL_TRACER("TPageManager::sendCustomEvent(int value1, int value2, int value3, const string& msg, int evType)");
4976
 
4977
    if (value1 < 1)
4978
        return false;
4979
 
4980
    amx::ANET_SEND scmd;
4981
    scmd.port = cp;
4982
    scmd.channel = cn;
4983
    scmd.ID = scmd.channel;
4984
    scmd.flag = 0;
4985
    scmd.type = evType;
4986
    scmd.value1 = value1;   // instance
4987
    scmd.value2 = value2;
4988
    scmd.value3 = value3;
4989
    scmd.msg = msg;
4990
 
4991
    if (!msg.empty())
4992
        scmd.dtype = 0x0001;// Char array
4993
 
4994
    scmd.MC = 0x008d;       // custom event
4995
 
4996
    if (gAmxNet)
4997
        gAmxNet->sendCommand(scmd);
4998
    else
4999
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
5000
 
5001
    return true;
5002
}
129 andreas 5003
#ifndef _NOSIP_
127 andreas 5004
string TPageManager::sipStateToString(TSIPClient::SIP_STATE_t s)
5005
{
5006
    DECL_TRACER("TPageManager::sipStateToString(TSIPClient::SIP_STATE_t s)");
5007
 
5008
    switch(s)
5009
    {
5010
        case TSIPClient::SIP_CONNECTED:     return "CONNECTED";
5011
        case TSIPClient::SIP_DISCONNECTED:  return "DISCONNECTED";
5012
        case TSIPClient::SIP_HOLD:          return "HOLD";
5013
        case TSIPClient::SIP_RINGING:       return "RINGING";
5014
        case TSIPClient::SIP_TRYING:        return "TRYING";
5015
 
5016
        default:
5017
            return "IDLE";
5018
    }
5019
 
5020
    return "IDLE";
5021
}
129 andreas 5022
#endif
134 andreas 5023
void TPageManager::sendOrientation()
5024
{
5025
    string ori;
5026
 
5027
    switch(mOrientation)
5028
    {
5029
        case O_PORTRAIT:            ori = "DeviceOrientationPortrait"; break;
5030
        case O_REVERSE_PORTRAIT:    ori = "DeviceOrientationPortraitUpsideDown"; break;
5031
        case O_LANDSCAPE:           ori = "DeviceOrientationLandscapeLeft"; break;
5032
        case O_REVERSE_LANDSCAPE:   ori = "DeviceOrientationLandscapeRight"; break;
5033
        case O_FACE_UP:             ori = "DeviceOrientationFaceUp"; break;
5034
        case O_FACE_DOWN:           ori = "DeviceOrientationFaceDown"; break;
5035
        default:
5036
            return;
5037
    }
5038
 
5039
    sendGlobalString("TPCACC-" + ori);
5040
}
5041
 
401 andreas 5042
void TPageManager::callSetPassword(ulong handle, const string& pw, int x, int y)
396 andreas 5043
{
401 andreas 5044
    DECL_TRACER("TPageManager::callSetPassword(ulong handle, const string& pw, int x, int y)");
396 andreas 5045
 
5046
    Button::TButton *bt = findButton(handle);
5047
 
5048
    if (!bt)
5049
    {
5050
        MSG_WARNING("callSetPassword: Button " << handleToString(handle) << " not found!");
5051
        return;
5052
    }
5053
 
5054
    string pass = pw;
5055
 
5056
    if (pass.empty())
5057
        pass = "\x01";
5058
 
5059
    bt->setPassword(pass);
401 andreas 5060
    bt->doClick(x, y, true);
5061
    bt->doClick(x, y, false);
396 andreas 5062
}
5063
 
153 andreas 5064
void TPageManager::onSwipeEvent(TPageManager::SWIPES sw)
5065
{
5066
    DECL_TRACER("TPageManager::onSwipeEvent(TPageManager::SWIPES sw)");
5067
 
5068
    // Swipes are defined in "external".
5069
    if (!mExternal)
5070
        return;
5071
 
5072
    extButtons_t eBt;
5073
    string dbg;
5074
 
5075
    switch(sw)
5076
    {
5077
        case SW_LEFT:   eBt = EXT_GESTURE_LEFT; dbg.assign("LEFT"); break;
5078
        case SW_RIGHT:  eBt = EXT_GESTURE_RIGHT; dbg.assign("RIGHT"); break;
5079
        case SW_UP:     eBt = EXT_GESTURE_UP; dbg.assign("UP"); break;
5080
        case SW_DOWN:   eBt = EXT_GESTURE_DOWN; dbg.assign("DOWN"); break;
5081
 
5082
        default:
5083
            return;
5084
    }
5085
 
5086
    int pgNum = getActualPageNumber();
5087
    EXTBUTTON_t bt = mExternal->getButton(pgNum, eBt);
5088
 
5089
    if (bt.bi == 0)
5090
        return;
5091
 
5092
    MSG_DEBUG("Received swipe " << dbg << " event for page " << pgNum << " on button " << bt.bi << " \"" << bt.na << "\"");
5093
 
5094
    if (!bt.cm.empty() && bt.co == 0)           // Feed command to ourself?
5095
    {                                           // Yes, then feed it into command queue.
5096
        MSG_DEBUG("Button has a self feed command");
5097
 
5098
        int channel = TConfig::getChannel();
5099
        int system = TConfig::getSystem();
5100
 
5101
        amx::ANET_COMMAND cmd;
5102
        cmd.MC = 0x000c;
5103
        cmd.device1 = channel;
5104
        cmd.port1 = bt.ap;
5105
        cmd.system = system;
5106
        cmd.data.message_string.device = channel;
5107
        cmd.data.message_string.port = bt.ap;  // Must be the address port of button
5108
        cmd.data.message_string.system = system;
5109
        cmd.data.message_string.type = 1;   // 8 bit char string
5110
 
5111
        vector<string>::iterator iter;
5112
 
5113
        for (iter = bt.cm.begin(); iter != bt.cm.end(); ++iter)
5114
        {
5115
            cmd.data.message_string.length = iter->length();
5116
            memset(&cmd.data.message_string.content, 0, sizeof(cmd.data.message_string.content));
5117
            strncpy((char *)&cmd.data.message_string.content, iter->c_str(), sizeof(cmd.data.message_string.content));
5118
            doCommand(cmd);
5119
        }
5120
    }
5121
    else if (!bt.cm.empty())
5122
    {
5123
        MSG_DEBUG("Button sends a command on port " << bt.co);
5124
 
5125
        vector<string>::iterator iter;
5126
 
5127
        for (iter = bt.cm.begin(); iter != bt.cm.end(); ++iter)
5128
            sendCommandString(bt.co, *iter);
5129
    }
5130
}
5131
 
36 andreas 5132
/****************************************************************************
11 andreas 5133
 * The following functions implements one of the commands the panel accepts.
5134
 ****************************************************************************/
43 andreas 5135
 
5136
/**
5137
 * This is a special function handling the progress bars when the files of the
5138
 * panel are updated. Instead of simply displaying a ready page, it fakes one
5139
 * with the actual dimensions of the main page. This is possible, because we've
5140
 * always a main page even if the panel is started for the first time.
5141
 */
5142
void TPageManager::doFTR(int port, vector<int>& channels, vector<string>& pars)
23 andreas 5143
{
43 andreas 5144
    DECL_TRACER("TPageManager::doFTR(int, vector<int>&, vector<string>& pars)");
14 andreas 5145
 
23 andreas 5146
    if (pars.empty())
5147
    {
5148
        MSG_WARNING("Command #FTR needs at least 1 parameter! Ignoring command.");
5149
        return;
5150
    }
5151
 
96 andreas 5152
    if (TStreamError::checkFilter(HLOG_DEBUG))
23 andreas 5153
    {
96 andreas 5154
        for (size_t i = 0; i < pars.size(); i++)
5155
        {
5156
            MSG_DEBUG("[" << i << "]: " << pars.at(i));
5157
        }
23 andreas 5158
    }
43 andreas 5159
 
5160
    if (pars.at(0).compare("START") == 0)
5161
    {
5162
        // Here we have to drop all pages and subpages first and then display
5163
        // the faked page with the progress bars.
5164
        MSG_DEBUG("Starting file transfer ...");
5165
        doPPX(port, channels, pars);
5166
        TPage *pg = getPage("_progress");
5167
 
5168
        if (!pg)
5169
        {
5170
            if (!readPage("_progress"))
5171
            {
5172
                MSG_ERROR("Error creating the system page _progress!");
5173
                return;
5174
            }
5175
 
5176
            pg = getPage("_progress");
5177
 
5178
            if (!pg)
5179
            {
5180
                MSG_ERROR("Error getting system page _progress!");
5181
                return;
5182
            }
5183
        }
5184
 
5185
        pg->setFonts(mFonts);
5186
        pg->registerCallback(_setBackground);
5187
        pg->regCallPlayVideo(_callPlayVideo);
5188
 
5189
        if (!pg || !_setPage || !mTSettings)
5190
            return;
5191
 
5192
        int width, height;
217 andreas 5193
        width = mTSettings->getWidth();
43 andreas 5194
        height = mTSettings->getHeight();
5195
#ifdef _SCALE_SKIA_
5196
        if (mScaleFactor != 1.0)
5197
        {
5198
            width = (int)((double)width * mScaleFactor);
5199
            height = (int)((double)height * mScaleFactor);
5200
        }
5201
#endif
5202
        _setPage((pg->getNumber() << 16) & 0xffff0000, width, height);
5203
        pg->show();
5204
        MSG_DEBUG("Page _progress on screen");
5205
    }
5206
    else if (pars.at(0).compare("SYNC") == 0)
5207
    {
5208
        TPage *pg = getPage("_progress");
5209
 
5210
        if (!pg)
5211
        {
5212
            MSG_ERROR("Page _progress not found!");
5213
            return;
5214
        }
5215
 
5216
        Button::TButton *bt = pg->getButton(1);   // Line 1
5217
 
5218
        if (!bt)
5219
        {
5220
            MSG_ERROR("Button 160 of page _progress not found!");
5221
            return;
5222
        }
5223
 
5224
        bt->setText(pars.at(2), 0);
5225
        bt->show();
5226
    }
5227
    else if (pars.at(0).compare("FTRSTART") == 0)
5228
    {
5229
        TPage *pg = getPage("_progress");
5230
 
5231
        if (!pg)
5232
        {
5233
            MSG_ERROR("Page _progress not found!");
5234
            return;
5235
        }
5236
 
5237
        Button::TButton *bt1 = pg->getButton(1);   // Line 1
5238
        Button::TButton *bt2 = pg->getButton(2);   // Line 2
5239
        Button::TButton *bt3 = pg->getButton(3);   // Bargraph 1
5240
        Button::TButton *bt4 = pg->getButton(4);   // Bargraph 2
5241
 
5242
        if (!bt1 || !bt2 || !bt3 || !bt4)
5243
        {
5244
            MSG_ERROR("Buttons of page _progress not found!");
5245
            return;
5246
        }
5247
 
5248
        bt1->setText("Transfering files ...", 0);
5249
        bt1->show();
5250
        bt2->setText(pars.at(3), 0);
5251
        bt2->show();
5252
        bt3->drawBargraph(0, atoi(pars.at(1).c_str()), true);
5253
        bt4->drawBargraph(0, atoi(pars.at(2).c_str()), true);
5254
    }
5255
    else if (pars.at(0).compare("FTRPART") == 0)
5256
    {
5257
        TPage *pg = getPage("_progress");
5258
 
5259
        if (!pg)
5260
        {
5261
            MSG_ERROR("Page _progress not found!");
5262
            return;
5263
        }
5264
 
5265
        Button::TButton *bt = pg->getButton(4);   // Bargraph 2
5266
 
5267
        if (!bt)
5268
        {
5269
            MSG_ERROR("Buttons of page _progress not found!");
5270
            return;
5271
        }
5272
 
5273
        bt->drawBargraph(0, atoi(pars.at(2).c_str()), true);
5274
    }
5275
    else if (pars.at(0).compare("END") == 0)
5276
    {
5277
        MSG_TRACE("End of file transfer reached.");
44 andreas 5278
 
155 andreas 5279
        // To make sure the new surface will not be deleted and replaced by the
5280
        // default build in surface, we must delete the "virgin" marker first.
5281
        // This is a file called <project path>/.system.
5282
        string virgin = TConfig::getProjectPath() + "/.system";
5283
        remove(virgin.c_str());     // Because this file may not exist we don't care about the result code.
5284
 
44 andreas 5285
        if (_resetSurface)
5286
            _resetSurface();
5287
        else
5288
        {
5289
            MSG_WARNING("Missing callback function \"resetSurface\"!");
5290
        }
43 andreas 5291
    }
23 andreas 5292
}
5293
 
318 andreas 5294
void TPageManager::doLEVON(int, vector<int>&, vector<string>&)
5295
{
5296
    DECL_TRACER("TPageManager::doLEVON(int, vector<int>&, vector<string>&)");
5297
 
5298
    mLevelSend = true;
343 andreas 5299
#if TESTMODE == 1
5300
    __success = true;
5301
    setAllDone();
5302
#endif
318 andreas 5303
}
5304
 
5305
void TPageManager::doLEVOF(int, vector<int>&, vector<string>&)
5306
{
5307
    DECL_TRACER("TPageManager::doLEVOF(int, vector<int>&, vector<string>&)");
5308
 
5309
    mLevelSend = false;
343 andreas 5310
#if TESTMODE == 1
5311
    __success = true;
5312
    setAllDone();
5313
#endif
318 andreas 5314
}
5315
 
5316
void TPageManager::doRXON(int, vector<int>&, vector<string>&)
5317
{
5318
    DECL_TRACER("TPageManager::doRXON(int, vector<int>&, vector<string>&)");
5319
 
5320
    mRxOn = true;
343 andreas 5321
#if TESTMODE == 1
5322
    __success = true;
5323
    setAllDone();
5324
#endif
318 andreas 5325
}
5326
 
5327
void TPageManager::doRXOF(int, vector<int>&, vector<string>&)
5328
{
5329
    DECL_TRACER("TPageManager::doRXOF(int, vector<int>&, vector<string>&)");
5330
 
5331
    mRxOn = false;
343 andreas 5332
#if TESTMODE == 1
5333
    __success = true;
5334
    setAllDone();
5335
#endif
318 andreas 5336
}
5337
 
22 andreas 5338
void TPageManager::doON(int port, vector<int>&, vector<string>& pars)
14 andreas 5339
{
5340
    DECL_TRACER("TPageManager::doON(int port, vector<int>& channels, vector<string>& pars)");
5341
 
5342
    if (pars.empty())
5343
    {
5344
        MSG_WARNING("Command ON needs 1 parameter! Ignoring command.");
343 andreas 5345
#if TESTMODE == 1
5346
        setAllDone();
5347
#endif
14 andreas 5348
        return;
5349
    }
5350
 
16 andreas 5351
    TError::clear();
14 andreas 5352
    int c = atoi(pars[0].c_str());
5353
 
5354
    if (c <= 0)
5355
    {
5356
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
343 andreas 5357
#if TESTMODE == 1
5358
        setAllDone();
5359
#endif
14 andreas 5360
        return;
5361
    }
5362
 
5363
    vector<int> chans = { c };
193 andreas 5364
    vector<TMap::MAP_T> map = findButtons(port, chans, TMap::TYPE_CM);
14 andreas 5365
 
5366
    if (TError::isError() || map.empty())
343 andreas 5367
    {
5368
#if TESTMODE == 1
5369
        setAllDone();
5370
#endif
14 andreas 5371
        return;
343 andreas 5372
    }
14 andreas 5373
 
5374
    vector<Button::TButton *> buttons = collectButtons(map);
5375
 
83 andreas 5376
    if (buttons.size() > 0)
14 andreas 5377
    {
83 andreas 5378
        vector<Button::TButton *>::iterator mapIter;
14 andreas 5379
 
118 andreas 5380
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
83 andreas 5381
        {
5382
            Button::TButton *bt = *mapIter;
5383
 
195 andreas 5384
            if (bt->getButtonType() == GENERAL)
343 andreas 5385
            {
83 andreas 5386
                bt->setActive(1);
343 andreas 5387
#if TESTMODE == 1
5388
                if (_gTestMode)
5389
                    _gTestMode->setResult(intToString(bt->getActiveInstance() + 1));
5390
#endif
5391
            }
83 andreas 5392
        }
14 andreas 5393
    }
343 andreas 5394
#if TESTMODE == 1
5395
    setDone();
5396
#endif
14 andreas 5397
}
5398
 
22 andreas 5399
void TPageManager::doOFF(int port, vector<int>&, vector<string>& pars)
14 andreas 5400
{
5401
    DECL_TRACER("TPageManager::doOFF(int port, vector<int>& channels, vector<string>& pars)");
5402
 
5403
    if (pars.empty())
5404
    {
5405
        MSG_WARNING("Command OFF needs 1 parameter! Ignoring command.");
343 andreas 5406
#if TESTMODE == 1
5407
        setAllDone();
5408
#endif
14 andreas 5409
        return;
5410
    }
5411
 
16 andreas 5412
    TError::clear();
14 andreas 5413
    int c = atoi(pars[0].c_str());
5414
 
5415
    if (c <= 0)
5416
    {
5417
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
343 andreas 5418
#if TESTMODE == 1
5419
        setAllDone();
5420
#endif
14 andreas 5421
        return;
5422
    }
5423
 
5424
    vector<int> chans = { c };
193 andreas 5425
    vector<TMap::MAP_T> map = findButtons(port, chans, TMap::TYPE_CM);
14 andreas 5426
 
5427
    if (TError::isError() || map.empty())
5428
        return;
5429
 
5430
    vector<Button::TButton *> buttons = collectButtons(map);
5431
 
83 andreas 5432
    if (buttons.size() > 0)
14 andreas 5433
    {
83 andreas 5434
        vector<Button::TButton *>::iterator mapIter;
14 andreas 5435
 
118 andreas 5436
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
83 andreas 5437
        {
5438
            Button::TButton *bt = *mapIter;
5439
 
195 andreas 5440
            if (bt->getButtonType() == GENERAL)
83 andreas 5441
                bt->setActive(0);
343 andreas 5442
#if TESTMODE == 1
5443
                if (_gTestMode)
5444
                    _gTestMode->setResult(intToString(bt->getActiveInstance() + 1));
5445
#endif
83 andreas 5446
        }
14 andreas 5447
    }
343 andreas 5448
#if TESTMODE == 1
5449
    setDone();
5450
#endif
14 andreas 5451
}
5452
 
22 andreas 5453
void TPageManager::doLEVEL(int port, vector<int>&, vector<string>& pars)
15 andreas 5454
{
5455
    DECL_TRACER("TPageManager::doLEVEL(int port, vector<int>& channels, vector<string>& pars)");
5456
 
5457
    if (pars.size() < 2)
5458
    {
5459
        MSG_WARNING("Command LEVEL needs 2 parameters! Ignoring command.");
343 andreas 5460
#if TESTMODE == 1
5461
        setAllDone();
5462
#endif
15 andreas 5463
        return;
5464
    }
5465
 
16 andreas 5466
    TError::clear();
15 andreas 5467
    int c = atoi(pars[0].c_str());
5468
    int level = atoi(pars[1].c_str());
5469
 
5470
    if (c <= 0)
5471
    {
5472
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
343 andreas 5473
#if TESTMODE == 1
5474
        setAllDone();
5475
#endif
15 andreas 5476
        return;
5477
    }
5478
 
5479
    vector<int> chans = { c };
193 andreas 5480
    vector<TMap::MAP_T> map = findBargraphs(port, chans);
15 andreas 5481
 
5482
    if (TError::isError() || map.empty())
5483
    {
5484
        MSG_WARNING("No bargraphs found!");
343 andreas 5485
#if TESTMODE == 1
5486
        setAllDone();
5487
#endif
15 andreas 5488
        return;
5489
    }
5490
 
5491
    vector<Button::TButton *> buttons = collectButtons(map);
5492
 
83 andreas 5493
    if (buttons.size() > 0)
15 andreas 5494
    {
83 andreas 5495
        vector<Button::TButton *>::iterator mapIter;
15 andreas 5496
 
118 andreas 5497
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
15 andreas 5498
        {
83 andreas 5499
            Button::TButton *bt = *mapIter;
5500
 
195 andreas 5501
            if (bt->getButtonType() == BARGRAPH)
343 andreas 5502
            {
83 andreas 5503
                bt->drawBargraph(bt->getActiveInstance(), level);
343 andreas 5504
#if TESTMODE == 1
5505
                if (_gTestMode)
5506
                    _gTestMode->setResult(intToString(bt->getLevelValue()));
5507
#endif
5508
            }
195 andreas 5509
            else if (bt->getButtonType() == MULTISTATE_BARGRAPH)
83 andreas 5510
            {
5511
                int state = (int)((double)bt->getStateCount() / (double)(bt->getRangeHigh() - bt->getRangeLow()) * (double)level);
5512
                bt->setActive(state);
343 andreas 5513
#if TESTMODE == 1
5514
                if (_gTestMode)
5515
                    _gTestMode->setResult(intToString(bt->getActiveInstance()));
5516
#endif
83 andreas 5517
            }
15 andreas 5518
        }
5519
    }
343 andreas 5520
#if TESTMODE == 1
5521
    setDone();
5522
#endif
15 andreas 5523
}
5524
 
22 andreas 5525
void TPageManager::doBLINK(int, vector<int>&, vector<string>& pars)
15 andreas 5526
{
5527
    DECL_TRACER("TPageManager::doBLINK(int port, vector<int>& channels, vector<string>& pars)");
5528
 
5529
    if (pars.size() < 4)
5530
    {
5531
        MSG_WARNING("Command BLINK expects 4 parameters! Command ignored.");
343 andreas 5532
#if TESTMODE == 1
5533
        setAllDone();
5534
#endif
15 andreas 5535
        return;
5536
    }
5537
 
16 andreas 5538
    TError::clear();
15 andreas 5539
    vector<int> sysButtons = { 141, 142, 143, 151, 152, 153, 154, 155, 156, 157, 158 };
193 andreas 5540
    vector<TMap::MAP_T> map = findButtons(0, sysButtons);
15 andreas 5541
 
5542
    if (TError::isError() || map.empty())
5543
    {
5544
        MSG_WARNING("No system buttons found.");
343 andreas 5545
#if TESTMODE == 1
5546
        setAllDone();
5547
#endif
15 andreas 5548
        return;
5549
    }
5550
 
5551
    vector<Button::TButton *> buttons = collectButtons(map);
5552
    vector<Button::TButton *>::iterator mapIter;
5553
 
5554
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
5555
    {
5556
        Button::TButton *bt = *mapIter;
5557
        bt->setActive(0);
343 andreas 5558
#if TESTMODE == 1
5559
                if (_gTestMode)
5560
                    _gTestMode->setResult(intToString(bt->getActiveInstance() + 1));
5561
#endif
15 andreas 5562
    }
343 andreas 5563
#if TESTMODE == 1
5564
    setDone();
5565
#endif
15 andreas 5566
}
5567
 
162 andreas 5568
/**
5569
 * Send the version of the panel to the NetLinx. This is the real application
5570
 * version.
5571
 */
127 andreas 5572
void TPageManager::doVER(int, vector<int>&, vector<string>&)
5573
{
5574
    DECL_TRACER("TPageManager::doVER(int, vector<int>&, vector<string>&)");
5575
 
5576
    amx::ANET_SEND scmd;
5577
    scmd.port = 1;
5578
    scmd.channel = 0;
5579
    scmd.msg.assign(string("^VER-")+VERSION_STRING());
5580
    scmd.MC = 0x008c;
5581
 
5582
    if (gAmxNet)
343 andreas 5583
    {
127 andreas 5584
        gAmxNet->sendCommand(scmd);
343 andreas 5585
#if TESTMODE == 1
5586
        __success = true;
347 andreas 5587
 
5588
        if (_gTestMode)
5589
            _gTestMode->setResult(VERSION_STRING());
343 andreas 5590
#endif
5591
    }
127 andreas 5592
    else
5593
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
343 andreas 5594
#if TESTMODE == 1
5595
    setAllDone();
5596
#endif
127 andreas 5597
}
5598
 
162 andreas 5599
/**
5600
 * Returns the user name used to connect to a SIP server. An empty string is
5601
 * returned if there is no user defined.
5602
 */
279 andreas 5603
#ifndef _NOSIP_
127 andreas 5604
void TPageManager::doWCN(int, vector<int>&, vector<string>&)
5605
{
5606
    DECL_TRACER("TPageManager::doWCN(int, vector<int>&, vector<string>&)");
5607
 
5608
    if (!TConfig::getSIPstatus())
343 andreas 5609
    {
5610
#if TESTMODE == 1
5611
        setAllDone();
5612
#endif
127 andreas 5613
        return;
343 andreas 5614
    }
127 andreas 5615
 
5616
    amx::ANET_SEND scmd;
5617
    scmd.port = 1;
5618
    scmd.channel = 0;
5619
    scmd.msg.assign("^WCN-" + TConfig::getSIPuser());
5620
    scmd.MC = 0x008c;
5621
 
5622
    if (gAmxNet)
343 andreas 5623
    {
127 andreas 5624
        gAmxNet->sendCommand(scmd);
343 andreas 5625
#if TESTMODE == 1
5626
        __success = true;
347 andreas 5627
 
5628
        if (_gTestMode)
5629
            _gTestMode->setResult(TConfig::getSIPuser());
343 andreas 5630
#endif
5631
    }
127 andreas 5632
    else
5633
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
343 andreas 5634
#if TESTMODE == 1
5635
        setAllDone();
5636
#endif
127 andreas 5637
}
279 andreas 5638
#endif
14 andreas 5639
/**
147 andreas 5640
 * Flip to specified page using the named animation.
5641
 * FIXME: Implement animation for pages.
5642
 */
5643
void TPageManager::doAFP(int, vector<int>&, vector<string>& pars)
5644
{
5645
    DECL_TRACER("TPageManager::doAFP(int, vector<int>&, vector<string>& pars)");
5646
 
5647
    if (pars.size() < 4)
5648
    {
5649
        MSG_ERROR("Less than 4 parameters!");
343 andreas 5650
#if TESTMODE == 1
5651
        setAllDone();
5652
#endif
147 andreas 5653
        return;
5654
    }
5655
 
5656
    TError::clear();
5657
    string pname = pars[0];
5658
//    string ani = pars[1];
5659
//    int origin = atoi(pars[2].c_str());
5660
//    int duration = atoi(pars[3].c_str());
5661
 
5662
    // FIXME: Animation of pages is currently not implemented.
5663
 
5664
    if (!pname.empty())
5665
        setPage(pname);
5666
    else if (mPreviousPage)
5667
        setPage(mPreviousPage);
343 andreas 5668
#if TESTMODE == 1
5669
    if (_gTestMode)
5670
        _gTestMode->setResult(getActualPage()->getName());
5671
 
5672
    setDone();
5673
#endif
147 andreas 5674
}
5675
 
5676
/**
14 andreas 5677
 * Add a specific popup page to a specified popup group if it does not already
5678
 * exist. If the new popup is added to a group which has a popup displayed on
5679
 * the current page along with the new pop-up, the displayed popup will be
5680
 * hidden and the new popup will be displayed.
5681
 */
22 andreas 5682
void TPageManager::doAPG(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 5683
{
5684
    DECL_TRACER("TPageManager::doAPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5685
 
5686
    if (pars.size() < 2)
5687
    {
5688
        MSG_ERROR("Less than 2 parameters!");
343 andreas 5689
#if TESTMODE == 1
5690
        setAllDone();
5691
#endif
11 andreas 5692
        return;
5693
    }
5694
 
16 andreas 5695
    TError::clear();
11 andreas 5696
    closeGroup(pars[1]);
14 andreas 5697
 
96 andreas 5698
    TPage *page = nullptr;
5699
    TSubPage *subPage = deliverSubPage(pars[0], &page);
14 andreas 5700
 
11 andreas 5701
    if (!subPage)
5702
    {
5703
        MSG_ERROR("Subpage " << pars[0] << " couldn't either found or created!");
343 andreas 5704
#if TESTMODE == 1
5705
        setAllDone();
5706
#endif
11 andreas 5707
        return;
5708
    }
5709
 
162 andreas 5710
    if (!page)
5711
    {
5712
        MSG_ERROR("There seems to be no page for subpage " << pars[0]);
343 andreas 5713
#if TESTMODE == 1
5714
        setAllDone();
5715
#endif
162 andreas 5716
        return;
5717
    }
5718
 
152 andreas 5719
    page->addSubPage(subPage);
11 andreas 5720
    subPage->setGroup(pars[1]);
14 andreas 5721
    subPage->setZOrder(page->getNextZOrder());
152 andreas 5722
    MSG_DEBUG("Setting new Z-order " << page->getActZOrder() << " on page " << page->getName());
11 andreas 5723
    subPage->show();
343 andreas 5724
#if TESTMODE == 1
347 andreas 5725
    if (_gTestMode)
5726
        _gTestMode->setResult(subPage->getGroupName() + ":" + subPage->getName());
5727
 
343 andreas 5728
    setDone();
5729
#endif
11 andreas 5730
}
5731
 
14 andreas 5732
/**
5733
 * Clear all popup pages from specified popup group.
5734
 */
22 andreas 5735
void TPageManager::doCPG(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 5736
{
5737
    DECL_TRACER("TPageManager::doCPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5738
 
5739
    if (pars.size() < 1)
5740
    {
5741
        MSG_ERROR("Expecting 1 parameter but got only 1!");
343 andreas 5742
#if TESTMODE == 1
5743
        setAllDone();
5744
#endif
11 andreas 5745
        return;
5746
    }
5747
 
16 andreas 5748
    TError::clear();
348 andreas 5749
    vector<SUBPAGELIST_T> pageList = mPageList->getSubPageList();
11 andreas 5750
 
83 andreas 5751
    if (pageList.size() > 0)
11 andreas 5752
    {
83 andreas 5753
        vector<SUBPAGELIST_T>::iterator pgIter;
5754
 
5755
        for (pgIter = pageList.begin(); pgIter != pageList.end(); pgIter++)
11 andreas 5756
        {
83 andreas 5757
            if (pgIter->group.compare(pars[0]) == 0)
5758
            {
5759
                pgIter->group.clear();
5760
                TSubPage *pg = getSubPage(pgIter->pageID);
11 andreas 5761
 
83 andreas 5762
                if (pg)
5763
                    pg->setGroup(pgIter->group);
343 andreas 5764
#if TESTMODE == 1
5765
                __success = true;
5766
#endif
83 andreas 5767
            }
11 andreas 5768
        }
5769
    }
343 andreas 5770
#if TESTMODE == 1
5771
    setDone();
5772
#endif
11 andreas 5773
}
5774
 
14 andreas 5775
/**
5776
 * Delete a specific popup page from specified popup group if it exists.
5777
 */
22 andreas 5778
void TPageManager::doDPG(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 5779
{
5780
    DECL_TRACER("TPageManager::doDPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5781
 
5782
    if (pars.size() < 2)
5783
    {
5784
        MSG_ERROR("Less than 2 parameters!");
348 andreas 5785
#if TESTMODE == 1
5786
        setAllDone();
5787
#endif
11 andreas 5788
        return;
5789
    }
5790
 
16 andreas 5791
    TError::clear();
11 andreas 5792
    SUBPAGELIST_T listPg = findSubPage(pars[0]);
5793
 
5794
    if (!listPg.isValid)
348 andreas 5795
    {
5796
#if TESTMODE == 1
5797
        setAllDone();
5798
#endif
11 andreas 5799
        return;
348 andreas 5800
    }
11 andreas 5801
 
5802
    if (listPg.group.compare(pars[1]) == 0)
5803
    {
5804
        listPg.group.clear();
5805
        TSubPage *pg = getSubPage(listPg.pageID);
5806
 
5807
        if (pg)
5808
            pg->setGroup(listPg.group);
348 andreas 5809
#if TESTMODE == 1
5810
        __success = true;
5811
#endif
11 andreas 5812
    }
348 andreas 5813
#if TESTMODE == 1
5814
    setDone();
5815
#endif
11 andreas 5816
}
5817
 
14 andreas 5818
/**
15 andreas 5819
 * Set the hide effect for the specified popup page to the named hide effect.
5820
 */
22 andreas 5821
void TPageManager::doPHE(int, vector<int>&, vector<string>& pars)
15 andreas 5822
{
5823
    DECL_TRACER("TPageManager::doPHE(int port, vector<int>& channels, vector<string>& pars)");
5824
 
5825
    if (pars.size() < 2)
5826
    {
5827
        MSG_ERROR("Less than 2 parameters!");
348 andreas 5828
#if TESTMODE == 1
5829
        setAllDone();
5830
#endif
15 andreas 5831
        return;
5832
    }
5833
 
16 andreas 5834
    TError::clear();
96 andreas 5835
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 5836
 
5837
    if (!pg)
348 andreas 5838
    {
5839
#if TESTMODE == 1
5840
        setAllDone();
5841
#endif
96 andreas 5842
        return;
348 andreas 5843
    }
15 andreas 5844
 
162 andreas 5845
    if (strCaseCompare(pars[1], "fade") == 0)
15 andreas 5846
        pg->setHideEffect(SE_FADE);
162 andreas 5847
    else if (strCaseCompare(pars[1], "slide to left") == 0)
15 andreas 5848
        pg->setHideEffect(SE_SLIDE_LEFT);
162 andreas 5849
    else if (strCaseCompare(pars[1], "slide to right") == 0)
15 andreas 5850
        pg->setHideEffect(SE_SLIDE_RIGHT);
162 andreas 5851
    else if (strCaseCompare(pars[1], "slide to top") == 0)
15 andreas 5852
        pg->setHideEffect(SE_SLIDE_TOP);
162 andreas 5853
    else if (strCaseCompare(pars[1], "slide to bottom") == 0)
15 andreas 5854
        pg->setHideEffect(SE_SLIDE_BOTTOM);
162 andreas 5855
    else if (strCaseCompare(pars[1], "slide to left fade") == 0)
15 andreas 5856
        pg->setHideEffect(SE_SLIDE_LEFT_FADE);
162 andreas 5857
    else if (strCaseCompare(pars[1], "slide to right fade") == 0)
15 andreas 5858
        pg->setHideEffect(SE_SLIDE_RIGHT_FADE);
162 andreas 5859
    else if (strCaseCompare(pars[1], "slide to top fade") == 0)
15 andreas 5860
        pg->setHideEffect(SE_SLIDE_TOP_FADE);
162 andreas 5861
    else if (strCaseCompare(pars[1], "slide to bottom fade") == 0)
15 andreas 5862
        pg->setHideEffect(SE_SLIDE_BOTTOM_FADE);
5863
    else
5864
        pg->setHideEffect(SE_NONE);
348 andreas 5865
#if TESTMODE == 1
5866
    if (_gTestMode)
5867
        _gTestMode->setResult(intToString(pg->getHideEffect()));
5868
 
5869
    __success = true;
5870
    setAllDone();
5871
#endif
15 andreas 5872
}
5873
 
5874
/**
5875
 * Set the hide effect position. Only 1 coordinate is ever needed for an effect;
5876
 * however, the command will specify both. This command sets the location at
5877
 * which the effect will end at.
5878
 */
22 andreas 5879
void TPageManager::doPHP(int, vector<int>&, vector<string>& pars)
15 andreas 5880
{
5881
    DECL_TRACER("TPageManager::doPHP(int port, vector<int>& channels, vector<string>& pars)");
5882
 
5883
    if (pars.size() < 2)
5884
    {
5885
        MSG_ERROR("Less than 2 parameters!");
348 andreas 5886
#if TESTMODE == 1
5887
        setAllDone();
5888
#endif
15 andreas 5889
        return;
5890
    }
5891
 
16 andreas 5892
    TError::clear();
15 andreas 5893
    size_t pos = pars[1].find(",");
5894
    int x, y;
5895
 
5896
    if (pos == string::npos)
5897
    {
5898
        x = atoi(pars[1].c_str());
5899
        y = 0;
5900
    }
5901
    else
5902
    {
5903
        x = atoi(pars[1].substr(0, pos).c_str());
5904
        y = atoi(pars[1].substr(pos+1).c_str());
5905
    }
5906
 
96 andreas 5907
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 5908
 
5909
    if (!pg)
348 andreas 5910
    {
5911
#if TESTMODE == 1
5912
        setAllDone();
5913
#endif
96 andreas 5914
        return;
348 andreas 5915
    }
15 andreas 5916
 
5917
    pg->setHideEndPosition(x, y);
348 andreas 5918
#if TESTMODE == 1
5919
    if (_gTestMode)
5920
    {
5921
        int x, y;
5922
        pg->getHideEndPosition(&x, &y);
5923
        _gTestMode->setResult(intToString(x) + "," + intToString(y));
5924
    }
5925
 
5926
    __success = true;
5927
    setAllDone();
5928
#endif
15 andreas 5929
}
5930
 
5931
/**
5932
 * Set the hide effect time for the specified popup page.
5933
 */
22 andreas 5934
void TPageManager::doPHT(int, vector<int>&, vector<string>& pars)
15 andreas 5935
{
5936
    DECL_TRACER("TPageManager::doPHT(int port, vector<int>& channels, vector<string>& pars)");
5937
 
5938
    if (pars.size() < 2)
5939
    {
5940
        MSG_ERROR("Less than 2 parameters!");
348 andreas 5941
#if TESTMODE == 1
5942
        setAllDone();
5943
#endif
15 andreas 5944
        return;
5945
    }
5946
 
16 andreas 5947
    TError::clear();
96 andreas 5948
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 5949
 
5950
    if (!pg)
348 andreas 5951
    {
5952
#if TESTMODE == 1
5953
        setAllDone();
5954
#endif
96 andreas 5955
        return;
348 andreas 5956
    }
15 andreas 5957
 
5958
    pg->setHideTime(atoi(pars[1].c_str()));
348 andreas 5959
#if TESTMODE == 1
5960
    if (_gTestMode)
5961
        _gTestMode->setResult(intToString(pg->getHideTime()));
5962
 
5963
    __success = true;
5964
    setAllDone();
5965
#endif
15 andreas 5966
}
5967
 
5968
/**
14 andreas 5969
 * Close all popups on a specified page. If the page name is empty, the current
5970
 * page is used. Same as the ’Clear Page’ command in TPDesign4.
5971
 */
22 andreas 5972
void TPageManager::doPPA(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 5973
{
5974
    DECL_TRACER("TPageManager::doPPA(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5975
 
16 andreas 5976
    TError::clear();
11 andreas 5977
    TPage *pg;
5978
 
5979
    if (pars.size() == 0)
5980
        pg = getPage(mActualPage);
5981
    else
5982
        pg = getPage(pars[0]);
5983
 
5984
    if (!pg)
348 andreas 5985
    {
5986
#if TESTMODE == 1
5987
        setAllDone();
5988
#endif
11 andreas 5989
        return;
348 andreas 5990
    }
11 andreas 5991
 
12 andreas 5992
    pg->drop();
14 andreas 5993
    pg->resetZOrder();
348 andreas 5994
#if TESTMODE == 1
5995
    setDone();
5996
#endif
11 andreas 5997
}
5998
 
14 andreas 5999
/**
6000
 * Deactivate a specific popup page on either a specified page or the current
6001
 * page. If the page name is empty, the current page is used. If the popup page
6002
 * is part of a group, the whole group is deactivated. This command works in
6003
 * the same way as the ’Hide Popup’ command in TPDesign4.
6004
 */
22 andreas 6005
void TPageManager::doPPF(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6006
{
6007
    DECL_TRACER("TPageManager::doPPF(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
6008
 
6009
    if (pars.size() < 1)
6010
    {
6011
        MSG_ERROR("At least 1 parameter is expected!");
349 andreas 6012
#if TESTMODE == 1
6013
        setAllDone();
6014
#endif
12 andreas 6015
        return;
6016
    }
6017
 
16 andreas 6018
    TError::clear();
14 andreas 6019
    hideSubPage(pars[0]);
335 andreas 6020
#if TESTMODE == 1
6021
    setDone();
6022
#endif
12 andreas 6023
}
6024
 
14 andreas 6025
/**
6026
 * Toggle a specific popup page on either a specified page or the current page.
6027
 * If the page name is empty, the current page is used. Toggling refers to the
6028
 * activating/deactivating (On/Off) of a popup page. This command works in the
6029
 * same way as the ’Toggle Popup’ command in TPDesign4.
6030
 */
22 andreas 6031
void TPageManager::doPPG(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6032
{
6033
    DECL_TRACER("TPageManager::doPPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 6034
 
12 andreas 6035
    if (pars.size() < 1)
6036
    {
6037
        MSG_ERROR("At least 1 parameter is expected!");
349 andreas 6038
#if TESTMODE == 1
6039
        setAllDone();
6040
#endif
12 andreas 6041
        return;
6042
    }
6043
 
16 andreas 6044
    TError::clear();
14 andreas 6045
    TPage *page = getPage(mActualPage);
6046
 
6047
    if (!page)
6048
    {
6049
        MSG_ERROR("No active page found! Internal error.");
349 andreas 6050
#if TESTMODE == 1
6051
        setAllDone();
6052
#endif
14 andreas 6053
        return;
6054
    }
6055
 
12 andreas 6056
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 6057
 
12 andreas 6058
    if (!pg)
349 andreas 6059
    {
6060
#if TESTMODE == 1
6061
        setAllDone();
6062
#endif
12 andreas 6063
        return;
349 andreas 6064
    }
14 andreas 6065
 
12 andreas 6066
    if (pg->isVisible())
6067
    {
6068
        pg->drop();
162 andreas 6069
        page->decZOrder();
349 andreas 6070
#if TESTMODE == 1
6071
        setDone();
6072
#endif
12 andreas 6073
        return;
6074
    }
6075
 
6076
    TSubPage *sub = getFirstSubPageGroup(pg->getGroupName());
14 andreas 6077
 
12 andreas 6078
    while(sub)
6079
    {
6080
        if (sub->getGroupName().compare(pg->getGroupName()) == 0 && sub->isVisible())
6081
            sub->drop();
14 andreas 6082
 
12 andreas 6083
        sub = getNextSubPageGroup(pg->getGroupName(), sub);
6084
    }
6085
 
152 andreas 6086
    pg->setZOrder(page->getNextZOrder());
6087
    MSG_DEBUG("Setting new Z-order " << page->getActZOrder() << " on page " << page->getName());
12 andreas 6088
    pg->show();
349 andreas 6089
#if TESTMODE == 1
6090
    setDone();
6091
#endif
12 andreas 6092
}
6093
 
14 andreas 6094
/**
6095
 * Kill refers to the deactivating (Off) of a popup window from all pages. If
6096
 * the pop-up page is part of a group, the whole group is deactivated. This
6097
 * command works in the same way as the 'Clear Group' command in TPDesign 4.
6098
 */
22 andreas 6099
void TPageManager::doPPK(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6100
{
6101
    DECL_TRACER("TPageManager::doPPK(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 6102
 
12 andreas 6103
    if (pars.size() < 1)
6104
    {
6105
        MSG_ERROR("At least 1 parameter is expected!");
349 andreas 6106
#if TESTMODE == 1
6107
        setAllDone();
6108
#endif
12 andreas 6109
        return;
6110
    }
6111
 
16 andreas 6112
    TError::clear();
14 andreas 6113
    TPage *page = getPage(mActualPage);
6114
 
6115
    if (!page)
6116
    {
6117
        MSG_ERROR("No active page found! Internal error.");
349 andreas 6118
#if TESTMODE == 1
6119
        setAllDone();
6120
#endif
14 andreas 6121
        return;
6122
    }
6123
 
12 andreas 6124
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 6125
 
12 andreas 6126
    if (pg)
14 andreas 6127
    {
6128
        pg->drop();
162 andreas 6129
        page->decZOrder();
14 andreas 6130
    }
349 andreas 6131
#if TESTMODE == 1
6132
        setDone();
6133
#endif
12 andreas 6134
}
6135
 
14 andreas 6136
/**
6137
 * Set the modality of a specific popup page to Modal or NonModal.
6138
 * A Modal popup page, when active, only allows you to use the buttons and
6139
 * features on that popup page. All other buttons on the panel page are
6140
 * inactivated.
6141
 */
22 andreas 6142
void TPageManager::doPPM(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6143
{
6144
    DECL_TRACER("TPageManager::doPPM(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 6145
 
12 andreas 6146
    if (pars.size() < 2)
6147
    {
6148
        MSG_ERROR("Expecting 2 parameters!");
349 andreas 6149
#if TESTMODE == 1
6150
        setAllDone();
6151
#endif
12 andreas 6152
        return;
6153
    }
14 andreas 6154
 
16 andreas 6155
    TError::clear();
12 andreas 6156
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 6157
 
12 andreas 6158
    if (pg)
6159
    {
162 andreas 6160
        if (pars[1] == "1" || strCaseCompare(pars[1], "modal") == 0)
12 andreas 6161
            pg->setModal(1);
6162
        else
6163
            pg->setModal(0);
349 andreas 6164
#if TESTMODE == 1
6165
        if (_gTestMode)
6166
            _gTestMode->setResult(pg->isModal() ? "TRUE" : "FALSE");
6167
#endif
12 andreas 6168
    }
349 andreas 6169
#if TESTMODE == 1
6170
        setAllDone();
6171
#endif
12 andreas 6172
}
6173
 
14 andreas 6174
/**
6175
 * Activate a specific popup page to launch on either a specified page or the
6176
 * current page. If the page name is empty, the current page is used. If the
6177
 * popup page is already on, do not re-draw it. This command works in the same
6178
 * way as the ’Show Popup’ command in TPDesign4.
6179
 */
22 andreas 6180
void TPageManager::doPPN(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6181
{
6182
    DECL_TRACER("TPageManager::doPPN(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
6183
 
6184
    if (pars.size() < 1)
6185
    {
6186
        MSG_ERROR("At least 1 parameter is expected!");
349 andreas 6187
#if TESTMODE == 1
6188
        setAllDone();
6189
#endif
12 andreas 6190
        return;
6191
    }
6192
 
16 andreas 6193
    TError::clear();
14 andreas 6194
    showSubPage(pars[0]);
349 andreas 6195
#if TESTMODE == 1
6196
    setDone();
6197
#endif
12 andreas 6198
}
6199
 
14 andreas 6200
/**
15 andreas 6201
 * Set a specific popup page to timeout within a specified time. If timeout is
6202
 * empty, popup page will clear the timeout.
6203
 */
22 andreas 6204
void TPageManager::doPPT(int, vector<int>&, vector<string>& pars)
15 andreas 6205
{
6206
    DECL_TRACER("TPageManager::doPPT(int port, vector<int>& channels, vector<string>& pars)");
6207
 
6208
    if (pars.size() < 2)
6209
    {
6210
        MSG_ERROR("Expecting 2 parameters!");
351 andreas 6211
#if TESTMODE == 1
6212
        setAllDone();
6213
#endif
15 andreas 6214
        return;
6215
    }
6216
 
16 andreas 6217
    TError::clear();
96 andreas 6218
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6219
 
6220
    if (!pg)
351 andreas 6221
    {
6222
#if TESTMODE == 1
6223
        setAllDone();
6224
#endif
96 andreas 6225
        return;
351 andreas 6226
    }
15 andreas 6227
 
6228
    pg->setTimeout(atoi(pars[1].c_str()));
351 andreas 6229
#if TESTMODE == 1
6230
    if (_gTestMode)
6231
        _gTestMode->setResult(intToString(pg->getTimeout()));
6232
 
6233
    __success = true;
6234
    setAllDone();
6235
#endif
15 andreas 6236
}
6237
 
6238
/**
14 andreas 6239
 * Close all popups on all pages. This command works in the same way as the
6240
 * 'Clear All' command in TPDesign 4.
6241
 */
22 andreas 6242
void TPageManager::doPPX(int, std::vector<int>&, std::vector<std::string>&)
12 andreas 6243
{
6244
    DECL_TRACER("TPageManager::doPPX(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
6245
 
16 andreas 6246
    TError::clear();
12 andreas 6247
    PCHAIN_T *chain = mPchain;
14 andreas 6248
 
12 andreas 6249
    while(chain)
6250
    {
6251
        TSubPage *sub = chain->page->getFirstSubPage();
14 andreas 6252
 
12 andreas 6253
        while (sub)
6254
        {
351 andreas 6255
            MSG_DEBUG("Dropping subpage " << sub->getNumber() << ", \"" << sub->getName() << "\".");
12 andreas 6256
            sub->drop();
6257
            sub = chain->page->getNextSubPage();
6258
        }
14 andreas 6259
 
12 andreas 6260
        chain = chain->next;
6261
    }
14 andreas 6262
 
6263
    TPage *page = getPage(mActualPage);
6264
 
6265
    if (!page)
6266
    {
6267
        MSG_ERROR("No active page found! Internal error.");
351 andreas 6268
#if TESTMODE == 1
6269
        setAllDone();
6270
#endif
14 andreas 6271
        return;
6272
    }
6273
 
6274
    page->resetZOrder();
351 andreas 6275
#if TESTMODE == 1
6276
    setDone();
6277
#endif
12 andreas 6278
}
6279
 
14 andreas 6280
/**
15 andreas 6281
 * Set the show effect for the specified popup page to the named show effect.
6282
 */
22 andreas 6283
void TPageManager::doPSE(int, vector<int>&, vector<string>& pars)
15 andreas 6284
{
6285
    DECL_TRACER("TPageManager::doPSE(int port, vector<int>& channels, vector<string>& pars)");
6286
 
6287
    if (pars.size() < 2)
6288
    {
6289
        MSG_ERROR("Less than 2 parameters!");
351 andreas 6290
#if TESTMODE == 1
6291
        setAllDone();
6292
#endif
15 andreas 6293
        return;
6294
    }
6295
 
16 andreas 6296
    TError::clear();
96 andreas 6297
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6298
 
6299
    if (!pg)
351 andreas 6300
    {
6301
#if TESTMODE == 1
6302
        setAllDone();
6303
#endif
96 andreas 6304
        return;
351 andreas 6305
    }
15 andreas 6306
 
162 andreas 6307
    if (strCaseCompare(pars[1], "fade") == 0)
15 andreas 6308
        pg->setShowEffect(SE_FADE);
162 andreas 6309
    else if (strCaseCompare(pars[1], "slide to left") == 0)
15 andreas 6310
        pg->setShowEffect(SE_SLIDE_LEFT);
162 andreas 6311
    else if (strCaseCompare(pars[1], "slide to right") == 0)
15 andreas 6312
        pg->setShowEffect(SE_SLIDE_RIGHT);
162 andreas 6313
    else if (strCaseCompare(pars[1], "slide to top") == 0)
15 andreas 6314
        pg->setShowEffect(SE_SLIDE_TOP);
162 andreas 6315
    else if (strCaseCompare(pars[1], "slide to bottom") == 0)
15 andreas 6316
        pg->setShowEffect(SE_SLIDE_BOTTOM);
162 andreas 6317
    else if (strCaseCompare(pars[1], "slide to left fade") == 0)
15 andreas 6318
        pg->setShowEffect(SE_SLIDE_LEFT_FADE);
162 andreas 6319
    else if (strCaseCompare(pars[1], "slide to right fade") == 0)
15 andreas 6320
        pg->setShowEffect(SE_SLIDE_RIGHT_FADE);
162 andreas 6321
    else if (strCaseCompare(pars[1], "slide to top fade") == 0)
15 andreas 6322
        pg->setShowEffect(SE_SLIDE_TOP_FADE);
162 andreas 6323
    else if (strCaseCompare(pars[1], "slide to bottom fade") == 0)
15 andreas 6324
        pg->setShowEffect(SE_SLIDE_BOTTOM_FADE);
6325
    else
6326
        pg->setShowEffect(SE_NONE);
351 andreas 6327
#if TESTMODE == 1
6328
    if (_gTestMode)
6329
        _gTestMode->setResult(intToString(pg->getShowEffect()));
6330
 
6331
    __success = true;
6332
    setAllDone();
6333
#endif
15 andreas 6334
}
6335
 
162 andreas 6336
/**
6337
 * Set the show effect position. Only 1 coordinate is ever needed for an effect;
6338
 * however, the command will specify both. This command sets the location at
6339
 * which the effect will begin.
6340
 */
22 andreas 6341
void TPageManager::doPSP(int, vector<int>&, vector<string>& pars)
15 andreas 6342
{
6343
    DECL_TRACER("TPageManager::doPSP(int port, vector<int>& channels, vector<string>& pars)");
6344
 
6345
    if (pars.size() < 2)
6346
    {
6347
        MSG_ERROR("Less than 2 parameters!");
351 andreas 6348
#if TESTMODE == 1
6349
        setAllDone();
6350
#endif
15 andreas 6351
        return;
6352
    }
6353
 
16 andreas 6354
    TError::clear();
15 andreas 6355
    size_t pos = pars[1].find(",");
6356
    int x, y;
6357
 
6358
    if (pos == string::npos)
6359
    {
6360
        x = atoi(pars[1].c_str());
6361
        y = 0;
6362
    }
6363
    else
6364
    {
6365
        x = atoi(pars[1].substr(0, pos).c_str());
6366
        y = atoi(pars[1].substr(pos+1).c_str());
6367
    }
6368
 
96 andreas 6369
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6370
 
6371
    if (!pg)
351 andreas 6372
    {
6373
#if TESTMODE == 1
6374
        setAllDone();
6375
#endif
96 andreas 6376
        return;
351 andreas 6377
    }
15 andreas 6378
 
6379
    pg->setShowEndPosition(x, y);
351 andreas 6380
#if TESTMODE == 1
6381
    pg->getShowEndPosition(&x, &y);
6382
 
6383
    if (_gTestMode)
6384
        _gTestMode->setResult(intToString(x) + "," + intToString(y));
6385
 
6386
    __success = true;
6387
    setAllDone();
6388
#endif
15 andreas 6389
}
6390
 
6391
/**
6392
 * Set the show effect time for the specified popup page.
6393
 */
22 andreas 6394
void TPageManager::doPST(int, vector<int>&, vector<string>& pars)
15 andreas 6395
{
6396
    DECL_TRACER("TPageManager::doPST(int port, vector<int>& channels, vector<string>& pars)");
6397
 
6398
    if (pars.size() < 2)
6399
    {
6400
        MSG_ERROR("Less than 2 parameters!");
351 andreas 6401
#if TESTMODE == 1
6402
        setAllDone();
6403
#endif
15 andreas 6404
        return;
6405
    }
6406
 
16 andreas 6407
    TError::clear();
96 andreas 6408
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6409
 
6410
    if (!pg)
351 andreas 6411
    {
6412
#if TESTMODE == 1
6413
        setAllDone();
6414
#endif
96 andreas 6415
        return;
351 andreas 6416
    }
15 andreas 6417
 
6418
    pg->setShowTime(atoi(pars[1].c_str()));
351 andreas 6419
#if TESTMODE == 1
6420
    if (_gTestMode)
6421
        _gTestMode->setResult(intToString(pg->getShowTime()));
6422
 
6423
    __success = 1;
6424
    setAllDone();
6425
#endif
15 andreas 6426
}
6427
 
6428
/**
14 andreas 6429
 * Flips to a page with a specified page name. If the page is currently active,
6430
 * it will not redraw the page.
6431
 */
22 andreas 6432
void TPageManager::doPAGE(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6433
{
6434
    DECL_TRACER("TPageManager::doPAGE(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 6435
 
15 andreas 6436
    if (pars.empty())
6437
    {
6438
        MSG_WARNING("Got no page parameter!");
351 andreas 6439
#if TESTMODE == 1
6440
        setAllDone();
6441
#endif
15 andreas 6442
        return;
6443
    }
14 andreas 6444
 
16 andreas 6445
    TError::clear();
15 andreas 6446
    setPage(pars[0]);
351 andreas 6447
#if TESTMODE == 1
6448
    if (_gTestMode)
6449
        _gTestMode->setResult(intToString(getActualPageNumber()));
6450
 
6451
    setDone();
6452
#endif
15 andreas 6453
}
6454
 
6455
/**
38 andreas 6456
 * @brief TPageManager::doANI Run a button animation (in 1/10 second).
6457
 * Syntax:
6458
 *      ^ANI-<vt addr range>,<start state>,<end state>,<time>
6459
 * Variable:
6460
 *      variable text address range = 1 - 4000.
6461
 *      start state = Beginning of button state (0= current state).
6462
 *      end state = End of button state.
6463
 *      time = In 1/10 second intervals.
6464
 * Example:
6465
 *      SEND_COMMAND Panel,"'^ANI-500,1,25,100'"
6466
 * Runs a button animation at text range 500 from state 1 to state 25 for 10 seconds.
6467
 *
6468
 * @param port      The port number
6469
 * @param channels  The channels of the buttons
6470
 * @param pars      The parameters
6471
 */
6472
void TPageManager::doANI(int port, std::vector<int> &channels, std::vector<std::string> &pars)
6473
{
6474
    DECL_TRACER("TPageManager::doANI(int port, std::vector<int> &channels, std::vector<std::string> &pars)");
6475
 
6476
    if (pars.size() < 3)
6477
    {
6478
        MSG_ERROR("Expecting 3 parameters but got " << pars.size() << "! Ignoring command.");
6479
        return;
6480
    }
6481
 
6482
    TError::clear();
6483
    int stateStart = atoi(pars[0].c_str());
6484
    int endState = atoi(pars[1].c_str());
6485
    int runTime = atoi(pars[2].c_str());
6486
 
193 andreas 6487
    vector<TMap::MAP_T> map = findButtons(port, channels);
38 andreas 6488
 
6489
    if (TError::isError() || map.empty())
6490
        return;
6491
 
6492
    vector<Button::TButton *> buttons = collectButtons(map);
6493
 
83 andreas 6494
    if (buttons.size() > 0)
38 andreas 6495
    {
83 andreas 6496
        vector<Button::TButton *>::iterator mapIter;
6497
 
6498
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
6499
        {
6500
            Button::TButton *bt = *mapIter;
6501
            bt->startAnimation(stateStart, endState, runTime);
6502
        }
38 andreas 6503
    }
351 andreas 6504
#if TESTMODE == 1
6505
    if (_gTestMode)
6506
        _gTestMode->setResult(intToString(stateStart) + "," + intToString(endState) + "," + intToString(runTime));
6507
 
6508
    setDone();
6509
#endif
38 andreas 6510
}
6511
 
6512
/**
15 andreas 6513
 * Add page flip action to a button if it does not already exist.
6514
 */
6515
void TPageManager::doAPF(int port, vector<int>& channels, vector<string>& pars)
6516
{
6517
    DECL_TRACER("TPageManager::doAPF(int port, vector<int>& channels, vector<string>& pars)");
6518
 
6519
    if (pars.size() < 2)
6520
    {
6521
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
351 andreas 6522
#if TESTMODE == 1
6523
        setAllDone();
6524
#endif
14 andreas 6525
        return;
15 andreas 6526
    }
14 andreas 6527
 
16 andreas 6528
    TError::clear();
15 andreas 6529
    string action = pars[0];
6530
    string pname = pars[1];
14 andreas 6531
 
193 andreas 6532
    vector<TMap::MAP_T> map = findButtons(port, channels);
14 andreas 6533
 
15 andreas 6534
    if (TError::isError() || map.empty())
351 andreas 6535
    {
6536
#if TESTMODE == 1
6537
        setAllDone();
6538
#endif
15 andreas 6539
        return;
351 andreas 6540
    }
15 andreas 6541
 
6542
    vector<Button::TButton *> buttons = collectButtons(map);
6543
 
83 andreas 6544
    if (buttons.size() > 0)
12 andreas 6545
    {
83 andreas 6546
        vector<Button::TButton *>::iterator mapIter;
6547
 
6548
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
6549
        {
6550
            Button::TButton *bt = *mapIter;
6551
            bt->addPushFunction(action, pname);
6552
        }
15 andreas 6553
    }
351 andreas 6554
#if TESTMODE == 1
6555
    if (_gTestMode)
6556
        _gTestMode->setResult(toUpper(action) + "," + toUpper(pname));
6557
 
6558
    __success = true;
6559
    setAllDone();
6560
#endif
15 andreas 6561
}
12 andreas 6562
 
15 andreas 6563
/**
43 andreas 6564
 * Append non-unicode text.
6565
 */
6566
void TPageManager::doBAT(int port, vector<int> &channels, vector<string> &pars)
6567
{
6568
    DECL_TRACER("TPageManager::doBAT(int port, vector<int> &channels, vector<string> &pars)");
6569
 
6570
    if (pars.size() < 1)
6571
    {
6572
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
330 andreas 6573
#if TESTMODE == 1
334 andreas 6574
        setAllDone();
330 andreas 6575
#endif
43 andreas 6576
        return;
6577
    }
6578
 
6579
    TError::clear();
6580
    int btState = atoi(pars[0].c_str());
6581
    string text;
6582
 
6583
    if (pars.size() > 1)
6584
        text = pars[1];
6585
 
193 andreas 6586
    vector<TMap::MAP_T> map = findButtons(port, channels);
43 andreas 6587
 
6588
    if (TError::isError() || map.empty())
330 andreas 6589
    {
6590
#if TESTMODE == 1
334 andreas 6591
        setAllDone();
330 andreas 6592
#endif
43 andreas 6593
        return;
330 andreas 6594
    }
43 andreas 6595
 
6596
    vector<Button::TButton *> buttons = collectButtons(map);
6597
 
162 andreas 6598
    if (buttons.empty())
330 andreas 6599
    {
6600
#if TESTMODE == 1
334 andreas 6601
        setAllDone();
330 andreas 6602
#endif
162 andreas 6603
        return;
330 andreas 6604
    }
162 andreas 6605
 
6606
    vector<Button::TButton *>::iterator mapIter;
6607
 
6608
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
43 andreas 6609
    {
162 andreas 6610
        Button::TButton *bt = *mapIter;
43 andreas 6611
 
331 andreas 6612
        bt->appendText(text, btState - 1);
330 andreas 6613
#if TESTMODE == 1
331 andreas 6614
        if (_gTestMode)
330 andreas 6615
        {
331 andreas 6616
            int st = (btState > 0 ? (btState - 1) : 0);
6617
            _gTestMode->setResult(bt->getText(st));
333 andreas 6618
        }
330 andreas 6619
 
331 andreas 6620
        __success = true;
330 andreas 6621
#endif
43 andreas 6622
    }
334 andreas 6623
#if TESTMODE == 1
6624
    setDone();
6625
#endif
43 andreas 6626
}
6627
 
6628
/**
60 andreas 6629
 * @brief Append unicode text. Same format as ^UNI.
6630
 * This command allows to set up to 50 characters of ASCII code. The unicode
6631
 * characters must be set as hex numbers.
6632
 */
6633
void TPageManager::doBAU(int port, vector<int>& channels, vector<string>& pars)
6634
{
6635
    DECL_TRACER("TPageManager::doBAU(int port, vector<int>& channels, vector<string>& pars)");
6636
 
6637
    if (pars.size() < 1)
6638
    {
6639
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 6640
#if TESTMODE == 1
6641
        setAllDone();
6642
#endif
60 andreas 6643
        return;
6644
    }
6645
 
6646
    TError::clear();
6647
    int btState = atoi(pars[0].c_str());
6648
    string text;
6649
    char ch[3];
6650
 
331 andreas 6651
    if (pars.size() > 1)
6652
        text = pars[1];
6653
 
6654
    if ((text.size() % 4) == 0)
60 andreas 6655
    {
162 andreas 6656
        try
60 andreas 6657
        {
162 andreas 6658
            text = pars[1];
331 andreas 6659
            MSG_DEBUG("Processing UTF16 string: " << text);
162 andreas 6660
            // Because the unicode characters are hex numbers, we scan the text
6661
            // and convert the hex numbers into real numbers.
6662
            size_t len = text.length();
6663
            bool inHex = false;
6664
            int lastChar = 0;
331 andreas 6665
            uint16_t *numstr = new uint16_t[len / 4];
162 andreas 6666
            int uniPos = 0;
331 andreas 6667
            int cntCount = 0;
60 andreas 6668
 
162 andreas 6669
            for (size_t i = 0; i < len; i++)
60 andreas 6670
            {
162 andreas 6671
                int c = text.at(i);
60 andreas 6672
 
162 andreas 6673
                if (!inHex && isHex(c))
6674
                {
6675
                    inHex = true;
6676
                    lastChar = c;
6677
                    continue;
6678
                }
6679
 
6680
                if (inHex && !isHex(c))
6681
                    break;
6682
 
6683
                if (inHex && isHex(c))
6684
                {
6685
                    ch[0] = lastChar;
6686
                    ch[1] = c;
6687
                    ch[2] = 0;
6688
                    uint16_t num = (uint16_t)strtol(ch, NULL, 16);
331 andreas 6689
 
6690
                    if ((cntCount % 2) != 0)
6691
                    {
6692
                        numstr[uniPos] |= num;
6693
                        uniPos++;
6694
                    }
6695
                    else
6696
                        numstr[uniPos] = (num << 8) & 0xff00;
6697
 
6698
                    cntCount++;
162 andreas 6699
                    inHex = false;
6700
 
6701
                    if (uniPos >= 50)
6702
                        break;
331 andreas 6703
                }
6704
            }
162 andreas 6705
 
331 andreas 6706
            text.clear();
6707
            // Here we make from the real numbers a UTF8 string
6708
            for (size_t i = 0; i < len / 4; ++i)
6709
            {
6710
                if (numstr[i] <= 0x00ff)
6711
                {
6712
                    ch[0] = numstr[i];
6713
                    ch[1] = 0;
6714
                    text.append(ch);
162 andreas 6715
                }
331 andreas 6716
                else
6717
                {
6718
                    ch[0] = (numstr[i] >> 8) & 0x00ff;
6719
                    ch[1] = numstr[i] & 0x00ff;
6720
                    ch[2] = 0;
6721
                    text.append(ch);
6722
                }
60 andreas 6723
            }
6724
 
331 andreas 6725
            delete[] numstr;
60 andreas 6726
        }
162 andreas 6727
        catch (std::exception const & e)
6728
        {
6729
            MSG_ERROR("Character conversion error: " << e.what());
351 andreas 6730
#if TESTMODE == 1
6731
            setAllDone();
6732
#endif
162 andreas 6733
            return;
6734
        }
60 andreas 6735
    }
331 andreas 6736
    else
6737
    {
6738
        MSG_WARNING("No or invalid UTF16 string: " << text);
351 andreas 6739
#if TESTMODE == 1
6740
        setAllDone();
6741
#endif
331 andreas 6742
        return;
6743
    }
60 andreas 6744
 
193 andreas 6745
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 6746
 
6747
    if (TError::isError() || map.empty())
351 andreas 6748
    {
6749
#if TESTMODE == 1
6750
        setAllDone();
6751
#endif
60 andreas 6752
        return;
351 andreas 6753
    }
60 andreas 6754
 
6755
    vector<Button::TButton *> buttons = collectButtons(map);
6756
 
83 andreas 6757
    if (buttons.size() > 0)
60 andreas 6758
    {
83 andreas 6759
        vector<Button::TButton *>::iterator mapIter;
60 andreas 6760
 
83 andreas 6761
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 6762
        {
83 andreas 6763
            Button::TButton *bt = *mapIter;
60 andreas 6764
 
331 andreas 6765
            bt->appendText(text, btState - 1);
330 andreas 6766
#if TESTMODE == 1
331 andreas 6767
            if (_gTestMode)
6768
                _gTestMode->setResult(bt->getText(btState - 1));
330 andreas 6769
 
331 andreas 6770
            __success = true;
330 andreas 6771
#endif
60 andreas 6772
        }
6773
    }
330 andreas 6774
#if TESTMODE == 1
334 andreas 6775
    setDone();
330 andreas 6776
#endif
60 andreas 6777
}
6778
 
6779
/**
43 andreas 6780
 * @brief TPageManager::doBCB Set the border color.
6781
 * Set the border color to the specified color. Only if the specified border
6782
 * color is not the same as the current color.
6783
 * Note: Color can be assigned by color name (without spaces), number or
6784
 * R,G,B value (RRGGBB or RRGGBBAA).
6785
 */
6786
void TPageManager::doBCB(int port, vector<int> &channels, vector<string> &pars)
6787
{
6788
    DECL_TRACER("TPageManager::doBCB(int port, vector<int> &channels, vector<string> &pars)");
6789
 
6790
    if (pars.size() < 1)
6791
    {
6792
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 6793
#if TESTMODE == 1
6794
        setAllDone();
6795
#endif
43 andreas 6796
        return;
6797
    }
6798
 
6799
    TError::clear();
6800
    int btState = atoi(pars[0].c_str());
6801
    string color;
6802
 
6803
    if (pars.size() > 1)
6804
        color = pars[1];
6805
 
193 andreas 6806
    vector<TMap::MAP_T> map = findButtons(port, channels);
43 andreas 6807
 
6808
    if (TError::isError() || map.empty())
351 andreas 6809
    {
6810
#if TESTMODE == 1
6811
        setAllDone();
6812
#endif
43 andreas 6813
        return;
351 andreas 6814
    }
43 andreas 6815
 
6816
    vector<Button::TButton *> buttons = collectButtons(map);
6817
 
83 andreas 6818
    if (buttons.size() > 0)
43 andreas 6819
    {
83 andreas 6820
        vector<Button::TButton *>::iterator mapIter;
43 andreas 6821
 
83 andreas 6822
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
43 andreas 6823
        {
83 andreas 6824
            Button::TButton *bt = *mapIter;
351 andreas 6825
            bt->setBorderColor(color, btState - 1);
6826
#if TESTMODE == 1
6827
            if (_gTestMode)
6828
                _gTestMode->setResult(bt->getBorderColor(btState == 0 ? 0 : btState - 1));
6829
#endif
43 andreas 6830
        }
6831
    }
351 andreas 6832
#if TESTMODE == 1
6833
    setDone();
6834
#endif
43 andreas 6835
}
60 andreas 6836
 
351 andreas 6837
/*
6838
 * Get the border color and send it as a custom event.
6839
 */
82 andreas 6840
void TPageManager::getBCB(int port, vector<int> &channels, vector<string> &pars)
6841
{
6842
    DECL_TRACER("TPageManager::getBCB(int port, vector<int> &channels, vector<string> &pars)");
6843
 
6844
    if (pars.size() < 1)
6845
    {
6846
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 6847
#if TESTMODE == 1
6848
        setAllDone();
6849
#endif
82 andreas 6850
        return;
6851
    }
6852
 
6853
    TError::clear();
6854
    int btState = atoi(pars[0].c_str());
6855
    string color;
6856
 
193 andreas 6857
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 6858
 
6859
    if (TError::isError() || map.empty())
351 andreas 6860
    {
6861
#if TESTMODE == 1
6862
        setAllDone();
6863
#endif
82 andreas 6864
        return;
351 andreas 6865
    }
82 andreas 6866
 
6867
    vector<Button::TButton *> buttons = collectButtons(map);
6868
 
351 andreas 6869
    if (buttons.empty())
82 andreas 6870
    {
351 andreas 6871
#if TESTMODE == 1
6872
        setAllDone();
6873
#endif
6874
        return;
6875
    }
82 andreas 6876
 
351 andreas 6877
    vector<Button::TButton *>::iterator iter;
6878
 
6879
    for (iter = buttons.begin(); iter != buttons.end(); ++iter)
6880
    {
6881
        Button::TButton *bt = *iter;
6882
 
110 andreas 6883
        if (btState == 0)       // All instances?
82 andreas 6884
        {
110 andreas 6885
            int bst = bt->getNumberInstances();
82 andreas 6886
 
110 andreas 6887
            for (int i = 0; i < bst; i++)
82 andreas 6888
            {
110 andreas 6889
                color = bt->getBorderColor(i);
82 andreas 6890
 
110 andreas 6891
                if (color.empty())
6892
                    continue;
83 andreas 6893
 
300 andreas 6894
                sendCustomEvent(i + 1, (int)color.length(), 0, color, 1011, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 6895
#if TESTMODE == 1
6896
                __success = true;
6897
 
6898
                if (_gTestMode)
6899
                    _gTestMode->setResult(color);
6900
#endif
83 andreas 6901
            }
110 andreas 6902
        }
6903
        else
6904
        {
6905
            color = bt->getBorderColor(btState - 1);
83 andreas 6906
 
110 andreas 6907
            if (color.empty())
351 andreas 6908
                continue;
82 andreas 6909
 
300 andreas 6910
            sendCustomEvent(btState, (int)color.length(), 0, color, 1011, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 6911
#if TESTMODE == 1
6912
            __success = true;
6913
 
6914
            if (_gTestMode)
6915
                _gTestMode->setResult(color);
6916
#endif
82 andreas 6917
        }
6918
    }
351 andreas 6919
#if TESTMODE == 1
6920
    setAllDone();
6921
#endif
82 andreas 6922
}
6923
 
43 andreas 6924
/**
60 andreas 6925
 * @brief Set the fill color to the specified color.
6926
 * Only if the specified fill color is not the same as the current color.
6927
 * Note: Color can be assigned by color name (without spaces), number or R,G,B value (RRGGBB or RRGGBBAA).
15 andreas 6928
 */
60 andreas 6929
void TPageManager::doBCF(int port, vector<int>& channels, vector<std::string>& pars)
15 andreas 6930
{
60 andreas 6931
    DECL_TRACER("TPageManager::doBCF(int port, vector<int>& channels, vector<std::string>& pars)");
15 andreas 6932
 
60 andreas 6933
    if (pars.size() < 1)
15 andreas 6934
    {
60 andreas 6935
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 6936
#if TESTMODE == 1
6937
        setAllDone();
6938
#endif
12 andreas 6939
        return;
6940
    }
14 andreas 6941
 
16 andreas 6942
    TError::clear();
15 andreas 6943
    int btState = atoi(pars[0].c_str());
60 andreas 6944
    string color;
14 andreas 6945
 
60 andreas 6946
    if (pars.size() > 1)
6947
        color = pars[1];
6948
 
193 andreas 6949
    vector<TMap::MAP_T> map = findButtons(port, channels);
15 andreas 6950
 
6951
    if (TError::isError() || map.empty())
351 andreas 6952
    {
6953
#if TESTMODE == 1
6954
        setAllDone();
6955
#endif
15 andreas 6956
        return;
351 andreas 6957
    }
15 andreas 6958
 
6959
    vector<Button::TButton *> buttons = collectButtons(map);
6960
 
83 andreas 6961
    if (buttons.size() > 0)
15 andreas 6962
    {
83 andreas 6963
        vector<Button::TButton *>::iterator mapIter;
15 andreas 6964
 
83 andreas 6965
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
15 andreas 6966
        {
83 andreas 6967
            Button::TButton *bt = *mapIter;
351 andreas 6968
            bt->setFillColor(color, btState - 1);
6969
#if TESTMODE == 1
6970
            if (_gTestMode)
6971
                _gTestMode->setResult(bt->getFillColor(btState == 0 ? 0 : btState - 1));
6972
#endif
15 andreas 6973
        }
6974
    }
351 andreas 6975
#if TESTMODE == 1
6976
    setDone();
6977
#endif
12 andreas 6978
}
6979
 
351 andreas 6980
/*
6981
 * Get the fill color and send it via a custom event to the NetLinx.
6982
 */
82 andreas 6983
void TPageManager::getBCF(int port, vector<int> &channels, vector<string> &pars)
6984
{
6985
    DECL_TRACER("TPageManager::getBCF(int port, vector<int> &channels, vector<string> &pars)");
6986
 
6987
    if (pars.size() < 1)
6988
    {
6989
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 6990
#if TESTMODE == 1
6991
        setAllDone();
6992
#endif
82 andreas 6993
        return;
6994
    }
6995
 
6996
    TError::clear();
6997
    int btState = atoi(pars[0].c_str());
6998
    string color;
6999
 
193 andreas 7000
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 7001
 
7002
    if (TError::isError() || map.empty())
351 andreas 7003
    {
7004
#if TESTMODE == 1
7005
        setAllDone();
7006
#endif
82 andreas 7007
        return;
351 andreas 7008
    }
82 andreas 7009
 
7010
    vector<Button::TButton *> buttons = collectButtons(map);
7011
 
351 andreas 7012
    if (buttons.empty())
82 andreas 7013
    {
351 andreas 7014
#if TESTMODE == 1
7015
        setAllDone();
7016
#endif
7017
        return;
7018
    }
82 andreas 7019
 
351 andreas 7020
    vector<Button::TButton *>::iterator iter;
7021
 
7022
    for (iter = buttons.begin(); iter != buttons.end(); ++iter)
7023
    {
7024
        Button::TButton *bt = *iter;
7025
 
110 andreas 7026
        if (btState == 0)       // All instances?
82 andreas 7027
        {
110 andreas 7028
            int bst = bt->getNumberInstances();
82 andreas 7029
 
110 andreas 7030
            for (int i = 0; i < bst; i++)
82 andreas 7031
            {
110 andreas 7032
                color = bt->getFillColor(i);
82 andreas 7033
 
110 andreas 7034
                if (color.empty())
7035
                    continue;
82 andreas 7036
 
300 andreas 7037
                sendCustomEvent(i + 1, (int)color.length(), 0, color, 1012, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 7038
#if TESTMODE == 1
7039
                __success = true;
7040
 
7041
                if (_gTestMode)
7042
                    _gTestMode->setResult(color);
7043
#endif
83 andreas 7044
            }
82 andreas 7045
        }
110 andreas 7046
        else
7047
        {
7048
            color = bt->getFillColor(btState-1);
351 andreas 7049
 
7050
            if (color.empty())
7051
                continue;
7052
 
300 andreas 7053
            sendCustomEvent(btState, (int)color.length(), 0, color, 1012, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 7054
#if TESTMODE == 1
7055
            __success = true;
7056
 
7057
            if (_gTestMode)
7058
                _gTestMode->setResult(color);
7059
#endif
110 andreas 7060
        }
82 andreas 7061
    }
351 andreas 7062
#if TESTMODE == 1
7063
    setAllDone();
7064
#endif
82 andreas 7065
}
7066
 
60 andreas 7067
/**
7068
 * @brief Set the text color to the specified color.
7069
 * Only if the specified text color is not the same as the current color.
7070
 * Note: Color can be assigned by color name (without spaces), number or R,G,B value (RRGGBB or RRGGBBAA).
7071
 */
7072
void TPageManager::doBCT(int port, vector<int>& channels, vector<string>& pars)
18 andreas 7073
{
60 andreas 7074
    DECL_TRACER("TPageManager::doBCT(int port, vector<int>& channels, vector<string>& pars)");
7075
 
7076
    if (pars.size() < 1)
7077
    {
7078
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7079
#if TESTMODE == 1
7080
        setAllDone();
7081
#endif
60 andreas 7082
        return;
7083
    }
7084
 
7085
    TError::clear();
7086
    int btState = atoi(pars[0].c_str());
7087
    string color;
7088
 
7089
    if (pars.size() > 1)
7090
        color = pars[1];
7091
 
193 andreas 7092
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 7093
 
7094
    if (TError::isError() || map.empty())
351 andreas 7095
    {
7096
#if TESTMODE == 1
7097
        setAllDone();
7098
#endif
60 andreas 7099
        return;
351 andreas 7100
    }
60 andreas 7101
 
7102
    vector<Button::TButton *> buttons = collectButtons(map);
7103
 
83 andreas 7104
    if (buttons.size() > 0)
60 andreas 7105
    {
83 andreas 7106
        vector<Button::TButton *>::iterator mapIter;
60 andreas 7107
 
83 andreas 7108
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 7109
        {
83 andreas 7110
            Button::TButton *bt = *mapIter;
351 andreas 7111
            bt->setTextColor(color, btState - 1);
7112
#if TESTMODE == 1
7113
            if (_gTestMode)
7114
                _gTestMode->setResult(bt->getTextColor(btState == 0 ? 0 : btState - 1));
7115
#endif
60 andreas 7116
        }
7117
    }
351 andreas 7118
#if TESTMODE == 1
7119
    setDone();
7120
#endif
18 andreas 7121
}
7122
 
351 andreas 7123
/*
7124
 * Get the text color of a button and send it via a custom event to the NetLinx.
7125
 */
82 andreas 7126
void TPageManager::getBCT(int port, vector<int> &channels, vector<string> &pars)
7127
{
7128
    DECL_TRACER("TPageManager::getBCT(int port, vector<int> &channels, vector<string> &pars)");
7129
 
7130
    if (pars.size() < 1)
7131
    {
7132
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7133
#if TESTMODE == 1
7134
        setAllDone();
7135
#endif
82 andreas 7136
        return;
7137
    }
7138
 
7139
    TError::clear();
7140
    int btState = atoi(pars[0].c_str());
7141
    string color;
7142
 
193 andreas 7143
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 7144
 
7145
    if (TError::isError() || map.empty())
351 andreas 7146
    {
7147
#if TESTMODE == 1
7148
        setAllDone();
7149
#endif
82 andreas 7150
        return;
351 andreas 7151
    }
82 andreas 7152
 
7153
    vector<Button::TButton *> buttons = collectButtons(map);
7154
 
351 andreas 7155
    if (buttons.empty())
82 andreas 7156
    {
351 andreas 7157
#if TESTMODE == 1
7158
        setAllDone();
7159
#endif
7160
        return;
7161
    }
82 andreas 7162
 
351 andreas 7163
    vector<Button::TButton *>::iterator iter;
7164
 
7165
    for (iter = buttons.begin(); iter != buttons.end(); ++iter)
7166
    {
7167
        Button::TButton *bt = *iter;
7168
 
110 andreas 7169
        if (btState == 0)       // All instances?
82 andreas 7170
        {
110 andreas 7171
            int bst = bt->getNumberInstances();
82 andreas 7172
 
110 andreas 7173
            for (int i = 0; i < bst; i++)
82 andreas 7174
            {
110 andreas 7175
                color = bt->getTextColor(i);
82 andreas 7176
 
110 andreas 7177
                if (color.empty())
7178
                    continue;
82 andreas 7179
 
300 andreas 7180
                sendCustomEvent(i + 1, (int)color.length(), 0, color, 1013, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 7181
#if TESTMODE == 1
7182
                __success = true;
7183
 
7184
                if (_gTestMode)
7185
                    _gTestMode->setResult(color);
7186
#endif
83 andreas 7187
            }
82 andreas 7188
        }
110 andreas 7189
        else
7190
        {
7191
            color = bt->getTextColor(btState - 1);
351 andreas 7192
 
7193
            if (color.empty())
7194
                continue;
7195
 
300 andreas 7196
            sendCustomEvent(btState, (int)color.length(), 0, color, 1013, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 7197
#if TESTMODE == 1
7198
            __success = true;
7199
 
7200
            if (_gTestMode)
7201
                _gTestMode->setResult(color);
7202
#endif
110 andreas 7203
        }
82 andreas 7204
    }
351 andreas 7205
#if TESTMODE == 1
7206
    setAllDone();
7207
#endif
82 andreas 7208
}
7209
 
60 andreas 7210
/**
7211
 * Set the button draw order
7212
 * Determines what order each layer of the button is drawn.
7213
 */
7214
void TPageManager::doBDO(int port, vector<int>& channels, vector<std::string>& pars)
32 andreas 7215
{
60 andreas 7216
    DECL_TRACER("TPageManager::doBDO(int port, vector<int>& channels, vector<std::string>& pars)");
32 andreas 7217
 
60 andreas 7218
    if (pars.size() < 1)
7219
    {
7220
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7221
#if TESTMODE == 1
7222
        setAllDone();
7223
#endif
32 andreas 7224
        return;
60 andreas 7225
    }
32 andreas 7226
 
60 andreas 7227
    TError::clear();
7228
    int btState = atoi(pars[0].c_str());
7229
    string order;
32 andreas 7230
 
60 andreas 7231
    if (pars.size() > 1)
7232
    {
7233
        string ord = pars[1];
7234
        // Convert the numbers into the expected draw order
7235
        for (size_t i = 0; i < ord.length(); i++)
7236
        {
7237
            if (ord.at(i) >= '1' && ord.at(i) <= '5')
7238
            {
7239
                char hv0[32];
7240
                snprintf(hv0, sizeof(hv0), "%02d", (int)(ord.at(i) - '0'));
7241
                order.append(hv0);
7242
            }
7243
            else
7244
            {
7245
                MSG_ERROR("Illegal order number " << ord.substr(i, 1) << "!");
7246
                return;
7247
            }
7248
        }
7249
 
7250
        if (order.length() != 10)
7251
        {
7252
            MSG_ERROR("Expected 5 order numbers but got " << (order.length() / 2)<< "!");
7253
            return;
7254
        }
7255
    }
7256
 
193 andreas 7257
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 7258
 
7259
    if (TError::isError() || map.empty())
351 andreas 7260
    {
7261
#if TESTMODE == 1
7262
        setAllDone();
7263
#endif
32 andreas 7264
        return;
351 andreas 7265
    }
32 andreas 7266
 
60 andreas 7267
    vector<Button::TButton *> buttons = collectButtons(map);
7268
 
83 andreas 7269
    if (buttons.size() > 0)
32 andreas 7270
    {
83 andreas 7271
        vector<Button::TButton *>::iterator mapIter;
32 andreas 7272
 
83 andreas 7273
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 7274
        {
83 andreas 7275
            Button::TButton *bt = *mapIter;
351 andreas 7276
            bt->setDrawOrder(order, btState - 1);
7277
#if TESTMODE == 1
7278
            if (_gTestMode)
7279
                _gTestMode->setResult(bt->getDrawOrder(btState == 0 ? 0 : btState - 1));
7280
#endif
60 andreas 7281
        }
7282
    }
351 andreas 7283
#if TESTMODE == 1
7284
    setDone();
7285
#endif
60 andreas 7286
}
32 andreas 7287
 
60 andreas 7288
/**
7289
 * Set the feedback type of the button.
7290
 * ONLY works on General-type buttons.
7291
 */
7292
void TPageManager::doBFB(int port, vector<int>& channels, vector<std::string>& pars)
7293
{
7294
    DECL_TRACER("TPageManager::doBFB(int port, vector<int>& channels, vector<std::string>& pars)");
32 andreas 7295
 
60 andreas 7296
    if (pars.size() < 1)
7297
    {
7298
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7299
#if TESTMODE == 1
7300
        setAllDone();
7301
#endif
60 andreas 7302
        return;
7303
    }
7304
 
7305
    TError::clear();
7306
    Button::FEEDBACK type = Button::FB_NONE;
7307
    string stype = pars[0];
7308
    vector<string> stypes = { "None", "Channel", "Invert", "On", "Momentary", "Blink" };
7309
    vector<string>::iterator iter;
7310
    int i = 0;
7311
 
7312
    for (iter = stypes.begin(); iter != stypes.end(); ++iter)
7313
    {
7314
        if (strCaseCompare(stype, *iter) == 0)
33 andreas 7315
        {
60 andreas 7316
            type = (Button::FEEDBACK)i;
7317
            break;
32 andreas 7318
        }
60 andreas 7319
 
7320
        i++;
32 andreas 7321
    }
7322
 
193 andreas 7323
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 7324
 
7325
    if (TError::isError() || map.empty())
351 andreas 7326
    {
7327
#if TESTMODE == 1
7328
        setAllDone();
7329
#endif
60 andreas 7330
        return;
351 andreas 7331
    }
60 andreas 7332
 
7333
    vector<Button::TButton *> buttons = collectButtons(map);
7334
 
83 andreas 7335
    if (buttons.size() > 0)
60 andreas 7336
    {
83 andreas 7337
        vector<Button::TButton *>::iterator mapIter;
7338
 
7339
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
7340
        {
7341
            Button::TButton *bt = *mapIter;
7342
            bt->setFeedback(type);
351 andreas 7343
#if TESTMODE == 1
7344
            if (_gTestMode)
7345
                _gTestMode->setResult(intToString(bt->getFeedback()));
7346
#endif
83 andreas 7347
        }
60 andreas 7348
    }
335 andreas 7349
#if TESTMODE == 1
7350
    setDone();
7351
#endif
32 andreas 7352
}
7353
 
224 andreas 7354
/*
7355
 * Set the input mask for the specified address.
7356
 */
7357
void TPageManager::doBIM(int port, vector<int>& channels, vector<std::string>& pars)
7358
{
7359
    DECL_TRACER("TPageManager::doBIM(int port, vector<int>& channels, vector<std::string>& pars)");
7360
 
7361
    if (pars.size() < 1)
7362
    {
7363
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7364
#if TESTMODE == 1
7365
        setAllDone();
7366
#endif
224 andreas 7367
        return;
7368
    }
7369
 
7370
    TError::clear();
7371
    string mask = pars[0];
7372
    vector<TMap::MAP_T> map = findButtons(port, channels);
7373
 
7374
    if (TError::isError() || map.empty())
351 andreas 7375
    {
7376
#if TESTMODE == 1
7377
        setAllDone();
7378
#endif
224 andreas 7379
        return;
351 andreas 7380
    }
224 andreas 7381
 
7382
    vector<Button::TButton *> buttons = collectButtons(map);
7383
 
7384
    if (buttons.size() > 0)
7385
    {
7386
        vector<Button::TButton *>::iterator mapIter;
7387
 
7388
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
7389
        {
7390
            Button::TButton *bt = *mapIter;
7391
            bt->setInputMask(mask);
351 andreas 7392
#if TESTMODE == 1
7393
            if (_gTestMode)
7394
                _gTestMode->setResult(bt->getInputMask());
7395
#endif
224 andreas 7396
        }
7397
    }
351 andreas 7398
#if TESTMODE == 1
7399
    setDone();
7400
#endif
224 andreas 7401
}
7402
 
351 andreas 7403
/**
7404
 * @brief Button copy command.
7405
 * Copy attributes of the source button to all the
7406
 * destination buttons. Note that the source is a single button state. Each
7407
 * state must be copied as a separate command. The <codes> section represents
7408
 * what attributes will be copied. All codes are 2 char pairs that can be
7409
 * separated by comma, space, percent or just ran together.
7410
 */
106 andreas 7411
void TPageManager::doBMC(int port, vector<int>& channels, vector<std::string>& pars)
7412
{
7413
    DECL_TRACER("TPageManager::doBMC(int port, vector<int>& channels, vector<std::string>& pars)");
7414
 
7415
    if (pars.size() < 5)
7416
    {
7417
        MSG_ERROR("Expecting 5 parameters but got " << pars.size() << ". Ignoring command.");
351 andreas 7418
#if TESTMODE == 1
7419
        setAllDone();
7420
#endif
106 andreas 7421
        return;
7422
    }
7423
 
7424
    TError::clear();
7425
    int btState = atoi(pars[0].c_str());
7426
    int src_port = atoi(pars[1].c_str());
7427
    int src_addr = atoi(pars[2].c_str());
7428
    int src_state = atoi(pars[3].c_str());
7429
    string src_codes = pars[4];
7430
    vector<int> src_channel;
7431
    src_channel.push_back(src_addr);
7432
 
193 andreas 7433
    vector<TMap::MAP_T> src_map = findButtons(src_port, src_channel);
106 andreas 7434
 
7435
    if (src_map.size() == 0)
7436
    {
7437
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " does not exist!");
351 andreas 7438
#if TESTMODE == 1
7439
        setAllDone();
7440
#endif
106 andreas 7441
        return;
7442
    }
7443
 
7444
    vector<Button::TButton *>src_buttons = collectButtons(src_map);
7445
 
7446
    if (src_buttons.size() == 0)
7447
    {
7448
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " does not exist!");
351 andreas 7449
#if TESTMODE == 1
7450
        setAllDone();
7451
#endif
106 andreas 7452
        return;
7453
    }
7454
 
7455
    if (src_buttons[0]->getNumberInstances() < src_state)
7456
    {
7457
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " has less then " << src_state << " elements.");
351 andreas 7458
#if TESTMODE == 1
7459
        setAllDone();
7460
#endif
106 andreas 7461
        return;
7462
    }
7463
 
7464
    if (src_state < 1)
7465
    {
7466
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " has invalid source state " << src_state << ".");
351 andreas 7467
#if TESTMODE == 1
7468
        setAllDone();
7469
#endif
106 andreas 7470
        return;
7471
    }
7472
 
7473
    src_state--;
7474
 
7475
    if (btState > 0)
7476
        btState--;
7477
 
193 andreas 7478
    vector<TMap::MAP_T> map = findButtons(port, channels);
106 andreas 7479
    vector<Button::TButton *> buttons = collectButtons(map);
7480
    //                        0     1     2     3     4     5     6     7
7481
    vector<string>codes = { "BM", "BR", "CB", "CF", "CT", "EC", "EF", "FT",
7482
                            "IC", "JB", "JI", "JT", "LN", "OP", "SO", "TX", // 8 - 15
7483
                            "VI", "WW" };   // 16, 17
7484
 
7485
    for (size_t ibuttons = 0; ibuttons < buttons.size(); ibuttons++)
7486
    {
7487
        vector<string>::iterator iter;
7488
        int idx = 0;
7489
 
7490
        for (iter = codes.begin(); iter != codes.end(); ++iter)
7491
        {
7492
            if (src_codes.find(*iter) != string::npos)
7493
            {
7494
                int j, x, y;
7495
 
7496
                switch(idx)
7497
                {
7498
                    case 0: buttons[ibuttons]->setBitmap(src_buttons[0]->getBitmapName(src_state), btState); break;
7499
                    case 1: buttons[ibuttons]->setBorderStyle(src_buttons[0]->getBorderStyle(src_state), btState); break;
7500
                    case 2: buttons[ibuttons]->setBorderColor(src_buttons[0]->getBorderColor(src_state), btState); break;
7501
                    case 3: buttons[ibuttons]->setFillColor(src_buttons[0]->getFillColor(src_state), btState); break;
7502
                    case 4: buttons[ibuttons]->setTextColor(src_buttons[0]->getTextColor(src_state), btState); break;
7503
                    case 5: buttons[ibuttons]->setTextEffectColor(src_buttons[0]->getTextEffectColor(src_state), btState); break;
7504
                    case 6: buttons[ibuttons]->setTextEffect(src_buttons[0]->getTextEffect(src_state), btState); break;
7505
                    case 7: buttons[ibuttons]->setFontIndex(src_buttons[0]->getFontIndex(src_state), btState); break;
110 andreas 7506
                    case 8: buttons[ibuttons]->setIcon(src_buttons[0]->getIconIndex(src_state), btState); break;
106 andreas 7507
 
7508
                    case 9:
7509
                        j = src_buttons[0]->getBitmapJustification(&x, &y, src_state);
7510
                        buttons[ibuttons]->setBitmapJustification(j, x, y, btState);
7511
                    break;
7512
 
7513
                    case 10:
7514
                        j = src_buttons[0]->getIconJustification(&x, &y, src_state);
7515
                        buttons[ibuttons]->setIconJustification(j, x, y, btState);
7516
                    break;
7517
 
7518
                    case 11:
7519
                        j = src_buttons[0]->getTextJustification(&x, &y, src_state);
7520
                        buttons[ibuttons]->setTextJustification(j, x, y, btState);
7521
                    break;
7522
 
7523
                    case 12: MSG_INFO("\"Lines of video removed\" not supported!"); break;
7524
                    case 13: buttons[ibuttons]->setOpacity(src_buttons[0]->getOpacity(src_state), btState); break;
7525
                    case 14: buttons[ibuttons]->setSound(src_buttons[0]->getSound(src_state), btState); break;
7526
                    case 15: buttons[ibuttons]->setText(src_buttons [0]->getText(src_state), btState); break;
7527
                    case 16: MSG_INFO("\"Video slot ID\" not supported!"); break;
7528
                    case 17: buttons[ibuttons]->setTextWordWrap(src_buttons[0]->getTextWordWrap(src_state), btState); break;
7529
                }
7530
            }
7531
 
7532
            idx++;
7533
        }
7534
    }
7535
}
7536
 
149 andreas 7537
void TPageManager::doBMF (int port, vector<int>& channels, vector<string>& pars)
7538
{
7539
    DECL_TRACER("TPageManager::doBMF (int port, vector<int>& channels, vector<string>& pars)");
7540
 
7541
    if (pars.size() < 2)
332 andreas 7542
    {
7543
        MSG_ERROR("Less then 2 parameters!");
7544
#if TESTMODE == 1
334 andreas 7545
        setAllDone();
332 andreas 7546
#endif
149 andreas 7547
        return;
332 andreas 7548
    }
149 andreas 7549
 
7550
    TError::clear();
7551
    int btState = atoi(pars[0].c_str()) - 1;
150 andreas 7552
    string commands;
149 andreas 7553
 
150 andreas 7554
    for (size_t i = 1; i < pars.size(); ++i)
7555
    {
7556
        if (i > 1)
7557
            commands += ",";
7558
 
7559
        commands += pars[i];
7560
    }
7561
 
193 andreas 7562
    vector<TMap::MAP_T> map = findButtons(port, channels);
149 andreas 7563
 
7564
    if (TError::isError() || map.empty())
332 andreas 7565
    {
7566
#if TESTMODE == 1
334 andreas 7567
        setAllDone();
332 andreas 7568
#endif
149 andreas 7569
        return;
332 andreas 7570
    }
149 andreas 7571
 
7572
    // Start of parsing the command line
162 andreas 7573
    // We splitt the command line into parts by searching for a percent (%) sign.
149 andreas 7574
    vector<string> parts = StrSplit(commands, "%");
7575
 
162 andreas 7576
    if (parts.empty())
332 andreas 7577
        parts.push_back(commands);
334 andreas 7578
 
149 andreas 7579
    // Search for all buttons who need to be updated
7580
    vector<Button::TButton *> buttons = collectButtons(map);
7581
 
7582
    if (buttons.size() > 0)
7583
    {
7584
        vector<Button::TButton *>::iterator mapIter;
7585
 
7586
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
7587
        {
7588
            Button::TButton *bt = *mapIter;
162 andreas 7589
 
7590
            if (!bt)
7591
            {
7592
                MSG_WARNING("Command ^BMF found an invalid pointer to a button!")
7593
                continue;
7594
            }
7595
 
149 andreas 7596
            // Iterate through commands and apply them to button
7597
            vector<string>::iterator iter;
7598
 
7599
            for (iter = parts.begin(); iter != parts.end(); ++iter)
7600
            {
7601
                char cmd = iter->at(0);
7602
                char cmd2;
7603
                string content;
7604
 
7605
                switch(cmd)
7606
                {
7607
                    case 'B':   // Border style
361 andreas 7608
                        if (iter->at(1) == ',')
7609
                            content = iter->substr(2);
7610
                        else
7611
                            content = iter->substr(1);
332 andreas 7612
 
7613
                        if (!content.empty() && isdigit(content[0]))
334 andreas 7614
                            bt->setBorderStyle(atoi(content.c_str()), btState);
332 andreas 7615
                        else
7616
                            bt->setBorderStyle(content, btState);
7617
#if TESTMODE == 1
7618
                        if (_gTestMode)
7619
                            _gTestMode->setResult(bt->getBorderStyle(btState < 0 ? 0 : btState));
7620
#endif
149 andreas 7621
                    break;
7622
 
7623
                    case 'C':   // Colors
7624
                        cmd2 = iter->at(1);
7625
                        content = iter->substr(2);
7626
 
7627
                        switch(cmd2)
7628
                        {
7629
                            case 'B':   // Border color
7630
                                bt->setBorderColor(content, btState);
332 andreas 7631
#if TESTMODE == 1
7632
                                if (_gTestMode)
7633
                                    _gTestMode->setResult(bt->getBorderColor(btState < 0 ? 0 : btState));
7634
#endif
149 andreas 7635
                            break;
7636
 
7637
                            case 'F':   // Fill color
7638
                                bt->setFillColor(content, btState);
332 andreas 7639
#if TESTMODE == 1
7640
                                if (_gTestMode)
7641
                                    _gTestMode->setResult(bt->getFillColor(btState < 0 ? 0 : btState));
7642
#endif
149 andreas 7643
                            break;
7644
 
7645
                            case 'T':   // Text color
7646
                                bt->setTextColor(content, btState);
332 andreas 7647
#if TESTMODE == 1
7648
                                if (_gTestMode)
7649
                                    _gTestMode->setResult(bt->getTextColor(btState < 0 ? 0 : btState));
7650
#endif
149 andreas 7651
                            break;
7652
                        }
7653
                    break;
7654
 
150 andreas 7655
                    case 'D':   // Draw order
7656
                        cmd2 = iter->at(1);
7657
                        content = iter->substr(2);
7658
 
7659
                        if (cmd2 == 'O')
332 andreas 7660
                        {
150 andreas 7661
                            bt->setDrawOrder(content, btState);
332 andreas 7662
#if TESTMODE == 1
7663
                            if (_gTestMode)
7664
                                _gTestMode->setResult(bt->getDrawOrder(btState < 0 ? 0 : btState));
7665
#endif
7666
                        }
150 andreas 7667
                    break;
7668
 
149 andreas 7669
                    case 'E':   // Text effect
7670
                        cmd2 = iter->at(1);
7671
                        content = iter->substr(2);
7672
 
7673
                        switch(cmd2)
7674
                        {
7675
                            case 'C':   // Text effect color
7676
                                bt->setTextEffectColor(content, btState);
332 andreas 7677
#if TESTMODE == 1
7678
                                if (_gTestMode)
7679
                                    _gTestMode->setResult(bt->getTextEffectColor(btState < 0 ? 0 : btState));
7680
#endif
149 andreas 7681
                            break;
7682
 
7683
                            case 'F':   // Text effect name
7684
                                bt->setTextEffectName(content, btState);
332 andreas 7685
#if TESTMODE == 1
7686
                                if (_gTestMode)
7687
                                    _gTestMode->setResult(bt->getTextEffectName(btState < 0 ? 0 : btState));
7688
#endif
149 andreas 7689
                            break;
7690
 
7691
                            case 'N':   // Enable/disable button
7692
                                bt->setEnable((content[0] == '1' ? true : false));
332 andreas 7693
#if TESTMODE == 1
7694
                                if (_gTestMode)
334 andreas 7695
                                {
332 andreas 7696
                                    _gTestMode->setResult(bt->isEnabled() ? "TRUE" : "FALSE");
334 andreas 7697
                                    __success = true;
7698
                                    setScreenDone();
7699
                                }
332 andreas 7700
#endif
149 andreas 7701
                            break;
7702
                        }
7703
                    break;
7704
 
7705
                    case 'F':   // Set font file name
361 andreas 7706
                        if (iter->at(1) == ',')
7707
                            content = iter->substr(2);
7708
                        else
7709
                            content = iter->substr(1);
150 andreas 7710
 
7711
                        if (!isdigit(content[0]))
334 andreas 7712
                            bt->setFontName(content, btState);
150 andreas 7713
                        else
7714
                            bt->setFontIndex(atoi(content.c_str()), btState);
334 andreas 7715
#if TESTMODE == 1
7716
                        if (_gTestMode)
7717
                            _gTestMode->setResult(intToString(bt->getFontIndex(btState < 0 ? 0 : btState)));
7718
#endif
149 andreas 7719
                    break;
7720
 
7721
                    case 'G':   // Bargraphs
7722
                        cmd2 = iter->at(1);
7723
                        content = iter->substr(2);
7724
 
7725
                        switch(cmd2)
7726
                        {
7727
                            case 'C':   // Bargraph slider color
7728
                                bt->setBargraphSliderColor(content);
7729
                            break;
7730
 
7731
                            case 'D':   // Ramp down time
387 andreas 7732
                                bt->setBargraphRampDownTime(atoi(content.c_str()));
149 andreas 7733
                            break;
7734
 
7735
                            case 'G':   // Drag increment
387 andreas 7736
                                bt->setBargraphDragIncrement(atoi(content.c_str()));
149 andreas 7737
                            break;
7738
 
7739
                            case 'H':   // Upper limit
7740
                                bt->setBargraphUpperLimit(atoi(content.c_str()));
7741
                            break;
7742
 
7743
                            case 'I':   // Invert/noninvert
387 andreas 7744
                                if (bt->getButtonType() == BARGRAPH || bt->getButtonType() == MULTISTATE_BARGRAPH)
7745
                                    bt->setBargraphInvert(atoi(content.c_str()) > 0 ? true : false);
149 andreas 7746
                            break;
7747
 
7748
                            case 'L':   // Lower limit
7749
                                bt->setBargraphLowerLimit(atoi(content.c_str()));
7750
                            break;
7751
 
7752
                            case 'N':   // Slider name
361 andreas 7753
                                bt->setBargraphSliderName(content);
149 andreas 7754
                            break;
7755
 
7756
                            case 'R':   // Repeat interval
7757
                                // FIXME: Add function to set repeat interval
7758
                            break;
7759
 
7760
                            case 'U':   // Ramp up time
387 andreas 7761
                                bt->setBargraphRampUpTime(atoi(content.c_str()));
149 andreas 7762
                            break;
7763
 
7764
                            case 'V':   // Bargraph value
387 andreas 7765
                                bt->setBargraphLevel(atoi(content.c_str()));
149 andreas 7766
                            break;
7767
                        }
7768
                    break;
7769
 
152 andreas 7770
                    case 'I':   // Set the icon
7771
                        content = iter->substr(1);
7772
                        bt->setIcon(atoi(content.c_str()), btState);
332 andreas 7773
#if TESTMODE == 1
7774
                        if (_gTestMode)
7775
                            _gTestMode->setResult(intToString(bt->getIconIndex()));
7776
#endif
152 andreas 7777
                    break;
7778
 
149 andreas 7779
                    case 'J':   // Set text justification
150 andreas 7780
                        cmd2 = iter->at(1);
7781
 
361 andreas 7782
                        if (cmd2 == ',')
150 andreas 7783
                        {
7784
                            content = iter->substr(1);
152 andreas 7785
                            int just = atoi(content.c_str());
7786
                            int x = 0, y = 0;
7787
 
7788
                            if (just == 0)
7789
                            {
7790
                                vector<string> coords = StrSplit(content, ",");
7791
 
7792
                                if (coords.size() >= 3)
7793
                                {
7794
                                    x = atoi(coords[1].c_str());
7795
                                    y = atoi(coords[2].c_str());
7796
                                }
7797
                            }
7798
 
7799
                            bt->setTextJustification(atoi(content.c_str()), x, y, btState);
334 andreas 7800
#if TESTMODE == 1
7801
                            if (_gTestMode)
7802
                            {
7803
                                just = bt->getTextJustification(&x, &y, btState < 0 ? 0 : btState);
7804
                                string s = intToString(just) + "," + intToString(x) + "," + intToString(y);
7805
                                _gTestMode->setResult(s);
7806
                            }
7807
#endif
150 andreas 7808
                        }
361 andreas 7809
                        else if (cmd2 == 'T' || cmd2 == 'B' || cmd2 == 'I')
150 andreas 7810
                        {
7811
                            content = iter->substr(2);
152 andreas 7812
                            int x = 0, y = 0;
7813
                            int just = atoi(content.c_str());
150 andreas 7814
 
152 andreas 7815
                            if (just == 0)
7816
                            {
7817
                                vector<string> coords = StrSplit(content, ",");
7818
 
7819
                                if (coords.size() >= 3)
7820
                                {
7821
                                    x = atoi(coords[1].c_str());
7822
                                    y = atoi(coords[2].c_str());
7823
                                }
7824
                            }
7825
 
150 andreas 7826
                            switch(cmd2)
7827
                            {
7828
                                case 'B':   // Alignment of bitmap
152 andreas 7829
                                    bt->setBitmapJustification(atoi(content.c_str()), x, y, btState);
334 andreas 7830
#if TESTMODE == 1
7831
                                    just = bt->getBitmapJustification(&x, &y, btState < 0 ? 0 : btState);
7832
#endif
150 andreas 7833
                                break;
7834
 
7835
                                case 'I':   // Alignment of icon
152 andreas 7836
                                    bt->setIconJustification(atoi(content.c_str()), x, y, btState);
334 andreas 7837
#if TESTMODE == 1
7838
                                    just = bt->getIconJustification(&x, &y, btState < 0 ? 0 : btState);
7839
#endif
150 andreas 7840
                                break;
7841
 
7842
                                case 'T':   // Alignment of text
152 andreas 7843
                                    bt->setTextJustification(atoi(content.c_str()), x, y, btState);
334 andreas 7844
#if TESTMODE == 1
7845
                                    just = bt->getTextJustification(&x, &y, btState < 0 ? 0 : btState);
7846
#endif
150 andreas 7847
                                break;
7848
                            }
334 andreas 7849
#if TESTMODE == 1
7850
                            if (_gTestMode)
7851
                            {
7852
                                string s = intToString(just) + "," + intToString(x) + "," + intToString(y);
7853
                                _gTestMode->setResult(s);
7854
                            }
7855
#endif
150 andreas 7856
                        }
7857
                    break;
7858
 
7859
                    case 'M':   // Text area
7860
                        cmd2 = iter->at(1);
7861
                        content = iter->substr(2);
7862
 
7863
                        switch(cmd2)
7864
                        {
152 andreas 7865
                            case 'I':   // Set mask image
7866
                                // FIXME: Add code for image mask
7867
                            break;
7868
 
150 andreas 7869
                            case 'K':   // Input mask of text area
7870
                                // FIXME: Add input mask
7871
                            break;
7872
 
7873
                            case 'L':   // Maximum length of text area
7874
                                // FIXME: Add code to set maximum length
7875
                            break;
7876
                        }
7877
                    break;
7878
 
7879
                    case 'O':   // Set feedback typ, opacity
7880
                        cmd2 = iter->at(1);
7881
 
7882
                        switch(cmd2)
7883
                        {
7884
                            case 'P':   // Set opacity
7885
                                bt->setOpacity(atoi(iter->substr(2).c_str()), btState);
7886
                            break;
7887
 
7888
                            case 'T':   // Set feedback type
7889
                                content = iter->substr(2);
7890
                                content = toUpper(content);
7891
 
7892
                                if (content == "NONE")
7893
                                    bt->setFeedback(Button::FB_NONE);
7894
                                else if (content == "CHANNEL")
7895
                                    bt->setFeedback(Button::FB_CHANNEL);
7896
                                else if (content == "INVERT")
7897
                                    bt->setFeedback(Button::FB_INV_CHANNEL);
7898
                                else if (content == "ON")
7899
                                    bt->setFeedback(Button::FB_ALWAYS_ON);
7900
                                else if (content == "MOMENTARY")
7901
                                    bt->setFeedback(Button::FB_MOMENTARY);
7902
                                else if (content == "BLINK")
7903
                                    bt->setFeedback(Button::FB_BLINK);
7904
                                else
7905
                                {
7906
                                    MSG_WARNING("Unknown feedback type " << content);
7907
                                }
335 andreas 7908
#if TESTMODE == 1
7909
                                if (_gTestMode)
7910
                                    _gTestMode->setResult(intToString(bt->getFeedback()));
7911
#endif
150 andreas 7912
                            break;
7913
 
7914
                            default:
7915
                                content = iter->substr(1);
7916
                                // FIXME: Add code to set the feedback type
7917
                        }
7918
                    break;
7919
 
152 andreas 7920
                    case 'P':   // Set picture/bitmap file name
7921
                        content = iter->substr(1);
165 andreas 7922
 
7923
                        if (content.find(".") == string::npos)  // If the image has no extension ...
7924
                        {                                       // we must find the image in the map
7925
                            string iname = findImage(content);
7926
 
7927
                            if (!iname.empty())
7928
                                content = iname;
7929
                        }
7930
 
152 andreas 7931
                        bt->setBitmap(content, btState);
7932
                    break;
7933
 
7934
                    case 'R':   // Set rectangle
7935
                    {
7936
                        content = iter->substr(1);
7937
                        vector<string> corners = StrSplit(content, ",");
7938
 
7939
                        if (corners.size() > 0)
7940
                        {
7941
                            vector<string>::iterator itcorn;
7942
                            int pos = 0;
7943
                            int left, top, right, bottom;
7944
                            left = top = right = bottom = 0;
7945
 
7946
                            for (itcorn = corners.begin(); itcorn != corners.end(); ++itcorn)
7947
                            {
7948
                                switch(pos)
7949
                                {
7950
                                    case 0: left   = atoi(itcorn->c_str()); break;
7951
                                    case 1: top    = atoi(itcorn->c_str()); break;
7952
                                    case 2: right  = atoi(itcorn->c_str()); break;
7953
                                    case 3: bottom = atoi(itcorn->c_str()); break;
7954
                                }
7955
 
7956
                                pos++;
7957
                            }
7958
 
7959
                            if (pos >= 4)
334 andreas 7960
                            {
152 andreas 7961
                                bt->setRectangle(left, top, right, bottom);
334 andreas 7962
                                bt->refresh();
7963
                            }
152 andreas 7964
                        }
334 andreas 7965
#if TESTMODE == 1
7966
                        if (_gTestMode)
7967
                        {
7968
                            int left, top, width, height;
7969
                            bt->getRectangle(&left, &top, &height, &width);
7970
                            string res(intToString(left) + "," + intToString(top) + "," + intToString(width) + "," + intToString(height));
7971
                            _gTestMode->setResult(res);
7972
                        }
7973
#endif
152 andreas 7974
                    }
7975
                    break;
7976
 
150 andreas 7977
                    case 'S':   // show/hide, style, sound
7978
                        cmd2 = iter->at(1);
7979
                        content = iter->substr(2);
7980
 
7981
                        switch(cmd2)
7982
                        {
7983
                            case 'F':   // Set focus of text area button
7984
                                // FIXME: Add code to set the focus of text area button
7985
                            break;
7986
 
7987
                            case 'M':   // Submit text
169 andreas 7988
                                if (content.find("|"))  // To be replaced by LF (0x0a)?
7989
                                {
7990
                                    size_t pos = 0;
7991
 
7992
                                    while ((pos = content.find("|")) != string::npos)
7993
                                        content = content.replace(pos, 1, "\n");
7994
                                }
7995
 
150 andreas 7996
                                bt->setText(content, btState);
7997
                            break;
7998
 
7999
                            case 'O':   // Sound
8000
                                bt->setSound(content, btState);
335 andreas 8001
#if TESTMODE == 1
8002
                                if (_gTestMode)
8003
                                    _gTestMode->setResult(bt->getSound(btState < 0 ? 0 : btState));
8004
#endif
150 andreas 8005
                            break;
8006
 
8007
                            case 'T':   // Button style
8008
                                // FIXME: Add code to set the button style
8009
                            break;
8010
 
8011
                            case 'W':   // Show / hide button
8012
                                if (content[0] == '0')
334 andreas 8013
                                    bt->hide(true);
150 andreas 8014
                                else
8015
                                    bt->show();
334 andreas 8016
#if TESTMODE == 1
8017
                                if (_gTestMode)
8018
                                    _gTestMode->setResult(bt->isVisible() ? "TRUE" : "FALSE");
8019
#endif
150 andreas 8020
                            break;
8021
                        }
8022
                    break;
8023
 
152 andreas 8024
                    case 'T':   // Set text
8025
                        content = iter->substr(1);
169 andreas 8026
 
8027
                        if (content.find("|"))  // To be replaced by LF (0x0a)?
8028
                        {
8029
                            size_t pos = 0;
8030
 
8031
                            while ((pos = content.find("|")) != string::npos)
8032
                                content = content.replace(pos, 1, "\n");
8033
                        }
8034
 
152 andreas 8035
                        bt->setText(content, btState);
334 andreas 8036
#if TESTMODE == 1
8037
                        if (_gTestMode)
8038
                            _gTestMode->setResult(bt->getText(btState < 0 ? 0 : btState));
8039
#endif
152 andreas 8040
                    break;
8041
 
150 andreas 8042
                    case 'U':   // Set the unicode text
8043
                        if (iter->at(1) == 'N')
8044
                        {
8045
                            content = iter->substr(2);
152 andreas 8046
                            string byte, text;
8047
                            size_t pos = 0;
8048
 
8049
                            while (pos < content.length())
8050
                            {
8051
                                byte = content.substr(pos, 2);
8052
                                char ch = (char)strtol(byte.c_str(), NULL, 16);
8053
                                text += ch;
8054
                                pos += 2;
8055
                            }
8056
 
169 andreas 8057
                            if (text.find("|"))  // To be replaced by LF (0x0a)?
8058
                            {
8059
                                size_t pos = 0;
8060
 
8061
                                while ((pos = text.find("|")) != string::npos)
8062
                                    text = text.replace(pos, 1, "\n");
8063
                            }
8064
 
152 andreas 8065
                            bt->setText(text, btState);
150 andreas 8066
                        }
8067
                    break;
8068
 
8069
                    case 'V':   // Video on / off
8070
                        cmd2 = iter->at(1);
8071
                        // Controlling a computer remotely is not supported.
8072
                        if (cmd2 != 'L' && cmd2 != 'N' && cmd2 != 'P')
8073
                        {
8074
                            content = iter->substr(2);
8075
                            // FIXME: Add code to switch video on or off
8076
                        }
8077
                    break;
8078
 
8079
                    case 'W':   // Word wrap
152 andreas 8080
                        if (iter->at(1) == 'W')
8081
                        {
8082
                            content = iter->substr(2);
8083
                            bt->setTextWordWrap(content[0] == '1' ? true : false, btState);
8084
                        }
149 andreas 8085
                    break;
8086
                }
8087
            }
8088
        }
8089
    }
332 andreas 8090
#if TESTMODE == 1
334 andreas 8091
    setDone();
332 andreas 8092
#endif
149 andreas 8093
}
8094
 
14 andreas 8095
/**
110 andreas 8096
 * Set the maximum length of the text area button. If this value is set to
8097
 * zero (0), the text area has no max length. The maximum length available is
8098
 * 2000. This is only for a Text area input button and not for a Text area input
8099
 * masking button.
8100
 */
8101
void TPageManager::doBML(int port, vector<int>& channels, vector<string>& pars)
8102
{
8103
    DECL_TRACER("TPageManager::doBML(int port, vector<int>& channels, vector<string>& pars)");
8104
 
8105
    if (pars.size() < 1)
8106
    {
8107
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
8108
        return;
8109
    }
8110
 
8111
    TError::clear();
8112
    int maxLen = atoi(pars[0].c_str());
8113
 
8114
    if (maxLen < 0 || maxLen > 2000)
8115
    {
8116
        MSG_WARNING("Got illegal length of text area! [" << maxLen << "]");
8117
        return;
8118
    }
8119
 
193 andreas 8120
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 8121
 
8122
    if (TError::isError() || map.empty())
8123
        return;
8124
 
8125
    vector<Button::TButton *> buttons = collectButtons(map);
8126
 
8127
    if (buttons.size() > 0)
8128
    {
8129
        vector<Button::TButton *>::iterator mapIter;
8130
 
8131
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8132
        {
8133
            Button::TButton *bt = *mapIter;
8134
            bt->setTextMaxChars(maxLen);
8135
        }
8136
    }
8137
}
8138
 
8139
/**
60 andreas 8140
 * Assign a picture to those buttons with a defined address range.
8141
 */
8142
void TPageManager::doBMP(int port, vector<int>& channels, vector<string>& pars)
8143
{
8144
    DECL_TRACER("TPageManager::doBMP(int port, vector<int>& channels, vector<string>& pars)");
8145
 
8146
    if (pars.size() < 2)
8147
    {
8148
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
8149
        return;
8150
    }
8151
 
8152
    TError::clear();
8153
    int btState = atoi(pars[0].c_str());
8154
    string bitmap = pars[1];
104 andreas 8155
    // If this is a G5 command, we may have up to 2 additional parameters.
8156
    int slot = -1, justify = -1, jx = 0, jy = 0;
60 andreas 8157
 
104 andreas 8158
    if (pars.size() > 2)
8159
    {
8160
        slot = atoi(pars[2].c_str());
8161
 
8162
        if (pars.size() >= 4)
8163
        {
8164
            justify = atoi(pars[4].c_str());
8165
 
8166
            if (justify == 0)
8167
            {
8168
                if (pars.size() >= 5)
8169
                    jx = atoi(pars[5].c_str());
8170
 
8171
                if (pars.size() >= 6)
8172
                    jy = atoi(pars[6].c_str());
8173
            }
8174
        }
8175
    }
8176
 
193 andreas 8177
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 8178
 
8179
    if (TError::isError() || map.empty())
8180
        return;
8181
 
8182
    vector<Button::TButton *> buttons = collectButtons(map);
8183
 
83 andreas 8184
    if (buttons.size() > 0)
60 andreas 8185
    {
83 andreas 8186
        vector<Button::TButton *>::iterator mapIter;
60 andreas 8187
 
83 andreas 8188
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 8189
        {
83 andreas 8190
            Button::TButton *bt = *mapIter;
252 andreas 8191
//            setButtonCallbacks(bt);
60 andreas 8192
 
83 andreas 8193
            if (btState == 0)       // All instances?
8194
            {
8195
                int bst = bt->getNumberInstances();
96 andreas 8196
                MSG_DEBUG("Setting bitmap " << bitmap << " on all " << bst << " instances...");
83 andreas 8197
 
8198
                for (int i = 0; i < bst; i++)
104 andreas 8199
                {
8200
                    if (justify >= 0)
8201
                    {
8202
                        if (slot == 2)
8203
                            bt->setIconJustification(justify, jx, jy, i);
8204
                        else
106 andreas 8205
                            bt->setBitmapJustification(justify, jx, jy, i);
104 andreas 8206
                    }
8207
 
8208
                    if (slot >= 0)
8209
                    {
8210
                        switch(slot)
8211
                        {
8212
                            case 0: bt->setCameleon(bitmap, i); break;
8213
                            case 2: bt->setIcon(bitmap, i); break;  // On G4 we have no bitmap layer. Therefor we use layer 2 as icon layer.
8214
                            default:
8215
                                bt->setBitmap(bitmap, i);
8216
                        }
8217
                    }
8218
                    else
8219
                        bt->setBitmap(bitmap, i);
8220
                }
83 andreas 8221
            }
8222
            else
104 andreas 8223
            {
8224
                if (justify >= 0)
8225
                {
8226
                    if (slot == 2)
8227
                        bt->setIconJustification(justify, jx, jy, btState);
8228
                    else
106 andreas 8229
                        bt->setBitmapJustification(justify, jx, jy, btState);
104 andreas 8230
                }
8231
 
8232
                if (slot >= 0)
8233
                {
8234
                    switch(slot)
8235
                    {
8236
                        case 0: bt->setCameleon(bitmap, btState); break;
8237
                        case 2: bt->setIcon(bitmap, btState); break;      // On G4 we have no bitmap layer. Therefor we use layer 2 as icon layer.
8238
                        default:
8239
                            bt->setBitmap(bitmap, btState);
8240
                    }
8241
                }
8242
                else
8243
                    bt->setBitmap(bitmap, btState);
8244
            }
60 andreas 8245
        }
8246
    }
8247
}
8248
 
82 andreas 8249
void TPageManager::getBMP(int port, vector<int> &channels, vector<string> &pars)
8250
{
8251
    DECL_TRACER("TPageManager::getBMP(int port, vector<int> &channels, vector<string> &pars)");
8252
 
8253
    if (pars.size() < 1)
8254
    {
8255
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
8256
        return;
8257
    }
8258
 
8259
    TError::clear();
8260
    int btState = atoi(pars[0].c_str());
8261
    string bmp;
8262
 
193 andreas 8263
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 8264
 
8265
    if (TError::isError() || map.empty())
8266
        return;
8267
 
8268
    vector<Button::TButton *> buttons = collectButtons(map);
8269
 
83 andreas 8270
    if (buttons.size() > 0)
82 andreas 8271
    {
110 andreas 8272
        Button::TButton *bt = buttons[0];
82 andreas 8273
 
110 andreas 8274
        if (btState == 0)       // All instances?
82 andreas 8275
        {
110 andreas 8276
            int bst = bt->getNumberInstances();
82 andreas 8277
 
110 andreas 8278
            for (int i = 0; i < bst; i++)
82 andreas 8279
            {
110 andreas 8280
                bmp = bt->getBitmapName(i);
82 andreas 8281
 
110 andreas 8282
                if (bmp.empty())
8283
                    continue;
82 andreas 8284
 
300 andreas 8285
                sendCustomEvent(i + 1, (int)bmp.length(), 0, bmp, 1002, bt->getChannelPort(), bt->getChannelNumber());
83 andreas 8286
            }
82 andreas 8287
        }
110 andreas 8288
        else
8289
        {
8290
            bmp = bt->getTextColor(btState-1);
300 andreas 8291
            sendCustomEvent(btState, (int)bmp.length(), 0, bmp, 1002, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 8292
        }
82 andreas 8293
    }
8294
}
8295
 
60 andreas 8296
/**
16 andreas 8297
 * Set the button opacity. The button opacity can be specified as a decimal
8298
 * between 0 - 255, where zero (0) is invisible and 255 is opaque, or as a
8299
 * HEX code, as used in the color commands by preceding the HEX code with
8300
 * the # sign. In this case, #00 becomes invisible and #FF becomes opaque.
8301
 * If the opacity is set to zero (0), this does not make the button inactive,
8302
 * only invisible.
8303
 */
8304
void TPageManager::doBOP(int port, vector<int>& channels, vector<string>& pars)
8305
{
8306
    DECL_TRACER("TPageManager::doBOP(int port, vector<int>& channels, vector<string>& pars)");
8307
 
8308
    if (pars.size() < 2)
8309
    {
8310
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
335 andreas 8311
#if TESTMODE == 1
8312
        setAllDone();
8313
#endif
16 andreas 8314
        return;
8315
    }
8316
 
8317
    TError::clear();
335 andreas 8318
    int btState = atoi(pars[0].c_str()) - 1;
16 andreas 8319
    int btOpacity = 0;
8320
 
8321
    if (pars[1].at(0) == '#')
8322
        btOpacity = (int)strtol(pars[1].substr(1).c_str(), NULL, 16);
8323
    else
8324
        btOpacity = atoi(pars[1].c_str());
8325
 
193 andreas 8326
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8327
 
8328
    if (TError::isError() || map.empty())
335 andreas 8329
    {
8330
#if TESTMODE == 1
8331
        setAllDone();
8332
#endif
16 andreas 8333
        return;
335 andreas 8334
    }
16 andreas 8335
 
8336
    vector<Button::TButton *> buttons = collectButtons(map);
8337
 
83 andreas 8338
    if (buttons.size() > 0)
16 andreas 8339
    {
83 andreas 8340
        vector<Button::TButton *>::iterator mapIter;
16 andreas 8341
 
83 andreas 8342
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
16 andreas 8343
        {
83 andreas 8344
            Button::TButton *bt = *mapIter;
335 andreas 8345
            bt->setOpacity(btOpacity, btState);
8346
#if TESTMODE == 1
8347
            if (_gTestMode)
8348
                _gTestMode->setResult(intToString(bt->getOpacity(btState < 0 ? 0 : btState)));
342 andreas 8349
#endif
16 andreas 8350
        }
8351
    }
335 andreas 8352
#if TESTMODE == 1
8353
    setDone();
8354
#endif
16 andreas 8355
}
8356
 
106 andreas 8357
void TPageManager::getBOP(int port, vector<int>& channels, vector<string>& pars)
8358
{
8359
    DECL_TRACER("TPageManager::getBOP(int port, vector<int>& channels, vector<string>& pars)");
8360
 
8361
    if (pars.size() < 1)
8362
    {
8363
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
8364
        return;
8365
    }
8366
 
8367
    TError::clear();
8368
    int btState = atoi(pars[0].c_str());
8369
 
193 andreas 8370
    vector<TMap::MAP_T> map = findButtons(port, channels);
106 andreas 8371
 
8372
    if (TError::isError() || map.empty())
8373
        return;
8374
 
8375
    vector<Button::TButton *> buttons = collectButtons(map);
8376
 
8377
    if (buttons.size() > 0)
8378
    {
110 andreas 8379
        Button::TButton *bt = buttons[0];
106 andreas 8380
 
110 andreas 8381
        if (btState == 0)       // All instances?
106 andreas 8382
        {
110 andreas 8383
            int bst = bt->getNumberInstances();
106 andreas 8384
 
110 andreas 8385
            for (int i = 0; i < bst; i++)
106 andreas 8386
            {
110 andreas 8387
                int oo = bt->getOpacity(i);
8388
                sendCustomEvent(i + 1, oo, 0, "", 1015, bt->getChannelPort(), bt->getChannelNumber());
106 andreas 8389
            }
8390
        }
110 andreas 8391
        else
8392
        {
8393
            int oo = bt->getOpacity(btState-1);
8394
            sendCustomEvent(btState, oo, 0, "", 1015, bt->getChannelPort(), bt->getChannelNumber());
8395
        }
106 andreas 8396
    }
8397
}
8398
 
60 andreas 8399
void TPageManager::doBOR(int port, vector<int>& channels, vector<string>& pars)
8400
{
8401
    DECL_TRACER("TPageManager::doBOR(int port, vector<int>& channels, vector<string>& pars)");
8402
 
8403
    if (pars.size() < 1)
8404
    {
8405
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
335 andreas 8406
#if TESTMODE == 1
8407
        setAllDone();
8408
#endif
60 andreas 8409
        return;
8410
    }
8411
 
8412
    TError::clear();
8413
    // Numbers of styles from 0 to 41
8414
    string bor = pars[0];
8415
    string border = "None";
8416
    int ibor = -1;
336 andreas 8417
    Border::TIntBorder borders;
60 andreas 8418
 
8419
    if (bor.at(0) >= '0' && bor.at(0) <= '9')
336 andreas 8420
    {
60 andreas 8421
        ibor = atoi(bor.c_str());
8422
 
336 andreas 8423
        if (ibor >= 0 && ibor <= 41)
8424
            border = borders.getTP4BorderName(ibor);
8425
        else
60 andreas 8426
        {
336 andreas 8427
            MSG_WARNING("Invalid border style ID " << ibor);
8428
#if TESTMODE == 1
8429
            setAllDone();
8430
#endif
8431
            return;
8432
        }
60 andreas 8433
 
336 andreas 8434
        MSG_DEBUG("Id " << ibor << " is border " << border);
60 andreas 8435
    }
336 andreas 8436
    else
60 andreas 8437
    {
336 andreas 8438
        if (!borders.isTP4BorderValid(bor))
8439
        {
8440
            MSG_WARNING("Unknown border style " << bor);
335 andreas 8441
#if TESTMODE == 1
336 andreas 8442
            setAllDone();
335 andreas 8443
#endif
336 andreas 8444
            return;
8445
        }
60 andreas 8446
 
336 andreas 8447
        border = bor;
60 andreas 8448
    }
8449
 
193 andreas 8450
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 8451
 
8452
    if (TError::isError() || map.empty())
335 andreas 8453
    {
8454
#if TESTMODE == 1
8455
        setAllDone();
8456
#endif
60 andreas 8457
        return;
335 andreas 8458
    }
60 andreas 8459
 
8460
    vector<Button::TButton *> buttons = collectButtons(map);
8461
 
83 andreas 8462
    if (buttons.size() > 0)
60 andreas 8463
    {
83 andreas 8464
        vector<Button::TButton *>::iterator mapIter;
8465
 
8466
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8467
        {
8468
            Button::TButton *bt = *mapIter;
8469
            bt->setBorderStyle(border);
335 andreas 8470
#if TESTMODE == 1
8471
            if (_gTestMode)
8472
                _gTestMode->setResult(bt->getBorderStyle(0));
8473
#endif
83 andreas 8474
        }
60 andreas 8475
    }
335 andreas 8476
#if TESTMODE == 1
8477
    setDone();
8478
#endif
60 andreas 8479
}
8480
 
107 andreas 8481
void TPageManager::doBOS(int port, vector<int>& channels, vector<string>& pars)
8482
{
8483
    DECL_TRACER("TPageManager::doBOS(int port, vector<int>& channels, vector<string>& pars)");
8484
 
8485
    if (pars.size() < 2)
8486
    {
8487
        MSG_ERROR("Expecting at least 2 parameters but got " << pars.size() << "! Ignoring command.");
8488
        return;
8489
    }
8490
 
8491
    TError::clear();
8492
    int btState = atoi(pars[0].c_str());
8493
    int videoState = atoi(pars[1].c_str());
8494
 
193 andreas 8495
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 8496
 
8497
    if (TError::isError() || map.empty())
8498
        return;
8499
 
8500
    vector<Button::TButton *> buttons = collectButtons(map);
8501
 
8502
    if (buttons.size() > 0)
8503
    {
8504
        vector<Button::TButton *>::iterator mapIter;
8505
 
8506
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8507
        {
8508
            Button::TButton *bt = *mapIter;
8509
 
8510
            if (btState == 0)       // All instances?
8511
                bt->setDynamic(videoState);
8512
            else
8513
                bt->setDynamic(videoState, btState-1);
8514
        }
8515
    }
8516
}
8517
 
16 andreas 8518
/**
60 andreas 8519
 * Set the border of a button state/states.
8520
 * The border names are available through the TPDesign4 border-name drop-down
8521
 * list.
8522
 */
8523
void TPageManager::doBRD(int port, vector<int>& channels, vector<string>& pars)
8524
{
8525
    DECL_TRACER("TPageManager::doBRD(int port, vector<int>& channels, vector<string>& pars)");
8526
 
8527
    if (pars.size() < 1)
8528
    {
8529
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8530
        return;
8531
    }
8532
 
8533
    TError::clear();
8534
    int btState = atoi(pars[0].c_str());
8535
    string border = "None";
8536
 
8537
    if (pars.size() > 1)
8538
        border = pars[1];
8539
 
193 andreas 8540
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 8541
 
8542
    if (TError::isError() || map.empty())
8543
        return;
8544
 
8545
    vector<Button::TButton *> buttons = collectButtons(map);
8546
 
83 andreas 8547
    if (buttons.size() > 0)
60 andreas 8548
    {
83 andreas 8549
        vector<Button::TButton *>::iterator mapIter;
60 andreas 8550
 
83 andreas 8551
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 8552
        {
83 andreas 8553
            Button::TButton *bt = *mapIter;
252 andreas 8554
//            setButtonCallbacks(bt);
60 andreas 8555
 
83 andreas 8556
            if (btState == 0)       // All instances?
8557
            {
8558
                int bst = bt->getNumberInstances();
8559
 
8560
                for (int i = 0; i < bst; i++)
106 andreas 8561
                    bt->setBorderStyle(border, i+1);
83 andreas 8562
            }
8563
            else
106 andreas 8564
                bt->setBorderStyle(border, btState);
60 andreas 8565
        }
8566
    }
8567
}
8568
 
107 andreas 8569
void TPageManager::getBRD(int port, vector<int>& channels, vector<string>& pars)
8570
{
8571
    DECL_TRACER("TPageManager::getBRD(int port, vector<int>& channels, vector<string>& pars)");
8572
 
8573
    if (pars.size() < 1)
8574
    {
8575
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8576
        return;
8577
    }
8578
 
8579
    TError::clear();
8580
    int btState = atoi(pars[0].c_str());
8581
 
193 andreas 8582
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 8583
 
8584
    if (TError::isError() || map.empty())
8585
        return;
8586
 
8587
    vector<Button::TButton *> buttons = collectButtons(map);
8588
 
8589
    if (buttons.size() > 0)
8590
    {
110 andreas 8591
        Button::TButton *bt = buttons[0];
107 andreas 8592
 
110 andreas 8593
        if (btState == 0)       // All instances?
107 andreas 8594
        {
110 andreas 8595
            int bst = bt->getNumberInstances();
107 andreas 8596
 
110 andreas 8597
            for (int i = 0; i < bst; i++)
107 andreas 8598
            {
110 andreas 8599
                string bname = bt->getBorderStyle(i);
300 andreas 8600
                sendCustomEvent(i + 1, (int)bname.length(), 0, bname, 1014, bt->getChannelPort(), bt->getChannelNumber());
107 andreas 8601
            }
8602
        }
110 andreas 8603
        else
8604
        {
8605
            string bname = bt->getBorderStyle(btState-1);
300 andreas 8606
            sendCustomEvent(btState, (int)bname.length(), 0, bname, 1014, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 8607
        }
107 andreas 8608
    }
8609
}
8610
 
60 andreas 8611
/**
16 andreas 8612
 * Set the button size and its position on the page.
8613
 */
8614
void TPageManager::doBSP(int port, vector<int>& channels, vector<string>& pars)
8615
{
8616
    DECL_TRACER("TPageManager::doBSP(int port, vector<int>& channels, vector<string>& pars)");
8617
 
8618
    if (pars.size() < 1)
8619
    {
8620
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
341 andreas 8621
#if TESTMODE == 1
8622
        setAllDone();
8623
#endif
16 andreas 8624
        return;
8625
    }
8626
 
8627
    TError::clear();
8628
    bool bLeft = false, bTop = false, bRight = false, bBottom = false;
8629
    int x, y;
8630
 
83 andreas 8631
    if (pars.size() > 0)
16 andreas 8632
    {
83 andreas 8633
        vector<string>::iterator iter;
8634
 
8635
        for (iter = pars.begin(); iter != pars.end(); iter++)
8636
        {
8637
            if (iter->compare("left") == 0)
8638
                bLeft = true;
8639
            else if (iter->compare("top") == 0)
8640
                bTop = true;
8641
            else if (iter->compare("right") == 0)
8642
                bRight = true;
8643
            else if (iter->compare("bottom") == 0)
8644
                bBottom = true;
8645
        }
16 andreas 8646
    }
8647
 
193 andreas 8648
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8649
 
8650
    if (TError::isError() || map.empty())
8651
        return;
8652
 
8653
    vector<Button::TButton *> buttons = collectButtons(map);
8654
 
83 andreas 8655
    if (buttons.size() > 0)
16 andreas 8656
    {
83 andreas 8657
        vector<Button::TButton *>::iterator mapIter;
16 andreas 8658
 
83 andreas 8659
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8660
        {
8661
            Button::TButton *bt = *mapIter;
16 andreas 8662
 
83 andreas 8663
            if (bLeft)
8664
                x = 0;
16 andreas 8665
 
83 andreas 8666
            if (bTop)
8667
                y = 0;
16 andreas 8668
 
341 andreas 8669
            if (bRight || bBottom)
16 andreas 8670
            {
83 andreas 8671
                ulong handle = bt->getHandle();
8672
                int parentID = (handle >> 16) & 0x0000ffff;
8673
                int pwidth = 0;
341 andreas 8674
                int pheight = 0;
16 andreas 8675
 
83 andreas 8676
                if (parentID < 500)
16 andreas 8677
                {
83 andreas 8678
                    TPage *pg = getPage(parentID);
8679
 
8680
                    if (!pg)
8681
                    {
8682
                        MSG_ERROR("Internal error: Page " << parentID << " not found!");
8683
                        return;
8684
                    }
8685
 
8686
                    pwidth = pg->getWidth();
341 andreas 8687
                    pheight = pg->getHeight();
16 andreas 8688
                }
83 andreas 8689
                else
8690
                {
8691
                    TSubPage *spg = getSubPage(parentID);
16 andreas 8692
 
83 andreas 8693
                    if (!spg)
8694
                    {
8695
                        MSG_ERROR("Internal error: Subpage " << parentID << " not found!");
8696
                        return;
8697
                    }
16 andreas 8698
 
83 andreas 8699
                    pwidth = spg->getWidth();
341 andreas 8700
                    pheight = spg->getHeight();
16 andreas 8701
                }
8702
 
341 andreas 8703
                if (bRight)
8704
                    x = pwidth - bt->getWidth();
8705
 
8706
                if (bBottom)
8707
                    y = pheight - bt->getHeight();
16 andreas 8708
            }
8709
 
341 andreas 8710
            bt->setLeftTop(x, y);
8711
#if TESTMODE == 1
8712
            if (_gTestMode)
83 andreas 8713
            {
341 andreas 8714
                int left = bt->getLeftPosition();
8715
                int top = bt->getTopPosition();
8716
                string res = intToString(left) + "," + intToString(top);
8717
                _gTestMode->setResult(res);
16 andreas 8718
            }
341 andreas 8719
#endif
16 andreas 8720
        }
8721
    }
341 andreas 8722
#if TESTMODE == 1
8723
    setDone();
8724
#endif
16 andreas 8725
}
8726
 
8727
/**
107 andreas 8728
 * Submit text for text area buttons. This command causes the text areas to
8729
 * send their text as strings to the NetLinx Master.
8730
 */
8731
void TPageManager::doBSM(int port, vector<int>& channels, vector<string>&)
8732
{
8733
    DECL_TRACER("TPageManager::doBSM(int port, vector<int>& channels, vector<string>& pars)");
8734
 
8735
    TError::clear();
193 andreas 8736
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 8737
 
8738
    if (TError::isError() || map.empty())
341 andreas 8739
    {
8740
#if TESTMODE == 1
8741
        setAllDone();
8742
#endif
107 andreas 8743
        return;
341 andreas 8744
    }
107 andreas 8745
 
8746
    vector<Button::TButton *> buttons = collectButtons(map);
8747
 
8748
    if (buttons.size() > 0)
8749
    {
8750
        vector<Button::TButton *>::iterator mapIter;
8751
 
8752
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8753
        {
8754
            Button::TButton *bt = *mapIter;
8755
 
195 andreas 8756
            if (bt->getButtonType() != TEXT_INPUT && bt->getButtonType() != GENERAL)
341 andreas 8757
            {
8758
#if TESTMODE == 1
8759
                setAllDone();
8760
#endif
107 andreas 8761
                return;
341 andreas 8762
            }
107 andreas 8763
 
8764
            amx::ANET_SEND scmd;
8765
            scmd.port = bt->getChannelPort();
8766
            scmd.channel = bt->getChannelNumber();
8767
            scmd.ID = scmd.channel;
8768
            scmd.msg = bt->getText(0);
8769
            scmd.MC = 0x008b;       // string value
8770
 
8771
            if (gAmxNet)
8772
                gAmxNet->sendCommand(scmd);
8773
            else
8774
                MSG_WARNING("Missing global class TAmxNet. Can't send message!");
8775
 
8776
        }
8777
    }
8778
}
8779
 
8780
/**
8781
 * Set the sound played when a button is pressed. If the sound name is blank
8782
 * the sound is then cleared. If the sound name is not matched, the button
8783
 * sound is not changed.
8784
 */
8785
void TPageManager::doBSO(int port, vector<int>& channels, vector<string>& pars)
8786
{
8787
    DECL_TRACER("TPageManager::doBSO(int port, vector<int>& channels, vector<string>& pars)");
8788
 
8789
    if (pars.size() < 2)
8790
    {
8791
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
8792
        return;
8793
    }
8794
 
8795
    if (!gPrjResources)
8796
        return;
8797
 
8798
    TError::clear();
8799
    int btState = atoi(pars[0].c_str());
8800
    string sound = pars[1];
8801
 
8802
    if (!soundExist(sound))
8803
        return;
8804
 
193 andreas 8805
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 8806
 
8807
    if (TError::isError() || map.empty())
8808
        return;
8809
 
8810
    vector<Button::TButton *> buttons = collectButtons(map);
8811
 
8812
    if (buttons.size() > 0)
8813
    {
8814
        vector<Button::TButton *>::iterator mapIter;
8815
 
8816
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8817
        {
8818
            Button::TButton *bt = *mapIter;
8819
 
8820
            if (btState == 0)
8821
            {
8822
                int bst = bt->getNumberInstances();
8823
 
8824
                for (int i = 0; i < bst; i++)
8825
                    bt->setSound(sound, i);
8826
            }
8827
            else
8828
                bt->setSound(sound, btState-1);
8829
        }
8830
    }
8831
}
8832
 
8833
/**
16 andreas 8834
 * Set the button word wrap feature to those buttons with a defined address
8835
 * range. By default, word-wrap is Off.
8836
 */
8837
void TPageManager::doBWW(int port, vector<int>& channels, vector<string>& pars)
8838
{
8839
    DECL_TRACER("TPageManager::doBWW(int port, vector<int>& channels, vector<string>& pars)");
8840
 
8841
    if (pars.size() < 1)
8842
    {
8843
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
8844
        return;
8845
    }
8846
 
8847
    TError::clear();
8848
    int btState = atoi(pars[0].c_str());
8849
 
193 andreas 8850
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8851
 
8852
    if (TError::isError() || map.empty())
8853
        return;
8854
 
8855
    vector<Button::TButton *> buttons = collectButtons(map);
8856
 
83 andreas 8857
    if (buttons.size() > 0)
16 andreas 8858
    {
83 andreas 8859
        vector<Button::TButton *>::iterator mapIter;
16 andreas 8860
 
83 andreas 8861
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
16 andreas 8862
        {
83 andreas 8863
            Button::TButton *bt = *mapIter;
252 andreas 8864
//            setButtonCallbacks(bt);
16 andreas 8865
 
83 andreas 8866
            if (btState == 0)       // All instances?
8867
            {
8868
                int bst = bt->getNumberInstances();
8869
                MSG_DEBUG("Setting word wrap on all " << bst << " instances...");
8870
 
8871
                for (int i = 0; i < bst; i++)
110 andreas 8872
                    bt->setTextWordWrap(true, i);
83 andreas 8873
            }
8874
            else
110 andreas 8875
                bt->setTextWordWrap(true, btState - 1);
16 andreas 8876
        }
8877
    }
8878
}
8879
 
108 andreas 8880
void TPageManager::getBWW(int port, vector<int>& channels, vector<string>& pars)
8881
{
8882
    DECL_TRACER("TPageManager::getBWW(int port, vector<int>& channels, vector<string>& pars)");
8883
 
8884
    if (pars.size() < 1)
8885
    {
8886
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8887
        return;
8888
    }
8889
 
8890
    TError::clear();
8891
    int btState = atoi(pars[0].c_str());
8892
 
193 andreas 8893
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 8894
 
8895
    if (TError::isError() || map.empty())
8896
        return;
8897
 
8898
    vector<Button::TButton *> buttons = collectButtons(map);
8899
 
8900
    if (buttons.size() > 0)
8901
    {
110 andreas 8902
        Button::TButton *bt = buttons[0];
108 andreas 8903
 
110 andreas 8904
        if (btState == 0)       // All instances?
108 andreas 8905
        {
110 andreas 8906
            int bst = bt->getNumberInstances();
108 andreas 8907
 
110 andreas 8908
            for (int i = 0; i < bst; i++)
8909
                sendCustomEvent(i + 1, bt->getTextWordWrap(i), 0, "", 1010, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 8910
        }
110 andreas 8911
        else
8912
            sendCustomEvent(btState, bt->getTextWordWrap(btState-1), 0, "", 1010, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 8913
    }
8914
}
8915
 
16 andreas 8916
/**
8917
 * Clear all page flips from a button.
8918
 */
22 andreas 8919
void TPageManager::doCPF(int port, vector<int>& channels, vector<string>&)
16 andreas 8920
{
8921
    DECL_TRACER("TPageManager::doCPF(int port, vector<int>& channels, vector<string>& pars)");
8922
 
8923
    TError::clear();
193 andreas 8924
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8925
 
8926
    if (TError::isError() || map.empty())
8927
        return;
8928
 
8929
    vector<Button::TButton *> buttons = collectButtons(map);
8930
 
83 andreas 8931
    if (buttons.size() > 0)
16 andreas 8932
    {
83 andreas 8933
        vector<Button::TButton *>::iterator mapIter;
8934
 
8935
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8936
        {
8937
            Button::TButton *bt = *mapIter;
252 andreas 8938
//            setButtonCallbacks(bt);
83 andreas 8939
            bt->clearPushFunctions();
8940
        }
16 andreas 8941
    }
8942
}
8943
 
8944
/**
8945
 * Delete page flips from button if it already exists.
8946
 */
8947
void TPageManager::doDPF(int port, vector<int>& channels, vector<string>& pars)
8948
{
8949
    DECL_TRACER("TPageManager::doDPF(int port, vector<int>& channels, vector<string>& pars)");
8950
 
8951
    if (pars.size() < 1)
8952
    {
8953
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8954
        return;
8955
    }
8956
 
8957
    TError::clear();
8958
    string action = pars[0];
8959
    string pname;
8960
 
8961
    if (pars.size() >= 2)
8962
    {
8963
        pname = pars[1];
8964
        vector<Button::TButton *> list;
8965
        // First we search for a subpage because this is more likely
8966
        TSubPage *spg = getSubPage(pname);
8967
 
8968
        if (spg)
8969
            list = spg->getButtons(port, channels[0]);
8970
        else    // Then for a page
8971
        {
8972
            TPage *pg = getPage(pname);
8973
 
8974
            if (pg)
8975
                list = pg->getButtons(port, channels[0]);
8976
            else
8977
            {
8978
                MSG_WARNING("The name " << pname << " doesn't name either a page or a subpage!");
8979
                return;
8980
            }
8981
        }
8982
 
8983
        if (list.empty())
8984
            return;
8985
 
8986
        vector<Button::TButton *>::iterator it;
8987
 
8988
        for (it = list.begin(); it != list.end(); it++)
8989
        {
8990
            Button::TButton *bt = *it;
252 andreas 8991
//            setButtonCallbacks(bt);
16 andreas 8992
            bt->clearPushFunction(action);
8993
        }
8994
 
8995
        return;
8996
    }
8997
 
8998
    // Here we don't have a page name
193 andreas 8999
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 9000
 
9001
    if (TError::isError() || map.empty())
9002
        return;
9003
 
9004
    vector<Button::TButton *> buttons = collectButtons(map);
9005
 
83 andreas 9006
    if (buttons.size() > 0)
16 andreas 9007
    {
83 andreas 9008
        vector<Button::TButton *>::iterator mapIter;
9009
 
9010
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9011
        {
9012
            Button::TButton *bt = *mapIter;
252 andreas 9013
//            setButtonCallbacks(bt);
83 andreas 9014
            bt->clearPushFunction(action);
9015
        }
16 andreas 9016
    }
9017
}
9018
 
9019
/**
9020
 * Enable or disable buttons with a set variable text range.
9021
 */
9022
void TPageManager::doENA(int port, vector<int>& channels, vector<string>& pars)
9023
{
9024
    DECL_TRACER("TPageManager::doENA(int port, vector<int>& channels, vector<string>& pars)");
9025
 
9026
    if (pars.empty())
9027
    {
9028
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
341 andreas 9029
#if TESTMODE == 1
9030
        setAllDone();
9031
#endif
16 andreas 9032
        return;
9033
    }
9034
 
9035
    TError::clear();
9036
    int cvalue = atoi(pars[0].c_str());
9037
 
193 andreas 9038
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 9039
 
9040
    if (TError::isError() || map.empty())
341 andreas 9041
    {
9042
#if TESTMODE == 1
9043
        setAllDone();
9044
#endif
16 andreas 9045
        return;
341 andreas 9046
    }
16 andreas 9047
 
9048
    vector<Button::TButton *> buttons = collectButtons(map);
9049
 
83 andreas 9050
    if (buttons.size() > 0)
16 andreas 9051
    {
83 andreas 9052
        vector<Button::TButton *>::iterator mapIter;
9053
 
9054
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9055
        {
9056
            Button::TButton *bt = *mapIter;
9057
            bt->setEnable(((cvalue)?true:false));
341 andreas 9058
#if TESTMODE == 1
9059
            __success = true;
9060
 
9061
            if (_gTestMode)
9062
                _gTestMode->setResult(intToString(cvalue));
9063
#endif
83 andreas 9064
        }
16 andreas 9065
    }
341 andreas 9066
#if TESTMODE == 1
9067
    setAllDone();
9068
#endif
16 andreas 9069
}
9070
 
9071
/**
9072
 * Set a font to a specific Font ID value for those buttons with a defined
9073
 * address range. Font ID numbers are generated by the TPDesign4 programmers
9074
 * report.
9075
 */
9076
void TPageManager::doFON(int port, vector<int>& channels, vector<string>& pars)
9077
{
9078
    DECL_TRACER("TPageManager::doFON(int port, vector<int>& channels, vector<string>& pars)");
9079
 
9080
    if (pars.size() < 2)
9081
    {
9082
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
342 andreas 9083
#if TESTMODE == 1
9084
        setAllDone();
9085
#endif
16 andreas 9086
        return;
9087
    }
9088
 
9089
    TError::clear();
342 andreas 9090
    int btState = atoi(pars[0].c_str()) - 1;
16 andreas 9091
    int fvalue = atoi(pars[1].c_str());
9092
 
193 andreas 9093
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 9094
 
9095
    if (TError::isError() || map.empty())
9096
        return;
9097
 
9098
    vector<Button::TButton *> buttons = collectButtons(map);
9099
 
83 andreas 9100
    if (buttons.size() > 0)
16 andreas 9101
    {
83 andreas 9102
        vector<Button::TButton *>::iterator mapIter;
16 andreas 9103
 
83 andreas 9104
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
16 andreas 9105
        {
83 andreas 9106
            Button::TButton *bt = *mapIter;
342 andreas 9107
            bt->setFont(fvalue, btState);
9108
#if TESTMODE == 1
9109
            if (_gTestMode)
9110
                _gTestMode->setResult(intToString(bt->getFontIndex(btState < 0 ? 0 : btState)));
9111
#endif
16 andreas 9112
        }
9113
    }
342 andreas 9114
#if TESTMODE == 1
9115
    setDone();
9116
#endif
16 andreas 9117
}
9118
 
108 andreas 9119
void TPageManager::getFON(int port, vector<int>& channels, vector<string>& pars)
9120
{
9121
    DECL_TRACER("TPageManager::getFON(int port, vector<int>& channels, vector<string>& pars)");
9122
 
9123
    if (pars.size() < 1)
9124
    {
9125
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
342 andreas 9126
#if TESTMODE == 1
9127
        setAllDone();
9128
#endif
108 andreas 9129
        return;
9130
    }
9131
 
9132
    TError::clear();
9133
    int btState = atoi(pars[0].c_str());
9134
 
193 andreas 9135
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9136
 
9137
    if (TError::isError() || map.empty())
342 andreas 9138
    {
9139
#if TESTMODE == 1
9140
        setAllDone();
9141
#endif
108 andreas 9142
        return;
342 andreas 9143
    }
108 andreas 9144
 
9145
    vector<Button::TButton *> buttons = collectButtons(map);
9146
 
9147
    if (buttons.size() > 0)
9148
    {
110 andreas 9149
        Button::TButton *bt = buttons[0];
108 andreas 9150
 
110 andreas 9151
        if (btState == 0)       // All instances?
108 andreas 9152
        {
110 andreas 9153
            int bst = bt->getNumberInstances();
108 andreas 9154
 
110 andreas 9155
            for (int i = 0; i < bst; i++)
9156
                sendCustomEvent(i + 1, bt->getFontIndex(i), 0, "", 1007, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9157
        }
110 andreas 9158
        else
9159
            sendCustomEvent(btState, bt->getFontIndex(btState - 1), 0, "", 1007, bt->getChannelPort(), bt->getChannelNumber());
342 andreas 9160
#if TESTMODE == 1
9161
        if (_gTestMode)
9162
            _gTestMode->setResult(intToString(bt->getFontIndex(btState < 0 ? 0 : btState)));
9163
#endif
108 andreas 9164
    }
342 andreas 9165
#if TESTMODE == 1
9166
    __success = true;
9167
    setAllDone();
9168
#endif
108 andreas 9169
}
9170
 
388 andreas 9171
void TPageManager::doGDI(int port, vector<int>& channels, vector<std::string>& pars)
9172
{
9173
    DECL_TRACER("TPageManager::doGDI(int port, vector<int>& channels, vector<std::string>& pars)");
9174
 
9175
    if (pars.size() < 1)
9176
    {
9177
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9178
        return;
9179
    }
9180
 
9181
    TError::clear();
9182
    int inc = atoi(pars[0].c_str());
9183
 
9184
    if (inc < 0)
9185
    {
9186
        MSG_ERROR("Invalid drag increment of " << inc << "!");
9187
        return;
9188
    }
9189
 
9190
    vector<TMap::MAP_T> map = findButtons(port, channels);
9191
 
9192
    if (TError::isError() || map.empty())
9193
        return;
9194
 
9195
    vector<Button::TButton *> buttons = collectButtons(map);
9196
 
9197
    if (buttons.size() > 0)
9198
    {
9199
        vector<Button::TButton *>::iterator mapIter;
9200
 
9201
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9202
        {
9203
            Button::TButton *bt = *mapIter;
9204
            bt->setBargraphDragIncrement(inc);
9205
        }
9206
    }
9207
}
9208
/* Currently not implemented
9209
void TPageManager::doGDV(int port, vector<int>& channels, vector<std::string>& pars)
9210
{
9211
    DECL_TRACER("TPageManager::doGDV(int port, vector<int>& channels, vector<std::string>& pars)");
9212
}
9213
*/
16 andreas 9214
/**
60 andreas 9215
 * Change the bargraph upper limit.
9216
 */
9217
void TPageManager::doGLH(int port, vector<int>& channels, vector<std::string>& pars)
9218
{
9219
    DECL_TRACER("TPageManager::doGLH(int port, vector<int>& channels, vector<std::string>& pars)");
9220
 
9221
    if (pars.size() < 1)
9222
    {
9223
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9224
        return;
9225
    }
9226
 
9227
    TError::clear();
9228
    int limit = atoi(pars[0].c_str());
9229
 
9230
    if (limit < 1)
9231
    {
9232
        MSG_ERROR("Invalid upper limit " << limit << "!");
9233
        return;
9234
    }
9235
 
193 andreas 9236
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 9237
 
9238
    if (TError::isError() || map.empty())
9239
        return;
9240
 
9241
    vector<Button::TButton *> buttons = collectButtons(map);
9242
 
83 andreas 9243
    if (buttons.size() > 0)
60 andreas 9244
    {
83 andreas 9245
        vector<Button::TButton *>::iterator mapIter;
9246
 
9247
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9248
        {
9249
            Button::TButton *bt = *mapIter;
252 andreas 9250
//            setButtonCallbacks(bt);
83 andreas 9251
            bt->setBargraphUpperLimit(limit);
9252
        }
60 andreas 9253
    }
9254
}
9255
 
9256
/**
9257
 * Change the bargraph lower limit.
9258
 */
9259
void TPageManager::doGLL(int port, vector<int>& channels, vector<std::string>& pars)
9260
{
9261
    DECL_TRACER("TPageManager::doGLL(int port, vector<int>& channels, vector<std::string>& pars)");
9262
 
9263
    if (pars.size() < 1)
9264
    {
9265
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9266
        return;
9267
    }
9268
 
9269
    TError::clear();
9270
    int limit = atoi(pars[0].c_str());
9271
 
9272
    if (limit < 1)
9273
    {
9274
        MSG_ERROR("Invalid lower limit " << limit << "!");
9275
        return;
9276
    }
9277
 
193 andreas 9278
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 9279
 
9280
    if (TError::isError() || map.empty())
9281
        return;
9282
 
9283
    vector<Button::TButton *> buttons = collectButtons(map);
9284
 
83 andreas 9285
    if (buttons.size() > 0)
60 andreas 9286
    {
83 andreas 9287
        vector<Button::TButton *>::iterator mapIter;
9288
 
9289
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9290
        {
9291
            Button::TButton *bt = *mapIter;
252 andreas 9292
//            setButtonCallbacks(bt);
83 andreas 9293
            bt->setBargraphLowerLimit(limit);
9294
        }
60 andreas 9295
    }
9296
}
9297
 
108 andreas 9298
void TPageManager::doGSC(int port, vector<int>& channels, vector<string>& pars)
9299
{
9300
    DECL_TRACER("TPageManager::doGSC(int port, vector<int>& channels, vector<string>& pars)");
9301
 
9302
    if (pars.size() < 1)
9303
    {
9304
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9305
        return;
9306
    }
9307
 
9308
    TError::clear();
9309
    string color = pars[0];
193 andreas 9310
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9311
 
9312
    if (TError::isError() || map.empty())
9313
        return;
9314
 
9315
    vector<Button::TButton *> buttons = collectButtons(map);
9316
 
9317
    if (buttons.size() > 0)
9318
    {
9319
        vector<Button::TButton *>::iterator mapIter;
9320
 
9321
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9322
        {
9323
            Button::TButton *bt = *mapIter;
9324
            bt->setBargraphSliderColor(color);
9325
        }
9326
    }
9327
}
9328
 
361 andreas 9329
/*
388 andreas 9330
 * Set bargraph ramp down time in 1/10 seconds.
9331
 */
9332
void TPageManager::doGRD(int port, vector<int>& channels, vector<string>& pars)
9333
{
9334
    DECL_TRACER("TPageManager::doGRD(int port, vector<int>& channels, vector<string>& pars)");
9335
 
9336
    if (pars.size() < 1)
9337
    {
9338
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9339
        return;
9340
    }
9341
 
9342
    TError::clear();
9343
    int t = atoi(pars[0].c_str());
9344
 
9345
    if (t < 0)
9346
    {
9347
        MSG_ERROR("Invalid ramp down time limit " << t << "!");
9348
        return;
9349
    }
9350
 
9351
    vector<TMap::MAP_T> map = findButtons(port, channels);
9352
 
9353
    if (TError::isError() || map.empty())
9354
        return;
9355
 
9356
    vector<Button::TButton *> buttons = collectButtons(map);
9357
 
9358
    if (buttons.size() > 0)
9359
    {
9360
        vector<Button::TButton *>::iterator mapIter;
9361
 
9362
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9363
        {
9364
            Button::TButton *bt = *mapIter;
9365
            bt->setBargraphRampDownTime(t);
9366
        }
9367
    }
9368
}
9369
 
9370
/*
9371
 * Set bargraph ramp up time in 1/10 seconds.
9372
 */
9373
void TPageManager::doGRU(int port, vector<int>& channels, vector<string>& pars)
9374
{
9375
    DECL_TRACER("TPageManager::doGRU(int port, vector<int>& channels, vector<string>& pars)");
9376
 
9377
    if (pars.size() < 1)
9378
    {
9379
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9380
        return;
9381
    }
9382
 
9383
    TError::clear();
9384
    int t = atoi(pars[0].c_str());
9385
 
9386
    if (t < 0)
9387
    {
9388
        MSG_ERROR("Invalid ramp up time limit " << t << "!");
9389
        return;
9390
    }
9391
 
9392
    vector<TMap::MAP_T> map = findButtons(port, channels);
9393
 
9394
    if (TError::isError() || map.empty())
9395
        return;
9396
 
9397
    vector<Button::TButton *> buttons = collectButtons(map);
9398
 
9399
    if (buttons.size() > 0)
9400
    {
9401
        vector<Button::TButton *>::iterator mapIter;
9402
 
9403
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9404
        {
9405
            Button::TButton *bt = *mapIter;
9406
            bt->setBargraphRampUpTime(t);
9407
        }
9408
    }
9409
}
9410
 
9411
/*
361 andreas 9412
 * Change the bargraph slider name or joystick cursor name.
9413
 */
9414
void TPageManager::doGSN(int port, vector<int>& channels, vector<string>& pars)
9415
{
9416
    DECL_TRACER("TPageManager::doGSN(int port, vector<int>& channels, vector<string>& pars)");
9417
 
9418
    if (pars.size() < 1)
9419
    {
9420
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9421
        return;
9422
    }
9423
 
9424
    TError::clear();
9425
    string name = pars[0];
9426
    vector<TMap::MAP_T> map = findButtons(port, channels);
9427
 
9428
    if (TError::isError() || map.empty())
9429
        return;
9430
 
9431
    vector<Button::TButton *> buttons = collectButtons(map);
9432
 
9433
    if (buttons.size() > 0)
9434
    {
9435
        vector<Button::TButton *>::iterator mapIter;
9436
 
9437
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9438
        {
9439
            Button::TButton *bt = *mapIter;
9440
            bt->setBargraphSliderName(name);
9441
        }
9442
    }
9443
}
9444
 
60 andreas 9445
/**
14 andreas 9446
 * Set the icon to a button.
9447
 */
9448
void TPageManager::doICO(int port, vector<int>& channels, vector<string>& pars)
9449
{
9450
    DECL_TRACER("TPageManager::doICO(int port, vector<int>& channels, vector<string>& pars)");
9451
 
9452
    if (pars.size() < 2)
9453
    {
9454
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
9455
        return;
9456
    }
9457
 
16 andreas 9458
    TError::clear();
14 andreas 9459
    int btState = atoi(pars[0].c_str());
9460
    int iconIdx = atoi(pars[1].c_str());
9461
 
193 andreas 9462
    vector<TMap::MAP_T> map = findButtons(port, channels);
14 andreas 9463
 
9464
    if (TError::isError() || map.empty())
9465
        return;
9466
 
9467
    vector<Button::TButton *> buttons = collectButtons(map);
9468
 
83 andreas 9469
    if (buttons.size() > 0)
14 andreas 9470
    {
83 andreas 9471
        vector<Button::TButton *>::iterator mapIter;
14 andreas 9472
 
83 andreas 9473
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
14 andreas 9474
        {
83 andreas 9475
            Button::TButton *bt = *mapIter;
14 andreas 9476
 
83 andreas 9477
            if (btState == 0)       // All instances?
14 andreas 9478
            {
316 andreas 9479
                if (iconIdx > 0)
9480
                    bt->setIcon(iconIdx, -1);
9481
                else
9482
                    bt->revokeIcon(-1);
14 andreas 9483
            }
83 andreas 9484
            else if (iconIdx > 0)
9485
                bt->setIcon(iconIdx, btState - 1);
9486
            else
9487
                bt->revokeIcon(btState - 1);
14 andreas 9488
        }
9489
    }
9490
}
9491
 
108 andreas 9492
void TPageManager::getICO(int port, vector<int>& channels, vector<string>& pars)
9493
{
9494
    DECL_TRACER("TPageManager::getICO(int port, vector<int>& channels, vector<string>& pars)");
9495
 
9496
    if (pars.size() < 1)
9497
    {
9498
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9499
        return;
9500
    }
9501
 
9502
    TError::clear();
9503
    int btState = atoi(pars[0].c_str());
9504
 
193 andreas 9505
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9506
 
9507
    if (TError::isError() || map.empty())
9508
        return;
9509
 
9510
    vector<Button::TButton *> buttons = collectButtons(map);
9511
 
9512
    if (buttons.size() > 0)
9513
    {
110 andreas 9514
        Button::TButton *bt = buttons[0];
108 andreas 9515
 
110 andreas 9516
        if (btState == 0)       // All instances?
108 andreas 9517
        {
110 andreas 9518
            int bst = bt->getNumberInstances();
108 andreas 9519
 
110 andreas 9520
            for (int i = 0; i < bst; i++)
9521
                sendCustomEvent(i + 1, bt->getIconIndex(i), 0, "", 1003, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9522
        }
110 andreas 9523
        else
9524
            sendCustomEvent(btState, bt->getIconIndex(btState - 1), 0, "", 1003, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9525
    }
9526
}
9527
 
14 andreas 9528
/**
108 andreas 9529
 * Set bitmap/picture alignment using a numeric keypad layout for those buttons
9530
 * with a defined address range. The alignment of 0 is followed by
9531
 * ',<left>,<top>'. The left and top coordinates are relative to the upper left
9532
 * corner of the button.
9533
 */
9534
void TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)
9535
{
9536
    DECL_TRACER("TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)");
9537
 
9538
    if (pars.size() < 2)
9539
    {
9540
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
9541
        return;
9542
    }
9543
 
9544
    TError::clear();
9545
    int btState = atoi(pars[0].c_str());
9546
    int align = atoi(pars[1].c_str());
9547
    int x = 0, y = 0;
9548
 
9549
    if (!align && pars.size() >= 3)
9550
    {
9551
        x = atoi(pars[2].c_str());
9552
 
9553
        if (pars.size() >= 4)
9554
            y = atoi(pars[3].c_str());
9555
    }
9556
 
193 andreas 9557
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9558
 
9559
    if (TError::isError() || map.empty())
9560
        return;
9561
 
9562
    vector<Button::TButton *> buttons = collectButtons(map);
9563
 
9564
    if (buttons.size() > 0)
9565
    {
9566
        vector<Button::TButton *>::iterator mapIter;
9567
 
9568
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9569
        {
9570
            Button::TButton *bt = *mapIter;
9571
 
9572
            if (btState == 0)
9573
                bt->setBitmapJustification(align, x, y, -1);
9574
            else
9575
                bt->setBitmapJustification(align, x, y, btState-1);
9576
        }
9577
    }
9578
}
9579
 
9580
void TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)
9581
{
9582
    DECL_TRACER("TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)");
9583
 
9584
    if (pars.size() < 1)
9585
    {
9586
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9587
        return;
9588
    }
9589
 
9590
    TError::clear();
9591
    int btState = atoi(pars[0].c_str());
9592
    int j, x, y;
9593
 
193 andreas 9594
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9595
 
9596
    if (TError::isError() || map.empty())
9597
        return;
9598
 
9599
    vector<Button::TButton *> buttons = collectButtons(map);
9600
 
9601
    if (buttons.size() > 0)
9602
    {
110 andreas 9603
        Button::TButton *bt = buttons[0];
108 andreas 9604
 
110 andreas 9605
        if (btState == 0)       // All instances?
108 andreas 9606
        {
110 andreas 9607
            int bst = bt->getNumberInstances();
108 andreas 9608
 
110 andreas 9609
            for (int i = 0; i < bst; i++)
108 andreas 9610
            {
110 andreas 9611
                j = bt->getBitmapJustification(&x, &y, i);
9612
                sendCustomEvent(i + 1, j, 0, "", 1005, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9613
            }
9614
        }
110 andreas 9615
        else
9616
        {
9617
            j = bt->getBitmapJustification(&x, &y, btState-1);
9618
            sendCustomEvent(btState, j, 0, "", 1005, bt->getChannelPort(), bt->getChannelNumber());
9619
        }
108 andreas 9620
    }
9621
}
9622
 
9623
/**
9624
 * Set icon alignment using a numeric keypad layout for those buttons with a
9625
 * defined address range. The alignment of 0 is followed by ',<left>,<top>'.
9626
 * The left and top coordinates are relative to the upper left corner of the
9627
 * button.
9628
 */
9629
void TPageManager::doJSI(int port, vector<int>& channels, vector<string>& pars)
9630
{
9631
    DECL_TRACER("TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)");
9632
 
9633
    if (pars.size() < 2)
9634
    {
9635
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
9636
        return;
9637
    }
9638
 
9639
    TError::clear();
9640
    int btState = atoi(pars[0].c_str());
9641
    int align = atoi(pars[1].c_str());
9642
    int x = 0, y = 0;
9643
 
9644
    if (!align && pars.size() >= 3)
9645
    {
9646
        x = atoi(pars[2].c_str());
9647
 
9648
        if (pars.size() >= 4)
9649
            y = atoi(pars[3].c_str());
9650
    }
9651
 
193 andreas 9652
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9653
 
9654
    if (TError::isError() || map.empty())
9655
        return;
9656
 
9657
    vector<Button::TButton *> buttons = collectButtons(map);
9658
 
9659
    if (buttons.size() > 0)
9660
    {
9661
        vector<Button::TButton *>::iterator mapIter;
9662
 
9663
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9664
        {
9665
            Button::TButton *bt = *mapIter;
9666
 
9667
            if (btState == 0)
9668
                bt->setIconJustification(align, x, y, -1);
9669
            else
9670
                bt->setIconJustification(align, x, y, btState-1);
9671
        }
9672
    }
9673
}
9674
 
9675
void TPageManager::getJSI(int port, vector<int>& channels, vector<string>& pars)
9676
{
9677
    DECL_TRACER("TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)");
9678
 
9679
    if (pars.size() < 1)
9680
    {
9681
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9682
        return;
9683
    }
9684
 
9685
    TError::clear();
9686
    int btState = atoi(pars[0].c_str());
9687
    int j, x, y;
9688
 
193 andreas 9689
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9690
 
9691
    if (TError::isError() || map.empty())
9692
        return;
9693
 
9694
    vector<Button::TButton *> buttons = collectButtons(map);
9695
 
9696
    if (buttons.size() > 0)
9697
    {
110 andreas 9698
        Button::TButton *bt = buttons[0];
108 andreas 9699
 
110 andreas 9700
        if (btState == 0)       // All instances?
108 andreas 9701
        {
110 andreas 9702
            int bst = bt->getNumberInstances();
108 andreas 9703
 
110 andreas 9704
            for (int i = 0; i < bst; i++)
108 andreas 9705
            {
110 andreas 9706
                j = bt->getIconJustification(&x, &y, i);
9707
                sendCustomEvent(i + 1, j, 0, "", 1006, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9708
            }
9709
        }
110 andreas 9710
        else
9711
        {
9712
            j = bt->getIconJustification(&x, &y, btState-1);
9713
            sendCustomEvent(btState, j, 0, "", 1006, bt->getChannelPort(), bt->getChannelNumber());
9714
        }
108 andreas 9715
    }
9716
}
9717
 
9718
void TPageManager::doJST(int port, vector<int>& channels, vector<string>& pars)
9719
{
9720
    DECL_TRACER("TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)");
9721
 
9722
    if (pars.size() < 2)
9723
    {
9724
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
9725
        return;
9726
    }
9727
 
9728
    TError::clear();
9729
    int btState = atoi(pars[0].c_str());
9730
    int align = atoi(pars[1].c_str());
9731
    int x = 0, y = 0;
9732
 
9733
    if (!align && pars.size() >= 3)
9734
    {
9735
        x = atoi(pars[2].c_str());
9736
 
9737
        if (pars.size() >= 4)
9738
            y = atoi(pars[3].c_str());
9739
    }
9740
 
193 andreas 9741
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9742
 
9743
    if (TError::isError() || map.empty())
9744
        return;
9745
 
9746
    vector<Button::TButton *> buttons = collectButtons(map);
9747
 
9748
    if (buttons.size() > 0)
9749
    {
9750
        vector<Button::TButton *>::iterator mapIter;
9751
 
9752
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9753
        {
9754
            Button::TButton *bt = *mapIter;
9755
 
9756
            if (btState == 0)
9757
                bt->setTextJustification(align, x, y, -1);
9758
            else
9759
                bt->setTextJustification(align, x, y, btState-1);
9760
        }
9761
    }
9762
}
9763
 
9764
void TPageManager::getJST(int port, vector<int>& channels, vector<string>& pars)
9765
{
9766
    DECL_TRACER("TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)");
9767
 
9768
    if (pars.size() < 1)
9769
    {
9770
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9771
        return;
9772
    }
9773
 
9774
    TError::clear();
9775
    int btState = atoi(pars[0].c_str());
9776
    int j, x, y;
9777
 
193 andreas 9778
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9779
 
9780
    if (TError::isError() || map.empty())
9781
        return;
9782
 
9783
    vector<Button::TButton *> buttons = collectButtons(map);
9784
 
9785
    if (buttons.size() > 0)
9786
    {
110 andreas 9787
        Button::TButton *bt = buttons[0];
108 andreas 9788
 
110 andreas 9789
        if (btState == 0)       // All instances?
108 andreas 9790
        {
110 andreas 9791
            int bst = bt->getNumberInstances();
108 andreas 9792
 
110 andreas 9793
            for (int i = 0; i < bst; i++)
108 andreas 9794
            {
110 andreas 9795
                j = bt->getTextJustification(&x, &y, i);
9796
                sendCustomEvent(i + 1, j, 0, "", 1004, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9797
            }
9798
        }
110 andreas 9799
        else
9800
        {
9801
            j = bt->getTextJustification(&x, &y, btState-1);
9802
            sendCustomEvent(btState, j, 0, "", 1004, bt->getChannelPort(), bt->getChannelNumber());
9803
        }
108 andreas 9804
    }
9805
}
9806
 
9807
/**
395 andreas 9808
 * @brief TPageManager::getMSP
9809
 * Sets the speed of a marquee line. Allowed range is from 1 to 10, where 10 is
9810
 * the fastest speed.
9811
 *
9812
 * @param port      The port number
9813
 * @param channels  The channels
9814
 * @param pars      Parameters
9815
 */
9816
void TPageManager::doMSP(int port, vector<int>& channels, vector<string>& pars)
9817
{
9818
    DECL_TRACER("TPageManager::getMSP(int port, vector<int>& channels, vector<string>& pars)");
9819
 
9820
    if (pars.size() < 2)
9821
    {
9822
        MSG_ERROR("Expecting at least 2 parameter but got less! Command ignored.");
9823
        return;
9824
    }
9825
 
9826
    TError::clear();
9827
    int btState = atoi(pars[0].c_str()) - 1;
9828
    int speed = atoi(pars[1].c_str());
9829
 
9830
    if (speed < 1 || speed > 10)
9831
    {
9832
        MSG_ERROR("Speed for marquee line is out of range!");
9833
        return;
9834
    }
9835
 
9836
    vector<TMap::MAP_T> map = findButtons(port, channels);
9837
 
9838
    if (TError::isError() || map.empty())
9839
        return;
9840
 
9841
    vector<Button::TButton *> buttons = collectButtons(map);
9842
 
9843
    if (buttons.size() > 0)
9844
    {
9845
        vector<Button::TButton *>::iterator iter;
9846
 
9847
        for (iter = buttons.begin(); iter != buttons.end(); ++iter)
9848
        {
9849
            Button::TButton *bt = buttons[0];
9850
            bt->setMarqueeSpeed(speed, btState);
9851
        }
9852
    }
9853
}
9854
 
9855
/**
16 andreas 9856
 * Show or hide a button with a set variable text range.
9857
 */
9858
void TPageManager::doSHO(int port, vector<int>& channels, vector<string>& pars)
9859
{
9860
    DECL_TRACER("TPageManager::doSHO(int port, vector<int>& channels, vector<string>& pars)");
9861
 
9862
    if (pars.empty())
9863
    {
9864
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
9865
        return;
9866
    }
9867
 
9868
    TError::clear();
9869
    int cvalue = atoi(pars[0].c_str());
9870
 
193 andreas 9871
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 9872
 
9873
    if (TError::isError() || map.empty())
9874
        return;
9875
 
9876
    vector<Button::TButton *> buttons = collectButtons(map);
9877
 
83 andreas 9878
    if (buttons.size() > 0)
16 andreas 9879
    {
83 andreas 9880
        vector<Button::TButton *>::iterator mapIter;
9881
 
9882
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9883
        {
9884
            Button::TButton *bt = *mapIter;
318 andreas 9885
 
100 andreas 9886
            int pgID = (bt->getParent() >> 16) & 0x0000ffff;
9887
            bool pVisible = false;
9888
 
9889
            if (pgID < 500)
9890
            {
9891
                TPage *pg = getPage(pgID);
9892
 
9893
                if (pg && pg->isVisilble())
9894
                    pVisible = true;
9895
            }
9896
            else
9897
            {
9898
                TSubPage *pg = getSubPage(pgID);
9899
 
9900
                if (pg && pg->isVisible())
9901
                    pVisible = true;
9902
            }
9903
 
151 andreas 9904
            bool oldV = bt->isVisible();
9905
            bool visible = cvalue ? true : false;
9906
            MSG_DEBUG("Button " << bt->getButtonIndex() << ", \"" << bt->getButtonName() << "\" set " << (visible ? "VISIBLE" : "HIDDEN") << " (Previous: " << (oldV ? "VISIBLE" : "HIDDEN") << ")");
98 andreas 9907
 
151 andreas 9908
            if (visible != oldV)
100 andreas 9909
            {
151 andreas 9910
                bt->setVisible(visible);
100 andreas 9911
 
151 andreas 9912
                if (pVisible)
9913
                {
9914
                    setButtonCallbacks(bt);
9915
 
9916
                    if (_setVisible)
9917
                        _setVisible(bt->getHandle(), visible);
9918
                    else
9919
                        bt->refresh();
9920
                }
100 andreas 9921
            }
83 andreas 9922
        }
16 andreas 9923
    }
9924
}
9925
 
108 andreas 9926
void TPageManager::doTEC(int port, vector<int>& channels, vector<string>& pars)
9927
{
9928
    DECL_TRACER("TPageManager::doTEC(int port, vector<int>& channels, vector<string>& pars)");
9929
 
9930
    if (pars.size() < 2)
9931
    {
9932
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
9933
        return;
9934
    }
9935
 
9936
    TError::clear();
9937
    int btState = atoi(pars[0].c_str());
9938
    string color = pars[1];
9939
 
193 andreas 9940
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9941
 
9942
    if (TError::isError() || map.empty())
9943
        return;
9944
 
9945
    vector<Button::TButton *> buttons = collectButtons(map);
9946
 
9947
    if (buttons.size() > 0)
9948
    {
9949
        vector<Button::TButton *>::iterator mapIter;
9950
 
9951
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9952
        {
9953
            Button::TButton *bt = *mapIter;
9954
 
9955
            if (btState == 0)
9956
                bt->setTextEffectColor(color);
9957
            else
9958
                bt->setTextEffectColor(color, btState-1);
9959
        }
9960
    }
9961
}
9962
 
9963
void TPageManager::getTEC(int port, vector<int>& channels, vector<string>& pars)
9964
{
9965
    DECL_TRACER("TPageManager::getTEC(int port, vector<int>& channels, vector<string>& pars)");
9966
 
9967
    if (pars.size() < 1)
9968
    {
9969
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9970
        return;
9971
    }
9972
 
9973
    TError::clear();
9974
    int btState = atoi(pars[0].c_str());
9975
 
193 andreas 9976
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9977
 
9978
    if (TError::isError() || map.empty())
9979
        return;
9980
 
9981
    vector<Button::TButton *> buttons = collectButtons(map);
9982
 
9983
    if (buttons.size() > 0)
9984
    {
110 andreas 9985
        Button::TButton *bt = buttons[0];
9986
 
9987
        if (btState == 0)       // All instances?
9988
        {
9989
            int bst = bt->getNumberInstances();
9990
 
9991
            for (int i = 0; i < bst; i++)
9992
            {
9993
                string c = bt->getTextEffectColor(i);
300 andreas 9994
                sendCustomEvent(i + 1, (int)c.length(), 0, c, 1009, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 9995
            }
9996
        }
9997
        else
9998
        {
9999
            string c = bt->getTextEffectColor(btState-1);
300 andreas 10000
            sendCustomEvent(btState, (int)c.length(), 0, c, 1009, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 10001
        }
10002
    }
10003
}
10004
 
10005
void TPageManager::doTEF(int port, vector<int>& channels, vector<string>& pars)
10006
{
10007
    DECL_TRACER("TPageManager::doTEF(int port, vector<int>& channels, vector<string>& pars)");
10008
 
10009
    if (pars.size() < 2)
10010
    {
10011
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
10012
        return;
10013
    }
10014
 
10015
    TError::clear();
10016
    int btState = atoi(pars[0].c_str());
10017
    string tef = pars[1];
10018
 
193 andreas 10019
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 10020
 
10021
    if (TError::isError() || map.empty())
10022
        return;
10023
 
10024
    vector<Button::TButton *> buttons = collectButtons(map);
10025
 
10026
    if (buttons.size() > 0)
10027
    {
108 andreas 10028
        vector<Button::TButton *>::iterator mapIter;
10029
 
10030
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10031
        {
10032
            Button::TButton *bt = *mapIter;
10033
 
110 andreas 10034
            if (btState == 0)
10035
                bt->setTextEffectName(tef);
10036
            else
10037
                bt->setTextEffectName(tef, btState-1);
10038
        }
10039
    }
10040
}
108 andreas 10041
 
110 andreas 10042
void TPageManager::getTEF(int port, vector<int>& channels, vector<string>& pars)
10043
{
10044
    DECL_TRACER("TPageManager::getTEF(int port, vector<int>& channels, vector<string>& pars)");
108 andreas 10045
 
110 andreas 10046
    if (pars.size() < 1)
10047
    {
10048
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
10049
        return;
10050
    }
108 andreas 10051
 
110 andreas 10052
    TError::clear();
10053
    int btState = atoi(pars[0].c_str());
10054
 
193 andreas 10055
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 10056
 
10057
    if (TError::isError() || map.empty())
10058
        return;
10059
 
10060
    vector<Button::TButton *> buttons = collectButtons(map);
10061
 
10062
    if (buttons.size() > 0)
10063
    {
10064
        Button::TButton *bt = buttons[0];
10065
 
10066
        if (btState == 0)       // All instances?
10067
        {
10068
            int bst = bt->getNumberInstances();
10069
 
10070
            for (int i = 0; i < bst; i++)
108 andreas 10071
            {
110 andreas 10072
                string c = bt->getTextEffectName(i);
300 andreas 10073
                sendCustomEvent(i + 1, (int)c.length(), 0, c, 1008, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 10074
            }
10075
        }
110 andreas 10076
        else
10077
        {
10078
            string c = bt->getTextEffectName(btState-1);
300 andreas 10079
            sendCustomEvent(btState, (int)c.length(), 0, c, 1008, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 10080
        }
108 andreas 10081
    }
10082
}
10083
 
16 andreas 10084
/**
14 andreas 10085
 * Assign a text string to those buttons with a defined address range.
10086
 * Sets Non-Unicode text.
10087
 */
10088
void TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)
10089
{
10090
    DECL_TRACER("TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)");
10091
 
10092
    if (pars.size() < 1)
10093
    {
10094
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
331 andreas 10095
#if TESTMODE == 1
334 andreas 10096
        setAllDone();
331 andreas 10097
#endif
14 andreas 10098
        return;
10099
    }
10100
 
16 andreas 10101
    TError::clear();
333 andreas 10102
    int btState = atoi(pars[0].c_str()) - 1;
14 andreas 10103
    string text;
10104
 
333 andreas 10105
    // Every comma (,) in the text produces a new parameter. Therefor we must
10106
    // concatenate this parameters together and insert the comma.
14 andreas 10107
    if (pars.size() > 1)
150 andreas 10108
    {
10109
        for (size_t i = 1; i < pars.size(); ++i)
10110
        {
10111
            if (i > 1)
10112
                text += ",";
14 andreas 10113
 
150 andreas 10114
            text += pars[i];
10115
        }
10116
    }
10117
 
193 andreas 10118
    vector<TMap::MAP_T> map = findButtons(port, channels);
14 andreas 10119
 
10120
    if (TError::isError() || map.empty())
331 andreas 10121
    {
10122
#if TESTMODE == 1
334 andreas 10123
        setAllDone();
331 andreas 10124
#endif
14 andreas 10125
        return;
331 andreas 10126
    }
14 andreas 10127
 
10128
    vector<Button::TButton *> buttons = collectButtons(map);
10129
 
83 andreas 10130
    if (buttons.size() > 0)
14 andreas 10131
    {
83 andreas 10132
        vector<Button::TButton *>::iterator mapIter;
14 andreas 10133
 
333 andreas 10134
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
14 andreas 10135
        {
83 andreas 10136
            Button::TButton *bt = *mapIter;
14 andreas 10137
 
252 andreas 10138
            if (!bt)
333 andreas 10139
                continue;
252 andreas 10140
 
333 andreas 10141
            bt->setText(text, btState);
331 andreas 10142
#if TESTMODE == 1
333 andreas 10143
            if (_gTestMode)
10144
                _gTestMode->setResult(bt->getText(btState < 0 ? 0 : btState));
331 andreas 10145
 
333 andreas 10146
            __success = true;
331 andreas 10147
#endif
14 andreas 10148
        }
10149
    }
331 andreas 10150
#if TESTMODE == 1
334 andreas 10151
    setDone();
331 andreas 10152
#endif
14 andreas 10153
}
21 andreas 10154
 
110 andreas 10155
void TPageManager::getTXT(int port, vector<int>& channels, vector<string>& pars)
10156
{
10157
    DECL_TRACER("TPageManager::getTXT(int port, vector<int>& channels, vector<string>& pars)");
10158
 
10159
    if (pars.size() < 1)
10160
    {
10161
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
10162
        return;
10163
    }
10164
 
10165
    TError::clear();
10166
    int btState = atoi(pars[0].c_str());
10167
 
193 andreas 10168
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 10169
 
10170
    if (TError::isError() || map.empty())
10171
        return;
10172
 
10173
    vector<Button::TButton *> buttons = collectButtons(map);
10174
 
10175
    if (buttons.size() > 0)
10176
    {
10177
        Button::TButton *bt = buttons[0];
10178
 
10179
        if (btState == 0)       // All instances?
10180
        {
10181
            int bst = bt->getNumberInstances();
10182
 
10183
            for (int i = 0; i < bst; i++)
10184
            {
10185
                string c = bt->getText(i);
300 andreas 10186
                sendCustomEvent(i + 1, (int)c.length(), 0, c, 1001, bt->getChannelPort(), bt->getChannelNumber());
333 andreas 10187
#if TESTMODE == 1
10188
                if (_gTestMode)
10189
                    _gTestMode->setResult(c);
10190
#endif
110 andreas 10191
            }
10192
        }
10193
        else
10194
        {
10195
            string c = bt->getText(btState-1);
300 andreas 10196
            sendCustomEvent(btState, (int)c.length(), 0, c, 1001, bt->getChannelPort(), bt->getChannelNumber());
333 andreas 10197
#if TESTMODE == 1
10198
            if (_gTestMode)
10199
                _gTestMode->setResult(c);
10200
#endif
110 andreas 10201
        }
10202
    }
334 andreas 10203
#if TESTMODE == 1
10204
    setAllDone();
10205
#endif
110 andreas 10206
}
10207
 
97 andreas 10208
/*
104 andreas 10209
 * Set button state legacy unicode text command.
10210
 *
10211
 * Set Unicode text in the legacy G4 format. For the ^UNI command, the Unicode
10212
 * text is sent as ASCII-HEX nibbles.
10213
 */
10214
void TPageManager::doUNI(int port, vector<int>& channels, vector<string>& pars)
10215
{
10216
    DECL_TRACER("TPageManager::doUNI(int port, vector<int>& channels, vector<string>& pars)");
10217
 
10218
    if (pars.size() < 1)
10219
    {
10220
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
331 andreas 10221
#if TESTMODE == 1
334 andreas 10222
        setAllDone();
331 andreas 10223
#endif
104 andreas 10224
        return;
10225
    }
10226
 
10227
    TError::clear();
333 andreas 10228
    int btState = atoi(pars[0].c_str()) - 1;
104 andreas 10229
    string text;
10230
 
361 andreas 10231
    // Unicode is the stadard character set used by Windows internally. It
10232
    // consists of 16 bit unsiged numbers. This can't be transported into a
10233
    // standard character string because a NULL byte means end of string.
10234
    // Therefor we must convert it to UFT-8.
104 andreas 10235
    if (pars.size() > 1)
10236
    {
10237
        string byte;
361 andreas 10238
        std::wstring uni;
104 andreas 10239
        size_t pos = 0;
10240
 
10241
        while (pos < pars[1].length())
10242
        {
361 andreas 10243
            byte = pars[1].substr(pos, 4);
10244
            wchar_t ch = (char)strtol(byte.c_str(), NULL, 16);
10245
            uni += ch;
10246
            pos += 4;
104 andreas 10247
        }
361 andreas 10248
 
10249
        text = UnicodeToUTF8(uni);
104 andreas 10250
    }
10251
 
193 andreas 10252
    vector<TMap::MAP_T> map = findButtons(port, channels);
104 andreas 10253
 
10254
    if (TError::isError() || map.empty())
331 andreas 10255
    {
10256
#if TESTMODE == 1
334 andreas 10257
        setAllDone();
331 andreas 10258
#endif
104 andreas 10259
        return;
331 andreas 10260
    }
104 andreas 10261
 
10262
    vector<Button::TButton *> buttons = collectButtons(map);
10263
 
10264
    if (buttons.size() > 0)
10265
    {
10266
        vector<Button::TButton *>::iterator mapIter;
10267
 
10268
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10269
        {
10270
            Button::TButton *bt = *mapIter;
10271
 
331 andreas 10272
#if TESTMODE == 1
333 andreas 10273
            bool res = bt->setText(text, btState);
104 andreas 10274
 
333 andreas 10275
            if (_gTestMode)
10276
                _gTestMode->setResult(bt->getText(btState < 0 ? 0 : btState));
331 andreas 10277
 
333 andreas 10278
            __success = res;
10279
#else
10280
            bt->setText(text, btState);
331 andreas 10281
#endif
104 andreas 10282
        }
10283
    }
334 andreas 10284
#if TESTMODE == 1
10285
    setDone();
10286
#endif
104 andreas 10287
}
10288
 
10289
void TPageManager::doUTF(int port, vector<int>& channels, vector<string>& pars)
10290
{
10291
    DECL_TRACER("TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)");
10292
 
10293
    if (pars.size() < 1)
10294
    {
10295
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
10296
        return;
10297
    }
10298
 
10299
    TError::clear();
10300
    int btState = atoi(pars[0].c_str());
10301
    string text;
10302
 
10303
    if (pars.size() > 1)
150 andreas 10304
    {
10305
        for (size_t i = 1; i < pars.size(); ++i)
10306
        {
10307
            if (i > 1)
10308
                text += ",";
104 andreas 10309
 
150 andreas 10310
            text += pars[i];
10311
        }
10312
    }
10313
 
193 andreas 10314
    vector<TMap::MAP_T> map = findButtons(port, channels);
104 andreas 10315
 
10316
    if (TError::isError() || map.empty())
10317
        return;
10318
 
10319
    vector<Button::TButton *> buttons = collectButtons(map);
10320
 
10321
    if (buttons.size() > 0)
10322
    {
10323
        vector<Button::TButton *>::iterator mapIter;
10324
 
10325
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10326
        {
10327
            Button::TButton *bt = *mapIter;
10328
 
10329
            if (btState == 0)       // All instances?
10330
            {
10331
                int bst = bt->getNumberInstances();
10332
 
10333
                for (int i = 0; i < bst; i++)
10334
                    bt->setText(text, i);
10335
            }
10336
            else
10337
                bt->setText(text, btState - 1);
10338
        }
10339
    }
10340
}
111 andreas 10341
 
361 andreas 10342
/**
10343
 * Simulates a touch/release/pulse at the given coordinate. If the push event
10344
 * is less then 0 or grater than 2 the command is ignored. It is also ignored
10345
 * if the x and y coordinate is out of range. The range must be between 0 and
10346
 * the maximum with and height.
10347
 */
148 andreas 10348
void TPageManager::doVTP (int, vector<int>&, vector<string>& pars)
10349
{
10350
    DECL_TRACER("TPageManager::doVTP (int, vector<int>&, vector<string>& pars)");
10351
 
10352
    if (pars.size() < 3)
10353
    {
10354
        MSG_ERROR("Expected 3 parameters but got only " << pars.size() << " parameters!");
10355
        return;
10356
    }
10357
 
10358
    int pushType = atoi(pars[0].c_str());
10359
    int x = atoi(pars[1].c_str());
10360
    int y = atoi(pars[2].c_str());
10361
 
10362
    if (pushType < 0 || pushType > 2)
10363
    {
10364
        MSG_ERROR("Invalid push type " << pushType << ". Ignoring command!");
10365
        return;
10366
    }
10367
 
217 andreas 10368
    if (x < 0 || x > mTSettings->getWidth() || y < 0 || y > mTSettings->getHeight())
148 andreas 10369
    {
10370
        MSG_ERROR("Illegal coordinates " << x << " x " << y << ". Ignoring command!");
10371
        return;
10372
    }
10373
 
10374
    if (pushType == 0 || pushType == 2)
10375
        mouseEvent(x, y, true);
10376
 
10377
    if (pushType == 1 || pushType == 2)
10378
        mouseEvent(x, y, false);
10379
}
10380
 
400 andreas 10381
 
111 andreas 10382
/**
10383
 * Set the keyboard passthru.
10384
 */
10385
void TPageManager::doKPS(int, vector<int>&, vector<string>& pars)
10386
{
10387
    DECL_TRACER("TPageManager::doKPS(int, vector<int>&, vector<string>& pars)");
10388
 
10389
    if (pars.size() < 1)
10390
    {
10391
        MSG_ERROR("Got no parameter. Ignoring command!");
10392
        return;
10393
    }
10394
 
10395
    int state = atoi(pars[0].c_str());
10396
 
10397
    if (state == 0)
10398
        mPassThrough = false;
10399
    else if (state == 5)
10400
        mPassThrough = true;
10401
}
10402
 
400 andreas 10403
void TPageManager::doVKS(int, vector<int>&, vector<string>& pars)
111 andreas 10404
{
400 andreas 10405
    DECL_TRACER("TPageManager::doVKS(int, vector<int>&, vector<string>& pars)");
111 andreas 10406
 
10407
    if (pars.size() < 1)
10408
    {
10409
        MSG_ERROR("Got no parameter. Ignoring command!");
10410
        return;
10411
    }
10412
 
10413
    if (_sendVirtualKeys)
10414
        _sendVirtualKeys(pars[0]);
10415
}
10416
 
400 andreas 10417
void TPageManager::doLPB(int port, vector<int>& channels, vector<string>& pars)
10418
{
10419
    DECL_TRACER("TPageManager::doLPB(int port, vector<int>& channels, vector<string>& pars)");
10420
 
10421
    if (pars.size() < 1)
10422
        return;
10423
 
10424
    TError::clear();
10425
    string passwd = pars[0];
10426
    vector<TMap::MAP_T> map = findButtons(port, channels);
10427
 
10428
    if (TError::isError() || map.empty())
10429
        return;
10430
 
10431
    vector<Button::TButton *> buttons = collectButtons(map);
10432
 
10433
    if (buttons.size() > 0)
10434
    {
10435
        vector<Button::TButton *>::iterator mapIter;
10436
 
10437
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10438
        {
10439
            Button::TButton *bt = *mapIter;
10440
            bt->setUserName(passwd);
10441
        }
10442
    }
10443
}
10444
 
401 andreas 10445
void TPageManager::doLPC(int, vector<int>&, vector<string>&)
400 andreas 10446
{
401 andreas 10447
    DECL_TRACER("TPageManager::doLPC(int, vector<int>&, vector<string>&)");
400 andreas 10448
 
10449
    TConfig::clearUserPasswords();
10450
}
10451
 
10452
void TPageManager::doLPR(int, vector<int>&, vector<string>& pars)
10453
{
10454
    DECL_TRACER("TPageManager::doLPR(int, vector<int>&, vector<string>& pars)");
10455
 
10456
    if (pars.size() < 1)
10457
        return;
10458
 
10459
    string user = pars[0];
10460
    TConfig::clearUserPassword(user);
10461
}
10462
 
10463
void TPageManager::doLPS(int, vector<int>&, vector<string>& pars)
10464
{
10465
    DECL_TRACER("TPageManager::doLPS(int, vector<int>&, vector<string>& pars)");
10466
 
10467
    if (pars.size() < 2)
10468
        return;
10469
 
10470
    string user = pars[0];
10471
    string password;
10472
 
10473
    // In case the password contains one or more comma (,), the password is
10474
    // splitted. The following loop concatenates the password into one. Because
10475
    // the comma is lost, we must add it again.
10476
    for (size_t i = 0; i < pars.size(); ++i)
10477
    {
10478
        if (i > 0)
10479
            password += ",";
10480
 
10481
        password += pars[i];
10482
    }
10483
 
10484
    TConfig::setUserPassword(user, password);
10485
}
10486
 
104 andreas 10487
/*
400 andreas 10488
 * Set the page flip password. @PWD sets the level 1 password only.
10489
 */
10490
void TPageManager::doAPWD(int, vector<int>&, vector<string>& pars)
10491
{
10492
    DECL_TRACER("TPageManager::doPWD(int port, vector<int>&, vector<string>& pars)");
10493
 
10494
    if (pars.size() < 1)
10495
    {
10496
        MSG_ERROR("Got less then 1 parameter!");
10497
        return;
10498
    }
10499
 
10500
    string password;
10501
    // In case the password contains one or more comma (,), the password is
10502
    // splitted. The following loop concatenates the password into one. Because
10503
    // the comma is lost, we must add it again.
10504
    for (size_t i = 0; i < pars.size(); ++i)
10505
    {
10506
        if (i > 0)
10507
            password += ",";
10508
 
10509
        password += pars[i];
10510
    }
10511
 
10512
    TConfig::savePassword1(password);
10513
}
10514
 
10515
/*
10516
 * Set the page flip password. Password level is required and must be 1 - 4
10517
 */
10518
void TPageManager::doPWD(int, vector<int>&, vector<string>& pars)
10519
{
10520
    DECL_TRACER("TPageManager::doPWD(int, vector<int>&, vector<string>& pars)");
10521
 
10522
    if (pars.size() < 2)
10523
    {
10524
        MSG_ERROR("Got less then 2 parameters!");
10525
        return;
10526
    }
10527
 
10528
    int pwIdx = atoi(pars[0].c_str());
10529
    string password;
10530
    // In case the password contains one or more comma (,), the password is
10531
    // splitted. The following loop concatenates the password into one. Because
10532
    // the comma is lost, we must add it again.
10533
    for (size_t i = 1; i < pars.size(); ++i)
10534
    {
10535
        if (i > 1)
10536
            password += ",";
10537
 
10538
        password += pars[i];
10539
    }
10540
 
10541
    switch(pwIdx)
10542
    {
10543
        case 1: TConfig::savePassword1(password); break;
10544
        case 2: TConfig::savePassword2(password); break;
10545
        case 3: TConfig::savePassword3(password); break;
10546
        case 4: TConfig::savePassword4(password); break;
10547
    }
10548
}
10549
 
10550
/*
97 andreas 10551
 * Set the bitmap of a button to use a particular resource.
10552
 * Syntax:
10553
 *    "'^BBR-<vt addr range>,<button states range>,<resource name>'"
10554
 * Variable:
10555
 *    variable text address range = 1 - 4000.
10556
 *    button states range = 1 - 256 for multi-state buttons (0 = All states, for General buttons 1 = Off state and 2 = On state).
10557
 *    resource name = 1 - 50 ASCII characters.
10558
 * Example:
10559
 *    SEND_COMMAND Panel,"'^BBR-700,1,Sports_Image'"
10560
 *    Sets the resource name of the button to ’Sports_Image’.
10561
 */
21 andreas 10562
void TPageManager::doBBR(int port, vector<int>& channels, vector<string>& pars)
10563
{
10564
    DECL_TRACER("TPageManager::doBBR(int port, vector<int>& channels, vector<string>& pars)");
10565
 
10566
    if (pars.size() < 2)
10567
    {
10568
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
10569
        return;
10570
    }
10571
 
10572
    TError::clear();
10573
    int btState = atoi(pars[0].c_str());
10574
    string resName = pars[1];
10575
 
193 andreas 10576
    vector<TMap::MAP_T> map = findButtons(port, channels);
21 andreas 10577
 
10578
    if (TError::isError() || map.empty())
10579
        return;
10580
 
10581
    vector<Button::TButton *> buttons = collectButtons(map);
10582
 
83 andreas 10583
    if (buttons.size() > 0)
21 andreas 10584
    {
83 andreas 10585
        vector<Button::TButton *>::iterator mapIter;
21 andreas 10586
 
83 andreas 10587
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
21 andreas 10588
        {
83 andreas 10589
            Button::TButton *bt = *mapIter;
252 andreas 10590
//            setButtonCallbacks(bt);
21 andreas 10591
 
83 andreas 10592
            if (btState == 0)       // All instances?
10593
            {
10594
                int bst = bt->getNumberInstances();
10595
                MSG_DEBUG("Setting BBR on all " << bst << " instances...");
10596
 
10597
                for (int i = 0; i < bst; i++)
10598
                    bt->setResourceName(resName, i);
10599
            }
10600
            else
10601
                bt->setResourceName(resName, btState - 1);
97 andreas 10602
 
10603
            if (bt->isVisible())
10604
                bt->refresh();
99 andreas 10605
            else if (_setVisible)
10606
                _setVisible(bt->getHandle(), false);
21 andreas 10607
        }
10608
    }
10609
}
10610
 
97 andreas 10611
/*
10612
 * Add new resources
10613
 * Adds any and all resource parameters by sending embedded codes and data.
10614
 * Since the embedded codes are preceded by a '%' character, any '%' character
10615
 * contained in* the URL must be escaped with a second '%' character (see
10616
 * example).
10617
 * The file name field (indicated by a %F embedded code) may contain special
10618
 * escape sequences as shown in the ^RAF, ^RMF.
10619
 * Syntax:
10620
 *    "'^RAF-<resource name>,<data>'"
10621
 * Variables:
10622
 *    resource name = 1 - 50 ASCII characters.
10623
 *    data = Refers to the embedded codes, see the ^RAF, ^RMF.
10624
 * Example:
10625
 *    SEND_COMMAND Panel,"'^RAF-New Image,%P0%HAMX.COM%ALab/Test%%5Ffile%Ftest.jpg'"
10626
 *    Adds a new resource.
10627
 *    The resource name is ’New Image’
10628
 *    %P (protocol) is an HTTP
10629
 *    %H (host name) is AMX.COM
10630
 *    %A (file path) is Lab/Test_f ile
10631
 *    %F (file name) is test.jpg.
10632
 *    Note that the %%5F in the file path is actually encoded as %5F.
10633
 */
10634
void TPageManager::doRAF(int, vector<int>&, vector<string>& pars)
10635
{
10636
    DECL_TRACER("TPageManager::doRAF(int port, vector<int>& channels, vector<string>& pars)");
10637
 
10638
    if (pars.size() < 2)
10639
    {
10640
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
10641
        return;
10642
    }
10643
 
10644
    string name = pars[0];
10645
    string data = pars[1];
10646
 
10647
    vector<string> parts = StrSplit(data, "%");
10648
    RESOURCE_T res;
10649
 
10650
    if (parts.size() > 0)
10651
    {
10652
        vector<string>::iterator sIter;
10653
 
10654
        for (sIter = parts.begin(); sIter != parts.end(); sIter++)
10655
        {
10656
            const char *s = sIter->c_str();
10657
            string ss = *sIter;
10658
            MSG_DEBUG("Parsing \"" << ss << "\" with token << " << ss[0]);
10659
 
10660
            switch(*s)
10661
            {
10662
                case 'P':
10663
                    if (*(s+1) == '0')
10664
                        res.protocol = "HTTP";
10665
                    else
10666
                        res.protocol = "FTP";
10667
                    break;
10668
 
10669
                case 'U': res.user = sIter->substr(1); break;
10670
                case 'S': res.password = sIter->substr(1); break;
10671
                case 'H': res.host = sIter->substr(1); break;
10672
                case 'F': res.file = sIter->substr(1); break;
10673
                case 'A': res.path = sIter->substr(1); break;
10674
                case 'R': res.refresh = atoi(sIter->substr(1).c_str()); break;
10675
 
10676
                default:
10677
                    MSG_WARNING("Option " << sIter->at(0) << " is currently not implemented!");
10678
            }
10679
        }
10680
 
10681
        if (gPrjResources)
10682
            gPrjResources->addResource(name, res.protocol, res.host, res.path, res.file, res.user, res.password, res.refresh);
10683
    }
10684
}
10685
 
111 andreas 10686
void TPageManager::doRFR(int, vector<int>&, vector<string>& pars)
97 andreas 10687
{
10688
    DECL_TRACER("TPageManager::doRFR(int port, vector<int>& channels, vector<string>& pars)");
10689
 
10690
    if (pars.size() < 1)
10691
    {
10692
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
10693
        return;
10694
    }
10695
 
10696
    string name = pars[0];
193 andreas 10697
    vector<TMap::MAP_T> map = findButtonByName(name);
97 andreas 10698
 
10699
    if (TError::isError() || map.empty())
10700
        return;
10701
 
10702
    vector<Button::TButton *> buttons = collectButtons(map);
10703
 
10704
    if (buttons.size() > 0)
10705
    {
10706
        vector<Button::TButton *>::iterator mapIter;
10707
 
10708
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10709
        {
10710
            Button::TButton *bt = *mapIter;
10711
 
10712
            if (bt->isVisible())
10713
            {
252 andreas 10714
//                setButtonCallbacks(bt);
97 andreas 10715
                bt->refresh();
10716
            }
10717
        }
10718
    }
10719
}
10720
 
10721
/*
10722
 * Modify an existing resource
10723
 *
10724
 * Modifies any and all resource parameters by sending embedded codes and data.
10725
 * Since the embedded codes are preceded by a '%' character, any '%' character
10726
 * contained in the URL must be escaped with a second '%' character (see
10727
 * example).
10728
 * The file name field (indicated by a %F embedded code) may contain special
10729
 * escape sequences as shown in the ^RAF.
10730
 *
10731
 * Syntax:
10732
 * "'^RMF-<resource name>,<data>'"
10733
 * Variables:
10734
 *   • resource name = 1 - 50 ASCII characters
10735
 *   • data = Refers to the embedded codes, see the ^RAF, ^RMF.
10736
 * Example:
10737
 *   SEND_COMMAND Panel,"'^RMF-Sports_Image,%ALab%%5FTest/Images%Ftest.jpg'"
10738
 * Changes the resource ’Sports_Image’ file name to ’test.jpg’ and the path to
10739
 * ’Lab_Test/Images’.
10740
 * Note that the %%5F in the file path is actually encoded as %5F.
10741
 */
22 andreas 10742
void TPageManager::doRMF(int, vector<int>&, vector<string>& pars)
21 andreas 10743
{
10744
    DECL_TRACER("TPageManager::doRMF(int port, vector<int>& channels, vector<string>& pars)");
10745
 
10746
    if (pars.size() < 2)
10747
    {
10748
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
10749
        return;
10750
    }
10751
 
10752
    string name = pars[0];
10753
    string data = pars[1];
10754
 
10755
    vector<string> parts = StrSplit(data, "%");
10756
    RESOURCE_T res;
10757
 
83 andreas 10758
    if (parts.size() > 0)
21 andreas 10759
    {
83 andreas 10760
        vector<string>::iterator sIter;
21 andreas 10761
 
83 andreas 10762
        for (sIter = parts.begin(); sIter != parts.end(); sIter++)
21 andreas 10763
        {
83 andreas 10764
            const char *s = sIter->c_str();
10765
            string ss = *sIter;
10766
            MSG_DEBUG("Parsing \"" << ss << "\" with token << " << ss[0]);
21 andreas 10767
 
83 andreas 10768
            switch(*s)
10769
            {
10770
                case 'P':
10771
                    if (*(s+1) == '0')
10772
                        res.protocol = "HTTP";
10773
                    else
10774
                        res.protocol = "FTP";
10775
                break;
21 andreas 10776
 
83 andreas 10777
                case 'U': res.user = sIter->substr(1); break;
10778
                case 'S': res.password = sIter->substr(1); break;
10779
                case 'H': res.host = sIter->substr(1); break;
10780
                case 'F': res.file = sIter->substr(1); break;
10781
                case 'A': res.path = sIter->substr(1); break;
10782
                case 'R': res.refresh = atoi(sIter->substr(1).c_str()); break;
10783
 
10784
                default:
10785
                    MSG_WARNING("Option " << sIter->at(0) << " is currently not implemented!");
10786
            }
21 andreas 10787
        }
83 andreas 10788
 
10789
        if (gPrjResources)
10790
            gPrjResources->setResource(name, res.protocol, res.host, res.path, res.file, res.user, res.password, res.refresh);
21 andreas 10791
    }
10792
}
62 andreas 10793
 
10794
/**
111 andreas 10795
 * Change the refresh rate for a given resource.
10796
 */
10797
void TPageManager::doRSR(int, vector<int>&, vector<string>& pars)
10798
{
10799
    DECL_TRACER("TPageManager::doRSR(int, vector<int>&, vector<string>& pars)");
10800
 
10801
    if (pars.size() < 2)
10802
    {
10803
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
10804
        return;
10805
    }
10806
 
10807
    string resName = pars[0];
10808
    int resRefresh = atoi(pars[1].c_str());
10809
 
10810
    if (!gPrjResources)
10811
    {
10812
        MSG_ERROR("Missing the resource module. Ignoring command!");
10813
        return;
10814
    }
10815
 
10816
    RESOURCE_T res = gPrjResources->findResource(resName);
10817
 
10818
    if (res.name.empty() || res.refresh == resRefresh)
10819
        return;
10820
 
10821
    gPrjResources->setResource(resName, res.protocol, res.host, res.path, res.file, res.user, res.password, resRefresh);
10822
}
10823
 
10824
/**
62 andreas 10825
 * @brief TPageManager::doAKB - Pop up the keyboard icon
10826
 * Pop up the keyboard icon and initialize the text string to that specified.
10827
 * Keyboard string is set to null on power up and is stored until power is lost.
10828
 * The Prompt Text is optional.
10829
 */
10830
void TPageManager::doAKB(int, vector<int>&, vector<string> &pars)
10831
{
10832
    DECL_TRACER("TPageManager::doAKB(int, vector<int>&, vector<string> &pars)");
10833
 
10834
    if (pars.size() < 1)
10835
    {
10836
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
10837
        return;
10838
    }
10839
 
10840
    string initText = pars[0];
10841
    string promptText;
10842
 
10843
    if (pars.size() > 1)
10844
        promptText = pars[1];
10845
 
63 andreas 10846
    if (initText.empty())
10847
        initText = mAkbText;
10848
    else
10849
        mAkbText = initText;
62 andreas 10850
 
10851
    if (_callKeyboard)
63 andreas 10852
        _callKeyboard(initText, promptText, false);
62 andreas 10853
}
10854
 
63 andreas 10855
/**
10856
 * Pop up the keyboard icon and initialize the text string to that
10857
 * specified.
10858
 */
62 andreas 10859
void TPageManager::doAKEYB(int port, vector<int>& channels, vector<string>& pars)
10860
{
10861
    DECL_TRACER("TPageManager::doAKEYB(int port, vector<int>& channels, vector<string>& pars)");
10862
 
10863
    doAKB(port, channels, pars);
10864
}
10865
 
63 andreas 10866
void TPageManager::doAKEYP(int port, std::vector<int>& channels, std::vector<std::string>& pars)
10867
{
10868
    DECL_TRACER("TPageManager::doAKEYP(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
10869
 
10870
    doAKP(port, channels, pars);
10871
}
10872
 
62 andreas 10873
/**
63 andreas 10874
 * Remove keyboard or keypad that was displayed using 'AKEYB', 'AKEYP', 'PKEYP',
10875
 * @AKB, @AKP, @PKP, @EKP, or @TKP commands.
10876
 */
10877
void TPageManager::doAKEYR(int, vector<int>&, vector<string>&)
10878
{
10879
    DECL_TRACER("TPageManager::doAKEYR(int, vector<int>&, vector<string>&)");
10880
 
10881
    if (_callResetKeyboard)
10882
        _callResetKeyboard();
10883
}
10884
 
10885
/**
62 andreas 10886
 * @brief TPageManager::doAKP - Pop up the keypad icon
10887
 * Pop up the keypad icon and initialize the text string to that specified.
10888
 * Keypad string is set to null on power up and is stored until power is lost.
10889
 * The Prompt Text is optional.
10890
 */
10891
void TPageManager::doAKP(int, std::vector<int>&, std::vector<std::string> &pars)
10892
{
10893
    DECL_TRACER("TPageManager::doAKP(int, vector<int>&, vector<string> &pars)");
10894
 
10895
    if (pars.size() < 1)
10896
    {
10897
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
10898
        return;
10899
    }
10900
 
10901
    string initText = pars[0];
10902
    string promptText;
10903
 
10904
    if (pars.size() > 1)
10905
        promptText = pars[1];
10906
 
63 andreas 10907
    if (initText.empty())
10908
        initText = mAkpText;
10909
    else
10910
        mAkpText = initText;
62 andreas 10911
 
10912
    if (_callKeypad)
63 andreas 10913
        _callKeypad(initText, promptText, false);
62 andreas 10914
}
10915
 
63 andreas 10916
/**
10917
 * Remove keyboard or keypad that was displayed using 'AKEYB', 'AKEYP', 'PKEYP',
10918
 * @AKB, @AKP, @PKP, @EKP, or @TKP commands.
10919
 */
10920
void TPageManager::doAKR(int port, vector<int>& channels, vector<string>& pars)
62 andreas 10921
{
63 andreas 10922
    DECL_TRACER("TPageManager::doAKR(int, vector<int>&, vector<string>&)");
62 andreas 10923
 
63 andreas 10924
    doAKEYR(port, channels, pars);
62 andreas 10925
}
10926
 
108 andreas 10927
void TPageManager::doABEEP(int, std::vector<int>&, vector<string>&)
10928
{
10929
    DECL_TRACER("TPageManager::doBEEP(int, std::vector<int>&, vector<string>&)");
10930
 
10931
    if (!_playSound)
334 andreas 10932
    {
10933
#if TESTMODE == 1
10934
        setAllDone();
10935
#endif
108 andreas 10936
        return;
334 andreas 10937
    }
108 andreas 10938
 
10939
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getSingleBeepSound();
10940
    TValidateFile vf;
10941
 
326 andreas 10942
    if (vf.isValidFile(snd))
108 andreas 10943
        _playSound(snd);
326 andreas 10944
#if TESTMODE == 1
10945
    else
10946
    {
10947
        MSG_PROTOCOL("Sound file invalid!");
334 andreas 10948
        setAllDone();
326 andreas 10949
    }
10950
#endif
108 andreas 10951
}
10952
 
10953
void TPageManager::doADBEEP(int, std::vector<int>&, vector<string>&)
10954
{
10955
    DECL_TRACER("TPageManager::doDBEEP(int, std::vector<int>&, vector<string>&)");
10956
 
10957
    if (!_playSound)
10958
        return;
10959
 
10960
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getDoubleBeepSound();
10961
    TValidateFile vf;
10962
 
326 andreas 10963
    if (vf.isValidFile(snd))
108 andreas 10964
        _playSound(snd);
326 andreas 10965
#if TESTMODE == 1
10966
    else
10967
    {
10968
        MSG_PROTOCOL("Sound file invalid!");
334 andreas 10969
        setAllDone();
326 andreas 10970
    }
10971
#endif
108 andreas 10972
}
10973
 
71 andreas 10974
void TPageManager::doBEEP(int, std::vector<int>&, vector<string>&)
10975
{
10976
    DECL_TRACER("TPageManager::doBEEP(int, std::vector<int>&, vector<string>&)");
10977
 
10978
    if (!_playSound)
326 andreas 10979
    {
10980
#if TESTMODE == 1
10981
        MSG_PROTOCOL("Method \"playSound()\" not initialized!");
334 andreas 10982
        setAllDone();
326 andreas 10983
#endif
71 andreas 10984
        return;
326 andreas 10985
    }
71 andreas 10986
 
10987
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getSingleBeepSound();
10988
    TValidateFile vf;
108 andreas 10989
    TSystemSound sysSound(TConfig::getSystemPath(TConfig::SOUNDS));
71 andreas 10990
 
326 andreas 10991
    if (sysSound.getSystemSoundState() && vf.isValidFile(snd))
71 andreas 10992
        _playSound(snd);
326 andreas 10993
#if TESTMODE == 1
10994
    else
10995
    {
10996
        if (!sysSound.getSystemSoundState())
10997
        {
10998
            MSG_PROTOCOL("Sound state disabled!")
10999
        }
11000
        else
11001
        {
11002
            MSG_PROTOCOL("Sound file invalid!");
11003
        }
11004
 
334 andreas 11005
        setAllDone();
326 andreas 11006
    }
11007
#endif
71 andreas 11008
}
11009
 
11010
void TPageManager::doDBEEP(int, std::vector<int>&, vector<string>&)
11011
{
11012
    DECL_TRACER("TPageManager::doDBEEP(int, std::vector<int>&, vector<string>&)");
11013
 
11014
    if (!_playSound)
11015
        return;
11016
 
11017
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getDoubleBeepSound();
11018
    TValidateFile vf;
108 andreas 11019
    TSystemSound sysSound(TConfig::getSystemPath(TConfig::SOUNDS));
71 andreas 11020
 
326 andreas 11021
    if (sysSound.getSystemSoundState() && vf.isValidFile(snd))
71 andreas 11022
        _playSound(snd);
326 andreas 11023
#if TESTMODE == 1
11024
    else
11025
    {
11026
        if (!sysSound.getSystemSoundState())
11027
        {
11028
            MSG_PROTOCOL("Sound state disabled!")
11029
        }
11030
        else
11031
        {
11032
            MSG_PROTOCOL("Sound file invalid!");
11033
        }
11034
 
334 andreas 11035
        setAllDone();
326 andreas 11036
    }
11037
#endif
71 andreas 11038
}
11039
 
63 andreas 11040
/**
11041
 * @brief Pop up the keypad icon and initialize the text string to that specified.
11042
 * Keypad string is set to null on power up and is stored until power is lost.
11043
 * The Prompt Text is optional.
11044
 */
62 andreas 11045
void TPageManager::doEKP(int port, std::vector<int>& channels, std::vector<std::string>& pars)
11046
{
11047
    DECL_TRACER("TPageManager::doEKP(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
11048
 
11049
    doAKP(port, channels, pars);
11050
}
63 andreas 11051
 
11052
/**
11053
 * @brief Present a private keyboard.
11054
 * Pops up the keyboard icon and initializes the text string to that specified.
11055
 * Keyboard displays a '*' instead of the letters typed. The Prompt Text is optional.
11056
 */
11057
void TPageManager::doPKB(int, vector<int>&, vector<string>& pars)
11058
{
11059
    DECL_TRACER("TPageManager::doPKB(int, vector<int>&, vector<string>& pars)");
11060
 
11061
    if (pars.size() < 1)
11062
    {
11063
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
11064
        return;
11065
    }
11066
 
11067
    string initText = pars[0];
11068
    string promptText;
11069
 
11070
    if (pars.size() > 1)
11071
        promptText = pars[1];
11072
 
11073
    if (_callKeyboard)
11074
        _callKeyboard(initText, promptText, true);
11075
}
11076
 
11077
/**
11078
 * @brief Present a private keypad.
11079
 * Pops up the keypad icon and initializes the text string to that specified.
11080
 * Keypad displays a '*' instead of the numbers typed. The Prompt Text is optional.
11081
 */
11082
void TPageManager::doPKP(int, vector<int>&, vector<string>& pars)
11083
{
11084
    DECL_TRACER("TPageManager::doPKP(int, vector<int>&, vector<string>& pars)");
11085
 
11086
    if (pars.size() < 1)
11087
    {
11088
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
11089
        return;
11090
    }
11091
 
11092
    string initText = pars[0];
11093
    string promptText;
11094
 
11095
    if (pars.size() > 1)
11096
        promptText = pars[1];
11097
 
11098
    if (_callKeypad)
11099
        _callKeypad(initText, promptText, true);
11100
}
11101
 
11102
/**
408 andreas 11103
 * @brief Reset protected password command
11104
 * This command is used to reset the protected setup password to the factory
11105
 * default value.
11106
 */
11107
void TPageManager::doRPP(int, vector<int>&, vector<string>&)
11108
{
11109
    DECL_TRACER("TPageManager::doRPP(int, vector<int>&, vector<string>&)");
11110
 
11111
    TConfig::savePassword1("1988");
11112
}
11113
 
11114
/**
64 andreas 11115
 * Send panel to SETUP page.
11116
 */
11117
void TPageManager::doSetup(int, vector<int>&, vector<string>&)
11118
{
11119
    DECL_TRACER("TPageManager::doSetup(int, vector<int>&, vector<string>&)");
11120
 
11121
    if (_callShowSetup)
11122
        _callShowSetup();
11123
}
11124
 
11125
/**
11126
 * Shut down the App
11127
 */
11128
void TPageManager::doShutdown(int, vector<int>&, vector<string>&)
11129
{
11130
    DECL_TRACER("TPageManager::doShutdown(int, vector<int>&, vector<string>&)");
11131
 
97 andreas 11132
    MSG_PROTOCOL("Received shutdown ...");
64 andreas 11133
#ifdef __ANDROID__
11134
    stopNetworkState();
11135
#endif
11136
    prg_stopped = true;
11137
    killed = true;
11138
 
11139
    if (_shutdown)
11140
        _shutdown();
11141
}
11142
 
82 andreas 11143
void TPageManager::doSOU(int, vector<int>&, vector<string>& pars)
11144
{
11145
    DECL_TRACER("TPageManager::doSOU(int, vector<int>&, vector<string>& pars)");
11146
 
11147
    if (pars.size() < 1)
11148
    {
11149
        MSG_ERROR("@SOU: Expecting a sound file as parameter! Ignoring command.");
11150
        return;
11151
    }
11152
 
11153
    if (!_playSound)
11154
    {
11155
        MSG_ERROR("@SOU: Missing sound module!");
11156
        return;
11157
    }
11158
 
165 andreas 11159
    if (pars[0].empty() || strCaseCompare(pars[0], "None") == 0)
11160
        return;
11161
 
82 andreas 11162
    _playSound(pars[0]);
11163
}
11164
 
326 andreas 11165
void TPageManager::doMUT(int, vector<int>&, vector<string>& pars)
11166
{
11167
    DECL_TRACER("TPageManager::doMUT(int, vector<int>&, vector<string>& pars)");
11168
 
11169
    if (pars.size() < 1)
11170
    {
11171
        MSG_ERROR("^MUT: Expecting a state parameter! Ignoring command.");
11172
        return;
11173
    }
11174
 
11175
    bool mute = 0;
11176
 
11177
    if (pars[0] == "0")
11178
        mute = false;
11179
    else
11180
        mute = true;
11181
 
11182
    TConfig::setMuteState(mute);
11183
#if TESTMODE == 1
327 andreas 11184
    if (_gTestMode)
11185
    {
11186
        bool st = TConfig::getMuteState();
11187
        _gTestMode->setResult(st ? "1" : "0");
11188
    }
11189
 
326 andreas 11190
    __success = true;
334 andreas 11191
    setAllDone();
326 andreas 11192
#endif
11193
}
11194
 
64 andreas 11195
/**
63 andreas 11196
 * @brief Present a telephone keypad.
11197
 * Pops up the keypad icon and initializes the text string to that specified.
11198
 * The Prompt Text is optional.
11199
 */
11200
void TPageManager::doTKP(int port, vector<int>& channels, vector<string>& pars)
11201
{
11202
    DECL_TRACER("TPageManager::doTKP(int port, vector<int>& channels, vector<string>& pars)");
11203
 
11204
    // TODO: Implement a real telefone keypad.
11205
    doAKP(port, channels, pars);
11206
}
11207
 
11208
/**
11209
 * Popup the virtual keyboard
11210
 */
123 andreas 11211
void TPageManager::doVKB(int port, vector<int>& channels, vector<string>& pars)
63 andreas 11212
{
123 andreas 11213
    DECL_TRACER("TPageManager::doVKB(int port, vector<int>& channels, vector<string>& pars)");
63 andreas 11214
 
11215
    doAKP(port, channels, pars);
11216
}
129 andreas 11217
#ifndef _NOSIP_
123 andreas 11218
void TPageManager::sendPHN(vector<string>& cmds)
11219
{
11220
    DECL_TRACER("TPageManager::sendPHN(const vector<string>& cmds)");
11221
 
11222
    vector<int> channels;
11223
    doPHN(-1, channels, cmds);
11224
}
11225
 
141 andreas 11226
void TPageManager::actPHN(vector<string>& cmds)
11227
{
11228
    DECL_TRACER("TPageManager::actPHN(const vector<string>& cmds)");
11229
 
11230
    vector<int> channels;
11231
    doPHN(1, channels, cmds);
11232
}
11233
 
140 andreas 11234
void TPageManager::phonePickup(int id)
11235
{
11236
    DECL_TRACER("TPageManager::phonePickup(int id)");
11237
 
11238
    if (id < 0 || id >= 4)
11239
        return;
11240
 
11241
    if (mSIPClient)
11242
        mSIPClient->pickup(id);
11243
}
11244
 
11245
void TPageManager::phoneHangup(int id)
11246
{
11247
    DECL_TRACER("TPageManager::phoneHangup(int id)");
11248
 
11249
    if (id < 0 || id >= 4)
11250
        return;
11251
 
11252
    if (mSIPClient)
11253
        mSIPClient->terminate(id);
11254
}
11255
 
123 andreas 11256
/**
11257
 * @brief Phone commands.
11258
 * The phone commands could come from the master or are send to the master.
11259
 * If the parameter \p port is less then 0 (zero) a command is send to the
11260
 * master. In any other case the command came from the mater.
125 andreas 11261
 *
11262
 * @param port  This is used to signal if the command was sent by the master
11263
 *              or generated from the panel. If ths is less then 0, then the
11264
 *              method was called because of an event happen in the panel.
11265
 *              If this is grater or equal 0, then the event is comming from
11266
 *              the master.
11267
 * @param pars  This are parameters. The first parameter defines the action
11268
 *              to be done. According to the command this parameter may have a
11269
 *              different number of arguments.
123 andreas 11270
 */
11271
void TPageManager::doPHN(int port, vector<int>&, vector<string>& pars)
11272
{
11273
    DECL_TRACER("TPageManager::doPHN(int port, vector<int>&, vector<string>& pars)");
11274
 
11275
    if (pars.size() < 1)
11276
    {
11277
        MSG_ERROR("Expecting at least 1 parameter but got none! Ignoring command.");
11278
        return;
11279
    }
11280
 
11281
    string sCommand;
11282
    string cmd = toUpper(pars[0]);
11283
 
11284
    // Master to panel
11285
    if (port >= 0)
11286
    {
11287
        if (!mSIPClient)
11288
        {
11289
            MSG_ERROR("SIP client class was not initialized!")
11290
            return;
11291
        }
11292
 
11293
        if (cmd == "ANSWER")
11294
        {
11295
            if (pars.size() >= 2)
11296
            {
124 andreas 11297
                int id = atoi(pars[1].c_str());
11298
 
11299
                if (mSIPClient->getSIPState(id) == TSIPClient::SIP_HOLD)
11300
                    mSIPClient->resume(id);
11301
                else
135 andreas 11302
                    mSIPClient->pickup(id);
123 andreas 11303
            }
11304
        }
11305
        else if (cmd == "AUTOANSWER")
11306
        {
11307
            if (pars.size() >= 2)
11308
            {
11309
                if (pars[1].at(0) == '0')
11310
                    mPHNautoanswer = false;
11311
                else
11312
                    mPHNautoanswer = true;
127 andreas 11313
 
11314
                vector<string> cmds;
11315
                cmds = { "AUTOANSWER", to_string(mPHNautoanswer ? 1 : 0) };
128 andreas 11316
                sendPHN(cmds);
123 andreas 11317
            }
11318
        }
11319
        else if (cmd == "CALL")     // Initiate a call
11320
        {
11321
            if (pars.size() >= 2)
127 andreas 11322
                mSIPClient->call(pars[1]);
123 andreas 11323
        }
11324
        else if (cmd == "DTMF")     // Send tone modified codes
11325
        {
127 andreas 11326
            if (pars.size() >= 2)
11327
                mSIPClient->sendDTMF(pars[1]);
123 andreas 11328
        }
11329
        else if (cmd == "HANGUP")   // terminate a call
11330
        {
124 andreas 11331
            if (pars.size() >= 2)
11332
            {
11333
                int id = atoi(pars[1].c_str());
11334
                mSIPClient->terminate(id);
11335
            }
123 andreas 11336
        }
11337
        else if (cmd == "HOLD")     // Hold the line
11338
        {
124 andreas 11339
            if (pars.size() >= 2)
11340
            {
11341
                int id = atoi(pars[1].c_str());
11342
                mSIPClient->hold(id);
11343
            }
123 andreas 11344
        }
128 andreas 11345
        else if (cmd == "LINESTATE") // State of all line
127 andreas 11346
        {
128 andreas 11347
            mSIPClient->sendLinestate();
127 andreas 11348
        }
123 andreas 11349
        else if (cmd == "PRIVACY")  // Set/unset "do not disturb"
11350
        {
128 andreas 11351
            if (pars.size() >= 2)
11352
            {
11353
                bool state = (pars[1].at(0) == '1' ? true : false);
11354
                mSIPClient->sendPrivate(state);
11355
            }
123 andreas 11356
        }
11357
        else if (cmd == "REDIAL")   // Redials the last number
11358
        {
128 andreas 11359
            mSIPClient->redial();
123 andreas 11360
        }
11361
        else if (cmd == "TRANSFER") // Transfer call to provided number
11362
        {
128 andreas 11363
            if (pars.size() >= 3)
11364
            {
11365
                int id = atoi(pars[1].c_str());
11366
                string num = pars[2];
11367
 
11368
                if (mSIPClient->transfer(id, num))
11369
                {
11370
                    vector<string> cmds;
11371
                    cmds.push_back("TRANSFERRED");
11372
                    sendPHN(cmds);
11373
                }
11374
            }
123 andreas 11375
        }
144 andreas 11376
        else if (cmd == "IM")
11377
        {
11378
            if (pars.size() < 3)
11379
                return;
11380
 
11381
            string to = pars[1];
11382
            string msg = pars[2];
11383
            string toUri;
11384
 
11385
            if (to.find("sip:") == string::npos)
11386
                toUri = "sip:";
11387
 
11388
            toUri += to;
11389
 
11390
            if (to.find("@") == string::npos)
11391
                toUri += "@" + TConfig::getSIPproxy();
11392
 
11393
            mSIPClient->sendIM(toUri, msg);
11394
        }
123 andreas 11395
        else if (cmd == "SETUP")    // Some temporary settings
11396
        {
11397
            if (pars.size() < 2)
11398
                return;
11399
 
11400
            if (pars[1] == "DOMAIN" && pars.size() >= 3)
11401
                TConfig::setSIPdomain(pars[2]);
11402
            else if (pars[1] == "DTMFDURATION")
11403
            {
138 andreas 11404
                unsigned int ms = atoi(pars[2].c_str());
11405
                mSIPClient->setDTMFduration(ms);
123 andreas 11406
            }
11407
            else if (pars[1] == "ENABLE")   // (re)register user
11408
            {
11409
                TConfig::setSIPstatus(true);
127 andreas 11410
                mSIPClient->cleanUp();
135 andreas 11411
                mSIPClient->init();
123 andreas 11412
            }
127 andreas 11413
            else if (pars[1] == "DOMAIN" && pars.size() >= 3)
11414
                TConfig::setSIPdomain(pars[2]);
123 andreas 11415
            else if (pars[1] == "PASSWORD" && pars.size() >= 3)
11416
                TConfig::setSIPpassword(pars[2]);
11417
            else if (pars[1] == "PORT" && pars.size() != 3)
11418
                TConfig::setSIPport(atoi(pars[2].c_str()));
11419
            else if (pars[1] == "PROXYADDR" && pars.size() >= 3)
11420
                TConfig::setSIPproxy(pars[2]);
11421
            else if (pars[1] == "STUNADDR" && pars.size() >= 3)
11422
                TConfig::setSIPstun(pars[2]);
11423
            else if (pars[1] == "USERNAME" && pars.size() >= 3)
11424
                TConfig::setSIPuser(pars[2]);
11425
        }
11426
        else
11427
        {
11428
            MSG_ERROR("Unknown command ^PHN-" << cmd << " ignored!");
11429
        }
11430
    }
11431
    else   // Panel to master
11432
    {
11433
        vector<string>::iterator iter;
11434
 
11435
        for (iter = pars.begin(); iter != pars.end(); ++iter)
11436
        {
11437
            if (!sCommand.empty())
11438
                sCommand += ",";
11439
 
11440
            sCommand += *iter;
11441
        }
11442
 
11443
        sendPHNcommand(sCommand);
11444
    }
11445
}
127 andreas 11446
 
11447
void TPageManager::getPHN(int, vector<int>&, vector<string>& pars)
11448
{
11449
    DECL_TRACER("TPageManager::getPHN(int, vector<int>&, vector<string>& pars)");
11450
 
11451
    if (pars.size() < 1)
11452
    {
11453
        MSG_ERROR("Invalid number of arguments!");
11454
        return;
11455
    }
11456
 
11457
    string cmd = pars[0];
11458
 
11459
    if (cmd == "AUTOANSWER")
11460
        sendPHNcommand(cmd + "," + (mPHNautoanswer ? "1" : "0"));
11461
    else if (cmd == "LINESTATE")
11462
    {
11463
        if (!mSIPClient)
11464
            return;
11465
 
138 andreas 11466
        mSIPClient->sendLinestate();
127 andreas 11467
    }
11468
    else if (cmd == "MSGWAITING")
11469
    {
144 andreas 11470
        size_t num = mSIPClient->getNumberMessages();
11471
        sendPHNcommand(cmd + "," + (num > 0 ? "1" : "0") + "," + std::to_string(num) + "0,0,0");
127 andreas 11472
    }
11473
    else if (cmd == "PRIVACY")
11474
    {
138 andreas 11475
        if (mSIPClient->getPrivate())
11476
            sendPHNcommand(cmd + ",1");
11477
        else
11478
            sendPHNcommand(cmd + ",0");
127 andreas 11479
    }
144 andreas 11480
    else if (cmd == "REDIAL")
11481
    {
11482
        if (pars.size() < 2)
11483
            return;
11484
 
11485
        sendPHNcommand(cmd + "," + pars[1]);
11486
    }
127 andreas 11487
    else
11488
    {
11489
        MSG_WARNING("Unknown command " << cmd << " found!");
11490
    }
11491
}
129 andreas 11492
#endif  // _NOSIP_
134 andreas 11493
 
300 andreas 11494
/*
318 andreas 11495
 *  Hide all subpages in a subpage viewer button.
11496
 */
11497
void TPageManager::doSHA(int port, vector<int> &channels, vector<string> &pars)
11498
{
11499
    DECL_TRACER("TPageManager::doSHA(int port, vector<int> &channels, vector<string> &pars)");
11500
 
343 andreas 11501
    Q_UNUSED(pars);
318 andreas 11502
    vector<TMap::MAP_T> map = findButtons(port, channels);
11503
 
11504
    if (TError::isError() || map.empty())
11505
        return;
11506
 
11507
    vector<Button::TButton *> buttons = collectButtons(map);
11508
 
11509
    if (!buttons.empty())
11510
    {
11511
        vector<Button::TButton *>::iterator mapIter;
11512
 
11513
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11514
        {
11515
            Button::TButton *bt = *mapIter;
11516
 
11517
            if (_hideAllSubViewItems)
11518
                _hideAllSubViewItems(bt->getHandle());
11519
        }
11520
    }
11521
}
11522
 
11523
void TPageManager::doSHD(int port, vector<int>& channels, vector<string>& pars)
11524
{
11525
    DECL_TRACER("TPageManager::doSHD(int port, vector<int>& channels, vector<string>& pars)");
11526
 
11527
    if (pars.size() < 1)
11528
        return;
11529
 
11530
    string name = pars[0];
11531
 
11532
    vector<TMap::MAP_T> map = findButtons(port, channels);
11533
 
11534
    if (TError::isError() || map.empty())
11535
        return;
11536
 
11537
    vector<Button::TButton *> buttons = collectButtons(map);
11538
 
11539
    if (!buttons.empty())
11540
    {
11541
        vector<Button::TButton *>::iterator mapIter;
11542
 
11543
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11544
        {
11545
            Button::TButton *bt = *mapIter;
11546
 
11547
            vector<TSubPage *> subviews = createSubViewList(bt->getSubViewID());
11548
 
11549
            if (subviews.empty())
11550
                continue;
11551
 
11552
            vector<TSubPage *>::iterator itSub;
11553
 
11554
            for (itSub = subviews.begin(); itSub != subviews.end(); ++itSub)
11555
            {
11556
                TSubPage *sub = *itSub;
11557
 
11558
                if (sub && sub->getName() == name)
11559
                {
11560
                    if (_hideSubViewItem)
11561
                        _hideSubViewItem(bt->getHandle(), sub->getHandle());
11562
 
11563
                    break;
11564
                }
11565
            }
11566
        }
11567
    }
11568
}
11569
 
11570
void TPageManager::doSPD(int port, vector<int>& channels, vector<string>& pars)
11571
{
11572
    DECL_TRACER("TPageManager::doSPD(int port, vector<int>& channel, vector<string>& pars)");
11573
 
11574
    if (pars.size() < 1)
11575
        return;
11576
 
11577
    TError::clear();
11578
    int padding = atoi(pars[0].c_str());
11579
 
11580
    if (padding < 0 || padding > 100)
11581
        return;
11582
 
11583
    vector<TMap::MAP_T> map = findButtons(port, channels);
11584
 
11585
    if (TError::isError() || map.empty())
11586
        return;
11587
 
11588
    vector<Button::TButton *> buttons = collectButtons(map);
11589
 
11590
    if (!buttons.empty())
11591
    {
11592
        vector<Button::TButton *>::iterator mapIter;
11593
 
11594
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11595
        {
11596
            Button::TButton *bt = *mapIter;
11597
 
11598
            if (_setSubViewPadding)
11599
                _setSubViewPadding(bt->getHandle(), padding);
11600
        }
11601
    }
11602
}
11603
 
11604
/*
300 andreas 11605
 * This command will perform one of three different operations based on the following conditions:
11606
 * 1. If the named subpage is hidden in the set associated with the viewer button it will be shown in the anchor position.
11607
 * 2. If the named subpage is not present in the set it will be added to the set and shown in the anchor position.
11608
 * 3. If the named subpage is already present in the set and is not hidden then the viewer button will move it to the anchor
11609
 * position. The anchor position is the location on the subpage viewer button specified by its weighting. This will either be
11610
 * left, center or right for horizontal subpage viewer buttons or top, center or bottom for vertical subpage viewer buttons.
11611
 * Surrounding subpages are relocated on the viewer button as needed to accommodate the described operations
11612
 */
11613
void TPageManager::doSSH(int port, vector<int> &channels, vector<string> &pars)
11614
{
11615
    DECL_TRACER("TPageManager::doSSH(int port, vector<int> &channels, vector<string> &pars)");
11616
 
11617
    if (pars.size() < 1)
11618
    {
11619
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
11620
        return;
11621
    }
11622
 
11623
    TError::clear();
11624
    string name = pars[0];
11625
    int position = 0;   // optional
11626
    int time = 0;       // optional
11627
 
11628
    if (pars.size() > 1)
11629
        position = atoi(pars[1].c_str());
11630
 
11631
    if (pars.size() > 2)
11632
        time = atoi(pars[2].c_str());
11633
 
11634
    vector<TMap::MAP_T> map = findButtons(port, channels);
11635
 
11636
    if (TError::isError() || map.empty())
11637
        return;
11638
 
11639
    vector<Button::TButton *> buttons = collectButtons(map);
11640
 
11641
    if (!buttons.empty())
11642
    {
11643
        vector<Button::TButton *>::iterator mapIter;
11644
 
11645
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11646
        {
11647
            Button::TButton *bt = *mapIter;
11648
            vector<TSubPage *> subviews = createSubViewList(bt->getSubViewID());
11649
 
11650
            if (subviews.empty() || !bt)
11651
                continue;
11652
 
11653
            vector<TSubPage *>::iterator itSub;
11654
 
11655
            for (itSub = subviews.begin(); itSub != subviews.end(); ++itSub)
11656
            {
11657
                TSubPage *sub = *itSub;
11658
 
11659
                if (sub && sub->getName() == name)
11660
                {
11661
                    if (_showSubViewItem)
11662
                        _showSubViewItem(sub->getHandle(), bt->getHandle(), position, time);
11663
 
11664
                    break;
11665
                }
11666
            }
11667
        }
11668
    }
11669
}
11670
 
318 andreas 11671
void TPageManager::doSTG(int port, vector<int>& channels, vector<string>& pars)
11672
{
11673
    DECL_TRACER("TPageManager::doSTG(int port, vector<int>& channels, vector<string>& pars)");
11674
 
11675
    if (pars.empty())
11676
    {
11677
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
11678
        return;
11679
    }
11680
 
11681
    TError::clear();
11682
    string name = pars[0];
11683
    int position = 0;   // optional
11684
    int time = 0;       // optional
11685
 
11686
    if (pars.size() > 1)
11687
        position = atoi(pars[1].c_str());
11688
 
11689
    if (pars.size() > 2)
11690
        time = atoi(pars[2].c_str());
11691
 
11692
    vector<TMap::MAP_T> map = findButtons(port, channels);
11693
 
11694
    if (TError::isError() || map.empty())
11695
        return;
11696
 
11697
    vector<Button::TButton *> buttons = collectButtons(map);
11698
 
11699
    if (!buttons.empty())
11700
    {
11701
        vector<Button::TButton *>::iterator mapIter;
11702
 
11703
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11704
        {
11705
            Button::TButton *bt = *mapIter;
11706
            vector<TSubPage *> subviews = createSubViewList(bt->getSubViewID());
11707
 
11708
            if (subviews.empty() || !bt)
11709
                continue;
11710
 
11711
            vector<TSubPage *>::iterator itSub;
11712
 
11713
            for (itSub = subviews.begin(); itSub != subviews.end(); ++itSub)
11714
            {
11715
                TSubPage *sub = *itSub;
11716
 
11717
                if (sub && sub->getName() == name)
11718
                {
11719
                    if (_toggleSubViewItem)
11720
                        _toggleSubViewItem(sub->getHandle(), bt->getHandle(), position, time);
11721
 
11722
                    break;
11723
                }
11724
            }
11725
        }
11726
    }
11727
}
11728
 
227 andreas 11729
void TPageManager::doLVD(int port, vector<int> &channels, vector<string> &pars)
225 andreas 11730
{
227 andreas 11731
    DECL_TRACER("TPageManager::doLVD(int port, vector<int> &channels, vector<string> &pars)");
225 andreas 11732
 
11733
    if (pars.size() < 1)
11734
    {
11735
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
11736
        return;
11737
    }
11738
 
11739
    TError::clear();
11740
    string source = pars[0];
11741
    vector<string> configs;
11742
 
11743
    if (pars.size() > 1)
11744
    {
11745
        for (size_t i = 1; i < pars.size(); ++i)
227 andreas 11746
        {
11747
            string low = toLower(pars[i]);
11748
 
11749
            if (low.find_first_of("user=") != string::npos ||
11750
                low.find_first_of("pass=") != string::npos ||
11751
                low.find_first_of("csv=")  != string::npos ||
11752
                low.find_first_of("has_headers=") != string::npos)
11753
            {
11754
                configs.push_back(pars[i]);
11755
            }
11756
        }
225 andreas 11757
    }
11758
 
11759
    vector<TMap::MAP_T> map = findButtons(port, channels);
11760
 
11761
    if (TError::isError() || map.empty())
11762
        return;
11763
 
11764
    vector<Button::TButton *> buttons = collectButtons(map);
11765
 
11766
    if (buttons.size() > 0)
11767
    {
11768
        vector<Button::TButton *>::iterator mapIter;
11769
 
11770
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11771
        {
11772
            Button::TButton *bt = *mapIter;
11773
            bt->setListSource(source, configs);
11774
        }
11775
    }
11776
 
11777
}
11778
 
230 andreas 11779
void TPageManager::doLVE(int port, vector<int> &channels, vector<string> &pars)
11780
{
11781
    DECL_TRACER("TPageManager::doLVE(int port, vector<int> &channels, vector<string> &pars)");
11782
 
11783
    if (pars.size() < 1)
11784
    {
11785
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
11786
        return;
11787
    }
11788
 
11789
    TError::clear();
11790
    int num = atoi(pars[0].c_str());
11791
 
11792
    vector<TMap::MAP_T> map = findButtons(port, channels);
11793
 
11794
    if (TError::isError() || map.empty())
11795
        return;
11796
 
11797
    vector<Button::TButton *> buttons = collectButtons(map);
11798
 
11799
    if (buttons.size() > 0)
11800
    {
11801
        vector<Button::TButton *>::iterator mapIter;
11802
 
11803
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11804
        {
11805
            Button::TButton *bt = *mapIter;
11806
            bt->setListViewEventNumber(num);
11807
        }
11808
    }
11809
 
11810
}
11811
 
227 andreas 11812
void TPageManager::doLVF(int port, vector<int> &channels, vector<string> &pars)
11813
{
11814
    DECL_TRACER("TPageManager::doLVF(int port, vector<int> &channels, vector<string> &pars)");
11815
 
11816
    if (pars.size() < 1)
11817
    {
11818
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
11819
        return;
11820
    }
11821
 
11822
    TError::clear();
11823
    string filter;
11824
 
11825
    vector<string>::iterator iter;
11826
 
11827
    for (iter = pars.begin(); iter != pars.end(); ++iter)
11828
    {
11829
        if (filter.length() > 0)
11830
            filter += ",";
11831
 
11832
        filter += *iter;
11833
    }
11834
 
11835
    vector<TMap::MAP_T> map = findButtons(port, channels);
11836
 
11837
    if (TError::isError() || map.empty())
11838
        return;
11839
 
11840
    vector<Button::TButton *> buttons = collectButtons(map);
11841
 
11842
    if (buttons.size() > 0)
11843
    {
11844
        vector<Button::TButton *>::iterator mapIter;
11845
 
11846
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11847
        {
11848
            Button::TButton *bt = *mapIter;
11849
            bt->setListSourceFilter(filter);
11850
        }
11851
    }
11852
}
11853
 
230 andreas 11854
void TPageManager::doLVL(int port, vector<int> &channels, vector<string> &pars)
11855
{
11856
    DECL_TRACER("TPageManager::doLVL(int port, vector<int> &channels, vector<string> &pars)");
11857
 
11858
    if (pars.size() < 1)
11859
    {
11860
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
11861
        return;
11862
    }
11863
 
11864
    TError::clear();
233 andreas 11865
    bool hasColumns = false;
230 andreas 11866
    int columns = 0;
233 andreas 11867
    bool hasLayout = false;
230 andreas 11868
    int layout = 0;
233 andreas 11869
    bool hasComponent = false;
11870
    int component = 0;
11871
    bool hasCellHeight = false;
11872
    bool cellHeightPercent = false;
11873
    int cellheight = 0;
11874
    bool hasP1 = false;
11875
    int p1 = 0;
11876
    bool hasP2 = false;
11877
    int p2 = 0;
11878
    bool hasFilter = false;
11879
    bool filter = false;
11880
    bool hasFilterHeight = false;
11881
    bool filterHeightPercent = false;
11882
    int filterheight = 0;
11883
    bool hasAlphaScroll = false;
11884
    bool alphascroll = false;
230 andreas 11885
 
11886
    vector<string>::iterator iter;
11887
 
11888
    for (iter = pars.begin(); iter != pars.end(); ++iter)
11889
    {
11890
        string low = toLower(*iter);
11891
 
11892
        if (low.find("columns=") != string::npos ||
11893
            low.find("nc=") != string::npos ||
11894
            low.find("numcol=") != string::npos)
11895
        {
11896
            size_t pos = low.find("=");
11897
            string sCols = low.substr(pos + 1);
11898
            columns = atoi(sCols.c_str());
233 andreas 11899
            hasColumns = true;
11900
        }
11901
        else if (low.find("c=") != string::npos || low.find("comp=") != string::npos)
11902
        {
11903
            size_t pos = low.find("=");
11904
            string sComp = low.substr(pos + 1);
11905
            component |= atoi(sComp.c_str());
11906
            hasComponent = true;
11907
        }
11908
        else if (low.find("l=") != string::npos || low.find("layout=") != string::npos)
11909
        {
11910
            size_t pos = low.find("=");
11911
            string sLay = low.substr(pos + 1);
11912
            layout = atoi(sLay.c_str());
11913
            hasLayout = true;
11914
        }
11915
        else if (low.find("ch=") != string::npos || low.find("cellheight=") != string::npos)
11916
        {
11917
            size_t pos = low.find("=");
11918
            string sCh = low.substr(pos + 1);
11919
            cellheight = atoi(sCh.c_str());
230 andreas 11920
 
233 andreas 11921
            if (low.find("%") != string::npos)
11922
                cellHeightPercent = true;
11923
 
11924
            hasCellHeight = true;
230 andreas 11925
        }
233 andreas 11926
        else if (low.find("p1=") != string::npos)
11927
        {
11928
            size_t pos = low.find("=");
11929
            string sP1 = low.substr(pos + 1);
11930
            p1 = atoi(sP1.c_str());
11931
            hasP1 = true;
11932
        }
11933
        else if (low.find("p2=") != string::npos)
11934
        {
11935
            size_t pos = low.find("=");
11936
            string sP2 = low.substr(pos + 1);
11937
            p2 = atoi(sP2.c_str());
11938
            hasP2 = true;
11939
        }
11940
        else if (low.find("f=") != string::npos || low.find("filter=") != string::npos)
11941
        {
11942
            size_t pos = low.find("=");
11943
            string sFilter = low.substr(pos + 1);
11944
            filter = isTrue(sFilter);
11945
            hasFilter = true;
11946
        }
11947
        else if (low.find("fh=") != string::npos || low.find("filterheight=") != string::npos)
11948
        {
11949
            size_t pos = low.find("=");
11950
            string sFilter = low.substr(pos + 1);
11951
            filterheight = atoi(sFilter.c_str());
11952
 
11953
            if (low.find("%") != string::npos)
11954
                filterHeightPercent = true;
11955
 
11956
            hasFilterHeight = true;
11957
        }
11958
        else if (low.find("as=") != string::npos || low.find("alphascroll=") != string::npos)
11959
        {
11960
            size_t pos = low.find("=");
11961
            string sAlpha = low.substr(pos + 1);
11962
            alphascroll = isTrue(sAlpha);
11963
            hasAlphaScroll = true;
11964
        }
230 andreas 11965
    }
11966
 
11967
    vector<TMap::MAP_T> map = findButtons(port, channels);
11968
 
11969
    if (TError::isError() || map.empty())
11970
        return;
11971
 
11972
    vector<Button::TButton *> buttons = collectButtons(map);
11973
 
11974
    if (buttons.size() > 0)
11975
    {
11976
        vector<Button::TButton *>::iterator mapIter;
11977
 
11978
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11979
        {
11980
            Button::TButton *bt = *mapIter;
233 andreas 11981
 
11982
            if (hasColumns)         bt->setListViewColumns(columns);
11983
            if (hasComponent)       bt->setListViewComponent(component);
11984
            if (hasLayout)          bt->setListViewLayout(layout);
11985
            if (hasCellHeight)      bt->setListViewCellheight(cellheight, cellHeightPercent);
11986
            if (hasP1)              bt->setListViewP1(p1);
11987
            if (hasP2)              bt->setListViewP2(p2);
11988
            if (hasFilter)          bt->setListViewColumnFilter(filter);
11989
            if (hasFilterHeight)    bt->setListViewFilterHeight(filterheight, filterHeightPercent);
11990
            if (hasAlphaScroll)     bt->setListViewAlphaScroll(alphascroll);
230 andreas 11991
        }
11992
    }
11993
}
11994
 
233 andreas 11995
void TPageManager::doLVM(int port, vector<int> &channels, vector<string> &pars)
11996
{
11997
    DECL_TRACER("TPageManager::doLVM(int port, vector<int> &channels, vector<string> &pars)");
11998
 
11999
    if (pars.size() < 1)
12000
    {
12001
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
12002
        return;
12003
    }
12004
 
12005
    TError::clear();
12006
    map<string,string> mapField;
12007
 
12008
    vector<string>::iterator iter;
12009
 
12010
    for (iter = pars.begin(); iter != pars.end(); ++iter)
12011
    {
12012
        string left, right;
12013
        size_t pos = 0;
12014
 
12015
        if ((pos = iter->find("=")) != string::npos)
12016
        {
12017
            string left = iter->substr(0, pos);
12018
            left = toLower(left);
12019
            string right = iter->substr(pos + 1);
12020
 
12021
            if (left == "t1" || left == "t2" || left == "i1")
12022
                mapField.insert(pair<string,string>(left, right));
12023
        }
12024
    }
12025
 
12026
    vector<TMap::MAP_T> map = findButtons(port, channels);
12027
 
12028
    if (TError::isError() || map.empty())
12029
        return;
12030
 
12031
    vector<Button::TButton *> buttons = collectButtons(map);
12032
 
12033
    if (buttons.size() > 0)
12034
    {
12035
        vector<Button::TButton *>::iterator mapIter;
12036
 
12037
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
12038
        {
12039
            Button::TButton *bt = *mapIter;
12040
            bt->setListViewFieldMap(mapField);
12041
        }
12042
    }
12043
}
12044
 
12045
void TPageManager::doLVN(int port, vector<int> &channels, vector<string> &pars)
12046
{
12047
    DECL_TRACER("TPageManager::doLVN(int port, vector<int> &channels, vector<string> &pars)");
12048
 
12049
    if (pars.size() < 1)
12050
    {
12051
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
12052
        return;
12053
    }
12054
 
12055
    TError::clear();
12056
    string command = pars[0];
12057
    bool select = false;
12058
 
12059
    if (pars.size() > 1)
12060
    {
12061
        if (isTrue(pars[1]))
12062
            select = true;
12063
    }
12064
 
12065
    vector<TMap::MAP_T> map = findButtons(port, channels);
12066
 
12067
    if (TError::isError() || map.empty())
12068
        return;
12069
 
12070
    vector<Button::TButton *> buttons = collectButtons(map);
12071
 
12072
    if (buttons.size() > 0)
12073
    {
12074
        vector<Button::TButton *>::iterator mapIter;
12075
 
12076
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
12077
        {
12078
            Button::TButton *bt = *mapIter;
12079
            bt->listViewNavigate(command, select);
12080
        }
12081
    }
12082
}
12083
 
12084
void TPageManager::doLVR(int port, vector<int> &channels, vector<string> &pars)
12085
{
12086
    DECL_TRACER("TPageManager::doLVR(int port, vector<int> &channels, vector<string> &pars)");
12087
 
12088
    TError::clear();
12089
    int interval = -1;
12090
    bool force = false;
12091
 
12092
    if (pars.size() > 0)
12093
        interval = atoi(pars[0].c_str());
12094
 
12095
    if (pars.size() > 1)
12096
        force = isTrue(pars[1]);
12097
 
12098
    vector<TMap::MAP_T> map = findButtons(port, channels);
12099
 
12100
    if (TError::isError() || map.empty())
12101
        return;
12102
 
12103
    vector<Button::TButton *> buttons = collectButtons(map);
12104
 
12105
    if (buttons.size() > 0)
12106
    {
12107
        vector<Button::TButton *>::iterator mapIter;
12108
 
12109
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
12110
        {
12111
            Button::TButton *bt = *mapIter;
12112
            bt->listViewRefresh(interval, force);
12113
        }
12114
    }
12115
}
12116
 
12117
void TPageManager::doLVS(int port, vector<int> &channels, vector<string> &pars)
12118
{
12119
    DECL_TRACER("TPageManager::doLVS(int port, vector<int> &channels, vector<string> &pars)");
12120
 
12121
    TError::clear();
12122
    vector<string> sortColumns;
12123
    Button::LIST_SORT sort = Button::LIST_SORT_NONE;
12124
    string override;
12125
 
12126
    if (pars.size() > 0)
12127
    {
12128
        vector<string>::iterator iter;
12129
 
12130
        for (iter = pars.begin(); iter != pars.end(); ++iter)
12131
        {
12132
            if (iter->find(";") == string::npos)
12133
                sortColumns.push_back(*iter);
12134
            else
12135
            {
12136
                vector<string> parts = StrSplit(*iter, ";");
12137
                sortColumns.push_back(parts[0]);
12138
 
12139
                if (parts[1].find("a") != string::npos || parts[1].find("A") != string::npos)
12140
                    sort = Button::LIST_SORT_ASC;
12141
                else if (parts[1].find("d") != string::npos || parts[1].find("D") != string::npos)
12142
                    sort = Button::LIST_SORT_DESC;
12143
                else if (parts[1].find("*") != string::npos)
12144
                {
12145
                    if (parts.size() > 2 && !parts[2].empty())
12146
                    {
12147
                        override = parts[2];
12148
                        sort = Button::LIST_SORT_OVERRIDE;
12149
                    }
12150
                }
12151
                else if (parts[1].find("n") != string::npos || parts[1].find("N") != string::npos)
12152
                    sort = Button::LIST_SORT_NONE;
12153
            }
12154
        }
12155
    }
12156
 
12157
    vector<TMap::MAP_T> map = findButtons(port, channels);
12158
 
12159
    if (TError::isError() || map.empty())
12160
        return;
12161
 
12162
    vector<Button::TButton *> buttons = collectButtons(map);
12163
 
12164
    if (buttons.size() > 0)
12165
    {
12166
        vector<Button::TButton *>::iterator mapIter;
12167
 
12168
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
12169
        {
12170
            Button::TButton *bt = *mapIter;
12171
            bt->listViewSortData(sortColumns, sort, override);
12172
        }
12173
    }
12174
}
12175
 
134 andreas 12176
void TPageManager::doTPCCMD(int, vector<int>&, vector<string>& pars)
12177
{
12178
    DECL_TRACER("TPageManager::doTPCCMD(int, vector<int>&, vector<string>& pars)");
12179
 
12180
    if (pars.size() < 1)
12181
    {
12182
        MSG_ERROR("Too few arguments for TPCCMD!");
12183
        return;
12184
    }
12185
 
12186
    string cmd = pars[0];
12187
 
12188
    if (strCaseCompare(cmd, "LocalHost") == 0)
12189
    {
12190
        if (pars.size() < 2 || pars[1].empty())
12191
        {
12192
            MSG_ERROR("The command \"LocalHost\" requires an additional parameter!");
12193
            return;
12194
        }
12195
 
12196
        TConfig::saveController(pars[1]);
12197
    }
12198
    else if (strCaseCompare(cmd, "LocalPort") == 0)
12199
    {
12200
        if (pars.size() < 2 || pars[1].empty())
12201
        {
12202
            MSG_ERROR("The command \"LocalPort\" requires an additional parameter!");
12203
            return;
12204
        }
12205
 
12206
        int port = atoi(pars[1].c_str());
12207
 
12208
        if (port > 0 && port < 65536)
12209
            TConfig::savePort(port);
12210
        else
12211
        {
12212
            MSG_ERROR("Invalid network port " << port);
12213
        }
12214
    }
12215
    else if (strCaseCompare(cmd, "DeviceID") == 0)
12216
    {
12217
        if (pars.size() < 2 || pars[1].empty())
12218
        {
12219
            MSG_ERROR("The command \"DeviceID\" requires an additional parameter!");
12220
            return;
12221
        }
12222
 
12223
        int id = atoi(pars[1].c_str());
12224
 
12225
        if (id >= 10000 && id < 30000)
12226
            TConfig::setSystemChannel(id);
12227
    }
12228
    else if (strCaseCompare(cmd, "ApplyProfile") == 0)
12229
    {
12230
        // We restart the network connection only
12231
        if (gAmxNet)
12232
            gAmxNet->reconnect();
12233
    }
12234
    else if (strCaseCompare(cmd, "QueryDeviceInfo") == 0)
12235
    {
12236
        string info = "DEVICEINFO-TPANELID," + TConfig::getPanelType();
12237
        info += ";HOSTNAME,";
12238
        char hostname[HOST_NAME_MAX];
12239
 
12240
        if (gethostname(hostname, HOST_NAME_MAX) != 0)
12241
        {
12242
            MSG_ERROR("Can't get host name: " << strerror(errno));
12243
            return;
12244
        }
12245
 
12246
        info.append(hostname);
12247
        info += ";UUID," + TConfig::getUUID();
12248
        sendGlobalString(info);
12249
    }
12250
    else if (strCaseCompare(cmd, "LockRotation") == 0)
12251
    {
12252
        if (pars.size() < 2 || pars[1].empty())
12253
        {
12254
            MSG_ERROR("The command \"LockRotation\" requires an additional parameter!");
12255
            return;
12256
        }
12257
 
12258
        if (strCaseCompare(pars[1], "true") == 0)
12259
            TConfig::setRotationFixed(true);
12260
        else
12261
            TConfig::setRotationFixed(false);
12262
    }
12263
    else if (strCaseCompare(cmd, "ButtonHit") == 0)
12264
    {
12265
        if (pars.size() < 2 || pars[1].empty())
12266
        {
12267
            MSG_ERROR("The command \"ButtonHit\" requires an additional parameter!");
12268
            return;
12269
        }
12270
 
12271
        if (strCaseCompare(pars[1], "true") == 0)
12272
            TConfig::saveSystemSoundState(true);
12273
        else
12274
            TConfig::saveSystemSoundState(false);
12275
    }
12276
    else if (strCaseCompare(cmd, "ReprocessTP4") == 0)
12277
    {
12278
        if (_resetSurface)
12279
            _resetSurface();
12280
    }
12281
}
12282
 
12283
void TPageManager::doTPCACC(int, vector<int>&, vector<string>& pars)
12284
{
12285
    DECL_TRACER("TPageManager::doTPCACC(int, vector<int>&, vector<string>& pars)");
12286
 
12287
    if (pars.size() < 1)
12288
    {
12289
        MSG_ERROR("Too few arguments for TPCACC!");
12290
        return;
12291
    }
12292
 
12293
    string cmd = pars[0];
12294
 
12295
    if (strCaseCompare(cmd, "ENABLE") == 0)
12296
    {
12297
        mInformOrientation = true;
12298
        sendOrientation();
12299
    }
12300
    else if (strCaseCompare(cmd, "DISABLE") == 0)
12301
    {
12302
        mInformOrientation = false;
12303
    }
12304
    else if (strCaseCompare(cmd, "QUERY") == 0)
12305
    {
12306
        sendOrientation();
12307
    }
12308
}
153 andreas 12309
 
279 andreas 12310
#ifndef _NOSIP_
153 andreas 12311
void TPageManager::doTPCSIP(int, vector<int>&, vector<string>& pars)
12312
{
12313
    DECL_TRACER("TPageManager::doTPCSIP(int port, vector<int>& channels, vector<string>& pars)");
12314
 
12315
    if (pars.empty())
12316
        return;
12317
 
12318
    string cmd = toUpper(pars[0]);
12319
 
12320
    if (cmd == "SHOW" && _showPhoneDialog)
12321
        _showPhoneDialog(true);
12322
    else if (!_showPhoneDialog)
12323
    {
12324
        MSG_ERROR("There is no phone dialog registered!");
12325
    }
12326
}
279 andreas 12327
#endif