Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 andreas 1
/*
435 andreas 2
 * Copyright (C) 2020 to 2024 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.
416 andreas 1005
    REG_CMD(doGIV, "^GIV");     // 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
        }
433 andreas 1229
 
1230
        if (!mButtonStates.empty())
1231
        {
1232
            vector<TButtonStates *>::iterator iter;
1233
 
1234
            for (iter = mButtonStates.begin(); iter != mButtonStates.end(); ++iter)
1235
                delete *iter;
1236
 
1237
            mButtonStates.clear();
1238
        }
3 andreas 1239
    }
1240
    catch (std::exception& e)
1241
    {
1242
        MSG_ERROR("Memory error: " << e.what());
1243
    }
90 andreas 1244
 
1245
    gPageManager = nullptr;
3 andreas 1246
}
1247
 
11 andreas 1248
void TPageManager::initialize()
1249
{
1250
    DECL_TRACER("TPageManager::initialize()");
1251
 
14 andreas 1252
    surface_mutex.lock();
11 andreas 1253
    dropAllSubPages();
1254
    dropAllPages();
1255
 
186 andreas 1256
    string projectPath = TConfig::getProjectPath();
1257
 
1258
    if (!fs::exists(projectPath + "/prj.xma"))
1259
        projectPath += "/__system";
1260
 
90 andreas 1261
    if (mAmxNet && mAmxNet->isConnected())
1262
        mAmxNet->close();
88 andreas 1263
 
11 andreas 1264
    if (mTSettings)
1265
        mTSettings->loadSettings();
1266
    else
186 andreas 1267
        mTSettings = new TSettings(projectPath);
11 andreas 1268
 
1269
    if (TError::isError())
14 andreas 1270
    {
1271
        surface_mutex.unlock();
11 andreas 1272
        return;
14 andreas 1273
    }
11 andreas 1274
 
178 andreas 1275
    // Set the panel type from the project information
1276
    TConfig::savePanelType(mTSettings->getPanelType());
1277
 
88 andreas 1278
    if (gPrjResources)
1279
        delete gPrjResources;
11 andreas 1280
 
88 andreas 1281
    gPrjResources = new TPrjResources(mTSettings->getResourcesList());
11 andreas 1282
 
88 andreas 1283
    if (mPalette)
1284
        delete mPalette;
1285
 
1286
    mPalette = new TPalette();
1287
 
11 andreas 1288
    vector<PALETTE_SETUP> pal = mTSettings->getSettings().palettes;
1289
 
83 andreas 1290
    if (pal.size() > 0)
1291
    {
1292
        vector<PALETTE_SETUP>::iterator iterPal;
11 andreas 1293
 
118 andreas 1294
        for (iterPal = pal.begin(); iterPal != pal.end(); ++iterPal)
83 andreas 1295
            mPalette->initialize(iterPal->file);
1296
    }
1297
 
11 andreas 1298
    if (!TError::isError())
1299
        TColor::setPalette(mPalette);
1300
 
88 andreas 1301
    if (mFonts)
1302
        delete mFonts;
11 andreas 1303
 
88 andreas 1304
    mFonts = new TFont();
1305
 
11 andreas 1306
    if (TError::isError())
1307
    {
1308
        MSG_ERROR("Initializing fonts was not successfull!");
14 andreas 1309
        surface_mutex.unlock();
11 andreas 1310
        return;
1311
    }
1312
 
88 andreas 1313
    if (gIcons)
1314
        delete gIcons;
11 andreas 1315
 
88 andreas 1316
    gIcons = new TIcons();
1317
 
11 andreas 1318
    if (TError::isError())
1319
    {
1320
        MSG_ERROR("Initializing icons was not successfull!");
14 andreas 1321
        surface_mutex.unlock();
11 andreas 1322
        return;
1323
    }
1324
 
88 andreas 1325
    if (mPageList)
1326
        delete mPageList;
11 andreas 1327
 
88 andreas 1328
    mPageList = new TPageList();
11 andreas 1329
 
88 andreas 1330
    if (mExternal)
1331
        delete mExternal;
1332
 
1333
    mExternal = new TExternal();
1334
 
11 andreas 1335
    PAGELIST_T page;
1336
 
1337
    if (!mTSettings->getSettings().powerUpPage.empty())
1338
    {
88 andreas 1339
        if (readPage(mTSettings->getSettings().powerUpPage))
14 andreas 1340
        {
88 andreas 1341
            MSG_TRACE("Found power up page " << mTSettings->getSettings().powerUpPage);
1342
            page = findPage(mTSettings->getSettings().powerUpPage);
1343
            mActualPage = page.pageID;
14 andreas 1344
        }
11 andreas 1345
    }
1346
 
1347
    TPage *pg = getPage(mActualPage);
1348
 
1349
    vector<string> popups = mTSettings->getSettings().powerUpPopup;
1350
 
83 andreas 1351
    if (popups.size() > 0)
11 andreas 1352
    {
83 andreas 1353
        vector<string>::iterator iter;
1354
 
118 andreas 1355
        for (iter = popups.begin(); iter != popups.end(); ++iter)
14 andreas 1356
        {
88 andreas 1357
            if (readSubPage(*iter))
83 andreas 1358
            {
88 andreas 1359
                MSG_TRACE("Found power up popup " << *iter);
11 andreas 1360
 
88 andreas 1361
                if (pg)
1362
                {
1363
                    TSubPage *spage = getSubPage(*iter);
350 andreas 1364
                    spage->setParent(pg->getHandle());
88 andreas 1365
                    pg->addSubPage(spage);
1366
                }
83 andreas 1367
            }
11 andreas 1368
        }
1369
    }
1370
 
88 andreas 1371
    // Here we initialize the system resources like borders, cursors, sliders, ...
1372
    if (mSystemDraw)
1373
        delete mSystemDraw;
1374
 
1375
    mSystemDraw = new TSystemDraw(TConfig::getSystemPath(TConfig::BASE));
1376
 
1377
    TError::clear();        // Clear all errors who may be occured until here
1378
 
11 andreas 1379
    // Start the thread
92 andreas 1380
    startComm();
1381
 
1382
    surface_mutex.unlock();
1383
}
1384
 
1385
bool TPageManager::startComm()
1386
{
1387
    DECL_TRACER("TPageManager::startComm()");
1388
 
1389
    if (mAmxNet && mAmxNet->isNetRun())
1390
        return true;
1391
 
1392
    try
11 andreas 1393
    {
92 andreas 1394
        if (!mAmxNet)
13 andreas 1395
        {
92 andreas 1396
            if (_netRunning)
13 andreas 1397
            {
92 andreas 1398
                // Wait until previous connection thread ended
1399
                while (_netRunning)
1400
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
13 andreas 1401
            }
14 andreas 1402
 
92 andreas 1403
            mAmxNet = new amx::TAmxNet();
1404
            mAmxNet->setCallback(bind(&TPageManager::doCommand, this, std::placeholders::_1));
1405
            mAmxNet->setPanelID(TConfig::getChannel());
134 andreas 1406
            mAmxNet->setSerialNum(V_SERIAL);
13 andreas 1407
        }
90 andreas 1408
 
1409
        if (!mAmxNet->isNetRun())
1410
            mAmxNet->Run();
85 andreas 1411
    }
92 andreas 1412
    catch (std::exception& e)
1413
    {
1414
        MSG_ERROR("Error starting the AmxNet thread: " << e.what());
1415
        return false;
1416
    }
14 andreas 1417
 
92 andreas 1418
    return true;
11 andreas 1419
}
1420
 
38 andreas 1421
void TPageManager::startUp()
1422
{
1423
    DECL_TRACER("TPageManager::startUp()");
1424
 
44 andreas 1425
    if (mAmxNet)
90 andreas 1426
    {
1427
        MSG_WARNING("Communication with controller already initialized!");
44 andreas 1428
        return;
90 andreas 1429
    }
44 andreas 1430
 
92 andreas 1431
    if (!startComm())
1432
        return;
90 andreas 1433
 
38 andreas 1434
#ifdef __ANDROID__
130 andreas 1435
    initOrientation();
38 andreas 1436
    initNetworkState();
1437
#endif
1438
}
89 andreas 1439
 
1440
void TPageManager::reset()
1441
{
1442
    DECL_TRACER("TPageManager::reset()");
1443
 
100 andreas 1444
    // Freshly initialize everything.
89 andreas 1445
    initialize();
1446
}
1447
 
169 andreas 1448
void TPageManager::runCommands()
1449
{
1450
    DECL_TRACER("TPageManager::runCommands()");
1451
 
418 andreas 1452
    if (cmdLoop_busy)
169 andreas 1453
        return;
1454
 
1455
    try
1456
    {
1457
        mThreadCommand = std::thread([=] { this->commandLoop(); });
1458
        mThreadCommand.detach();
1459
    }
1460
    catch (std::exception& e)
1461
    {
1462
        MSG_ERROR("Error starting thread for command loop: " << e.what());
1463
        _netRunning = false;
1464
    }
1465
}
1466
 
197 andreas 1467
void TPageManager::showSetup()
1468
{
1469
    DECL_TRACER("TPageManager::showSetup()");
251 andreas 1470
#ifdef Q_OS_ANDROID
260 andreas 1471
    // Scan Netlinx for TP4 files and update the list of setup.
1472
    if (TConfig::getController().compare("0.0.0.0") != 0)
1473
    {
1474
        if (_startWait)
1475
            _startWait(string("Please wait while I try to load the list of surface files from Netlinx (") + TConfig::getController() + ")");
1476
 
1477
        TTPInit tpinit;
1478
        std::vector<TTPInit::FILELIST_t> fileList;
1479
        tpinit.setPath(TConfig::getProjectPath());
1480
        fileList = tpinit.getFileList(".tp4");
1481
 
1482
        if (fileList.size() > 0)
1483
        {
1484
            vector<TTPInit::FILELIST_t>::iterator iter;
264 andreas 1485
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
260 andreas 1486
            QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "clearSurfaces");
1487
#else
1488
            QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "clearSurfaces");
1489
#endif
1490
            for (iter = fileList.begin(); iter != fileList.end(); ++iter)
1491
            {
264 andreas 1492
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
260 andreas 1493
                QAndroidJniObject str = QAndroidJniObject::fromString(iter->fname.c_str());
1494
                QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "addSurface", "(Ljava/lang/String;)V", str.object<jstring>());
1495
#else
1496
                QJniObject str = QJniObject::fromString(iter->fname.c_str());
1497
                QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "addSurface", "(Ljava/lang/String;)V", str.object<jstring>());
1498
#endif
1499
            }
1500
        }
1501
 
1502
        if (_stopWait)
1503
            _stopWait();
1504
    }
1505
 
367 andreas 1506
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1507
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogLevel", "(Ljava/lang/Integer;)V", TConfig::getLogLevelBits());
383 andreas 1508
    QAndroidJniObject strPath = QAndroidJniObject::fromString(TConfig::getLogFile().c_str());
385 andreas 1509
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogEnableFile", "(Z)V", TConfig::getLogFileEnabled());
383 andreas 1510
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogPath", "(Ljava/lang/String;)V", strPath.object<jstring>());
406 andreas 1511
 
1512
    QAndroidJniObject pw1 = QAndroidJniObject::fromString(TConfig::getPassword1().c_str());
1513
    QAndroidJniObject pw2 = QAndroidJniObject::fromString(TConfig::getPassword2().c_str());
1514
    QAndroidJniObject pw3 = QAndroidJniObject::fromString(TConfig::getPassword3().c_str());
1515
    QAndroidJniObject pw4 = QAndroidJniObject::fromString(TConfig::getPassword4().c_str());
1516
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setPassword", "(ILjava/lang/String;)V", 1, pw1.object<jstring>());
1517
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setPassword", "(ILjava/lang/String;)V", 2, pw2.object<jstring>());
1518
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setPassword", "(ILjava/lang/String;)V", 3, pw3.object<jstring>());
1519
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setPassword", "(ILjava/lang/String;)V", 4, pw4.object<jstring>());
367 andreas 1520
#else
1521
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogLevel", "(I)V", TConfig::getLogLevelBits());
385 andreas 1522
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogEnableFile", "(I)V", (TConfig::getLogFileEnabled() ? 1 : 0));
383 andreas 1523
    QJniObject strPath = QJniObject::fromString(TConfig::getLogFile().c_str());
1524
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogPath", "(Ljava/lang/String;)V", strPath.object<jstring>());
397 andreas 1525
 
1526
    QJniObject pw1 = QJniObject::fromString(TConfig::getPassword1().c_str());
1527
    QJniObject pw2 = QJniObject::fromString(TConfig::getPassword2().c_str());
1528
    QJniObject pw3 = QJniObject::fromString(TConfig::getPassword3().c_str());
1529
    QJniObject pw4 = QJniObject::fromString(TConfig::getPassword4().c_str());
1530
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setPassword", "(ILjava/lang/String;)V", 1, pw1.object<jstring>());
1531
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setPassword", "(ILjava/lang/String;)V", 2, pw2.object<jstring>());
1532
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setPassword", "(ILjava/lang/String;)V", 3, pw3.object<jstring>());
1533
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setPassword", "(ILjava/lang/String;)V", 4, pw4.object<jstring>());
367 andreas 1534
#endif
1535
 
255 andreas 1536
    enterSetup();
250 andreas 1537
#else
1538
        if (_callShowSetup)
1539
            _callShowSetup();
1540
#endif
197 andreas 1541
}
1542
 
1543
void TPageManager::hideSetup()
1544
{
1545
    DECL_TRACER("TPageManager::hideSetup()");
1546
 
206 andreas 1547
    if (!mSetupActive || mSavedPage >= SYSTEM_PAGE_START)
197 andreas 1548
        return;
1549
 
198 andreas 1550
    mSetupActive = false;
197 andreas 1551
 
198 andreas 1552
    if (!mSavedPage)
1553
    {
1554
        string sPage = mTSettings->getPowerUpPage();
197 andreas 1555
 
198 andreas 1556
        if (!setPage(sPage, true))
1557
            setPage(1, true);
197 andreas 1558
 
1559
        return;
1560
    }
1561
 
198 andreas 1562
    setPage(mSavedPage, true);
213 andreas 1563
    MSG_PROTOCOL("Activated page: " << mSavedPage);
197 andreas 1564
 
198 andreas 1565
    if (mSavedSubpages.size() > 0)
197 andreas 1566
    {
198 andreas 1567
        vector<int>::iterator iter;
197 andreas 1568
 
198 andreas 1569
        for (iter = mSavedSubpages.begin(); iter != mSavedSubpages.end(); ++iter)
1570
        {
1571
            showSubPage(*iter);
213 andreas 1572
            MSG_PROTOCOL("Activated subpage: " << *iter);
198 andreas 1573
        }
217 andreas 1574
 
1575
        mSavedSubpages.clear();
197 andreas 1576
    }
1577
}
1578
 
205 andreas 1579
int TPageManager::getSelectedRow(ulong handle)
1580
{
1581
    DECL_TRACER("TPageManager::getSelectedRow(ulong handle)");
1582
 
300 andreas 1583
    int nPage = (handle >> 16) & 0x0000ffff;
205 andreas 1584
 
206 andreas 1585
    if ((nPage && TPage::isRegularPage(nPage)) || TPage::isSystemPage(nPage)) // Do we have a page?
205 andreas 1586
    {                                                   // Yes, then look on page
1587
        TPage *pg = getPage(nPage);
1588
 
1589
        if (!pg)
1590
            return -1;
1591
 
1592
        return pg->getSelectedRow(handle);
1593
    }
206 andreas 1594
    else if (TPage::isRegularSubPage(nPage) || TPage::isSystemSubPage(nPage))
205 andreas 1595
    {
1596
        TSubPage *subPg = getSubPage(nPage);
1597
 
1598
        if (!subPg)
1599
            return -1;
1600
 
1601
        return subPg->getSelectedRow(handle);
1602
    }
1603
 
271 andreas 1604
    MSG_WARNING("Invalid handle " << handleToString(handle) << " detected!");
205 andreas 1605
    return -1;
1606
}
1607
 
1608
string TPageManager::getSelectedItem(ulong handle)
1609
{
1610
    DECL_TRACER("TPageManager::getSelectedItem(ulong handle)");
1611
 
300 andreas 1612
    int nPage = (handle >> 16) & 0x0000ffff;
205 andreas 1613
 
206 andreas 1614
    if ((nPage && TPage::isRegularPage(nPage)) || TPage::isSystemPage(nPage)) // Do we have a page?
205 andreas 1615
    {                                                   // Yes, then look on page
1616
        TPage *pg = getPage(nPage);
1617
 
1618
        if (!pg)
1619
            return string();
1620
 
1621
        return pg->getSelectedItem(handle);
1622
    }
206 andreas 1623
    else if (TPage::isRegularSubPage(nPage) || TPage::isSystemSubPage(nPage))
205 andreas 1624
    {
1625
        TSubPage *subPg = getSubPage(nPage);
1626
 
1627
        if (!subPg)
1628
            return string();
1629
 
1630
        return subPg->getSelectedItem(handle);
1631
    }
1632
 
271 andreas 1633
    MSG_WARNING("Invalid handle " << handleToString(handle) << " detected!");
205 andreas 1634
    return string();
1635
}
1636
 
206 andreas 1637
void TPageManager::setSelectedRow(ulong handle, int row, const std::string& text)
205 andreas 1638
{
1639
    DECL_TRACER("TPageManager::setSelectedRow(ulong handle, int row)");
1640
 
300 andreas 1641
    int nPage = (handle >> 16) & 0x0000ffff;
205 andreas 1642
 
206 andreas 1643
    if (TPage::isRegularPage(nPage) || TPage::isSystemPage(nPage)) // Do we have a page?
205 andreas 1644
    {                                                   // Yes, then look on page
1645
        TPage *pg = getPage(nPage);
1646
 
1647
        if (!pg)
1648
            return;
1649
 
1650
        pg->setSelectedRow(handle, row);
1651
    }
206 andreas 1652
    else if (TPage::isRegularSubPage(nPage) || TPage::isSystemSubPage(nPage))   // Do we have a subpage?
1653
    {                                                   // Yes, then look on subpage
205 andreas 1654
        TSubPage *subPg = getSubPage(nPage);
1655
 
1656
        if (!subPg)
1657
            return;
1658
 
1659
        subPg->setSelectedRow(handle, row);
206 andreas 1660
        // Check if this is a system list. If so we must set the selected
1661
        // text to the input line or "label".
1662
        TPage *mainPage = nullptr;
1663
 
1664
        if (nPage >= SYSTEM_SUBPAGE_START)  // System subpage?
1665
        {
1666
            switch(nPage)
1667
            {
1668
                case SYSTEM_SUBPAGE_SYSTEMSOUND:
1669
                case SYSTEM_SUBPAGE_SINGLEBEEP:
1670
                case SYSTEM_SUBPAGE_DOUBLEBEEP:
1671
                    mainPage = getPage(SYSTEM_PAGE_SOUND);
1672
                break;
1673
 
1674
                case SYSTEM_SUBPAGE_SURFACE:
1675
                    mainPage = getPage(SYSTEM_PAGE_CONTROLLER);
1676
                break;
1677
            }
1678
        }
1679
 
1680
        if (mainPage)
1681
        {
1682
            if (nPage == SYSTEM_SUBPAGE_SYSTEMSOUND)  // System sound beep
1683
            {
1684
                Button::TButton *bt = mainPage->getButton(SYSTEM_PAGE_SOUND_TXSYSSOUND);
1685
 
1686
                if (bt)
1687
                {
1688
                    bt->setText(text, -1);
1689
                    TConfig::setTemporary(true);
1690
                    TConfig::saveSystemSoundFile(text);
1691
                }
1692
            }
1693
            else if (nPage == SYSTEM_SUBPAGE_SINGLEBEEP) // System sound single beep
1694
            {
1695
                Button::TButton *bt = mainPage->getButton(SYSTEM_PAGE_SOUND_TXSINGLEBEEP);
1696
 
1697
                if (bt)
1698
                {
1699
                    bt->setText(text, -1);
1700
                    TConfig::setTemporary(true);
1701
                    TConfig::saveSingleBeepFile(text);
1702
                }
1703
            }
1704
            else if (nPage == SYSTEM_SUBPAGE_DOUBLEBEEP) // System sound double beep
1705
            {
1706
                Button::TButton *bt = mainPage->getButton(SYSTEM_PAGE_SOUND_TXDOUBLEBEEP);
1707
 
1708
                if (bt)
1709
                {
1710
                    bt->setText(text, -1);
1711
                    TConfig::setTemporary(true);
1712
                    TConfig::saveDoubleBeepFile(text);
1713
                }
1714
            }
1715
            else if (nPage == SYSTEM_SUBPAGE_SURFACE)   // System TP4 files (surface files)
1716
            {
1717
                Button::TButton *bt = mainPage->getButton(SYSTEM_PAGE_CTRL_SURFACE);
1718
 
1719
                if (bt)
1720
                {
1721
                    MSG_DEBUG("Setting text: " << text);
1722
                    bt->setText(text, -1);
1723
                    TConfig::setTemporary(true);
1724
                    TConfig::saveFtpSurface(text);
1725
                }
1726
            }
1727
 
1728
            // Close the list subpage
1729
            subPg->drop();
1730
        }
205 andreas 1731
    }
1732
}
1733
 
383 andreas 1734
void TPageManager::redrawObject(ulong handle)
1735
{
1736
    DECL_TRACER("TPageManager::redrawObject(ulong handle)");
1737
 
1738
    int pnumber = (int)((handle >> 16) & 0x0000ffff);
1739
    int btnumber = (int)(handle & 0x0000ffff);
1740
 
1741
    if (pnumber < REGULAR_SUBPAGE_START)    // Is it a page?
1742
    {
1743
        TPage *page = getPage(pnumber);
1744
 
1745
        if (!page)
1746
        {
1747
            MSG_WARNING("Page " << pnumber << " not found!");
1748
            return;
1749
        }
1750
 
1751
        if (!page->isVisilble())
1752
            return;
1753
 
1754
        if (btnumber == 0)
1755
        {
1756
            page->show();
1757
            return;
1758
        }
1759
 
1760
        Button::TButton *button = page->getButton(btnumber);
1761
 
1762
        if (!button)
1763
        {
1764
            MSG_WARNING("Button " << btnumber << " on page " << pnumber << " not found!");
1765
            return;
1766
        }
1767
 
1768
        button->showLastButton();
1769
    }
1770
    else if (pnumber >= REGULAR_SUBPAGE_START && pnumber < SYSTEM_PAGE_START)
1771
    {
1772
        TSubPage *spage = getSubPage(pnumber);
1773
 
1774
        if (!spage)
1775
        {
1776
            MSG_WARNING("Subpage " << pnumber << " not found!");
1777
            return;
1778
        }
1779
 
1780
        if (!spage->isVisible())
1781
            return;
1782
 
1783
        if (btnumber == 0)
1784
        {
1785
            spage->show();
1786
            return;
1787
        }
1788
 
1789
        Button::TButton *button = spage->getButton(btnumber);
1790
 
1791
        if (!button)
1792
        {
1793
            MSG_WARNING("Button " << btnumber << " on subpage " << pnumber << " not found!");
1794
            return;
1795
        }
1796
 
1797
        button->showLastButton();
1798
    }
1799
    else
1800
    {
1801
        MSG_WARNING("System pages are not handled by redraw method! Ignoring page " << pnumber << ".");
1802
    }
1803
}
1804
 
198 andreas 1805
#ifdef _SCALE_SKIA_
197 andreas 1806
void TPageManager::setSetupScaleFactor(double scale, double sw, double sh)
1807
{
1808
    DECL_TRACER("TPageManager::setSetupScaleFactor(double scale, double sw, double sh)");
1809
 
1810
    mScaleSystem = scale;
1811
    mScaleSystemWidth = sw;
1812
    mScaleSystemHeight = sh;
1813
}
198 andreas 1814
#endif
197 andreas 1815
 
11 andreas 1816
/*
1817
 * The following method is called by the class TAmxNet whenever an event from
169 andreas 1818
 * the Netlinx occured.
11 andreas 1819
 */
1820
void TPageManager::doCommand(const amx::ANET_COMMAND& cmd)
1821
{
1822
    DECL_TRACER("TPageManager::doCommand(const amx::ANET_COMMAND& cmd)");
1823
 
169 andreas 1824
    if (!cmdLoop_busy)
1825
        runCommands();
1826
 
11 andreas 1827
    mCommands.push_back(cmd);
169 andreas 1828
}
11 andreas 1829
 
169 andreas 1830
void TPageManager::commandLoop()
1831
{
1832
    DECL_TRACER("TPageManager::commandLoop()");
1833
 
418 andreas 1834
    if (cmdLoop_busy)
11 andreas 1835
        return;
1836
 
418 andreas 1837
    cmdLoop_busy = true;
11 andreas 1838
    string com;
1839
 
169 andreas 1840
    while (cmdLoop_busy && !killed && !_restart_)
11 andreas 1841
    {
169 andreas 1842
        while (mCommands.size() > 0)
11 andreas 1843
        {
169 andreas 1844
            amx::ANET_COMMAND bef = mCommands.at(0);
1845
            mCommands.erase(mCommands.begin());
11 andreas 1846
 
169 andreas 1847
            switch (bef.MC)
1848
            {
1849
                case 0x0006:
1850
                case 0x0018:	// feedback channel on
1851
                    com.assign("ON-");
1852
                    com.append(to_string(bef.data.chan_state.channel));
1853
                    parseCommand(bef.device1, bef.data.chan_state.port, com);
1854
                break;
11 andreas 1855
 
169 andreas 1856
                case 0x0007:
1857
                case 0x0019:	// feedback channel off
1858
                    com.assign("OFF-");
1859
                    com.append(to_string(bef.data.chan_state.channel));
1860
                    parseCommand(bef.device1, bef.data.chan_state.port, com);
1861
                break;
11 andreas 1862
 
169 andreas 1863
                case 0x000a:	// level value change
1864
                    com = "LEVEL-";
1865
                    com += to_string(bef.data.message_value.value);
1866
                    com += ",";
11 andreas 1867
 
169 andreas 1868
                    switch (bef.data.message_value.type)
1869
                    {
1870
                        case 0x10: com += to_string(bef.data.message_value.content.byte); break;
1871
                        case 0x11: com += to_string(bef.data.message_value.content.ch); break;
1872
                        case 0x20: com += to_string(bef.data.message_value.content.integer); break;
1873
                        case 0x21: com += to_string(bef.data.message_value.content.sinteger); break;
1874
                        case 0x40: com += to_string(bef.data.message_value.content.dword); break;
1875
                        case 0x41: com += to_string(bef.data.message_value.content.sdword); break;
1876
                        case 0x4f: com += to_string(bef.data.message_value.content.fvalue); break;
1877
                        case 0x8f: com += to_string(bef.data.message_value.content.dvalue); break;
1878
                    }
11 andreas 1879
 
169 andreas 1880
                    parseCommand(bef.device1, bef.data.message_value.port, com);
1881
                break;
11 andreas 1882
 
169 andreas 1883
                case 0x000c:	// Command string
11 andreas 1884
                {
169 andreas 1885
                    amx::ANET_MSG_STRING msg = bef.data.message_string;
11 andreas 1886
 
169 andreas 1887
                    if (msg.length < strlen((char *)&msg.content))
1888
                    {
1889
                        mCmdBuffer.append((char *)&msg.content);
1890
                        break;
1891
                    }
1892
                    else if (mCmdBuffer.length() > 0)
1893
                    {
1894
                        mCmdBuffer.append((char *)&msg.content);
1895
                        size_t len = (mCmdBuffer.length() >= sizeof(msg.content)) ? (sizeof(msg.content)-1) : mCmdBuffer.length();
1896
                        strncpy((char *)&msg.content, mCmdBuffer.c_str(), len);
1897
                        msg.content[len] = 0;
1898
                    }
104 andreas 1899
 
412 andreas 1900
                    if (getCommand((char *)msg.content) == "^UTF" || bef.intern)  // This is already UTF8!
169 andreas 1901
                        com.assign((char *)msg.content);
1902
                    else
1903
                        com.assign(cp1250ToUTF8((char *)&msg.content));
11 andreas 1904
 
169 andreas 1905
                    parseCommand(bef.device1, msg.port, com);
1906
                    mCmdBuffer.clear();
1907
                }
1908
                break;
15 andreas 1909
 
169 andreas 1910
                case 0x0502:    // Blink message (contains date and time)
1911
                    com = "BLINK-" + to_string(bef.data.blinkMessage.hour) + ":";
1912
                    com += to_string(bef.data.blinkMessage.minute) + ":";
1913
                    com += to_string(bef.data.blinkMessage.second) + ",";
1914
                    com += to_string(bef.data.blinkMessage.year) + "-";
1915
                    com += to_string(bef.data.blinkMessage.month) + "-";
1916
                    com += to_string(bef.data.blinkMessage.day) + ",";
1917
                    com += to_string(bef.data.blinkMessage.weekday) + ",";
1918
                    com += ((bef.data.blinkMessage.LED & 0x0001) ? "ON" : "OFF");
1919
                    parseCommand(0, 0, com);
1920
                break;
11 andreas 1921
 
169 andreas 1922
                case 0x1000:	// Filetransfer
11 andreas 1923
                {
169 andreas 1924
                    amx::ANET_FILETRANSFER ftr = bef.data.filetransfer;
1925
 
1926
                    if (ftr.ftype == 0)
11 andreas 1927
                    {
169 andreas 1928
                        switch(ftr.function)
1929
                        {
1930
                            case 0x0100:	// Syncing directory
1931
                                com = "#FTR-SYNC:0:";
1932
                                com.append((char*)&ftr.data[0]);
1933
                                parseCommand(bef.device1, bef.port1, com);
1934
                            break;
11 andreas 1935
 
169 andreas 1936
                            case 0x0104:	// Delete file
1937
                                com = "#FTR-SYNC:"+to_string(bef.count)+":Deleting files ... ("+to_string(bef.count)+"%)";
1938
                                parseCommand(bef.device1, bef.port1, com);
1939
                            break;
11 andreas 1940
 
169 andreas 1941
                            case 0x0105:	// start filetransfer
1942
                                com = "#FTR-START";
1943
                                parseCommand(bef.device1, bef.port1, com);
1944
                            break;
1945
                        }
11 andreas 1946
                    }
169 andreas 1947
                    else
11 andreas 1948
                    {
169 andreas 1949
                        switch(ftr.function)
1950
                        {
1951
                            case 0x0003:	// Received part of file
1952
                            case 0x0004:	// End of file
1953
                                com = "#FTR-FTRPART:"+to_string(bef.count)+":"+to_string(ftr.info1);
1954
                                parseCommand(bef.device1, bef.port1, com);
1955
                            break;
11 andreas 1956
 
169 andreas 1957
                            case 0x0007:	// End of file transfer
1958
                            {
1959
                                com = "#FTR-END";
1960
                                parseCommand(bef.device1, bef.port1, com);
1961
                            }
1962
                            break;
1963
 
1964
                            case 0x0102:	// Receiving file
1965
                                com = "#FTR-FTRSTART:"+to_string(bef.count)+":"+to_string(ftr.info1)+":";
1966
                                com.append((char*)&ftr.data[0]);
1967
                                parseCommand(bef.device1, bef.port1, com);
1968
                            break;
11 andreas 1969
                        }
1970
                    }
1971
                }
169 andreas 1972
                break;
11 andreas 1973
            }
1974
        }
169 andreas 1975
 
1976
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
11 andreas 1977
    }
1978
 
169 andreas 1979
    cmdLoop_busy = false;
11 andreas 1980
}
1981
 
26 andreas 1982
void TPageManager::deployCallbacks()
1983
{
1984
    DECL_TRACER("TPageManager::deployCallbacks()");
1985
 
1986
    PCHAIN_T *p = mPchain;
1987
 
1988
    while (p)
1989
    {
1990
        if (p->page)
1991
        {
1992
            if (_setBackground)
1993
                p->page->registerCallback(_setBackground);
1994
 
1995
            if (_callPlayVideo)
1996
                p->page->regCallPlayVideo(_callPlayVideo);
1997
        }
1998
 
1999
        p = p->next;
2000
    }
2001
 
2002
    SPCHAIN_T *sp = mSPchain;
2003
 
2004
    while (sp)
2005
    {
2006
        if (sp->page)
2007
        {
2008
            if (_setBackground)
2009
                sp->page->registerCallback(_setBackground);
2010
 
2011
            if (_callPlayVideo)
2012
                sp->page->regCallPlayVideo(_callPlayVideo);
2013
        }
2014
 
2015
        sp = sp->next;
2016
    }
2017
}
36 andreas 2018
 
2019
void TPageManager::regCallbackNetState(std::function<void (int)> callNetState, ulong handle)
2020
{
2021
    DECL_TRACER("TPageManager::regCallbackNetState(std::function<void (int)> callNetState, ulong handle)");
2022
 
2023
    if (handle == 0)
2024
        return;
2025
 
2026
    mNetCalls.insert(std::pair<int, std::function<void (int)> >(handle, callNetState));
2027
}
2028
 
2029
void TPageManager::unregCallbackNetState(ulong handle)
2030
{
2031
    DECL_TRACER("TPageManager::unregCallbackNetState(ulong handle)");
2032
 
83 andreas 2033
    if (mNetCalls.size() == 0)
2034
        return;
2035
 
300 andreas 2036
    std::map<int, std::function<void (int)> >::iterator iter = mNetCalls.find((int)handle);
36 andreas 2037
 
2038
    if (iter != mNetCalls.end())
2039
        mNetCalls.erase(iter);
2040
}
247 andreas 2041
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
251 andreas 2042
#ifdef Q_OS_ANDROID
38 andreas 2043
void TPageManager::regCallbackBatteryState(std::function<void (int, bool, int)> callBatteryState, ulong handle)
2044
{
2045
    DECL_TRACER("TPageManager::regCallbackBatteryState(std::function<void (int, bool, int)> callBatteryState, ulong handle)");
2046
 
2047
    if (handle == 0)
2048
        return;
2049
 
2050
    mBatteryCalls.insert(std::pair<int, std::function<void (int, bool, int)> >(handle, callBatteryState));
2051
}
247 andreas 2052
#endif
2053
#ifdef Q_OS_IOS
2054
void TPageManager::regCallbackBatteryState(std::function<void (int, int)> callBatteryState, ulong handle)
2055
{
2056
    DECL_TRACER("TPageManager::regCallbackBatteryState(std::function<void (int, int)> callBatteryState, ulong handle)");
38 andreas 2057
 
247 andreas 2058
    if (handle == 0)
2059
        return;
2060
 
2061
    mBatteryCalls.insert(std::pair<int, std::function<void (int, int)> >(handle, callBatteryState));
264 andreas 2062
#ifdef Q_OS_IOS
2063
    mLastBatteryLevel = TIOSBattery::getBatteryLeft();
2064
    mLastBatteryState = TIOSBattery::getBatteryState();
247 andreas 2065
 
264 andreas 2066
#endif
247 andreas 2067
    if (mLastBatteryLevel > 0 || mLastBatteryState > 0)
2068
        informBatteryStatus(mLastBatteryLevel, mLastBatteryState);
2069
}
2070
#endif
38 andreas 2071
void TPageManager::unregCallbackBatteryState(ulong handle)
2072
{
2073
    DECL_TRACER("TPageManager::unregCallbackBatteryState(ulong handle)");
2074
 
83 andreas 2075
    if (mBatteryCalls.size() == 0)
2076
        return;
247 andreas 2077
#ifdef Q_OS_ANDROID
38 andreas 2078
    std::map<int, std::function<void (int, bool, int)> >::iterator iter = mBatteryCalls.find(handle);
247 andreas 2079
#endif
2080
#ifdef Q_OS_IOS
300 andreas 2081
    std::map<int, std::function<void (int, int)> >::iterator iter = mBatteryCalls.find((int)handle);
247 andreas 2082
#endif
38 andreas 2083
    if (iter != mBatteryCalls.end())
2084
        mBatteryCalls.erase(iter);
2085
}
247 andreas 2086
#endif  // defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
11 andreas 2087
/*
2088
 * The following function must be called to start the "panel".
2089
 */
5 andreas 2090
bool TPageManager::run()
2091
{
2092
    DECL_TRACER("TPageManager::run()");
2093
 
2094
    if (mActualPage <= 0)
2095
        return false;
2096
 
154 andreas 2097
    TPage *pg = getPage(mActualPage);
2098
 
2099
    if (!pg || !_setPage || !mTSettings)
2100
        return false;
2101
 
14 andreas 2102
    surface_mutex.lock();
7 andreas 2103
    pg->setFonts(mFonts);
5 andreas 2104
    pg->registerCallback(_setBackground);
21 andreas 2105
    pg->regCallPlayVideo(_callPlayVideo);
5 andreas 2106
 
26 andreas 2107
    int width, height;
217 andreas 2108
    width = mTSettings->getWidth();
26 andreas 2109
    height = mTSettings->getHeight();
43 andreas 2110
#ifdef _SCALE_SKIA_
26 andreas 2111
    if (mScaleFactor != 1.0)
2112
    {
2113
        width = (int)((double)width * mScaleFactor);
2114
        height = (int)((double)height * mScaleFactor);
2115
    }
43 andreas 2116
#endif
26 andreas 2117
    _setPage((pg->getNumber() << 16) & 0xffff0000, width, height);
5 andreas 2118
    pg->show();
2119
 
2120
    TSubPage *subPg = pg->getFirstSubPage();
2121
 
2122
    while (subPg)
2123
    {
7 andreas 2124
        subPg->setFonts(mFonts);
2125
        subPg->registerCallback(_setBackground);
2126
        subPg->registerCallbackDB(_displayButton);
11 andreas 2127
        subPg->regCallDropSubPage(_callDropSubPage);
21 andreas 2128
        subPg->regCallPlayVideo(_callPlayVideo);
7 andreas 2129
 
5 andreas 2130
        if (_setSubPage)
6 andreas 2131
        {
2132
            MSG_DEBUG("Drawing page " << subPg->getNumber() << ": " << subPg->getName() << "...");
26 andreas 2133
            width = subPg->getWidth();
2134
            height = subPg->getHeight();
2135
            int left = subPg->getLeft();
2136
            int top = subPg->getTop();
43 andreas 2137
#ifdef _SCALE_SKIA_
26 andreas 2138
            if (mScaleFactor != 1.0)
2139
            {
2140
                width = (int)((double)width * mScaleFactor);
2141
                height = (int)((double)height * mScaleFactor);
2142
                left = (int)((double)left * mScaleFactor);
2143
                top = (int)((double)top * mScaleFactor);
2144
            }
43 andreas 2145
#endif
41 andreas 2146
            ANIMATION_t ani;
2147
            ani.showEffect = subPg->getShowEffect();
2148
            ani.showTime = subPg->getShowTime();
42 andreas 2149
            ani.hideEffect = subPg->getHideEffect();
2150
            ani.hideTime = subPg->getHideTime();
162 andreas 2151
 
2152
            subPg->setZOrder(pg->getNextZOrder());
418 andreas 2153
            _setSubPage(subPg->getHandle(), pg->getHandle(), left, top, width, height, ani, subPg->isModal());
6 andreas 2154
            subPg->show();
2155
        }
5 andreas 2156
 
2157
        subPg = pg->getNextSubPage();
2158
    }
2159
 
14 andreas 2160
    surface_mutex.unlock();
5 andreas 2161
    return true;
2162
}
2163
 
4 andreas 2164
TPage *TPageManager::getPage(int pageID)
2165
{
2166
    DECL_TRACER("TPageManager::getPage(int pageID)");
2167
 
209 andreas 2168
    if (pageID <= 0)
2169
        return nullptr;
2170
 
4 andreas 2171
    PCHAIN_T *p = mPchain;
2172
 
2173
    while (p)
2174
    {
349 andreas 2175
        if (p->page && p->page->getNumber() == pageID)
4 andreas 2176
            return p->page;
2177
 
2178
        p = p->next;
2179
    }
2180
 
2181
    return nullptr;
2182
}
2183
 
2184
TPage *TPageManager::getPage(const string& name)
2185
{
2186
    DECL_TRACER("TPageManager::getPage(const string& name)");
2187
 
349 andreas 2188
    if (name.empty())
2189
        return nullptr;
2190
 
4 andreas 2191
    PCHAIN_T *p = mPchain;
2192
 
2193
    while (p)
2194
    {
349 andreas 2195
        if (p->page && p->page->getName().compare(name) == 0)
4 andreas 2196
            return p->page;
2197
 
2198
        p = p->next;
2199
    }
2200
 
2201
    return nullptr;
2202
}
2203
 
209 andreas 2204
TPage *TPageManager::loadPage(PAGELIST_T& pl, bool *refresh)
15 andreas 2205
{
209 andreas 2206
    DECL_TRACER("TPageManager::loadPage(PAGELIST_T& pl, bool *refresh)");
15 andreas 2207
 
209 andreas 2208
    if (refresh)
2209
        *refresh = false;
2210
 
15 andreas 2211
    if (!pl.isValid)
2212
        return nullptr;
2213
 
2214
    TPage *pg = getPage(pl.pageID);
2215
 
2216
    if (!pg)
2217
    {
2218
        if (!readPage(pl.pageID))
2219
            return nullptr;
2220
 
2221
        pg = getPage(pl.pageID);
2222
 
2223
        if (!pg)
2224
        {
2225
            MSG_ERROR("Error loading page " << pl.pageID << ", " << pl.name << " from file " << pl.file << "!");
2226
            return nullptr;
2227
        }
209 andreas 2228
 
2229
        if (refresh)
213 andreas 2230
            *refresh = true;        // Indicate that the page was freshly loaded
15 andreas 2231
    }
2232
 
2233
    return pg;
2234
}
2235
 
209 andreas 2236
void TPageManager::reloadSystemPage(TPage *page)
2237
{
2238
    DECL_TRACER("TPageManager::reloadSystemPage(TPage *page)");
2239
 
2240
    if (!page)
2241
        return;
2242
 
2243
    vector<Button::TButton *> buttons = page->getAllButtons();
2244
    vector<Button::TButton *>::iterator iter;
210 andreas 2245
    TConfig::setTemporary(false);
209 andreas 2246
 
2247
    for (iter = buttons.begin(); iter != buttons.end(); ++iter)
2248
    {
2249
        Button::TButton *bt = *iter;
2250
 
2251
        if (bt->getAddressPort() == 0 && bt->getAddressChannel() > 0)
2252
        {
2253
            switch(bt->getAddressChannel())
2254
            {
2255
                case SYSTEM_ITEM_LOGLOGFILE:        bt->setTextOnly(TConfig::getLogFile(), -1); break;
2256
 
2257
                case SYSTEM_ITEM_NETLINX_IP:        bt->setTextOnly(TConfig::getController(), -1); break;
2258
                case SYSTEM_ITEM_NETLINX_PORT:      bt->setTextOnly(std::to_string(TConfig::getPort()), -1); break;
2259
                case SYSTEM_ITEM_NETLINX_CHANNEL:   bt->setTextOnly(std::to_string(TConfig::getChannel()), -1); break;
2260
                case SYSTEM_ITEM_NETLINX_PTYPE:     bt->setTextOnly(TConfig::getPanelType(), -1); break;
2261
                case SYSTEM_ITEM_FTPUSER:           bt->setTextOnly(TConfig::getFtpUser(), -1); break;
2262
                case SYSTEM_ITEM_FTPPASSWORD:       bt->setTextOnly(TConfig::getFtpPassword(), -1); break;
2263
                case SYSTEM_ITEM_FTPSURFACE:        bt->setTextOnly(TConfig::getFtpSurface(), -1); break;
210 andreas 2264
 
2265
                case SYSTEM_ITEM_SIPPROXY:          bt->setTextOnly(TConfig::getSIPproxy(), -1); break;
2266
                case SYSTEM_ITEM_SIPPORT:           bt->setTextOnly(std::to_string(TConfig::getSIPport()), -1); break;
2267
                case SYSTEM_ITEM_SIPSTUN:           bt->setTextOnly(TConfig::getSIPstun(), -1); break;
2268
                case SYSTEM_ITEM_SIPDOMAIN:         bt->setTextOnly(TConfig::getSIPdomain(), -1); break;
2269
                case SYSTEM_ITEM_SIPUSER:           bt->setTextOnly(TConfig::getSIPuser(), -1); break;
2270
                case SYSTEM_ITEM_SIPPASSWORD:       bt->setTextOnly(TConfig::getSIPpassword(), -1); break;
2271
 
2272
                case SYSTEM_ITEM_SYSTEMSOUND:       bt->setTextOnly(TConfig::getSystemSound(), -1); break;
2273
                case SYSTEM_ITEM_SINGLEBEEP:        bt->setTextOnly(TConfig::getSingleBeepSound(), -1); break;
2274
                case SYSTEM_ITEM_DOUBLEBEEP:        bt->setTextOnly(TConfig::getDoubleBeepSound(), -1); break;
209 andreas 2275
            }
2276
        }
210 andreas 2277
        else if (bt->getChannelPort() == 0 && bt->getChannelNumber() > 0)
2278
        {
2279
            switch(bt->getChannelNumber())
2280
            {
2281
                case SYSTEM_ITEM_DEBUGINFO:         bt->setActiveInstance(IS_LOG_INFO() ? 1 : 0); break;
2282
                case SYSTEM_ITEM_DEBUGWARNING:      bt->setActiveInstance(IS_LOG_WARNING() ? 1 : 0); break;
2283
                case SYSTEM_ITEM_DEBUGERROR:        bt->setActiveInstance(IS_LOG_ERROR() ? 1 : 0); break;
2284
                case SYSTEM_ITEM_DEBUGTRACE:        bt->setActiveInstance(IS_LOG_TRACE() ? 1 : 0); break;
2285
                case SYSTEM_ITEM_DEBUGDEBUG:        bt->setActiveInstance(IS_LOG_DEBUG() ? 1 : 0); break;
2286
                case SYSTEM_ITEM_DEBUGPROTOCOL:     bt->setActiveInstance(IS_LOG_PROTOCOL() ? 1 : 0); break;
2287
                case SYSTEM_ITEM_DEBUGALL:          bt->setActiveInstance(IS_LOG_ALL() ? 1 : 0); break;
2288
                case SYSTEM_ITEM_DEBUGLONG:         bt->setActiveInstance(TConfig::isLongFormat() ? 1 : 0); break;
2289
                case SYSTEM_ITEM_DEBUGPROFILE:      bt->setActiveInstance(TConfig::getProfiling() ? 1 : 0); break;
2290
 
2291
                case SYSTEM_ITEM_FTPPASSIVE:        bt->setActiveInstance(TConfig::getFtpPassive() ? 1 : 0); break;
2292
 
2293
                case SYSTEM_ITEM_SIPIPV4:           bt->setActiveInstance(TConfig::getSIPnetworkIPv4() ? 1 : 0); break;
2294
                case SYSTEM_ITEM_SIPIPV6:           bt->setActiveInstance(TConfig::getSIPnetworkIPv6() ? 1 : 0); break;
2295
                case SYSTEM_ITEM_SIPENABLE:         bt->setActiveInstance(TConfig::getSIPstatus() ? 1 : 0); break;
2296
                case SYSTEM_ITEM_SIPIPHONE:         bt->setActiveInstance(TConfig::getSIPiphone() ? 1 : 0); break;
2297
 
2298
                case SYSTEM_ITEM_SOUNDSWITCH:       bt->setActiveInstance(TConfig::getSystemSoundState() ? 1 : 0); break;
2299
 
2300
                case SYSTEM_ITEM_VIEWSCALEFIT:      bt->setActiveInstance(TConfig::getScale() ? 1 : 0); break;
2301
                case SYSTEM_ITEM_VIEWBANNER:        bt->setActiveInstance(TConfig::showBanner() ? 1 : 0); break;
2302
                case SYSTEM_ITEM_VIEWNOTOOLBAR:     bt->setActiveInstance(TConfig::getToolbarSuppress() ? 1 : 0); break;
2303
                case SYSTEM_ITEM_VIEWTOOLBAR:       bt->setActiveInstance(TConfig::getToolbarForce() ? 1 : 0); break;
2304
                case SYSTEM_ITEM_VIEWROTATE:        bt->setActiveInstance(TConfig::getRotationFixed() ? 1 : 0); break;
2305
            }
2306
        }
416 andreas 2307
        else if (bt->getLevelPort() == 0 && bt->getLevelChannel() > 0)
210 andreas 2308
        {
416 andreas 2309
            switch(bt->getLevelChannel())
210 andreas 2310
            {
2311
                case SYSTEM_ITEM_SYSVOLUME:         bt->drawBargraph(0, TConfig::getSystemVolume(), false); break;
2312
                case SYSTEM_ITEM_SYSGAIN:           bt->drawBargraph(0, TConfig::getSystemGain(), false); break;
2313
            }
2314
        }
209 andreas 2315
    }
2316
}
2317
 
198 andreas 2318
bool TPageManager::setPage(int PageID, bool forget)
15 andreas 2319
{
198 andreas 2320
    DECL_TRACER("TPageManager::setPage(int PageID, bool forget)");
15 andreas 2321
 
295 andreas 2322
    return _setPageDo(PageID, "", forget);
15 andreas 2323
}
2324
 
168 andreas 2325
bool TPageManager::setPage(const string& name, bool forget)
15 andreas 2326
{
190 andreas 2327
    DECL_TRACER("TPageManager::setPage(const string& name, bool forget)");
15 andreas 2328
 
295 andreas 2329
    return _setPageDo(0, name, forget);
15 andreas 2330
}
2331
 
295 andreas 2332
bool TPageManager::_setPageDo(int pageID, const string& name, bool forget)
2333
{
2334
    DECL_TRACER("TPageManager::_setPageDo(int pageID, const string& name, bool forget)");
2335
 
2336
    TPage *pg = nullptr;
2337
 
2338
    if (pageID > 0 && mActualPage == pageID)
343 andreas 2339
    {
2340
#if TESTMODE == 1
2341
        __success = true;
2342
        setScreenDone();
2343
#endif
295 andreas 2344
        return true;
343 andreas 2345
    }
295 andreas 2346
    else if (!name.empty())
2347
    {
2348
        pg = getPage(mActualPage);
2349
 
2350
        if (pg && pg->getName().compare(name) == 0)
343 andreas 2351
        {
2352
#if TESTMODE == 1
2353
            __success = true;
2354
            setScreenDone();
2355
#endif
295 andreas 2356
            return true;
343 andreas 2357
        }
295 andreas 2358
    }
2359
    else if (pageID > 0)
2360
        pg = getPage(mActualPage);
2361
    else
343 andreas 2362
    {
2363
#if TESTMODE == 1
2364
        setScreenDone();
2365
#endif
295 andreas 2366
        return false;
343 andreas 2367
    }
295 andreas 2368
 
2369
    // FIXME: Make this a vector array to hold a larger history!
2370
    if (!forget)
2371
        mPreviousPage = mActualPage;    // Necessary to be able to jump back to at least the last previous page
2372
 
2373
    if (pg)
2374
        pg->drop();
2375
 
2376
    mActualPage = 0;
2377
    PAGELIST_T listPg;
2378
 
2379
    if (pageID > 0)
2380
        listPg = findPage(pageID);
2381
    else
2382
        listPg = findPage(name);
2383
 
2384
    bool refresh = false;
2385
 
2386
    if ((pg = loadPage(listPg, &refresh)) == nullptr)
343 andreas 2387
    {
2388
#if TESTMODE == 1
2389
        setScreenDone();
2390
#endif
295 andreas 2391
        return false;
343 andreas 2392
    }
295 andreas 2393
 
2394
    mActualPage = pg->getNumber();
2395
 
2396
    if (mActualPage >= SYSTEM_PAGE_START && !refresh)
2397
        reloadSystemPage(pg);
2398
 
2399
    int width = (mActualPage >= SYSTEM_PAGE_START ? mSystemSettings->getWidth() : mTSettings->getWidth());
2400
    int height = (mActualPage >= SYSTEM_PAGE_START ? mSystemSettings->getHeight() : mTSettings->getHeight());
2401
 
2402
    if (_setPage)
2403
        _setPage((mActualPage << 16) & 0xffff0000, width, height);
2404
 
2405
    pg->show();
2406
    return true;
2407
}
2408
 
2409
 
4 andreas 2410
TSubPage *TPageManager::getSubPage(int pageID)
2411
{
2412
    DECL_TRACER("TPageManager::getSubPage(int pageID)");
2413
 
419 andreas 2414
    if (pageID < REGULAR_SUBPAGE_START)
2415
        return nullptr;
2416
 
4 andreas 2417
    SPCHAIN_T *p = mSPchain;
2418
 
2419
    while(p)
2420
    {
2421
        if (p->page->getNumber() == pageID)
2422
            return p->page;
2423
 
2424
        p = p->next;
2425
    }
2426
 
2427
    return nullptr;
2428
}
2429
 
2430
TSubPage *TPageManager::getSubPage(const std::string& name)
2431
{
2432
    DECL_TRACER("TPageManager::getSubPage(const std::string& name)");
2433
 
2434
    SPCHAIN_T *p = mSPchain;
2435
 
2436
    while (p)
2437
    {
2438
        if (p->page->getName().compare(name) == 0)
2439
            return p->page;
2440
 
2441
        p = p->next;
2442
    }
2443
 
146 andreas 2444
    MSG_DEBUG("Page " << name << " not found in cache.");
4 andreas 2445
    return nullptr;
2446
}
2447
 
96 andreas 2448
TSubPage *TPageManager::deliverSubPage(const string& name, TPage **pg)
2449
{
198 andreas 2450
    DECL_TRACER("TPageManager::deliverSubPage(const string& name, TPage **pg)");
96 andreas 2451
 
2452
    TPage *page = getActualPage();
2453
 
2454
    if (!page)
2455
    {
2456
        MSG_ERROR("No actual page loaded!");
2457
        return nullptr;
2458
    }
2459
 
2460
    if (pg)
2461
        *pg = page;
2462
 
2463
    TSubPage *subPage = getSubPage(name);
2464
 
2465
    if (!subPage)
2466
    {
2467
        if (!readSubPage(name))
2468
        {
2469
            MSG_ERROR("Error reading subpage " << name);
2470
            return nullptr;
2471
        }
2472
 
2473
        subPage = getSubPage(name);
2474
 
2475
        if (!subPage)
2476
        {
2477
            MSG_ERROR("Fatal: A page with name " << name << " does not exist!");
2478
            return nullptr;
2479
        }
350 andreas 2480
 
2481
        subPage->setParent(page->getHandle());
96 andreas 2482
    }
2483
 
2484
    return subPage;
2485
}
2486
 
198 andreas 2487
TSubPage *TPageManager::deliverSubPage(int number, TPage **pg)
2488
{
2489
    DECL_TRACER("TPageManager::deliverSubPage(int number, TPage **pg)");
2490
 
2491
    TPage *page = getActualPage();
2492
 
2493
    if (!page)
2494
    {
2495
        MSG_ERROR("No actual page loaded!");
2496
        return nullptr;
2497
    }
2498
 
2499
    if (pg)
2500
        *pg = page;
2501
 
2502
    TSubPage *subPage = getSubPage(number);
2503
 
2504
    if (!subPage)
2505
    {
2506
        if (!readSubPage(number))
2507
        {
2508
            MSG_ERROR("Error reading subpage " << number);
2509
            return nullptr;
2510
        }
2511
 
2512
        subPage = getSubPage(number);
2513
 
2514
        if (!subPage)
2515
        {
2516
            MSG_ERROR("Fatal: A page with name " << number << " does not exist!");
2517
            return nullptr;
2518
        }
350 andreas 2519
 
2520
        subPage->setParent(page->getHandle());
198 andreas 2521
    }
2522
 
2523
    return subPage;
2524
}
2525
 
3 andreas 2526
bool TPageManager::readPages()
2527
{
2528
    DECL_TRACER("TPageManager::readPages()");
2529
 
2530
    if (!mPageList)
2531
    {
2532
        MSG_ERROR("Page list is not initialized!");
2533
        TError::setError();
2534
        return false;
2535
    }
2536
 
2537
    // Read all pages
2538
    vector<PAGELIST_T> pageList = mPageList->getPagelist();
2539
 
83 andreas 2540
    if (pageList.size() > 0)
3 andreas 2541
    {
83 andreas 2542
        vector<PAGELIST_T>::iterator pgIter;
14 andreas 2543
 
118 andreas 2544
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
14 andreas 2545
        {
83 andreas 2546
            TPage *page = new TPage(pgIter->name+".xml");
14 andreas 2547
 
83 andreas 2548
            if (TError::isError())
2549
            {
2550
                delete page;
2551
                return false;
2552
            }
3 andreas 2553
 
83 andreas 2554
            page->setPalette(mPalette);
2555
            page->setFonts(mFonts);
2556
            page->registerCallback(_setBackground);
2557
            page->registerCallbackDB(_displayButton);
2558
            page->regCallPlayVideo(_callPlayVideo);
2559
 
2560
            if (!addPage(page))
2561
                return false;
2562
        }
3 andreas 2563
    }
2564
 
348 andreas 2565
    vector<SUBPAGELIST_T> subPageList = mPageList->getSubPageList();
3 andreas 2566
 
83 andreas 2567
    if (subPageList.size() > 0)
3 andreas 2568
    {
83 andreas 2569
        vector<SUBPAGELIST_T>::iterator spgIter;
14 andreas 2570
 
118 andreas 2571
        for (spgIter = subPageList.begin(); spgIter != subPageList.end(); ++spgIter)
14 andreas 2572
        {
83 andreas 2573
            TSubPage *page = new TSubPage(spgIter->name+".xml");
14 andreas 2574
 
83 andreas 2575
            if (TError::isError())
2576
            {
2577
                delete page;
2578
                return false;
2579
            }
3 andreas 2580
 
83 andreas 2581
            page->setPalette(mPalette);
2582
            page->setFonts(mFonts);
2583
            page->registerCallback(_setBackground);
2584
            page->registerCallbackDB(_displayButton);
2585
            page->regCallDropSubPage(_callDropSubPage);
2586
            page->regCallPlayVideo(_callPlayVideo);
2587
            page->setGroup(spgIter->group);
2588
 
2589
            if (!addSubPage(page))
2590
                return false;
2591
        }
3 andreas 2592
    }
2593
 
2594
    return true;
2595
}
2596
 
2597
bool TPageManager::readPage(const std::string& name)
2598
{
2599
    DECL_TRACER("TPageManager::readPage(const std::string& name)");
2600
 
2601
    PAGELIST_T page = findPage(name);
2602
 
206 andreas 2603
    if ((page.pageID <= 0 || page.pageID >= MAX_PAGE_ID) && page.pageID < SYSTEM_PAGE_START && page.pageID >= SYSTEM_SUBPAGE_START)
3 andreas 2604
    {
2605
        MSG_ERROR("Page " << name << " not found!");
2606
        return false;
2607
    }
2608
 
43 andreas 2609
    TPage *pg;
14 andreas 2610
 
43 andreas 2611
    if (name.compare("_progress") == 0)
2612
        pg = new TPage(name);
2613
    else
2614
        pg = new TPage(page.name+".xml");
2615
 
14 andreas 2616
    if (TError::isError())
2617
    {
2618
        delete pg;
2619
        return false;
2620
    }
2621
 
4 andreas 2622
    pg->setPalette(mPalette);
7 andreas 2623
    pg->setFonts(mFonts);
2624
    pg->registerCallback(_setBackground);
2625
    pg->registerCallbackDB(_displayButton);
21 andreas 2626
    pg->regCallPlayVideo(_callPlayVideo);
3 andreas 2627
 
2628
    if (!addPage(pg))
2629
        return false;
2630
 
2631
    return true;
2632
}
2633
 
2634
bool TPageManager::readPage(int ID)
2635
{
2636
    DECL_TRACER("TPageManager::readPage(int ID)");
2637
 
16 andreas 2638
    TError::clear();
3 andreas 2639
    PAGELIST_T page = findPage(ID);
2640
 
2641
    if (page.pageID <= 0)
2642
    {
2643
        MSG_ERROR("Page with ID " << ID << " not found!");
2644
        return false;
2645
    }
2646
 
43 andreas 2647
    TPage *pg;
14 andreas 2648
 
43 andreas 2649
    if (ID == 300)      // Progress page of system?
2650
        pg = new TPage("_progress");
2651
    else
2652
        pg = new TPage(page.name+".xml");
2653
 
14 andreas 2654
    if (TError::isError())
2655
    {
2656
        delete pg;
2657
        return false;
2658
    }
2659
 
4 andreas 2660
    pg->setPalette(mPalette);
7 andreas 2661
    pg->setFonts(mFonts);
2662
    pg->registerCallback(_setBackground);
2663
    pg->registerCallbackDB(_displayButton);
21 andreas 2664
    pg->regCallPlayVideo(_callPlayVideo);
3 andreas 2665
 
2666
    if (!addPage(pg))
2667
        return false;
2668
 
2669
    return true;
2670
}
2671
 
2672
bool TPageManager::readSubPage(const std::string& name)
2673
{
2674
    DECL_TRACER("TPageManager::readSubPage(const std::string& name)");
2675
 
16 andreas 2676
    TError::clear();
3 andreas 2677
    SUBPAGELIST_T page = findSubPage(name);
2678
 
206 andreas 2679
    if (page.pageID < MAX_PAGE_ID || (page.pageID >= SYSTEM_PAGE_START && page.pageID < SYSTEM_SUBPAGE_START))
3 andreas 2680
    {
2681
        MSG_ERROR("Subpage " << name << " not found!");
2682
        return false;
2683
    }
2684
 
14 andreas 2685
    if (haveSubPage(name))
2686
        return true;
2687
 
3 andreas 2688
    TSubPage *pg = new TSubPage(page.name+".xml");
14 andreas 2689
 
2690
    if (TError::isError())
2691
    {
2692
        delete pg;
2693
        return false;
2694
    }
2695
 
4 andreas 2696
    pg->setPalette(mPalette);
7 andreas 2697
    pg->setFonts(mFonts);
2698
    pg->registerCallback(_setBackground);
2699
    pg->registerCallbackDB(_displayButton);
11 andreas 2700
    pg->regCallDropSubPage(_callDropSubPage);
21 andreas 2701
    pg->regCallPlayVideo(_callPlayVideo);
11 andreas 2702
    pg->setGroup(page.group);
3 andreas 2703
 
2704
    if (!addSubPage(pg))
14 andreas 2705
    {
2706
        delete pg;
3 andreas 2707
        return false;
14 andreas 2708
    }
3 andreas 2709
 
2710
    return true;
2711
}
2712
 
2713
bool TPageManager::readSubPage(int ID)
2714
{
2715
    DECL_TRACER("TPageManager::readSubPage(int ID)");
2716
 
16 andreas 2717
    TError::clear();
3 andreas 2718
    SUBPAGELIST_T page = findSubPage(ID);
2719
 
154 andreas 2720
    if (page.pageID <= MAX_PAGE_ID)
3 andreas 2721
    {
2722
        MSG_ERROR("Subpage with ID " << ID << " not found!");
2723
        return false;
2724
    }
2725
 
2726
    TSubPage *pg = new TSubPage(page.name+".xml");
14 andreas 2727
 
2728
    if (TError::isError())
2729
    {
2730
        delete pg;
2731
        return false;
2732
    }
2733
 
4 andreas 2734
    pg->setPalette(mPalette);
7 andreas 2735
    pg->setFonts(mFonts);
2736
    pg->registerCallback(_setBackground);
2737
    pg->registerCallbackDB(_displayButton);
11 andreas 2738
    pg->regCallDropSubPage(_callDropSubPage);
21 andreas 2739
    pg->regCallPlayVideo(_callPlayVideo);
11 andreas 2740
    pg->setGroup(page.group);
3 andreas 2741
 
2742
    if (!addSubPage(pg))
2743
        return false;
2744
 
2745
    return true;
2746
}
2747
 
279 andreas 2748
vector<TSubPage *> TPageManager::createSubViewList(int id)
2749
{
2750
    DECL_TRACER("TPageManager::createSubViewList(int id)");
2751
 
2752
    vector<TSubPage *> subviews;
2753
 
2754
    if (id <= 0)
2755
        return subviews;
2756
 
2757
    if (!mPageList)
2758
    {
2759
        MSG_WARNING("Missing page list and because of this can't make a subview list!");
2760
        return subviews;
2761
    }
2762
 
2763
    SUBVIEWLIST_T slist = mPageList->findSubViewList(id);
2764
 
2765
    if (slist.id <= 0 || slist.items.empty())
2766
    {
2767
        if (slist.id <= 0)
2768
        {
2769
            MSG_WARNING("Found no subview list with ID " << id);
2770
        }
2771
        else
2772
        {
300 andreas 2773
            MSG_WARNING("Subview list " << id << " has no items!");
279 andreas 2774
        }
2775
 
2776
        return subviews;
2777
    }
2778
 
2779
    vector<SUBVIEWITEM_T>::iterator iter;
2780
 
2781
    for (iter = slist.items.begin(); iter != slist.items.end(); ++iter)
2782
    {
2783
        if (!haveSubPage(iter->pageID))
2784
        {
2785
            if (!readSubPage(iter->pageID))
2786
                return vector<TSubPage *>();
2787
        }
2788
 
284 andreas 2789
        TSubPage *pg = getSubPage(iter->pageID);
279 andreas 2790
 
2791
        if (pg)
2792
            subviews.push_back(pg);
284 andreas 2793
        else
2794
        {
2795
            MSG_DEBUG("No subpage with ID " << id);
2796
        }
279 andreas 2797
    }
2798
 
300 andreas 2799
    MSG_DEBUG("Found " << subviews.size() << " subview items.");
279 andreas 2800
    return subviews;
2801
}
2802
 
280 andreas 2803
void TPageManager::showSubViewList(int id, Button::TButton *bt)
279 andreas 2804
{
280 andreas 2805
    DECL_TRACER("TPageManager::showSubViewList(int id, Button::TButton *bt)");
279 andreas 2806
 
2807
    vector<TSubPage *> subviews = createSubViewList(id);
2808
 
303 andreas 2809
    if (subviews.empty() || !_addViewButtonItems || !bt)
284 andreas 2810
    {
2811
        MSG_DEBUG("Number views: " << subviews.size() << (_addViewButtonItems ? ", addView" : ", NO addView") << (_displayViewButton ? " display" : " NO display"));
279 andreas 2812
        return;
284 andreas 2813
    }
279 andreas 2814
 
293 andreas 2815
    ulong btHandle = bt->getHandle();
2816
    MSG_DEBUG("Working on button " << handleToString(btHandle) << " (" << bt->getName() << ") with " << subviews.size() << " pages.");
289 andreas 2817
    TBitmap bm = bt->getLastBitmap();
2818
    TColor::COLOR_T fillColor = TColor::getAMXColor(bt->getFillColor());
293 andreas 2819
    _displayViewButton(btHandle, bt->getParent(), bt->isSubViewVertical(), bm, bt->getWidth(), bt->getHeight(), bt->getLeftPosition(), bt->getTopPosition(), bt->getSubViewSpace(), fillColor);
280 andreas 2820
 
2821
    vector<PGSUBVIEWITEM_T> items;
2822
    PGSUBVIEWITEM_T svItem;
2823
    PGSUBVIEWATOM_T svAtom;
279 andreas 2824
    vector<TSubPage *>::iterator iter;
2825
 
2826
    for (iter = subviews.begin(); iter != subviews.end(); ++iter)
2827
    {
280 andreas 2828
        TSubPage *sub = *iter;
306 andreas 2829
        sub->setParent(btHandle);
279 andreas 2830
 
289 andreas 2831
        svItem.clear();
2832
        Button::TButton *button = sub->getFirstButton();
2833
        SkBitmap bitmap = sub->getBgImage();
280 andreas 2834
 
2835
        svItem.handle = sub->getHandle();
289 andreas 2836
        svItem.parent = btHandle;
280 andreas 2837
        svItem.width = sub->getWidth();
2838
        svItem.height = sub->getHeight();
281 andreas 2839
        svItem.bgcolor = TColor::getAMXColor(sub->getFillColor());
300 andreas 2840
        svItem.scrollbar = bt->getSubViewScrollbar();
2841
        svItem.scrollbarOffset = bt->getSubViewScrollbarOffset();
2842
        svItem.position = bt->getSubViewAnchor();
302 andreas 2843
        svItem.wrap = bt->getWrapSubViewPages();
280 andreas 2844
 
289 andreas 2845
        if (!bitmap.empty())
2846
            svItem.image.setBitmap((unsigned char *)bitmap.getPixels(), bitmap.info().width(), bitmap.info().height(), bitmap.info().bytesPerPixel());
280 andreas 2847
 
289 andreas 2848
        while (button)
280 andreas 2849
        {
300 andreas 2850
            button->drawButton(0, false, true);
289 andreas 2851
            svAtom.clear();
2852
            svAtom.handle = button->getHandle();
280 andreas 2853
            svAtom.parent = sub->getHandle();
289 andreas 2854
            svAtom.width = button->getWidth();
2855
            svAtom.height = button->getHeight();
2856
            svAtom.left = button->getLeftPosition();
2857
            svAtom.top = button->getTopPosition();
300 andreas 2858
            svAtom.bgcolor = TColor::getAMXColor(button->getFillColor(button->getActiveInstance()));
293 andreas 2859
            svAtom.bounding = button->getBounding();
289 andreas 2860
            Button::BITMAP_t bmap = button->getLastImage();
280 andreas 2861
 
289 andreas 2862
            if (bmap.buffer)
300 andreas 2863
                svAtom.image.setBitmap(bmap.buffer, bmap.width, bmap.height, (int)(bmap.rowBytes / bmap.width));
289 andreas 2864
 
280 andreas 2865
            svItem.atoms.push_back(svAtom);
289 andreas 2866
            button = sub->getNextButton();
280 andreas 2867
        }
2868
 
2869
        items.push_back(svItem);
279 andreas 2870
    }
281 andreas 2871
 
285 andreas 2872
    _addViewButtonItems(bt->getHandle(), items);
284 andreas 2873
 
2874
    if (_pageFinished)
306 andreas 2875
        _pageFinished(bt->getHandle());
279 andreas 2876
}
2877
 
300 andreas 2878
void TPageManager::updateSubViewItem(Button::TButton *bt)
2879
{
2880
    DECL_TRACER("TPageManager::updateSubViewItem(Button::TButton *bt)");
2881
 
303 andreas 2882
    if (!bt)
300 andreas 2883
        return;
2884
 
303 andreas 2885
    updview_mutex.lock();
2886
    mUpdateViews.push_back(bt);
2887
    updview_mutex.unlock();
2888
}
2889
 
2890
void TPageManager::_updateSubViewItem(Button::TButton *bt)
2891
{
2892
    DECL_TRACER("TPageManager::_updateSubViewItem(Button::TButton *bt)");
2893
 
2894
    if (!mPageList || !_updateViewButtonItem)
2895
        return;
2896
 
300 andreas 2897
    // The parent of this kind of button is always the button of type subview.
2898
    // If we take the parent handle and extract the page ID (upper 16 bits)
2899
    // we get the page ID of the subpage or page ID of the page the button is
2900
    // ordered to.
2901
    int pageID = (bt->getParent() >> 16) & 0x0000ffff;
306 andreas 2902
    ulong parent = 0;
300 andreas 2903
    Button::TButton *button = nullptr;
2904
    PGSUBVIEWITEM_T item;
2905
    PGSUBVIEWATOM_T atom;
2906
    SkBitmap bitmap;
2907
    TPage *pg = nullptr;
2908
    TSubPage *sub = nullptr;
2909
 
2910
    if (pageID < REGULAR_SUBPAGE_START)     // Is it a page?
2911
    {
2912
        pg = getPage(pageID);
2913
 
2914
        if (!pg)
2915
        {
2916
            MSG_WARNING("Invalid page " << pageID << "!");
2917
            return;
2918
        }
2919
 
2920
        button = pg->getFirstButton();
2921
        bitmap = pg->getBgImage();
2922
 
2923
        item.handle = pg->getHandle();
2924
        item.parent = bt->getParent();
2925
        item.width = pg->getWidth();
2926
        item.height = pg->getHeight();
2927
        item.bgcolor = TColor::getAMXColor(pg->getFillColor());
2928
    }
2929
    else
2930
    {
2931
        sub = getSubPage(pageID);
2932
 
2933
        if (!sub)
2934
        {
2935
            MSG_WARNING("Couldn't find the subpage " << pageID << "!");
2936
            return;
2937
        }
2938
 
306 andreas 2939
        parent = sub->getParent();
300 andreas 2940
        button = sub->getFirstButton();
2941
        bitmap = sub->getBgImage();
2942
 
2943
        item.handle = sub->getHandle();
2944
        item.parent = bt->getParent();
2945
        item.width = sub->getWidth();
2946
        item.height = sub->getHeight();
303 andreas 2947
        item.position = bt->getSubViewAnchor();
300 andreas 2948
        item.bgcolor = TColor::getAMXColor(sub->getFillColor());
2949
    }
2950
 
2951
 
2952
    if (!bitmap.empty())
2953
        item.image.setBitmap((unsigned char *)bitmap.getPixels(), bitmap.info().width(), bitmap.info().height(), bitmap.info().bytesPerPixel());
2954
 
2955
    while (button)
2956
    {
2957
        atom.clear();
2958
        atom.handle = button->getHandle();
303 andreas 2959
        atom.parent = item.handle;
300 andreas 2960
        atom.width = button->getWidth();
2961
        atom.height = button->getHeight();
2962
        atom.left = button->getLeftPosition();
2963
        atom.top = button->getTopPosition();
2964
        atom.bgcolor = TColor::getAMXColor(button->getFillColor(button->getActiveInstance()));
2965
        atom.bounding = button->getBounding();
2966
        Button::BITMAP_t bmap = button->getLastImage();
2967
 
2968
        if (bmap.buffer)
2969
            atom.image.setBitmap(bmap.buffer, bmap.width, bmap.height, (int)(bmap.rowBytes / bmap.width));
2970
 
2971
        item.atoms.push_back(atom);
2972
        button = (pg ? pg->getNextButton() : sub->getNextButton());
2973
    }
2974
 
306 andreas 2975
    _updateViewButtonItem(item, parent);
300 andreas 2976
}
2977
 
192 andreas 2978
void TPageManager::updateActualPage()
2979
{
2980
    DECL_TRACER("TPageManager::updateActualPage()");
2981
 
2982
    if (!mActualPage)
2983
        return;
2984
 
2985
    TPage *pg = getPage(mActualPage);
2986
    Button::TButton *bt = pg->getFirstButton();
2987
 
2988
    while (bt)
2989
    {
2990
        bt->refresh();
2991
        bt = pg->getNextButton();
2992
    }
2993
}
2994
 
2995
void TPageManager::updateSubpage(int ID)
2996
{
2997
    DECL_TRACER("TPageManager::updateSubpage(int ID)");
2998
 
2999
    TSubPage *pg = getSubPage(ID);
3000
 
3001
    if (!pg)
3002
        return;
3003
 
3004
    vector<Button::TButton *> blist = pg->getAllButtons();
3005
    vector<Button::TButton *>::iterator iter;
3006
 
3007
    if (blist.empty())
3008
        return;
3009
 
3010
    for (iter = blist.begin(); iter != blist.end(); ++iter)
3011
    {
3012
        Button::TButton *bt = *iter;
3013
        bt->refresh();
3014
    }
3015
}
3016
 
3017
void TPageManager::updateSubpage(const std::string &name)
3018
{
3019
    DECL_TRACER("TPageManager::updateSubpage(const std::string &name)");
3020
 
3021
    TSubPage *pg = getSubPage(name);
3022
 
3023
    if (!pg)
3024
        return;
3025
 
3026
    vector<Button::TButton *> blist = pg->getAllButtons();
3027
    vector<Button::TButton *>::iterator iter;
3028
 
3029
    if (blist.empty())
3030
        return;
3031
 
3032
    for (iter = blist.begin(); iter != blist.end(); ++iter)
3033
    {
3034
        Button::TButton *bt = *iter;
3035
        bt->refresh();
3036
    }
3037
}
3038
 
3 andreas 3039
/******************** Internal private methods *********************/
3040
 
3041
PAGELIST_T TPageManager::findPage(const std::string& name)
3042
{
3043
    DECL_TRACER("TPageManager::findPage(const std::string& name)");
3044
 
194 andreas 3045
    vector<PAGELIST_T> pageList;
3 andreas 3046
 
194 andreas 3047
    if (!mSetupActive)
3048
        pageList = mPageList->getPagelist();
3049
    else
3050
        pageList = mPageList->getSystemPagelist();
3051
 
83 andreas 3052
    if (pageList.size() > 0)
3 andreas 3053
    {
83 andreas 3054
        vector<PAGELIST_T>::iterator pgIter;
3055
 
118 andreas 3056
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 3057
        {
3058
            if (pgIter->name.compare(name) == 0)
3059
                return *pgIter;
3060
        }
3 andreas 3061
    }
3062
 
194 andreas 3063
    MSG_WARNING("Page " << name << " not found!");
3 andreas 3064
    return PAGELIST_T();
3065
}
3066
 
3067
PAGELIST_T TPageManager::findPage(int ID)
3068
{
3069
    DECL_TRACER("TPageManager::findPage(int ID)");
3070
 
206 andreas 3071
    vector<PAGELIST_T> pageList = (ID < SYSTEM_PAGE_START ? mPageList->getPagelist() : mPageList->getSystemPagelist());
3 andreas 3072
 
83 andreas 3073
    if (pageList.size() > 0)
3 andreas 3074
    {
83 andreas 3075
        vector<PAGELIST_T>::iterator pgIter;
3076
 
118 andreas 3077
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 3078
        {
3079
            if (pgIter->pageID == ID)
3080
                return *pgIter;
3081
        }
3 andreas 3082
    }
3083
 
3084
    return PAGELIST_T();
3085
}
3086
 
3087
SUBPAGELIST_T TPageManager::findSubPage(const std::string& name)
3088
{
3089
    DECL_TRACER("TPageManager::findSubPage(const std::string& name)");
3090
 
348 andreas 3091
    vector<SUBPAGELIST_T> pageList = (mSetupActive ? mPageList->getSystemSupPageList() : mPageList->getSubPageList());
3 andreas 3092
 
83 andreas 3093
    if (pageList.size() > 0)
3 andreas 3094
    {
83 andreas 3095
        vector<SUBPAGELIST_T>::iterator pgIter;
3096
 
118 andreas 3097
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 3098
        {
3099
            if (pgIter->name.compare(name) == 0)
3100
                return *pgIter;
3101
        }
3 andreas 3102
    }
3103
 
3104
    return SUBPAGELIST_T();
3105
}
3106
 
3107
SUBPAGELIST_T TPageManager::findSubPage(int ID)
3108
{
3109
    DECL_TRACER("TPageManager::findSubPage(int ID)");
3110
 
348 andreas 3111
    vector<SUBPAGELIST_T> pageList = (ID < SYSTEM_PAGE_START ? mPageList->getSubPageList() : mPageList->getSystemSupPageList());
3 andreas 3112
 
83 andreas 3113
    if (pageList.size() > 0)
3 andreas 3114
    {
83 andreas 3115
        vector<SUBPAGELIST_T>::iterator pgIter;
3116
 
118 andreas 3117
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 3118
        {
3119
            if (pgIter->pageID == ID)
3120
                return *pgIter;
3121
        }
3 andreas 3122
    }
3123
 
3124
    return SUBPAGELIST_T();
3125
}
3126
 
3127
bool TPageManager::addPage(TPage* pg)
3128
{
3129
    DECL_TRACER("TPageManager::addPage(TPage* pg)");
3130
 
3131
    if (!pg)
3132
    {
3133
        MSG_ERROR("Parameter is NULL!");
3134
        TError::setError();
3135
        return false;
3136
    }
3137
 
3138
    PCHAIN_T *chain = new PCHAIN_T;
3139
    chain->page = pg;
5 andreas 3140
    chain->next = nullptr;
3 andreas 3141
 
3142
    if (mPchain)
3143
    {
3144
        PCHAIN_T *p = mPchain;
3145
 
3146
        while (p->next)
3147
            p = p->next;
3148
 
3149
        p->next = chain;
3150
    }
3151
    else
14 andreas 3152
    {
3 andreas 3153
        mPchain = chain;
14 andreas 3154
        setPChain(mPchain);
3155
    }
3 andreas 3156
 
156 andreas 3157
//    MSG_DEBUG("Added page " << chain->page->getName());
3 andreas 3158
    return true;
3159
}
3160
 
3161
bool TPageManager::addSubPage(TSubPage* pg)
3162
{
3163
    DECL_TRACER("TPageManager::addSubPage(TSubPage* pg)");
3164
 
3165
    if (!pg)
3166
    {
3167
        MSG_ERROR("Parameter is NULL!");
3168
        TError::setError();
3169
        return false;
3170
    }
3171
 
14 andreas 3172
    if (haveSubPage(pg->getNumber()))
3173
    {
3174
        MSG_ERROR("Subpage " << pg->getNumber() << ", " << pg->getName() << " is already in chain!");
3175
        return false;
3176
    }
3177
 
3 andreas 3178
    SPCHAIN_T *chain = new SPCHAIN_T;
3179
    chain->page = pg;
5 andreas 3180
    chain->next = nullptr;
3 andreas 3181
 
3182
    if (mSPchain)
3183
    {
3184
        SPCHAIN_T *p = mSPchain;
3185
 
3186
        while (p->next)
3187
            p = p->next;
3188
 
3189
        p->next = chain;
3190
    }
3191
    else
14 andreas 3192
    {
3 andreas 3193
        mSPchain = chain;
14 andreas 3194
        setSPChain(mSPchain);
3195
    }
3 andreas 3196
 
3197
    return true;
3198
}
4 andreas 3199
 
11 andreas 3200
void TPageManager::dropAllPages()
3201
{
3202
    DECL_TRACER("TPageManager::dropAllPages()");
3203
 
3204
    PCHAIN_T *pg = mPchain;
3205
    PCHAIN_T *next = nullptr;
3206
 
3207
    while (pg)
3208
    {
3209
        next = pg->next;
3210
 
3211
        if (pg->page)
3212
        {
3213
            if (_callDropPage)
3214
                _callDropPage((pg->page->getNumber() << 16) & 0xffff0000);
3215
 
3216
            delete pg->page;
3217
        }
3218
 
3219
        delete pg;
3220
        pg = next;
3221
    }
14 andreas 3222
 
3223
    mPchain = nullptr;
3224
    setPChain(mPchain);
11 andreas 3225
}
3226
 
3227
void TPageManager::dropAllSubPages()
3228
{
3229
    DECL_TRACER("TPageManager::dropAllSubPages()");
3230
 
3231
    SPCHAIN_T *spg = mSPchain;
3232
    SPCHAIN_T *next;
3233
 
3234
    while (spg)
3235
    {
3236
        next = spg->next;
3237
 
3238
        if (spg->page)
3239
        {
3240
            if (_callDropSubPage)
350 andreas 3241
                _callDropSubPage((spg->page->getNumber() << 16) & 0xffff0000, spg->page->getParent());
11 andreas 3242
 
3243
            delete spg->page;
3244
        }
3245
 
3246
        delete spg;
3247
        spg = next;
3248
    }
14 andreas 3249
 
3250
    mSPchain = nullptr;
3251
    setSPChain(mSPchain);
11 andreas 3252
}
3253
 
44 andreas 3254
bool TPageManager::destroyAll()
3255
{
3256
    DECL_TRACER("TPageManager::destroyAll()");
3257
 
3258
    dropAllSubPages();
3259
    dropAllPages();
3260
    mActualPage = 0;
3261
    mPreviousPage = 0;
3262
    mActualGroupName.clear();
3263
 
3264
    if (mPageList)
3265
    {
3266
        delete mPageList;
3267
        mPageList = nullptr;
3268
    }
3269
 
3270
    if (mTSettings)
3271
    {
3272
        delete mTSettings;
3273
        mTSettings = nullptr;
3274
    }
3275
 
194 andreas 3276
    if (mSystemSettings)
3277
    {
3278
        delete mSystemSettings;
3279
        mSystemSettings = nullptr;
3280
    }
3281
 
44 andreas 3282
    if (mPalette)
3283
    {
3284
        delete mPalette;
3285
        mPalette = nullptr;
3286
    }
3287
 
3288
    if (mFonts)
3289
    {
3290
        delete mFonts;
3291
        mFonts = nullptr;
3292
    }
3293
 
3294
    if (mExternal)
3295
    {
3296
        delete mExternal;
3297
        mExternal = nullptr;
3298
    }
3299
 
3300
    if (gPrjResources)
3301
    {
3302
        delete gPrjResources;
3303
        gPrjResources = nullptr;
3304
    }
3305
 
3306
    if (gIcons)
3307
    {
3308
        delete gIcons;
3309
        gIcons = nullptr;
3310
    }
3311
 
3312
    if (TError::isError())
3313
        return false;
3314
 
3315
    return true;
3316
}
3317
 
150 andreas 3318
bool TPageManager::overlap(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2)
3319
{
3320
    DECL_TRACER("TPageManager::overlap(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2)");
3321
 
3322
    struct point
3323
    {
3324
        int x;
3325
        int y;
3326
    };
3327
 
3328
    struct point l1, r1, l2, r2;
3329
 
3330
    l1.x = x1;
3331
    l1.y = y1;
3332
    r1.x = x1 + w1;
3333
    r1.y = y1 + h1;
3334
 
3335
    l2.x = x2;
3336
    l2.y = y2;
3337
    r2.x = x2 + w2;
3338
    r2.y = y2 + h2;
3339
 
3340
    if (l1.x == r1.x || l1.y == r1.y || l2.x == r2.x || l2.y == r2.y)
3341
    {
3342
        // the line cannot have positive overlap
3343
        return false;
3344
    }
3345
 
183 andreas 3346
    return std::max(l1.x, l2.x) < std::min(r1.x, r2.x) &&
150 andreas 3347
           std::max(l1.y, l2.y) < std::min(r1.y, r2.y);
3348
}
3349
 
51 andreas 3350
Button::TButton *TPageManager::findButton(ulong handle)
3351
{
3352
    DECL_TRACER("TPageManager::findButton(ulong handle)");
3353
 
209 andreas 3354
    if (!handle)
3355
        return nullptr;
3356
 
51 andreas 3357
    TPage *pg = getPage(mActualPage);
3358
 
3359
    if (!pg)
3360
        return nullptr;
3361
 
3362
    vector<Button::TButton *> pgBtList = pg->getAllButtons();
3363
    vector<Button::TButton *>::iterator iter;
83 andreas 3364
 
3365
    if (pgBtList.size() > 0)
51 andreas 3366
    {
83 andreas 3367
        // First we look into the elements of the page
3368
        for (iter = pgBtList.begin(); iter != pgBtList.end(); ++iter)
3369
        {
3370
            Button::TButton *bt = *iter;
51 andreas 3371
 
83 andreas 3372
            if (bt->getHandle() == handle)
3373
                return bt;
3374
        }
51 andreas 3375
    }
3376
 
3377
    // We've not found the wanted element in the elements of the page. So
3378
    // we're looking at the elements of the subpages.
3379
    TSubPage *sp = pg->getFirstSubPage();
3380
 
3381
    if (!sp)
3382
        return nullptr;
3383
 
3384
    while (sp)
3385
    {
3386
        vector<Button::TButton *> spBtList = sp->getAllButtons();
3387
 
83 andreas 3388
        if (spBtList.size() > 0)
51 andreas 3389
        {
83 andreas 3390
            for (iter = spBtList.begin(); iter != spBtList.end(); ++iter)
3391
            {
3392
                Button::TButton *bt = *iter;
51 andreas 3393
 
83 andreas 3394
                if (bt->getHandle() == handle)
3395
                    return bt;
3396
            }
51 andreas 3397
        }
3398
 
3399
        sp = pg->getNextSubPage();
3400
    }
3401
 
3402
    return nullptr;
3403
}
3404
 
428 andreas 3405
/**
3406
 * @brief Find a bargraph
3407
 * The method can search for a bargraph on a particular page or subpage defined
3408
 * by \b parent. if no page or subpage defined, it searches on the actual page
3409
 * or subpage.
3410
 * If it finds a bargraph it returns the pointer to it. Otherwise a nullptr is
3411
 * returned.
3412
 *
3413
 * @param lp        The brgraph port number.
3414
 * @param lv        The bargraph code number.
3415
 * @param parent    The parent handle of the bargraph.
3416
 *
3417
 * @return If the wanted bargraph with the parent handle exists, the pointer to
3418
 * it is returned. Otherwise it return a \b nullptr.
3419
 */
427 andreas 3420
Button::TButton *TPageManager::findBargraph(int lp, int lv, ulong parent)
426 andreas 3421
{
427 andreas 3422
    DECL_TRACER("TPageManager::findBargraph(int lp, int lv, ulong parent)");
426 andreas 3423
 
428 andreas 3424
    int page = (parent >> 16) & 0x0000ffff;
3425
    vector<Button::TButton *>::iterator iter;
426 andreas 3426
 
428 andreas 3427
    if (!page)
3428
    {
3429
        page = mActualPage;
426 andreas 3430
 
428 andreas 3431
        if (!page)
3432
        {
3433
            MSG_WARNING("No valid active page!");
3434
            return nullptr;
3435
        }
3436
    }
426 andreas 3437
 
428 andreas 3438
    MSG_DEBUG("Searching for bargraph " << lp << ":" << lv << " on page " << page);
3439
 
427 andreas 3440
    if (page < REGULAR_SUBPAGE_START)
426 andreas 3441
    {
428 andreas 3442
        TPage *pg = getPage(mActualPage);
3443
 
3444
        if (!pg)
3445
            return nullptr;
3446
 
427 andreas 3447
        vector<Button::TButton *> pgBtList = pg->getAllButtons();
3448
        MSG_DEBUG("Found " << pgBtList.size() << " buttons.");
3449
 
3450
        if (pgBtList.size() > 0)
426 andreas 3451
        {
427 andreas 3452
            // First we look into the elements of the page
3453
            for (iter = pgBtList.begin(); iter != pgBtList.end(); ++iter)
3454
            {
3455
                Button::TButton *bt = *iter;
426 andreas 3456
 
427 andreas 3457
                if (bt->getButtonType() == BARGRAPH && bt->getLevelPort() == lp && bt->getLevelChannel() == lv && bt->getParent() == parent)
3458
                {
428 andreas 3459
                    MSG_DEBUG("Found bargraph LP:" << lp << ", LV:" << lv << " on page " << page);
427 andreas 3460
                    return bt;
3461
                }
3462
            }
426 andreas 3463
        }
427 andreas 3464
 
428 andreas 3465
        MSG_WARNING("No bargraph " << lp << ":" << lv << " on page " << page);
427 andreas 3466
        return nullptr;
426 andreas 3467
    }
3468
 
3469
    // We've not found the wanted element in the elements of the page. So
428 andreas 3470
    // we're looking at the elements of the subpage.
3471
    TSubPage *sp = getSubPage(page);
426 andreas 3472
 
3473
    if (!sp)
428 andreas 3474
    {
3475
        MSG_WARNING("Found no subpage " << page);
426 andreas 3476
        return nullptr;
428 andreas 3477
    }
426 andreas 3478
 
428 andreas 3479
    vector<Button::TButton *> spBtList = sp->getAllButtons();
3480
    MSG_DEBUG("Found " << spBtList.size() << " buttons.");
3481
 
3482
    if (spBtList.size() > 0)
426 andreas 3483
    {
428 andreas 3484
        for (iter = spBtList.begin(); iter != spBtList.end(); ++iter)
3485
        {
3486
            Button::TButton *bt = *iter;
426 andreas 3487
 
428 andreas 3488
            if (bt->getButtonType() == BARGRAPH && bt->getLevelPort() == lp && bt->getLevelChannel() == lv && bt->getParent() == parent)
426 andreas 3489
            {
428 andreas 3490
                MSG_DEBUG("Found bargraph LP:" << lp << ", LV:" << lv << " on subpage " << page);
3491
                return bt;
426 andreas 3492
            }
3493
        }
3494
    }
3495
 
428 andreas 3496
    MSG_WARNING("No bargraph " << lp << ":" << lv << " on subpage " << page);
426 andreas 3497
    return nullptr;
3498
}
3499
 
4 andreas 3500
TPage *TPageManager::getActualPage()
3501
{
168 andreas 3502
    DECL_TRACER("TPageManager::getActualPage()");
3503
 
4 andreas 3504
    return getPage(mActualPage);
3505
}
3506
 
3507
TSubPage *TPageManager::getFirstSubPage()
3508
{
3509
    DECL_TRACER("TPageManager::getFirstSubPage()");
168 andreas 3510
 
349 andreas 3511
    mLastSubPage = 0;
4 andreas 3512
    TPage *pg = getPage(mActualPage);
3513
 
3514
    if (!pg)
3515
        return nullptr;
3516
 
349 andreas 3517
    map<int, TSubPage *> sp = pg->getSortedSubpages(true);
3518
 
3519
    if (!sp.empty())
3520
    {
3521
        map<int, TSubPage *>::iterator iter = sp.begin();
3522
        mLastSubPage = iter->first;
3523
        return iter->second;
3524
    }
3525
 
3526
    return nullptr;
4 andreas 3527
}
3528
 
3529
TSubPage *TPageManager::getNextSubPage()
3530
{
3531
    DECL_TRACER("TPageManager::getNextSubPage()");
3532
 
3533
    TPage *pg = getPage(mActualPage);
3534
 
3535
    if (pg)
349 andreas 3536
    {
3537
        map<int, TSubPage *> sp = pg->getSortedSubpages();
4 andreas 3538
 
349 andreas 3539
        if (sp.empty())
3540
        {
3541
            mLastSubPage = 0;
3542
            return nullptr;
3543
        }
3544
        else
3545
        {
3546
            map<int, TSubPage *>::iterator iter = sp.find(mLastSubPage);
3547
 
3548
            if (iter != sp.end())
3549
            {
3550
                iter++;
3551
 
3552
                if (iter != sp.end())
3553
                {
3554
                    mLastSubPage = iter->first;
3555
                    return iter->second;
3556
                }
3557
            }
3558
        }
3559
    }
3560
 
3561
    mLastSubPage = 0;
4 andreas 3562
    return nullptr;
3563
}
10 andreas 3564
 
154 andreas 3565
TSubPage *TPageManager::getPrevSubPage()
3566
{
3567
    DECL_TRACER("TPageManager::getPrevSubPage()");
3568
 
3569
    TPage *pg = getPage(mActualPage);
3570
 
3571
    if (pg)
349 andreas 3572
    {
3573
        map<int, TSubPage *> sp = pg->getSortedSubpages();
154 andreas 3574
 
349 andreas 3575
        if (sp.empty())
3576
        {
3577
            mLastSubPage = 0;
3578
            return nullptr;
3579
        }
3580
        else
3581
        {
3582
            map<int, TSubPage *>::iterator iter = sp.find(mLastSubPage);
3583
 
3584
            if (iter != sp.end() && iter != sp.begin())
3585
            {
3586
                iter--;
3587
                mLastSubPage = iter->first;
3588
                return iter->second;
3589
            }
3590
 
3591
            MSG_DEBUG("Page " << mLastSubPage << " not found!");
3592
        }
3593
    }
3594
 
3595
    mLastSubPage = 0;
154 andreas 3596
    return nullptr;
3597
}
3598
 
3599
TSubPage *TPageManager::getLastSubPage()
3600
{
3601
    DECL_TRACER("TPageManager::getLastSubPage()");
3602
 
349 andreas 3603
    mLastSubPage = 0;
154 andreas 3604
    TPage *pg = getPage(mActualPage);
3605
 
3606
    if (pg)
3607
    {
349 andreas 3608
        map<int, TSubPage *> sp = pg->getSortedSubpages(true);
3609
 
3610
        if (sp.empty())
3611
            return nullptr;
3612
        else
3613
        {
3614
            map<int, TSubPage *>::iterator iter = sp.end();
3615
            iter--;
3616
            mLastSubPage = iter->first;
3617
            return iter->second;
3618
        }
154 andreas 3619
    }
3620
    else
3621
    {
3622
        MSG_WARNING("Actual page " << mActualPage << " not found!");
3623
    }
3624
 
3625
    return nullptr;
3626
}
3627
 
11 andreas 3628
TSubPage *TPageManager::getFirstSubPageGroup(const string& group)
3629
{
3630
    DECL_TRACER("TPageManager::getFirstSubPageGroup(const string& group)");
3631
 
14 andreas 3632
    if (group.empty())
3633
    {
3634
        MSG_WARNING("Empty group name is invalid. Ignoring it!");
3635
        mActualGroupName.clear();
3636
        mActualGroupPage = nullptr;
3637
        return nullptr;
3638
    }
3639
 
11 andreas 3640
    mActualGroupName = group;
3641
    TSubPage *pg = getFirstSubPage();
3642
 
3643
    while (pg)
3644
    {
14 andreas 3645
        MSG_DEBUG("Evaluating group " << pg->getGroupName() << " with " << group);
3646
 
11 andreas 3647
        if (pg->getGroupName().compare(group) == 0)
3648
        {
3649
            mActualGroupPage = pg;
3650
            return pg;
3651
        }
3652
 
3653
        pg = getNextSubPage();
3654
    }
3655
 
3656
    mActualGroupName.clear();
3657
    mActualGroupPage = nullptr;
3658
    return nullptr;
3659
}
3660
 
3661
TSubPage *TPageManager::getNextSubPageGroup()
3662
{
3663
    DECL_TRACER("TPageManager::getNextSubPageGroup()");
3664
 
3665
    if (mActualGroupName.empty())
3666
        return nullptr;
3667
 
3668
    TSubPage *pg = getFirstSubPage();
3669
    bool found = false;
3670
 
3671
    while (pg)
3672
    {
14 andreas 3673
        MSG_DEBUG("Evaluating group " << pg->getGroupName() << " with " << mActualGroupName);
3674
 
3675
        if (!found && pg == mActualGroupPage)
11 andreas 3676
        {
3677
            pg = getNextSubPage();
14 andreas 3678
            found = true;
11 andreas 3679
            continue;
3680
        }
3681
 
14 andreas 3682
        if (found && pg->getGroupName().compare(mActualGroupName) == 0)
11 andreas 3683
        {
3684
            mActualGroupPage = pg;
3685
            return pg;
3686
        }
3687
 
3688
        pg = getNextSubPage();
3689
    }
3690
 
3691
    mActualGroupName.clear();
3692
    mActualGroupPage = nullptr;
3693
    return nullptr;
3694
}
3695
 
3696
TSubPage *TPageManager::getNextSubPageGroup(const string& group, TSubPage* pg)
3697
{
3698
    DECL_TRACER("TPageManager::getNextSubPageGroup(const string& group, TSubPage* pg)");
3699
 
3700
    if (group.empty() || !pg)
3701
        return nullptr;
3702
 
3703
    TSubPage *page = getFirstSubPage();
3704
    bool found = false;
3705
 
3706
    while (page)
3707
    {
14 andreas 3708
        MSG_DEBUG("Evaluating group " << pg->getGroupName() << " with " << group);
3709
 
3710
        if (!found && pg == page)
11 andreas 3711
        {
3712
            page = getNextSubPage();
14 andreas 3713
            found = true;
11 andreas 3714
            continue;
3715
        }
3716
 
14 andreas 3717
        if (found && page->getGroupName().compare(group) == 0)
11 andreas 3718
            return page;
3719
 
3720
        page = getNextSubPage();
3721
    }
3722
 
3723
    return nullptr;
3724
}
3725
 
3726
TSubPage *TPageManager::getTopPage()
3727
{
3728
    DECL_TRACER("TPageManager::getTopPage()");
3729
 
3730
    // Scan for all occupied regions
3731
    vector<RECT_T> regions;
3732
 
3733
    TSubPage *pg = getFirstSubPage();
3734
 
3735
    while (pg)
3736
    {
3737
        RECT_T r = pg->getRegion();
3738
        regions.push_back(r);
3739
        pg = getNextSubPage();
3740
    }
3741
 
3742
    // Now scan all pages against all regions to find the top most
3743
    pg = getFirstSubPage();
3744
    TSubPage *top = nullptr;
3745
    int zPos = 0;
3746
 
3747
    while (pg)
3748
    {
3749
        RECT_T r = pg->getRegion();
3750
 
83 andreas 3751
        if (regions.size() > 0)
11 andreas 3752
        {
83 andreas 3753
            vector<RECT_T>::iterator iter;
3754
            int zo = 0;
11 andreas 3755
 
118 andreas 3756
            for (iter = regions.begin(); iter != regions.end(); ++iter)
83 andreas 3757
            {
3758
                if (doOverlap(*iter, r) && zPos > zo)
3759
                    top = pg;
3760
 
3761
                zo++;
3762
            }
11 andreas 3763
        }
3764
 
3765
        pg = getNextSubPage();
3766
        zPos++;
3767
    }
3768
 
3769
    return top;
3770
}
3771
 
3772
TSubPage *TPageManager::getCoordMatch(int x, int y)
3773
{
3774
    DECL_TRACER("TPageManager::getCoordMatch(int x, int y)");
3775
 
26 andreas 3776
    int realX = x;
3777
    int realY = y;
3778
 
11 andreas 3779
    // Reverse order of pages
154 andreas 3780
    TSubPage *pg = getLastSubPage();
11 andreas 3781
 
154 andreas 3782
    // Iterate in reverse order through array
11 andreas 3783
    while (pg)
3784
    {
154 andreas 3785
        if (!pg->isVisible() || pg->getZOrder() == ZORDER_INVALID)
151 andreas 3786
        {
154 andreas 3787
            pg = getPrevSubPage();
3788
            continue;
151 andreas 3789
        }
14 andreas 3790
 
154 andreas 3791
        MSG_DEBUG("Scanning subpage (Z: " << pg->getZOrder() << "): " << pg->getNumber() << ", " << pg->getName());
3792
        RECT_T r = pg->getRegion();
11 andreas 3793
 
154 andreas 3794
        if (r.left <= realX && (r.left + r.width) >= realX &&
3795
            r.top <= realY && (r.top + r.height) >= realY)
11 andreas 3796
        {
154 andreas 3797
            MSG_DEBUG("Click matches subpage " << pg->getNumber() << " (" << pg->getName() << ")");
3798
            return pg;
3799
        }
83 andreas 3800
 
154 andreas 3801
        pg = getPrevSubPage();
11 andreas 3802
    }
3803
 
3804
    return nullptr;
3805
}
3806
 
40 andreas 3807
Button::TButton *TPageManager::getCoordMatchPage(int x, int y)
3808
{
3809
    DECL_TRACER("TPageManager::getCoordMatchPage(int x, int y)");
3810
 
3811
    TPage *page = getActualPage();
3812
 
3813
    if (page)
3814
    {
150 andreas 3815
        Button::TButton *bt = page->getLastButton();
40 andreas 3816
 
3817
        while (bt)
3818
        {
150 andreas 3819
            bool clickable = bt->isClickable();
3820
            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 3821
 
150 andreas 3822
            if (!clickable)
146 andreas 3823
            {
150 andreas 3824
                bt = page->getPreviousButton();
146 andreas 3825
                continue;
3826
            }
3827
 
40 andreas 3828
            if (bt->getLeftPosition() <= x && (bt->getLeftPosition() + bt->getWidth()) >= x &&
3829
                bt->getTopPosition() <= y && (bt->getTopPosition() + bt->getHeight()) >= y)
3830
            {
154 andreas 3831
                if (!bt->isClickable(x - bt->getLeftPosition(), y - bt->getTopPosition()))
3832
                {
3833
                    bt = page->getPreviousButton();
3834
                    continue;
3835
                }
3836
 
40 andreas 3837
                MSG_DEBUG("Click matches button " << bt->getButtonIndex() << " (" << bt->getButtonName() << ")");
3838
                return bt;
3839
            }
3840
 
150 andreas 3841
            bt = page->getPreviousButton();
40 andreas 3842
        }
3843
    }
3844
 
3845
    return nullptr;
3846
}
3847
 
11 andreas 3848
bool TPageManager::doOverlap(RECT_T r1, RECT_T r2)
3849
{
3850
    DECL_TRACER("TPageManager::doOverlap(RECT_T r1, RECT_T r2)");
3851
 
3852
    // If one rectangle is on left side of other
3853
    if (r1.left >= r2.left || r2.left >= r1.left)
3854
        return false;
3855
 
3856
    // If one rectangle is above other
3857
    if (r1.top <= r2.top || r2.top <= r1.top)
3858
        return false;
3859
 
3860
    return true;
3861
}
3862
 
14 andreas 3863
bool TPageManager::havePage(const string& name)
11 andreas 3864
{
14 andreas 3865
    DECL_TRACER("TPageManager::havePage(const string& name)");
11 andreas 3866
 
14 andreas 3867
    if (name.empty())
3868
        return false;
3869
 
3870
    PCHAIN_T *pg = mPchain;
3871
 
3872
    while (pg)
3873
    {
3874
        if (pg->page && pg->page->getName().compare(name) == 0)
3875
            return true;
3876
 
3877
        pg = pg->next;
3878
    }
3879
 
3880
    return false;
3881
}
3882
 
3883
bool TPageManager::haveSubPage(const string& name)
3884
{
3885
    DECL_TRACER("TPageManager::haveSubPage(const string& name)");
3886
 
3887
    if (name.empty())
3888
        return false;
3889
 
11 andreas 3890
    SPCHAIN_T *pg = mSPchain;
3891
 
3892
    while (pg)
3893
    {
14 andreas 3894
        if (pg->page && pg->page->getName().compare(name) == 0)
3895
        {
3896
            MSG_DEBUG("Subpage " << pg->page->getNumber() << ", " << name << " found.");
3897
            return true;
3898
        }
3899
 
3900
        pg = pg->next;
3901
    }
3902
 
3903
    MSG_DEBUG("Subpage " << name << " not found.");
3904
    return false;
3905
}
3906
 
3907
bool TPageManager::haveSubPage(int id)
3908
{
3909
    DECL_TRACER("TPageManager::haveSubPage(int id)");
3910
 
3911
    SPCHAIN_T *pg = mSPchain;
3912
 
3913
    while (pg)
3914
    {
3915
        if (pg->page && pg->page->getNumber() == id)
3916
        {
3917
            MSG_DEBUG("Subpage " << pg->page->getNumber() << ", " << pg->page->getName() << " found.");
3918
            return true;
3919
        }
3920
 
3921
        pg = pg->next;
3922
    }
3923
 
3924
    MSG_DEBUG("Subpage " << id << " not found.");
3925
    return false;
3926
}
3927
 
3928
bool TPageManager::haveSubPage(const string& page, const string& name)
3929
{
3930
    DECL_TRACER("TPageManager::haveSubPage(const string& page, const string& name)");
3931
 
3932
    TPage *pg = getPage(page);
3933
 
3934
    if (!pg)
3935
        return false;
3936
 
3937
    TSubPage *spg = pg->getFirstSubPage();
3938
 
3939
    while (spg)
3940
    {
3941
        if (spg->getName().compare(name) == 0)
3942
        {
3943
            MSG_DEBUG("Subpage " << spg->getNumber() << ", " << name << " found.");
3944
            return true;
3945
        }
3946
 
3947
        spg = pg->getNextSubPage();
3948
    }
3949
 
3950
    MSG_DEBUG("Subpage " << name << " not found on page " << page << ".");
3951
    return false;
3952
}
3953
 
3954
bool TPageManager::haveSubPage(const string& page, int id)
3955
{
3956
    DECL_TRACER("TPageManager::haveSubPage(const string& page, int id)");
3957
 
3958
    TPage *pg = getPage(page);
3959
 
3960
    if (!pg)
3961
        return false;
3962
 
3963
    TSubPage *spg = pg->getFirstSubPage();
3964
 
3965
    while (spg)
3966
    {
3967
        if (spg->getNumber() == id)
3968
        {
3969
            MSG_DEBUG("Subpage " << spg->getNumber() << ", " << spg->getName() << " found.");
3970
            return true;
3971
        }
3972
 
3973
        spg = pg->getNextSubPage();
3974
    }
3975
 
3976
    MSG_DEBUG("Subpage " << id << " on page " << page << " not found.");
3977
    return false;
3978
}
3979
 
3980
void TPageManager::closeGroup(const string& group)
3981
{
3982
    DECL_TRACER("TPageManager::closeGroup(const string& group)");
3983
 
3984
    SPCHAIN_T *pg = mSPchain;
3985
 
3986
    while (pg)
3987
    {
11 andreas 3988
        if (pg->page->getGroupName().compare(group) == 0 && pg->page->isVisible())
3989
        {
3990
            pg->page->regCallDropSubPage(_callDropSubPage);
3991
            pg->page->drop();
3992
            break;
3993
        }
3994
 
3995
        pg = pg->next;
3996
    }
3997
}
3998
 
14 andreas 3999
void TPageManager::showSubPage(const string& name)
4000
{
4001
    DECL_TRACER("TPageManager::showSubPage(const string& name)");
4002
 
4003
    if (name.empty())
349 andreas 4004
    {
4005
#if TESTMODE == 1
4006
        setScreenDone();
4007
#endif
14 andreas 4008
        return;
349 andreas 4009
    }
275 andreas 4010
 
152 andreas 4011
    TPage *page = nullptr;
4012
    TSubPage *pg = deliverSubPage(name, &page);
14 andreas 4013
 
96 andreas 4014
    if (!pg)
349 andreas 4015
    {
4016
#if TESTMODE == 1
4017
        setScreenDone();
4018
#endif
14 andreas 4019
        return;
349 andreas 4020
    }
14 andreas 4021
 
152 andreas 4022
    if (page)
350 andreas 4023
    {
4024
        pg->setParent(page->getHandle());
152 andreas 4025
        page->addSubPage(pg);
350 andreas 4026
    }
152 andreas 4027
 
14 andreas 4028
    string group = pg->getGroupName();
4029
 
4030
    if (!group.empty())
4031
    {
4032
        TSubPage *sub = getFirstSubPageGroup(group);
4033
 
4034
        while(sub)
4035
        {
4036
            if (sub->isVisible() && sub->getNumber() != pg->getNumber())
4037
                sub->drop();
4038
 
4039
            sub = getNextSubPageGroup(group, sub);
4040
        }
4041
    }
4042
 
150 andreas 4043
    if (pg->isVisible())
4044
    {
152 andreas 4045
        MSG_DEBUG("Page " << pg->getName() << " is already visible but maybe not on top.");
150 andreas 4046
 
4047
        TSubPage *sub = getFirstSubPage();
4048
        bool redraw = false;
4049
 
4050
        while (sub)
4051
        {
151 andreas 4052
            if (sub->isVisible() && pg->getZOrder() < sub->getZOrder() &&
4053
                overlap(sub->getLeft(), sub->getTop(), sub->getWidth(), sub->getHeight(),
150 andreas 4054
                pg->getLeft(), pg->getTop(), pg->getWidth(), pg->getHeight()))
4055
            {
4056
                MSG_DEBUG("Page " << sub->getName() << " is overlapping page " << pg->getName());
4057
                redraw = true;
4058
                break;
4059
            }
4060
 
4061
            sub = getNextSubPage();
4062
        }
4063
 
151 andreas 4064
        if (redraw && _toFront)
4065
        {
300 andreas 4066
            _toFront((uint)pg->getHandle());
151 andreas 4067
            pg->setZOrder(page->getNextZOrder());
349 andreas 4068
//            page->sortSubpages();
154 andreas 4069
            MSG_DEBUG("Setting new Z-order " << page->getActZOrder() << " on subpage " << pg->getName());
151 andreas 4070
        }
154 andreas 4071
        else if (redraw && !_toFront)
150 andreas 4072
            pg->drop();
4073
    }
4074
 
14 andreas 4075
    if (!pg->isVisible())
4076
    {
4077
        if (!page)
4078
        {
198 andreas 4079
            page = getPage(mActualPage);
4080
 
4081
            if (!page)
4082
            {
4083
                MSG_ERROR("No active page found! Internal error.");
4084
                return;
4085
            }
14 andreas 4086
        }
4087
 
4088
        if (!haveSubPage(pg->getNumber()) && !page->addSubPage(pg))
4089
            return;
4090
 
4091
        pg->setZOrder(page->getNextZOrder());
4092
 
4093
        if (_setSubPage)
26 andreas 4094
        {
4095
            int left = pg->getLeft();
4096
            int top = pg->getTop();
4097
            int width = pg->getWidth();
4098
            int height = pg->getHeight();
43 andreas 4099
#ifdef _SCALE_SKIA_
26 andreas 4100
            if (mScaleFactor != 1.0)
4101
            {
4102
                left = (int)((double)left * mScaleFactor);
4103
                top = (int)((double)top * mScaleFactor);
4104
                width = (int)((double)width * mScaleFactor);
4105
                height = (int)((double)height * mScaleFactor);
28 andreas 4106
                MSG_DEBUG("Scaled subpage: left=" << left << ", top=" << top << ", width=" << width << ", height=" << height);
26 andreas 4107
            }
43 andreas 4108
#endif
41 andreas 4109
            ANIMATION_t ani;
4110
            ani.showEffect = pg->getShowEffect();
4111
            ani.showTime = pg->getShowTime();
42 andreas 4112
            ani.hideEffect = pg->getHideEffect();
4113
            ani.hideTime = pg->getHideTime();
54 andreas 4114
            // Test for a timer on the page
4115
            if (pg->getTimeout() > 0)
4116
                pg->startTimer();
4117
 
418 andreas 4118
            _setSubPage(pg->getHandle(), page->getHandle(), left, top, width, height, ani, pg->isModal());
26 andreas 4119
        }
293 andreas 4120
 
4121
        pg->show();
14 andreas 4122
    }
4123
}
4124
 
198 andreas 4125
void TPageManager::showSubPage(int number, bool force)
4126
{
4127
    DECL_TRACER("TPageManager::showSubPage(int number, bool force)");
4128
 
4129
    if (number <= 0)
4130
        return;
4131
 
4132
    TPage *page = nullptr;
4133
    TSubPage *pg = deliverSubPage(number, &page);
4134
 
4135
    if (!pg)
4136
        return;
4137
 
4138
    if (page)
350 andreas 4139
    {
4140
        pg->setParent(page->getHandle());
198 andreas 4141
        page->addSubPage(pg);
350 andreas 4142
    }
198 andreas 4143
 
4144
    string group = pg->getGroupName();
4145
 
4146
    if (!group.empty())
4147
    {
4148
        TSubPage *sub = getFirstSubPageGroup(group);
4149
 
4150
        while(sub)
4151
        {
4152
            if (sub->isVisible() && sub->getNumber() != pg->getNumber())
4153
                sub->drop();
4154
 
4155
            sub = getNextSubPageGroup(group, sub);
4156
        }
4157
    }
4158
 
4159
    if (pg->isVisible() && !force)
4160
    {
4161
        MSG_DEBUG("Page " << pg->getName() << " is already visible but maybe not on top.");
4162
 
4163
        TSubPage *sub = getFirstSubPage();
4164
        bool redraw = false;
4165
 
4166
        while (sub)
4167
        {
4168
            if (sub->isVisible() && pg->getZOrder() < sub->getZOrder() &&
4169
                overlap(sub->getLeft(), sub->getTop(), sub->getWidth(), sub->getHeight(),
4170
                        pg->getLeft(), pg->getTop(), pg->getWidth(), pg->getHeight()))
4171
            {
4172
                MSG_DEBUG("Page " << sub->getName() << " is overlapping page " << pg->getName());
4173
                redraw = true;
4174
                break;
4175
            }
4176
 
4177
            sub = getNextSubPage();
4178
        }
4179
 
4180
        if (redraw && _toFront)
4181
        {
300 andreas 4182
            _toFront((uint)pg->getHandle());
198 andreas 4183
            pg->setZOrder(page->getNextZOrder());
4184
            page->sortSubpages();
4185
            MSG_DEBUG("Setting new Z-order " << page->getActZOrder() << " on subpage " << pg->getName());
4186
        }
4187
        else if (redraw && !_toFront)
4188
            pg->drop();
4189
    }
4190
 
4191
    if (!pg->isVisible() || force)
4192
    {
4193
        if (!page)
4194
        {
4195
            MSG_ERROR("No active page found! Internal error.");
4196
            return;
4197
        }
4198
 
4199
        if (!haveSubPage(pg->getNumber()) && !page->addSubPage(pg))
4200
            return;
4201
 
4202
        if (!pg->isVisible())
4203
            pg->setZOrder(page->getNextZOrder());
4204
 
4205
        if (_setSubPage)
4206
        {
4207
            int left = pg->getLeft();
4208
            int top = pg->getTop();
4209
            int width = pg->getWidth();
4210
            int height = pg->getHeight();
262 andreas 4211
#ifdef _SCALE_SKIA_
198 andreas 4212
            if (mScaleFactor != 1.0)
4213
            {
4214
                left = (int)((double)left * mScaleFactor);
4215
                top = (int)((double)top * mScaleFactor);
4216
                width = (int)((double)width * mScaleFactor);
4217
                height = (int)((double)height * mScaleFactor);
4218
                MSG_DEBUG("Scaled subpage: left=" << left << ", top=" << top << ", width=" << width << ", height=" << height);
4219
            }
262 andreas 4220
#endif
198 andreas 4221
            ANIMATION_t ani;
4222
            ani.showEffect = pg->getShowEffect();
4223
            ani.showTime = pg->getShowTime();
4224
            ani.hideEffect = pg->getHideEffect();
4225
            ani.hideTime = pg->getHideTime();
4226
            // Test for a timer on the page
4227
            if (pg->getTimeout() > 0)
4228
                pg->startTimer();
4229
 
418 andreas 4230
            _setSubPage(pg->getHandle(), page->getHandle(), left, top, width, height, ani, pg->isModal());
198 andreas 4231
        }
4232
    }
4233
 
4234
    pg->show();
4235
}
4236
 
14 andreas 4237
void TPageManager::hideSubPage(const string& name)
4238
{
4239
    DECL_TRACER("TPageManager::hideSubPage(const string& name)");
4240
 
4241
    if (name.empty())
335 andreas 4242
    {
4243
#if TESTMODE == 1
4244
        setScreenDone();
4245
#endif
14 andreas 4246
        return;
335 andreas 4247
    }
14 andreas 4248
 
4249
    TPage *page = getPage(mActualPage);
4250
 
4251
    if (!page)
4252
    {
4253
        MSG_ERROR("No active page found! Internal error.");
335 andreas 4254
#if TESTMODE == 1
4255
        setScreenDone();
4256
#endif
14 andreas 4257
        return;
4258
    }
4259
 
4260
    TSubPage *pg = getSubPage(name);
4261
 
4262
    if (pg)
4263
    {
4264
        pg->drop();
154 andreas 4265
        page->decZOrder();
14 andreas 4266
    }
4267
}
4268
 
299 andreas 4269
/**
4270
 * @brief TPageManager::runClickQueue - Processing mouse clicks
4271
 * The following method is starting a thread which tests a queue containing
4272
 * the mouse clicks. To not drain the CPU, it sleeps for a short time if there
4273
 * are no more events in the queue.
4274
 * If there is an entry in the queue, it copies it to a local struct and
4275
 * deletes it from the queue. It take always the oldest antry (first entry)
4276
 * and removes this entry from the queue until the queue is empty. This makes
4277
 * it to a FIFO (first in, first out).
4278
 * Depending on the state of the variable "coords" the method for mouse
4279
 * coordinate click is executed or the method for a handle.
4280
 * The thread runs as long as the variable "mClickQueueRun" is TRUE and the
4281
 * variable "prg_stopped" is FALSE.
4282
 */
4283
void TPageManager::runClickQueue()
4284
{
4285
    DECL_TRACER("TPageManager::runClickQueue()");
4286
 
4287
    if (mClickQueueRun)
4288
        return;
4289
 
4290
    mClickQueueRun = true;
4291
 
4292
    try
4293
    {
4294
        std::thread thr = std::thread([=] {
300 andreas 4295
            MSG_PROTOCOL("Thread \"TPageManager::runClickQueue()\" was started.");
4296
 
299 andreas 4297
            while (mClickQueueRun && !prg_stopped)
4298
            {
300 andreas 4299
                while (!mClickQueue.empty())
299 andreas 4300
                {
4301
#ifdef QT_DEBUG
300 andreas 4302
                    if (mClickQueue[0].coords)
4303
                        MSG_TRACE("TPageManager::runClickQueue() -- executing: _mouseEvent(" << mClickQueue[0].x << ", " << mClickQueue[0].y << ", " << (mClickQueue[0].pressed ? "TRUE" : "FALSE") << ")")
299 andreas 4304
                    else
300 andreas 4305
                        MSG_TRACE("TPageManager::runClickQueue() -- executing: _mouseEvent(" << handleToString(mClickQueue[0].handle) << ", " << (mClickQueue[0].pressed ? "TRUE" : "FALSE") << ")")
299 andreas 4306
#endif
409 andreas 4307
                    if (mClickQueue[0].eventType == _EVENT_MOUSE_CLICK)
4308
                    {
4309
                        if (mClickQueue[0].coords)
4310
                            _mouseEvent(mClickQueue[0].x, mClickQueue[0].y, mClickQueue[0].pressed);
4311
                        else
4312
                            _mouseEvent(mClickQueue[0].handle, mClickQueue[0].handle);
4313
                    }
4314
                    else  if (mClickQueue[0].eventType == _EVENT_MOUSE_MOVE)
4315
                        _mouseMoveEvent(mClickQueue[0].x, mClickQueue[0].y);
300 andreas 4316
 
299 andreas 4317
                    mClickQueue.erase(mClickQueue.begin()); // Remove first entry
4318
                }
4319
 
4320
                std::this_thread::sleep_for(std::chrono::microseconds(10));
4321
            }
4322
 
303 andreas 4323
            mClickQueueRun = false;
299 andreas 4324
            return;
4325
        });
4326
 
4327
        thr.detach();
4328
    }
4329
    catch (std::exception& e)
4330
    {
300 andreas 4331
        MSG_ERROR("Error starting a thread to handle the click queue: " << e.what());
299 andreas 4332
        mClickQueueRun = false;
4333
    }
4334
}
4335
 
303 andreas 4336
void TPageManager::runUpdateSubViewItem()
4337
{
4338
    DECL_TRACER("TPageManager::runUpdateSubViewItem()");
299 andreas 4339
 
303 andreas 4340
    if (mUpdateViewsRun)
4341
        return;
4342
 
4343
    mUpdateViewsRun = true;
4344
 
4345
    try
4346
    {
4347
        std::thread thr = std::thread([=] {
4348
            MSG_PROTOCOL("Thread \"TPageManager::runUpdateSubViewItem()\" was started.");
4349
 
4350
            while (mUpdateViewsRun && !prg_stopped)
4351
            {
4352
                while (!mUpdateViews.empty())
4353
                {
4354
                    _updateSubViewItem(mUpdateViews[0]);
4355
                    mUpdateViews.erase(mUpdateViews.begin()); // Remove first entry
4356
                }
4357
 
4358
                std::this_thread::sleep_for(std::chrono::microseconds(10));
4359
            }
4360
 
4361
            mUpdateViewsRun = false;
4362
            return;
4363
        });
4364
 
4365
        thr.detach();
4366
    }
4367
    catch (std::exception& e)
4368
    {
4369
        MSG_ERROR("Error starting a thread to handle the click queue: " << e.what());
4370
        mUpdateViewsRun = false;
4371
    }
4372
}
4373
 
11 andreas 4374
/*
4375
 * Catch the mouse presses and scan all pages and subpages for an element to
4376
 * receive the klick.
4377
 */
10 andreas 4378
void TPageManager::mouseEvent(int x, int y, bool pressed)
4379
{
4380
    DECL_TRACER("TPageManager::mouseEvent(int x, int y, bool pressed)");
4381
 
316 andreas 4382
    TTRYLOCK(click_mutex);
299 andreas 4383
 
4384
    _CLICK_QUEUE_t cq;
409 andreas 4385
    cq.eventType = _EVENT_MOUSE_CLICK;
299 andreas 4386
    cq.x = x;
4387
    cq.y = y;
4388
    cq.pressed = pressed;
4389
    cq.coords = true;
4390
    mClickQueue.push_back(cq);
334 andreas 4391
#if TESTMODE == 1
4392
    setScreenDone();
4393
#endif
299 andreas 4394
}
4395
 
409 andreas 4396
void TPageManager::mouseMoveEvent(int x, int y)
4397
{
4398
    DECL_TRACER("TPageManager::mouseMoveEvent(int x, int y)");
4399
 
4400
    TTRYLOCK(click_mutex);
4401
 
4402
    _CLICK_QUEUE_t cq;
4403
    cq.eventType = _EVENT_MOUSE_MOVE;
4404
    cq.x = x;
4405
    cq.y = y;
4406
    cq.coords = true;
4407
    mClickQueue.push_back(cq);
4408
#if TESTMODE == 1
4409
    setScreenDone();
4410
#endif
4411
}
4412
 
299 andreas 4413
void TPageManager::_mouseEvent(int x, int y, bool pressed)
4414
{
4415
    DECL_TRACER("TPageManager::_mouseEvent(int x, int y, bool pressed)");
4416
 
16 andreas 4417
    TError::clear();
334 andreas 4418
#if TESTMODE == 1
4419
    if (_gTestMode)
4420
        _gTestMode->setMouseClick(x, y, pressed);
4421
#endif
11 andreas 4422
    int realX = x - mFirstLeftPixel;
4423
    int realY = y - mFirstTopPixel;
263 andreas 4424
 
31 andreas 4425
    MSG_DEBUG("Mouse at " << realX << ", " << realY << ", state " << ((pressed) ? "PRESSED" : "RELEASED") << ", [ " << x << " | " << y << " ]");
43 andreas 4426
#ifdef _SCALE_SKIA_
100 andreas 4427
    if (mScaleFactor != 1.0 && mScaleFactor > 0.0)
26 andreas 4428
    {
4429
        realX = (int)((double)realX / mScaleFactor);
4430
        realY = (int)((double)realY / mScaleFactor);
31 andreas 4431
        MSG_DEBUG("Scaled coordinates: x=" << realX << ", y=" << realY);
26 andreas 4432
    }
43 andreas 4433
#endif
70 andreas 4434
 
154 andreas 4435
    TSubPage *subPage = nullptr;
11 andreas 4436
 
154 andreas 4437
    if (pressed)
4438
        subPage = getCoordMatch(realX, realY);
318 andreas 4439
    else if (mLastPagePush)
154 andreas 4440
        subPage = getSubPage(mLastPagePush);
4441
    else
4442
        subPage = getCoordMatch(realX, realY);
4443
 
11 andreas 4444
    if (!subPage)
14 andreas 4445
    {
146 andreas 4446
        Button::TButton *bt = getCoordMatchPage(realX, realY);
40 andreas 4447
 
4448
        if (bt)
4449
        {
4450
            MSG_DEBUG("Button on page " << bt->getButtonIndex() << ": size: left=" << bt->getLeftPosition() << ", top=" << bt->getTopPosition() << ", width=" << bt->getWidth() << ", height=" << bt->getHeight());
4451
            bt->doClick(x - bt->getLeftPosition(), y - bt->getTopPosition(), pressed);
4452
        }
4453
 
419 andreas 4454
        if (pressed)
4455
            mLastPagePush = getActualPageNumber();
4456
 
11 andreas 4457
        return;
14 andreas 4458
    }
11 andreas 4459
 
154 andreas 4460
    MSG_DEBUG("Subpage " << subPage->getNumber() << " [" << subPage->getName() << "]: size: left=" << subPage->getLeft() << ", top=" << subPage->getTop() << ", width=" << subPage->getWidth() << ", height=" << subPage->getHeight());
4461
 
4462
    if (pressed)
4463
        mLastPagePush = subPage->getNumber();
4464
    else
4465
        mLastPagePush = 0;
4466
 
11 andreas 4467
    subPage->doClick(realX - subPage->getLeft(), realY - subPage->getTop(), pressed);
10 andreas 4468
}
11 andreas 4469
 
409 andreas 4470
void TPageManager::_mouseMoveEvent(int x, int y)
4471
{
4472
    DECL_TRACER("TPageManager::_mouseMoveEvent(int x, int y)");
4473
 
4474
    int realX = x - mFirstLeftPixel;
4475
    int realY = y - mFirstTopPixel;
4476
 
4477
#ifdef _SCALE_SKIA_
4478
    if (mScaleFactor != 1.0 && mScaleFactor > 0.0)
4479
    {
4480
        realX = (int)((double)realX / mScaleFactor);
4481
        realY = (int)((double)realY / mScaleFactor);
4482
        MSG_DEBUG("Scaled coordinates: x=" << realX << ", y=" << realY);
4483
    }
4484
#endif
4485
 
4486
    TSubPage *subPage = nullptr;
4487
    subPage = getCoordMatch(realX, realY);
4488
 
4489
    if (!subPage)
4490
    {
4491
        Button::TButton *bt = getCoordMatchPage(realX, realY);
4492
 
416 andreas 4493
        if (bt)
4494
        {
4495
            if (bt->getButtonType() == BARGRAPH)
4496
                bt->moveBargraphLevel(realX - bt->getLeftPosition(), realY - bt->getTopPosition());
418 andreas 4497
            else if (bt->getButtonType() == JOYSTICK && !bt->getLevelFuction().empty())
416 andreas 4498
            {
4499
                bt->drawJoystick(realX - bt->getLeftPosition(), realY - bt->getTopPosition());
4500
                // Send the levels
4501
                bt->sendJoystickLevels();
4502
            }
4503
        }
409 andreas 4504
 
4505
        return;
4506
    }
4507
 
4508
    subPage->moveMouse(realX - subPage->getLeft(), realY - subPage->getTop());
4509
}
4510
 
289 andreas 4511
void TPageManager::mouseEvent(ulong handle, bool pressed)
4512
{
4513
    DECL_TRACER("TPageManager::mouseEvent(ulong handle, bool pressed)");
4514
 
320 andreas 4515
    if (!mClickQueue.empty() && mClickQueue.back().handle == handle && mClickQueue.back().pressed == pressed)
4516
        return;
4517
 
299 andreas 4518
    TLOCKER(click_mutex);
293 andreas 4519
 
299 andreas 4520
    _CLICK_QUEUE_t cq;
4521
    cq.handle = handle;
4522
    cq.pressed = pressed;
4523
    mClickQueue.push_back(cq);
4524
    MSG_DEBUG("Queued click for handle " << handleToString(cq.handle) << " state " << (cq.pressed ? "PRESSED" : "RELEASED"));
4525
}
4526
 
4527
void TPageManager::_mouseEvent(ulong handle, bool pressed)
4528
{
4529
    DECL_TRACER("TPageManager::_mouseEvent(ulong handle, bool pressed)");
4530
 
293 andreas 4531
    MSG_DEBUG("Doing click for handle " << handleToString(handle) << " state " << (pressed ? "PRESSED" : "RELEASED"));
4532
 
289 andreas 4533
    if (!handle)
4534
        return;
4535
 
4536
    int pageID = (handle >> 16) & 0x0000ffff;
4537
    int buttonID = (handle & 0x0000ffff);
4538
 
318 andreas 4539
    if (pageID < REGULAR_SUBPAGE_START || buttonID == 0)
289 andreas 4540
        return;
4541
 
4542
    TSubPage *subPage = getSubPage(pageID);
4543
 
4544
    if (subPage)
4545
    {
4546
        Button::TButton *bt = subPage->getButton(buttonID);
4547
 
4548
        if (bt)
4549
        {
318 andreas 4550
            MSG_DEBUG("Button on subpage " << pageID << ": " << buttonID);
289 andreas 4551
            bt->doClick(bt->getLeftPosition() + bt->getWidth() / 2, bt->getTopPosition() + bt->getHeight() / 2, pressed);
4552
        }
4553
    }
4554
}
4555
 
192 andreas 4556
void TPageManager::inputButtonFinished(ulong handle, const std::string &content)
4557
{
4558
    DECL_TRACER("TPageManager::inputButtonFinished(ulong handle, const std::string &content)");
4559
 
4560
    Button::TButton *bt = findButton(handle);
4561
 
4562
    if (!bt)
4563
    {
271 andreas 4564
        MSG_WARNING("Invalid button handle " << handleToString(handle));
192 andreas 4565
        return;
4566
    }
4567
 
4568
    bt->setTextOnly(content, -1);
4569
}
4570
 
309 andreas 4571
void TPageManager::inputCursorPositionChanged(ulong handle, int oldPos, int newPos)
4572
{
4573
    DECL_TRACER("TPageManager::inputCursorPositionChanged(ulong handle, int oldPos, int newPos)");
4574
 
4575
    Button::TButton *bt = findButton(handle);
4576
 
4577
    if (!bt)
4578
    {
4579
        MSG_WARNING("Invalid button handle " << handleToString(handle));
4580
        return;
4581
    }
4582
 
310 andreas 4583
    ulong pageID = (bt->getHandle() >> 16) & 0x0000ffff;
309 andreas 4584
 
4585
    if (pageID < REGULAR_SUBPAGE_START)
4586
    {
368 andreas 4587
        TPage *pg = getPage((int)pageID);
309 andreas 4588
 
4589
        if (!pg)
4590
            return;
4591
 
4592
        pg->setCursorPosition(handle, oldPos, newPos);
4593
    }
4594
    else
4595
    {
368 andreas 4596
        TSubPage *pg = getSubPage((int)pageID);
309 andreas 4597
 
4598
        if (!pg)
4599
            return;
4600
 
4601
        pg->setCursorPosition(handle, oldPos, newPos);
4602
    }
4603
}
4604
 
4605
void TPageManager::inputFocusChanged(ulong handle, bool in)
4606
{
4607
    DECL_TRACER("TPageManager::inputFocusChanged(ulong handle, bool in)");
4608
 
4609
    Button::TButton *bt = findButton(handle);
4610
 
4611
    if (!bt)
4612
    {
4613
        MSG_WARNING("Invalid button handle " << handleToString(handle));
4614
        return;
4615
    }
4616
 
310 andreas 4617
    ulong pageID = (bt->getHandle() >> 16) & 0x0000ffff;
4618
    MSG_DEBUG("Searching for page " << pageID);
309 andreas 4619
 
4620
    if (pageID < REGULAR_SUBPAGE_START)
4621
    {
368 andreas 4622
        TPage *pg = getPage((int)pageID);
309 andreas 4623
 
4624
        if (!pg)
4625
            return;
4626
 
4627
        pg->setInputFocus(handle, in);
4628
    }
4629
    else
4630
    {
368 andreas 4631
        TSubPage *pg = getSubPage((int)pageID);
309 andreas 4632
 
4633
        if (!pg)
4634
            return;
4635
 
4636
        pg->setInputFocus(handle, in);
4637
    }
4638
}
4639
 
208 andreas 4640
void TPageManager::setTextToButton(ulong handle, const string& txt, bool redraw)
51 andreas 4641
{
208 andreas 4642
    DECL_TRACER("TPageManager::setTextToButton(ulong handle, const string& txt, bool redraw)");
51 andreas 4643
 
4644
    // First we search for the button the handle points to
4645
    Button::TButton *button = findButton(handle);
4646
 
4647
    if (!button)
4648
    {
271 andreas 4649
        MSG_ERROR("No button with handle " << handleToString(handle) << " found!");
51 andreas 4650
        return;
4651
    }
4652
 
4653
    // Now we search for all buttons with the same channel and port number
4654
    vector<int> channels;
4655
    channels.push_back(button->getAddressChannel());
193 andreas 4656
    vector<TMap::MAP_T> map = findButtons(button->getAddressPort(), channels);
51 andreas 4657
 
4658
    if (TError::isError() || map.empty())
4659
        return;
4660
 
4661
    // Here we load all buttons found.
4662
    vector<Button::TButton *> buttons = collectButtons(map);
83 andreas 4663
 
4664
    if (buttons.size() > 0)
51 andreas 4665
    {
83 andreas 4666
        vector<Button::TButton *>::iterator mapIter;
4667
        // Finaly we iterate through all found buttons and set the text
118 andreas 4668
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
83 andreas 4669
        {
4670
            Button::TButton *bt = *mapIter;
51 andreas 4671
 
208 andreas 4672
            if (redraw)
4673
                bt->setText(txt, -1);
4674
            else
4675
                bt->setTextOnly(txt, -1);
83 andreas 4676
        }
51 andreas 4677
    }
4678
}
4679
 
193 andreas 4680
vector<Button::TButton *> TPageManager::collectButtons(vector<TMap::MAP_T>& map)
14 andreas 4681
{
193 andreas 4682
    DECL_TRACER("TPageManager::collectButtons(vector<TMap::MAP_T>& map)");
14 andreas 4683
 
4684
    vector<Button::TButton *> buttons;
83 andreas 4685
 
4686
    if (map.size() == 0)
4687
        return buttons;
4688
 
193 andreas 4689
    vector<TMap::MAP_T>::iterator iter;
14 andreas 4690
 
118 andreas 4691
    for (iter = map.begin(); iter != map.end(); ++iter)
14 andreas 4692
    {
209 andreas 4693
        if (iter->pg < REGULAR_SUBPAGE_START || (iter->pg >= SYSTEM_PAGE_START && iter->pg < SYSTEM_SUBPAGE_START))     // Main page?
14 andreas 4694
        {
4695
            TPage *page;
4696
 
4697
            if ((page = getPage(iter->pg)) == nullptr)
4698
            {
4699
                MSG_TRACE("Page " << iter->pg << ", " << iter->pn << " not found in memory. Reading it ...");
4700
 
4701
                if (!readPage(iter->pg))
4702
                    return buttons;
4703
 
4704
                page = getPage(iter->pg);
4705
            }
4706
 
4707
            Button::TButton *bt = page->getButton(iter->bt);
4708
 
4709
            if (bt)
4710
                buttons.push_back(bt);
4711
        }
4712
        else
4713
        {
4714
            TSubPage *subpage;
4715
 
4716
            if ((subpage = getSubPage(iter->pg)) == nullptr)
4717
            {
4718
                MSG_TRACE("Subpage " << iter->pg << ", " << iter->pn << " not found in memory. Reading it ...");
4719
 
4720
                if (!readSubPage(iter->pg))
4721
                    return buttons;
4722
 
4723
                subpage = getSubPage(iter->pg);
4724
                TPage *page = getActualPage();
4725
 
4726
                if (!page)
4727
                {
4728
                    MSG_ERROR("No actual page loaded!");
4729
                    return buttons;
4730
                }
4731
            }
4732
 
4733
            Button::TButton *bt = subpage->getButton(iter->bt);
4734
 
4735
            if (bt)
4736
                buttons.push_back(bt);
4737
        }
4738
    }
4739
 
4740
    return buttons;
4741
}
4742
 
11 andreas 4743
/****************************************************************************
36 andreas 4744
 * Calls from a Java activity. This is only available for Android OS.
4745
 ****************************************************************************/
182 andreas 4746
#ifdef Q_OS_ANDROID
36 andreas 4747
void TPageManager::initNetworkState()
4748
{
4749
    DECL_TRACER("TPageManager::initNetworkState()");
264 andreas 4750
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
36 andreas 4751
    QAndroidJniObject activity = QtAndroid::androidActivity();
4752
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "Init", "(Landroid/app/Activity;)V", activity.object());
4753
    activity.callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "InstallNetworkListener", "()V");
182 andreas 4754
#else
4755
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4756
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "Init", "(Landroid/app/Activity;)V", activity.object());
4757
    activity.callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "InstallNetworkListener", "()V");
4758
#endif
36 andreas 4759
}
4760
 
4761
void TPageManager::stopNetworkState()
4762
{
4763
    DECL_TRACER("TPageManager::stopNetworkState()");
264 andreas 4764
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
36 andreas 4765
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "destroyNetworkListener", "()V");
182 andreas 4766
#else
4767
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "destroyNetworkListener", "()V");
4768
#endif
36 andreas 4769
}
38 andreas 4770
 
4771
void TPageManager::initBatteryState()
4772
{
4773
    DECL_TRACER("TPageManager::initBatteryState()");
264 andreas 4774
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
38 andreas 4775
    QAndroidJniObject activity = QtAndroid::androidActivity();
4776
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "Init", "(Landroid/app/Activity;)V", activity.object());
182 andreas 4777
#else
4778
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4779
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "Init", "(Landroid/app/Activity;)V", activity.object());
4780
#endif
38 andreas 4781
    activity.callStaticMethod<void>("org/qtproject/theosys/BatteryState", "InstallBatteryListener", "()V");
4782
}
4783
 
61 andreas 4784
void TPageManager::initPhoneState()
4785
{
4786
    DECL_TRACER("TPageManager::initPhoneState()");
264 andreas 4787
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
61 andreas 4788
    QAndroidJniObject activity = QtAndroid::androidActivity();
4789
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/PhoneCallState", "Init", "(Landroid/app/Activity;)V", activity.object());
182 andreas 4790
#else
4791
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4792
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/PhoneCallState", "Init", "(Landroid/app/Activity;)V", activity.object());
4793
#endif
61 andreas 4794
    activity.callStaticMethod<void>("org/qtproject/theosys/PhoneCallState", "InstallPhoneListener", "()V");
4795
}
4796
 
38 andreas 4797
void TPageManager::stopBatteryState()
4798
{
4799
    DECL_TRACER("TPageManager::stopBatteryState()");
264 andreas 4800
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
38 andreas 4801
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "destroyBatteryListener", "()V");
182 andreas 4802
#else
4803
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "destroyBatteryListener", "()V");
4804
#endif
38 andreas 4805
}
4806
 
36 andreas 4807
void TPageManager::informTPanelNetwork(jboolean conn, jint level, jint type)
4808
{
250 andreas 4809
    DECL_TRACER("TPageManager::informTPanelNetwork(jboolean conn, jint level, jint type)");
36 andreas 4810
 
4811
    int l = 0;
4812
    string sType;
4813
 
4814
    switch (type)
4815
    {
4816
        case 1: sType = "Wifi"; break;
4817
        case 2: sType = "Mobile"; break;
4818
 
4819
        default:
4820
            sType = "Unknown"; break;
4821
    }
4822
 
4823
    if (conn)
4824
        l = level;
4825
 
93 andreas 4826
    if (mNetState && mNetState != type)     // Has the connection type changed?
4827
    {
4828
        if (gAmxNet)
4829
            gAmxNet->reconnect();
4830
    }
4831
 
4832
    mNetState = type;
4833
 
36 andreas 4834
    MSG_INFO("Connection status: " << (conn ? "Connected" : "Disconnected") << ", level: " << level << ", type: " << sType);
4835
 
83 andreas 4836
    if (mNetCalls.size() > 0)
36 andreas 4837
    {
83 andreas 4838
        std::map<int, std::function<void (int level)> >::iterator iter;
4839
 
4840
        for (iter = mNetCalls.begin(); iter != mNetCalls.end(); ++iter)
4841
            iter->second(l);
36 andreas 4842
    }
4843
}
38 andreas 4844
 
4845
void TPageManager::informBatteryStatus(jint level, jboolean charging, jint chargeType)
4846
{
4847
    DECL_TRACER("TPageManager::informBatteryStatus(jint level, jboolean charging, jint chargeType)");
4848
 
59 andreas 4849
    MSG_INFO("Battery status: level: " << level << ", " << (charging ? "Charging" : "not charging") << ", type: " << chargeType << ", Elements: " << mBatteryCalls.size());
38 andreas 4850
 
83 andreas 4851
    if (mBatteryCalls.size() > 0)
38 andreas 4852
    {
83 andreas 4853
        std::map<int, std::function<void (int, bool, int)> >::iterator iter;
4854
 
4855
        for (iter = mBatteryCalls.begin(); iter != mBatteryCalls.end(); ++iter)
4856
            iter->second(level, charging, chargeType);
38 andreas 4857
    }
4858
}
61 andreas 4859
 
4860
void TPageManager::informPhoneState(bool call, const string &pnumber)
4861
{
4862
    DECL_TRACER("TPageManager::informPhoneState(bool call, const string &pnumber)");
4863
 
4864
    MSG_INFO("Call state: " << (call ? "Call in progress" : "No call") << ", phone number: " << pnumber);
4865
 
4866
    if (!gAmxNet)
4867
    {
4868
        MSG_WARNING("The network manager for the AMX controller is not initialized!");
4869
        return;
4870
    }
4871
}
130 andreas 4872
 
4873
void TPageManager::initOrientation()
4874
{
4875
    DECL_TRACER("TPageManager::initOrientation()");
4876
 
131 andreas 4877
    int rotate = getSettings()->getRotate();
264 andreas 4878
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
130 andreas 4879
    QAndroidJniObject activity = QtAndroid::androidActivity();
131 andreas 4880
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Orientation", "Init", "(Landroid/app/Activity;I)V", activity.object(), rotate);
182 andreas 4881
#else
4882
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4883
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Orientation", "Init", "(Landroid/app/Activity;I)V", activity.object(), rotate);
4884
#endif
130 andreas 4885
    activity.callStaticMethod<void>("org/qtproject/theosys/Orientation", "InstallOrientationListener", "()V");
4886
}
255 andreas 4887
 
4888
void TPageManager::enterSetup()
4889
{
260 andreas 4890
    DECL_TRACER("TPageManager::enterSetup()");
264 andreas 4891
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
255 andreas 4892
    QAndroidJniObject activity = QtAndroid::androidActivity();
4893
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "callSettings", "(Landroid/app/Activity;)V", activity.object());
4894
#else
4895
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4896
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "callSettings", "(Landroid/app/Activity;)V", activity.object());
4897
#endif
4898
}
59 andreas 4899
#endif  // __ANDROID__
247 andreas 4900
#ifdef Q_OS_IOS
4901
void TPageManager::informBatteryStatus(int level, int state)
4902
{
4903
    DECL_TRACER("TPageManager::informBatteryStatus(int level, int state)");
36 andreas 4904
 
247 andreas 4905
    MSG_INFO("Battery status: level: " << level << ", " << state);
4906
 
4907
    if (mBatteryCalls.size() > 0)
4908
    {
4909
        std::map<int, std::function<void (int, int)> >::iterator iter;
4910
 
4911
        for (iter = mBatteryCalls.begin(); iter != mBatteryCalls.end(); ++iter)
4912
            iter->second(level, state);
4913
    }
4914
}
250 andreas 4915
 
4916
void TPageManager::informTPanelNetwork(bool conn, int level, int type)
4917
{
4918
    DECL_TRACER("TPageManager::informTPanelNetwork(bool conn, int level, int type)");
4919
 
4920
    int l = 0;
4921
    string sType;
4922
 
4923
    switch (type)
4924
    {
4925
        case 1: sType = "Ethernet"; break;
4926
        case 2: sType = "Mobile"; break;
4927
        case 3: sType = "WiFi"; break;
4928
        case 4: sType = "Bluetooth"; break;
4929
 
4930
        default:
4931
            sType = "Unknown"; break;
4932
    }
4933
 
4934
    if (conn)
4935
        l = level;
4936
 
4937
    if (mNetState && mNetState != type)     // Has the connection type changed?
4938
    {
4939
        if (gAmxNet)
4940
            gAmxNet->reconnect();
4941
    }
4942
 
4943
    mNetState = type;
4944
 
4945
    MSG_INFO("Connection status: " << (conn ? "Connected" : "Disconnected") << ", level: " << level << ", type: " << sType);
4946
 
4947
    if (mNetCalls.size() > 0)
4948
    {
4949
        std::map<int, std::function<void (int level)> >::iterator iter;
4950
 
4951
        for (iter = mNetCalls.begin(); iter != mNetCalls.end(); ++iter)
4952
            iter->second(l);
4953
    }
4954
}
4955
 
247 andreas 4956
#endif
4957
 
60 andreas 4958
void TPageManager::setButtonCallbacks(Button::TButton *bt)
4959
{
227 andreas 4960
    DECL_TRACER("TPageManager::setButtonCallbacks(Button::TButton *bt)");
4961
 
162 andreas 4962
    if (!bt)
4963
        return;
4964
 
60 andreas 4965
    bt->registerCallback(_displayButton);
4966
    bt->regCallPlayVideo(_callPlayVideo);
4967
    bt->setFonts(mFonts);
4968
    bt->setPalette(mPalette);
4969
}
4970
 
4971
void TPageManager::externalButton(extButtons_t bt, bool checked)
4972
{
4973
    DECL_TRACER("TPageManager::externalButton(extButtons_t bt)");
4974
 
4975
    if (!mExternal)
4976
        return;
4977
 
4978
    EXTBUTTON_t button = mExternal->getButton(bt);
4979
 
4980
    if (button.type == EXT_NOBUTTON)
4981
        return;
4982
 
4983
    if (button.cp && button.ch)
4984
    {
4985
        amx::ANET_SEND scmd;
4986
 
4987
        scmd.device = TConfig::getChannel();
4988
        scmd.port = button.cp;
4989
        scmd.channel = button.ch;
4990
 
4991
        if (checked)
4992
            scmd.MC = 0x0084;   // push button
134 andreas 4993
        else
4994
            scmd.MC = 0x0085;   // release button
60 andreas 4995
 
134 andreas 4996
        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 4997
 
134 andreas 4998
        if (gAmxNet)
4999
            gAmxNet->sendCommand(scmd);
5000
        else
5001
        {
5002
            MSG_WARNING("Missing global class TAmxNet. Can't send a message!");
5003
        }
60 andreas 5004
    }
5005
}
5006
 
62 andreas 5007
void TPageManager::sendKeyboard(const std::string& text)
5008
{
5009
    DECL_TRACER("TPageManager::sendKeyboard(const std::string& text)");
5010
 
5011
    amx::ANET_SEND scmd;
5012
    scmd.port = 1;
5013
    scmd.channel = 0;
5014
    scmd.msg = UTF8ToCp1250(text);
5015
    scmd.MC = 0x008b;
441 andreas 5016
    MSG_DEBUG("Sending keyboard: " << text);
62 andreas 5017
 
5018
    if (gAmxNet)
5019
        gAmxNet->sendCommand(scmd);
5020
    else
5021
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
5022
}
5023
 
5024
void TPageManager::sendKeypad(const std::string& text)
5025
{
5026
    DECL_TRACER("TPageManager::sendKeypad(const std::string& text)");
5027
 
269 andreas 5028
    sendKeyboard(text);
62 andreas 5029
}
5030
 
5031
void TPageManager::sendString(uint handle, const std::string& text)
5032
{
5033
    DECL_TRACER("TPageManager::sendString(uint handle, const std::string& text)");
5034
 
5035
    Button::TButton *bt = findButton(handle);
5036
 
5037
    if (!bt)
5038
    {
271 andreas 5039
        MSG_WARNING("Button " << handleToString(handle) << " not found!");
62 andreas 5040
        return;
5041
    }
5042
 
5043
    amx::ANET_SEND scmd;
5044
    scmd.port = bt->getAddressPort();
5045
    scmd.channel = bt->getAddressChannel();
5046
    scmd.msg = UTF8ToCp1250(text);
5047
    scmd.MC = 0x008b;
5048
 
5049
    if (gAmxNet)
5050
        gAmxNet->sendCommand(scmd);
5051
    else
5052
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
5053
}
5054
 
134 andreas 5055
void TPageManager::sendGlobalString(const string& text)
5056
{
5057
    DECL_TRACER("TPageManager::sendGlobalString(const string& text)");
5058
 
5059
    if (text.empty() || text.find("-") == string::npos)
5060
        return;
5061
 
5062
    amx::ANET_SEND scmd;
5063
    scmd.port = 1;
5064
    scmd.channel = 0;
5065
    scmd.msg = text;
5066
    scmd.MC = 0x008b;
5067
 
5068
    if (gAmxNet)
5069
        gAmxNet->sendCommand(scmd);
5070
    else
5071
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
5072
}
5073
 
147 andreas 5074
void TPageManager::sendCommandString(int port, const string& cmd)
5075
{
5076
    DECL_TRACER("TPageManager::sendGlobalString(const string& text)");
5077
 
5078
    if (cmd.empty())
5079
        return;
5080
 
5081
    amx::ANET_SEND scmd;
5082
    scmd.port = port;
5083
    scmd.channel = 0;
5084
    scmd.msg = cmd;
5085
    scmd.MC = 0x008c;
5086
 
5087
    if (gAmxNet)
5088
        gAmxNet->sendCommand(scmd);
5089
    else
5090
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
5091
}
5092
 
428 andreas 5093
void TPageManager::sendLevel(int lp, int lv, int level)
5094
{
5095
    DECL_TRACER("TPageManager::sendLevel(int lp, int lv, int level)");
5096
 
5097
    if (!lv)
5098
        return;
5099
 
5100
    amx::ANET_SEND scmd;
5101
    scmd.device = TConfig::getChannel();
5102
    scmd.port = lp;
5103
    scmd.channel = lv;
5104
    scmd.level = lv;
5105
    scmd.MC = 0x008a;
5106
    scmd.value = level;
5107
 
5108
    if (gAmxNet)
5109
        gAmxNet->sendCommand(scmd);
5110
    else
5111
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
5112
}
5113
 
5114
void TPageManager::sendInternalLevel(int lp, int lv, int level)
5115
{
5116
    DECL_TRACER("TPageManager::sendInternalLevel(int lp, int lv, int level)");
5117
 
5118
    amx::ANET_COMMAND cmd;
429 andreas 5119
    int channel = TConfig::getChannel();
5120
    int system = TConfig::getSystem();
5121
 
428 andreas 5122
    cmd.MC = 0x000a;
429 andreas 5123
    cmd.device1 = channel;
428 andreas 5124
    cmd.port1 = lp;
429 andreas 5125
    cmd.system = system;
5126
    cmd.data.message_value.system = system;
5127
    cmd.data.message_value.device = channel;
428 andreas 5128
    cmd.data.message_value.port = lp;           // Must be the address port of bargraph
5129
    cmd.data.message_value.value = lv;          // Must be the level channel of bargraph
5130
    cmd.data.message_value.type = DTSZ_UINT;    // unsigned integer
5131
    cmd.data.message_value.content.sinteger = level;
5132
    doCommand(cmd);
5133
}
5134
 
123 andreas 5135
void TPageManager::sendPHNcommand(const std::string& cmd)
5136
{
5137
    DECL_TRACER("TPageManager::sendPHNcommand(const std::string& cmd)");
5138
 
5139
    amx::ANET_SEND scmd;
144 andreas 5140
    scmd.port = mTSettings->getSettings().voipCommandPort;
123 andreas 5141
    scmd.channel = TConfig::getChannel();
5142
    scmd.msg = "^PHN-" + cmd;
127 andreas 5143
    scmd.MC = 0x008c;
5144
    MSG_DEBUG("Sending PHN command: ^PHN-" << cmd);
123 andreas 5145
 
5146
    if (gAmxNet)
5147
        gAmxNet->sendCommand(scmd);
5148
    else
5149
        MSG_WARNING("Missing global class TAmxNet. Can't send ^PHN command!");
5150
}
5151
 
111 andreas 5152
void TPageManager::sendKeyStroke(char key)
5153
{
5154
    DECL_TRACER("TPageManager::sendKeyStroke(char key)");
5155
 
5156
    if (!key)
5157
        return;
5158
 
5159
    char msg[2];
5160
    msg[0] = key;
5161
    msg[1] = 0;
5162
 
5163
    amx::ANET_SEND scmd;
5164
    scmd.port = 1;
5165
    scmd.channel = 0;
5166
    scmd.msg.assign(msg);
127 andreas 5167
    scmd.MC = 0x008c;
111 andreas 5168
 
5169
    if (gAmxNet)
5170
        gAmxNet->sendCommand(scmd);
5171
    else
5172
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
5173
}
5174
 
110 andreas 5175
/**
5176
 * Sending a custom event is identical in all cases. Because of this I
5177
 * implemented this method to send a custom event. This is called in all cases
5178
 * where a ?XXX command is received.
5179
 *
5180
 * @param value1    The instance of the button.
5181
 * @param value2    The value of a numeric request or the length of the string.
5182
 * @param value3    Always 0
5183
 * @param msg       In case of a string this contains the string.
5184
 * @param evType    This is the event type, a number between 1001 and 1099.
5185
 * @param cp        Channel port of button.
5186
 * @param cn        Channel number. of button.
5187
 *
5188
 * @return If all parameters are valid it returns TRUE.
5189
 */
5190
bool TPageManager::sendCustomEvent(int value1, int value2, int value3, const string& msg, int evType, int cp, int cn)
5191
{
5192
    DECL_TRACER("TPageManager::sendCustomEvent(int value1, int value2, int value3, const string& msg, int evType)");
5193
 
5194
    if (value1 < 1)
5195
        return false;
5196
 
5197
    amx::ANET_SEND scmd;
5198
    scmd.port = cp;
5199
    scmd.channel = cn;
5200
    scmd.ID = scmd.channel;
5201
    scmd.flag = 0;
5202
    scmd.type = evType;
5203
    scmd.value1 = value1;   // instance
5204
    scmd.value2 = value2;
5205
    scmd.value3 = value3;
5206
    scmd.msg = msg;
5207
 
5208
    if (!msg.empty())
5209
        scmd.dtype = 0x0001;// Char array
5210
 
5211
    scmd.MC = 0x008d;       // custom event
5212
 
5213
    if (gAmxNet)
5214
        gAmxNet->sendCommand(scmd);
5215
    else
5216
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
5217
 
5218
    return true;
5219
}
129 andreas 5220
#ifndef _NOSIP_
127 andreas 5221
string TPageManager::sipStateToString(TSIPClient::SIP_STATE_t s)
5222
{
5223
    DECL_TRACER("TPageManager::sipStateToString(TSIPClient::SIP_STATE_t s)");
5224
 
5225
    switch(s)
5226
    {
5227
        case TSIPClient::SIP_CONNECTED:     return "CONNECTED";
5228
        case TSIPClient::SIP_DISCONNECTED:  return "DISCONNECTED";
5229
        case TSIPClient::SIP_HOLD:          return "HOLD";
5230
        case TSIPClient::SIP_RINGING:       return "RINGING";
5231
        case TSIPClient::SIP_TRYING:        return "TRYING";
5232
 
5233
        default:
5234
            return "IDLE";
5235
    }
5236
 
5237
    return "IDLE";
5238
}
129 andreas 5239
#endif
134 andreas 5240
void TPageManager::sendOrientation()
5241
{
5242
    string ori;
5243
 
5244
    switch(mOrientation)
5245
    {
5246
        case O_PORTRAIT:            ori = "DeviceOrientationPortrait"; break;
5247
        case O_REVERSE_PORTRAIT:    ori = "DeviceOrientationPortraitUpsideDown"; break;
5248
        case O_LANDSCAPE:           ori = "DeviceOrientationLandscapeLeft"; break;
5249
        case O_REVERSE_LANDSCAPE:   ori = "DeviceOrientationLandscapeRight"; break;
5250
        case O_FACE_UP:             ori = "DeviceOrientationFaceUp"; break;
5251
        case O_FACE_DOWN:           ori = "DeviceOrientationFaceDown"; break;
5252
        default:
5253
            return;
5254
    }
5255
 
5256
    sendGlobalString("TPCACC-" + ori);
5257
}
5258
 
401 andreas 5259
void TPageManager::callSetPassword(ulong handle, const string& pw, int x, int y)
396 andreas 5260
{
401 andreas 5261
    DECL_TRACER("TPageManager::callSetPassword(ulong handle, const string& pw, int x, int y)");
396 andreas 5262
 
5263
    Button::TButton *bt = findButton(handle);
5264
 
5265
    if (!bt)
5266
    {
5267
        MSG_WARNING("callSetPassword: Button " << handleToString(handle) << " not found!");
5268
        return;
5269
    }
5270
 
5271
    string pass = pw;
5272
 
5273
    if (pass.empty())
5274
        pass = "\x01";
5275
 
5276
    bt->setPassword(pass);
401 andreas 5277
    bt->doClick(x, y, true);
5278
    bt->doClick(x, y, false);
396 andreas 5279
}
5280
 
431 andreas 5281
TButtonStates *TPageManager::addButtonState(BUTTONTYPE t, int rap, int rad, int rch, int rcp, int rlp, int rlv)
429 andreas 5282
{
431 andreas 5283
    DECL_TRACER("TPageManager::addButtonState(BUTTONTYPE t, int rap, int rad, int rch, int rcp, int rlp, int rlv)");
429 andreas 5284
 
431 andreas 5285
    TButtonStates *pbs = new TButtonStates(t, rap, rad, rch, rcp, rlp, rlv);
5286
    uint32_t id = pbs->getID();
5287
 
429 andreas 5288
    if (!mButtonStates.empty())
5289
    {
5290
        vector<TButtonStates *>::iterator iter;
5291
 
5292
        for (iter = mButtonStates.begin(); iter != mButtonStates.end(); ++iter)
5293
        {
5294
            TButtonStates *bs = *iter;
5295
 
431 andreas 5296
            if (bs->isButton(t, id))
5297
            {
5298
                delete pbs;
429 andreas 5299
                return bs;
431 andreas 5300
            }
429 andreas 5301
        }
5302
    }
5303
 
431 andreas 5304
    mButtonStates.push_back(pbs);
5305
    return pbs;
429 andreas 5306
}
5307
 
431 andreas 5308
TButtonStates *TPageManager::addButtonState(const TButtonStates& rbs)
429 andreas 5309
{
431 andreas 5310
    DECL_TRACER("TPageManager::addButtonState(const TButtonStates& rbs)");
429 andreas 5311
 
5312
    if (!mButtonStates.empty())
5313
    {
5314
        vector<TButtonStates *>::iterator iter;
431 andreas 5315
        TButtonStates bs = rbs;
5316
        BUTTONTYPE type = bs.getType();
5317
        uint32_t id = bs.getID();
429 andreas 5318
 
5319
        for (iter = mButtonStates.begin(); iter != mButtonStates.end(); ++iter)
5320
        {
5321
            TButtonStates *pbs = *iter;
5322
 
431 andreas 5323
            if (pbs->isButton(type, id))
429 andreas 5324
                return pbs;
5325
        }
5326
    }
5327
 
431 andreas 5328
    TButtonStates *pbs = new TButtonStates(rbs);
429 andreas 5329
    mButtonStates.push_back(pbs);
5330
    return pbs;
5331
}
5332
 
431 andreas 5333
TButtonStates *TPageManager::getButtonState(BUTTONTYPE t, int rap, int rad, int rch, int rcp, int rlp, int rlv)
429 andreas 5334
{
431 andreas 5335
    DECL_TRACER("TPageManager::getButtonState(BUTTONTYPE t, int rap, int rad, int rch, int rcp, int rlp, int rlv)");
429 andreas 5336
 
5337
    if (mButtonStates.empty())
5338
        return nullptr;
5339
 
5340
    vector<TButtonStates *>::iterator iter;
5341
    MSG_DEBUG("Found " << mButtonStates.size() << " button states.");
5342
 
5343
    for (iter = mButtonStates.begin(); iter != mButtonStates.end(); ++iter)
5344
    {
5345
        TButtonStates *bs = *iter;
5346
 
431 andreas 5347
        if (bs->isButton(t, rap, rad, rch, rcp, rlp, rlv))
429 andreas 5348
            return bs;
5349
    }
5350
 
5351
    return nullptr;
5352
}
5353
 
431 andreas 5354
TButtonStates *TPageManager::getButtonState(uint32_t id)
5355
{
5356
    DECL_TRACER("TPageManager::getButtonState(uint32_t id)");
5357
 
5358
    if (mButtonStates.empty())
5359
        return nullptr;
5360
 
5361
    vector<TButtonStates *>::iterator iter;
5362
    MSG_DEBUG("Found " << mButtonStates.size() << " button states.");
5363
 
5364
    for (iter = mButtonStates.begin(); iter != mButtonStates.end(); ++iter)
5365
    {
5366
        TButtonStates *bs = *iter;
5367
 
5368
        if (bs->isButton(id))
5369
            return bs;
5370
    }
5371
 
5372
    return nullptr;
5373
}
5374
 
5375
TButtonStates *TPageManager::getButtonState(BUTTONTYPE t, uint32_t id)
5376
{
5377
    DECL_TRACER("TPageManager::getButtonState(BUTTONTYPE t, uint32_t id)");
5378
 
5379
    if (mButtonStates.empty())
5380
        return nullptr;
5381
 
5382
    vector<TButtonStates *>::iterator iter;
5383
    MSG_DEBUG("Found " << mButtonStates.size() << " button states.");
5384
 
5385
    for (iter = mButtonStates.begin(); iter != mButtonStates.end(); ++iter)
5386
    {
5387
        TButtonStates *bs = *iter;
5388
 
5389
        if (bs->isButton(t, id))
5390
            return bs;
5391
    }
5392
 
5393
    return nullptr;
5394
}
5395
 
153 andreas 5396
void TPageManager::onSwipeEvent(TPageManager::SWIPES sw)
5397
{
5398
    DECL_TRACER("TPageManager::onSwipeEvent(TPageManager::SWIPES sw)");
5399
 
5400
    // Swipes are defined in "external".
5401
    if (!mExternal)
5402
        return;
5403
 
5404
    extButtons_t eBt;
5405
    string dbg;
5406
 
5407
    switch(sw)
5408
    {
5409
        case SW_LEFT:   eBt = EXT_GESTURE_LEFT; dbg.assign("LEFT"); break;
5410
        case SW_RIGHT:  eBt = EXT_GESTURE_RIGHT; dbg.assign("RIGHT"); break;
5411
        case SW_UP:     eBt = EXT_GESTURE_UP; dbg.assign("UP"); break;
5412
        case SW_DOWN:   eBt = EXT_GESTURE_DOWN; dbg.assign("DOWN"); break;
5413
 
5414
        default:
5415
            return;
5416
    }
5417
 
5418
    int pgNum = getActualPageNumber();
5419
    EXTBUTTON_t bt = mExternal->getButton(pgNum, eBt);
5420
 
5421
    if (bt.bi == 0)
5422
        return;
5423
 
5424
    MSG_DEBUG("Received swipe " << dbg << " event for page " << pgNum << " on button " << bt.bi << " \"" << bt.na << "\"");
5425
 
5426
    if (!bt.cm.empty() && bt.co == 0)           // Feed command to ourself?
5427
    {                                           // Yes, then feed it into command queue.
5428
        MSG_DEBUG("Button has a self feed command");
5429
 
5430
        int channel = TConfig::getChannel();
5431
        int system = TConfig::getSystem();
5432
 
5433
        amx::ANET_COMMAND cmd;
5434
        cmd.MC = 0x000c;
5435
        cmd.device1 = channel;
5436
        cmd.port1 = bt.ap;
5437
        cmd.system = system;
5438
        cmd.data.message_string.device = channel;
5439
        cmd.data.message_string.port = bt.ap;  // Must be the address port of button
5440
        cmd.data.message_string.system = system;
5441
        cmd.data.message_string.type = 1;   // 8 bit char string
5442
 
5443
        vector<string>::iterator iter;
5444
 
5445
        for (iter = bt.cm.begin(); iter != bt.cm.end(); ++iter)
5446
        {
5447
            cmd.data.message_string.length = iter->length();
5448
            memset(&cmd.data.message_string.content, 0, sizeof(cmd.data.message_string.content));
5449
            strncpy((char *)&cmd.data.message_string.content, iter->c_str(), sizeof(cmd.data.message_string.content));
5450
            doCommand(cmd);
5451
        }
5452
    }
5453
    else if (!bt.cm.empty())
5454
    {
5455
        MSG_DEBUG("Button sends a command on port " << bt.co);
5456
 
5457
        vector<string>::iterator iter;
5458
 
5459
        for (iter = bt.cm.begin(); iter != bt.cm.end(); ++iter)
5460
            sendCommandString(bt.co, *iter);
5461
    }
5462
}
5463
 
36 andreas 5464
/****************************************************************************
11 andreas 5465
 * The following functions implements one of the commands the panel accepts.
5466
 ****************************************************************************/
43 andreas 5467
 
5468
/**
5469
 * This is a special function handling the progress bars when the files of the
5470
 * panel are updated. Instead of simply displaying a ready page, it fakes one
5471
 * with the actual dimensions of the main page. This is possible, because we've
5472
 * always a main page even if the panel is started for the first time.
5473
 */
5474
void TPageManager::doFTR(int port, vector<int>& channels, vector<string>& pars)
23 andreas 5475
{
43 andreas 5476
    DECL_TRACER("TPageManager::doFTR(int, vector<int>&, vector<string>& pars)");
14 andreas 5477
 
23 andreas 5478
    if (pars.empty())
5479
    {
5480
        MSG_WARNING("Command #FTR needs at least 1 parameter! Ignoring command.");
5481
        return;
5482
    }
5483
 
96 andreas 5484
    if (TStreamError::checkFilter(HLOG_DEBUG))
23 andreas 5485
    {
96 andreas 5486
        for (size_t i = 0; i < pars.size(); i++)
5487
        {
5488
            MSG_DEBUG("[" << i << "]: " << pars.at(i));
5489
        }
23 andreas 5490
    }
43 andreas 5491
 
5492
    if (pars.at(0).compare("START") == 0)
5493
    {
5494
        // Here we have to drop all pages and subpages first and then display
5495
        // the faked page with the progress bars.
5496
        MSG_DEBUG("Starting file transfer ...");
5497
        doPPX(port, channels, pars);
5498
        TPage *pg = getPage("_progress");
5499
 
5500
        if (!pg)
5501
        {
5502
            if (!readPage("_progress"))
5503
            {
5504
                MSG_ERROR("Error creating the system page _progress!");
5505
                return;
5506
            }
5507
 
5508
            pg = getPage("_progress");
5509
 
5510
            if (!pg)
5511
            {
5512
                MSG_ERROR("Error getting system page _progress!");
5513
                return;
5514
            }
5515
        }
5516
 
5517
        pg->setFonts(mFonts);
5518
        pg->registerCallback(_setBackground);
5519
        pg->regCallPlayVideo(_callPlayVideo);
5520
 
5521
        if (!pg || !_setPage || !mTSettings)
5522
            return;
5523
 
5524
        int width, height;
217 andreas 5525
        width = mTSettings->getWidth();
43 andreas 5526
        height = mTSettings->getHeight();
5527
#ifdef _SCALE_SKIA_
5528
        if (mScaleFactor != 1.0)
5529
        {
5530
            width = (int)((double)width * mScaleFactor);
5531
            height = (int)((double)height * mScaleFactor);
5532
        }
5533
#endif
5534
        _setPage((pg->getNumber() << 16) & 0xffff0000, width, height);
5535
        pg->show();
5536
        MSG_DEBUG("Page _progress on screen");
5537
    }
5538
    else if (pars.at(0).compare("SYNC") == 0)
5539
    {
5540
        TPage *pg = getPage("_progress");
5541
 
5542
        if (!pg)
5543
        {
5544
            MSG_ERROR("Page _progress not found!");
5545
            return;
5546
        }
5547
 
5548
        Button::TButton *bt = pg->getButton(1);   // Line 1
5549
 
5550
        if (!bt)
5551
        {
5552
            MSG_ERROR("Button 160 of page _progress not found!");
5553
            return;
5554
        }
5555
 
5556
        bt->setText(pars.at(2), 0);
5557
        bt->show();
5558
    }
5559
    else if (pars.at(0).compare("FTRSTART") == 0)
5560
    {
5561
        TPage *pg = getPage("_progress");
5562
 
5563
        if (!pg)
5564
        {
5565
            MSG_ERROR("Page _progress not found!");
5566
            return;
5567
        }
5568
 
5569
        Button::TButton *bt1 = pg->getButton(1);   // Line 1
5570
        Button::TButton *bt2 = pg->getButton(2);   // Line 2
5571
        Button::TButton *bt3 = pg->getButton(3);   // Bargraph 1
5572
        Button::TButton *bt4 = pg->getButton(4);   // Bargraph 2
5573
 
5574
        if (!bt1 || !bt2 || !bt3 || !bt4)
5575
        {
5576
            MSG_ERROR("Buttons of page _progress not found!");
5577
            return;
5578
        }
5579
 
5580
        bt1->setText("Transfering files ...", 0);
5581
        bt1->show();
5582
        bt2->setText(pars.at(3), 0);
5583
        bt2->show();
5584
        bt3->drawBargraph(0, atoi(pars.at(1).c_str()), true);
5585
        bt4->drawBargraph(0, atoi(pars.at(2).c_str()), true);
5586
    }
5587
    else if (pars.at(0).compare("FTRPART") == 0)
5588
    {
5589
        TPage *pg = getPage("_progress");
5590
 
5591
        if (!pg)
5592
        {
5593
            MSG_ERROR("Page _progress not found!");
5594
            return;
5595
        }
5596
 
5597
        Button::TButton *bt = pg->getButton(4);   // Bargraph 2
5598
 
5599
        if (!bt)
5600
        {
5601
            MSG_ERROR("Buttons of page _progress not found!");
5602
            return;
5603
        }
5604
 
5605
        bt->drawBargraph(0, atoi(pars.at(2).c_str()), true);
5606
    }
5607
    else if (pars.at(0).compare("END") == 0)
5608
    {
5609
        MSG_TRACE("End of file transfer reached.");
44 andreas 5610
 
155 andreas 5611
        // To make sure the new surface will not be deleted and replaced by the
5612
        // default build in surface, we must delete the "virgin" marker first.
5613
        // This is a file called <project path>/.system.
5614
        string virgin = TConfig::getProjectPath() + "/.system";
5615
        remove(virgin.c_str());     // Because this file may not exist we don't care about the result code.
5616
 
44 andreas 5617
        if (_resetSurface)
5618
            _resetSurface();
5619
        else
5620
        {
5621
            MSG_WARNING("Missing callback function \"resetSurface\"!");
5622
        }
43 andreas 5623
    }
23 andreas 5624
}
5625
 
318 andreas 5626
void TPageManager::doLEVON(int, vector<int>&, vector<string>&)
5627
{
5628
    DECL_TRACER("TPageManager::doLEVON(int, vector<int>&, vector<string>&)");
5629
 
5630
    mLevelSend = true;
343 andreas 5631
#if TESTMODE == 1
5632
    __success = true;
5633
    setAllDone();
5634
#endif
318 andreas 5635
}
5636
 
5637
void TPageManager::doLEVOF(int, vector<int>&, vector<string>&)
5638
{
5639
    DECL_TRACER("TPageManager::doLEVOF(int, vector<int>&, vector<string>&)");
5640
 
5641
    mLevelSend = false;
343 andreas 5642
#if TESTMODE == 1
5643
    __success = true;
5644
    setAllDone();
5645
#endif
318 andreas 5646
}
5647
 
5648
void TPageManager::doRXON(int, vector<int>&, vector<string>&)
5649
{
5650
    DECL_TRACER("TPageManager::doRXON(int, vector<int>&, vector<string>&)");
5651
 
5652
    mRxOn = true;
343 andreas 5653
#if TESTMODE == 1
5654
    __success = true;
5655
    setAllDone();
5656
#endif
318 andreas 5657
}
5658
 
5659
void TPageManager::doRXOF(int, vector<int>&, vector<string>&)
5660
{
5661
    DECL_TRACER("TPageManager::doRXOF(int, vector<int>&, vector<string>&)");
5662
 
5663
    mRxOn = false;
343 andreas 5664
#if TESTMODE == 1
5665
    __success = true;
5666
    setAllDone();
5667
#endif
318 andreas 5668
}
5669
 
22 andreas 5670
void TPageManager::doON(int port, vector<int>&, vector<string>& pars)
14 andreas 5671
{
5672
    DECL_TRACER("TPageManager::doON(int port, vector<int>& channels, vector<string>& pars)");
5673
 
5674
    if (pars.empty())
5675
    {
5676
        MSG_WARNING("Command ON needs 1 parameter! Ignoring command.");
343 andreas 5677
#if TESTMODE == 1
5678
        setAllDone();
5679
#endif
14 andreas 5680
        return;
5681
    }
5682
 
16 andreas 5683
    TError::clear();
14 andreas 5684
    int c = atoi(pars[0].c_str());
5685
 
5686
    if (c <= 0)
5687
    {
5688
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
343 andreas 5689
#if TESTMODE == 1
5690
        setAllDone();
5691
#endif
14 andreas 5692
        return;
5693
    }
5694
 
5695
    vector<int> chans = { c };
193 andreas 5696
    vector<TMap::MAP_T> map = findButtons(port, chans, TMap::TYPE_CM);
14 andreas 5697
 
5698
    if (TError::isError() || map.empty())
343 andreas 5699
    {
5700
#if TESTMODE == 1
5701
        setAllDone();
5702
#endif
14 andreas 5703
        return;
343 andreas 5704
    }
14 andreas 5705
 
5706
    vector<Button::TButton *> buttons = collectButtons(map);
5707
 
83 andreas 5708
    if (buttons.size() > 0)
14 andreas 5709
    {
83 andreas 5710
        vector<Button::TButton *>::iterator mapIter;
14 andreas 5711
 
118 andreas 5712
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
83 andreas 5713
        {
5714
            Button::TButton *bt = *mapIter;
5715
 
195 andreas 5716
            if (bt->getButtonType() == GENERAL)
343 andreas 5717
            {
83 andreas 5718
                bt->setActive(1);
343 andreas 5719
#if TESTMODE == 1
5720
                if (_gTestMode)
5721
                    _gTestMode->setResult(intToString(bt->getActiveInstance() + 1));
5722
#endif
5723
            }
83 andreas 5724
        }
14 andreas 5725
    }
343 andreas 5726
#if TESTMODE == 1
5727
    setDone();
5728
#endif
14 andreas 5729
}
5730
 
22 andreas 5731
void TPageManager::doOFF(int port, vector<int>&, vector<string>& pars)
14 andreas 5732
{
5733
    DECL_TRACER("TPageManager::doOFF(int port, vector<int>& channels, vector<string>& pars)");
5734
 
5735
    if (pars.empty())
5736
    {
5737
        MSG_WARNING("Command OFF needs 1 parameter! Ignoring command.");
343 andreas 5738
#if TESTMODE == 1
5739
        setAllDone();
5740
#endif
14 andreas 5741
        return;
5742
    }
5743
 
16 andreas 5744
    TError::clear();
14 andreas 5745
    int c = atoi(pars[0].c_str());
5746
 
5747
    if (c <= 0)
5748
    {
5749
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
343 andreas 5750
#if TESTMODE == 1
5751
        setAllDone();
5752
#endif
14 andreas 5753
        return;
5754
    }
5755
 
5756
    vector<int> chans = { c };
193 andreas 5757
    vector<TMap::MAP_T> map = findButtons(port, chans, TMap::TYPE_CM);
14 andreas 5758
 
5759
    if (TError::isError() || map.empty())
5760
        return;
5761
 
5762
    vector<Button::TButton *> buttons = collectButtons(map);
5763
 
83 andreas 5764
    if (buttons.size() > 0)
14 andreas 5765
    {
83 andreas 5766
        vector<Button::TButton *>::iterator mapIter;
14 andreas 5767
 
118 andreas 5768
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
83 andreas 5769
        {
5770
            Button::TButton *bt = *mapIter;
5771
 
195 andreas 5772
            if (bt->getButtonType() == GENERAL)
83 andreas 5773
                bt->setActive(0);
343 andreas 5774
#if TESTMODE == 1
5775
                if (_gTestMode)
5776
                    _gTestMode->setResult(intToString(bt->getActiveInstance() + 1));
5777
#endif
83 andreas 5778
        }
14 andreas 5779
    }
343 andreas 5780
#if TESTMODE == 1
5781
    setDone();
5782
#endif
14 andreas 5783
}
5784
 
22 andreas 5785
void TPageManager::doLEVEL(int port, vector<int>&, vector<string>& pars)
15 andreas 5786
{
5787
    DECL_TRACER("TPageManager::doLEVEL(int port, vector<int>& channels, vector<string>& pars)");
5788
 
5789
    if (pars.size() < 2)
5790
    {
5791
        MSG_WARNING("Command LEVEL needs 2 parameters! Ignoring command.");
343 andreas 5792
#if TESTMODE == 1
5793
        setAllDone();
5794
#endif
15 andreas 5795
        return;
5796
    }
5797
 
16 andreas 5798
    TError::clear();
15 andreas 5799
    int c = atoi(pars[0].c_str());
5800
    int level = atoi(pars[1].c_str());
5801
 
5802
    if (c <= 0)
5803
    {
5804
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
343 andreas 5805
#if TESTMODE == 1
5806
        setAllDone();
5807
#endif
15 andreas 5808
        return;
5809
    }
5810
 
5811
    vector<int> chans = { c };
193 andreas 5812
    vector<TMap::MAP_T> map = findBargraphs(port, chans);
15 andreas 5813
 
5814
    if (TError::isError() || map.empty())
5815
    {
5816
        MSG_WARNING("No bargraphs found!");
343 andreas 5817
#if TESTMODE == 1
5818
        setAllDone();
5819
#endif
15 andreas 5820
        return;
5821
    }
5822
 
5823
    vector<Button::TButton *> buttons = collectButtons(map);
5824
 
83 andreas 5825
    if (buttons.size() > 0)
15 andreas 5826
    {
429 andreas 5827
        MSG_DEBUG("Found " << buttons.size() << " buttons.");
83 andreas 5828
        vector<Button::TButton *>::iterator mapIter;
15 andreas 5829
 
118 andreas 5830
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
15 andreas 5831
        {
83 andreas 5832
            Button::TButton *bt = *mapIter;
429 andreas 5833
            MSG_DEBUG("Evaluating button " << handleToString(bt->getHandle()))
83 andreas 5834
 
418 andreas 5835
            if (bt->getButtonType() == BARGRAPH && bt->getLevelChannel() == c)
343 andreas 5836
            {
435 andreas 5837
                if (bt->isBargraphInverted())
5838
                    level = (bt->getRangeHigh() - bt->getRangeLow()) - level;
5839
 
83 andreas 5840
                bt->drawBargraph(bt->getActiveInstance(), level);
439 andreas 5841
                bt->sendBargraphLevel();
343 andreas 5842
#if TESTMODE == 1
5843
                if (_gTestMode)
5844
                    _gTestMode->setResult(intToString(bt->getLevelValue()));
5845
#endif
5846
            }
416 andreas 5847
            else if (bt->getButtonType() == JOYSTICK)
5848
            {
5849
                int x = (bt->getLevelChannel() == c ? level : bt->getLevelAxisX());
5850
                int y = (bt->getLevelChannel() == c ? bt->getLevelAxisY() : level);
418 andreas 5851
 
5852
                if (bt->isBargraphInverted())
435 andreas 5853
                    x = (bt->getRangeHigh() - bt->getRangeLow()) - x;
418 andreas 5854
 
5855
                if (bt->isJoystickAuxInverted())
435 andreas 5856
                    y = (bt->getRangeHigh() - bt->getRangeLow()) - y;
418 andreas 5857
 
416 andreas 5858
                bt->drawJoystick(x, y);
439 andreas 5859
                bt->sendJoystickLevels();
5860
#if TESTMODE == 1
5861
                if (_gTestMode)
5862
                {
5863
                    std::stringstream s;
5864
                    s << x << "|" << y;
5865
                    _gTestMode->setResult(s.str());
5866
                }
5867
#endif
416 andreas 5868
            }
418 andreas 5869
            else if (bt->getButtonType() == MULTISTATE_BARGRAPH && bt->getLevelChannel() == c)
83 andreas 5870
            {
5871
                int state = (int)((double)bt->getStateCount() / (double)(bt->getRangeHigh() - bt->getRangeLow()) * (double)level);
5872
                bt->setActive(state);
439 andreas 5873
                bt->sendBargraphLevel();
343 andreas 5874
#if TESTMODE == 1
5875
                if (_gTestMode)
5876
                    _gTestMode->setResult(intToString(bt->getActiveInstance()));
5877
#endif
83 andreas 5878
            }
15 andreas 5879
        }
5880
    }
429 andreas 5881
    else
5882
        MSG_DEBUG("No buttons found!");
5883
 
343 andreas 5884
#if TESTMODE == 1
5885
    setDone();
5886
#endif
15 andreas 5887
}
5888
 
22 andreas 5889
void TPageManager::doBLINK(int, vector<int>&, vector<string>& pars)
15 andreas 5890
{
5891
    DECL_TRACER("TPageManager::doBLINK(int port, vector<int>& channels, vector<string>& pars)");
5892
 
5893
    if (pars.size() < 4)
5894
    {
5895
        MSG_WARNING("Command BLINK expects 4 parameters! Command ignored.");
343 andreas 5896
#if TESTMODE == 1
5897
        setAllDone();
5898
#endif
15 andreas 5899
        return;
5900
    }
5901
 
16 andreas 5902
    TError::clear();
15 andreas 5903
    vector<int> sysButtons = { 141, 142, 143, 151, 152, 153, 154, 155, 156, 157, 158 };
193 andreas 5904
    vector<TMap::MAP_T> map = findButtons(0, sysButtons);
15 andreas 5905
 
5906
    if (TError::isError() || map.empty())
5907
    {
5908
        MSG_WARNING("No system buttons found.");
343 andreas 5909
#if TESTMODE == 1
5910
        setAllDone();
5911
#endif
15 andreas 5912
        return;
5913
    }
5914
 
5915
    vector<Button::TButton *> buttons = collectButtons(map);
5916
    vector<Button::TButton *>::iterator mapIter;
5917
 
5918
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
5919
    {
5920
        Button::TButton *bt = *mapIter;
5921
        bt->setActive(0);
343 andreas 5922
#if TESTMODE == 1
5923
                if (_gTestMode)
5924
                    _gTestMode->setResult(intToString(bt->getActiveInstance() + 1));
5925
#endif
15 andreas 5926
    }
343 andreas 5927
#if TESTMODE == 1
5928
    setDone();
5929
#endif
15 andreas 5930
}
5931
 
162 andreas 5932
/**
5933
 * Send the version of the panel to the NetLinx. This is the real application
5934
 * version.
5935
 */
127 andreas 5936
void TPageManager::doVER(int, vector<int>&, vector<string>&)
5937
{
5938
    DECL_TRACER("TPageManager::doVER(int, vector<int>&, vector<string>&)");
5939
 
5940
    amx::ANET_SEND scmd;
5941
    scmd.port = 1;
5942
    scmd.channel = 0;
5943
    scmd.msg.assign(string("^VER-")+VERSION_STRING());
5944
    scmd.MC = 0x008c;
5945
 
5946
    if (gAmxNet)
343 andreas 5947
    {
127 andreas 5948
        gAmxNet->sendCommand(scmd);
343 andreas 5949
#if TESTMODE == 1
5950
        __success = true;
347 andreas 5951
 
5952
        if (_gTestMode)
5953
            _gTestMode->setResult(VERSION_STRING());
343 andreas 5954
#endif
5955
    }
127 andreas 5956
    else
5957
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
343 andreas 5958
#if TESTMODE == 1
5959
    setAllDone();
5960
#endif
127 andreas 5961
}
5962
 
162 andreas 5963
/**
5964
 * Returns the user name used to connect to a SIP server. An empty string is
5965
 * returned if there is no user defined.
5966
 */
279 andreas 5967
#ifndef _NOSIP_
127 andreas 5968
void TPageManager::doWCN(int, vector<int>&, vector<string>&)
5969
{
5970
    DECL_TRACER("TPageManager::doWCN(int, vector<int>&, vector<string>&)");
5971
 
5972
    if (!TConfig::getSIPstatus())
343 andreas 5973
    {
5974
#if TESTMODE == 1
5975
        setAllDone();
5976
#endif
127 andreas 5977
        return;
343 andreas 5978
    }
127 andreas 5979
 
5980
    amx::ANET_SEND scmd;
5981
    scmd.port = 1;
5982
    scmd.channel = 0;
5983
    scmd.msg.assign("^WCN-" + TConfig::getSIPuser());
5984
    scmd.MC = 0x008c;
5985
 
5986
    if (gAmxNet)
343 andreas 5987
    {
127 andreas 5988
        gAmxNet->sendCommand(scmd);
343 andreas 5989
#if TESTMODE == 1
5990
        __success = true;
347 andreas 5991
 
5992
        if (_gTestMode)
5993
            _gTestMode->setResult(TConfig::getSIPuser());
343 andreas 5994
#endif
5995
    }
127 andreas 5996
    else
5997
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
343 andreas 5998
#if TESTMODE == 1
5999
        setAllDone();
6000
#endif
127 andreas 6001
}
279 andreas 6002
#endif
14 andreas 6003
/**
147 andreas 6004
 * Flip to specified page using the named animation.
6005
 * FIXME: Implement animation for pages.
6006
 */
6007
void TPageManager::doAFP(int, vector<int>&, vector<string>& pars)
6008
{
6009
    DECL_TRACER("TPageManager::doAFP(int, vector<int>&, vector<string>& pars)");
6010
 
6011
    if (pars.size() < 4)
6012
    {
6013
        MSG_ERROR("Less than 4 parameters!");
343 andreas 6014
#if TESTMODE == 1
6015
        setAllDone();
6016
#endif
147 andreas 6017
        return;
6018
    }
6019
 
6020
    TError::clear();
6021
    string pname = pars[0];
6022
//    string ani = pars[1];
6023
//    int origin = atoi(pars[2].c_str());
6024
//    int duration = atoi(pars[3].c_str());
6025
 
6026
    // FIXME: Animation of pages is currently not implemented.
6027
 
6028
    if (!pname.empty())
6029
        setPage(pname);
6030
    else if (mPreviousPage)
6031
        setPage(mPreviousPage);
343 andreas 6032
#if TESTMODE == 1
6033
    if (_gTestMode)
6034
        _gTestMode->setResult(getActualPage()->getName());
6035
 
6036
    setDone();
6037
#endif
147 andreas 6038
}
6039
 
6040
/**
14 andreas 6041
 * Add a specific popup page to a specified popup group if it does not already
6042
 * exist. If the new popup is added to a group which has a popup displayed on
6043
 * the current page along with the new pop-up, the displayed popup will be
6044
 * hidden and the new popup will be displayed.
6045
 */
22 andreas 6046
void TPageManager::doAPG(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 6047
{
6048
    DECL_TRACER("TPageManager::doAPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
6049
 
6050
    if (pars.size() < 2)
6051
    {
6052
        MSG_ERROR("Less than 2 parameters!");
343 andreas 6053
#if TESTMODE == 1
6054
        setAllDone();
6055
#endif
11 andreas 6056
        return;
6057
    }
6058
 
16 andreas 6059
    TError::clear();
11 andreas 6060
    closeGroup(pars[1]);
14 andreas 6061
 
96 andreas 6062
    TPage *page = nullptr;
6063
    TSubPage *subPage = deliverSubPage(pars[0], &page);
14 andreas 6064
 
11 andreas 6065
    if (!subPage)
6066
    {
6067
        MSG_ERROR("Subpage " << pars[0] << " couldn't either found or created!");
343 andreas 6068
#if TESTMODE == 1
6069
        setAllDone();
6070
#endif
11 andreas 6071
        return;
6072
    }
6073
 
162 andreas 6074
    if (!page)
6075
    {
6076
        MSG_ERROR("There seems to be no page for subpage " << pars[0]);
343 andreas 6077
#if TESTMODE == 1
6078
        setAllDone();
6079
#endif
162 andreas 6080
        return;
6081
    }
6082
 
152 andreas 6083
    page->addSubPage(subPage);
11 andreas 6084
    subPage->setGroup(pars[1]);
14 andreas 6085
    subPage->setZOrder(page->getNextZOrder());
152 andreas 6086
    MSG_DEBUG("Setting new Z-order " << page->getActZOrder() << " on page " << page->getName());
11 andreas 6087
    subPage->show();
343 andreas 6088
#if TESTMODE == 1
347 andreas 6089
    if (_gTestMode)
6090
        _gTestMode->setResult(subPage->getGroupName() + ":" + subPage->getName());
6091
 
343 andreas 6092
    setDone();
6093
#endif
11 andreas 6094
}
6095
 
14 andreas 6096
/**
6097
 * Clear all popup pages from specified popup group.
6098
 */
22 andreas 6099
void TPageManager::doCPG(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 6100
{
6101
    DECL_TRACER("TPageManager::doCPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
6102
 
6103
    if (pars.size() < 1)
6104
    {
6105
        MSG_ERROR("Expecting 1 parameter but got only 1!");
343 andreas 6106
#if TESTMODE == 1
6107
        setAllDone();
6108
#endif
11 andreas 6109
        return;
6110
    }
6111
 
16 andreas 6112
    TError::clear();
348 andreas 6113
    vector<SUBPAGELIST_T> pageList = mPageList->getSubPageList();
11 andreas 6114
 
83 andreas 6115
    if (pageList.size() > 0)
11 andreas 6116
    {
83 andreas 6117
        vector<SUBPAGELIST_T>::iterator pgIter;
6118
 
6119
        for (pgIter = pageList.begin(); pgIter != pageList.end(); pgIter++)
11 andreas 6120
        {
83 andreas 6121
            if (pgIter->group.compare(pars[0]) == 0)
6122
            {
6123
                pgIter->group.clear();
6124
                TSubPage *pg = getSubPage(pgIter->pageID);
11 andreas 6125
 
83 andreas 6126
                if (pg)
6127
                    pg->setGroup(pgIter->group);
343 andreas 6128
#if TESTMODE == 1
6129
                __success = true;
6130
#endif
83 andreas 6131
            }
11 andreas 6132
        }
6133
    }
343 andreas 6134
#if TESTMODE == 1
6135
    setDone();
6136
#endif
11 andreas 6137
}
6138
 
14 andreas 6139
/**
6140
 * Delete a specific popup page from specified popup group if it exists.
6141
 */
22 andreas 6142
void TPageManager::doDPG(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 6143
{
6144
    DECL_TRACER("TPageManager::doDPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
6145
 
6146
    if (pars.size() < 2)
6147
    {
6148
        MSG_ERROR("Less than 2 parameters!");
348 andreas 6149
#if TESTMODE == 1
6150
        setAllDone();
6151
#endif
11 andreas 6152
        return;
6153
    }
6154
 
16 andreas 6155
    TError::clear();
11 andreas 6156
    SUBPAGELIST_T listPg = findSubPage(pars[0]);
6157
 
6158
    if (!listPg.isValid)
348 andreas 6159
    {
6160
#if TESTMODE == 1
6161
        setAllDone();
6162
#endif
11 andreas 6163
        return;
348 andreas 6164
    }
11 andreas 6165
 
6166
    if (listPg.group.compare(pars[1]) == 0)
6167
    {
6168
        listPg.group.clear();
6169
        TSubPage *pg = getSubPage(listPg.pageID);
6170
 
6171
        if (pg)
6172
            pg->setGroup(listPg.group);
348 andreas 6173
#if TESTMODE == 1
6174
        __success = true;
6175
#endif
11 andreas 6176
    }
348 andreas 6177
#if TESTMODE == 1
6178
    setDone();
6179
#endif
11 andreas 6180
}
6181
 
14 andreas 6182
/**
15 andreas 6183
 * Set the hide effect for the specified popup page to the named hide effect.
6184
 */
22 andreas 6185
void TPageManager::doPHE(int, vector<int>&, vector<string>& pars)
15 andreas 6186
{
6187
    DECL_TRACER("TPageManager::doPHE(int port, vector<int>& channels, vector<string>& pars)");
6188
 
6189
    if (pars.size() < 2)
6190
    {
6191
        MSG_ERROR("Less than 2 parameters!");
348 andreas 6192
#if TESTMODE == 1
6193
        setAllDone();
6194
#endif
15 andreas 6195
        return;
6196
    }
6197
 
16 andreas 6198
    TError::clear();
96 andreas 6199
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6200
 
6201
    if (!pg)
348 andreas 6202
    {
6203
#if TESTMODE == 1
6204
        setAllDone();
6205
#endif
96 andreas 6206
        return;
348 andreas 6207
    }
15 andreas 6208
 
162 andreas 6209
    if (strCaseCompare(pars[1], "fade") == 0)
15 andreas 6210
        pg->setHideEffect(SE_FADE);
162 andreas 6211
    else if (strCaseCompare(pars[1], "slide to left") == 0)
15 andreas 6212
        pg->setHideEffect(SE_SLIDE_LEFT);
162 andreas 6213
    else if (strCaseCompare(pars[1], "slide to right") == 0)
15 andreas 6214
        pg->setHideEffect(SE_SLIDE_RIGHT);
162 andreas 6215
    else if (strCaseCompare(pars[1], "slide to top") == 0)
15 andreas 6216
        pg->setHideEffect(SE_SLIDE_TOP);
162 andreas 6217
    else if (strCaseCompare(pars[1], "slide to bottom") == 0)
15 andreas 6218
        pg->setHideEffect(SE_SLIDE_BOTTOM);
162 andreas 6219
    else if (strCaseCompare(pars[1], "slide to left fade") == 0)
15 andreas 6220
        pg->setHideEffect(SE_SLIDE_LEFT_FADE);
162 andreas 6221
    else if (strCaseCompare(pars[1], "slide to right fade") == 0)
15 andreas 6222
        pg->setHideEffect(SE_SLIDE_RIGHT_FADE);
162 andreas 6223
    else if (strCaseCompare(pars[1], "slide to top fade") == 0)
15 andreas 6224
        pg->setHideEffect(SE_SLIDE_TOP_FADE);
162 andreas 6225
    else if (strCaseCompare(pars[1], "slide to bottom fade") == 0)
15 andreas 6226
        pg->setHideEffect(SE_SLIDE_BOTTOM_FADE);
6227
    else
6228
        pg->setHideEffect(SE_NONE);
348 andreas 6229
#if TESTMODE == 1
6230
    if (_gTestMode)
6231
        _gTestMode->setResult(intToString(pg->getHideEffect()));
6232
 
6233
    __success = true;
6234
    setAllDone();
6235
#endif
15 andreas 6236
}
6237
 
6238
/**
6239
 * Set the hide effect position. Only 1 coordinate is ever needed for an effect;
6240
 * however, the command will specify both. This command sets the location at
6241
 * which the effect will end at.
6242
 */
22 andreas 6243
void TPageManager::doPHP(int, vector<int>&, vector<string>& pars)
15 andreas 6244
{
6245
    DECL_TRACER("TPageManager::doPHP(int port, vector<int>& channels, vector<string>& pars)");
6246
 
6247
    if (pars.size() < 2)
6248
    {
6249
        MSG_ERROR("Less than 2 parameters!");
348 andreas 6250
#if TESTMODE == 1
6251
        setAllDone();
6252
#endif
15 andreas 6253
        return;
6254
    }
6255
 
16 andreas 6256
    TError::clear();
15 andreas 6257
    size_t pos = pars[1].find(",");
6258
    int x, y;
6259
 
6260
    if (pos == string::npos)
6261
    {
6262
        x = atoi(pars[1].c_str());
6263
        y = 0;
6264
    }
6265
    else
6266
    {
6267
        x = atoi(pars[1].substr(0, pos).c_str());
6268
        y = atoi(pars[1].substr(pos+1).c_str());
6269
    }
6270
 
96 andreas 6271
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6272
 
6273
    if (!pg)
348 andreas 6274
    {
6275
#if TESTMODE == 1
6276
        setAllDone();
6277
#endif
96 andreas 6278
        return;
348 andreas 6279
    }
15 andreas 6280
 
6281
    pg->setHideEndPosition(x, y);
348 andreas 6282
#if TESTMODE == 1
6283
    if (_gTestMode)
6284
    {
6285
        int x, y;
6286
        pg->getHideEndPosition(&x, &y);
6287
        _gTestMode->setResult(intToString(x) + "," + intToString(y));
6288
    }
6289
 
6290
    __success = true;
6291
    setAllDone();
6292
#endif
15 andreas 6293
}
6294
 
6295
/**
6296
 * Set the hide effect time for the specified popup page.
6297
 */
22 andreas 6298
void TPageManager::doPHT(int, vector<int>&, vector<string>& pars)
15 andreas 6299
{
6300
    DECL_TRACER("TPageManager::doPHT(int port, vector<int>& channels, vector<string>& pars)");
6301
 
6302
    if (pars.size() < 2)
6303
    {
6304
        MSG_ERROR("Less than 2 parameters!");
348 andreas 6305
#if TESTMODE == 1
6306
        setAllDone();
6307
#endif
15 andreas 6308
        return;
6309
    }
6310
 
16 andreas 6311
    TError::clear();
96 andreas 6312
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6313
 
6314
    if (!pg)
348 andreas 6315
    {
6316
#if TESTMODE == 1
6317
        setAllDone();
6318
#endif
96 andreas 6319
        return;
348 andreas 6320
    }
15 andreas 6321
 
6322
    pg->setHideTime(atoi(pars[1].c_str()));
348 andreas 6323
#if TESTMODE == 1
6324
    if (_gTestMode)
6325
        _gTestMode->setResult(intToString(pg->getHideTime()));
6326
 
6327
    __success = true;
6328
    setAllDone();
6329
#endif
15 andreas 6330
}
6331
 
6332
/**
14 andreas 6333
 * Close all popups on a specified page. If the page name is empty, the current
6334
 * page is used. Same as the ’Clear Page’ command in TPDesign4.
6335
 */
22 andreas 6336
void TPageManager::doPPA(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 6337
{
6338
    DECL_TRACER("TPageManager::doPPA(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
6339
 
16 andreas 6340
    TError::clear();
11 andreas 6341
    TPage *pg;
6342
 
6343
    if (pars.size() == 0)
6344
        pg = getPage(mActualPage);
6345
    else
6346
        pg = getPage(pars[0]);
6347
 
6348
    if (!pg)
348 andreas 6349
    {
6350
#if TESTMODE == 1
6351
        setAllDone();
6352
#endif
11 andreas 6353
        return;
348 andreas 6354
    }
11 andreas 6355
 
12 andreas 6356
    pg->drop();
14 andreas 6357
    pg->resetZOrder();
348 andreas 6358
#if TESTMODE == 1
6359
    setDone();
6360
#endif
11 andreas 6361
}
6362
 
14 andreas 6363
/**
6364
 * Deactivate a specific popup page on either a specified page or the current
6365
 * page. If the page name is empty, the current page is used. If the popup page
6366
 * is part of a group, the whole group is deactivated. This command works in
6367
 * the same way as the ’Hide Popup’ command in TPDesign4.
6368
 */
22 andreas 6369
void TPageManager::doPPF(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6370
{
6371
    DECL_TRACER("TPageManager::doPPF(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
6372
 
6373
    if (pars.size() < 1)
6374
    {
6375
        MSG_ERROR("At least 1 parameter is expected!");
349 andreas 6376
#if TESTMODE == 1
6377
        setAllDone();
6378
#endif
12 andreas 6379
        return;
6380
    }
6381
 
16 andreas 6382
    TError::clear();
14 andreas 6383
    hideSubPage(pars[0]);
335 andreas 6384
#if TESTMODE == 1
6385
    setDone();
6386
#endif
12 andreas 6387
}
6388
 
14 andreas 6389
/**
6390
 * Toggle a specific popup page on either a specified page or the current page.
6391
 * If the page name is empty, the current page is used. Toggling refers to the
6392
 * activating/deactivating (On/Off) of a popup page. This command works in the
6393
 * same way as the ’Toggle Popup’ command in TPDesign4.
6394
 */
22 andreas 6395
void TPageManager::doPPG(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6396
{
6397
    DECL_TRACER("TPageManager::doPPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 6398
 
12 andreas 6399
    if (pars.size() < 1)
6400
    {
6401
        MSG_ERROR("At least 1 parameter is expected!");
349 andreas 6402
#if TESTMODE == 1
6403
        setAllDone();
6404
#endif
12 andreas 6405
        return;
6406
    }
6407
 
16 andreas 6408
    TError::clear();
14 andreas 6409
    TPage *page = getPage(mActualPage);
6410
 
6411
    if (!page)
6412
    {
6413
        MSG_ERROR("No active page found! Internal error.");
349 andreas 6414
#if TESTMODE == 1
6415
        setAllDone();
6416
#endif
14 andreas 6417
        return;
6418
    }
6419
 
12 andreas 6420
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 6421
 
12 andreas 6422
    if (!pg)
349 andreas 6423
    {
6424
#if TESTMODE == 1
6425
        setAllDone();
6426
#endif
12 andreas 6427
        return;
349 andreas 6428
    }
14 andreas 6429
 
12 andreas 6430
    if (pg->isVisible())
6431
    {
6432
        pg->drop();
162 andreas 6433
        page->decZOrder();
349 andreas 6434
#if TESTMODE == 1
6435
        setDone();
6436
#endif
12 andreas 6437
        return;
6438
    }
6439
 
6440
    TSubPage *sub = getFirstSubPageGroup(pg->getGroupName());
14 andreas 6441
 
12 andreas 6442
    while(sub)
6443
    {
6444
        if (sub->getGroupName().compare(pg->getGroupName()) == 0 && sub->isVisible())
6445
            sub->drop();
14 andreas 6446
 
12 andreas 6447
        sub = getNextSubPageGroup(pg->getGroupName(), sub);
6448
    }
6449
 
152 andreas 6450
    pg->setZOrder(page->getNextZOrder());
6451
    MSG_DEBUG("Setting new Z-order " << page->getActZOrder() << " on page " << page->getName());
12 andreas 6452
    pg->show();
349 andreas 6453
#if TESTMODE == 1
6454
    setDone();
6455
#endif
12 andreas 6456
}
6457
 
14 andreas 6458
/**
6459
 * Kill refers to the deactivating (Off) of a popup window from all pages. If
6460
 * the pop-up page is part of a group, the whole group is deactivated. This
6461
 * command works in the same way as the 'Clear Group' command in TPDesign 4.
6462
 */
22 andreas 6463
void TPageManager::doPPK(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6464
{
6465
    DECL_TRACER("TPageManager::doPPK(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 6466
 
12 andreas 6467
    if (pars.size() < 1)
6468
    {
6469
        MSG_ERROR("At least 1 parameter is expected!");
349 andreas 6470
#if TESTMODE == 1
6471
        setAllDone();
6472
#endif
12 andreas 6473
        return;
6474
    }
6475
 
16 andreas 6476
    TError::clear();
14 andreas 6477
    TPage *page = getPage(mActualPage);
6478
 
6479
    if (!page)
6480
    {
6481
        MSG_ERROR("No active page found! Internal error.");
349 andreas 6482
#if TESTMODE == 1
6483
        setAllDone();
6484
#endif
14 andreas 6485
        return;
6486
    }
6487
 
12 andreas 6488
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 6489
 
12 andreas 6490
    if (pg)
14 andreas 6491
    {
6492
        pg->drop();
162 andreas 6493
        page->decZOrder();
14 andreas 6494
    }
349 andreas 6495
#if TESTMODE == 1
6496
        setDone();
6497
#endif
12 andreas 6498
}
6499
 
14 andreas 6500
/**
6501
 * Set the modality of a specific popup page to Modal or NonModal.
6502
 * A Modal popup page, when active, only allows you to use the buttons and
6503
 * features on that popup page. All other buttons on the panel page are
6504
 * inactivated.
6505
 */
22 andreas 6506
void TPageManager::doPPM(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6507
{
6508
    DECL_TRACER("TPageManager::doPPM(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 6509
 
12 andreas 6510
    if (pars.size() < 2)
6511
    {
6512
        MSG_ERROR("Expecting 2 parameters!");
349 andreas 6513
#if TESTMODE == 1
6514
        setAllDone();
6515
#endif
12 andreas 6516
        return;
6517
    }
14 andreas 6518
 
16 andreas 6519
    TError::clear();
12 andreas 6520
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 6521
 
12 andreas 6522
    if (pg)
6523
    {
162 andreas 6524
        if (pars[1] == "1" || strCaseCompare(pars[1], "modal") == 0)
12 andreas 6525
            pg->setModal(1);
6526
        else
6527
            pg->setModal(0);
349 andreas 6528
#if TESTMODE == 1
6529
        if (_gTestMode)
6530
            _gTestMode->setResult(pg->isModal() ? "TRUE" : "FALSE");
6531
#endif
12 andreas 6532
    }
349 andreas 6533
#if TESTMODE == 1
6534
        setAllDone();
6535
#endif
12 andreas 6536
}
6537
 
14 andreas 6538
/**
6539
 * Activate a specific popup page to launch on either a specified page or the
6540
 * current page. If the page name is empty, the current page is used. If the
6541
 * popup page is already on, do not re-draw it. This command works in the same
6542
 * way as the ’Show Popup’ command in TPDesign4.
6543
 */
22 andreas 6544
void TPageManager::doPPN(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6545
{
6546
    DECL_TRACER("TPageManager::doPPN(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
6547
 
6548
    if (pars.size() < 1)
6549
    {
6550
        MSG_ERROR("At least 1 parameter is expected!");
349 andreas 6551
#if TESTMODE == 1
6552
        setAllDone();
6553
#endif
12 andreas 6554
        return;
6555
    }
6556
 
16 andreas 6557
    TError::clear();
14 andreas 6558
    showSubPage(pars[0]);
349 andreas 6559
#if TESTMODE == 1
6560
    setDone();
6561
#endif
12 andreas 6562
}
6563
 
14 andreas 6564
/**
15 andreas 6565
 * Set a specific popup page to timeout within a specified time. If timeout is
6566
 * empty, popup page will clear the timeout.
6567
 */
22 andreas 6568
void TPageManager::doPPT(int, vector<int>&, vector<string>& pars)
15 andreas 6569
{
6570
    DECL_TRACER("TPageManager::doPPT(int port, vector<int>& channels, vector<string>& pars)");
6571
 
6572
    if (pars.size() < 2)
6573
    {
6574
        MSG_ERROR("Expecting 2 parameters!");
351 andreas 6575
#if TESTMODE == 1
6576
        setAllDone();
6577
#endif
15 andreas 6578
        return;
6579
    }
6580
 
16 andreas 6581
    TError::clear();
96 andreas 6582
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6583
 
6584
    if (!pg)
351 andreas 6585
    {
6586
#if TESTMODE == 1
6587
        setAllDone();
6588
#endif
96 andreas 6589
        return;
351 andreas 6590
    }
15 andreas 6591
 
6592
    pg->setTimeout(atoi(pars[1].c_str()));
351 andreas 6593
#if TESTMODE == 1
6594
    if (_gTestMode)
6595
        _gTestMode->setResult(intToString(pg->getTimeout()));
6596
 
6597
    __success = true;
6598
    setAllDone();
6599
#endif
15 andreas 6600
}
6601
 
6602
/**
14 andreas 6603
 * Close all popups on all pages. This command works in the same way as the
6604
 * 'Clear All' command in TPDesign 4.
6605
 */
22 andreas 6606
void TPageManager::doPPX(int, std::vector<int>&, std::vector<std::string>&)
12 andreas 6607
{
6608
    DECL_TRACER("TPageManager::doPPX(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
6609
 
16 andreas 6610
    TError::clear();
12 andreas 6611
    PCHAIN_T *chain = mPchain;
14 andreas 6612
 
12 andreas 6613
    while(chain)
6614
    {
6615
        TSubPage *sub = chain->page->getFirstSubPage();
14 andreas 6616
 
12 andreas 6617
        while (sub)
6618
        {
351 andreas 6619
            MSG_DEBUG("Dropping subpage " << sub->getNumber() << ", \"" << sub->getName() << "\".");
12 andreas 6620
            sub->drop();
6621
            sub = chain->page->getNextSubPage();
6622
        }
14 andreas 6623
 
12 andreas 6624
        chain = chain->next;
6625
    }
14 andreas 6626
 
6627
    TPage *page = getPage(mActualPage);
6628
 
6629
    if (!page)
6630
    {
6631
        MSG_ERROR("No active page found! Internal error.");
351 andreas 6632
#if TESTMODE == 1
6633
        setAllDone();
6634
#endif
14 andreas 6635
        return;
6636
    }
6637
 
6638
    page->resetZOrder();
351 andreas 6639
#if TESTMODE == 1
6640
    setDone();
6641
#endif
12 andreas 6642
}
6643
 
14 andreas 6644
/**
15 andreas 6645
 * Set the show effect for the specified popup page to the named show effect.
6646
 */
22 andreas 6647
void TPageManager::doPSE(int, vector<int>&, vector<string>& pars)
15 andreas 6648
{
6649
    DECL_TRACER("TPageManager::doPSE(int port, vector<int>& channels, vector<string>& pars)");
6650
 
6651
    if (pars.size() < 2)
6652
    {
6653
        MSG_ERROR("Less than 2 parameters!");
351 andreas 6654
#if TESTMODE == 1
6655
        setAllDone();
6656
#endif
15 andreas 6657
        return;
6658
    }
6659
 
16 andreas 6660
    TError::clear();
96 andreas 6661
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6662
 
6663
    if (!pg)
351 andreas 6664
    {
6665
#if TESTMODE == 1
6666
        setAllDone();
6667
#endif
96 andreas 6668
        return;
351 andreas 6669
    }
15 andreas 6670
 
162 andreas 6671
    if (strCaseCompare(pars[1], "fade") == 0)
15 andreas 6672
        pg->setShowEffect(SE_FADE);
162 andreas 6673
    else if (strCaseCompare(pars[1], "slide to left") == 0)
15 andreas 6674
        pg->setShowEffect(SE_SLIDE_LEFT);
162 andreas 6675
    else if (strCaseCompare(pars[1], "slide to right") == 0)
15 andreas 6676
        pg->setShowEffect(SE_SLIDE_RIGHT);
162 andreas 6677
    else if (strCaseCompare(pars[1], "slide to top") == 0)
15 andreas 6678
        pg->setShowEffect(SE_SLIDE_TOP);
162 andreas 6679
    else if (strCaseCompare(pars[1], "slide to bottom") == 0)
15 andreas 6680
        pg->setShowEffect(SE_SLIDE_BOTTOM);
162 andreas 6681
    else if (strCaseCompare(pars[1], "slide to left fade") == 0)
15 andreas 6682
        pg->setShowEffect(SE_SLIDE_LEFT_FADE);
162 andreas 6683
    else if (strCaseCompare(pars[1], "slide to right fade") == 0)
15 andreas 6684
        pg->setShowEffect(SE_SLIDE_RIGHT_FADE);
162 andreas 6685
    else if (strCaseCompare(pars[1], "slide to top fade") == 0)
15 andreas 6686
        pg->setShowEffect(SE_SLIDE_TOP_FADE);
162 andreas 6687
    else if (strCaseCompare(pars[1], "slide to bottom fade") == 0)
15 andreas 6688
        pg->setShowEffect(SE_SLIDE_BOTTOM_FADE);
6689
    else
6690
        pg->setShowEffect(SE_NONE);
351 andreas 6691
#if TESTMODE == 1
6692
    if (_gTestMode)
6693
        _gTestMode->setResult(intToString(pg->getShowEffect()));
6694
 
6695
    __success = true;
6696
    setAllDone();
6697
#endif
15 andreas 6698
}
6699
 
162 andreas 6700
/**
6701
 * Set the show effect position. Only 1 coordinate is ever needed for an effect;
6702
 * however, the command will specify both. This command sets the location at
6703
 * which the effect will begin.
6704
 */
22 andreas 6705
void TPageManager::doPSP(int, vector<int>&, vector<string>& pars)
15 andreas 6706
{
6707
    DECL_TRACER("TPageManager::doPSP(int port, vector<int>& channels, vector<string>& pars)");
6708
 
6709
    if (pars.size() < 2)
6710
    {
6711
        MSG_ERROR("Less than 2 parameters!");
351 andreas 6712
#if TESTMODE == 1
6713
        setAllDone();
6714
#endif
15 andreas 6715
        return;
6716
    }
6717
 
16 andreas 6718
    TError::clear();
15 andreas 6719
    size_t pos = pars[1].find(",");
6720
    int x, y;
6721
 
6722
    if (pos == string::npos)
6723
    {
6724
        x = atoi(pars[1].c_str());
6725
        y = 0;
6726
    }
6727
    else
6728
    {
6729
        x = atoi(pars[1].substr(0, pos).c_str());
6730
        y = atoi(pars[1].substr(pos+1).c_str());
6731
    }
6732
 
96 andreas 6733
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6734
 
6735
    if (!pg)
351 andreas 6736
    {
6737
#if TESTMODE == 1
6738
        setAllDone();
6739
#endif
96 andreas 6740
        return;
351 andreas 6741
    }
15 andreas 6742
 
6743
    pg->setShowEndPosition(x, y);
351 andreas 6744
#if TESTMODE == 1
6745
    pg->getShowEndPosition(&x, &y);
6746
 
6747
    if (_gTestMode)
6748
        _gTestMode->setResult(intToString(x) + "," + intToString(y));
6749
 
6750
    __success = true;
6751
    setAllDone();
6752
#endif
15 andreas 6753
}
6754
 
6755
/**
6756
 * Set the show effect time for the specified popup page.
6757
 */
22 andreas 6758
void TPageManager::doPST(int, vector<int>&, vector<string>& pars)
15 andreas 6759
{
6760
    DECL_TRACER("TPageManager::doPST(int port, vector<int>& channels, vector<string>& pars)");
6761
 
6762
    if (pars.size() < 2)
6763
    {
6764
        MSG_ERROR("Less than 2 parameters!");
351 andreas 6765
#if TESTMODE == 1
6766
        setAllDone();
6767
#endif
15 andreas 6768
        return;
6769
    }
6770
 
16 andreas 6771
    TError::clear();
96 andreas 6772
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6773
 
6774
    if (!pg)
351 andreas 6775
    {
6776
#if TESTMODE == 1
6777
        setAllDone();
6778
#endif
96 andreas 6779
        return;
351 andreas 6780
    }
15 andreas 6781
 
6782
    pg->setShowTime(atoi(pars[1].c_str()));
351 andreas 6783
#if TESTMODE == 1
6784
    if (_gTestMode)
6785
        _gTestMode->setResult(intToString(pg->getShowTime()));
6786
 
6787
    __success = 1;
6788
    setAllDone();
6789
#endif
15 andreas 6790
}
6791
 
6792
/**
14 andreas 6793
 * Flips to a page with a specified page name. If the page is currently active,
6794
 * it will not redraw the page.
6795
 */
22 andreas 6796
void TPageManager::doPAGE(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6797
{
6798
    DECL_TRACER("TPageManager::doPAGE(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 6799
 
15 andreas 6800
    if (pars.empty())
6801
    {
6802
        MSG_WARNING("Got no page parameter!");
351 andreas 6803
#if TESTMODE == 1
6804
        setAllDone();
6805
#endif
15 andreas 6806
        return;
6807
    }
14 andreas 6808
 
16 andreas 6809
    TError::clear();
15 andreas 6810
    setPage(pars[0]);
351 andreas 6811
#if TESTMODE == 1
6812
    if (_gTestMode)
6813
        _gTestMode->setResult(intToString(getActualPageNumber()));
6814
 
6815
    setDone();
6816
#endif
15 andreas 6817
}
6818
 
6819
/**
38 andreas 6820
 * @brief TPageManager::doANI Run a button animation (in 1/10 second).
6821
 * Syntax:
6822
 *      ^ANI-<vt addr range>,<start state>,<end state>,<time>
6823
 * Variable:
6824
 *      variable text address range = 1 - 4000.
6825
 *      start state = Beginning of button state (0= current state).
6826
 *      end state = End of button state.
6827
 *      time = In 1/10 second intervals.
6828
 * Example:
6829
 *      SEND_COMMAND Panel,"'^ANI-500,1,25,100'"
6830
 * Runs a button animation at text range 500 from state 1 to state 25 for 10 seconds.
6831
 *
6832
 * @param port      The port number
6833
 * @param channels  The channels of the buttons
6834
 * @param pars      The parameters
6835
 */
6836
void TPageManager::doANI(int port, std::vector<int> &channels, std::vector<std::string> &pars)
6837
{
6838
    DECL_TRACER("TPageManager::doANI(int port, std::vector<int> &channels, std::vector<std::string> &pars)");
6839
 
6840
    if (pars.size() < 3)
6841
    {
6842
        MSG_ERROR("Expecting 3 parameters but got " << pars.size() << "! Ignoring command.");
6843
        return;
6844
    }
6845
 
6846
    TError::clear();
6847
    int stateStart = atoi(pars[0].c_str());
6848
    int endState = atoi(pars[1].c_str());
6849
    int runTime = atoi(pars[2].c_str());
6850
 
193 andreas 6851
    vector<TMap::MAP_T> map = findButtons(port, channels);
38 andreas 6852
 
6853
    if (TError::isError() || map.empty())
6854
        return;
6855
 
6856
    vector<Button::TButton *> buttons = collectButtons(map);
6857
 
83 andreas 6858
    if (buttons.size() > 0)
38 andreas 6859
    {
83 andreas 6860
        vector<Button::TButton *>::iterator mapIter;
6861
 
6862
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
6863
        {
6864
            Button::TButton *bt = *mapIter;
6865
            bt->startAnimation(stateStart, endState, runTime);
6866
        }
38 andreas 6867
    }
351 andreas 6868
#if TESTMODE == 1
6869
    if (_gTestMode)
6870
        _gTestMode->setResult(intToString(stateStart) + "," + intToString(endState) + "," + intToString(runTime));
6871
 
6872
    setDone();
6873
#endif
38 andreas 6874
}
6875
 
6876
/**
15 andreas 6877
 * Add page flip action to a button if it does not already exist.
6878
 */
6879
void TPageManager::doAPF(int port, vector<int>& channels, vector<string>& pars)
6880
{
6881
    DECL_TRACER("TPageManager::doAPF(int port, vector<int>& channels, vector<string>& pars)");
6882
 
6883
    if (pars.size() < 2)
6884
    {
6885
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
351 andreas 6886
#if TESTMODE == 1
6887
        setAllDone();
6888
#endif
14 andreas 6889
        return;
15 andreas 6890
    }
14 andreas 6891
 
16 andreas 6892
    TError::clear();
15 andreas 6893
    string action = pars[0];
6894
    string pname = pars[1];
14 andreas 6895
 
193 andreas 6896
    vector<TMap::MAP_T> map = findButtons(port, channels);
14 andreas 6897
 
15 andreas 6898
    if (TError::isError() || map.empty())
351 andreas 6899
    {
6900
#if TESTMODE == 1
6901
        setAllDone();
6902
#endif
15 andreas 6903
        return;
351 andreas 6904
    }
15 andreas 6905
 
6906
    vector<Button::TButton *> buttons = collectButtons(map);
6907
 
83 andreas 6908
    if (buttons.size() > 0)
12 andreas 6909
    {
83 andreas 6910
        vector<Button::TButton *>::iterator mapIter;
6911
 
6912
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
6913
        {
6914
            Button::TButton *bt = *mapIter;
6915
            bt->addPushFunction(action, pname);
6916
        }
15 andreas 6917
    }
351 andreas 6918
#if TESTMODE == 1
6919
    if (_gTestMode)
6920
        _gTestMode->setResult(toUpper(action) + "," + toUpper(pname));
6921
 
6922
    __success = true;
6923
    setAllDone();
6924
#endif
15 andreas 6925
}
12 andreas 6926
 
15 andreas 6927
/**
43 andreas 6928
 * Append non-unicode text.
6929
 */
6930
void TPageManager::doBAT(int port, vector<int> &channels, vector<string> &pars)
6931
{
6932
    DECL_TRACER("TPageManager::doBAT(int port, vector<int> &channels, vector<string> &pars)");
6933
 
6934
    if (pars.size() < 1)
6935
    {
6936
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
330 andreas 6937
#if TESTMODE == 1
334 andreas 6938
        setAllDone();
330 andreas 6939
#endif
43 andreas 6940
        return;
6941
    }
6942
 
6943
    TError::clear();
6944
    int btState = atoi(pars[0].c_str());
6945
    string text;
6946
 
6947
    if (pars.size() > 1)
6948
        text = pars[1];
6949
 
193 andreas 6950
    vector<TMap::MAP_T> map = findButtons(port, channels);
43 andreas 6951
 
6952
    if (TError::isError() || map.empty())
330 andreas 6953
    {
6954
#if TESTMODE == 1
334 andreas 6955
        setAllDone();
330 andreas 6956
#endif
43 andreas 6957
        return;
330 andreas 6958
    }
43 andreas 6959
 
6960
    vector<Button::TButton *> buttons = collectButtons(map);
6961
 
162 andreas 6962
    if (buttons.empty())
330 andreas 6963
    {
6964
#if TESTMODE == 1
334 andreas 6965
        setAllDone();
330 andreas 6966
#endif
162 andreas 6967
        return;
330 andreas 6968
    }
162 andreas 6969
 
6970
    vector<Button::TButton *>::iterator mapIter;
6971
 
6972
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
43 andreas 6973
    {
162 andreas 6974
        Button::TButton *bt = *mapIter;
43 andreas 6975
 
331 andreas 6976
        bt->appendText(text, btState - 1);
330 andreas 6977
#if TESTMODE == 1
331 andreas 6978
        if (_gTestMode)
330 andreas 6979
        {
331 andreas 6980
            int st = (btState > 0 ? (btState - 1) : 0);
6981
            _gTestMode->setResult(bt->getText(st));
333 andreas 6982
        }
330 andreas 6983
 
331 andreas 6984
        __success = true;
330 andreas 6985
#endif
43 andreas 6986
    }
334 andreas 6987
#if TESTMODE == 1
6988
    setDone();
6989
#endif
43 andreas 6990
}
6991
 
6992
/**
60 andreas 6993
 * @brief Append unicode text. Same format as ^UNI.
6994
 * This command allows to set up to 50 characters of ASCII code. The unicode
6995
 * characters must be set as hex numbers.
6996
 */
6997
void TPageManager::doBAU(int port, vector<int>& channels, vector<string>& pars)
6998
{
6999
    DECL_TRACER("TPageManager::doBAU(int port, vector<int>& channels, vector<string>& pars)");
7000
 
7001
    if (pars.size() < 1)
7002
    {
7003
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7004
#if TESTMODE == 1
7005
        setAllDone();
7006
#endif
60 andreas 7007
        return;
7008
    }
7009
 
7010
    TError::clear();
7011
    int btState = atoi(pars[0].c_str());
7012
    string text;
7013
    char ch[3];
7014
 
331 andreas 7015
    if (pars.size() > 1)
7016
        text = pars[1];
7017
 
7018
    if ((text.size() % 4) == 0)
60 andreas 7019
    {
162 andreas 7020
        try
60 andreas 7021
        {
162 andreas 7022
            text = pars[1];
331 andreas 7023
            MSG_DEBUG("Processing UTF16 string: " << text);
162 andreas 7024
            // Because the unicode characters are hex numbers, we scan the text
7025
            // and convert the hex numbers into real numbers.
7026
            size_t len = text.length();
7027
            bool inHex = false;
7028
            int lastChar = 0;
331 andreas 7029
            uint16_t *numstr = new uint16_t[len / 4];
162 andreas 7030
            int uniPos = 0;
331 andreas 7031
            int cntCount = 0;
60 andreas 7032
 
162 andreas 7033
            for (size_t i = 0; i < len; i++)
60 andreas 7034
            {
162 andreas 7035
                int c = text.at(i);
60 andreas 7036
 
162 andreas 7037
                if (!inHex && isHex(c))
7038
                {
7039
                    inHex = true;
7040
                    lastChar = c;
7041
                    continue;
7042
                }
7043
 
7044
                if (inHex && !isHex(c))
7045
                    break;
7046
 
7047
                if (inHex && isHex(c))
7048
                {
7049
                    ch[0] = lastChar;
7050
                    ch[1] = c;
7051
                    ch[2] = 0;
7052
                    uint16_t num = (uint16_t)strtol(ch, NULL, 16);
331 andreas 7053
 
7054
                    if ((cntCount % 2) != 0)
7055
                    {
7056
                        numstr[uniPos] |= num;
7057
                        uniPos++;
7058
                    }
7059
                    else
7060
                        numstr[uniPos] = (num << 8) & 0xff00;
7061
 
7062
                    cntCount++;
162 andreas 7063
                    inHex = false;
7064
 
7065
                    if (uniPos >= 50)
7066
                        break;
331 andreas 7067
                }
7068
            }
162 andreas 7069
 
331 andreas 7070
            text.clear();
7071
            // Here we make from the real numbers a UTF8 string
7072
            for (size_t i = 0; i < len / 4; ++i)
7073
            {
7074
                if (numstr[i] <= 0x00ff)
7075
                {
7076
                    ch[0] = numstr[i];
7077
                    ch[1] = 0;
7078
                    text.append(ch);
162 andreas 7079
                }
331 andreas 7080
                else
7081
                {
7082
                    ch[0] = (numstr[i] >> 8) & 0x00ff;
7083
                    ch[1] = numstr[i] & 0x00ff;
7084
                    ch[2] = 0;
7085
                    text.append(ch);
7086
                }
60 andreas 7087
            }
7088
 
331 andreas 7089
            delete[] numstr;
60 andreas 7090
        }
162 andreas 7091
        catch (std::exception const & e)
7092
        {
7093
            MSG_ERROR("Character conversion error: " << e.what());
351 andreas 7094
#if TESTMODE == 1
7095
            setAllDone();
7096
#endif
162 andreas 7097
            return;
7098
        }
60 andreas 7099
    }
331 andreas 7100
    else
7101
    {
7102
        MSG_WARNING("No or invalid UTF16 string: " << text);
351 andreas 7103
#if TESTMODE == 1
7104
        setAllDone();
7105
#endif
331 andreas 7106
        return;
7107
    }
60 andreas 7108
 
193 andreas 7109
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 7110
 
7111
    if (TError::isError() || map.empty())
351 andreas 7112
    {
7113
#if TESTMODE == 1
7114
        setAllDone();
7115
#endif
60 andreas 7116
        return;
351 andreas 7117
    }
60 andreas 7118
 
7119
    vector<Button::TButton *> buttons = collectButtons(map);
7120
 
83 andreas 7121
    if (buttons.size() > 0)
60 andreas 7122
    {
83 andreas 7123
        vector<Button::TButton *>::iterator mapIter;
60 andreas 7124
 
83 andreas 7125
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 7126
        {
83 andreas 7127
            Button::TButton *bt = *mapIter;
60 andreas 7128
 
331 andreas 7129
            bt->appendText(text, btState - 1);
330 andreas 7130
#if TESTMODE == 1
331 andreas 7131
            if (_gTestMode)
7132
                _gTestMode->setResult(bt->getText(btState - 1));
330 andreas 7133
 
331 andreas 7134
            __success = true;
330 andreas 7135
#endif
60 andreas 7136
        }
7137
    }
330 andreas 7138
#if TESTMODE == 1
334 andreas 7139
    setDone();
330 andreas 7140
#endif
60 andreas 7141
}
7142
 
7143
/**
43 andreas 7144
 * @brief TPageManager::doBCB Set the border color.
7145
 * Set the border color to the specified color. Only if the specified border
7146
 * color is not the same as the current color.
7147
 * Note: Color can be assigned by color name (without spaces), number or
7148
 * R,G,B value (RRGGBB or RRGGBBAA).
7149
 */
7150
void TPageManager::doBCB(int port, vector<int> &channels, vector<string> &pars)
7151
{
7152
    DECL_TRACER("TPageManager::doBCB(int port, vector<int> &channels, vector<string> &pars)");
7153
 
7154
    if (pars.size() < 1)
7155
    {
7156
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7157
#if TESTMODE == 1
7158
        setAllDone();
7159
#endif
43 andreas 7160
        return;
7161
    }
7162
 
7163
    TError::clear();
7164
    int btState = atoi(pars[0].c_str());
7165
    string color;
7166
 
7167
    if (pars.size() > 1)
7168
        color = pars[1];
7169
 
193 andreas 7170
    vector<TMap::MAP_T> map = findButtons(port, channels);
43 andreas 7171
 
7172
    if (TError::isError() || map.empty())
351 andreas 7173
    {
7174
#if TESTMODE == 1
7175
        setAllDone();
7176
#endif
43 andreas 7177
        return;
351 andreas 7178
    }
43 andreas 7179
 
7180
    vector<Button::TButton *> buttons = collectButtons(map);
7181
 
83 andreas 7182
    if (buttons.size() > 0)
43 andreas 7183
    {
83 andreas 7184
        vector<Button::TButton *>::iterator mapIter;
43 andreas 7185
 
83 andreas 7186
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
43 andreas 7187
        {
83 andreas 7188
            Button::TButton *bt = *mapIter;
351 andreas 7189
            bt->setBorderColor(color, btState - 1);
7190
#if TESTMODE == 1
7191
            if (_gTestMode)
7192
                _gTestMode->setResult(bt->getBorderColor(btState == 0 ? 0 : btState - 1));
7193
#endif
43 andreas 7194
        }
7195
    }
351 andreas 7196
#if TESTMODE == 1
7197
    setDone();
7198
#endif
43 andreas 7199
}
60 andreas 7200
 
351 andreas 7201
/*
7202
 * Get the border color and send it as a custom event.
7203
 */
82 andreas 7204
void TPageManager::getBCB(int port, vector<int> &channels, vector<string> &pars)
7205
{
7206
    DECL_TRACER("TPageManager::getBCB(int port, vector<int> &channels, vector<string> &pars)");
7207
 
7208
    if (pars.size() < 1)
7209
    {
7210
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7211
#if TESTMODE == 1
7212
        setAllDone();
7213
#endif
82 andreas 7214
        return;
7215
    }
7216
 
7217
    TError::clear();
7218
    int btState = atoi(pars[0].c_str());
7219
    string color;
7220
 
193 andreas 7221
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 7222
 
7223
    if (TError::isError() || map.empty())
351 andreas 7224
    {
7225
#if TESTMODE == 1
7226
        setAllDone();
7227
#endif
82 andreas 7228
        return;
351 andreas 7229
    }
82 andreas 7230
 
7231
    vector<Button::TButton *> buttons = collectButtons(map);
7232
 
351 andreas 7233
    if (buttons.empty())
82 andreas 7234
    {
351 andreas 7235
#if TESTMODE == 1
7236
        setAllDone();
7237
#endif
7238
        return;
7239
    }
82 andreas 7240
 
351 andreas 7241
    vector<Button::TButton *>::iterator iter;
7242
 
7243
    for (iter = buttons.begin(); iter != buttons.end(); ++iter)
7244
    {
7245
        Button::TButton *bt = *iter;
7246
 
110 andreas 7247
        if (btState == 0)       // All instances?
82 andreas 7248
        {
110 andreas 7249
            int bst = bt->getNumberInstances();
82 andreas 7250
 
110 andreas 7251
            for (int i = 0; i < bst; i++)
82 andreas 7252
            {
110 andreas 7253
                color = bt->getBorderColor(i);
82 andreas 7254
 
110 andreas 7255
                if (color.empty())
7256
                    continue;
83 andreas 7257
 
300 andreas 7258
                sendCustomEvent(i + 1, (int)color.length(), 0, color, 1011, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 7259
#if TESTMODE == 1
7260
                __success = true;
7261
 
7262
                if (_gTestMode)
7263
                    _gTestMode->setResult(color);
7264
#endif
83 andreas 7265
            }
110 andreas 7266
        }
7267
        else
7268
        {
7269
            color = bt->getBorderColor(btState - 1);
83 andreas 7270
 
110 andreas 7271
            if (color.empty())
351 andreas 7272
                continue;
82 andreas 7273
 
300 andreas 7274
            sendCustomEvent(btState, (int)color.length(), 0, color, 1011, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 7275
#if TESTMODE == 1
7276
            __success = true;
7277
 
7278
            if (_gTestMode)
7279
                _gTestMode->setResult(color);
7280
#endif
82 andreas 7281
        }
7282
    }
351 andreas 7283
#if TESTMODE == 1
7284
    setAllDone();
7285
#endif
82 andreas 7286
}
7287
 
43 andreas 7288
/**
60 andreas 7289
 * @brief Set the fill color to the specified color.
7290
 * Only if the specified fill color is not the same as the current color.
7291
 * Note: Color can be assigned by color name (without spaces), number or R,G,B value (RRGGBB or RRGGBBAA).
15 andreas 7292
 */
60 andreas 7293
void TPageManager::doBCF(int port, vector<int>& channels, vector<std::string>& pars)
15 andreas 7294
{
60 andreas 7295
    DECL_TRACER("TPageManager::doBCF(int port, vector<int>& channels, vector<std::string>& pars)");
15 andreas 7296
 
60 andreas 7297
    if (pars.size() < 1)
15 andreas 7298
    {
60 andreas 7299
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7300
#if TESTMODE == 1
7301
        setAllDone();
7302
#endif
12 andreas 7303
        return;
7304
    }
14 andreas 7305
 
16 andreas 7306
    TError::clear();
15 andreas 7307
    int btState = atoi(pars[0].c_str());
60 andreas 7308
    string color;
14 andreas 7309
 
60 andreas 7310
    if (pars.size() > 1)
7311
        color = pars[1];
7312
 
193 andreas 7313
    vector<TMap::MAP_T> map = findButtons(port, channels);
15 andreas 7314
 
7315
    if (TError::isError() || map.empty())
351 andreas 7316
    {
7317
#if TESTMODE == 1
7318
        setAllDone();
7319
#endif
15 andreas 7320
        return;
351 andreas 7321
    }
15 andreas 7322
 
7323
    vector<Button::TButton *> buttons = collectButtons(map);
7324
 
83 andreas 7325
    if (buttons.size() > 0)
15 andreas 7326
    {
83 andreas 7327
        vector<Button::TButton *>::iterator mapIter;
15 andreas 7328
 
83 andreas 7329
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
15 andreas 7330
        {
83 andreas 7331
            Button::TButton *bt = *mapIter;
351 andreas 7332
            bt->setFillColor(color, btState - 1);
7333
#if TESTMODE == 1
7334
            if (_gTestMode)
7335
                _gTestMode->setResult(bt->getFillColor(btState == 0 ? 0 : btState - 1));
7336
#endif
15 andreas 7337
        }
7338
    }
351 andreas 7339
#if TESTMODE == 1
7340
    setDone();
7341
#endif
12 andreas 7342
}
7343
 
351 andreas 7344
/*
7345
 * Get the fill color and send it via a custom event to the NetLinx.
7346
 */
82 andreas 7347
void TPageManager::getBCF(int port, vector<int> &channels, vector<string> &pars)
7348
{
7349
    DECL_TRACER("TPageManager::getBCF(int port, vector<int> &channels, vector<string> &pars)");
7350
 
7351
    if (pars.size() < 1)
7352
    {
7353
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7354
#if TESTMODE == 1
7355
        setAllDone();
7356
#endif
82 andreas 7357
        return;
7358
    }
7359
 
7360
    TError::clear();
7361
    int btState = atoi(pars[0].c_str());
7362
    string color;
7363
 
193 andreas 7364
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 7365
 
7366
    if (TError::isError() || map.empty())
351 andreas 7367
    {
7368
#if TESTMODE == 1
7369
        setAllDone();
7370
#endif
82 andreas 7371
        return;
351 andreas 7372
    }
82 andreas 7373
 
7374
    vector<Button::TButton *> buttons = collectButtons(map);
7375
 
351 andreas 7376
    if (buttons.empty())
82 andreas 7377
    {
351 andreas 7378
#if TESTMODE == 1
7379
        setAllDone();
7380
#endif
7381
        return;
7382
    }
82 andreas 7383
 
351 andreas 7384
    vector<Button::TButton *>::iterator iter;
7385
 
7386
    for (iter = buttons.begin(); iter != buttons.end(); ++iter)
7387
    {
7388
        Button::TButton *bt = *iter;
7389
 
110 andreas 7390
        if (btState == 0)       // All instances?
82 andreas 7391
        {
110 andreas 7392
            int bst = bt->getNumberInstances();
82 andreas 7393
 
110 andreas 7394
            for (int i = 0; i < bst; i++)
82 andreas 7395
            {
110 andreas 7396
                color = bt->getFillColor(i);
82 andreas 7397
 
110 andreas 7398
                if (color.empty())
7399
                    continue;
82 andreas 7400
 
300 andreas 7401
                sendCustomEvent(i + 1, (int)color.length(), 0, color, 1012, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 7402
#if TESTMODE == 1
7403
                __success = true;
7404
 
7405
                if (_gTestMode)
7406
                    _gTestMode->setResult(color);
7407
#endif
83 andreas 7408
            }
82 andreas 7409
        }
110 andreas 7410
        else
7411
        {
7412
            color = bt->getFillColor(btState-1);
351 andreas 7413
 
7414
            if (color.empty())
7415
                continue;
7416
 
300 andreas 7417
            sendCustomEvent(btState, (int)color.length(), 0, color, 1012, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 7418
#if TESTMODE == 1
7419
            __success = true;
7420
 
7421
            if (_gTestMode)
7422
                _gTestMode->setResult(color);
7423
#endif
110 andreas 7424
        }
82 andreas 7425
    }
351 andreas 7426
#if TESTMODE == 1
7427
    setAllDone();
7428
#endif
82 andreas 7429
}
7430
 
60 andreas 7431
/**
7432
 * @brief Set the text color to the specified color.
7433
 * Only if the specified text color is not the same as the current color.
7434
 * Note: Color can be assigned by color name (without spaces), number or R,G,B value (RRGGBB or RRGGBBAA).
7435
 */
7436
void TPageManager::doBCT(int port, vector<int>& channels, vector<string>& pars)
18 andreas 7437
{
60 andreas 7438
    DECL_TRACER("TPageManager::doBCT(int port, vector<int>& channels, vector<string>& pars)");
7439
 
7440
    if (pars.size() < 1)
7441
    {
7442
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7443
#if TESTMODE == 1
7444
        setAllDone();
7445
#endif
60 andreas 7446
        return;
7447
    }
7448
 
7449
    TError::clear();
7450
    int btState = atoi(pars[0].c_str());
7451
    string color;
7452
 
7453
    if (pars.size() > 1)
7454
        color = pars[1];
7455
 
193 andreas 7456
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 7457
 
7458
    if (TError::isError() || map.empty())
351 andreas 7459
    {
7460
#if TESTMODE == 1
7461
        setAllDone();
7462
#endif
60 andreas 7463
        return;
351 andreas 7464
    }
60 andreas 7465
 
7466
    vector<Button::TButton *> buttons = collectButtons(map);
7467
 
83 andreas 7468
    if (buttons.size() > 0)
60 andreas 7469
    {
83 andreas 7470
        vector<Button::TButton *>::iterator mapIter;
60 andreas 7471
 
83 andreas 7472
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 7473
        {
83 andreas 7474
            Button::TButton *bt = *mapIter;
351 andreas 7475
            bt->setTextColor(color, btState - 1);
7476
#if TESTMODE == 1
7477
            if (_gTestMode)
7478
                _gTestMode->setResult(bt->getTextColor(btState == 0 ? 0 : btState - 1));
7479
#endif
60 andreas 7480
        }
7481
    }
351 andreas 7482
#if TESTMODE == 1
7483
    setDone();
7484
#endif
18 andreas 7485
}
7486
 
351 andreas 7487
/*
7488
 * Get the text color of a button and send it via a custom event to the NetLinx.
7489
 */
82 andreas 7490
void TPageManager::getBCT(int port, vector<int> &channels, vector<string> &pars)
7491
{
7492
    DECL_TRACER("TPageManager::getBCT(int port, vector<int> &channels, vector<string> &pars)");
7493
 
7494
    if (pars.size() < 1)
7495
    {
7496
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7497
#if TESTMODE == 1
7498
        setAllDone();
7499
#endif
82 andreas 7500
        return;
7501
    }
7502
 
7503
    TError::clear();
7504
    int btState = atoi(pars[0].c_str());
7505
    string color;
7506
 
193 andreas 7507
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 7508
 
7509
    if (TError::isError() || map.empty())
351 andreas 7510
    {
7511
#if TESTMODE == 1
7512
        setAllDone();
7513
#endif
82 andreas 7514
        return;
351 andreas 7515
    }
82 andreas 7516
 
7517
    vector<Button::TButton *> buttons = collectButtons(map);
7518
 
351 andreas 7519
    if (buttons.empty())
82 andreas 7520
    {
351 andreas 7521
#if TESTMODE == 1
7522
        setAllDone();
7523
#endif
7524
        return;
7525
    }
82 andreas 7526
 
351 andreas 7527
    vector<Button::TButton *>::iterator iter;
7528
 
7529
    for (iter = buttons.begin(); iter != buttons.end(); ++iter)
7530
    {
7531
        Button::TButton *bt = *iter;
7532
 
110 andreas 7533
        if (btState == 0)       // All instances?
82 andreas 7534
        {
110 andreas 7535
            int bst = bt->getNumberInstances();
82 andreas 7536
 
110 andreas 7537
            for (int i = 0; i < bst; i++)
82 andreas 7538
            {
110 andreas 7539
                color = bt->getTextColor(i);
82 andreas 7540
 
110 andreas 7541
                if (color.empty())
7542
                    continue;
82 andreas 7543
 
300 andreas 7544
                sendCustomEvent(i + 1, (int)color.length(), 0, color, 1013, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 7545
#if TESTMODE == 1
7546
                __success = true;
7547
 
7548
                if (_gTestMode)
7549
                    _gTestMode->setResult(color);
7550
#endif
83 andreas 7551
            }
82 andreas 7552
        }
110 andreas 7553
        else
7554
        {
7555
            color = bt->getTextColor(btState - 1);
351 andreas 7556
 
7557
            if (color.empty())
7558
                continue;
7559
 
300 andreas 7560
            sendCustomEvent(btState, (int)color.length(), 0, color, 1013, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 7561
#if TESTMODE == 1
7562
            __success = true;
7563
 
7564
            if (_gTestMode)
7565
                _gTestMode->setResult(color);
7566
#endif
110 andreas 7567
        }
82 andreas 7568
    }
351 andreas 7569
#if TESTMODE == 1
7570
    setAllDone();
7571
#endif
82 andreas 7572
}
7573
 
60 andreas 7574
/**
7575
 * Set the button draw order
7576
 * Determines what order each layer of the button is drawn.
7577
 */
7578
void TPageManager::doBDO(int port, vector<int>& channels, vector<std::string>& pars)
32 andreas 7579
{
60 andreas 7580
    DECL_TRACER("TPageManager::doBDO(int port, vector<int>& channels, vector<std::string>& pars)");
32 andreas 7581
 
60 andreas 7582
    if (pars.size() < 1)
7583
    {
7584
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7585
#if TESTMODE == 1
7586
        setAllDone();
7587
#endif
32 andreas 7588
        return;
60 andreas 7589
    }
32 andreas 7590
 
60 andreas 7591
    TError::clear();
7592
    int btState = atoi(pars[0].c_str());
7593
    string order;
32 andreas 7594
 
60 andreas 7595
    if (pars.size() > 1)
7596
    {
7597
        string ord = pars[1];
7598
        // Convert the numbers into the expected draw order
7599
        for (size_t i = 0; i < ord.length(); i++)
7600
        {
7601
            if (ord.at(i) >= '1' && ord.at(i) <= '5')
7602
            {
7603
                char hv0[32];
7604
                snprintf(hv0, sizeof(hv0), "%02d", (int)(ord.at(i) - '0'));
7605
                order.append(hv0);
7606
            }
7607
            else
7608
            {
7609
                MSG_ERROR("Illegal order number " << ord.substr(i, 1) << "!");
7610
                return;
7611
            }
7612
        }
7613
 
7614
        if (order.length() != 10)
7615
        {
7616
            MSG_ERROR("Expected 5 order numbers but got " << (order.length() / 2)<< "!");
7617
            return;
7618
        }
7619
    }
7620
 
193 andreas 7621
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 7622
 
7623
    if (TError::isError() || map.empty())
351 andreas 7624
    {
7625
#if TESTMODE == 1
7626
        setAllDone();
7627
#endif
32 andreas 7628
        return;
351 andreas 7629
    }
32 andreas 7630
 
60 andreas 7631
    vector<Button::TButton *> buttons = collectButtons(map);
7632
 
83 andreas 7633
    if (buttons.size() > 0)
32 andreas 7634
    {
83 andreas 7635
        vector<Button::TButton *>::iterator mapIter;
32 andreas 7636
 
83 andreas 7637
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 7638
        {
83 andreas 7639
            Button::TButton *bt = *mapIter;
351 andreas 7640
            bt->setDrawOrder(order, btState - 1);
7641
#if TESTMODE == 1
7642
            if (_gTestMode)
7643
                _gTestMode->setResult(bt->getDrawOrder(btState == 0 ? 0 : btState - 1));
7644
#endif
60 andreas 7645
        }
7646
    }
351 andreas 7647
#if TESTMODE == 1
7648
    setDone();
7649
#endif
60 andreas 7650
}
32 andreas 7651
 
60 andreas 7652
/**
7653
 * Set the feedback type of the button.
7654
 * ONLY works on General-type buttons.
7655
 */
7656
void TPageManager::doBFB(int port, vector<int>& channels, vector<std::string>& pars)
7657
{
7658
    DECL_TRACER("TPageManager::doBFB(int port, vector<int>& channels, vector<std::string>& pars)");
32 andreas 7659
 
60 andreas 7660
    if (pars.size() < 1)
7661
    {
7662
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7663
#if TESTMODE == 1
7664
        setAllDone();
7665
#endif
60 andreas 7666
        return;
7667
    }
7668
 
7669
    TError::clear();
7670
    Button::FEEDBACK type = Button::FB_NONE;
7671
    string stype = pars[0];
7672
    vector<string> stypes = { "None", "Channel", "Invert", "On", "Momentary", "Blink" };
7673
    vector<string>::iterator iter;
7674
    int i = 0;
7675
 
7676
    for (iter = stypes.begin(); iter != stypes.end(); ++iter)
7677
    {
7678
        if (strCaseCompare(stype, *iter) == 0)
33 andreas 7679
        {
60 andreas 7680
            type = (Button::FEEDBACK)i;
7681
            break;
32 andreas 7682
        }
60 andreas 7683
 
7684
        i++;
32 andreas 7685
    }
7686
 
193 andreas 7687
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 7688
 
7689
    if (TError::isError() || map.empty())
351 andreas 7690
    {
7691
#if TESTMODE == 1
7692
        setAllDone();
7693
#endif
60 andreas 7694
        return;
351 andreas 7695
    }
60 andreas 7696
 
7697
    vector<Button::TButton *> buttons = collectButtons(map);
7698
 
83 andreas 7699
    if (buttons.size() > 0)
60 andreas 7700
    {
83 andreas 7701
        vector<Button::TButton *>::iterator mapIter;
7702
 
7703
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
7704
        {
7705
            Button::TButton *bt = *mapIter;
7706
            bt->setFeedback(type);
351 andreas 7707
#if TESTMODE == 1
7708
            if (_gTestMode)
7709
                _gTestMode->setResult(intToString(bt->getFeedback()));
7710
#endif
83 andreas 7711
        }
60 andreas 7712
    }
335 andreas 7713
#if TESTMODE == 1
7714
    setDone();
7715
#endif
32 andreas 7716
}
7717
 
224 andreas 7718
/*
7719
 * Set the input mask for the specified address.
7720
 */
7721
void TPageManager::doBIM(int port, vector<int>& channels, vector<std::string>& pars)
7722
{
7723
    DECL_TRACER("TPageManager::doBIM(int port, vector<int>& channels, vector<std::string>& pars)");
7724
 
7725
    if (pars.size() < 1)
7726
    {
7727
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7728
#if TESTMODE == 1
7729
        setAllDone();
7730
#endif
224 andreas 7731
        return;
7732
    }
7733
 
7734
    TError::clear();
7735
    string mask = pars[0];
7736
    vector<TMap::MAP_T> map = findButtons(port, channels);
7737
 
7738
    if (TError::isError() || map.empty())
351 andreas 7739
    {
7740
#if TESTMODE == 1
7741
        setAllDone();
7742
#endif
224 andreas 7743
        return;
351 andreas 7744
    }
224 andreas 7745
 
7746
    vector<Button::TButton *> buttons = collectButtons(map);
7747
 
7748
    if (buttons.size() > 0)
7749
    {
7750
        vector<Button::TButton *>::iterator mapIter;
7751
 
7752
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
7753
        {
7754
            Button::TButton *bt = *mapIter;
7755
            bt->setInputMask(mask);
351 andreas 7756
#if TESTMODE == 1
7757
            if (_gTestMode)
7758
                _gTestMode->setResult(bt->getInputMask());
7759
#endif
224 andreas 7760
        }
7761
    }
351 andreas 7762
#if TESTMODE == 1
7763
    setDone();
7764
#endif
224 andreas 7765
}
7766
 
351 andreas 7767
/**
7768
 * @brief Button copy command.
7769
 * Copy attributes of the source button to all the
7770
 * destination buttons. Note that the source is a single button state. Each
7771
 * state must be copied as a separate command. The <codes> section represents
7772
 * what attributes will be copied. All codes are 2 char pairs that can be
7773
 * separated by comma, space, percent or just ran together.
7774
 */
106 andreas 7775
void TPageManager::doBMC(int port, vector<int>& channels, vector<std::string>& pars)
7776
{
7777
    DECL_TRACER("TPageManager::doBMC(int port, vector<int>& channels, vector<std::string>& pars)");
7778
 
7779
    if (pars.size() < 5)
7780
    {
7781
        MSG_ERROR("Expecting 5 parameters but got " << pars.size() << ". Ignoring command.");
351 andreas 7782
#if TESTMODE == 1
7783
        setAllDone();
7784
#endif
106 andreas 7785
        return;
7786
    }
7787
 
7788
    TError::clear();
7789
    int btState = atoi(pars[0].c_str());
7790
    int src_port = atoi(pars[1].c_str());
7791
    int src_addr = atoi(pars[2].c_str());
7792
    int src_state = atoi(pars[3].c_str());
7793
    string src_codes = pars[4];
7794
    vector<int> src_channel;
7795
    src_channel.push_back(src_addr);
7796
 
193 andreas 7797
    vector<TMap::MAP_T> src_map = findButtons(src_port, src_channel);
106 andreas 7798
 
7799
    if (src_map.size() == 0)
7800
    {
7801
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " does not exist!");
351 andreas 7802
#if TESTMODE == 1
7803
        setAllDone();
7804
#endif
106 andreas 7805
        return;
7806
    }
7807
 
7808
    vector<Button::TButton *>src_buttons = collectButtons(src_map);
7809
 
7810
    if (src_buttons.size() == 0)
7811
    {
7812
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " does not exist!");
351 andreas 7813
#if TESTMODE == 1
7814
        setAllDone();
7815
#endif
106 andreas 7816
        return;
7817
    }
7818
 
7819
    if (src_buttons[0]->getNumberInstances() < src_state)
7820
    {
7821
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " has less then " << src_state << " elements.");
351 andreas 7822
#if TESTMODE == 1
7823
        setAllDone();
7824
#endif
106 andreas 7825
        return;
7826
    }
7827
 
7828
    if (src_state < 1)
7829
    {
7830
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " has invalid source state " << src_state << ".");
351 andreas 7831
#if TESTMODE == 1
7832
        setAllDone();
7833
#endif
106 andreas 7834
        return;
7835
    }
7836
 
7837
    src_state--;
7838
 
7839
    if (btState > 0)
7840
        btState--;
7841
 
193 andreas 7842
    vector<TMap::MAP_T> map = findButtons(port, channels);
106 andreas 7843
    vector<Button::TButton *> buttons = collectButtons(map);
7844
    //                        0     1     2     3     4     5     6     7
7845
    vector<string>codes = { "BM", "BR", "CB", "CF", "CT", "EC", "EF", "FT",
7846
                            "IC", "JB", "JI", "JT", "LN", "OP", "SO", "TX", // 8 - 15
7847
                            "VI", "WW" };   // 16, 17
7848
 
7849
    for (size_t ibuttons = 0; ibuttons < buttons.size(); ibuttons++)
7850
    {
7851
        vector<string>::iterator iter;
7852
        int idx = 0;
7853
 
7854
        for (iter = codes.begin(); iter != codes.end(); ++iter)
7855
        {
7856
            if (src_codes.find(*iter) != string::npos)
7857
            {
7858
                int j, x, y;
7859
 
7860
                switch(idx)
7861
                {
7862
                    case 0: buttons[ibuttons]->setBitmap(src_buttons[0]->getBitmapName(src_state), btState); break;
7863
                    case 1: buttons[ibuttons]->setBorderStyle(src_buttons[0]->getBorderStyle(src_state), btState); break;
7864
                    case 2: buttons[ibuttons]->setBorderColor(src_buttons[0]->getBorderColor(src_state), btState); break;
7865
                    case 3: buttons[ibuttons]->setFillColor(src_buttons[0]->getFillColor(src_state), btState); break;
7866
                    case 4: buttons[ibuttons]->setTextColor(src_buttons[0]->getTextColor(src_state), btState); break;
7867
                    case 5: buttons[ibuttons]->setTextEffectColor(src_buttons[0]->getTextEffectColor(src_state), btState); break;
7868
                    case 6: buttons[ibuttons]->setTextEffect(src_buttons[0]->getTextEffect(src_state), btState); break;
7869
                    case 7: buttons[ibuttons]->setFontIndex(src_buttons[0]->getFontIndex(src_state), btState); break;
110 andreas 7870
                    case 8: buttons[ibuttons]->setIcon(src_buttons[0]->getIconIndex(src_state), btState); break;
106 andreas 7871
 
7872
                    case 9:
7873
                        j = src_buttons[0]->getBitmapJustification(&x, &y, src_state);
7874
                        buttons[ibuttons]->setBitmapJustification(j, x, y, btState);
7875
                    break;
7876
 
7877
                    case 10:
7878
                        j = src_buttons[0]->getIconJustification(&x, &y, src_state);
7879
                        buttons[ibuttons]->setIconJustification(j, x, y, btState);
7880
                    break;
7881
 
7882
                    case 11:
7883
                        j = src_buttons[0]->getTextJustification(&x, &y, src_state);
7884
                        buttons[ibuttons]->setTextJustification(j, x, y, btState);
7885
                    break;
7886
 
7887
                    case 12: MSG_INFO("\"Lines of video removed\" not supported!"); break;
7888
                    case 13: buttons[ibuttons]->setOpacity(src_buttons[0]->getOpacity(src_state), btState); break;
7889
                    case 14: buttons[ibuttons]->setSound(src_buttons[0]->getSound(src_state), btState); break;
7890
                    case 15: buttons[ibuttons]->setText(src_buttons [0]->getText(src_state), btState); break;
7891
                    case 16: MSG_INFO("\"Video slot ID\" not supported!"); break;
7892
                    case 17: buttons[ibuttons]->setTextWordWrap(src_buttons[0]->getTextWordWrap(src_state), btState); break;
7893
                }
7894
            }
7895
 
7896
            idx++;
7897
        }
7898
    }
7899
}
7900
 
149 andreas 7901
void TPageManager::doBMF (int port, vector<int>& channels, vector<string>& pars)
7902
{
7903
    DECL_TRACER("TPageManager::doBMF (int port, vector<int>& channels, vector<string>& pars)");
7904
 
7905
    if (pars.size() < 2)
332 andreas 7906
    {
7907
        MSG_ERROR("Less then 2 parameters!");
7908
#if TESTMODE == 1
334 andreas 7909
        setAllDone();
332 andreas 7910
#endif
149 andreas 7911
        return;
332 andreas 7912
    }
149 andreas 7913
 
7914
    TError::clear();
7915
    int btState = atoi(pars[0].c_str()) - 1;
150 andreas 7916
    string commands;
149 andreas 7917
 
150 andreas 7918
    for (size_t i = 1; i < pars.size(); ++i)
7919
    {
7920
        if (i > 1)
7921
            commands += ",";
7922
 
7923
        commands += pars[i];
7924
    }
7925
 
193 andreas 7926
    vector<TMap::MAP_T> map = findButtons(port, channels);
149 andreas 7927
 
7928
    if (TError::isError() || map.empty())
332 andreas 7929
    {
7930
#if TESTMODE == 1
334 andreas 7931
        setAllDone();
332 andreas 7932
#endif
149 andreas 7933
        return;
332 andreas 7934
    }
149 andreas 7935
 
7936
    // Start of parsing the command line
162 andreas 7937
    // We splitt the command line into parts by searching for a percent (%) sign.
149 andreas 7938
    vector<string> parts = StrSplit(commands, "%");
7939
 
162 andreas 7940
    if (parts.empty())
332 andreas 7941
        parts.push_back(commands);
334 andreas 7942
 
149 andreas 7943
    // Search for all buttons who need to be updated
7944
    vector<Button::TButton *> buttons = collectButtons(map);
7945
 
7946
    if (buttons.size() > 0)
7947
    {
7948
        vector<Button::TButton *>::iterator mapIter;
7949
 
7950
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
7951
        {
7952
            Button::TButton *bt = *mapIter;
162 andreas 7953
 
7954
            if (!bt)
7955
            {
7956
                MSG_WARNING("Command ^BMF found an invalid pointer to a button!")
7957
                continue;
7958
            }
7959
 
149 andreas 7960
            // Iterate through commands and apply them to button
7961
            vector<string>::iterator iter;
7962
 
7963
            for (iter = parts.begin(); iter != parts.end(); ++iter)
7964
            {
7965
                char cmd = iter->at(0);
7966
                char cmd2;
7967
                string content;
7968
 
7969
                switch(cmd)
7970
                {
7971
                    case 'B':   // Border style
361 andreas 7972
                        if (iter->at(1) == ',')
7973
                            content = iter->substr(2);
7974
                        else
7975
                            content = iter->substr(1);
332 andreas 7976
 
7977
                        if (!content.empty() && isdigit(content[0]))
334 andreas 7978
                            bt->setBorderStyle(atoi(content.c_str()), btState);
332 andreas 7979
                        else
7980
                            bt->setBorderStyle(content, btState);
7981
#if TESTMODE == 1
7982
                        if (_gTestMode)
7983
                            _gTestMode->setResult(bt->getBorderStyle(btState < 0 ? 0 : btState));
7984
#endif
149 andreas 7985
                    break;
7986
 
7987
                    case 'C':   // Colors
7988
                        cmd2 = iter->at(1);
7989
                        content = iter->substr(2);
7990
 
7991
                        switch(cmd2)
7992
                        {
7993
                            case 'B':   // Border color
7994
                                bt->setBorderColor(content, btState);
332 andreas 7995
#if TESTMODE == 1
7996
                                if (_gTestMode)
7997
                                    _gTestMode->setResult(bt->getBorderColor(btState < 0 ? 0 : btState));
7998
#endif
149 andreas 7999
                            break;
8000
 
8001
                            case 'F':   // Fill color
8002
                                bt->setFillColor(content, btState);
332 andreas 8003
#if TESTMODE == 1
8004
                                if (_gTestMode)
8005
                                    _gTestMode->setResult(bt->getFillColor(btState < 0 ? 0 : btState));
8006
#endif
149 andreas 8007
                            break;
8008
 
8009
                            case 'T':   // Text color
8010
                                bt->setTextColor(content, btState);
332 andreas 8011
#if TESTMODE == 1
8012
                                if (_gTestMode)
8013
                                    _gTestMode->setResult(bt->getTextColor(btState < 0 ? 0 : btState));
8014
#endif
149 andreas 8015
                            break;
8016
                        }
8017
                    break;
8018
 
150 andreas 8019
                    case 'D':   // Draw order
8020
                        cmd2 = iter->at(1);
8021
                        content = iter->substr(2);
8022
 
8023
                        if (cmd2 == 'O')
332 andreas 8024
                        {
150 andreas 8025
                            bt->setDrawOrder(content, btState);
332 andreas 8026
#if TESTMODE == 1
8027
                            if (_gTestMode)
8028
                                _gTestMode->setResult(bt->getDrawOrder(btState < 0 ? 0 : btState));
8029
#endif
8030
                        }
150 andreas 8031
                    break;
8032
 
149 andreas 8033
                    case 'E':   // Text effect
8034
                        cmd2 = iter->at(1);
8035
                        content = iter->substr(2);
8036
 
8037
                        switch(cmd2)
8038
                        {
8039
                            case 'C':   // Text effect color
8040
                                bt->setTextEffectColor(content, btState);
332 andreas 8041
#if TESTMODE == 1
8042
                                if (_gTestMode)
8043
                                    _gTestMode->setResult(bt->getTextEffectColor(btState < 0 ? 0 : btState));
8044
#endif
149 andreas 8045
                            break;
8046
 
8047
                            case 'F':   // Text effect name
8048
                                bt->setTextEffectName(content, btState);
332 andreas 8049
#if TESTMODE == 1
8050
                                if (_gTestMode)
8051
                                    _gTestMode->setResult(bt->getTextEffectName(btState < 0 ? 0 : btState));
8052
#endif
149 andreas 8053
                            break;
8054
 
8055
                            case 'N':   // Enable/disable button
8056
                                bt->setEnable((content[0] == '1' ? true : false));
332 andreas 8057
#if TESTMODE == 1
8058
                                if (_gTestMode)
334 andreas 8059
                                {
332 andreas 8060
                                    _gTestMode->setResult(bt->isEnabled() ? "TRUE" : "FALSE");
334 andreas 8061
                                    __success = true;
8062
                                    setScreenDone();
8063
                                }
332 andreas 8064
#endif
149 andreas 8065
                            break;
8066
                        }
8067
                    break;
8068
 
8069
                    case 'F':   // Set font file name
361 andreas 8070
                        if (iter->at(1) == ',')
8071
                            content = iter->substr(2);
8072
                        else
8073
                            content = iter->substr(1);
150 andreas 8074
 
8075
                        if (!isdigit(content[0]))
334 andreas 8076
                            bt->setFontName(content, btState);
150 andreas 8077
                        else
8078
                            bt->setFontIndex(atoi(content.c_str()), btState);
334 andreas 8079
#if TESTMODE == 1
8080
                        if (_gTestMode)
8081
                            _gTestMode->setResult(intToString(bt->getFontIndex(btState < 0 ? 0 : btState)));
8082
#endif
149 andreas 8083
                    break;
8084
 
8085
                    case 'G':   // Bargraphs
8086
                        cmd2 = iter->at(1);
8087
                        content = iter->substr(2);
8088
 
8089
                        switch(cmd2)
8090
                        {
8091
                            case 'C':   // Bargraph slider color
8092
                                bt->setBargraphSliderColor(content);
8093
                            break;
8094
 
8095
                            case 'D':   // Ramp down time
387 andreas 8096
                                bt->setBargraphRampDownTime(atoi(content.c_str()));
149 andreas 8097
                            break;
8098
 
8099
                            case 'G':   // Drag increment
387 andreas 8100
                                bt->setBargraphDragIncrement(atoi(content.c_str()));
149 andreas 8101
                            break;
8102
 
8103
                            case 'H':   // Upper limit
8104
                                bt->setBargraphUpperLimit(atoi(content.c_str()));
8105
                            break;
8106
 
8107
                            case 'I':   // Invert/noninvert
387 andreas 8108
                                if (bt->getButtonType() == BARGRAPH || bt->getButtonType() == MULTISTATE_BARGRAPH)
8109
                                    bt->setBargraphInvert(atoi(content.c_str()) > 0 ? true : false);
149 andreas 8110
                            break;
8111
 
8112
                            case 'L':   // Lower limit
8113
                                bt->setBargraphLowerLimit(atoi(content.c_str()));
8114
                            break;
8115
 
8116
                            case 'N':   // Slider name
361 andreas 8117
                                bt->setBargraphSliderName(content);
149 andreas 8118
                            break;
8119
 
8120
                            case 'R':   // Repeat interval
8121
                                // FIXME: Add function to set repeat interval
8122
                            break;
8123
 
8124
                            case 'U':   // Ramp up time
387 andreas 8125
                                bt->setBargraphRampUpTime(atoi(content.c_str()));
149 andreas 8126
                            break;
8127
 
8128
                            case 'V':   // Bargraph value
387 andreas 8129
                                bt->setBargraphLevel(atoi(content.c_str()));
149 andreas 8130
                            break;
8131
                        }
8132
                    break;
8133
 
152 andreas 8134
                    case 'I':   // Set the icon
8135
                        content = iter->substr(1);
8136
                        bt->setIcon(atoi(content.c_str()), btState);
332 andreas 8137
#if TESTMODE == 1
8138
                        if (_gTestMode)
8139
                            _gTestMode->setResult(intToString(bt->getIconIndex()));
8140
#endif
152 andreas 8141
                    break;
8142
 
149 andreas 8143
                    case 'J':   // Set text justification
150 andreas 8144
                        cmd2 = iter->at(1);
8145
 
361 andreas 8146
                        if (cmd2 == ',')
150 andreas 8147
                        {
8148
                            content = iter->substr(1);
152 andreas 8149
                            int just = atoi(content.c_str());
8150
                            int x = 0, y = 0;
8151
 
8152
                            if (just == 0)
8153
                            {
8154
                                vector<string> coords = StrSplit(content, ",");
8155
 
8156
                                if (coords.size() >= 3)
8157
                                {
8158
                                    x = atoi(coords[1].c_str());
8159
                                    y = atoi(coords[2].c_str());
8160
                                }
8161
                            }
8162
 
8163
                            bt->setTextJustification(atoi(content.c_str()), x, y, btState);
334 andreas 8164
#if TESTMODE == 1
8165
                            if (_gTestMode)
8166
                            {
8167
                                just = bt->getTextJustification(&x, &y, btState < 0 ? 0 : btState);
8168
                                string s = intToString(just) + "," + intToString(x) + "," + intToString(y);
8169
                                _gTestMode->setResult(s);
8170
                            }
8171
#endif
150 andreas 8172
                        }
361 andreas 8173
                        else if (cmd2 == 'T' || cmd2 == 'B' || cmd2 == 'I')
150 andreas 8174
                        {
8175
                            content = iter->substr(2);
152 andreas 8176
                            int x = 0, y = 0;
8177
                            int just = atoi(content.c_str());
150 andreas 8178
 
152 andreas 8179
                            if (just == 0)
8180
                            {
8181
                                vector<string> coords = StrSplit(content, ",");
8182
 
8183
                                if (coords.size() >= 3)
8184
                                {
8185
                                    x = atoi(coords[1].c_str());
8186
                                    y = atoi(coords[2].c_str());
8187
                                }
8188
                            }
8189
 
150 andreas 8190
                            switch(cmd2)
8191
                            {
8192
                                case 'B':   // Alignment of bitmap
152 andreas 8193
                                    bt->setBitmapJustification(atoi(content.c_str()), x, y, btState);
334 andreas 8194
#if TESTMODE == 1
8195
                                    just = bt->getBitmapJustification(&x, &y, btState < 0 ? 0 : btState);
8196
#endif
150 andreas 8197
                                break;
8198
 
8199
                                case 'I':   // Alignment of icon
152 andreas 8200
                                    bt->setIconJustification(atoi(content.c_str()), x, y, btState);
334 andreas 8201
#if TESTMODE == 1
8202
                                    just = bt->getIconJustification(&x, &y, btState < 0 ? 0 : btState);
8203
#endif
150 andreas 8204
                                break;
8205
 
8206
                                case 'T':   // Alignment of text
152 andreas 8207
                                    bt->setTextJustification(atoi(content.c_str()), x, y, btState);
334 andreas 8208
#if TESTMODE == 1
8209
                                    just = bt->getTextJustification(&x, &y, btState < 0 ? 0 : btState);
8210
#endif
150 andreas 8211
                                break;
8212
                            }
334 andreas 8213
#if TESTMODE == 1
8214
                            if (_gTestMode)
8215
                            {
8216
                                string s = intToString(just) + "," + intToString(x) + "," + intToString(y);
8217
                                _gTestMode->setResult(s);
8218
                            }
8219
#endif
150 andreas 8220
                        }
8221
                    break;
8222
 
8223
                    case 'M':   // Text area
8224
                        cmd2 = iter->at(1);
8225
                        content = iter->substr(2);
8226
 
8227
                        switch(cmd2)
8228
                        {
152 andreas 8229
                            case 'I':   // Set mask image
8230
                                // FIXME: Add code for image mask
8231
                            break;
8232
 
150 andreas 8233
                            case 'K':   // Input mask of text area
8234
                                // FIXME: Add input mask
8235
                            break;
8236
 
8237
                            case 'L':   // Maximum length of text area
8238
                                // FIXME: Add code to set maximum length
8239
                            break;
8240
                        }
8241
                    break;
8242
 
8243
                    case 'O':   // Set feedback typ, opacity
8244
                        cmd2 = iter->at(1);
8245
 
8246
                        switch(cmd2)
8247
                        {
8248
                            case 'P':   // Set opacity
8249
                                bt->setOpacity(atoi(iter->substr(2).c_str()), btState);
8250
                            break;
8251
 
8252
                            case 'T':   // Set feedback type
8253
                                content = iter->substr(2);
8254
                                content = toUpper(content);
8255
 
8256
                                if (content == "NONE")
8257
                                    bt->setFeedback(Button::FB_NONE);
8258
                                else if (content == "CHANNEL")
8259
                                    bt->setFeedback(Button::FB_CHANNEL);
8260
                                else if (content == "INVERT")
8261
                                    bt->setFeedback(Button::FB_INV_CHANNEL);
8262
                                else if (content == "ON")
8263
                                    bt->setFeedback(Button::FB_ALWAYS_ON);
8264
                                else if (content == "MOMENTARY")
8265
                                    bt->setFeedback(Button::FB_MOMENTARY);
8266
                                else if (content == "BLINK")
8267
                                    bt->setFeedback(Button::FB_BLINK);
8268
                                else
8269
                                {
8270
                                    MSG_WARNING("Unknown feedback type " << content);
8271
                                }
335 andreas 8272
#if TESTMODE == 1
8273
                                if (_gTestMode)
8274
                                    _gTestMode->setResult(intToString(bt->getFeedback()));
8275
#endif
150 andreas 8276
                            break;
8277
 
8278
                            default:
8279
                                content = iter->substr(1);
8280
                                // FIXME: Add code to set the feedback type
8281
                        }
8282
                    break;
8283
 
152 andreas 8284
                    case 'P':   // Set picture/bitmap file name
8285
                        content = iter->substr(1);
165 andreas 8286
 
8287
                        if (content.find(".") == string::npos)  // If the image has no extension ...
8288
                        {                                       // we must find the image in the map
8289
                            string iname = findImage(content);
8290
 
8291
                            if (!iname.empty())
8292
                                content = iname;
8293
                        }
8294
 
152 andreas 8295
                        bt->setBitmap(content, btState);
8296
                    break;
8297
 
8298
                    case 'R':   // Set rectangle
8299
                    {
8300
                        content = iter->substr(1);
8301
                        vector<string> corners = StrSplit(content, ",");
8302
 
8303
                        if (corners.size() > 0)
8304
                        {
8305
                            vector<string>::iterator itcorn;
8306
                            int pos = 0;
8307
                            int left, top, right, bottom;
8308
                            left = top = right = bottom = 0;
8309
 
8310
                            for (itcorn = corners.begin(); itcorn != corners.end(); ++itcorn)
8311
                            {
8312
                                switch(pos)
8313
                                {
8314
                                    case 0: left   = atoi(itcorn->c_str()); break;
8315
                                    case 1: top    = atoi(itcorn->c_str()); break;
8316
                                    case 2: right  = atoi(itcorn->c_str()); break;
8317
                                    case 3: bottom = atoi(itcorn->c_str()); break;
8318
                                }
8319
 
8320
                                pos++;
8321
                            }
8322
 
8323
                            if (pos >= 4)
334 andreas 8324
                            {
152 andreas 8325
                                bt->setRectangle(left, top, right, bottom);
334 andreas 8326
                                bt->refresh();
8327
                            }
152 andreas 8328
                        }
334 andreas 8329
#if TESTMODE == 1
8330
                        if (_gTestMode)
8331
                        {
8332
                            int left, top, width, height;
8333
                            bt->getRectangle(&left, &top, &height, &width);
8334
                            string res(intToString(left) + "," + intToString(top) + "," + intToString(width) + "," + intToString(height));
8335
                            _gTestMode->setResult(res);
8336
                        }
8337
#endif
152 andreas 8338
                    }
8339
                    break;
8340
 
150 andreas 8341
                    case 'S':   // show/hide, style, sound
8342
                        cmd2 = iter->at(1);
8343
                        content = iter->substr(2);
8344
 
8345
                        switch(cmd2)
8346
                        {
8347
                            case 'F':   // Set focus of text area button
8348
                                // FIXME: Add code to set the focus of text area button
8349
                            break;
8350
 
8351
                            case 'M':   // Submit text
169 andreas 8352
                                if (content.find("|"))  // To be replaced by LF (0x0a)?
8353
                                {
8354
                                    size_t pos = 0;
8355
 
8356
                                    while ((pos = content.find("|")) != string::npos)
8357
                                        content = content.replace(pos, 1, "\n");
8358
                                }
8359
 
150 andreas 8360
                                bt->setText(content, btState);
8361
                            break;
8362
 
8363
                            case 'O':   // Sound
8364
                                bt->setSound(content, btState);
335 andreas 8365
#if TESTMODE == 1
8366
                                if (_gTestMode)
8367
                                    _gTestMode->setResult(bt->getSound(btState < 0 ? 0 : btState));
8368
#endif
150 andreas 8369
                            break;
8370
 
8371
                            case 'T':   // Button style
8372
                                // FIXME: Add code to set the button style
8373
                            break;
8374
 
8375
                            case 'W':   // Show / hide button
8376
                                if (content[0] == '0')
334 andreas 8377
                                    bt->hide(true);
150 andreas 8378
                                else
8379
                                    bt->show();
334 andreas 8380
#if TESTMODE == 1
8381
                                if (_gTestMode)
8382
                                    _gTestMode->setResult(bt->isVisible() ? "TRUE" : "FALSE");
8383
#endif
150 andreas 8384
                            break;
8385
                        }
8386
                    break;
8387
 
152 andreas 8388
                    case 'T':   // Set text
8389
                        content = iter->substr(1);
169 andreas 8390
 
8391
                        if (content.find("|"))  // To be replaced by LF (0x0a)?
8392
                        {
8393
                            size_t pos = 0;
8394
 
8395
                            while ((pos = content.find("|")) != string::npos)
8396
                                content = content.replace(pos, 1, "\n");
8397
                        }
8398
 
152 andreas 8399
                        bt->setText(content, btState);
334 andreas 8400
#if TESTMODE == 1
8401
                        if (_gTestMode)
8402
                            _gTestMode->setResult(bt->getText(btState < 0 ? 0 : btState));
8403
#endif
152 andreas 8404
                    break;
8405
 
150 andreas 8406
                    case 'U':   // Set the unicode text
8407
                        if (iter->at(1) == 'N')
8408
                        {
8409
                            content = iter->substr(2);
152 andreas 8410
                            string byte, text;
8411
                            size_t pos = 0;
8412
 
8413
                            while (pos < content.length())
8414
                            {
8415
                                byte = content.substr(pos, 2);
8416
                                char ch = (char)strtol(byte.c_str(), NULL, 16);
8417
                                text += ch;
8418
                                pos += 2;
8419
                            }
8420
 
169 andreas 8421
                            if (text.find("|"))  // To be replaced by LF (0x0a)?
8422
                            {
8423
                                size_t pos = 0;
8424
 
8425
                                while ((pos = text.find("|")) != string::npos)
8426
                                    text = text.replace(pos, 1, "\n");
8427
                            }
8428
 
152 andreas 8429
                            bt->setText(text, btState);
150 andreas 8430
                        }
8431
                    break;
8432
 
8433
                    case 'V':   // Video on / off
8434
                        cmd2 = iter->at(1);
8435
                        // Controlling a computer remotely is not supported.
8436
                        if (cmd2 != 'L' && cmd2 != 'N' && cmd2 != 'P')
8437
                        {
8438
                            content = iter->substr(2);
8439
                            // FIXME: Add code to switch video on or off
8440
                        }
8441
                    break;
8442
 
8443
                    case 'W':   // Word wrap
152 andreas 8444
                        if (iter->at(1) == 'W')
8445
                        {
8446
                            content = iter->substr(2);
8447
                            bt->setTextWordWrap(content[0] == '1' ? true : false, btState);
8448
                        }
149 andreas 8449
                    break;
8450
                }
8451
            }
8452
        }
8453
    }
332 andreas 8454
#if TESTMODE == 1
334 andreas 8455
    setDone();
332 andreas 8456
#endif
149 andreas 8457
}
8458
 
14 andreas 8459
/**
110 andreas 8460
 * Set the maximum length of the text area button. If this value is set to
8461
 * zero (0), the text area has no max length. The maximum length available is
8462
 * 2000. This is only for a Text area input button and not for a Text area input
8463
 * masking button.
8464
 */
8465
void TPageManager::doBML(int port, vector<int>& channels, vector<string>& pars)
8466
{
8467
    DECL_TRACER("TPageManager::doBML(int port, vector<int>& channels, vector<string>& pars)");
8468
 
8469
    if (pars.size() < 1)
8470
    {
8471
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
8472
        return;
8473
    }
8474
 
8475
    TError::clear();
8476
    int maxLen = atoi(pars[0].c_str());
8477
 
8478
    if (maxLen < 0 || maxLen > 2000)
8479
    {
8480
        MSG_WARNING("Got illegal length of text area! [" << maxLen << "]");
8481
        return;
8482
    }
8483
 
193 andreas 8484
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 8485
 
8486
    if (TError::isError() || map.empty())
8487
        return;
8488
 
8489
    vector<Button::TButton *> buttons = collectButtons(map);
8490
 
8491
    if (buttons.size() > 0)
8492
    {
8493
        vector<Button::TButton *>::iterator mapIter;
8494
 
8495
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8496
        {
8497
            Button::TButton *bt = *mapIter;
8498
            bt->setTextMaxChars(maxLen);
8499
        }
8500
    }
8501
}
8502
 
8503
/**
60 andreas 8504
 * Assign a picture to those buttons with a defined address range.
8505
 */
8506
void TPageManager::doBMP(int port, vector<int>& channels, vector<string>& pars)
8507
{
8508
    DECL_TRACER("TPageManager::doBMP(int port, vector<int>& channels, vector<string>& pars)");
8509
 
8510
    if (pars.size() < 2)
8511
    {
8512
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
8513
        return;
8514
    }
8515
 
8516
    TError::clear();
8517
    int btState = atoi(pars[0].c_str());
8518
    string bitmap = pars[1];
104 andreas 8519
    // If this is a G5 command, we may have up to 2 additional parameters.
8520
    int slot = -1, justify = -1, jx = 0, jy = 0;
60 andreas 8521
 
104 andreas 8522
    if (pars.size() > 2)
8523
    {
8524
        slot = atoi(pars[2].c_str());
8525
 
8526
        if (pars.size() >= 4)
8527
        {
8528
            justify = atoi(pars[4].c_str());
8529
 
8530
            if (justify == 0)
8531
            {
8532
                if (pars.size() >= 5)
8533
                    jx = atoi(pars[5].c_str());
8534
 
8535
                if (pars.size() >= 6)
8536
                    jy = atoi(pars[6].c_str());
8537
            }
8538
        }
8539
    }
8540
 
193 andreas 8541
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 8542
 
8543
    if (TError::isError() || map.empty())
8544
        return;
8545
 
8546
    vector<Button::TButton *> buttons = collectButtons(map);
8547
 
83 andreas 8548
    if (buttons.size() > 0)
60 andreas 8549
    {
83 andreas 8550
        vector<Button::TButton *>::iterator mapIter;
60 andreas 8551
 
83 andreas 8552
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 8553
        {
83 andreas 8554
            Button::TButton *bt = *mapIter;
252 andreas 8555
//            setButtonCallbacks(bt);
60 andreas 8556
 
83 andreas 8557
            if (btState == 0)       // All instances?
8558
            {
8559
                int bst = bt->getNumberInstances();
96 andreas 8560
                MSG_DEBUG("Setting bitmap " << bitmap << " on all " << bst << " instances...");
83 andreas 8561
 
8562
                for (int i = 0; i < bst; i++)
104 andreas 8563
                {
8564
                    if (justify >= 0)
8565
                    {
8566
                        if (slot == 2)
8567
                            bt->setIconJustification(justify, jx, jy, i);
8568
                        else
106 andreas 8569
                            bt->setBitmapJustification(justify, jx, jy, i);
104 andreas 8570
                    }
8571
 
8572
                    if (slot >= 0)
8573
                    {
8574
                        switch(slot)
8575
                        {
8576
                            case 0: bt->setCameleon(bitmap, i); break;
8577
                            case 2: bt->setIcon(bitmap, i); break;  // On G4 we have no bitmap layer. Therefor we use layer 2 as icon layer.
8578
                            default:
8579
                                bt->setBitmap(bitmap, i);
8580
                        }
8581
                    }
8582
                    else
8583
                        bt->setBitmap(bitmap, i);
8584
                }
83 andreas 8585
            }
8586
            else
104 andreas 8587
            {
8588
                if (justify >= 0)
8589
                {
8590
                    if (slot == 2)
8591
                        bt->setIconJustification(justify, jx, jy, btState);
8592
                    else
106 andreas 8593
                        bt->setBitmapJustification(justify, jx, jy, btState);
104 andreas 8594
                }
8595
 
8596
                if (slot >= 0)
8597
                {
8598
                    switch(slot)
8599
                    {
8600
                        case 0: bt->setCameleon(bitmap, btState); break;
8601
                        case 2: bt->setIcon(bitmap, btState); break;      // On G4 we have no bitmap layer. Therefor we use layer 2 as icon layer.
8602
                        default:
8603
                            bt->setBitmap(bitmap, btState);
8604
                    }
8605
                }
8606
                else
8607
                    bt->setBitmap(bitmap, btState);
8608
            }
60 andreas 8609
        }
8610
    }
8611
}
8612
 
82 andreas 8613
void TPageManager::getBMP(int port, vector<int> &channels, vector<string> &pars)
8614
{
8615
    DECL_TRACER("TPageManager::getBMP(int port, vector<int> &channels, vector<string> &pars)");
8616
 
8617
    if (pars.size() < 1)
8618
    {
8619
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
8620
        return;
8621
    }
8622
 
8623
    TError::clear();
8624
    int btState = atoi(pars[0].c_str());
8625
    string bmp;
8626
 
193 andreas 8627
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 8628
 
8629
    if (TError::isError() || map.empty())
8630
        return;
8631
 
8632
    vector<Button::TButton *> buttons = collectButtons(map);
8633
 
83 andreas 8634
    if (buttons.size() > 0)
82 andreas 8635
    {
110 andreas 8636
        Button::TButton *bt = buttons[0];
82 andreas 8637
 
110 andreas 8638
        if (btState == 0)       // All instances?
82 andreas 8639
        {
110 andreas 8640
            int bst = bt->getNumberInstances();
82 andreas 8641
 
110 andreas 8642
            for (int i = 0; i < bst; i++)
82 andreas 8643
            {
110 andreas 8644
                bmp = bt->getBitmapName(i);
82 andreas 8645
 
110 andreas 8646
                if (bmp.empty())
8647
                    continue;
82 andreas 8648
 
300 andreas 8649
                sendCustomEvent(i + 1, (int)bmp.length(), 0, bmp, 1002, bt->getChannelPort(), bt->getChannelNumber());
83 andreas 8650
            }
82 andreas 8651
        }
110 andreas 8652
        else
8653
        {
8654
            bmp = bt->getTextColor(btState-1);
300 andreas 8655
            sendCustomEvent(btState, (int)bmp.length(), 0, bmp, 1002, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 8656
        }
82 andreas 8657
    }
8658
}
8659
 
60 andreas 8660
/**
16 andreas 8661
 * Set the button opacity. The button opacity can be specified as a decimal
8662
 * between 0 - 255, where zero (0) is invisible and 255 is opaque, or as a
8663
 * HEX code, as used in the color commands by preceding the HEX code with
8664
 * the # sign. In this case, #00 becomes invisible and #FF becomes opaque.
8665
 * If the opacity is set to zero (0), this does not make the button inactive,
8666
 * only invisible.
8667
 */
8668
void TPageManager::doBOP(int port, vector<int>& channels, vector<string>& pars)
8669
{
8670
    DECL_TRACER("TPageManager::doBOP(int port, vector<int>& channels, vector<string>& pars)");
8671
 
8672
    if (pars.size() < 2)
8673
    {
8674
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
335 andreas 8675
#if TESTMODE == 1
8676
        setAllDone();
8677
#endif
16 andreas 8678
        return;
8679
    }
8680
 
8681
    TError::clear();
335 andreas 8682
    int btState = atoi(pars[0].c_str()) - 1;
16 andreas 8683
    int btOpacity = 0;
8684
 
8685
    if (pars[1].at(0) == '#')
8686
        btOpacity = (int)strtol(pars[1].substr(1).c_str(), NULL, 16);
8687
    else
8688
        btOpacity = atoi(pars[1].c_str());
8689
 
193 andreas 8690
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8691
 
8692
    if (TError::isError() || map.empty())
335 andreas 8693
    {
8694
#if TESTMODE == 1
8695
        setAllDone();
8696
#endif
16 andreas 8697
        return;
335 andreas 8698
    }
16 andreas 8699
 
8700
    vector<Button::TButton *> buttons = collectButtons(map);
8701
 
83 andreas 8702
    if (buttons.size() > 0)
16 andreas 8703
    {
83 andreas 8704
        vector<Button::TButton *>::iterator mapIter;
16 andreas 8705
 
83 andreas 8706
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
16 andreas 8707
        {
83 andreas 8708
            Button::TButton *bt = *mapIter;
335 andreas 8709
            bt->setOpacity(btOpacity, btState);
8710
#if TESTMODE == 1
8711
            if (_gTestMode)
8712
                _gTestMode->setResult(intToString(bt->getOpacity(btState < 0 ? 0 : btState)));
342 andreas 8713
#endif
16 andreas 8714
        }
8715
    }
335 andreas 8716
#if TESTMODE == 1
8717
    setDone();
8718
#endif
16 andreas 8719
}
8720
 
106 andreas 8721
void TPageManager::getBOP(int port, vector<int>& channels, vector<string>& pars)
8722
{
8723
    DECL_TRACER("TPageManager::getBOP(int port, vector<int>& channels, vector<string>& pars)");
8724
 
8725
    if (pars.size() < 1)
8726
    {
8727
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
8728
        return;
8729
    }
8730
 
8731
    TError::clear();
8732
    int btState = atoi(pars[0].c_str());
8733
 
193 andreas 8734
    vector<TMap::MAP_T> map = findButtons(port, channels);
106 andreas 8735
 
8736
    if (TError::isError() || map.empty())
8737
        return;
8738
 
8739
    vector<Button::TButton *> buttons = collectButtons(map);
8740
 
8741
    if (buttons.size() > 0)
8742
    {
110 andreas 8743
        Button::TButton *bt = buttons[0];
106 andreas 8744
 
110 andreas 8745
        if (btState == 0)       // All instances?
106 andreas 8746
        {
110 andreas 8747
            int bst = bt->getNumberInstances();
106 andreas 8748
 
110 andreas 8749
            for (int i = 0; i < bst; i++)
106 andreas 8750
            {
110 andreas 8751
                int oo = bt->getOpacity(i);
8752
                sendCustomEvent(i + 1, oo, 0, "", 1015, bt->getChannelPort(), bt->getChannelNumber());
106 andreas 8753
            }
8754
        }
110 andreas 8755
        else
8756
        {
8757
            int oo = bt->getOpacity(btState-1);
8758
            sendCustomEvent(btState, oo, 0, "", 1015, bt->getChannelPort(), bt->getChannelNumber());
8759
        }
106 andreas 8760
    }
8761
}
8762
 
60 andreas 8763
void TPageManager::doBOR(int port, vector<int>& channels, vector<string>& pars)
8764
{
8765
    DECL_TRACER("TPageManager::doBOR(int port, vector<int>& channels, vector<string>& pars)");
8766
 
8767
    if (pars.size() < 1)
8768
    {
8769
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
335 andreas 8770
#if TESTMODE == 1
8771
        setAllDone();
8772
#endif
60 andreas 8773
        return;
8774
    }
8775
 
8776
    TError::clear();
8777
    // Numbers of styles from 0 to 41
8778
    string bor = pars[0];
8779
    string border = "None";
8780
    int ibor = -1;
336 andreas 8781
    Border::TIntBorder borders;
60 andreas 8782
 
8783
    if (bor.at(0) >= '0' && bor.at(0) <= '9')
336 andreas 8784
    {
60 andreas 8785
        ibor = atoi(bor.c_str());
8786
 
336 andreas 8787
        if (ibor >= 0 && ibor <= 41)
8788
            border = borders.getTP4BorderName(ibor);
8789
        else
60 andreas 8790
        {
336 andreas 8791
            MSG_WARNING("Invalid border style ID " << ibor);
8792
#if TESTMODE == 1
8793
            setAllDone();
8794
#endif
8795
            return;
8796
        }
60 andreas 8797
 
336 andreas 8798
        MSG_DEBUG("Id " << ibor << " is border " << border);
60 andreas 8799
    }
336 andreas 8800
    else
60 andreas 8801
    {
336 andreas 8802
        if (!borders.isTP4BorderValid(bor))
8803
        {
8804
            MSG_WARNING("Unknown border style " << bor);
335 andreas 8805
#if TESTMODE == 1
336 andreas 8806
            setAllDone();
335 andreas 8807
#endif
336 andreas 8808
            return;
8809
        }
60 andreas 8810
 
336 andreas 8811
        border = bor;
60 andreas 8812
    }
8813
 
193 andreas 8814
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 8815
 
8816
    if (TError::isError() || map.empty())
335 andreas 8817
    {
8818
#if TESTMODE == 1
8819
        setAllDone();
8820
#endif
60 andreas 8821
        return;
335 andreas 8822
    }
60 andreas 8823
 
8824
    vector<Button::TButton *> buttons = collectButtons(map);
8825
 
83 andreas 8826
    if (buttons.size() > 0)
60 andreas 8827
    {
83 andreas 8828
        vector<Button::TButton *>::iterator mapIter;
8829
 
8830
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8831
        {
8832
            Button::TButton *bt = *mapIter;
8833
            bt->setBorderStyle(border);
335 andreas 8834
#if TESTMODE == 1
8835
            if (_gTestMode)
8836
                _gTestMode->setResult(bt->getBorderStyle(0));
8837
#endif
83 andreas 8838
        }
60 andreas 8839
    }
335 andreas 8840
#if TESTMODE == 1
8841
    setDone();
8842
#endif
60 andreas 8843
}
8844
 
107 andreas 8845
void TPageManager::doBOS(int port, vector<int>& channels, vector<string>& pars)
8846
{
8847
    DECL_TRACER("TPageManager::doBOS(int port, vector<int>& channels, vector<string>& pars)");
8848
 
8849
    if (pars.size() < 2)
8850
    {
8851
        MSG_ERROR("Expecting at least 2 parameters but got " << pars.size() << "! Ignoring command.");
8852
        return;
8853
    }
8854
 
8855
    TError::clear();
8856
    int btState = atoi(pars[0].c_str());
8857
    int videoState = atoi(pars[1].c_str());
8858
 
193 andreas 8859
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 8860
 
8861
    if (TError::isError() || map.empty())
8862
        return;
8863
 
8864
    vector<Button::TButton *> buttons = collectButtons(map);
8865
 
8866
    if (buttons.size() > 0)
8867
    {
8868
        vector<Button::TButton *>::iterator mapIter;
8869
 
8870
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8871
        {
8872
            Button::TButton *bt = *mapIter;
8873
 
8874
            if (btState == 0)       // All instances?
8875
                bt->setDynamic(videoState);
8876
            else
8877
                bt->setDynamic(videoState, btState-1);
8878
        }
8879
    }
8880
}
8881
 
16 andreas 8882
/**
60 andreas 8883
 * Set the border of a button state/states.
8884
 * The border names are available through the TPDesign4 border-name drop-down
8885
 * list.
8886
 */
8887
void TPageManager::doBRD(int port, vector<int>& channels, vector<string>& pars)
8888
{
8889
    DECL_TRACER("TPageManager::doBRD(int port, vector<int>& channels, vector<string>& pars)");
8890
 
8891
    if (pars.size() < 1)
8892
    {
8893
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8894
        return;
8895
    }
8896
 
8897
    TError::clear();
8898
    int btState = atoi(pars[0].c_str());
8899
    string border = "None";
8900
 
8901
    if (pars.size() > 1)
8902
        border = pars[1];
8903
 
193 andreas 8904
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 8905
 
8906
    if (TError::isError() || map.empty())
8907
        return;
8908
 
8909
    vector<Button::TButton *> buttons = collectButtons(map);
8910
 
83 andreas 8911
    if (buttons.size() > 0)
60 andreas 8912
    {
83 andreas 8913
        vector<Button::TButton *>::iterator mapIter;
60 andreas 8914
 
83 andreas 8915
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 8916
        {
83 andreas 8917
            Button::TButton *bt = *mapIter;
252 andreas 8918
//            setButtonCallbacks(bt);
60 andreas 8919
 
83 andreas 8920
            if (btState == 0)       // All instances?
8921
            {
8922
                int bst = bt->getNumberInstances();
8923
 
8924
                for (int i = 0; i < bst; i++)
106 andreas 8925
                    bt->setBorderStyle(border, i+1);
83 andreas 8926
            }
8927
            else
106 andreas 8928
                bt->setBorderStyle(border, btState);
60 andreas 8929
        }
8930
    }
8931
}
8932
 
107 andreas 8933
void TPageManager::getBRD(int port, vector<int>& channels, vector<string>& pars)
8934
{
8935
    DECL_TRACER("TPageManager::getBRD(int port, vector<int>& channels, vector<string>& pars)");
8936
 
8937
    if (pars.size() < 1)
8938
    {
8939
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8940
        return;
8941
    }
8942
 
8943
    TError::clear();
8944
    int btState = atoi(pars[0].c_str());
8945
 
193 andreas 8946
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 8947
 
8948
    if (TError::isError() || map.empty())
8949
        return;
8950
 
8951
    vector<Button::TButton *> buttons = collectButtons(map);
8952
 
8953
    if (buttons.size() > 0)
8954
    {
110 andreas 8955
        Button::TButton *bt = buttons[0];
107 andreas 8956
 
110 andreas 8957
        if (btState == 0)       // All instances?
107 andreas 8958
        {
110 andreas 8959
            int bst = bt->getNumberInstances();
107 andreas 8960
 
110 andreas 8961
            for (int i = 0; i < bst; i++)
107 andreas 8962
            {
110 andreas 8963
                string bname = bt->getBorderStyle(i);
300 andreas 8964
                sendCustomEvent(i + 1, (int)bname.length(), 0, bname, 1014, bt->getChannelPort(), bt->getChannelNumber());
107 andreas 8965
            }
8966
        }
110 andreas 8967
        else
8968
        {
8969
            string bname = bt->getBorderStyle(btState-1);
300 andreas 8970
            sendCustomEvent(btState, (int)bname.length(), 0, bname, 1014, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 8971
        }
107 andreas 8972
    }
8973
}
8974
 
60 andreas 8975
/**
16 andreas 8976
 * Set the button size and its position on the page.
8977
 */
8978
void TPageManager::doBSP(int port, vector<int>& channels, vector<string>& pars)
8979
{
8980
    DECL_TRACER("TPageManager::doBSP(int port, vector<int>& channels, vector<string>& pars)");
8981
 
8982
    if (pars.size() < 1)
8983
    {
8984
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
341 andreas 8985
#if TESTMODE == 1
8986
        setAllDone();
8987
#endif
16 andreas 8988
        return;
8989
    }
8990
 
8991
    TError::clear();
8992
    bool bLeft = false, bTop = false, bRight = false, bBottom = false;
8993
    int x, y;
8994
 
83 andreas 8995
    if (pars.size() > 0)
16 andreas 8996
    {
83 andreas 8997
        vector<string>::iterator iter;
8998
 
8999
        for (iter = pars.begin(); iter != pars.end(); iter++)
9000
        {
9001
            if (iter->compare("left") == 0)
9002
                bLeft = true;
9003
            else if (iter->compare("top") == 0)
9004
                bTop = true;
9005
            else if (iter->compare("right") == 0)
9006
                bRight = true;
9007
            else if (iter->compare("bottom") == 0)
9008
                bBottom = true;
9009
        }
16 andreas 9010
    }
9011
 
193 andreas 9012
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 9013
 
9014
    if (TError::isError() || map.empty())
9015
        return;
9016
 
9017
    vector<Button::TButton *> buttons = collectButtons(map);
409 andreas 9018
    x = y = 0;
16 andreas 9019
 
83 andreas 9020
    if (buttons.size() > 0)
16 andreas 9021
    {
83 andreas 9022
        vector<Button::TButton *>::iterator mapIter;
16 andreas 9023
 
83 andreas 9024
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9025
        {
9026
            Button::TButton *bt = *mapIter;
16 andreas 9027
 
83 andreas 9028
            if (bLeft)
9029
                x = 0;
16 andreas 9030
 
83 andreas 9031
            if (bTop)
9032
                y = 0;
16 andreas 9033
 
341 andreas 9034
            if (bRight || bBottom)
16 andreas 9035
            {
83 andreas 9036
                ulong handle = bt->getHandle();
9037
                int parentID = (handle >> 16) & 0x0000ffff;
9038
                int pwidth = 0;
341 andreas 9039
                int pheight = 0;
16 andreas 9040
 
83 andreas 9041
                if (parentID < 500)
16 andreas 9042
                {
83 andreas 9043
                    TPage *pg = getPage(parentID);
9044
 
9045
                    if (!pg)
9046
                    {
9047
                        MSG_ERROR("Internal error: Page " << parentID << " not found!");
9048
                        return;
9049
                    }
9050
 
9051
                    pwidth = pg->getWidth();
341 andreas 9052
                    pheight = pg->getHeight();
16 andreas 9053
                }
83 andreas 9054
                else
9055
                {
9056
                    TSubPage *spg = getSubPage(parentID);
16 andreas 9057
 
83 andreas 9058
                    if (!spg)
9059
                    {
9060
                        MSG_ERROR("Internal error: Subpage " << parentID << " not found!");
9061
                        return;
9062
                    }
16 andreas 9063
 
83 andreas 9064
                    pwidth = spg->getWidth();
341 andreas 9065
                    pheight = spg->getHeight();
16 andreas 9066
                }
9067
 
341 andreas 9068
                if (bRight)
9069
                    x = pwidth - bt->getWidth();
9070
 
9071
                if (bBottom)
9072
                    y = pheight - bt->getHeight();
16 andreas 9073
            }
9074
 
341 andreas 9075
            bt->setLeftTop(x, y);
9076
#if TESTMODE == 1
9077
            if (_gTestMode)
83 andreas 9078
            {
341 andreas 9079
                int left = bt->getLeftPosition();
9080
                int top = bt->getTopPosition();
9081
                string res = intToString(left) + "," + intToString(top);
9082
                _gTestMode->setResult(res);
16 andreas 9083
            }
341 andreas 9084
#endif
16 andreas 9085
        }
9086
    }
341 andreas 9087
#if TESTMODE == 1
9088
    setDone();
9089
#endif
16 andreas 9090
}
9091
 
9092
/**
107 andreas 9093
 * Submit text for text area buttons. This command causes the text areas to
9094
 * send their text as strings to the NetLinx Master.
9095
 */
9096
void TPageManager::doBSM(int port, vector<int>& channels, vector<string>&)
9097
{
9098
    DECL_TRACER("TPageManager::doBSM(int port, vector<int>& channels, vector<string>& pars)");
9099
 
9100
    TError::clear();
193 andreas 9101
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 9102
 
9103
    if (TError::isError() || map.empty())
341 andreas 9104
    {
9105
#if TESTMODE == 1
9106
        setAllDone();
9107
#endif
107 andreas 9108
        return;
341 andreas 9109
    }
107 andreas 9110
 
9111
    vector<Button::TButton *> buttons = collectButtons(map);
9112
 
9113
    if (buttons.size() > 0)
9114
    {
9115
        vector<Button::TButton *>::iterator mapIter;
9116
 
9117
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9118
        {
9119
            Button::TButton *bt = *mapIter;
9120
 
195 andreas 9121
            if (bt->getButtonType() != TEXT_INPUT && bt->getButtonType() != GENERAL)
341 andreas 9122
            {
9123
#if TESTMODE == 1
9124
                setAllDone();
9125
#endif
107 andreas 9126
                return;
341 andreas 9127
            }
107 andreas 9128
 
9129
            amx::ANET_SEND scmd;
9130
            scmd.port = bt->getChannelPort();
9131
            scmd.channel = bt->getChannelNumber();
9132
            scmd.ID = scmd.channel;
9133
            scmd.msg = bt->getText(0);
9134
            scmd.MC = 0x008b;       // string value
9135
 
9136
            if (gAmxNet)
9137
                gAmxNet->sendCommand(scmd);
9138
            else
9139
                MSG_WARNING("Missing global class TAmxNet. Can't send message!");
9140
 
9141
        }
9142
    }
9143
}
9144
 
9145
/**
9146
 * Set the sound played when a button is pressed. If the sound name is blank
9147
 * the sound is then cleared. If the sound name is not matched, the button
9148
 * sound is not changed.
9149
 */
9150
void TPageManager::doBSO(int port, vector<int>& channels, vector<string>& pars)
9151
{
9152
    DECL_TRACER("TPageManager::doBSO(int port, vector<int>& channels, vector<string>& pars)");
9153
 
9154
    if (pars.size() < 2)
9155
    {
9156
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
9157
        return;
9158
    }
9159
 
9160
    if (!gPrjResources)
9161
        return;
9162
 
9163
    TError::clear();
9164
    int btState = atoi(pars[0].c_str());
9165
    string sound = pars[1];
9166
 
9167
    if (!soundExist(sound))
9168
        return;
9169
 
193 andreas 9170
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 9171
 
9172
    if (TError::isError() || map.empty())
9173
        return;
9174
 
9175
    vector<Button::TButton *> buttons = collectButtons(map);
9176
 
9177
    if (buttons.size() > 0)
9178
    {
9179
        vector<Button::TButton *>::iterator mapIter;
9180
 
9181
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9182
        {
9183
            Button::TButton *bt = *mapIter;
9184
 
9185
            if (btState == 0)
9186
            {
9187
                int bst = bt->getNumberInstances();
9188
 
9189
                for (int i = 0; i < bst; i++)
9190
                    bt->setSound(sound, i);
9191
            }
9192
            else
9193
                bt->setSound(sound, btState-1);
9194
        }
9195
    }
9196
}
9197
 
9198
/**
16 andreas 9199
 * Set the button word wrap feature to those buttons with a defined address
9200
 * range. By default, word-wrap is Off.
9201
 */
9202
void TPageManager::doBWW(int port, vector<int>& channels, vector<string>& pars)
9203
{
9204
    DECL_TRACER("TPageManager::doBWW(int port, vector<int>& channels, vector<string>& pars)");
9205
 
9206
    if (pars.size() < 1)
9207
    {
9208
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9209
        return;
9210
    }
9211
 
9212
    TError::clear();
9213
    int btState = atoi(pars[0].c_str());
9214
 
193 andreas 9215
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 9216
 
9217
    if (TError::isError() || map.empty())
9218
        return;
9219
 
9220
    vector<Button::TButton *> buttons = collectButtons(map);
9221
 
83 andreas 9222
    if (buttons.size() > 0)
16 andreas 9223
    {
83 andreas 9224
        vector<Button::TButton *>::iterator mapIter;
16 andreas 9225
 
83 andreas 9226
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
16 andreas 9227
        {
83 andreas 9228
            Button::TButton *bt = *mapIter;
252 andreas 9229
//            setButtonCallbacks(bt);
16 andreas 9230
 
83 andreas 9231
            if (btState == 0)       // All instances?
9232
            {
9233
                int bst = bt->getNumberInstances();
9234
                MSG_DEBUG("Setting word wrap on all " << bst << " instances...");
9235
 
9236
                for (int i = 0; i < bst; i++)
110 andreas 9237
                    bt->setTextWordWrap(true, i);
83 andreas 9238
            }
9239
            else
110 andreas 9240
                bt->setTextWordWrap(true, btState - 1);
16 andreas 9241
        }
9242
    }
9243
}
9244
 
108 andreas 9245
void TPageManager::getBWW(int port, vector<int>& channels, vector<string>& pars)
9246
{
9247
    DECL_TRACER("TPageManager::getBWW(int port, vector<int>& channels, vector<string>& pars)");
9248
 
9249
    if (pars.size() < 1)
9250
    {
9251
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9252
        return;
9253
    }
9254
 
9255
    TError::clear();
9256
    int btState = atoi(pars[0].c_str());
9257
 
193 andreas 9258
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9259
 
9260
    if (TError::isError() || map.empty())
9261
        return;
9262
 
9263
    vector<Button::TButton *> buttons = collectButtons(map);
9264
 
9265
    if (buttons.size() > 0)
9266
    {
110 andreas 9267
        Button::TButton *bt = buttons[0];
108 andreas 9268
 
110 andreas 9269
        if (btState == 0)       // All instances?
108 andreas 9270
        {
110 andreas 9271
            int bst = bt->getNumberInstances();
108 andreas 9272
 
110 andreas 9273
            for (int i = 0; i < bst; i++)
9274
                sendCustomEvent(i + 1, bt->getTextWordWrap(i), 0, "", 1010, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9275
        }
110 andreas 9276
        else
9277
            sendCustomEvent(btState, bt->getTextWordWrap(btState-1), 0, "", 1010, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9278
    }
9279
}
9280
 
16 andreas 9281
/**
9282
 * Clear all page flips from a button.
9283
 */
22 andreas 9284
void TPageManager::doCPF(int port, vector<int>& channels, vector<string>&)
16 andreas 9285
{
9286
    DECL_TRACER("TPageManager::doCPF(int port, vector<int>& channels, vector<string>& pars)");
9287
 
9288
    TError::clear();
193 andreas 9289
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 9290
 
9291
    if (TError::isError() || map.empty())
9292
        return;
9293
 
9294
    vector<Button::TButton *> buttons = collectButtons(map);
9295
 
83 andreas 9296
    if (buttons.size() > 0)
16 andreas 9297
    {
83 andreas 9298
        vector<Button::TButton *>::iterator mapIter;
9299
 
9300
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9301
        {
9302
            Button::TButton *bt = *mapIter;
252 andreas 9303
//            setButtonCallbacks(bt);
83 andreas 9304
            bt->clearPushFunctions();
9305
        }
16 andreas 9306
    }
9307
}
9308
 
9309
/**
9310
 * Delete page flips from button if it already exists.
9311
 */
9312
void TPageManager::doDPF(int port, vector<int>& channels, vector<string>& pars)
9313
{
9314
    DECL_TRACER("TPageManager::doDPF(int port, vector<int>& channels, vector<string>& pars)");
9315
 
9316
    if (pars.size() < 1)
9317
    {
9318
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9319
        return;
9320
    }
9321
 
9322
    TError::clear();
9323
    string action = pars[0];
9324
    string pname;
9325
 
9326
    if (pars.size() >= 2)
9327
    {
9328
        pname = pars[1];
9329
        vector<Button::TButton *> list;
9330
        // First we search for a subpage because this is more likely
9331
        TSubPage *spg = getSubPage(pname);
9332
 
9333
        if (spg)
9334
            list = spg->getButtons(port, channels[0]);
9335
        else    // Then for a page
9336
        {
9337
            TPage *pg = getPage(pname);
9338
 
9339
            if (pg)
9340
                list = pg->getButtons(port, channels[0]);
9341
            else
9342
            {
9343
                MSG_WARNING("The name " << pname << " doesn't name either a page or a subpage!");
9344
                return;
9345
            }
9346
        }
9347
 
9348
        if (list.empty())
9349
            return;
9350
 
9351
        vector<Button::TButton *>::iterator it;
9352
 
9353
        for (it = list.begin(); it != list.end(); it++)
9354
        {
9355
            Button::TButton *bt = *it;
252 andreas 9356
//            setButtonCallbacks(bt);
16 andreas 9357
            bt->clearPushFunction(action);
9358
        }
9359
 
9360
        return;
9361
    }
9362
 
9363
    // Here we don't have a page name
193 andreas 9364
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 9365
 
9366
    if (TError::isError() || map.empty())
9367
        return;
9368
 
9369
    vector<Button::TButton *> buttons = collectButtons(map);
9370
 
83 andreas 9371
    if (buttons.size() > 0)
16 andreas 9372
    {
83 andreas 9373
        vector<Button::TButton *>::iterator mapIter;
9374
 
9375
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9376
        {
9377
            Button::TButton *bt = *mapIter;
252 andreas 9378
//            setButtonCallbacks(bt);
83 andreas 9379
            bt->clearPushFunction(action);
9380
        }
16 andreas 9381
    }
9382
}
9383
 
9384
/**
9385
 * Enable or disable buttons with a set variable text range.
9386
 */
9387
void TPageManager::doENA(int port, vector<int>& channels, vector<string>& pars)
9388
{
9389
    DECL_TRACER("TPageManager::doENA(int port, vector<int>& channels, vector<string>& pars)");
9390
 
9391
    if (pars.empty())
9392
    {
9393
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
341 andreas 9394
#if TESTMODE == 1
9395
        setAllDone();
9396
#endif
16 andreas 9397
        return;
9398
    }
9399
 
9400
    TError::clear();
9401
    int cvalue = atoi(pars[0].c_str());
9402
 
193 andreas 9403
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 9404
 
9405
    if (TError::isError() || map.empty())
341 andreas 9406
    {
9407
#if TESTMODE == 1
9408
        setAllDone();
9409
#endif
16 andreas 9410
        return;
341 andreas 9411
    }
16 andreas 9412
 
9413
    vector<Button::TButton *> buttons = collectButtons(map);
9414
 
83 andreas 9415
    if (buttons.size() > 0)
16 andreas 9416
    {
83 andreas 9417
        vector<Button::TButton *>::iterator mapIter;
9418
 
9419
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9420
        {
9421
            Button::TButton *bt = *mapIter;
9422
            bt->setEnable(((cvalue)?true:false));
341 andreas 9423
#if TESTMODE == 1
9424
            __success = true;
9425
 
9426
            if (_gTestMode)
9427
                _gTestMode->setResult(intToString(cvalue));
9428
#endif
83 andreas 9429
        }
16 andreas 9430
    }
341 andreas 9431
#if TESTMODE == 1
9432
    setAllDone();
9433
#endif
16 andreas 9434
}
9435
 
9436
/**
9437
 * Set a font to a specific Font ID value for those buttons with a defined
9438
 * address range. Font ID numbers are generated by the TPDesign4 programmers
9439
 * report.
9440
 */
9441
void TPageManager::doFON(int port, vector<int>& channels, vector<string>& pars)
9442
{
9443
    DECL_TRACER("TPageManager::doFON(int port, vector<int>& channels, vector<string>& pars)");
9444
 
9445
    if (pars.size() < 2)
9446
    {
9447
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
342 andreas 9448
#if TESTMODE == 1
9449
        setAllDone();
9450
#endif
16 andreas 9451
        return;
9452
    }
9453
 
9454
    TError::clear();
342 andreas 9455
    int btState = atoi(pars[0].c_str()) - 1;
16 andreas 9456
    int fvalue = atoi(pars[1].c_str());
9457
 
193 andreas 9458
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 9459
 
9460
    if (TError::isError() || map.empty())
9461
        return;
9462
 
9463
    vector<Button::TButton *> buttons = collectButtons(map);
9464
 
83 andreas 9465
    if (buttons.size() > 0)
16 andreas 9466
    {
83 andreas 9467
        vector<Button::TButton *>::iterator mapIter;
16 andreas 9468
 
83 andreas 9469
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
16 andreas 9470
        {
83 andreas 9471
            Button::TButton *bt = *mapIter;
342 andreas 9472
            bt->setFont(fvalue, btState);
9473
#if TESTMODE == 1
9474
            if (_gTestMode)
9475
                _gTestMode->setResult(intToString(bt->getFontIndex(btState < 0 ? 0 : btState)));
9476
#endif
16 andreas 9477
        }
9478
    }
342 andreas 9479
#if TESTMODE == 1
9480
    setDone();
9481
#endif
16 andreas 9482
}
9483
 
108 andreas 9484
void TPageManager::getFON(int port, vector<int>& channels, vector<string>& pars)
9485
{
9486
    DECL_TRACER("TPageManager::getFON(int port, vector<int>& channels, vector<string>& pars)");
9487
 
9488
    if (pars.size() < 1)
9489
    {
9490
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
342 andreas 9491
#if TESTMODE == 1
9492
        setAllDone();
9493
#endif
108 andreas 9494
        return;
9495
    }
9496
 
9497
    TError::clear();
9498
    int btState = atoi(pars[0].c_str());
9499
 
193 andreas 9500
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9501
 
9502
    if (TError::isError() || map.empty())
342 andreas 9503
    {
9504
#if TESTMODE == 1
9505
        setAllDone();
9506
#endif
108 andreas 9507
        return;
342 andreas 9508
    }
108 andreas 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->getFontIndex(i), 0, "", 1007, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9522
        }
110 andreas 9523
        else
9524
            sendCustomEvent(btState, bt->getFontIndex(btState - 1), 0, "", 1007, bt->getChannelPort(), bt->getChannelNumber());
342 andreas 9525
#if TESTMODE == 1
9526
        if (_gTestMode)
9527
            _gTestMode->setResult(intToString(bt->getFontIndex(btState < 0 ? 0 : btState)));
9528
#endif
108 andreas 9529
    }
342 andreas 9530
#if TESTMODE == 1
9531
    __success = true;
9532
    setAllDone();
9533
#endif
108 andreas 9534
}
9535
 
388 andreas 9536
void TPageManager::doGDI(int port, vector<int>& channels, vector<std::string>& pars)
9537
{
9538
    DECL_TRACER("TPageManager::doGDI(int port, vector<int>& channels, vector<std::string>& pars)");
9539
 
9540
    if (pars.size() < 1)
9541
    {
9542
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9543
        return;
9544
    }
9545
 
9546
    TError::clear();
9547
    int inc = atoi(pars[0].c_str());
9548
 
9549
    if (inc < 0)
9550
    {
9551
        MSG_ERROR("Invalid drag increment of " << inc << "!");
9552
        return;
9553
    }
9554
 
9555
    vector<TMap::MAP_T> map = findButtons(port, channels);
9556
 
9557
    if (TError::isError() || map.empty())
9558
        return;
9559
 
9560
    vector<Button::TButton *> buttons = collectButtons(map);
9561
 
9562
    if (buttons.size() > 0)
9563
    {
9564
        vector<Button::TButton *>::iterator mapIter;
9565
 
9566
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9567
        {
9568
            Button::TButton *bt = *mapIter;
9569
            bt->setBargraphDragIncrement(inc);
9570
        }
9571
    }
9572
}
416 andreas 9573
/*
9574
 * Invert the joystick axis to move the origin to another corner.
9575
 */
9576
void TPageManager::doGIV(int port, vector<int>& channels, vector<std::string>& pars)
388 andreas 9577
{
416 andreas 9578
    DECL_TRACER("TPageManager::doGIV(int port, vector<int>& channels, vector<std::string>& pars)");
9579
 
9580
    if (pars.empty())
9581
        return;
9582
 
9583
    TError::clear();
9584
    int inv = atoi(pars[0].c_str());
9585
 
9586
    if (inv < 0 || inv > 3)
9587
    {
9588
        MSG_ERROR("Invalid invert type " << inv);
9589
        return;
9590
    }
9591
 
9592
    vector<TMap::MAP_T> map = findButtons(port, channels);
9593
 
9594
    if (TError::isError() || map.empty())
9595
        return;
9596
 
9597
    vector<Button::TButton *> buttons = collectButtons(map);
9598
 
9599
    if (buttons.size() > 0)
9600
    {
9601
        vector<Button::TButton *>::iterator mapIter;
9602
 
9603
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9604
        {
9605
            Button::TButton *bt = *mapIter;
9606
            bt->setBargraphInvert(inv);
9607
        }
9608
    }
388 andreas 9609
}
416 andreas 9610
 
16 andreas 9611
/**
60 andreas 9612
 * Change the bargraph upper limit.
9613
 */
9614
void TPageManager::doGLH(int port, vector<int>& channels, vector<std::string>& pars)
9615
{
9616
    DECL_TRACER("TPageManager::doGLH(int port, vector<int>& channels, vector<std::string>& pars)");
9617
 
9618
    if (pars.size() < 1)
9619
    {
9620
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9621
        return;
9622
    }
9623
 
9624
    TError::clear();
9625
    int limit = atoi(pars[0].c_str());
9626
 
9627
    if (limit < 1)
9628
    {
9629
        MSG_ERROR("Invalid upper limit " << limit << "!");
9630
        return;
9631
    }
9632
 
193 andreas 9633
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 9634
 
9635
    if (TError::isError() || map.empty())
9636
        return;
9637
 
9638
    vector<Button::TButton *> buttons = collectButtons(map);
9639
 
83 andreas 9640
    if (buttons.size() > 0)
60 andreas 9641
    {
83 andreas 9642
        vector<Button::TButton *>::iterator mapIter;
9643
 
9644
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9645
        {
9646
            Button::TButton *bt = *mapIter;
9647
            bt->setBargraphUpperLimit(limit);
9648
        }
60 andreas 9649
    }
9650
}
9651
 
9652
/**
9653
 * Change the bargraph lower limit.
9654
 */
9655
void TPageManager::doGLL(int port, vector<int>& channels, vector<std::string>& pars)
9656
{
9657
    DECL_TRACER("TPageManager::doGLL(int port, vector<int>& channels, vector<std::string>& pars)");
9658
 
9659
    if (pars.size() < 1)
9660
    {
9661
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9662
        return;
9663
    }
9664
 
9665
    TError::clear();
9666
    int limit = atoi(pars[0].c_str());
9667
 
9668
    if (limit < 1)
9669
    {
9670
        MSG_ERROR("Invalid lower limit " << limit << "!");
9671
        return;
9672
    }
9673
 
193 andreas 9674
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 9675
 
9676
    if (TError::isError() || map.empty())
9677
        return;
9678
 
9679
    vector<Button::TButton *> buttons = collectButtons(map);
9680
 
83 andreas 9681
    if (buttons.size() > 0)
60 andreas 9682
    {
83 andreas 9683
        vector<Button::TButton *>::iterator mapIter;
9684
 
9685
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9686
        {
9687
            Button::TButton *bt = *mapIter;
9688
            bt->setBargraphLowerLimit(limit);
9689
        }
60 andreas 9690
    }
9691
}
9692
 
416 andreas 9693
/*
9694
 * Change the bargraph slider color or joystick cursor color.
9695
 */
108 andreas 9696
void TPageManager::doGSC(int port, vector<int>& channels, vector<string>& pars)
9697
{
9698
    DECL_TRACER("TPageManager::doGSC(int port, vector<int>& channels, vector<string>& pars)");
9699
 
9700
    if (pars.size() < 1)
9701
    {
9702
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9703
        return;
9704
    }
9705
 
9706
    TError::clear();
9707
    string color = pars[0];
193 andreas 9708
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9709
 
9710
    if (TError::isError() || map.empty())
9711
        return;
9712
 
9713
    vector<Button::TButton *> buttons = collectButtons(map);
9714
 
9715
    if (buttons.size() > 0)
9716
    {
9717
        vector<Button::TButton *>::iterator mapIter;
9718
 
9719
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9720
        {
9721
            Button::TButton *bt = *mapIter;
9722
            bt->setBargraphSliderColor(color);
9723
        }
9724
    }
9725
}
9726
 
361 andreas 9727
/*
388 andreas 9728
 * Set bargraph ramp down time in 1/10 seconds.
9729
 */
9730
void TPageManager::doGRD(int port, vector<int>& channels, vector<string>& pars)
9731
{
9732
    DECL_TRACER("TPageManager::doGRD(int port, vector<int>& channels, vector<string>& pars)");
9733
 
9734
    if (pars.size() < 1)
9735
    {
9736
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9737
        return;
9738
    }
9739
 
9740
    TError::clear();
9741
    int t = atoi(pars[0].c_str());
9742
 
9743
    if (t < 0)
9744
    {
9745
        MSG_ERROR("Invalid ramp down time limit " << t << "!");
9746
        return;
9747
    }
9748
 
9749
    vector<TMap::MAP_T> map = findButtons(port, channels);
9750
 
9751
    if (TError::isError() || map.empty())
9752
        return;
9753
 
9754
    vector<Button::TButton *> buttons = collectButtons(map);
9755
 
9756
    if (buttons.size() > 0)
9757
    {
9758
        vector<Button::TButton *>::iterator mapIter;
9759
 
9760
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9761
        {
9762
            Button::TButton *bt = *mapIter;
9763
            bt->setBargraphRampDownTime(t);
9764
        }
9765
    }
9766
}
9767
 
9768
/*
9769
 * Set bargraph ramp up time in 1/10 seconds.
9770
 */
9771
void TPageManager::doGRU(int port, vector<int>& channels, vector<string>& pars)
9772
{
9773
    DECL_TRACER("TPageManager::doGRU(int port, vector<int>& channels, vector<string>& pars)");
9774
 
9775
    if (pars.size() < 1)
9776
    {
9777
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9778
        return;
9779
    }
9780
 
9781
    TError::clear();
9782
    int t = atoi(pars[0].c_str());
9783
 
9784
    if (t < 0)
9785
    {
9786
        MSG_ERROR("Invalid ramp up time limit " << t << "!");
9787
        return;
9788
    }
9789
 
9790
    vector<TMap::MAP_T> map = findButtons(port, channels);
9791
 
9792
    if (TError::isError() || map.empty())
9793
        return;
9794
 
9795
    vector<Button::TButton *> buttons = collectButtons(map);
9796
 
9797
    if (buttons.size() > 0)
9798
    {
9799
        vector<Button::TButton *>::iterator mapIter;
9800
 
9801
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9802
        {
9803
            Button::TButton *bt = *mapIter;
9804
            bt->setBargraphRampUpTime(t);
9805
        }
9806
    }
9807
}
9808
 
9809
/*
361 andreas 9810
 * Change the bargraph slider name or joystick cursor name.
9811
 */
9812
void TPageManager::doGSN(int port, vector<int>& channels, vector<string>& pars)
9813
{
9814
    DECL_TRACER("TPageManager::doGSN(int port, vector<int>& channels, vector<string>& pars)");
9815
 
9816
    if (pars.size() < 1)
9817
    {
9818
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9819
        return;
9820
    }
9821
 
9822
    TError::clear();
9823
    string name = pars[0];
9824
    vector<TMap::MAP_T> map = findButtons(port, channels);
9825
 
9826
    if (TError::isError() || map.empty())
9827
        return;
9828
 
9829
    vector<Button::TButton *> buttons = collectButtons(map);
9830
 
9831
    if (buttons.size() > 0)
9832
    {
9833
        vector<Button::TButton *>::iterator mapIter;
9834
 
9835
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9836
        {
9837
            Button::TButton *bt = *mapIter;
9838
            bt->setBargraphSliderName(name);
9839
        }
9840
    }
9841
}
9842
 
60 andreas 9843
/**
14 andreas 9844
 * Set the icon to a button.
9845
 */
9846
void TPageManager::doICO(int port, vector<int>& channels, vector<string>& pars)
9847
{
9848
    DECL_TRACER("TPageManager::doICO(int port, vector<int>& channels, vector<string>& pars)");
9849
 
9850
    if (pars.size() < 2)
9851
    {
9852
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
9853
        return;
9854
    }
9855
 
16 andreas 9856
    TError::clear();
14 andreas 9857
    int btState = atoi(pars[0].c_str());
9858
    int iconIdx = atoi(pars[1].c_str());
9859
 
193 andreas 9860
    vector<TMap::MAP_T> map = findButtons(port, channels);
14 andreas 9861
 
9862
    if (TError::isError() || map.empty())
9863
        return;
9864
 
9865
    vector<Button::TButton *> buttons = collectButtons(map);
9866
 
83 andreas 9867
    if (buttons.size() > 0)
14 andreas 9868
    {
83 andreas 9869
        vector<Button::TButton *>::iterator mapIter;
14 andreas 9870
 
83 andreas 9871
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
14 andreas 9872
        {
83 andreas 9873
            Button::TButton *bt = *mapIter;
14 andreas 9874
 
83 andreas 9875
            if (btState == 0)       // All instances?
14 andreas 9876
            {
316 andreas 9877
                if (iconIdx > 0)
9878
                    bt->setIcon(iconIdx, -1);
9879
                else
9880
                    bt->revokeIcon(-1);
14 andreas 9881
            }
83 andreas 9882
            else if (iconIdx > 0)
9883
                bt->setIcon(iconIdx, btState - 1);
9884
            else
9885
                bt->revokeIcon(btState - 1);
14 andreas 9886
        }
9887
    }
9888
}
9889
 
108 andreas 9890
void TPageManager::getICO(int port, vector<int>& channels, vector<string>& pars)
9891
{
9892
    DECL_TRACER("TPageManager::getICO(int port, vector<int>& channels, vector<string>& pars)");
9893
 
9894
    if (pars.size() < 1)
9895
    {
9896
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9897
        return;
9898
    }
9899
 
9900
    TError::clear();
9901
    int btState = atoi(pars[0].c_str());
9902
 
193 andreas 9903
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9904
 
9905
    if (TError::isError() || map.empty())
9906
        return;
9907
 
9908
    vector<Button::TButton *> buttons = collectButtons(map);
9909
 
9910
    if (buttons.size() > 0)
9911
    {
110 andreas 9912
        Button::TButton *bt = buttons[0];
108 andreas 9913
 
110 andreas 9914
        if (btState == 0)       // All instances?
108 andreas 9915
        {
110 andreas 9916
            int bst = bt->getNumberInstances();
108 andreas 9917
 
110 andreas 9918
            for (int i = 0; i < bst; i++)
9919
                sendCustomEvent(i + 1, bt->getIconIndex(i), 0, "", 1003, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9920
        }
110 andreas 9921
        else
9922
            sendCustomEvent(btState, bt->getIconIndex(btState - 1), 0, "", 1003, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9923
    }
9924
}
9925
 
14 andreas 9926
/**
108 andreas 9927
 * Set bitmap/picture alignment using a numeric keypad layout for those buttons
9928
 * with a defined address range. The alignment of 0 is followed by
9929
 * ',<left>,<top>'. The left and top coordinates are relative to the upper left
9930
 * corner of the button.
9931
 */
9932
void TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)
9933
{
9934
    DECL_TRACER("TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)");
9935
 
9936
    if (pars.size() < 2)
9937
    {
9938
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
9939
        return;
9940
    }
9941
 
9942
    TError::clear();
9943
    int btState = atoi(pars[0].c_str());
9944
    int align = atoi(pars[1].c_str());
9945
    int x = 0, y = 0;
9946
 
9947
    if (!align && pars.size() >= 3)
9948
    {
9949
        x = atoi(pars[2].c_str());
9950
 
9951
        if (pars.size() >= 4)
9952
            y = atoi(pars[3].c_str());
9953
    }
9954
 
193 andreas 9955
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9956
 
9957
    if (TError::isError() || map.empty())
9958
        return;
9959
 
9960
    vector<Button::TButton *> buttons = collectButtons(map);
9961
 
9962
    if (buttons.size() > 0)
9963
    {
9964
        vector<Button::TButton *>::iterator mapIter;
9965
 
9966
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9967
        {
9968
            Button::TButton *bt = *mapIter;
9969
 
9970
            if (btState == 0)
9971
                bt->setBitmapJustification(align, x, y, -1);
9972
            else
9973
                bt->setBitmapJustification(align, x, y, btState-1);
9974
        }
9975
    }
9976
}
9977
 
9978
void TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)
9979
{
9980
    DECL_TRACER("TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)");
9981
 
9982
    if (pars.size() < 1)
9983
    {
9984
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9985
        return;
9986
    }
9987
 
9988
    TError::clear();
9989
    int btState = atoi(pars[0].c_str());
9990
    int j, x, y;
9991
 
193 andreas 9992
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9993
 
9994
    if (TError::isError() || map.empty())
9995
        return;
9996
 
9997
    vector<Button::TButton *> buttons = collectButtons(map);
9998
 
9999
    if (buttons.size() > 0)
10000
    {
110 andreas 10001
        Button::TButton *bt = buttons[0];
108 andreas 10002
 
110 andreas 10003
        if (btState == 0)       // All instances?
108 andreas 10004
        {
110 andreas 10005
            int bst = bt->getNumberInstances();
108 andreas 10006
 
110 andreas 10007
            for (int i = 0; i < bst; i++)
108 andreas 10008
            {
110 andreas 10009
                j = bt->getBitmapJustification(&x, &y, i);
10010
                sendCustomEvent(i + 1, j, 0, "", 1005, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 10011
            }
10012
        }
110 andreas 10013
        else
10014
        {
10015
            j = bt->getBitmapJustification(&x, &y, btState-1);
10016
            sendCustomEvent(btState, j, 0, "", 1005, bt->getChannelPort(), bt->getChannelNumber());
10017
        }
108 andreas 10018
    }
10019
}
10020
 
10021
/**
10022
 * Set icon alignment using a numeric keypad layout for those buttons with a
10023
 * defined address range. The alignment of 0 is followed by ',<left>,<top>'.
10024
 * The left and top coordinates are relative to the upper left corner of the
10025
 * button.
10026
 */
10027
void TPageManager::doJSI(int port, vector<int>& channels, vector<string>& pars)
10028
{
10029
    DECL_TRACER("TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)");
10030
 
10031
    if (pars.size() < 2)
10032
    {
10033
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
10034
        return;
10035
    }
10036
 
10037
    TError::clear();
10038
    int btState = atoi(pars[0].c_str());
10039
    int align = atoi(pars[1].c_str());
10040
    int x = 0, y = 0;
10041
 
10042
    if (!align && pars.size() >= 3)
10043
    {
10044
        x = atoi(pars[2].c_str());
10045
 
10046
        if (pars.size() >= 4)
10047
            y = atoi(pars[3].c_str());
10048
    }
10049
 
193 andreas 10050
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 10051
 
10052
    if (TError::isError() || map.empty())
10053
        return;
10054
 
10055
    vector<Button::TButton *> buttons = collectButtons(map);
10056
 
10057
    if (buttons.size() > 0)
10058
    {
10059
        vector<Button::TButton *>::iterator mapIter;
10060
 
10061
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10062
        {
10063
            Button::TButton *bt = *mapIter;
10064
 
10065
            if (btState == 0)
10066
                bt->setIconJustification(align, x, y, -1);
10067
            else
10068
                bt->setIconJustification(align, x, y, btState-1);
10069
        }
10070
    }
10071
}
10072
 
10073
void TPageManager::getJSI(int port, vector<int>& channels, vector<string>& pars)
10074
{
10075
    DECL_TRACER("TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)");
10076
 
10077
    if (pars.size() < 1)
10078
    {
10079
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
10080
        return;
10081
    }
10082
 
10083
    TError::clear();
10084
    int btState = atoi(pars[0].c_str());
10085
    int j, x, y;
10086
 
193 andreas 10087
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 10088
 
10089
    if (TError::isError() || map.empty())
10090
        return;
10091
 
10092
    vector<Button::TButton *> buttons = collectButtons(map);
10093
 
10094
    if (buttons.size() > 0)
10095
    {
110 andreas 10096
        Button::TButton *bt = buttons[0];
108 andreas 10097
 
110 andreas 10098
        if (btState == 0)       // All instances?
108 andreas 10099
        {
110 andreas 10100
            int bst = bt->getNumberInstances();
108 andreas 10101
 
110 andreas 10102
            for (int i = 0; i < bst; i++)
108 andreas 10103
            {
110 andreas 10104
                j = bt->getIconJustification(&x, &y, i);
10105
                sendCustomEvent(i + 1, j, 0, "", 1006, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 10106
            }
10107
        }
110 andreas 10108
        else
10109
        {
10110
            j = bt->getIconJustification(&x, &y, btState-1);
10111
            sendCustomEvent(btState, j, 0, "", 1006, bt->getChannelPort(), bt->getChannelNumber());
10112
        }
108 andreas 10113
    }
10114
}
10115
 
10116
void TPageManager::doJST(int port, vector<int>& channels, vector<string>& pars)
10117
{
10118
    DECL_TRACER("TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)");
10119
 
10120
    if (pars.size() < 2)
10121
    {
10122
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
10123
        return;
10124
    }
10125
 
10126
    TError::clear();
10127
    int btState = atoi(pars[0].c_str());
10128
    int align = atoi(pars[1].c_str());
10129
    int x = 0, y = 0;
10130
 
10131
    if (!align && pars.size() >= 3)
10132
    {
10133
        x = atoi(pars[2].c_str());
10134
 
10135
        if (pars.size() >= 4)
10136
            y = atoi(pars[3].c_str());
10137
    }
10138
 
193 andreas 10139
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 10140
 
10141
    if (TError::isError() || map.empty())
10142
        return;
10143
 
10144
    vector<Button::TButton *> buttons = collectButtons(map);
10145
 
10146
    if (buttons.size() > 0)
10147
    {
10148
        vector<Button::TButton *>::iterator mapIter;
10149
 
10150
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10151
        {
10152
            Button::TButton *bt = *mapIter;
10153
 
10154
            if (btState == 0)
10155
                bt->setTextJustification(align, x, y, -1);
10156
            else
10157
                bt->setTextJustification(align, x, y, btState-1);
10158
        }
10159
    }
10160
}
10161
 
10162
void TPageManager::getJST(int port, vector<int>& channels, vector<string>& pars)
10163
{
10164
    DECL_TRACER("TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)");
10165
 
10166
    if (pars.size() < 1)
10167
    {
10168
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
10169
        return;
10170
    }
10171
 
10172
    TError::clear();
10173
    int btState = atoi(pars[0].c_str());
10174
    int j, x, y;
10175
 
193 andreas 10176
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 10177
 
10178
    if (TError::isError() || map.empty())
10179
        return;
10180
 
10181
    vector<Button::TButton *> buttons = collectButtons(map);
10182
 
10183
    if (buttons.size() > 0)
10184
    {
110 andreas 10185
        Button::TButton *bt = buttons[0];
108 andreas 10186
 
110 andreas 10187
        if (btState == 0)       // All instances?
108 andreas 10188
        {
110 andreas 10189
            int bst = bt->getNumberInstances();
108 andreas 10190
 
110 andreas 10191
            for (int i = 0; i < bst; i++)
108 andreas 10192
            {
110 andreas 10193
                j = bt->getTextJustification(&x, &y, i);
10194
                sendCustomEvent(i + 1, j, 0, "", 1004, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 10195
            }
10196
        }
110 andreas 10197
        else
10198
        {
10199
            j = bt->getTextJustification(&x, &y, btState-1);
10200
            sendCustomEvent(btState, j, 0, "", 1004, bt->getChannelPort(), bt->getChannelNumber());
10201
        }
108 andreas 10202
    }
10203
}
10204
 
10205
/**
395 andreas 10206
 * @brief TPageManager::getMSP
10207
 * Sets the speed of a marquee line. Allowed range is from 1 to 10, where 10 is
10208
 * the fastest speed.
10209
 *
10210
 * @param port      The port number
10211
 * @param channels  The channels
10212
 * @param pars      Parameters
10213
 */
10214
void TPageManager::doMSP(int port, vector<int>& channels, vector<string>& pars)
10215
{
10216
    DECL_TRACER("TPageManager::getMSP(int port, vector<int>& channels, vector<string>& pars)");
10217
 
10218
    if (pars.size() < 2)
10219
    {
10220
        MSG_ERROR("Expecting at least 2 parameter but got less! Command ignored.");
10221
        return;
10222
    }
10223
 
10224
    TError::clear();
10225
    int btState = atoi(pars[0].c_str()) - 1;
10226
    int speed = atoi(pars[1].c_str());
10227
 
10228
    if (speed < 1 || speed > 10)
10229
    {
10230
        MSG_ERROR("Speed for marquee line is out of range!");
10231
        return;
10232
    }
10233
 
10234
    vector<TMap::MAP_T> map = findButtons(port, channels);
10235
 
10236
    if (TError::isError() || map.empty())
10237
        return;
10238
 
10239
    vector<Button::TButton *> buttons = collectButtons(map);
10240
 
10241
    if (buttons.size() > 0)
10242
    {
10243
        vector<Button::TButton *>::iterator iter;
10244
 
10245
        for (iter = buttons.begin(); iter != buttons.end(); ++iter)
10246
        {
10247
            Button::TButton *bt = buttons[0];
10248
            bt->setMarqueeSpeed(speed, btState);
10249
        }
10250
    }
10251
}
10252
 
10253
/**
16 andreas 10254
 * Show or hide a button with a set variable text range.
10255
 */
10256
void TPageManager::doSHO(int port, vector<int>& channels, vector<string>& pars)
10257
{
10258
    DECL_TRACER("TPageManager::doSHO(int port, vector<int>& channels, vector<string>& pars)");
10259
 
10260
    if (pars.empty())
10261
    {
10262
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
10263
        return;
10264
    }
10265
 
10266
    TError::clear();
10267
    int cvalue = atoi(pars[0].c_str());
10268
 
193 andreas 10269
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 10270
 
10271
    if (TError::isError() || map.empty())
10272
        return;
10273
 
10274
    vector<Button::TButton *> buttons = collectButtons(map);
10275
 
83 andreas 10276
    if (buttons.size() > 0)
16 andreas 10277
    {
83 andreas 10278
        vector<Button::TButton *>::iterator mapIter;
10279
 
10280
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10281
        {
10282
            Button::TButton *bt = *mapIter;
318 andreas 10283
 
100 andreas 10284
            int pgID = (bt->getParent() >> 16) & 0x0000ffff;
10285
            bool pVisible = false;
10286
 
10287
            if (pgID < 500)
10288
            {
10289
                TPage *pg = getPage(pgID);
10290
 
10291
                if (pg && pg->isVisilble())
10292
                    pVisible = true;
10293
            }
10294
            else
10295
            {
10296
                TSubPage *pg = getSubPage(pgID);
10297
 
10298
                if (pg && pg->isVisible())
10299
                    pVisible = true;
10300
            }
10301
 
151 andreas 10302
            bool oldV = bt->isVisible();
10303
            bool visible = cvalue ? true : false;
10304
            MSG_DEBUG("Button " << bt->getButtonIndex() << ", \"" << bt->getButtonName() << "\" set " << (visible ? "VISIBLE" : "HIDDEN") << " (Previous: " << (oldV ? "VISIBLE" : "HIDDEN") << ")");
98 andreas 10305
 
151 andreas 10306
            if (visible != oldV)
100 andreas 10307
            {
151 andreas 10308
                bt->setVisible(visible);
100 andreas 10309
 
151 andreas 10310
                if (pVisible)
10311
                {
10312
                    setButtonCallbacks(bt);
10313
 
10314
                    if (_setVisible)
10315
                        _setVisible(bt->getHandle(), visible);
10316
                    else
10317
                        bt->refresh();
10318
                }
100 andreas 10319
            }
83 andreas 10320
        }
16 andreas 10321
    }
10322
}
10323
 
108 andreas 10324
void TPageManager::doTEC(int port, vector<int>& channels, vector<string>& pars)
10325
{
10326
    DECL_TRACER("TPageManager::doTEC(int port, vector<int>& channels, vector<string>& pars)");
10327
 
10328
    if (pars.size() < 2)
10329
    {
10330
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
10331
        return;
10332
    }
10333
 
10334
    TError::clear();
10335
    int btState = atoi(pars[0].c_str());
10336
    string color = pars[1];
10337
 
193 andreas 10338
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 10339
 
10340
    if (TError::isError() || map.empty())
10341
        return;
10342
 
10343
    vector<Button::TButton *> buttons = collectButtons(map);
10344
 
10345
    if (buttons.size() > 0)
10346
    {
10347
        vector<Button::TButton *>::iterator mapIter;
10348
 
10349
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10350
        {
10351
            Button::TButton *bt = *mapIter;
10352
 
10353
            if (btState == 0)
10354
                bt->setTextEffectColor(color);
10355
            else
10356
                bt->setTextEffectColor(color, btState-1);
10357
        }
10358
    }
10359
}
10360
 
10361
void TPageManager::getTEC(int port, vector<int>& channels, vector<string>& pars)
10362
{
10363
    DECL_TRACER("TPageManager::getTEC(int port, vector<int>& channels, vector<string>& pars)");
10364
 
10365
    if (pars.size() < 1)
10366
    {
10367
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
10368
        return;
10369
    }
10370
 
10371
    TError::clear();
10372
    int btState = atoi(pars[0].c_str());
10373
 
193 andreas 10374
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 10375
 
10376
    if (TError::isError() || map.empty())
10377
        return;
10378
 
10379
    vector<Button::TButton *> buttons = collectButtons(map);
10380
 
10381
    if (buttons.size() > 0)
10382
    {
110 andreas 10383
        Button::TButton *bt = buttons[0];
10384
 
10385
        if (btState == 0)       // All instances?
10386
        {
10387
            int bst = bt->getNumberInstances();
10388
 
10389
            for (int i = 0; i < bst; i++)
10390
            {
10391
                string c = bt->getTextEffectColor(i);
300 andreas 10392
                sendCustomEvent(i + 1, (int)c.length(), 0, c, 1009, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 10393
            }
10394
        }
10395
        else
10396
        {
10397
            string c = bt->getTextEffectColor(btState-1);
300 andreas 10398
            sendCustomEvent(btState, (int)c.length(), 0, c, 1009, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 10399
        }
10400
    }
10401
}
10402
 
10403
void TPageManager::doTEF(int port, vector<int>& channels, vector<string>& pars)
10404
{
10405
    DECL_TRACER("TPageManager::doTEF(int port, vector<int>& channels, vector<string>& pars)");
10406
 
10407
    if (pars.size() < 2)
10408
    {
10409
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
10410
        return;
10411
    }
10412
 
10413
    TError::clear();
10414
    int btState = atoi(pars[0].c_str());
10415
    string tef = pars[1];
10416
 
193 andreas 10417
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 10418
 
10419
    if (TError::isError() || map.empty())
10420
        return;
10421
 
10422
    vector<Button::TButton *> buttons = collectButtons(map);
10423
 
10424
    if (buttons.size() > 0)
10425
    {
108 andreas 10426
        vector<Button::TButton *>::iterator mapIter;
10427
 
10428
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10429
        {
10430
            Button::TButton *bt = *mapIter;
10431
 
110 andreas 10432
            if (btState == 0)
10433
                bt->setTextEffectName(tef);
10434
            else
10435
                bt->setTextEffectName(tef, btState-1);
10436
        }
10437
    }
10438
}
108 andreas 10439
 
110 andreas 10440
void TPageManager::getTEF(int port, vector<int>& channels, vector<string>& pars)
10441
{
10442
    DECL_TRACER("TPageManager::getTEF(int port, vector<int>& channels, vector<string>& pars)");
108 andreas 10443
 
110 andreas 10444
    if (pars.size() < 1)
10445
    {
10446
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
10447
        return;
10448
    }
108 andreas 10449
 
110 andreas 10450
    TError::clear();
10451
    int btState = atoi(pars[0].c_str());
10452
 
193 andreas 10453
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 10454
 
10455
    if (TError::isError() || map.empty())
10456
        return;
10457
 
10458
    vector<Button::TButton *> buttons = collectButtons(map);
10459
 
10460
    if (buttons.size() > 0)
10461
    {
10462
        Button::TButton *bt = buttons[0];
10463
 
10464
        if (btState == 0)       // All instances?
10465
        {
10466
            int bst = bt->getNumberInstances();
10467
 
10468
            for (int i = 0; i < bst; i++)
108 andreas 10469
            {
110 andreas 10470
                string c = bt->getTextEffectName(i);
300 andreas 10471
                sendCustomEvent(i + 1, (int)c.length(), 0, c, 1008, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 10472
            }
10473
        }
110 andreas 10474
        else
10475
        {
10476
            string c = bt->getTextEffectName(btState-1);
300 andreas 10477
            sendCustomEvent(btState, (int)c.length(), 0, c, 1008, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 10478
        }
108 andreas 10479
    }
10480
}
10481
 
16 andreas 10482
/**
14 andreas 10483
 * Assign a text string to those buttons with a defined address range.
10484
 * Sets Non-Unicode text.
10485
 */
10486
void TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)
10487
{
10488
    DECL_TRACER("TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)");
10489
 
10490
    if (pars.size() < 1)
10491
    {
10492
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
331 andreas 10493
#if TESTMODE == 1
334 andreas 10494
        setAllDone();
331 andreas 10495
#endif
14 andreas 10496
        return;
10497
    }
10498
 
16 andreas 10499
    TError::clear();
333 andreas 10500
    int btState = atoi(pars[0].c_str()) - 1;
14 andreas 10501
    string text;
10502
 
333 andreas 10503
    // Every comma (,) in the text produces a new parameter. Therefor we must
10504
    // concatenate this parameters together and insert the comma.
14 andreas 10505
    if (pars.size() > 1)
150 andreas 10506
    {
10507
        for (size_t i = 1; i < pars.size(); ++i)
10508
        {
10509
            if (i > 1)
10510
                text += ",";
14 andreas 10511
 
150 andreas 10512
            text += pars[i];
10513
        }
10514
    }
10515
 
193 andreas 10516
    vector<TMap::MAP_T> map = findButtons(port, channels);
14 andreas 10517
 
10518
    if (TError::isError() || map.empty())
331 andreas 10519
    {
10520
#if TESTMODE == 1
334 andreas 10521
        setAllDone();
331 andreas 10522
#endif
14 andreas 10523
        return;
331 andreas 10524
    }
14 andreas 10525
 
10526
    vector<Button::TButton *> buttons = collectButtons(map);
10527
 
83 andreas 10528
    if (buttons.size() > 0)
14 andreas 10529
    {
83 andreas 10530
        vector<Button::TButton *>::iterator mapIter;
14 andreas 10531
 
333 andreas 10532
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
14 andreas 10533
        {
83 andreas 10534
            Button::TButton *bt = *mapIter;
14 andreas 10535
 
252 andreas 10536
            if (!bt)
333 andreas 10537
                continue;
252 andreas 10538
 
333 andreas 10539
            bt->setText(text, btState);
331 andreas 10540
#if TESTMODE == 1
333 andreas 10541
            if (_gTestMode)
10542
                _gTestMode->setResult(bt->getText(btState < 0 ? 0 : btState));
331 andreas 10543
 
333 andreas 10544
            __success = true;
331 andreas 10545
#endif
14 andreas 10546
        }
10547
    }
331 andreas 10548
#if TESTMODE == 1
334 andreas 10549
    setDone();
331 andreas 10550
#endif
14 andreas 10551
}
21 andreas 10552
 
110 andreas 10553
void TPageManager::getTXT(int port, vector<int>& channels, vector<string>& pars)
10554
{
10555
    DECL_TRACER("TPageManager::getTXT(int port, vector<int>& channels, vector<string>& pars)");
10556
 
10557
    if (pars.size() < 1)
10558
    {
10559
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
10560
        return;
10561
    }
10562
 
10563
    TError::clear();
10564
    int btState = atoi(pars[0].c_str());
10565
 
193 andreas 10566
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 10567
 
10568
    if (TError::isError() || map.empty())
10569
        return;
10570
 
10571
    vector<Button::TButton *> buttons = collectButtons(map);
10572
 
10573
    if (buttons.size() > 0)
10574
    {
10575
        Button::TButton *bt = buttons[0];
10576
 
10577
        if (btState == 0)       // All instances?
10578
        {
10579
            int bst = bt->getNumberInstances();
10580
 
10581
            for (int i = 0; i < bst; i++)
10582
            {
10583
                string c = bt->getText(i);
300 andreas 10584
                sendCustomEvent(i + 1, (int)c.length(), 0, c, 1001, bt->getChannelPort(), bt->getChannelNumber());
333 andreas 10585
#if TESTMODE == 1
10586
                if (_gTestMode)
10587
                    _gTestMode->setResult(c);
10588
#endif
110 andreas 10589
            }
10590
        }
10591
        else
10592
        {
10593
            string c = bt->getText(btState-1);
300 andreas 10594
            sendCustomEvent(btState, (int)c.length(), 0, c, 1001, bt->getChannelPort(), bt->getChannelNumber());
333 andreas 10595
#if TESTMODE == 1
10596
            if (_gTestMode)
10597
                _gTestMode->setResult(c);
10598
#endif
110 andreas 10599
        }
10600
    }
334 andreas 10601
#if TESTMODE == 1
10602
    setAllDone();
10603
#endif
110 andreas 10604
}
10605
 
97 andreas 10606
/*
104 andreas 10607
 * Set button state legacy unicode text command.
10608
 *
10609
 * Set Unicode text in the legacy G4 format. For the ^UNI command, the Unicode
10610
 * text is sent as ASCII-HEX nibbles.
10611
 */
10612
void TPageManager::doUNI(int port, vector<int>& channels, vector<string>& pars)
10613
{
10614
    DECL_TRACER("TPageManager::doUNI(int port, vector<int>& channels, vector<string>& pars)");
10615
 
10616
    if (pars.size() < 1)
10617
    {
10618
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
331 andreas 10619
#if TESTMODE == 1
334 andreas 10620
        setAllDone();
331 andreas 10621
#endif
104 andreas 10622
        return;
10623
    }
10624
 
10625
    TError::clear();
333 andreas 10626
    int btState = atoi(pars[0].c_str()) - 1;
104 andreas 10627
    string text;
10628
 
361 andreas 10629
    // Unicode is the stadard character set used by Windows internally. It
10630
    // consists of 16 bit unsiged numbers. This can't be transported into a
10631
    // standard character string because a NULL byte means end of string.
10632
    // Therefor we must convert it to UFT-8.
104 andreas 10633
    if (pars.size() > 1)
10634
    {
10635
        string byte;
361 andreas 10636
        std::wstring uni;
104 andreas 10637
        size_t pos = 0;
10638
 
10639
        while (pos < pars[1].length())
10640
        {
361 andreas 10641
            byte = pars[1].substr(pos, 4);
10642
            wchar_t ch = (char)strtol(byte.c_str(), NULL, 16);
10643
            uni += ch;
10644
            pos += 4;
104 andreas 10645
        }
361 andreas 10646
 
10647
        text = UnicodeToUTF8(uni);
104 andreas 10648
    }
10649
 
193 andreas 10650
    vector<TMap::MAP_T> map = findButtons(port, channels);
104 andreas 10651
 
10652
    if (TError::isError() || map.empty())
331 andreas 10653
    {
10654
#if TESTMODE == 1
334 andreas 10655
        setAllDone();
331 andreas 10656
#endif
104 andreas 10657
        return;
331 andreas 10658
    }
104 andreas 10659
 
10660
    vector<Button::TButton *> buttons = collectButtons(map);
10661
 
10662
    if (buttons.size() > 0)
10663
    {
10664
        vector<Button::TButton *>::iterator mapIter;
10665
 
10666
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10667
        {
10668
            Button::TButton *bt = *mapIter;
10669
 
331 andreas 10670
#if TESTMODE == 1
333 andreas 10671
            bool res = bt->setText(text, btState);
104 andreas 10672
 
333 andreas 10673
            if (_gTestMode)
10674
                _gTestMode->setResult(bt->getText(btState < 0 ? 0 : btState));
331 andreas 10675
 
333 andreas 10676
            __success = res;
10677
#else
10678
            bt->setText(text, btState);
331 andreas 10679
#endif
104 andreas 10680
        }
10681
    }
334 andreas 10682
#if TESTMODE == 1
10683
    setDone();
10684
#endif
104 andreas 10685
}
10686
 
10687
void TPageManager::doUTF(int port, vector<int>& channels, vector<string>& pars)
10688
{
10689
    DECL_TRACER("TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)");
10690
 
10691
    if (pars.size() < 1)
10692
    {
10693
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
10694
        return;
10695
    }
10696
 
10697
    TError::clear();
10698
    int btState = atoi(pars[0].c_str());
10699
    string text;
10700
 
10701
    if (pars.size() > 1)
150 andreas 10702
    {
10703
        for (size_t i = 1; i < pars.size(); ++i)
10704
        {
10705
            if (i > 1)
10706
                text += ",";
104 andreas 10707
 
150 andreas 10708
            text += pars[i];
10709
        }
10710
    }
10711
 
193 andreas 10712
    vector<TMap::MAP_T> map = findButtons(port, channels);
104 andreas 10713
 
10714
    if (TError::isError() || map.empty())
10715
        return;
10716
 
10717
    vector<Button::TButton *> buttons = collectButtons(map);
10718
 
10719
    if (buttons.size() > 0)
10720
    {
10721
        vector<Button::TButton *>::iterator mapIter;
10722
 
10723
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10724
        {
10725
            Button::TButton *bt = *mapIter;
10726
 
10727
            if (btState == 0)       // All instances?
10728
            {
10729
                int bst = bt->getNumberInstances();
10730
 
10731
                for (int i = 0; i < bst; i++)
10732
                    bt->setText(text, i);
10733
            }
10734
            else
10735
                bt->setText(text, btState - 1);
10736
        }
10737
    }
10738
}
111 andreas 10739
 
361 andreas 10740
/**
10741
 * Simulates a touch/release/pulse at the given coordinate. If the push event
10742
 * is less then 0 or grater than 2 the command is ignored. It is also ignored
10743
 * if the x and y coordinate is out of range. The range must be between 0 and
10744
 * the maximum with and height.
10745
 */
148 andreas 10746
void TPageManager::doVTP (int, vector<int>&, vector<string>& pars)
10747
{
10748
    DECL_TRACER("TPageManager::doVTP (int, vector<int>&, vector<string>& pars)");
10749
 
10750
    if (pars.size() < 3)
10751
    {
10752
        MSG_ERROR("Expected 3 parameters but got only " << pars.size() << " parameters!");
10753
        return;
10754
    }
10755
 
10756
    int pushType = atoi(pars[0].c_str());
10757
    int x = atoi(pars[1].c_str());
10758
    int y = atoi(pars[2].c_str());
10759
 
10760
    if (pushType < 0 || pushType > 2)
10761
    {
10762
        MSG_ERROR("Invalid push type " << pushType << ". Ignoring command!");
10763
        return;
10764
    }
10765
 
217 andreas 10766
    if (x < 0 || x > mTSettings->getWidth() || y < 0 || y > mTSettings->getHeight())
148 andreas 10767
    {
10768
        MSG_ERROR("Illegal coordinates " << x << " x " << y << ". Ignoring command!");
10769
        return;
10770
    }
10771
 
10772
    if (pushType == 0 || pushType == 2)
10773
        mouseEvent(x, y, true);
10774
 
10775
    if (pushType == 1 || pushType == 2)
10776
        mouseEvent(x, y, false);
10777
}
10778
 
400 andreas 10779
 
111 andreas 10780
/**
10781
 * Set the keyboard passthru.
10782
 */
10783
void TPageManager::doKPS(int, vector<int>&, vector<string>& pars)
10784
{
10785
    DECL_TRACER("TPageManager::doKPS(int, vector<int>&, vector<string>& pars)");
10786
 
10787
    if (pars.size() < 1)
10788
    {
10789
        MSG_ERROR("Got no parameter. Ignoring command!");
10790
        return;
10791
    }
10792
 
10793
    int state = atoi(pars[0].c_str());
10794
 
10795
    if (state == 0)
10796
        mPassThrough = false;
10797
    else if (state == 5)
10798
        mPassThrough = true;
10799
}
10800
 
400 andreas 10801
void TPageManager::doVKS(int, vector<int>&, vector<string>& pars)
111 andreas 10802
{
400 andreas 10803
    DECL_TRACER("TPageManager::doVKS(int, vector<int>&, vector<string>& pars)");
111 andreas 10804
 
10805
    if (pars.size() < 1)
10806
    {
10807
        MSG_ERROR("Got no parameter. Ignoring command!");
10808
        return;
10809
    }
10810
 
10811
    if (_sendVirtualKeys)
10812
        _sendVirtualKeys(pars[0]);
10813
}
10814
 
400 andreas 10815
void TPageManager::doLPB(int port, vector<int>& channels, vector<string>& pars)
10816
{
10817
    DECL_TRACER("TPageManager::doLPB(int port, vector<int>& channels, vector<string>& pars)");
10818
 
10819
    if (pars.size() < 1)
10820
        return;
10821
 
10822
    TError::clear();
10823
    string passwd = pars[0];
10824
    vector<TMap::MAP_T> map = findButtons(port, channels);
10825
 
10826
    if (TError::isError() || map.empty())
10827
        return;
10828
 
10829
    vector<Button::TButton *> buttons = collectButtons(map);
10830
 
10831
    if (buttons.size() > 0)
10832
    {
10833
        vector<Button::TButton *>::iterator mapIter;
10834
 
10835
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10836
        {
10837
            Button::TButton *bt = *mapIter;
10838
            bt->setUserName(passwd);
10839
        }
10840
    }
10841
}
10842
 
401 andreas 10843
void TPageManager::doLPC(int, vector<int>&, vector<string>&)
400 andreas 10844
{
401 andreas 10845
    DECL_TRACER("TPageManager::doLPC(int, vector<int>&, vector<string>&)");
400 andreas 10846
 
10847
    TConfig::clearUserPasswords();
10848
}
10849
 
10850
void TPageManager::doLPR(int, vector<int>&, vector<string>& pars)
10851
{
10852
    DECL_TRACER("TPageManager::doLPR(int, vector<int>&, vector<string>& pars)");
10853
 
10854
    if (pars.size() < 1)
10855
        return;
10856
 
10857
    string user = pars[0];
10858
    TConfig::clearUserPassword(user);
10859
}
10860
 
10861
void TPageManager::doLPS(int, vector<int>&, vector<string>& pars)
10862
{
10863
    DECL_TRACER("TPageManager::doLPS(int, vector<int>&, vector<string>& pars)");
10864
 
10865
    if (pars.size() < 2)
10866
        return;
10867
 
10868
    string user = pars[0];
10869
    string password;
10870
 
10871
    // In case the password contains one or more comma (,), the password is
10872
    // splitted. The following loop concatenates the password into one. Because
10873
    // the comma is lost, we must add it again.
10874
    for (size_t i = 0; i < pars.size(); ++i)
10875
    {
10876
        if (i > 0)
10877
            password += ",";
10878
 
10879
        password += pars[i];
10880
    }
10881
 
10882
    TConfig::setUserPassword(user, password);
10883
}
10884
 
104 andreas 10885
/*
400 andreas 10886
 * Set the page flip password. @PWD sets the level 1 password only.
10887
 */
10888
void TPageManager::doAPWD(int, vector<int>&, vector<string>& pars)
10889
{
10890
    DECL_TRACER("TPageManager::doPWD(int port, vector<int>&, vector<string>& pars)");
10891
 
10892
    if (pars.size() < 1)
10893
    {
10894
        MSG_ERROR("Got less then 1 parameter!");
10895
        return;
10896
    }
10897
 
10898
    string password;
10899
    // In case the password contains one or more comma (,), the password is
10900
    // splitted. The following loop concatenates the password into one. Because
10901
    // the comma is lost, we must add it again.
10902
    for (size_t i = 0; i < pars.size(); ++i)
10903
    {
10904
        if (i > 0)
10905
            password += ",";
10906
 
10907
        password += pars[i];
10908
    }
10909
 
10910
    TConfig::savePassword1(password);
10911
}
10912
 
10913
/*
10914
 * Set the page flip password. Password level is required and must be 1 - 4
10915
 */
10916
void TPageManager::doPWD(int, vector<int>&, vector<string>& pars)
10917
{
10918
    DECL_TRACER("TPageManager::doPWD(int, vector<int>&, vector<string>& pars)");
10919
 
10920
    if (pars.size() < 2)
10921
    {
10922
        MSG_ERROR("Got less then 2 parameters!");
10923
        return;
10924
    }
10925
 
10926
    int pwIdx = atoi(pars[0].c_str());
10927
    string password;
10928
    // In case the password contains one or more comma (,), the password is
10929
    // splitted. The following loop concatenates the password into one. Because
10930
    // the comma is lost, we must add it again.
10931
    for (size_t i = 1; i < pars.size(); ++i)
10932
    {
10933
        if (i > 1)
10934
            password += ",";
10935
 
10936
        password += pars[i];
10937
    }
10938
 
10939
    switch(pwIdx)
10940
    {
10941
        case 1: TConfig::savePassword1(password); break;
10942
        case 2: TConfig::savePassword2(password); break;
10943
        case 3: TConfig::savePassword3(password); break;
10944
        case 4: TConfig::savePassword4(password); break;
10945
    }
10946
}
10947
 
10948
/*
97 andreas 10949
 * Set the bitmap of a button to use a particular resource.
10950
 * Syntax:
10951
 *    "'^BBR-<vt addr range>,<button states range>,<resource name>'"
10952
 * Variable:
10953
 *    variable text address range = 1 - 4000.
10954
 *    button states range = 1 - 256 for multi-state buttons (0 = All states, for General buttons 1 = Off state and 2 = On state).
10955
 *    resource name = 1 - 50 ASCII characters.
10956
 * Example:
10957
 *    SEND_COMMAND Panel,"'^BBR-700,1,Sports_Image'"
10958
 *    Sets the resource name of the button to ’Sports_Image’.
10959
 */
21 andreas 10960
void TPageManager::doBBR(int port, vector<int>& channels, vector<string>& pars)
10961
{
10962
    DECL_TRACER("TPageManager::doBBR(int port, vector<int>& channels, vector<string>& pars)");
10963
 
10964
    if (pars.size() < 2)
10965
    {
10966
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
10967
        return;
10968
    }
10969
 
10970
    TError::clear();
10971
    int btState = atoi(pars[0].c_str());
10972
    string resName = pars[1];
10973
 
193 andreas 10974
    vector<TMap::MAP_T> map = findButtons(port, channels);
21 andreas 10975
 
10976
    if (TError::isError() || map.empty())
10977
        return;
10978
 
10979
    vector<Button::TButton *> buttons = collectButtons(map);
10980
 
83 andreas 10981
    if (buttons.size() > 0)
21 andreas 10982
    {
83 andreas 10983
        vector<Button::TButton *>::iterator mapIter;
21 andreas 10984
 
83 andreas 10985
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
21 andreas 10986
        {
83 andreas 10987
            Button::TButton *bt = *mapIter;
252 andreas 10988
//            setButtonCallbacks(bt);
21 andreas 10989
 
83 andreas 10990
            if (btState == 0)       // All instances?
10991
            {
10992
                int bst = bt->getNumberInstances();
10993
                MSG_DEBUG("Setting BBR on all " << bst << " instances...");
10994
 
10995
                for (int i = 0; i < bst; i++)
10996
                    bt->setResourceName(resName, i);
10997
            }
10998
            else
10999
                bt->setResourceName(resName, btState - 1);
97 andreas 11000
 
11001
            if (bt->isVisible())
11002
                bt->refresh();
99 andreas 11003
            else if (_setVisible)
11004
                _setVisible(bt->getHandle(), false);
21 andreas 11005
        }
11006
    }
11007
}
11008
 
97 andreas 11009
/*
11010
 * Add new resources
11011
 * Adds any and all resource parameters by sending embedded codes and data.
11012
 * Since the embedded codes are preceded by a '%' character, any '%' character
11013
 * contained in* the URL must be escaped with a second '%' character (see
11014
 * example).
11015
 * The file name field (indicated by a %F embedded code) may contain special
11016
 * escape sequences as shown in the ^RAF, ^RMF.
11017
 * Syntax:
11018
 *    "'^RAF-<resource name>,<data>'"
11019
 * Variables:
11020
 *    resource name = 1 - 50 ASCII characters.
11021
 *    data = Refers to the embedded codes, see the ^RAF, ^RMF.
11022
 * Example:
11023
 *    SEND_COMMAND Panel,"'^RAF-New Image,%P0%HAMX.COM%ALab/Test%%5Ffile%Ftest.jpg'"
11024
 *    Adds a new resource.
11025
 *    The resource name is ’New Image’
11026
 *    %P (protocol) is an HTTP
11027
 *    %H (host name) is AMX.COM
11028
 *    %A (file path) is Lab/Test_f ile
11029
 *    %F (file name) is test.jpg.
11030
 *    Note that the %%5F in the file path is actually encoded as %5F.
11031
 */
11032
void TPageManager::doRAF(int, vector<int>&, vector<string>& pars)
11033
{
11034
    DECL_TRACER("TPageManager::doRAF(int port, vector<int>& channels, vector<string>& pars)");
11035
 
11036
    if (pars.size() < 2)
11037
    {
11038
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
11039
        return;
11040
    }
11041
 
11042
    string name = pars[0];
11043
    string data = pars[1];
11044
 
11045
    vector<string> parts = StrSplit(data, "%");
11046
    RESOURCE_T res;
11047
 
11048
    if (parts.size() > 0)
11049
    {
11050
        vector<string>::iterator sIter;
11051
 
11052
        for (sIter = parts.begin(); sIter != parts.end(); sIter++)
11053
        {
11054
            const char *s = sIter->c_str();
11055
            string ss = *sIter;
11056
            MSG_DEBUG("Parsing \"" << ss << "\" with token << " << ss[0]);
11057
 
11058
            switch(*s)
11059
            {
11060
                case 'P':
11061
                    if (*(s+1) == '0')
11062
                        res.protocol = "HTTP";
11063
                    else
11064
                        res.protocol = "FTP";
11065
                    break;
11066
 
11067
                case 'U': res.user = sIter->substr(1); break;
11068
                case 'S': res.password = sIter->substr(1); break;
11069
                case 'H': res.host = sIter->substr(1); break;
11070
                case 'F': res.file = sIter->substr(1); break;
11071
                case 'A': res.path = sIter->substr(1); break;
11072
                case 'R': res.refresh = atoi(sIter->substr(1).c_str()); break;
11073
 
11074
                default:
11075
                    MSG_WARNING("Option " << sIter->at(0) << " is currently not implemented!");
11076
            }
11077
        }
11078
 
11079
        if (gPrjResources)
11080
            gPrjResources->addResource(name, res.protocol, res.host, res.path, res.file, res.user, res.password, res.refresh);
11081
    }
11082
}
11083
 
111 andreas 11084
void TPageManager::doRFR(int, vector<int>&, vector<string>& pars)
97 andreas 11085
{
11086
    DECL_TRACER("TPageManager::doRFR(int port, vector<int>& channels, vector<string>& pars)");
11087
 
11088
    if (pars.size() < 1)
11089
    {
11090
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
11091
        return;
11092
    }
11093
 
11094
    string name = pars[0];
193 andreas 11095
    vector<TMap::MAP_T> map = findButtonByName(name);
97 andreas 11096
 
11097
    if (TError::isError() || map.empty())
11098
        return;
11099
 
11100
    vector<Button::TButton *> buttons = collectButtons(map);
11101
 
11102
    if (buttons.size() > 0)
11103
    {
11104
        vector<Button::TButton *>::iterator mapIter;
11105
 
11106
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11107
        {
11108
            Button::TButton *bt = *mapIter;
11109
 
11110
            if (bt->isVisible())
11111
            {
252 andreas 11112
//                setButtonCallbacks(bt);
97 andreas 11113
                bt->refresh();
11114
            }
11115
        }
11116
    }
11117
}
11118
 
11119
/*
11120
 * Modify an existing resource
11121
 *
11122
 * Modifies any and all resource parameters by sending embedded codes and data.
11123
 * Since the embedded codes are preceded by a '%' character, any '%' character
11124
 * contained in the URL must be escaped with a second '%' character (see
11125
 * example).
11126
 * The file name field (indicated by a %F embedded code) may contain special
11127
 * escape sequences as shown in the ^RAF.
11128
 *
11129
 * Syntax:
11130
 * "'^RMF-<resource name>,<data>'"
11131
 * Variables:
11132
 *   • resource name = 1 - 50 ASCII characters
11133
 *   • data = Refers to the embedded codes, see the ^RAF, ^RMF.
11134
 * Example:
11135
 *   SEND_COMMAND Panel,"'^RMF-Sports_Image,%ALab%%5FTest/Images%Ftest.jpg'"
11136
 * Changes the resource ’Sports_Image’ file name to ’test.jpg’ and the path to
11137
 * ’Lab_Test/Images’.
11138
 * Note that the %%5F in the file path is actually encoded as %5F.
11139
 */
22 andreas 11140
void TPageManager::doRMF(int, vector<int>&, vector<string>& pars)
21 andreas 11141
{
11142
    DECL_TRACER("TPageManager::doRMF(int port, vector<int>& channels, vector<string>& pars)");
11143
 
11144
    if (pars.size() < 2)
11145
    {
11146
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
11147
        return;
11148
    }
11149
 
11150
    string name = pars[0];
11151
    string data = pars[1];
11152
 
11153
    vector<string> parts = StrSplit(data, "%");
11154
    RESOURCE_T res;
11155
 
83 andreas 11156
    if (parts.size() > 0)
21 andreas 11157
    {
83 andreas 11158
        vector<string>::iterator sIter;
21 andreas 11159
 
83 andreas 11160
        for (sIter = parts.begin(); sIter != parts.end(); sIter++)
21 andreas 11161
        {
83 andreas 11162
            const char *s = sIter->c_str();
11163
            string ss = *sIter;
11164
            MSG_DEBUG("Parsing \"" << ss << "\" with token << " << ss[0]);
21 andreas 11165
 
83 andreas 11166
            switch(*s)
11167
            {
11168
                case 'P':
11169
                    if (*(s+1) == '0')
11170
                        res.protocol = "HTTP";
11171
                    else
11172
                        res.protocol = "FTP";
11173
                break;
21 andreas 11174
 
83 andreas 11175
                case 'U': res.user = sIter->substr(1); break;
11176
                case 'S': res.password = sIter->substr(1); break;
11177
                case 'H': res.host = sIter->substr(1); break;
11178
                case 'F': res.file = sIter->substr(1); break;
11179
                case 'A': res.path = sIter->substr(1); break;
11180
                case 'R': res.refresh = atoi(sIter->substr(1).c_str()); break;
11181
 
11182
                default:
11183
                    MSG_WARNING("Option " << sIter->at(0) << " is currently not implemented!");
11184
            }
21 andreas 11185
        }
83 andreas 11186
 
11187
        if (gPrjResources)
11188
            gPrjResources->setResource(name, res.protocol, res.host, res.path, res.file, res.user, res.password, res.refresh);
21 andreas 11189
    }
11190
}
62 andreas 11191
 
11192
/**
111 andreas 11193
 * Change the refresh rate for a given resource.
11194
 */
11195
void TPageManager::doRSR(int, vector<int>&, vector<string>& pars)
11196
{
11197
    DECL_TRACER("TPageManager::doRSR(int, vector<int>&, vector<string>& pars)");
11198
 
11199
    if (pars.size() < 2)
11200
    {
11201
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
11202
        return;
11203
    }
11204
 
11205
    string resName = pars[0];
11206
    int resRefresh = atoi(pars[1].c_str());
11207
 
11208
    if (!gPrjResources)
11209
    {
11210
        MSG_ERROR("Missing the resource module. Ignoring command!");
11211
        return;
11212
    }
11213
 
11214
    RESOURCE_T res = gPrjResources->findResource(resName);
11215
 
11216
    if (res.name.empty() || res.refresh == resRefresh)
11217
        return;
11218
 
11219
    gPrjResources->setResource(resName, res.protocol, res.host, res.path, res.file, res.user, res.password, resRefresh);
11220
}
11221
 
11222
/**
62 andreas 11223
 * @brief TPageManager::doAKB - Pop up the keyboard icon
11224
 * Pop up the keyboard icon and initialize the text string to that specified.
11225
 * Keyboard string is set to null on power up and is stored until power is lost.
11226
 * The Prompt Text is optional.
11227
 */
11228
void TPageManager::doAKB(int, vector<int>&, vector<string> &pars)
11229
{
11230
    DECL_TRACER("TPageManager::doAKB(int, vector<int>&, vector<string> &pars)");
11231
 
11232
    if (pars.size() < 1)
11233
    {
11234
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
11235
        return;
11236
    }
11237
 
11238
    string initText = pars[0];
11239
    string promptText;
11240
 
11241
    if (pars.size() > 1)
11242
        promptText = pars[1];
11243
 
63 andreas 11244
    if (initText.empty())
11245
        initText = mAkbText;
11246
    else
11247
        mAkbText = initText;
62 andreas 11248
 
11249
    if (_callKeyboard)
63 andreas 11250
        _callKeyboard(initText, promptText, false);
62 andreas 11251
}
11252
 
63 andreas 11253
/**
11254
 * Pop up the keyboard icon and initialize the text string to that
11255
 * specified.
11256
 */
62 andreas 11257
void TPageManager::doAKEYB(int port, vector<int>& channels, vector<string>& pars)
11258
{
11259
    DECL_TRACER("TPageManager::doAKEYB(int port, vector<int>& channels, vector<string>& pars)");
11260
 
11261
    doAKB(port, channels, pars);
11262
}
11263
 
63 andreas 11264
void TPageManager::doAKEYP(int port, std::vector<int>& channels, std::vector<std::string>& pars)
11265
{
11266
    DECL_TRACER("TPageManager::doAKEYP(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
11267
 
11268
    doAKP(port, channels, pars);
11269
}
11270
 
62 andreas 11271
/**
63 andreas 11272
 * Remove keyboard or keypad that was displayed using 'AKEYB', 'AKEYP', 'PKEYP',
11273
 * @AKB, @AKP, @PKP, @EKP, or @TKP commands.
11274
 */
11275
void TPageManager::doAKEYR(int, vector<int>&, vector<string>&)
11276
{
11277
    DECL_TRACER("TPageManager::doAKEYR(int, vector<int>&, vector<string>&)");
11278
 
11279
    if (_callResetKeyboard)
11280
        _callResetKeyboard();
11281
}
11282
 
11283
/**
62 andreas 11284
 * @brief TPageManager::doAKP - Pop up the keypad icon
11285
 * Pop up the keypad icon and initialize the text string to that specified.
11286
 * Keypad string is set to null on power up and is stored until power is lost.
11287
 * The Prompt Text is optional.
11288
 */
11289
void TPageManager::doAKP(int, std::vector<int>&, std::vector<std::string> &pars)
11290
{
11291
    DECL_TRACER("TPageManager::doAKP(int, vector<int>&, vector<string> &pars)");
11292
 
11293
    if (pars.size() < 1)
11294
    {
11295
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
11296
        return;
11297
    }
11298
 
11299
    string initText = pars[0];
11300
    string promptText;
11301
 
11302
    if (pars.size() > 1)
11303
        promptText = pars[1];
11304
 
63 andreas 11305
    if (initText.empty())
11306
        initText = mAkpText;
11307
    else
11308
        mAkpText = initText;
62 andreas 11309
 
11310
    if (_callKeypad)
63 andreas 11311
        _callKeypad(initText, promptText, false);
62 andreas 11312
}
11313
 
63 andreas 11314
/**
11315
 * Remove keyboard or keypad that was displayed using 'AKEYB', 'AKEYP', 'PKEYP',
11316
 * @AKB, @AKP, @PKP, @EKP, or @TKP commands.
11317
 */
11318
void TPageManager::doAKR(int port, vector<int>& channels, vector<string>& pars)
62 andreas 11319
{
63 andreas 11320
    DECL_TRACER("TPageManager::doAKR(int, vector<int>&, vector<string>&)");
62 andreas 11321
 
63 andreas 11322
    doAKEYR(port, channels, pars);
62 andreas 11323
}
11324
 
108 andreas 11325
void TPageManager::doABEEP(int, std::vector<int>&, vector<string>&)
11326
{
11327
    DECL_TRACER("TPageManager::doBEEP(int, std::vector<int>&, vector<string>&)");
11328
 
11329
    if (!_playSound)
334 andreas 11330
    {
11331
#if TESTMODE == 1
11332
        setAllDone();
11333
#endif
108 andreas 11334
        return;
334 andreas 11335
    }
108 andreas 11336
 
11337
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getSingleBeepSound();
11338
    TValidateFile vf;
11339
 
326 andreas 11340
    if (vf.isValidFile(snd))
108 andreas 11341
        _playSound(snd);
326 andreas 11342
#if TESTMODE == 1
11343
    else
11344
    {
11345
        MSG_PROTOCOL("Sound file invalid!");
334 andreas 11346
        setAllDone();
326 andreas 11347
    }
11348
#endif
108 andreas 11349
}
11350
 
11351
void TPageManager::doADBEEP(int, std::vector<int>&, vector<string>&)
11352
{
11353
    DECL_TRACER("TPageManager::doDBEEP(int, std::vector<int>&, vector<string>&)");
11354
 
11355
    if (!_playSound)
11356
        return;
11357
 
11358
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getDoubleBeepSound();
11359
    TValidateFile vf;
11360
 
326 andreas 11361
    if (vf.isValidFile(snd))
108 andreas 11362
        _playSound(snd);
326 andreas 11363
#if TESTMODE == 1
11364
    else
11365
    {
11366
        MSG_PROTOCOL("Sound file invalid!");
334 andreas 11367
        setAllDone();
326 andreas 11368
    }
11369
#endif
108 andreas 11370
}
11371
 
71 andreas 11372
void TPageManager::doBEEP(int, std::vector<int>&, vector<string>&)
11373
{
11374
    DECL_TRACER("TPageManager::doBEEP(int, std::vector<int>&, vector<string>&)");
11375
 
11376
    if (!_playSound)
326 andreas 11377
    {
11378
#if TESTMODE == 1
11379
        MSG_PROTOCOL("Method \"playSound()\" not initialized!");
334 andreas 11380
        setAllDone();
326 andreas 11381
#endif
71 andreas 11382
        return;
326 andreas 11383
    }
71 andreas 11384
 
11385
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getSingleBeepSound();
11386
    TValidateFile vf;
108 andreas 11387
    TSystemSound sysSound(TConfig::getSystemPath(TConfig::SOUNDS));
71 andreas 11388
 
326 andreas 11389
    if (sysSound.getSystemSoundState() && vf.isValidFile(snd))
71 andreas 11390
        _playSound(snd);
326 andreas 11391
#if TESTMODE == 1
11392
    else
11393
    {
11394
        if (!sysSound.getSystemSoundState())
11395
        {
11396
            MSG_PROTOCOL("Sound state disabled!")
11397
        }
11398
        else
11399
        {
11400
            MSG_PROTOCOL("Sound file invalid!");
11401
        }
11402
 
334 andreas 11403
        setAllDone();
326 andreas 11404
    }
11405
#endif
71 andreas 11406
}
11407
 
11408
void TPageManager::doDBEEP(int, std::vector<int>&, vector<string>&)
11409
{
11410
    DECL_TRACER("TPageManager::doDBEEP(int, std::vector<int>&, vector<string>&)");
11411
 
11412
    if (!_playSound)
11413
        return;
11414
 
11415
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getDoubleBeepSound();
11416
    TValidateFile vf;
108 andreas 11417
    TSystemSound sysSound(TConfig::getSystemPath(TConfig::SOUNDS));
71 andreas 11418
 
326 andreas 11419
    if (sysSound.getSystemSoundState() && vf.isValidFile(snd))
71 andreas 11420
        _playSound(snd);
326 andreas 11421
#if TESTMODE == 1
11422
    else
11423
    {
11424
        if (!sysSound.getSystemSoundState())
11425
        {
11426
            MSG_PROTOCOL("Sound state disabled!")
11427
        }
11428
        else
11429
        {
11430
            MSG_PROTOCOL("Sound file invalid!");
11431
        }
11432
 
334 andreas 11433
        setAllDone();
326 andreas 11434
    }
11435
#endif
71 andreas 11436
}
11437
 
63 andreas 11438
/**
11439
 * @brief Pop up the keypad icon and initialize the text string to that specified.
11440
 * Keypad string is set to null on power up and is stored until power is lost.
11441
 * The Prompt Text is optional.
11442
 */
62 andreas 11443
void TPageManager::doEKP(int port, std::vector<int>& channels, std::vector<std::string>& pars)
11444
{
11445
    DECL_TRACER("TPageManager::doEKP(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
11446
 
11447
    doAKP(port, channels, pars);
11448
}
63 andreas 11449
 
11450
/**
11451
 * @brief Present a private keyboard.
11452
 * Pops up the keyboard icon and initializes the text string to that specified.
11453
 * Keyboard displays a '*' instead of the letters typed. The Prompt Text is optional.
11454
 */
11455
void TPageManager::doPKB(int, vector<int>&, vector<string>& pars)
11456
{
11457
    DECL_TRACER("TPageManager::doPKB(int, vector<int>&, vector<string>& pars)");
11458
 
11459
    if (pars.size() < 1)
11460
    {
11461
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
11462
        return;
11463
    }
11464
 
11465
    string initText = pars[0];
11466
    string promptText;
11467
 
11468
    if (pars.size() > 1)
11469
        promptText = pars[1];
11470
 
11471
    if (_callKeyboard)
11472
        _callKeyboard(initText, promptText, true);
11473
}
11474
 
11475
/**
11476
 * @brief Present a private keypad.
11477
 * Pops up the keypad icon and initializes the text string to that specified.
11478
 * Keypad displays a '*' instead of the numbers typed. The Prompt Text is optional.
11479
 */
11480
void TPageManager::doPKP(int, vector<int>&, vector<string>& pars)
11481
{
11482
    DECL_TRACER("TPageManager::doPKP(int, vector<int>&, vector<string>& pars)");
11483
 
11484
    if (pars.size() < 1)
11485
    {
11486
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
11487
        return;
11488
    }
11489
 
11490
    string initText = pars[0];
11491
    string promptText;
11492
 
11493
    if (pars.size() > 1)
11494
        promptText = pars[1];
11495
 
11496
    if (_callKeypad)
11497
        _callKeypad(initText, promptText, true);
11498
}
11499
 
11500
/**
408 andreas 11501
 * @brief Reset protected password command
11502
 * This command is used to reset the protected setup password to the factory
11503
 * default value.
11504
 */
11505
void TPageManager::doRPP(int, vector<int>&, vector<string>&)
11506
{
11507
    DECL_TRACER("TPageManager::doRPP(int, vector<int>&, vector<string>&)");
11508
 
11509
    TConfig::savePassword1("1988");
11510
}
11511
 
11512
/**
64 andreas 11513
 * Send panel to SETUP page.
11514
 */
11515
void TPageManager::doSetup(int, vector<int>&, vector<string>&)
11516
{
11517
    DECL_TRACER("TPageManager::doSetup(int, vector<int>&, vector<string>&)");
11518
 
11519
    if (_callShowSetup)
11520
        _callShowSetup();
11521
}
11522
 
11523
/**
11524
 * Shut down the App
11525
 */
11526
void TPageManager::doShutdown(int, vector<int>&, vector<string>&)
11527
{
11528
    DECL_TRACER("TPageManager::doShutdown(int, vector<int>&, vector<string>&)");
11529
 
97 andreas 11530
    MSG_PROTOCOL("Received shutdown ...");
64 andreas 11531
#ifdef __ANDROID__
11532
    stopNetworkState();
11533
#endif
11534
    prg_stopped = true;
11535
    killed = true;
11536
 
11537
    if (_shutdown)
11538
        _shutdown();
11539
}
11540
 
82 andreas 11541
void TPageManager::doSOU(int, vector<int>&, vector<string>& pars)
11542
{
11543
    DECL_TRACER("TPageManager::doSOU(int, vector<int>&, vector<string>& pars)");
11544
 
11545
    if (pars.size() < 1)
11546
    {
11547
        MSG_ERROR("@SOU: Expecting a sound file as parameter! Ignoring command.");
11548
        return;
11549
    }
11550
 
11551
    if (!_playSound)
11552
    {
11553
        MSG_ERROR("@SOU: Missing sound module!");
11554
        return;
11555
    }
11556
 
165 andreas 11557
    if (pars[0].empty() || strCaseCompare(pars[0], "None") == 0)
11558
        return;
11559
 
82 andreas 11560
    _playSound(pars[0]);
11561
}
11562
 
326 andreas 11563
void TPageManager::doMUT(int, vector<int>&, vector<string>& pars)
11564
{
11565
    DECL_TRACER("TPageManager::doMUT(int, vector<int>&, vector<string>& pars)");
11566
 
11567
    if (pars.size() < 1)
11568
    {
11569
        MSG_ERROR("^MUT: Expecting a state parameter! Ignoring command.");
11570
        return;
11571
    }
11572
 
11573
    bool mute = 0;
11574
 
11575
    if (pars[0] == "0")
11576
        mute = false;
11577
    else
11578
        mute = true;
11579
 
11580
    TConfig::setMuteState(mute);
11581
#if TESTMODE == 1
327 andreas 11582
    if (_gTestMode)
11583
    {
11584
        bool st = TConfig::getMuteState();
11585
        _gTestMode->setResult(st ? "1" : "0");
11586
    }
11587
 
326 andreas 11588
    __success = true;
334 andreas 11589
    setAllDone();
326 andreas 11590
#endif
11591
}
11592
 
64 andreas 11593
/**
63 andreas 11594
 * @brief Present a telephone keypad.
11595
 * Pops up the keypad icon and initializes the text string to that specified.
11596
 * The Prompt Text is optional.
11597
 */
11598
void TPageManager::doTKP(int port, vector<int>& channels, vector<string>& pars)
11599
{
11600
    DECL_TRACER("TPageManager::doTKP(int port, vector<int>& channels, vector<string>& pars)");
11601
 
11602
    // TODO: Implement a real telefone keypad.
11603
    doAKP(port, channels, pars);
11604
}
11605
 
11606
/**
11607
 * Popup the virtual keyboard
11608
 */
123 andreas 11609
void TPageManager::doVKB(int port, vector<int>& channels, vector<string>& pars)
63 andreas 11610
{
123 andreas 11611
    DECL_TRACER("TPageManager::doVKB(int port, vector<int>& channels, vector<string>& pars)");
63 andreas 11612
 
11613
    doAKP(port, channels, pars);
11614
}
129 andreas 11615
#ifndef _NOSIP_
123 andreas 11616
void TPageManager::sendPHN(vector<string>& cmds)
11617
{
11618
    DECL_TRACER("TPageManager::sendPHN(const vector<string>& cmds)");
11619
 
11620
    vector<int> channels;
11621
    doPHN(-1, channels, cmds);
11622
}
11623
 
141 andreas 11624
void TPageManager::actPHN(vector<string>& cmds)
11625
{
11626
    DECL_TRACER("TPageManager::actPHN(const vector<string>& cmds)");
11627
 
11628
    vector<int> channels;
11629
    doPHN(1, channels, cmds);
11630
}
11631
 
140 andreas 11632
void TPageManager::phonePickup(int id)
11633
{
11634
    DECL_TRACER("TPageManager::phonePickup(int id)");
11635
 
11636
    if (id < 0 || id >= 4)
11637
        return;
11638
 
11639
    if (mSIPClient)
11640
        mSIPClient->pickup(id);
11641
}
11642
 
11643
void TPageManager::phoneHangup(int id)
11644
{
11645
    DECL_TRACER("TPageManager::phoneHangup(int id)");
11646
 
11647
    if (id < 0 || id >= 4)
11648
        return;
11649
 
11650
    if (mSIPClient)
11651
        mSIPClient->terminate(id);
11652
}
11653
 
123 andreas 11654
/**
11655
 * @brief Phone commands.
11656
 * The phone commands could come from the master or are send to the master.
11657
 * If the parameter \p port is less then 0 (zero) a command is send to the
11658
 * master. In any other case the command came from the mater.
125 andreas 11659
 *
11660
 * @param port  This is used to signal if the command was sent by the master
11661
 *              or generated from the panel. If ths is less then 0, then the
11662
 *              method was called because of an event happen in the panel.
11663
 *              If this is grater or equal 0, then the event is comming from
11664
 *              the master.
11665
 * @param pars  This are parameters. The first parameter defines the action
11666
 *              to be done. According to the command this parameter may have a
11667
 *              different number of arguments.
123 andreas 11668
 */
11669
void TPageManager::doPHN(int port, vector<int>&, vector<string>& pars)
11670
{
11671
    DECL_TRACER("TPageManager::doPHN(int port, vector<int>&, vector<string>& pars)");
11672
 
11673
    if (pars.size() < 1)
11674
    {
11675
        MSG_ERROR("Expecting at least 1 parameter but got none! Ignoring command.");
11676
        return;
11677
    }
11678
 
11679
    string sCommand;
11680
    string cmd = toUpper(pars[0]);
11681
 
11682
    // Master to panel
11683
    if (port >= 0)
11684
    {
11685
        if (!mSIPClient)
11686
        {
11687
            MSG_ERROR("SIP client class was not initialized!")
11688
            return;
11689
        }
11690
 
11691
        if (cmd == "ANSWER")
11692
        {
11693
            if (pars.size() >= 2)
11694
            {
124 andreas 11695
                int id = atoi(pars[1].c_str());
11696
 
11697
                if (mSIPClient->getSIPState(id) == TSIPClient::SIP_HOLD)
11698
                    mSIPClient->resume(id);
11699
                else
135 andreas 11700
                    mSIPClient->pickup(id);
123 andreas 11701
            }
11702
        }
11703
        else if (cmd == "AUTOANSWER")
11704
        {
11705
            if (pars.size() >= 2)
11706
            {
11707
                if (pars[1].at(0) == '0')
11708
                    mPHNautoanswer = false;
11709
                else
11710
                    mPHNautoanswer = true;
127 andreas 11711
 
11712
                vector<string> cmds;
11713
                cmds = { "AUTOANSWER", to_string(mPHNautoanswer ? 1 : 0) };
128 andreas 11714
                sendPHN(cmds);
123 andreas 11715
            }
11716
        }
11717
        else if (cmd == "CALL")     // Initiate a call
11718
        {
11719
            if (pars.size() >= 2)
127 andreas 11720
                mSIPClient->call(pars[1]);
123 andreas 11721
        }
11722
        else if (cmd == "DTMF")     // Send tone modified codes
11723
        {
127 andreas 11724
            if (pars.size() >= 2)
11725
                mSIPClient->sendDTMF(pars[1]);
123 andreas 11726
        }
11727
        else if (cmd == "HANGUP")   // terminate a call
11728
        {
124 andreas 11729
            if (pars.size() >= 2)
11730
            {
11731
                int id = atoi(pars[1].c_str());
11732
                mSIPClient->terminate(id);
11733
            }
123 andreas 11734
        }
11735
        else if (cmd == "HOLD")     // Hold the line
11736
        {
124 andreas 11737
            if (pars.size() >= 2)
11738
            {
11739
                int id = atoi(pars[1].c_str());
11740
                mSIPClient->hold(id);
11741
            }
123 andreas 11742
        }
128 andreas 11743
        else if (cmd == "LINESTATE") // State of all line
127 andreas 11744
        {
128 andreas 11745
            mSIPClient->sendLinestate();
127 andreas 11746
        }
123 andreas 11747
        else if (cmd == "PRIVACY")  // Set/unset "do not disturb"
11748
        {
128 andreas 11749
            if (pars.size() >= 2)
11750
            {
11751
                bool state = (pars[1].at(0) == '1' ? true : false);
11752
                mSIPClient->sendPrivate(state);
11753
            }
123 andreas 11754
        }
11755
        else if (cmd == "REDIAL")   // Redials the last number
11756
        {
128 andreas 11757
            mSIPClient->redial();
123 andreas 11758
        }
11759
        else if (cmd == "TRANSFER") // Transfer call to provided number
11760
        {
128 andreas 11761
            if (pars.size() >= 3)
11762
            {
11763
                int id = atoi(pars[1].c_str());
11764
                string num = pars[2];
11765
 
11766
                if (mSIPClient->transfer(id, num))
11767
                {
11768
                    vector<string> cmds;
11769
                    cmds.push_back("TRANSFERRED");
11770
                    sendPHN(cmds);
11771
                }
11772
            }
123 andreas 11773
        }
144 andreas 11774
        else if (cmd == "IM")
11775
        {
11776
            if (pars.size() < 3)
11777
                return;
11778
 
11779
            string to = pars[1];
11780
            string msg = pars[2];
11781
            string toUri;
11782
 
11783
            if (to.find("sip:") == string::npos)
11784
                toUri = "sip:";
11785
 
11786
            toUri += to;
11787
 
11788
            if (to.find("@") == string::npos)
11789
                toUri += "@" + TConfig::getSIPproxy();
11790
 
11791
            mSIPClient->sendIM(toUri, msg);
11792
        }
123 andreas 11793
        else if (cmd == "SETUP")    // Some temporary settings
11794
        {
11795
            if (pars.size() < 2)
11796
                return;
11797
 
11798
            if (pars[1] == "DOMAIN" && pars.size() >= 3)
11799
                TConfig::setSIPdomain(pars[2]);
11800
            else if (pars[1] == "DTMFDURATION")
11801
            {
138 andreas 11802
                unsigned int ms = atoi(pars[2].c_str());
11803
                mSIPClient->setDTMFduration(ms);
123 andreas 11804
            }
11805
            else if (pars[1] == "ENABLE")   // (re)register user
11806
            {
11807
                TConfig::setSIPstatus(true);
127 andreas 11808
                mSIPClient->cleanUp();
135 andreas 11809
                mSIPClient->init();
123 andreas 11810
            }
127 andreas 11811
            else if (pars[1] == "DOMAIN" && pars.size() >= 3)
11812
                TConfig::setSIPdomain(pars[2]);
123 andreas 11813
            else if (pars[1] == "PASSWORD" && pars.size() >= 3)
11814
                TConfig::setSIPpassword(pars[2]);
11815
            else if (pars[1] == "PORT" && pars.size() != 3)
11816
                TConfig::setSIPport(atoi(pars[2].c_str()));
11817
            else if (pars[1] == "PROXYADDR" && pars.size() >= 3)
11818
                TConfig::setSIPproxy(pars[2]);
11819
            else if (pars[1] == "STUNADDR" && pars.size() >= 3)
11820
                TConfig::setSIPstun(pars[2]);
11821
            else if (pars[1] == "USERNAME" && pars.size() >= 3)
11822
                TConfig::setSIPuser(pars[2]);
11823
        }
11824
        else
11825
        {
11826
            MSG_ERROR("Unknown command ^PHN-" << cmd << " ignored!");
11827
        }
11828
    }
11829
    else   // Panel to master
11830
    {
11831
        vector<string>::iterator iter;
11832
 
11833
        for (iter = pars.begin(); iter != pars.end(); ++iter)
11834
        {
11835
            if (!sCommand.empty())
11836
                sCommand += ",";
11837
 
11838
            sCommand += *iter;
11839
        }
11840
 
11841
        sendPHNcommand(sCommand);
11842
    }
11843
}
127 andreas 11844
 
11845
void TPageManager::getPHN(int, vector<int>&, vector<string>& pars)
11846
{
11847
    DECL_TRACER("TPageManager::getPHN(int, vector<int>&, vector<string>& pars)");
11848
 
11849
    if (pars.size() < 1)
11850
    {
11851
        MSG_ERROR("Invalid number of arguments!");
11852
        return;
11853
    }
11854
 
11855
    string cmd = pars[0];
11856
 
11857
    if (cmd == "AUTOANSWER")
11858
        sendPHNcommand(cmd + "," + (mPHNautoanswer ? "1" : "0"));
11859
    else if (cmd == "LINESTATE")
11860
    {
11861
        if (!mSIPClient)
11862
            return;
11863
 
138 andreas 11864
        mSIPClient->sendLinestate();
127 andreas 11865
    }
11866
    else if (cmd == "MSGWAITING")
11867
    {
144 andreas 11868
        size_t num = mSIPClient->getNumberMessages();
11869
        sendPHNcommand(cmd + "," + (num > 0 ? "1" : "0") + "," + std::to_string(num) + "0,0,0");
127 andreas 11870
    }
11871
    else if (cmd == "PRIVACY")
11872
    {
138 andreas 11873
        if (mSIPClient->getPrivate())
11874
            sendPHNcommand(cmd + ",1");
11875
        else
11876
            sendPHNcommand(cmd + ",0");
127 andreas 11877
    }
144 andreas 11878
    else if (cmd == "REDIAL")
11879
    {
11880
        if (pars.size() < 2)
11881
            return;
11882
 
11883
        sendPHNcommand(cmd + "," + pars[1]);
11884
    }
127 andreas 11885
    else
11886
    {
11887
        MSG_WARNING("Unknown command " << cmd << " found!");
11888
    }
11889
}
129 andreas 11890
#endif  // _NOSIP_
134 andreas 11891
 
300 andreas 11892
/*
318 andreas 11893
 *  Hide all subpages in a subpage viewer button.
11894
 */
11895
void TPageManager::doSHA(int port, vector<int> &channels, vector<string> &pars)
11896
{
11897
    DECL_TRACER("TPageManager::doSHA(int port, vector<int> &channels, vector<string> &pars)");
11898
 
343 andreas 11899
    Q_UNUSED(pars);
318 andreas 11900
    vector<TMap::MAP_T> map = findButtons(port, channels);
11901
 
11902
    if (TError::isError() || map.empty())
11903
        return;
11904
 
11905
    vector<Button::TButton *> buttons = collectButtons(map);
11906
 
11907
    if (!buttons.empty())
11908
    {
11909
        vector<Button::TButton *>::iterator mapIter;
11910
 
11911
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11912
        {
11913
            Button::TButton *bt = *mapIter;
11914
 
11915
            if (_hideAllSubViewItems)
11916
                _hideAllSubViewItems(bt->getHandle());
11917
        }
11918
    }
11919
}
11920
 
11921
void TPageManager::doSHD(int port, vector<int>& channels, vector<string>& pars)
11922
{
11923
    DECL_TRACER("TPageManager::doSHD(int port, vector<int>& channels, vector<string>& pars)");
11924
 
11925
    if (pars.size() < 1)
11926
        return;
11927
 
11928
    string name = pars[0];
11929
 
11930
    vector<TMap::MAP_T> map = findButtons(port, channels);
11931
 
11932
    if (TError::isError() || map.empty())
11933
        return;
11934
 
11935
    vector<Button::TButton *> buttons = collectButtons(map);
11936
 
11937
    if (!buttons.empty())
11938
    {
11939
        vector<Button::TButton *>::iterator mapIter;
11940
 
11941
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11942
        {
11943
            Button::TButton *bt = *mapIter;
11944
 
11945
            vector<TSubPage *> subviews = createSubViewList(bt->getSubViewID());
11946
 
11947
            if (subviews.empty())
11948
                continue;
11949
 
11950
            vector<TSubPage *>::iterator itSub;
11951
 
11952
            for (itSub = subviews.begin(); itSub != subviews.end(); ++itSub)
11953
            {
11954
                TSubPage *sub = *itSub;
11955
 
11956
                if (sub && sub->getName() == name)
11957
                {
11958
                    if (_hideSubViewItem)
11959
                        _hideSubViewItem(bt->getHandle(), sub->getHandle());
11960
 
11961
                    break;
11962
                }
11963
            }
11964
        }
11965
    }
11966
}
11967
 
11968
void TPageManager::doSPD(int port, vector<int>& channels, vector<string>& pars)
11969
{
11970
    DECL_TRACER("TPageManager::doSPD(int port, vector<int>& channel, vector<string>& pars)");
11971
 
11972
    if (pars.size() < 1)
11973
        return;
11974
 
11975
    TError::clear();
11976
    int padding = atoi(pars[0].c_str());
11977
 
11978
    if (padding < 0 || padding > 100)
11979
        return;
11980
 
11981
    vector<TMap::MAP_T> map = findButtons(port, channels);
11982
 
11983
    if (TError::isError() || map.empty())
11984
        return;
11985
 
11986
    vector<Button::TButton *> buttons = collectButtons(map);
11987
 
11988
    if (!buttons.empty())
11989
    {
11990
        vector<Button::TButton *>::iterator mapIter;
11991
 
11992
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11993
        {
11994
            Button::TButton *bt = *mapIter;
11995
 
11996
            if (_setSubViewPadding)
11997
                _setSubViewPadding(bt->getHandle(), padding);
11998
        }
11999
    }
12000
}
12001
 
12002
/*
300 andreas 12003
 * This command will perform one of three different operations based on the following conditions:
12004
 * 1. If the named subpage is hidden in the set associated with the viewer button it will be shown in the anchor position.
12005
 * 2. If the named subpage is not present in the set it will be added to the set and shown in the anchor position.
12006
 * 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
12007
 * position. The anchor position is the location on the subpage viewer button specified by its weighting. This will either be
12008
 * left, center or right for horizontal subpage viewer buttons or top, center or bottom for vertical subpage viewer buttons.
12009
 * Surrounding subpages are relocated on the viewer button as needed to accommodate the described operations
12010
 */
12011
void TPageManager::doSSH(int port, vector<int> &channels, vector<string> &pars)
12012
{
12013
    DECL_TRACER("TPageManager::doSSH(int port, vector<int> &channels, vector<string> &pars)");
12014
 
12015
    if (pars.size() < 1)
12016
    {
12017
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
12018
        return;
12019
    }
12020
 
12021
    TError::clear();
12022
    string name = pars[0];
12023
    int position = 0;   // optional
12024
    int time = 0;       // optional
12025
 
12026
    if (pars.size() > 1)
12027
        position = atoi(pars[1].c_str());
12028
 
12029
    if (pars.size() > 2)
12030
        time = atoi(pars[2].c_str());
12031
 
12032
    vector<TMap::MAP_T> map = findButtons(port, channels);
12033
 
12034
    if (TError::isError() || map.empty())
12035
        return;
12036
 
12037
    vector<Button::TButton *> buttons = collectButtons(map);
12038
 
12039
    if (!buttons.empty())
12040
    {
12041
        vector<Button::TButton *>::iterator mapIter;
12042
 
12043
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
12044
        {
12045
            Button::TButton *bt = *mapIter;
12046
            vector<TSubPage *> subviews = createSubViewList(bt->getSubViewID());
12047
 
12048
            if (subviews.empty() || !bt)
12049
                continue;
12050
 
12051
            vector<TSubPage *>::iterator itSub;
12052
 
12053
            for (itSub = subviews.begin(); itSub != subviews.end(); ++itSub)
12054
            {
12055
                TSubPage *sub = *itSub;
12056
 
12057
                if (sub && sub->getName() == name)
12058
                {
12059
                    if (_showSubViewItem)
12060
                        _showSubViewItem(sub->getHandle(), bt->getHandle(), position, time);
12061
 
12062
                    break;
12063
                }
12064
            }
12065
        }
12066
    }
12067
}
12068
 
318 andreas 12069
void TPageManager::doSTG(int port, vector<int>& channels, vector<string>& pars)
12070
{
12071
    DECL_TRACER("TPageManager::doSTG(int port, vector<int>& channels, vector<string>& pars)");
12072
 
12073
    if (pars.empty())
12074
    {
12075
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
12076
        return;
12077
    }
12078
 
12079
    TError::clear();
12080
    string name = pars[0];
12081
    int position = 0;   // optional
12082
    int time = 0;       // optional
12083
 
12084
    if (pars.size() > 1)
12085
        position = atoi(pars[1].c_str());
12086
 
12087
    if (pars.size() > 2)
12088
        time = atoi(pars[2].c_str());
12089
 
12090
    vector<TMap::MAP_T> map = findButtons(port, channels);
12091
 
12092
    if (TError::isError() || map.empty())
12093
        return;
12094
 
12095
    vector<Button::TButton *> buttons = collectButtons(map);
12096
 
12097
    if (!buttons.empty())
12098
    {
12099
        vector<Button::TButton *>::iterator mapIter;
12100
 
12101
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
12102
        {
12103
            Button::TButton *bt = *mapIter;
12104
            vector<TSubPage *> subviews = createSubViewList(bt->getSubViewID());
12105
 
12106
            if (subviews.empty() || !bt)
12107
                continue;
12108
 
12109
            vector<TSubPage *>::iterator itSub;
12110
 
12111
            for (itSub = subviews.begin(); itSub != subviews.end(); ++itSub)
12112
            {
12113
                TSubPage *sub = *itSub;
12114
 
12115
                if (sub && sub->getName() == name)
12116
                {
12117
                    if (_toggleSubViewItem)
12118
                        _toggleSubViewItem(sub->getHandle(), bt->getHandle(), position, time);
12119
 
12120
                    break;
12121
                }
12122
            }
12123
        }
12124
    }
12125
}
12126
 
227 andreas 12127
void TPageManager::doLVD(int port, vector<int> &channels, vector<string> &pars)
225 andreas 12128
{
227 andreas 12129
    DECL_TRACER("TPageManager::doLVD(int port, vector<int> &channels, vector<string> &pars)");
225 andreas 12130
 
12131
    if (pars.size() < 1)
12132
    {
12133
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
12134
        return;
12135
    }
12136
 
12137
    TError::clear();
12138
    string source = pars[0];
12139
    vector<string> configs;
12140
 
12141
    if (pars.size() > 1)
12142
    {
12143
        for (size_t i = 1; i < pars.size(); ++i)
227 andreas 12144
        {
12145
            string low = toLower(pars[i]);
12146
 
12147
            if (low.find_first_of("user=") != string::npos ||
12148
                low.find_first_of("pass=") != string::npos ||
12149
                low.find_first_of("csv=")  != string::npos ||
12150
                low.find_first_of("has_headers=") != string::npos)
12151
            {
12152
                configs.push_back(pars[i]);
12153
            }
12154
        }
225 andreas 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->setListSource(source, configs);
12172
        }
12173
    }
12174
 
12175
}
12176
 
230 andreas 12177
void TPageManager::doLVE(int port, vector<int> &channels, vector<string> &pars)
12178
{
12179
    DECL_TRACER("TPageManager::doLVE(int port, vector<int> &channels, vector<string> &pars)");
12180
 
12181
    if (pars.size() < 1)
12182
    {
12183
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
12184
        return;
12185
    }
12186
 
12187
    TError::clear();
12188
    int num = atoi(pars[0].c_str());
12189
 
12190
    vector<TMap::MAP_T> map = findButtons(port, channels);
12191
 
12192
    if (TError::isError() || map.empty())
12193
        return;
12194
 
12195
    vector<Button::TButton *> buttons = collectButtons(map);
12196
 
12197
    if (buttons.size() > 0)
12198
    {
12199
        vector<Button::TButton *>::iterator mapIter;
12200
 
12201
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
12202
        {
12203
            Button::TButton *bt = *mapIter;
12204
            bt->setListViewEventNumber(num);
12205
        }
12206
    }
12207
 
12208
}
12209
 
227 andreas 12210
void TPageManager::doLVF(int port, vector<int> &channels, vector<string> &pars)
12211
{
12212
    DECL_TRACER("TPageManager::doLVF(int port, vector<int> &channels, vector<string> &pars)");
12213
 
12214
    if (pars.size() < 1)
12215
    {
12216
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
12217
        return;
12218
    }
12219
 
12220
    TError::clear();
12221
    string filter;
12222
 
12223
    vector<string>::iterator iter;
12224
 
12225
    for (iter = pars.begin(); iter != pars.end(); ++iter)
12226
    {
12227
        if (filter.length() > 0)
12228
            filter += ",";
12229
 
12230
        filter += *iter;
12231
    }
12232
 
12233
    vector<TMap::MAP_T> map = findButtons(port, channels);
12234
 
12235
    if (TError::isError() || map.empty())
12236
        return;
12237
 
12238
    vector<Button::TButton *> buttons = collectButtons(map);
12239
 
12240
    if (buttons.size() > 0)
12241
    {
12242
        vector<Button::TButton *>::iterator mapIter;
12243
 
12244
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
12245
        {
12246
            Button::TButton *bt = *mapIter;
12247
            bt->setListSourceFilter(filter);
12248
        }
12249
    }
12250
}
12251
 
230 andreas 12252
void TPageManager::doLVL(int port, vector<int> &channels, vector<string> &pars)
12253
{
12254
    DECL_TRACER("TPageManager::doLVL(int port, vector<int> &channels, vector<string> &pars)");
12255
 
12256
    if (pars.size() < 1)
12257
    {
12258
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
12259
        return;
12260
    }
12261
 
12262
    TError::clear();
233 andreas 12263
    bool hasColumns = false;
230 andreas 12264
    int columns = 0;
233 andreas 12265
    bool hasLayout = false;
230 andreas 12266
    int layout = 0;
233 andreas 12267
    bool hasComponent = false;
12268
    int component = 0;
12269
    bool hasCellHeight = false;
12270
    bool cellHeightPercent = false;
12271
    int cellheight = 0;
12272
    bool hasP1 = false;
12273
    int p1 = 0;
12274
    bool hasP2 = false;
12275
    int p2 = 0;
12276
    bool hasFilter = false;
12277
    bool filter = false;
12278
    bool hasFilterHeight = false;
12279
    bool filterHeightPercent = false;
12280
    int filterheight = 0;
12281
    bool hasAlphaScroll = false;
12282
    bool alphascroll = false;
230 andreas 12283
 
12284
    vector<string>::iterator iter;
12285
 
12286
    for (iter = pars.begin(); iter != pars.end(); ++iter)
12287
    {
12288
        string low = toLower(*iter);
12289
 
12290
        if (low.find("columns=") != string::npos ||
12291
            low.find("nc=") != string::npos ||
12292
            low.find("numcol=") != string::npos)
12293
        {
12294
            size_t pos = low.find("=");
12295
            string sCols = low.substr(pos + 1);
12296
            columns = atoi(sCols.c_str());
233 andreas 12297
            hasColumns = true;
12298
        }
12299
        else if (low.find("c=") != string::npos || low.find("comp=") != string::npos)
12300
        {
12301
            size_t pos = low.find("=");
12302
            string sComp = low.substr(pos + 1);
12303
            component |= atoi(sComp.c_str());
12304
            hasComponent = true;
12305
        }
12306
        else if (low.find("l=") != string::npos || low.find("layout=") != string::npos)
12307
        {
12308
            size_t pos = low.find("=");
12309
            string sLay = low.substr(pos + 1);
12310
            layout = atoi(sLay.c_str());
12311
            hasLayout = true;
12312
        }
12313
        else if (low.find("ch=") != string::npos || low.find("cellheight=") != string::npos)
12314
        {
12315
            size_t pos = low.find("=");
12316
            string sCh = low.substr(pos + 1);
12317
            cellheight = atoi(sCh.c_str());
230 andreas 12318
 
233 andreas 12319
            if (low.find("%") != string::npos)
12320
                cellHeightPercent = true;
12321
 
12322
            hasCellHeight = true;
230 andreas 12323
        }
233 andreas 12324
        else if (low.find("p1=") != string::npos)
12325
        {
12326
            size_t pos = low.find("=");
12327
            string sP1 = low.substr(pos + 1);
12328
            p1 = atoi(sP1.c_str());
12329
            hasP1 = true;
12330
        }
12331
        else if (low.find("p2=") != string::npos)
12332
        {
12333
            size_t pos = low.find("=");
12334
            string sP2 = low.substr(pos + 1);
12335
            p2 = atoi(sP2.c_str());
12336
            hasP2 = true;
12337
        }
12338
        else if (low.find("f=") != string::npos || low.find("filter=") != string::npos)
12339
        {
12340
            size_t pos = low.find("=");
12341
            string sFilter = low.substr(pos + 1);
12342
            filter = isTrue(sFilter);
12343
            hasFilter = true;
12344
        }
12345
        else if (low.find("fh=") != string::npos || low.find("filterheight=") != string::npos)
12346
        {
12347
            size_t pos = low.find("=");
12348
            string sFilter = low.substr(pos + 1);
12349
            filterheight = atoi(sFilter.c_str());
12350
 
12351
            if (low.find("%") != string::npos)
12352
                filterHeightPercent = true;
12353
 
12354
            hasFilterHeight = true;
12355
        }
12356
        else if (low.find("as=") != string::npos || low.find("alphascroll=") != string::npos)
12357
        {
12358
            size_t pos = low.find("=");
12359
            string sAlpha = low.substr(pos + 1);
12360
            alphascroll = isTrue(sAlpha);
12361
            hasAlphaScroll = true;
12362
        }
230 andreas 12363
    }
12364
 
12365
    vector<TMap::MAP_T> map = findButtons(port, channels);
12366
 
12367
    if (TError::isError() || map.empty())
12368
        return;
12369
 
12370
    vector<Button::TButton *> buttons = collectButtons(map);
12371
 
12372
    if (buttons.size() > 0)
12373
    {
12374
        vector<Button::TButton *>::iterator mapIter;
12375
 
12376
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
12377
        {
12378
            Button::TButton *bt = *mapIter;
233 andreas 12379
 
12380
            if (hasColumns)         bt->setListViewColumns(columns);
12381
            if (hasComponent)       bt->setListViewComponent(component);
12382
            if (hasLayout)          bt->setListViewLayout(layout);
12383
            if (hasCellHeight)      bt->setListViewCellheight(cellheight, cellHeightPercent);
12384
            if (hasP1)              bt->setListViewP1(p1);
12385
            if (hasP2)              bt->setListViewP2(p2);
12386
            if (hasFilter)          bt->setListViewColumnFilter(filter);
12387
            if (hasFilterHeight)    bt->setListViewFilterHeight(filterheight, filterHeightPercent);
12388
            if (hasAlphaScroll)     bt->setListViewAlphaScroll(alphascroll);
230 andreas 12389
        }
12390
    }
12391
}
12392
 
233 andreas 12393
void TPageManager::doLVM(int port, vector<int> &channels, vector<string> &pars)
12394
{
12395
    DECL_TRACER("TPageManager::doLVM(int port, vector<int> &channels, vector<string> &pars)");
12396
 
12397
    if (pars.size() < 1)
12398
    {
12399
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
12400
        return;
12401
    }
12402
 
12403
    TError::clear();
12404
    map<string,string> mapField;
12405
 
12406
    vector<string>::iterator iter;
12407
 
12408
    for (iter = pars.begin(); iter != pars.end(); ++iter)
12409
    {
12410
        string left, right;
12411
        size_t pos = 0;
12412
 
12413
        if ((pos = iter->find("=")) != string::npos)
12414
        {
12415
            string left = iter->substr(0, pos);
12416
            left = toLower(left);
12417
            string right = iter->substr(pos + 1);
12418
 
12419
            if (left == "t1" || left == "t2" || left == "i1")
12420
                mapField.insert(pair<string,string>(left, right));
12421
        }
12422
    }
12423
 
12424
    vector<TMap::MAP_T> map = findButtons(port, channels);
12425
 
12426
    if (TError::isError() || map.empty())
12427
        return;
12428
 
12429
    vector<Button::TButton *> buttons = collectButtons(map);
12430
 
12431
    if (buttons.size() > 0)
12432
    {
12433
        vector<Button::TButton *>::iterator mapIter;
12434
 
12435
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
12436
        {
12437
            Button::TButton *bt = *mapIter;
12438
            bt->setListViewFieldMap(mapField);
12439
        }
12440
    }
12441
}
12442
 
12443
void TPageManager::doLVN(int port, vector<int> &channels, vector<string> &pars)
12444
{
12445
    DECL_TRACER("TPageManager::doLVN(int port, vector<int> &channels, vector<string> &pars)");
12446
 
12447
    if (pars.size() < 1)
12448
    {
12449
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
12450
        return;
12451
    }
12452
 
12453
    TError::clear();
12454
    string command = pars[0];
12455
    bool select = false;
12456
 
12457
    if (pars.size() > 1)
12458
    {
12459
        if (isTrue(pars[1]))
12460
            select = true;
12461
    }
12462
 
12463
    vector<TMap::MAP_T> map = findButtons(port, channels);
12464
 
12465
    if (TError::isError() || map.empty())
12466
        return;
12467
 
12468
    vector<Button::TButton *> buttons = collectButtons(map);
12469
 
12470
    if (buttons.size() > 0)
12471
    {
12472
        vector<Button::TButton *>::iterator mapIter;
12473
 
12474
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
12475
        {
12476
            Button::TButton *bt = *mapIter;
12477
            bt->listViewNavigate(command, select);
12478
        }
12479
    }
12480
}
12481
 
12482
void TPageManager::doLVR(int port, vector<int> &channels, vector<string> &pars)
12483
{
12484
    DECL_TRACER("TPageManager::doLVR(int port, vector<int> &channels, vector<string> &pars)");
12485
 
12486
    TError::clear();
12487
    int interval = -1;
12488
    bool force = false;
12489
 
12490
    if (pars.size() > 0)
12491
        interval = atoi(pars[0].c_str());
12492
 
12493
    if (pars.size() > 1)
12494
        force = isTrue(pars[1]);
12495
 
12496
    vector<TMap::MAP_T> map = findButtons(port, channels);
12497
 
12498
    if (TError::isError() || map.empty())
12499
        return;
12500
 
12501
    vector<Button::TButton *> buttons = collectButtons(map);
12502
 
12503
    if (buttons.size() > 0)
12504
    {
12505
        vector<Button::TButton *>::iterator mapIter;
12506
 
12507
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
12508
        {
12509
            Button::TButton *bt = *mapIter;
12510
            bt->listViewRefresh(interval, force);
12511
        }
12512
    }
12513
}
12514
 
12515
void TPageManager::doLVS(int port, vector<int> &channels, vector<string> &pars)
12516
{
12517
    DECL_TRACER("TPageManager::doLVS(int port, vector<int> &channels, vector<string> &pars)");
12518
 
12519
    TError::clear();
12520
    vector<string> sortColumns;
12521
    Button::LIST_SORT sort = Button::LIST_SORT_NONE;
12522
    string override;
12523
 
12524
    if (pars.size() > 0)
12525
    {
12526
        vector<string>::iterator iter;
12527
 
12528
        for (iter = pars.begin(); iter != pars.end(); ++iter)
12529
        {
12530
            if (iter->find(";") == string::npos)
12531
                sortColumns.push_back(*iter);
12532
            else
12533
            {
12534
                vector<string> parts = StrSplit(*iter, ";");
12535
                sortColumns.push_back(parts[0]);
12536
 
12537
                if (parts[1].find("a") != string::npos || parts[1].find("A") != string::npos)
12538
                    sort = Button::LIST_SORT_ASC;
12539
                else if (parts[1].find("d") != string::npos || parts[1].find("D") != string::npos)
12540
                    sort = Button::LIST_SORT_DESC;
12541
                else if (parts[1].find("*") != string::npos)
12542
                {
12543
                    if (parts.size() > 2 && !parts[2].empty())
12544
                    {
12545
                        override = parts[2];
12546
                        sort = Button::LIST_SORT_OVERRIDE;
12547
                    }
12548
                }
12549
                else if (parts[1].find("n") != string::npos || parts[1].find("N") != string::npos)
12550
                    sort = Button::LIST_SORT_NONE;
12551
            }
12552
        }
12553
    }
12554
 
12555
    vector<TMap::MAP_T> map = findButtons(port, channels);
12556
 
12557
    if (TError::isError() || map.empty())
12558
        return;
12559
 
12560
    vector<Button::TButton *> buttons = collectButtons(map);
12561
 
12562
    if (buttons.size() > 0)
12563
    {
12564
        vector<Button::TButton *>::iterator mapIter;
12565
 
12566
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
12567
        {
12568
            Button::TButton *bt = *mapIter;
12569
            bt->listViewSortData(sortColumns, sort, override);
12570
        }
12571
    }
12572
}
12573
 
134 andreas 12574
void TPageManager::doTPCCMD(int, vector<int>&, vector<string>& pars)
12575
{
12576
    DECL_TRACER("TPageManager::doTPCCMD(int, vector<int>&, vector<string>& pars)");
12577
 
12578
    if (pars.size() < 1)
12579
    {
12580
        MSG_ERROR("Too few arguments for TPCCMD!");
12581
        return;
12582
    }
12583
 
12584
    string cmd = pars[0];
12585
 
12586
    if (strCaseCompare(cmd, "LocalHost") == 0)
12587
    {
12588
        if (pars.size() < 2 || pars[1].empty())
12589
        {
12590
            MSG_ERROR("The command \"LocalHost\" requires an additional parameter!");
12591
            return;
12592
        }
12593
 
12594
        TConfig::saveController(pars[1]);
12595
    }
12596
    else if (strCaseCompare(cmd, "LocalPort") == 0)
12597
    {
12598
        if (pars.size() < 2 || pars[1].empty())
12599
        {
12600
            MSG_ERROR("The command \"LocalPort\" requires an additional parameter!");
12601
            return;
12602
        }
12603
 
12604
        int port = atoi(pars[1].c_str());
12605
 
12606
        if (port > 0 && port < 65536)
12607
            TConfig::savePort(port);
12608
        else
12609
        {
12610
            MSG_ERROR("Invalid network port " << port);
12611
        }
12612
    }
12613
    else if (strCaseCompare(cmd, "DeviceID") == 0)
12614
    {
12615
        if (pars.size() < 2 || pars[1].empty())
12616
        {
12617
            MSG_ERROR("The command \"DeviceID\" requires an additional parameter!");
12618
            return;
12619
        }
12620
 
12621
        int id = atoi(pars[1].c_str());
12622
 
12623
        if (id >= 10000 && id < 30000)
12624
            TConfig::setSystemChannel(id);
12625
    }
12626
    else if (strCaseCompare(cmd, "ApplyProfile") == 0)
12627
    {
12628
        // We restart the network connection only
12629
        if (gAmxNet)
12630
            gAmxNet->reconnect();
12631
    }
12632
    else if (strCaseCompare(cmd, "QueryDeviceInfo") == 0)
12633
    {
12634
        string info = "DEVICEINFO-TPANELID," + TConfig::getPanelType();
12635
        info += ";HOSTNAME,";
12636
        char hostname[HOST_NAME_MAX];
12637
 
12638
        if (gethostname(hostname, HOST_NAME_MAX) != 0)
12639
        {
12640
            MSG_ERROR("Can't get host name: " << strerror(errno));
12641
            return;
12642
        }
12643
 
12644
        info.append(hostname);
12645
        info += ";UUID," + TConfig::getUUID();
12646
        sendGlobalString(info);
12647
    }
12648
    else if (strCaseCompare(cmd, "LockRotation") == 0)
12649
    {
12650
        if (pars.size() < 2 || pars[1].empty())
12651
        {
12652
            MSG_ERROR("The command \"LockRotation\" requires an additional parameter!");
12653
            return;
12654
        }
12655
 
12656
        if (strCaseCompare(pars[1], "true") == 0)
12657
            TConfig::setRotationFixed(true);
12658
        else
12659
            TConfig::setRotationFixed(false);
12660
    }
12661
    else if (strCaseCompare(cmd, "ButtonHit") == 0)
12662
    {
12663
        if (pars.size() < 2 || pars[1].empty())
12664
        {
12665
            MSG_ERROR("The command \"ButtonHit\" requires an additional parameter!");
12666
            return;
12667
        }
12668
 
12669
        if (strCaseCompare(pars[1], "true") == 0)
12670
            TConfig::saveSystemSoundState(true);
12671
        else
12672
            TConfig::saveSystemSoundState(false);
12673
    }
12674
    else if (strCaseCompare(cmd, "ReprocessTP4") == 0)
12675
    {
12676
        if (_resetSurface)
12677
            _resetSurface();
12678
    }
12679
}
12680
 
12681
void TPageManager::doTPCACC(int, vector<int>&, vector<string>& pars)
12682
{
12683
    DECL_TRACER("TPageManager::doTPCACC(int, vector<int>&, vector<string>& pars)");
12684
 
12685
    if (pars.size() < 1)
12686
    {
12687
        MSG_ERROR("Too few arguments for TPCACC!");
12688
        return;
12689
    }
12690
 
12691
    string cmd = pars[0];
12692
 
12693
    if (strCaseCompare(cmd, "ENABLE") == 0)
12694
    {
12695
        mInformOrientation = true;
12696
        sendOrientation();
12697
    }
12698
    else if (strCaseCompare(cmd, "DISABLE") == 0)
12699
    {
12700
        mInformOrientation = false;
12701
    }
12702
    else if (strCaseCompare(cmd, "QUERY") == 0)
12703
    {
12704
        sendOrientation();
12705
    }
12706
}
153 andreas 12707
 
279 andreas 12708
#ifndef _NOSIP_
153 andreas 12709
void TPageManager::doTPCSIP(int, vector<int>&, vector<string>& pars)
12710
{
12711
    DECL_TRACER("TPageManager::doTPCSIP(int port, vector<int>& channels, vector<string>& pars)");
12712
 
12713
    if (pars.empty())
12714
        return;
12715
 
12716
    string cmd = toUpper(pars[0]);
12717
 
12718
    if (cmd == "SHOW" && _showPhoneDialog)
12719
        _showPhoneDialog(true);
12720
    else if (!_showPhoneDialog)
12721
    {
12722
        MSG_ERROR("There is no phone dialog registered!");
12723
    }
12724
}
279 andreas 12725
#endif