Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 andreas 1
/*
269 andreas 2
 * Copyright (C) 2020 to 2023 by Andreas Theofilu <andreas@theosys.at>
3 andreas 3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software Foundation,
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
17
 */
18
 
270 andreas 19
#include <QtGlobal>
20
 
3 andreas 21
#include <vector>
14 andreas 22
#include <thread>
23
#include <mutex>
186 andreas 24
 
36 andreas 25
#ifdef __ANDROID__
264 andreas 26
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
183 andreas 27
#       include <QtAndroidExtras/QAndroidJniObject>
28
#       include <QtAndroidExtras/QtAndroid>
216 andreas 29
#   else
30
#       include <QJniObject>
31
#       include <QCoreApplication>
183 andreas 32
#   endif
33
#   include <android/log.h>
182 andreas 34
#endif
134 andreas 35
#include <unistd.h>
36
#ifndef __ANDROID__
183 andreas 37
#   include <fstab.h>
134 andreas 38
#endif
14 andreas 39
 
186 andreas 40
#if __cplusplus < 201402L
41
#   error "This module requires at least C++14 standard!"
42
#else
43
#   if __cplusplus < 201703L
44
#       include <experimental/filesystem>
45
namespace fs = std::experimental::filesystem;
46
#       warning "Support for C++14 and experimental filesystem will be removed in a future version!"
47
#   else
48
#       include <filesystem>
49
#       ifdef __ANDROID__
50
namespace fs = std::__fs::filesystem;
51
#       else
52
namespace fs = std::filesystem;
53
#       endif
54
#   endif
55
#endif
56
 
235 andreas 57
#ifdef __APPLE__
58
#   include <unistd.h>
59
#   ifndef HOST_NAME_MAX
60
#       ifdef MAXHOSTNAMELEN
61
#           define HOST_NAME_MAX    MAXHOSTNAMELEN
62
#       else
63
#           define HOST_NAME_MAX    64
64
#       endif   // MAXHOSTNAMELEN
65
#   endif       // HOST_NAME_MAX
66
#endif          // __APPLE__
67
 
3 andreas 68
#include "tpagemanager.h"
4 andreas 69
#include "tcolor.h"
3 andreas 70
#include "terror.h"
8 andreas 71
#include "ticons.h"
14 andreas 72
#include "tbutton.h"
8 andreas 73
#include "tprjresources.h"
11 andreas 74
#include "tresources.h"
271 andreas 75
#include "tresources.h"
71 andreas 76
#include "tsystemsound.h"
77
#include "tvalidatefile.h"
122 andreas 78
#include "ttpinit.h"
211 andreas 79
#include "tconfig.h"
299 andreas 80
#include "tlock.h"
336 andreas 81
#include "tintborder.h"
264 andreas 82
#ifdef Q_OS_IOS
83
#include "ios/tiosbattery.h"
84
#endif
326 andreas 85
#if TESTMODE == 1
86
#include "testmode.h"
87
#endif
3 andreas 88
 
89
using std::vector;
90
using std::string;
11 andreas 91
using std::map;
92
using std::pair;
93
using std::to_string;
14 andreas 94
using std::thread;
95
using std::atomic;
96
using std::mutex;
21 andreas 97
using std::bind;
3 andreas 98
 
8 andreas 99
TIcons *gIcons = nullptr;
100
TPrjResources *gPrjResources = nullptr;
14 andreas 101
TPageManager *gPageManager = nullptr;
169 andreas 102
//std::vector<amx::ANET_COMMAND> TPageManager::mCommands;
103
 
14 andreas 104
extern amx::TAmxNet *gAmxNet;
90 andreas 105
extern std::atomic<bool> _netRunning;
92 andreas 106
extern bool _restart_;                          //!< If this is set to true then the whole program will start over.
8 andreas 107
 
21 andreas 108
bool prg_stopped = false;
14 andreas 109
 
37 andreas 110
#ifdef __ANDROID__
255 andreas 111
string javaJStringToString(JNIEnv *env, jstring str)
112
{
113
    if (!str)
114
        return string();
115
 
116
    const jclass stringClass = env->GetObjectClass(str);
117
    const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
118
    const jbyteArray stringJbytes = (jbyteArray) env->CallObjectMethod(str, getBytes, env->NewStringUTF("UTF-8"));
119
 
120
    size_t length = (size_t) env->GetArrayLength(stringJbytes);
121
    jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL);
122
 
123
    string ret = std::string((char *)pBytes, length);
124
    env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT);
125
 
126
    env->DeleteLocalRef(stringJbytes);
127
    env->DeleteLocalRef(stringClass);
128
    return ret;
129
}
130
 
38 andreas 131
JNIEXPORT void JNICALL Java_org_qtproject_theosys_BatteryState_informBatteryStatus(JNIEnv *, jclass, jint level, jboolean charging, jint chargeType)
132
{
61 andreas 133
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_BatteryState_informBatteryStatus(JNIEnv *, jclass, jint level, jboolean charging, jint chargeType)");
134
 
38 andreas 135
    if (gPageManager)
136
        gPageManager->informBatteryStatus(level, charging, chargeType);
137
}
138
 
36 andreas 139
JNIEXPORT void JNICALL Java_org_qtproject_theosys_NetworkStatus_informTPanelNetwork(JNIEnv */*env*/, jclass /*clazz*/, jboolean conn, jint level, jint type)
140
{
61 andreas 141
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_NetworkStatus_informTPanelNetwork(JNIEnv */*env*/, jclass /*clazz*/, jboolean conn, jint level, jint type)");
365 andreas 142
 
143
    //Call native side conterpart
144
    if (gPageManager)
36 andreas 145
        gPageManager->informTPanelNetwork(conn, level, type);
146
}
47 andreas 147
 
61 andreas 148
JNIEXPORT void JNICALL Java_org_qtproject_theosys_PhoneCallState_informPhoneState(JNIEnv *env, jclass, jboolean call, jstring pnumber)
47 andreas 149
{
61 andreas 150
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_PhoneCallState_informPhoneState(JNIEnv *env, jclass, jboolean call, jstring pnumber)");
151
 
152
    string phoneNumber;
153
 
154
    if (pnumber)
255 andreas 155
        phoneNumber = javaJStringToString(env, pnumber);
61 andreas 156
 
157
    if (gPageManager)
158
        gPageManager->informPhoneState(call, phoneNumber);
47 andreas 159
}
160
 
61 andreas 161
JNIEXPORT void JNICALL Java_org_qtproject_theosys_Logger_logger(JNIEnv *env, jclass, jint mode, jstring msg)
47 andreas 162
{
163
    if (!msg)
164
        return;
165
 
255 andreas 166
    string ret = javaJStringToString(env, msg);
47 andreas 167
 
61 andreas 168
    try
169
    {
170
        if (TStreamError::checkFilter(mode))
260 andreas 171
        {
172
            *TError::Current()->getStream() << TError::append(mode) << ret << std::endl;
173
            TStreamError::resetFlags();
174
        }
61 andreas 175
    }
176
    catch (std::exception& e)
177
    {
178
        __android_log_print(ANDROID_LOG_ERROR, "tpanel", "%s", e.what());
179
    }
47 andreas 180
}
130 andreas 181
 
182
JNIEXPORT void JNICALL Java_org_qtproject_theosys_Orientation_informTPanelOrientation(JNIEnv */*env*/, jclass /*clazz*/, jint orientation)
183
{
184
    DECL_TRACER("Java_org_qtproject_theosys_Orientation_informTPanelOrientation(JNIEnv */*env*/, jclass /*clazz*/, jint orientation)");
185
 
134 andreas 186
    if (!gPageManager)
187
        return;
188
 
189
    if (gPageManager->onOrientationChange())
130 andreas 190
        gPageManager->onOrientationChange()(orientation);
134 andreas 191
 
192
    gPageManager->setOrientation(orientation);
193
 
194
    if (gPageManager->getInformOrientation())
195
        gPageManager->sendOrientation();
130 andreas 196
}
255 andreas 197
 
198
/* -------- Settings -------- */
256 andreas 199
 
200
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_saveSettings(JNIEnv *env, jclass clazz)
255 andreas 201
{
256 andreas 202
    DECL_TRACER("Java_org_qtproject_theosys_SettingsActivity_saveSettings(JNIEnv *env, jclass clazz)");
255 andreas 203
 
256 andreas 204
    Q_UNUSED(env);
255 andreas 205
    Q_UNUSED(clazz);
206
 
259 andreas 207
    TConfig::setTemporary(true);
208
    string oldNetlinx = TConfig::getController();
209
    int oldPort = TConfig::getPort();
210
    int oldChannelID = TConfig::getChannel();
211
    string oldSurface = TConfig::getFtpSurface();
212
    bool oldToolbarSuppress = TConfig::getToolbarSuppress();
213
    bool oldToolbarForce = TConfig::getToolbarForce();
214
    TConfig::setTemporary(false);
215
    MSG_DEBUG("Old values:\n" <<
216
              "   NetLinx: " << oldNetlinx << "\n" <<
217
              "   Port:    " << oldPort << "\n" <<
218
              "   Channel: " << oldChannelID << "\n" <<
219
              "   Surface: " << oldSurface << "\n" <<
220
              "   TB suppr:" << oldToolbarSuppress << "\n" <<
221
              "   TB force:" << oldToolbarForce);
256 andreas 222
    TConfig::saveSettings();
259 andreas 223
 
224
    MSG_DEBUG("New values:\n" <<
225
              "   NetLinx: " << TConfig::getController() << "\n" <<
226
              "   Port:    " << TConfig::getPort() << "\n" <<
227
              "   Channel: " << TConfig::getChannel() << "\n" <<
228
              "   Surface: " << TConfig::getFtpSurface() << "\n" <<
229
              "   TB suppr:" << TConfig::getToolbarSuppress() << "\n" <<
230
              "   TB force:" << TConfig::getToolbarForce());
231
 
232
    if (gPageManager && gPageManager->onSettingsChanged())
233
        gPageManager->onSettingsChanged()(oldNetlinx, oldPort, oldChannelID, oldSurface, oldToolbarSuppress, oldToolbarForce);
256 andreas 234
}
235
 
236
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxIp(JNIEnv *env, jclass clazz, jstring ip)
237
{
238
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxIp(JNIEnv *env, jclass clazz, jstring ip)");
239
 
240
    Q_UNUSED(clazz);
241
 
255 andreas 242
    string netlinxIp = javaJStringToString(env, ip);
243
 
244
    if (TConfig::getController() != netlinxIp)
245
        TConfig::saveController(netlinxIp);
246
}
247
 
256 andreas 248
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxPort(JNIEnv *env, jclass clazz, jint port)
255 andreas 249
{
256 andreas 250
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxPort(JNIEnv *env, jclass clazz, jint port)");
255 andreas 251
 
252
    Q_UNUSED(env);
253
    Q_UNUSED(clazz);
254
 
255
    if (port > 0 && port < 65535 && TConfig::getPort() != port)
256
        TConfig::savePort(port);
257
}
258
 
256 andreas 259
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxChannel(JNIEnv *env, jclass clazz, jint channel)
255 andreas 260
{
256 andreas 261
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxChannel(JNIEnv *env, jclass clazz, jint channel)");
255 andreas 262
 
263
    Q_UNUSED(env);
264
    Q_UNUSED(clazz);
265
 
266
    if (channel >= 10000 && channel < 20000 && TConfig::getChannel() != channel)
271 andreas 267
        TConfig::saveChannel(channel);
255 andreas 268
}
256 andreas 269
 
270
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxType(JNIEnv *env, jclass clazz, jstring type)
271
{
272
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxType(JNIEnv *env, jclass clazz, jstring type)");
273
 
274
    Q_UNUSED(clazz);
275
 
276
    string netlinxType = javaJStringToString(env, type);
277
 
278
    if (TConfig::getPanelType() != netlinxType)
279
        TConfig::savePanelType(netlinxType);
280
}
281
 
282
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxFtpUser(JNIEnv *env, jclass clazz, jstring user)
283
{
284
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxFtpUser(JNIEnv *env, jclass clazz, jstring user)");
285
 
286
    Q_UNUSED(clazz);
287
 
288
    string netlinxFtpUser = javaJStringToString(env, user);
289
 
290
    if (TConfig::getFtpUser() != netlinxFtpUser)
291
        TConfig::saveFtpUser(netlinxFtpUser);
292
}
293
 
294
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxFtpPassword(JNIEnv *env, jclass clazz, jstring pw)
295
{
296
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxFtpPassword(JNIEnv *env, jclass clazz, jstring pw)");
297
 
298
    Q_UNUSED(clazz);
299
 
300
    string netlinxPw = javaJStringToString(env, pw);
301
 
302
    if (TConfig::getFtpPassword() != netlinxPw)
303
        TConfig::saveFtpPassword(netlinxPw);
304
}
305
 
306
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxSurface(JNIEnv *env, jclass clazz, jstring surface)
307
{
308
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxIp(JNIEnv *env, jclass clazz, jstring surface)");
309
 
310
    Q_UNUSED(clazz);
311
 
312
    string netlinxSurface = javaJStringToString(env, surface);
313
 
314
    if (TConfig::getFtpSurface() != netlinxSurface)
315
        TConfig::saveFtpSurface(netlinxSurface);
316
}
317
 
318
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxFtpPassive(JNIEnv *env, jclass clazz, jboolean passive)
319
{
320
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxIp(JNIEnv *env, jclass clazz, jboolean passive)");
321
 
322
    Q_UNUSED(env);
323
    Q_UNUSED(clazz);
324
 
325
    if (TConfig::getFtpPassive() != passive)
326
        TConfig::saveFtpPassive(passive);
327
}
328
 
329
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setViewScale(JNIEnv *env, jclass clazz, jboolean scale)
330
{
331
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setViewScale(JNIEnv *env, jclass clazz, jboolean scale)");
332
 
333
    Q_UNUSED(env);
334
    Q_UNUSED(clazz);
335
 
336
    if (TConfig::getScale() != scale)
337
        TConfig::saveScale(scale);
338
}
339
 
340
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setViewToolbar(JNIEnv *env, jclass clazz, jboolean bar)
341
{
342
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setViewToolbar(JNIEnv *env, jclass clazz, jboolean bar)");
343
 
344
    Q_UNUSED(env);
345
    Q_UNUSED(clazz);
346
 
260 andreas 347
    if (TConfig::getToolbarSuppress() == bar)
348
        TConfig::saveToolbarSuppress(!bar);
256 andreas 349
}
350
 
351
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setViewToolbarForce(JNIEnv *env, jclass clazz, jboolean bar)
352
{
353
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setViewToolbarForce(JNIEnv *env, jclass clazz, jboolean bar)");
354
 
355
    Q_UNUSED(env);
356
    Q_UNUSED(clazz);
357
 
358
    if (TConfig::getToolbarForce() != bar)
359
        TConfig::saveToolbarForce(bar);
360
}
361
 
362
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setViewRotation(JNIEnv *env, jclass clazz, jboolean rotate)
363
{
364
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setViewRotation(JNIEnv *env, jclass clazz, jboolean rotate)");
365
 
366
    Q_UNUSED(env);
367
    Q_UNUSED(clazz);
368
 
369
    if (TConfig::getRotationFixed() != rotate)
370
        TConfig::setRotationFixed(rotate);
371
}
372
 
373
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundSystem(JNIEnv *env, jclass clazz, jstring sound)
374
{
375
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundSystem(JNIEnv *env, jclass clazz, jstring sound)");
376
 
377
    Q_UNUSED(clazz);
378
 
379
    string s = javaJStringToString(env, sound);
380
 
381
    if (TConfig::getSystemSound() != s)
382
        TConfig::saveSystemSoundFile(s);
383
}
384
 
385
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundSingle(JNIEnv *env, jclass clazz, jstring sound)
386
{
387
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundSingle(JNIEnv *env, jclass clazz, jstring sound)");
388
 
389
    Q_UNUSED(clazz);
390
 
391
    string s = javaJStringToString(env, sound);
392
 
393
    if (TConfig::getSingleBeepSound() != s)
394
        TConfig::saveSingleBeepFile(s);
395
}
396
 
397
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundDouble(JNIEnv *env, jclass clazz, jstring sound)
398
{
399
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundDouble(JNIEnv *env, jclass clazz, jstring sound)");
400
 
401
    Q_UNUSED(clazz);
402
 
403
    string s = javaJStringToString(env, sound);
404
 
405
    if (TConfig::getDoubleBeepSound() != s)
406
        TConfig::saveDoubleBeepFile(s);
407
}
408
 
409
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundEnable(JNIEnv *env, jclass clazz, jboolean sound)
410
{
411
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundEnable(JNIEnv *env, jclass clazz, jboolean sound)");
412
 
413
    Q_UNUSED(env);
414
    Q_UNUSED(clazz);
415
 
416
    if (TConfig::getSystemSoundState() != sound)
417
        TConfig::saveSystemSoundState(sound);
418
}
419
 
420
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundVolume(JNIEnv *env, jclass clazz, jint sound)
421
{
422
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundVolume(JNIEnv *env, jclass clazz, jint sound)");
423
 
424
    Q_UNUSED(env);
425
    Q_UNUSED(clazz);
426
 
427
    if (TConfig::getSystemVolume() != sound)
428
        TConfig::saveSystemVolume(sound);
429
}
430
 
431
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundGain(JNIEnv *env, jclass clazz, jint sound)
432
{
433
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundGain(JNIEnv *env, jclass clazz, jint sound)");
434
 
435
    Q_UNUSED(env);
436
    Q_UNUSED(clazz);
437
 
438
    if (TConfig::getSystemGain() != sound)
439
        TConfig::saveSystemGain(sound);
440
}
257 andreas 441
 
442
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipProxy(JNIEnv *env, jclass clazz, jstring sip)
443
{
444
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipProxy(JNIEnv *env, jclass clazz, jstring sip)");
445
 
446
    Q_UNUSED(clazz);
447
 
448
    string sipStr = javaJStringToString(env, sip);
449
 
450
    if (TConfig::getSIPproxy() != sipStr)
451
        TConfig::setSIPproxy(sipStr);
452
}
453
 
454
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipPort(JNIEnv *env, jclass clazz, jint sip)
455
{
456
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipPort(JNIEnv *env, jclass clazz, jint sip)");
457
 
458
    Q_UNUSED(env);
459
    Q_UNUSED(clazz);
460
 
461
    if (TConfig::getSIPport() != sip)
462
        TConfig::setSIPport(sip);
463
}
464
 
465
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipTlsPort(JNIEnv *env, jclass clazz, jint sip)
466
{
467
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipTlsPort(JNIEnv *env, jclass clazz, jint sip)");
468
 
469
    Q_UNUSED(env);
470
    Q_UNUSED(clazz);
471
 
472
    if (TConfig::getSIPportTLS() != sip)
473
        TConfig::setSIPportTLS(sip);
474
}
475
 
476
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipStun(JNIEnv *env, jclass clazz, jstring sip)
477
{
478
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipStun(JNIEnv *env, jclass clazz, jstring sip)");
479
 
480
    Q_UNUSED(clazz);
481
 
482
    string sipStr = javaJStringToString(env, sip);
483
 
484
    if (TConfig::getSIPstun() != sipStr)
485
        TConfig::setSIPstun(sipStr);
486
}
487
 
488
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipDomain(JNIEnv *env, jclass clazz, jstring sip)
489
{
490
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipDomain(JNIEnv *env, jclass clazz, jstring sip)");
491
 
492
    Q_UNUSED(clazz);
493
 
494
    string sipStr = javaJStringToString(env, sip);
495
 
496
    if (TConfig::getSIPdomain() != sipStr)
497
        TConfig::setSIPdomain(sipStr);
498
}
499
 
500
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipUser(JNIEnv *env, jclass clazz, jstring sip)
501
{
502
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipUser(JNIEnv *env, jclass clazz, jstring sip)");
503
 
504
    Q_UNUSED(clazz);
505
 
506
    string sipStr = javaJStringToString(env, sip);
507
 
508
    if (TConfig::getSIPuser() != sipStr)
509
        TConfig::setSIPuser(sipStr);
510
}
511
 
512
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipPassword(JNIEnv *env, jclass clazz, jstring sip)
513
{
514
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipPassword(JNIEnv *env, jclass clazz, jstring sip)");
515
 
516
    Q_UNUSED(clazz);
517
 
518
    string sipStr = javaJStringToString(env, sip);
519
 
520
    if (TConfig::getSIPpassword() != sipStr)
521
        TConfig::setSIPpassword(sipStr);
522
}
523
 
524
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipIpv4(JNIEnv *env, jclass clazz, jboolean sip)
525
{
526
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipIpv4(JNIEnv *env, jclass clazz, jboolean sip)");
527
 
528
    Q_UNUSED(env);
529
    Q_UNUSED(clazz);
530
 
531
    if (TConfig::getSIPnetworkIPv4() != sip)
532
        TConfig::setSIPnetworkIPv4(sip);
533
}
534
 
535
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipIpv6(JNIEnv *env, jclass clazz, jboolean sip)
536
{
537
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipIpv6(JNIEnv *env, jclass clazz, jboolean sip)");
538
 
539
    Q_UNUSED(env);
540
    Q_UNUSED(clazz);
541
 
542
    if (TConfig::getSIPnetworkIPv6() != sip)
543
        TConfig::setSIPnetworkIPv6(sip);
544
}
545
 
546
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipEnabled(JNIEnv *env, jclass clazz, jboolean sip)
547
{
548
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipEnabled(JNIEnv *env, jclass clazz, jboolean sip)");
549
 
550
    Q_UNUSED(env);
551
    Q_UNUSED(clazz);
552
 
553
    if (TConfig::getSIPstatus() != sip)
554
        TConfig::setSIPstatus(sip);
555
}
556
 
557
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipIphone(JNIEnv *env, jclass clazz, jboolean sip)
558
{
559
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipIphone(JNIEnv *env, jclass clazz, jboolean sip)");
560
 
561
    Q_UNUSED(env);
562
    Q_UNUSED(clazz);
563
 
564
    if (TConfig::getSIPiphone() != sip)
565
        TConfig::setSIPiphone(sip);
566
}
567
 
568
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogInfo(JNIEnv *env, jclass clazz, jboolean log)
569
{
570
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogInfo(JNIEnv *env, jclass clazz, jboolean log)");
571
 
572
    Q_UNUSED(env);
573
    Q_UNUSED(clazz);
574
 
575
    uint logSwitch = (log ? HLOG_INFO : 0);
576
 
577
    if ((TConfig::getLogLevelBits() & HLOG_INFO) != logSwitch)
578
    {
579
        if (!(TConfig::getLogLevelBits() & HLOG_INFO))
580
            TConfig::saveLogLevel(TConfig::getLogLevelBits() | HLOG_INFO);
581
        else
582
            TConfig::saveLogLevel(TConfig::getLogLevelBits() ^ HLOG_INFO);
583
    }
584
}
585
 
586
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogWarning(JNIEnv *env, jclass clazz, jboolean log)
587
{
588
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogWarning(JNIEnv *env, jclass clazz, jboolean log)");
589
 
590
    Q_UNUSED(env);
591
    Q_UNUSED(clazz);
592
 
593
    uint logSwitch = (log ? HLOG_WARNING : 0);
594
 
595
    if ((TConfig::getLogLevelBits() & HLOG_WARNING) != logSwitch)
596
    {
597
        if (!(TConfig::getLogLevelBits() & HLOG_INFO))
598
            TConfig::saveLogLevel(TConfig::getLogLevelBits() | HLOG_WARNING);
599
        else
600
            TConfig::saveLogLevel(TConfig::getLogLevelBits() ^ HLOG_WARNING);
601
    }
602
}
603
 
604
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogError(JNIEnv *env, jclass clazz, jboolean log)
605
{
606
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogError(JNIEnv *env, jclass clazz, jboolean log)");
607
 
608
    Q_UNUSED(env);
609
    Q_UNUSED(clazz);
610
 
611
    uint logSwitch = (log ? HLOG_ERROR : 0);
612
 
613
    if ((TConfig::getLogLevelBits() & HLOG_ERROR) != logSwitch)
614
    {
615
        if (!(TConfig::getLogLevelBits() & HLOG_ERROR))
616
            TConfig::saveLogLevel(TConfig::getLogLevelBits() | HLOG_ERROR);
617
        else
618
            TConfig::saveLogLevel(TConfig::getLogLevelBits() ^ HLOG_ERROR);
619
    }
620
}
621
 
622
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogTrace(JNIEnv *env, jclass clazz, jboolean log)
623
{
624
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogTrace(JNIEnv *env, jclass clazz, jboolean log)");
625
 
626
    Q_UNUSED(env);
627
    Q_UNUSED(clazz);
628
 
629
    uint logSwitch = (log ? HLOG_TRACE : 0);
630
 
631
    if ((TConfig::getLogLevelBits() & HLOG_TRACE) != logSwitch)
632
    {
633
        if (!(TConfig::getLogLevelBits() & HLOG_TRACE))
634
            TConfig::saveLogLevel(TConfig::getLogLevelBits() | HLOG_TRACE);
635
        else
636
            TConfig::saveLogLevel(TConfig::getLogLevelBits() ^ HLOG_TRACE);
637
    }
638
}
639
 
640
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogDebug(JNIEnv *env, jclass clazz, jboolean log)
641
{
642
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogDebug(JNIEnv *env, jclass clazz, jboolean log)");
643
 
644
    Q_UNUSED(env);
645
    Q_UNUSED(clazz);
646
 
647
    uint logSwitch = (log ? HLOG_DEBUG : 0);
648
 
649
    if ((TConfig::getLogLevelBits() & HLOG_DEBUG) != logSwitch)
650
    {
651
        if (!(TConfig::getLogLevelBits() & HLOG_DEBUG))
652
            TConfig::saveLogLevel(TConfig::getLogLevelBits() | HLOG_DEBUG);
653
        else
654
            TConfig::saveLogLevel(TConfig::getLogLevelBits() ^ HLOG_DEBUG);
655
    }
656
}
657
 
658
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogProfile(JNIEnv *env, jclass clazz, jboolean log)
659
{
660
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogProfile(JNIEnv *env, jclass clazz, jboolean log)");
661
 
662
    Q_UNUSED(env);
663
    Q_UNUSED(clazz);
664
 
665
    if (TConfig::getProfiling() != log)
666
        TConfig::saveProfiling(log);
667
}
668
 
669
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogLongFormat(JNIEnv *env, jclass clazz, jboolean log)
670
{
671
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogLongFormat(JNIEnv *env, jclass clazz, jboolean log)");
672
 
673
    Q_UNUSED(env);
674
    Q_UNUSED(clazz);
675
 
676
    if (TConfig::isLongFormat() != log)
677
        TConfig::saveFormat(log);
678
}
679
 
680
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogEnableFile(JNIEnv *env, jclass clazz, jboolean log)
681
{
682
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogEnableFile(JNIEnv *env, jclass clazz, jboolean log)");
683
 
684
    Q_UNUSED(env);
685
    Q_UNUSED(clazz);
686
 
383 andreas 687
    TConfig::setLogFileEnabled(log);
385 andreas 688
    TStreamError::setLogFileEnabled(log);
689
    string logFile = TConfig::getLogFile();
383 andreas 690
 
385 andreas 691
    if (log && !logFile.empty() && fs::is_regular_file(logFile))
692
        TStreamError::setLogFile(logFile);
693
    else if (!log)
694
        TStreamError::setLogFile("");
383 andreas 695
 
385 andreas 696
    __android_log_print(ANDROID_LOG_DEBUG, "tpanel", "JAVA::setLogEnableFile: Logfile was %s", (log ? "ENABLED" : "DISABLED"));
257 andreas 697
}
698
 
699
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogFile(JNIEnv *env, jclass clazz, jstring log)
700
{
701
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogFile(JNIEnv *env, jclass clazz, jstring sip)");
702
 
703
    Q_UNUSED(clazz);
704
 
705
    string logStr = javaJStringToString(env, log);
706
 
707
    if (TConfig::getLogFile() != logStr)
385 andreas 708
    {
257 andreas 709
        TConfig::saveLogFile(logStr);
385 andreas 710
        __android_log_print(ANDROID_LOG_DEBUG, "tpanel", "JAVA::setLogFile: Logfile set to: %s", logStr.c_str());
711
 
712
        if (fs::is_regular_file(logStr))
713
            TStreamError::setLogFile(logStr);
714
        else
715
        {
716
            TStreamError::setLogFile("");
717
            __android_log_print(ANDROID_LOG_WARN, "tpanel", "JAVA::setLogFile: Logfile \"%s\" is not accessible!", logStr.c_str());
718
        }
719
    }
257 andreas 720
}
37 andreas 721
#endif
36 andreas 722
 
3 andreas 723
TPageManager::TPageManager()
724
{
299 andreas 725
    TLOCKER(surface_mutex);
3 andreas 726
    DECL_TRACER("TPageManager::TPageManager()");
727
 
14 andreas 728
    gPageManager = this;
122 andreas 729
    TTPInit *tinit = new TTPInit;
186 andreas 730
    string projectPath = TConfig::getProjectPath();
197 andreas 731
    string pp = projectPath + "/prj.xma";
186 andreas 732
 
733
    tinit->setPath(projectPath);
156 andreas 734
    bool haveSurface = false;
122 andreas 735
 
736
    if (tinit->isVirgin())
156 andreas 737
        haveSurface = tinit->loadSurfaceFromController();
738
    else
739
        haveSurface = true;
122 andreas 740
 
197 andreas 741
    if (!fs::exists(pp))
193 andreas 742
    {
197 andreas 743
        projectPath = TConfig::getSystemProjectPath();
744
        pp = projectPath + "/prj.xma";
193 andreas 745
        mSetupActive = true;
746
    }
186 andreas 747
 
156 andreas 748
    if (!haveSurface)
749
    {
271 andreas 750
        if (!isValidFile(pp))
751
            tinit->reinitialize();
156 andreas 752
    }
159 andreas 753
    else
754
        tinit->makeSystemFiles();
156 andreas 755
 
122 andreas 756
    delete tinit;
156 andreas 757
 
43 andreas 758
    // Read the AMX panel settings.
186 andreas 759
    mTSettings = new TSettings(projectPath);
3 andreas 760
 
761
    if (TError::isError())
14 andreas 762
    {
23 andreas 763
        MSG_ERROR("Settings were not read successfull!");
3 andreas 764
        return;
14 andreas 765
    }
3 andreas 766
 
193 andreas 767
    if (!mSetupActive)
768
    {
197 andreas 769
        mSystemSettings = new TSettings(TConfig::getSystemProjectPath());
193 andreas 770
 
771
        if (TError::isError())
772
        {
773
            MSG_ERROR("System settings were not read successfull!");
774
            delete mTSettings;
775
            mTSettings = nullptr;
776
            return;
777
        }
778
    }
779
    else
780
        mSystemSettings = mTSettings;
781
 
178 andreas 782
    // Set the panel type from the project information
193 andreas 783
    if (!mSetupActive)
784
        TConfig::savePanelType(mTSettings->getPanelType());
178 andreas 785
 
122 andreas 786
    readMap();  // Start the initialisation of the AMX part.
787
 
8 andreas 788
    gPrjResources = new TPrjResources(mTSettings->getResourcesList());
4 andreas 789
    mPalette = new TPalette();
790
    vector<PALETTE_SETUP> pal = mTSettings->getSettings().palettes;
791
 
83 andreas 792
    if (pal.size() > 0)
793
    {
794
        vector<PALETTE_SETUP>::iterator iterPal;
4 andreas 795
 
118 andreas 796
        for (iterPal = pal.begin(); iterPal != pal.end(); ++iterPal)
83 andreas 797
            mPalette->initialize(iterPal->file);
798
    }
799
 
4 andreas 800
    if (!TError::isError())
801
        TColor::setPalette(mPalette);
802
 
7 andreas 803
    mFonts = new TFont();
804
 
805
    if (TError::isError())
806
    {
807
        MSG_ERROR("Initializing fonts was not successfull!");
808
    }
809
 
8 andreas 810
    gIcons = new TIcons();
811
 
812
    if (TError::isError())
813
    {
814
        MSG_ERROR("Initializing icons was not successfull!");
815
    }
816
 
3 andreas 817
    mPageList = new TPageList();
32 andreas 818
    mExternal = new TExternal();
4 andreas 819
    PAGELIST_T page;
820
 
194 andreas 821
    if (!mSetupActive)
3 andreas 822
    {
194 andreas 823
        if (!mTSettings->getSettings().powerUpPage.empty())
14 andreas 824
        {
194 andreas 825
            if (readPage(mTSettings->getSettings().powerUpPage))
826
            {
827
                MSG_TRACE("Found power up page " << mTSettings->getSettings().powerUpPage);
828
                page = findPage(mTSettings->getSettings().powerUpPage);
829
                mActualPage = page.pageID;
830
            }
14 andreas 831
        }
194 andreas 832
        else
833
        {
834
            MSG_WARNING("No power up page defined! Setting default page to 1.");
835
            mActualPage = 1;
836
        }
3 andreas 837
    }
23 andreas 838
    else
839
    {
194 andreas 840
        if (!mSystemSettings->getSettings().powerUpPage.empty())
841
        {
842
            if (readPage(mSystemSettings->getSettings().powerUpPage))
843
            {
844
                MSG_TRACE("Found power up page " << mSystemSettings->getSettings().powerUpPage);
845
                page = findPage(mSystemSettings->getSettings().powerUpPage);
846
                mActualPage = page.pageID;
847
            }
848
        }
849
        else
850
        {
851
            MSG_WARNING("No power up page defined! Setting default page to 5001.");
852
            mActualPage = 5001;
853
        }
23 andreas 854
    }
3 andreas 855
 
4 andreas 856
    TPage *pg = getPage(mActualPage);
857
 
194 andreas 858
    vector<string> popups;
3 andreas 859
 
194 andreas 860
    if (!mSetupActive)
861
        popups = mTSettings->getSettings().powerUpPopup;
862
    else
863
        popups = mSystemSettings->getSettings().powerUpPopup;
864
 
83 andreas 865
    if (popups.size() > 0)
3 andreas 866
    {
83 andreas 867
        vector<string>::iterator iter;
868
 
118 andreas 869
        for (iter = popups.begin(); iter != popups.end(); ++iter)
14 andreas 870
        {
88 andreas 871
            if (readSubPage(*iter))
83 andreas 872
            {
88 andreas 873
                MSG_TRACE("Found power up popup " << *iter);
3 andreas 874
 
88 andreas 875
                if (pg)
876
                {
877
                    TSubPage *spage = getSubPage(*iter);
350 andreas 878
                    spage->setParent(pg->getHandle());
88 andreas 879
                    pg->addSubPage(spage);
880
                }
83 andreas 881
            }
4 andreas 882
        }
3 andreas 883
    }
11 andreas 884
 
73 andreas 885
    // Here we initialize the system resources like borders, cursors, sliders, ...
886
    mSystemDraw = new TSystemDraw(TConfig::getSystemPath(TConfig::BASE));
887
 
888
    // Here are the commands supported by this emulation.
13 andreas 889
    MSG_INFO("Registering commands ...");
318 andreas 890
    REG_CMD(doLEVON, "LEVON");  // Enable device to send level changes to the master.
891
    REG_CMD(doLEVOF, "LEVOF");  // Disable the device from sending level changes to the master.
892
    REG_CMD(doRXON, "RXON");    // Enable device to send STRING changes to the master.
893
    REG_CMD(doRXOF, "RXOF");    // Disable the device from sending STRING changes to the master.
147 andreas 894
    REG_CMD(doAFP, "@AFP");     // Flips to a page with the specified page name using an animated transition.
895
    REG_CMD(doAFP, "^AFP");     // Flips to a page with the specified page name using an animated transition.
38 andreas 896
    REG_CMD(doAPG, "@APG");     // Add a specific popup page to a specified popup group.
897
    REG_CMD(doCPG, "@CPG");     // Clear all popup pages from specified popup group.
898
    REG_CMD(doDPG, "@DPG");     // Delete a specific popup page from specified popup group if it exists
899
//    REG_CMD(doPDR, "@PDR");     // Set the popup location reset flag.
900
    REG_CMD(doPHE, "@PHE");     // Set the hide effect for the specified popup page to the named hide effect.
901
    REG_CMD(doPHP, "@PHP");     // Set the hide effect position.
902
    REG_CMD(doPHT, "@PHT");     // Set the hide effect time for the specified popup page.
903
    REG_CMD(doPPA, "@PPA");     // Close all popups on a specified page.
104 andreas 904
    REG_CMD(doPPA, "^PPA");     // G5: Close all popups on a specified page.
38 andreas 905
    REG_CMD(doPPF, "@PPF");     // Deactivate a specific popup page on either a specified page or the current page.
104 andreas 906
    REG_CMD(doPPF, "^PPF");     // G5: Deactivate a specific popup page on either a specified page or the current page.
38 andreas 907
    REG_CMD(doPPF, "PPOF");     // Deactivate a specific popup page on either a specified page or the current page
908
    REG_CMD(doPPG, "@PPG");     // Toggle a specific popup page on either a specified page or the current page.
104 andreas 909
    REG_CMD(doPPG, "^PPG");     // G5: Toggle a specific popup page on either a specified page or the current page.
38 andreas 910
    REG_CMD(doPPG, "PPOG");     // Toggle a specific popup page on either a specified page or the current page.
911
    REG_CMD(doPPK, "@PPK");     // Kill a specific popup page from all pages.
104 andreas 912
    REG_CMD(doPPK, "^PPK");     // G5: Kill a specific popup page from all pages.
38 andreas 913
    REG_CMD(doPPM, "@PPM");     // Set the modality of a specific popup page to Modal or NonModal.
104 andreas 914
    REG_CMD(doPPM, "^PPM");     // G5: Set the modality of a specific popup page to Modal or NonModal.
38 andreas 915
    REG_CMD(doPPN, "@PPN");     // Activate a specific popup page to launch on either a specified page or the current page.
104 andreas 916
    REG_CMD(doPPN, "^PPN");     // G5: Activate a specific popup page to launch on either a specified page or the current page.
38 andreas 917
    REG_CMD(doPPN, "PPON");     // Activate a specific popup page to launch on either a specified page or the current page.
918
    REG_CMD(doPPT, "@PPT");     // Set a specific popup page to timeout within a specified time.
104 andreas 919
    REG_CMD(doPPT, "^PPT");     // G5: Set a specific popup page to timeout within a specified time.
38 andreas 920
    REG_CMD(doPPX, "@PPX");     // Close all popups on all pages.
104 andreas 921
    REG_CMD(doPPX, "^PPX");     // G5: Close all popups on all pages.
38 andreas 922
    REG_CMD(doPSE, "@PSE");     // Set the show effect for the specified popup page to the named show effect.
923
    REG_CMD(doPSP, "@PSP");     // Set the show effect position.
924
    REG_CMD(doPST, "@PST");     // Set the show effect time for the specified popup page.
925
    REG_CMD(doPAGE, "PAGE");    // Flip to a specified page.
104 andreas 926
    REG_CMD(doPAGE, "^PGE");    // G5: Flip to a specified page.
11 andreas 927
 
38 andreas 928
    REG_CMD(doANI, "^ANI");     // Run a button animation (in 1/10 second).
929
    REG_CMD(doAPF, "^APF");     // Add page flip action to a button if it does not already exist.
43 andreas 930
    REG_CMD(doBAT, "^BAT");     // Append non-unicode text.
60 andreas 931
    REG_CMD(doBAU, "^BAU");     // Append unicode text. Same format as ^UNI.
43 andreas 932
    REG_CMD(doBCB, "^BCB");     // Set the border color.
82 andreas 933
    REG_CMD(getBCB, "?BCB");    // Get the current border color.
60 andreas 934
    REG_CMD(doBCF, "^BCF");     // Set the fill color to the specified color.
82 andreas 935
    REG_CMD(getBCF, "?BCF");    // Get the current fill color.
60 andreas 936
    REG_CMD(doBCT, "^BCT");     // Set the text color to the specified color.
82 andreas 937
    REG_CMD(getBCT, "?BCT");    // Get the current text color.
60 andreas 938
    REG_CMD(doBDO, "^BDO");     // Set the button draw order
939
    REG_CMD(doBFB, "^BFB");     // Set the feedback type of the button.
224 andreas 940
    REG_CMD(doBIM, "^BIM");     // Set the input mask for the specified address
149 andreas 941
    REG_CMD(doBMC, "^BMC");     // Button copy command.
942
    REG_CMD(doBMF, "^BMF");     // Button Modify Command - Set any/all button parameters by sending embedded codes and data.
106 andreas 943
//    REG_CMD(doBMI, "^BMI");    // Set the button mask image.
149 andreas 944
    REG_CMD(doBML, "^BML");     // Set the maximum length of the text area button.
38 andreas 945
    REG_CMD(doBMP, "^BMP");     // Assign a picture to those buttons with a defined addressrange.
82 andreas 946
    REG_CMD(getBMP, "?BMP");    // Get the current bitmap name.
38 andreas 947
    REG_CMD(doBOP, "^BOP");     // Set the button opacity.
106 andreas 948
    REG_CMD(getBOP, "?BOP");    // Get the button opacity.
60 andreas 949
    REG_CMD(doBOR, "^BOR");     // Set a border to a specific border style.
107 andreas 950
    REG_CMD(doBOS, "^BOS");     // Set the button to display either a Video or Non-Video window.
60 andreas 951
    REG_CMD(doBRD, "^BRD");     // Set the border of a button state/states.
107 andreas 952
    REG_CMD(getBRD, "?BRD");    // Get the border of a button state/states.
103 andreas 953
//    REG_CMD(doBSF, "^BSF");     // Set the focus to the text area.
38 andreas 954
    REG_CMD(doBSP, "^BSP");     // Set the button size and position.
107 andreas 955
    REG_CMD(doBSM, "^BSM");     // Submit text for text area buttons.
956
    REG_CMD(doBSO, "^BSO");     // Set the sound played when a button is pressed.
38 andreas 957
    REG_CMD(doBWW, "^BWW");     // Set the button word wrap feature to those buttons with a defined address range.
108 andreas 958
    REG_CMD(getBWW, "?BWW");    // Get the button word wrap feature to those buttons with a defined address range.
38 andreas 959
    REG_CMD(doCPF, "^CPF");     // Clear all page flips from a button.
960
    REG_CMD(doDPF, "^DPF");     // Delete page flips from button if it already exists.
961
    REG_CMD(doENA, "^ENA");     // Enable or disable buttons with a set variable text range.
962
    REG_CMD(doFON, "^FON");     // Set a font to a specific Font ID value for those buttons with a range.
108 andreas 963
    REG_CMD(getFON, "?FON");    // Get the current font index.
388 andreas 964
    REG_CMD(doGDI, "^GDI");     // Change the bargraph drag increment.
103 andreas 965
//    REG_CMD(doGDV, "^GDV");     // Invert the joystick axis to move the origin to another corner.
60 andreas 966
    REG_CMD(doGLH, "^GLH");     // Change the bargraph upper limit.
967
    REG_CMD(doGLL, "^GLL");     // Change the bargraph lower limit.
388 andreas 968
    REG_CMD(doGRD, "^GRD");     // Change the bargraph ramp down time.
969
    REG_CMD(doGRU, "^GRU");     // Change the bargraph ramp up time.
361 andreas 970
    REG_CMD(doGSN, "^GSN");     // Set slider/cursor name.
108 andreas 971
    REG_CMD(doGSC, "^GSC");     // Change the bargraph slider color or joystick cursor color.
38 andreas 972
    REG_CMD(doICO, "^ICO");     // Set the icon to a button.
108 andreas 973
    REG_CMD(getICO, "?ICO");    // Get the current icon index.
974
    REG_CMD(doJSB, "^JSB");     // Set bitmap/picture alignment using a numeric keypad layout for those buttons with a defined address range.
975
    REG_CMD(getJSB, "?JSB");    // Get the current bitmap justification.
976
    REG_CMD(doJSI, "^JSI");     // Set icon alignment using a numeric keypad layout for those buttons with a defined address range.
977
    REG_CMD(getJSI, "?JSI");    // Get the current icon justification.
978
    REG_CMD(doJST, "^JST");     // Set text alignment using a numeric keypad layout for those buttons with a defined address range.
979
    REG_CMD(getJST, "?JST");    // Get the current text justification.
38 andreas 980
    REG_CMD(doSHO, "^SHO");     // Show or hide a button with a set variable text range.
108 andreas 981
    REG_CMD(doTEC, "^TEC");     // Set the text effect color for the specified addresses/states to the specified color.
982
    REG_CMD(getTEC, "?TEC");    // Get the current text effect color.
110 andreas 983
    REG_CMD(doTEF, "^TEF");     // Set the text effect. The Text Effect is specified by name and can be found in TPD4.
984
    REG_CMD(getTEF, "?TEF");    // Get the current text effect name.
103 andreas 985
//    REG_CMD(doTOP, "^TOP");     // Send events to the Master as string events.
38 andreas 986
    REG_CMD(doTXT, "^TXT");     // Assign a text string to those buttons with a defined address range.
110 andreas 987
    REG_CMD(getTXT, "?TXT");    // Get the current text information.
104 andreas 988
    REG_CMD(doUNI, "^UNI");     // Set Unicode text.
989
    REG_CMD(doUTF, "^UTF");     // G5: Set button state text using UTF-8 text command.
148 andreas 990
    REG_CMD(doVTP, "^VTP");     // Simulates a touch/release/pulse at the given coordinate
14 andreas 991
 
103 andreas 992
//    REG_CMD(doLPC, "^LPC");     // Clear all users from the User Access Passwords list on the Password Setup page.
993
//    REG_CMD(doLPR, "^LPR");     // Remove a given user from the User Access Passwords list on the Password Setup page.
994
//    REG_CMD(doLPS, "^LPS");     // Set the user name and password.
995
 
111 andreas 996
    REG_CMD(doKPS, "^KPS");     // Set the keyboard passthru.
997
    REG_CMD(doVKS, "^VKS");     // Send one or more virtual key strokes to the G4 application.
103 andreas 998
 
999
//    REG_CMD(doPWD, "@PWD");     // Set the page flip password.
1000
//    REG_CMD(doPWD, "^PWD");     // Set the page flip password.
1001
 
38 andreas 1002
    REG_CMD(doBBR, "^BBR");     // Set the bitmap of a button to use a particular resource.
97 andreas 1003
    REG_CMD(doRAF, "^RAF");     // Add new resources
1004
    REG_CMD(doRFR, "^RFR");     // Force a refresh for a given resource.
38 andreas 1005
    REG_CMD(doRMF, "^RMF");     // Modify an existing resource.
111 andreas 1006
    REG_CMD(doRSR, "^RSR");     // Change the refresh rate for a given resource.
21 andreas 1007
 
108 andreas 1008
    REG_CMD(doABEEP, "ABEEP");  // Output a single beep even if beep is Off.
1009
    REG_CMD(doADBEEP, "ADBEEP");// Output a double beep even if beep is Off.
62 andreas 1010
    REG_CMD(doAKB, "@AKB");     // Pop up the keyboard icon and initialize the text string to that specified.
1011
    REG_CMD(doAKEYB, "AKEYB");  // Pop up the keyboard icon and initialize the text string to that specified.
1012
    REG_CMD(doAKP, "@AKP");     // Pop up the keypad icon and initialize the text string to that specified.
1013
    REG_CMD(doAKEYP, "AKEYP");  // Pop up the keypad icon and initialize the text string to that specified.
63 andreas 1014
    REG_CMD(doAKEYR, "AKEYR");  // Remove the Keyboard/Keypad.
1015
    REG_CMD(doAKR, "@AKR");     // Remove the Keyboard/Keypad.
71 andreas 1016
    REG_CMD(doBEEP, "BEEP");    // Play a single beep.
104 andreas 1017
    REG_CMD(doBEEP, "^ABP");    // G5: Play a single beep.
71 andreas 1018
    REG_CMD(doDBEEP, "DBEEP");  // Play a double beep.
104 andreas 1019
    REG_CMD(doDBEEP, "^ADB");   // G5: Play a double beep.
62 andreas 1020
    REG_CMD(doEKP, "@EKP");     // Pop up the keypad icon and initialize the text string to that specified.
63 andreas 1021
    REG_CMD(doPKP, "@PKB");     // Present a private keyboard.
1022
    REG_CMD(doPKP, "PKEYP");    // Present a private keypad.
1023
    REG_CMD(doPKP, "@PKP");     // Present a private keypad.
64 andreas 1024
    REG_CMD(doSetup, "SETUP");  // Send panel to SETUP page.
104 andreas 1025
    REG_CMD(doSetup, "^STP");   // G5: Open setup page.
64 andreas 1026
    REG_CMD(doShutdown, "SHUTDOWN");// Shut down the App
82 andreas 1027
    REG_CMD(doSOU, "@SOU");     // Play a sound file.
104 andreas 1028
    REG_CMD(doSOU, "^SOU");     // G5: Play a sound file.
326 andreas 1029
    REG_CMD(doMUT, "^MUT");     // G5: Panel Volume Mute
63 andreas 1030
    REG_CMD(doTKP, "@TKP");     // Present a telephone keypad.
104 andreas 1031
    REG_CMD(doTKP, "^TKP");     // G5: Bring up a telephone keypad.
63 andreas 1032
    REG_CMD(doTKP, "@VKB");     // Present a virtual keyboard
104 andreas 1033
    REG_CMD(doTKP, "^VKB");     // G5: Bring up a virtual keyboard.
129 andreas 1034
#ifndef _NOSIP_
103 andreas 1035
    // Here the SIP commands will take place
123 andreas 1036
    REG_CMD(doPHN, "^PHN");     // SIP commands
127 andreas 1037
    REG_CMD(getPHN, "?PHN");    // SIP state commands
129 andreas 1038
#endif
300 andreas 1039
    // SubView commands
1040
//    REG_CMD(doEPR, "^EPR");     // Execute Push on Release.
1041
//    REG_CMD(doSCE, "^SCE");     // Configures subpage custom events.
1042
//    REG_CMD(doSDR, "^SDR");     // Enabling subpage dynamic reordering.
318 andreas 1043
    REG_CMD(doSHA, "^SHA");     // Subpage Hide All Command
1044
    REG_CMD(doSHD, "^SHD");     // Hides subpage
1045
    REG_CMD(doSPD, "^SPD");     //  Set the padding between subpages on a subpage viewer button
300 andreas 1046
    REG_CMD(doSSH, "^SSH");     // Subpage show command.
318 andreas 1047
    REG_CMD(doSTG, "^STG");     // Subpage toggle command
300 andreas 1048
 
225 andreas 1049
    // ListView commands (G5)
1050
    REG_CMD(doLVD, "^LVD");     // G5: Set Listview Data Source
230 andreas 1051
    REG_CMD(doLVE, "^LVE");     // G5: Set ListView custom event number
227 andreas 1052
    REG_CMD(doLVF, "^LVF");     // G5: Listview Filter
230 andreas 1053
    REG_CMD(doLVL, "^LVL");     // G5: ListView layout
233 andreas 1054
    REG_CMD(doLVM, "^LVM");     // G5: ListView map fields
1055
    REG_CMD(doLVN, "^LVN");     // G5: ListView navigate
1056
    REG_CMD(doLVR, "^LVR");     // G5: ListView refresh data
1057
    REG_CMD(doLVS, "^LVS");     // G5: ListView sort data
225 andreas 1058
 
103 andreas 1059
    // State commands
14 andreas 1060
    REG_CMD(doON, "ON");
1061
    REG_CMD(doOFF, "OFF");
15 andreas 1062
    REG_CMD(doLEVEL, "LEVEL");
1063
    REG_CMD(doBLINK, "BLINK");
127 andreas 1064
    REG_CMD(doVER, "^VER?");    // Return version string to master
279 andreas 1065
#ifndef _NOSIP_
127 andreas 1066
    REG_CMD(doWCN, "^WCN?");    // Return SIP phone number
279 andreas 1067
#endif
134 andreas 1068
    // TPControl commands
1069
    REG_CMD(doTPCCMD, "TPCCMD");    // Profile related options
1070
    REG_CMD(doTPCACC, "TPCACC");    // Device orientation
279 andreas 1071
#ifndef _NOSIP_
153 andreas 1072
    REG_CMD(doTPCSIP, "TPCSIP");    // Show the built in SIP phone
279 andreas 1073
#endif
134 andreas 1074
    // Virtual internal commands
26 andreas 1075
    REG_CMD(doFTR, "#FTR");     // File transfer (virtual internal command)
23 andreas 1076
 
123 andreas 1077
    // At least we must add the SIP client
129 andreas 1078
#ifndef _NOSIP_
127 andreas 1079
    mSIPClient = new TSIPClient;
123 andreas 1080
 
1081
    if (TError::isError())
1082
    {
1083
        MSG_ERROR("Error initializing the SIP client!");
1084
        TConfig::setSIPstatus(false);
1085
    }
129 andreas 1086
#endif
88 andreas 1087
    TError::clear();
299 andreas 1088
    runClickQueue();
303 andreas 1089
    runUpdateSubViewItem();
3 andreas 1090
}
1091
 
1092
TPageManager::~TPageManager()
1093
{
1094
    DECL_TRACER("TPageManager::~TPageManager()");
129 andreas 1095
#ifndef _NOSIP_
127 andreas 1096
    if (mSIPClient)
1097
    {
1098
        delete mSIPClient;
1099
        mSIPClient = nullptr;
1100
    }
129 andreas 1101
#endif
3 andreas 1102
    PCHAIN_T *p = mPchain;
1103
    PCHAIN_T *next = nullptr;
37 andreas 1104
#ifdef __ANDROID__
36 andreas 1105
    stopNetworkState();
37 andreas 1106
#endif
3 andreas 1107
    try
1108
    {
1109
        while (p)
1110
        {
1111
            next = p->next;
1112
 
1113
            if (p->page)
1114
                delete p->page;
1115
 
1116
            delete p;
1117
            p = next;
1118
        }
1119
 
1120
        SPCHAIN_T *sp = mSPchain;
1121
        SPCHAIN_T *snext = nullptr;
1122
 
1123
        while (sp)
1124
        {
1125
            snext = sp->next;
1126
 
1127
            if (sp->page)
1128
                delete sp->page;
1129
 
1130
            delete sp;
5 andreas 1131
            sp = snext;
3 andreas 1132
        }
1133
 
1134
        mPchain = nullptr;
1135
        mSPchain = nullptr;
14 andreas 1136
        setPChain(mPchain);
1137
        setSPChain(mSPchain);
3 andreas 1138
 
13 andreas 1139
        if (mAmxNet)
1140
        {
1141
            delete mAmxNet;
1142
            mAmxNet = nullptr;
1143
        }
1144
 
3 andreas 1145
        if (mTSettings)
1146
        {
1147
            delete mTSettings;
1148
            mTSettings = nullptr;
1149
        }
1150
 
1151
        if (mPageList)
1152
        {
1153
            delete mPageList;
1154
            mPageList = nullptr;
1155
        }
5 andreas 1156
 
1157
        if (mPalette)
1158
        {
1159
            delete mPalette;
1160
            mPalette = nullptr;
1161
        }
7 andreas 1162
 
1163
        if (mFonts)
1164
        {
1165
            delete mFonts;
1166
            mFonts = nullptr;
1167
        }
8 andreas 1168
 
1169
        if (gIcons)
1170
        {
1171
            delete gIcons;
1172
            gIcons = nullptr;
1173
        }
1174
 
1175
        if (gPrjResources)
1176
        {
1177
            delete gPrjResources;
1178
            gPrjResources = nullptr;
1179
        }
40 andreas 1180
 
33 andreas 1181
        if (mExternal)
1182
        {
1183
            delete mExternal;
1184
            mExternal = nullptr;
1185
        }
3 andreas 1186
    }
1187
    catch (std::exception& e)
1188
    {
1189
        MSG_ERROR("Memory error: " << e.what());
1190
    }
90 andreas 1191
 
1192
    gPageManager = nullptr;
3 andreas 1193
}
1194
 
11 andreas 1195
void TPageManager::initialize()
1196
{
1197
    DECL_TRACER("TPageManager::initialize()");
1198
 
14 andreas 1199
    surface_mutex.lock();
11 andreas 1200
    dropAllSubPages();
1201
    dropAllPages();
1202
 
186 andreas 1203
    string projectPath = TConfig::getProjectPath();
1204
 
1205
    if (!fs::exists(projectPath + "/prj.xma"))
1206
        projectPath += "/__system";
1207
 
90 andreas 1208
    if (mAmxNet && mAmxNet->isConnected())
1209
        mAmxNet->close();
88 andreas 1210
 
11 andreas 1211
    if (mTSettings)
1212
        mTSettings->loadSettings();
1213
    else
186 andreas 1214
        mTSettings = new TSettings(projectPath);
11 andreas 1215
 
1216
    if (TError::isError())
14 andreas 1217
    {
1218
        surface_mutex.unlock();
11 andreas 1219
        return;
14 andreas 1220
    }
11 andreas 1221
 
178 andreas 1222
    // Set the panel type from the project information
1223
    TConfig::savePanelType(mTSettings->getPanelType());
1224
 
88 andreas 1225
    if (gPrjResources)
1226
        delete gPrjResources;
11 andreas 1227
 
88 andreas 1228
    gPrjResources = new TPrjResources(mTSettings->getResourcesList());
11 andreas 1229
 
88 andreas 1230
    if (mPalette)
1231
        delete mPalette;
1232
 
1233
    mPalette = new TPalette();
1234
 
11 andreas 1235
    vector<PALETTE_SETUP> pal = mTSettings->getSettings().palettes;
1236
 
83 andreas 1237
    if (pal.size() > 0)
1238
    {
1239
        vector<PALETTE_SETUP>::iterator iterPal;
11 andreas 1240
 
118 andreas 1241
        for (iterPal = pal.begin(); iterPal != pal.end(); ++iterPal)
83 andreas 1242
            mPalette->initialize(iterPal->file);
1243
    }
1244
 
11 andreas 1245
    if (!TError::isError())
1246
        TColor::setPalette(mPalette);
1247
 
88 andreas 1248
    if (mFonts)
1249
        delete mFonts;
11 andreas 1250
 
88 andreas 1251
    mFonts = new TFont();
1252
 
11 andreas 1253
    if (TError::isError())
1254
    {
1255
        MSG_ERROR("Initializing fonts was not successfull!");
14 andreas 1256
        surface_mutex.unlock();
11 andreas 1257
        return;
1258
    }
1259
 
88 andreas 1260
    if (gIcons)
1261
        delete gIcons;
11 andreas 1262
 
88 andreas 1263
    gIcons = new TIcons();
1264
 
11 andreas 1265
    if (TError::isError())
1266
    {
1267
        MSG_ERROR("Initializing icons was not successfull!");
14 andreas 1268
        surface_mutex.unlock();
11 andreas 1269
        return;
1270
    }
1271
 
88 andreas 1272
    if (mPageList)
1273
        delete mPageList;
11 andreas 1274
 
88 andreas 1275
    mPageList = new TPageList();
11 andreas 1276
 
88 andreas 1277
    if (mExternal)
1278
        delete mExternal;
1279
 
1280
    mExternal = new TExternal();
1281
 
11 andreas 1282
    PAGELIST_T page;
1283
 
1284
    if (!mTSettings->getSettings().powerUpPage.empty())
1285
    {
88 andreas 1286
        if (readPage(mTSettings->getSettings().powerUpPage))
14 andreas 1287
        {
88 andreas 1288
            MSG_TRACE("Found power up page " << mTSettings->getSettings().powerUpPage);
1289
            page = findPage(mTSettings->getSettings().powerUpPage);
1290
            mActualPage = page.pageID;
14 andreas 1291
        }
11 andreas 1292
    }
1293
 
1294
    TPage *pg = getPage(mActualPage);
1295
 
1296
    vector<string> popups = mTSettings->getSettings().powerUpPopup;
1297
 
83 andreas 1298
    if (popups.size() > 0)
11 andreas 1299
    {
83 andreas 1300
        vector<string>::iterator iter;
1301
 
118 andreas 1302
        for (iter = popups.begin(); iter != popups.end(); ++iter)
14 andreas 1303
        {
88 andreas 1304
            if (readSubPage(*iter))
83 andreas 1305
            {
88 andreas 1306
                MSG_TRACE("Found power up popup " << *iter);
11 andreas 1307
 
88 andreas 1308
                if (pg)
1309
                {
1310
                    TSubPage *spage = getSubPage(*iter);
350 andreas 1311
                    spage->setParent(pg->getHandle());
88 andreas 1312
                    pg->addSubPage(spage);
1313
                }
83 andreas 1314
            }
11 andreas 1315
        }
1316
    }
1317
 
88 andreas 1318
    // Here we initialize the system resources like borders, cursors, sliders, ...
1319
    if (mSystemDraw)
1320
        delete mSystemDraw;
1321
 
1322
    mSystemDraw = new TSystemDraw(TConfig::getSystemPath(TConfig::BASE));
1323
 
1324
    TError::clear();        // Clear all errors who may be occured until here
1325
 
11 andreas 1326
    // Start the thread
92 andreas 1327
    startComm();
1328
 
1329
    surface_mutex.unlock();
1330
}
1331
 
1332
bool TPageManager::startComm()
1333
{
1334
    DECL_TRACER("TPageManager::startComm()");
1335
 
1336
    if (mAmxNet && mAmxNet->isNetRun())
1337
        return true;
1338
 
1339
    try
11 andreas 1340
    {
92 andreas 1341
        if (!mAmxNet)
13 andreas 1342
        {
92 andreas 1343
            if (_netRunning)
13 andreas 1344
            {
92 andreas 1345
                // Wait until previous connection thread ended
1346
                while (_netRunning)
1347
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
13 andreas 1348
            }
14 andreas 1349
 
92 andreas 1350
            mAmxNet = new amx::TAmxNet();
1351
            mAmxNet->setCallback(bind(&TPageManager::doCommand, this, std::placeholders::_1));
1352
            mAmxNet->setPanelID(TConfig::getChannel());
134 andreas 1353
            mAmxNet->setSerialNum(V_SERIAL);
13 andreas 1354
        }
90 andreas 1355
 
1356
        if (!mAmxNet->isNetRun())
1357
            mAmxNet->Run();
85 andreas 1358
    }
92 andreas 1359
    catch (std::exception& e)
1360
    {
1361
        MSG_ERROR("Error starting the AmxNet thread: " << e.what());
1362
        return false;
1363
    }
14 andreas 1364
 
92 andreas 1365
    return true;
11 andreas 1366
}
1367
 
38 andreas 1368
void TPageManager::startUp()
1369
{
1370
    DECL_TRACER("TPageManager::startUp()");
1371
 
44 andreas 1372
    if (mAmxNet)
90 andreas 1373
    {
1374
        MSG_WARNING("Communication with controller already initialized!");
44 andreas 1375
        return;
90 andreas 1376
    }
44 andreas 1377
 
92 andreas 1378
    if (!startComm())
1379
        return;
90 andreas 1380
 
38 andreas 1381
#ifdef __ANDROID__
130 andreas 1382
    initOrientation();
38 andreas 1383
    initNetworkState();
1384
#endif
1385
}
89 andreas 1386
 
1387
void TPageManager::reset()
1388
{
1389
    DECL_TRACER("TPageManager::reset()");
1390
 
100 andreas 1391
    // Freshly initialize everything.
89 andreas 1392
    initialize();
1393
}
1394
 
169 andreas 1395
void TPageManager::runCommands()
1396
{
1397
    DECL_TRACER("TPageManager::runCommands()");
1398
 
1399
    if (mBusy || cmdLoop_busy)
1400
        return;
1401
 
1402
    try
1403
    {
1404
        mThreadCommand = std::thread([=] { this->commandLoop(); });
1405
        mThreadCommand.detach();
1406
    }
1407
    catch (std::exception& e)
1408
    {
1409
        MSG_ERROR("Error starting thread for command loop: " << e.what());
1410
        _netRunning = false;
1411
    }
1412
}
1413
 
197 andreas 1414
void TPageManager::showSetup()
1415
{
1416
    DECL_TRACER("TPageManager::showSetup()");
251 andreas 1417
#ifdef Q_OS_ANDROID
260 andreas 1418
    // Scan Netlinx for TP4 files and update the list of setup.
1419
    if (TConfig::getController().compare("0.0.0.0") != 0)
1420
    {
1421
        if (_startWait)
1422
            _startWait(string("Please wait while I try to load the list of surface files from Netlinx (") + TConfig::getController() + ")");
1423
 
1424
        TTPInit tpinit;
1425
        std::vector<TTPInit::FILELIST_t> fileList;
1426
        tpinit.setPath(TConfig::getProjectPath());
1427
        fileList = tpinit.getFileList(".tp4");
1428
 
1429
        if (fileList.size() > 0)
1430
        {
1431
            vector<TTPInit::FILELIST_t>::iterator iter;
264 andreas 1432
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
260 andreas 1433
            QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "clearSurfaces");
1434
#else
1435
            QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "clearSurfaces");
1436
#endif
1437
            for (iter = fileList.begin(); iter != fileList.end(); ++iter)
1438
            {
264 andreas 1439
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
260 andreas 1440
                QAndroidJniObject str = QAndroidJniObject::fromString(iter->fname.c_str());
1441
                QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "addSurface", "(Ljava/lang/String;)V", str.object<jstring>());
1442
#else
1443
                QJniObject str = QJniObject::fromString(iter->fname.c_str());
1444
                QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "addSurface", "(Ljava/lang/String;)V", str.object<jstring>());
1445
#endif
1446
            }
1447
        }
1448
 
1449
        if (_stopWait)
1450
            _stopWait();
1451
    }
1452
 
367 andreas 1453
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1454
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogLevel", "(Ljava/lang/Integer;)V", TConfig::getLogLevelBits());
383 andreas 1455
    QAndroidJniObject strPath = QAndroidJniObject::fromString(TConfig::getLogFile().c_str());
385 andreas 1456
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogEnableFile", "(Z)V", TConfig::getLogFileEnabled());
383 andreas 1457
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogPath", "(Ljava/lang/String;)V", strPath.object<jstring>());
367 andreas 1458
#else
1459
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogLevel", "(I)V", TConfig::getLogLevelBits());
385 andreas 1460
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogEnableFile", "(I)V", (TConfig::getLogFileEnabled() ? 1 : 0));
383 andreas 1461
    QJniObject strPath = QJniObject::fromString(TConfig::getLogFile().c_str());
1462
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogPath", "(Ljava/lang/String;)V", strPath.object<jstring>());
367 andreas 1463
#endif
1464
 
255 andreas 1465
    enterSetup();
1466
/*    if (mSetupActive)
197 andreas 1467
        return;
1468
 
1469
    mSetupActive = true;
1470
    mSavedPage = mActualPage;
1471
 
198 andreas 1472
    TPage *pg = getPage(mActualPage);
197 andreas 1473
 
198 andreas 1474
    if (pg)
1475
    {
1476
        TSubPage *spage = pg->getFirstSubPage();
1477
        mSavedSubpages.clear();
197 andreas 1478
 
198 andreas 1479
        while (spage)
197 andreas 1480
        {
198 andreas 1481
            if (spage->isVisible())
1482
                mSavedSubpages.push_back(spage->getNumber());
1483
 
1484
            spage = pg->getNextSubPage();
197 andreas 1485
        }
1486
    }
1487
 
209 andreas 1488
    setPage(SYSTEM_PAGE_CONTROLLER, true);    // Call the page "Controller" (NetLinx settings)
255 andreas 1489
*/
250 andreas 1490
#else
1491
        if (_callShowSetup)
1492
            _callShowSetup();
1493
#endif
197 andreas 1494
}
1495
 
1496
void TPageManager::hideSetup()
1497
{
1498
    DECL_TRACER("TPageManager::hideSetup()");
1499
 
206 andreas 1500
    if (!mSetupActive || mSavedPage >= SYSTEM_PAGE_START)
197 andreas 1501
        return;
1502
 
198 andreas 1503
    mSetupActive = false;
197 andreas 1504
 
198 andreas 1505
    if (!mSavedPage)
1506
    {
1507
        string sPage = mTSettings->getPowerUpPage();
197 andreas 1508
 
198 andreas 1509
        if (!setPage(sPage, true))
1510
            setPage(1, true);
197 andreas 1511
 
1512
        return;
1513
    }
1514
 
198 andreas 1515
    setPage(mSavedPage, true);
213 andreas 1516
    MSG_PROTOCOL("Activated page: " << mSavedPage);
197 andreas 1517
 
198 andreas 1518
    if (mSavedSubpages.size() > 0)
197 andreas 1519
    {
198 andreas 1520
        vector<int>::iterator iter;
197 andreas 1521
 
198 andreas 1522
        for (iter = mSavedSubpages.begin(); iter != mSavedSubpages.end(); ++iter)
1523
        {
1524
            showSubPage(*iter);
213 andreas 1525
            MSG_PROTOCOL("Activated subpage: " << *iter);
198 andreas 1526
        }
217 andreas 1527
 
1528
        mSavedSubpages.clear();
197 andreas 1529
    }
1530
}
1531
 
205 andreas 1532
int TPageManager::getSelectedRow(ulong handle)
1533
{
1534
    DECL_TRACER("TPageManager::getSelectedRow(ulong handle)");
1535
 
300 andreas 1536
    int nPage = (handle >> 16) & 0x0000ffff;
205 andreas 1537
 
206 andreas 1538
    if ((nPage && TPage::isRegularPage(nPage)) || TPage::isSystemPage(nPage)) // Do we have a page?
205 andreas 1539
    {                                                   // Yes, then look on page
1540
        TPage *pg = getPage(nPage);
1541
 
1542
        if (!pg)
1543
            return -1;
1544
 
1545
        return pg->getSelectedRow(handle);
1546
    }
206 andreas 1547
    else if (TPage::isRegularSubPage(nPage) || TPage::isSystemSubPage(nPage))
205 andreas 1548
    {
1549
        TSubPage *subPg = getSubPage(nPage);
1550
 
1551
        if (!subPg)
1552
            return -1;
1553
 
1554
        return subPg->getSelectedRow(handle);
1555
    }
1556
 
271 andreas 1557
    MSG_WARNING("Invalid handle " << handleToString(handle) << " detected!");
205 andreas 1558
    return -1;
1559
}
1560
 
1561
string TPageManager::getSelectedItem(ulong handle)
1562
{
1563
    DECL_TRACER("TPageManager::getSelectedItem(ulong handle)");
1564
 
300 andreas 1565
    int nPage = (handle >> 16) & 0x0000ffff;
205 andreas 1566
 
206 andreas 1567
    if ((nPage && TPage::isRegularPage(nPage)) || TPage::isSystemPage(nPage)) // Do we have a page?
205 andreas 1568
    {                                                   // Yes, then look on page
1569
        TPage *pg = getPage(nPage);
1570
 
1571
        if (!pg)
1572
            return string();
1573
 
1574
        return pg->getSelectedItem(handle);
1575
    }
206 andreas 1576
    else if (TPage::isRegularSubPage(nPage) || TPage::isSystemSubPage(nPage))
205 andreas 1577
    {
1578
        TSubPage *subPg = getSubPage(nPage);
1579
 
1580
        if (!subPg)
1581
            return string();
1582
 
1583
        return subPg->getSelectedItem(handle);
1584
    }
1585
 
271 andreas 1586
    MSG_WARNING("Invalid handle " << handleToString(handle) << " detected!");
205 andreas 1587
    return string();
1588
}
1589
 
206 andreas 1590
void TPageManager::setSelectedRow(ulong handle, int row, const std::string& text)
205 andreas 1591
{
1592
    DECL_TRACER("TPageManager::setSelectedRow(ulong handle, int row)");
1593
 
300 andreas 1594
    int nPage = (handle >> 16) & 0x0000ffff;
205 andreas 1595
 
206 andreas 1596
    if (TPage::isRegularPage(nPage) || TPage::isSystemPage(nPage)) // Do we have a page?
205 andreas 1597
    {                                                   // Yes, then look on page
1598
        TPage *pg = getPage(nPage);
1599
 
1600
        if (!pg)
1601
            return;
1602
 
1603
        pg->setSelectedRow(handle, row);
1604
    }
206 andreas 1605
    else if (TPage::isRegularSubPage(nPage) || TPage::isSystemSubPage(nPage))   // Do we have a subpage?
1606
    {                                                   // Yes, then look on subpage
205 andreas 1607
        TSubPage *subPg = getSubPage(nPage);
1608
 
1609
        if (!subPg)
1610
            return;
1611
 
1612
        subPg->setSelectedRow(handle, row);
206 andreas 1613
        // Check if this is a system list. If so we must set the selected
1614
        // text to the input line or "label".
1615
        TPage *mainPage = nullptr;
1616
 
1617
        if (nPage >= SYSTEM_SUBPAGE_START)  // System subpage?
1618
        {
1619
            switch(nPage)
1620
            {
1621
                case SYSTEM_SUBPAGE_SYSTEMSOUND:
1622
                case SYSTEM_SUBPAGE_SINGLEBEEP:
1623
                case SYSTEM_SUBPAGE_DOUBLEBEEP:
1624
                    mainPage = getPage(SYSTEM_PAGE_SOUND);
1625
                break;
1626
 
1627
                case SYSTEM_SUBPAGE_SURFACE:
1628
                    mainPage = getPage(SYSTEM_PAGE_CONTROLLER);
1629
                break;
1630
            }
1631
        }
1632
 
1633
        if (mainPage)
1634
        {
1635
            if (nPage == SYSTEM_SUBPAGE_SYSTEMSOUND)  // System sound beep
1636
            {
1637
                Button::TButton *bt = mainPage->getButton(SYSTEM_PAGE_SOUND_TXSYSSOUND);
1638
 
1639
                if (bt)
1640
                {
1641
                    bt->setText(text, -1);
1642
                    TConfig::setTemporary(true);
1643
                    TConfig::saveSystemSoundFile(text);
1644
                }
1645
            }
1646
            else if (nPage == SYSTEM_SUBPAGE_SINGLEBEEP) // System sound single beep
1647
            {
1648
                Button::TButton *bt = mainPage->getButton(SYSTEM_PAGE_SOUND_TXSINGLEBEEP);
1649
 
1650
                if (bt)
1651
                {
1652
                    bt->setText(text, -1);
1653
                    TConfig::setTemporary(true);
1654
                    TConfig::saveSingleBeepFile(text);
1655
                }
1656
            }
1657
            else if (nPage == SYSTEM_SUBPAGE_DOUBLEBEEP) // System sound double beep
1658
            {
1659
                Button::TButton *bt = mainPage->getButton(SYSTEM_PAGE_SOUND_TXDOUBLEBEEP);
1660
 
1661
                if (bt)
1662
                {
1663
                    bt->setText(text, -1);
1664
                    TConfig::setTemporary(true);
1665
                    TConfig::saveDoubleBeepFile(text);
1666
                }
1667
            }
1668
            else if (nPage == SYSTEM_SUBPAGE_SURFACE)   // System TP4 files (surface files)
1669
            {
1670
                Button::TButton *bt = mainPage->getButton(SYSTEM_PAGE_CTRL_SURFACE);
1671
 
1672
                if (bt)
1673
                {
1674
                    MSG_DEBUG("Setting text: " << text);
1675
                    bt->setText(text, -1);
1676
                    TConfig::setTemporary(true);
1677
                    TConfig::saveFtpSurface(text);
1678
                }
1679
            }
1680
 
1681
            // Close the list subpage
1682
            subPg->drop();
1683
        }
205 andreas 1684
    }
1685
}
1686
 
383 andreas 1687
void TPageManager::redrawObject(ulong handle)
1688
{
1689
    DECL_TRACER("TPageManager::redrawObject(ulong handle)");
1690
 
1691
    int pnumber = (int)((handle >> 16) & 0x0000ffff);
1692
    int btnumber = (int)(handle & 0x0000ffff);
1693
 
1694
    if (pnumber < REGULAR_SUBPAGE_START)    // Is it a page?
1695
    {
1696
        TPage *page = getPage(pnumber);
1697
 
1698
        if (!page)
1699
        {
1700
            MSG_WARNING("Page " << pnumber << " not found!");
1701
            return;
1702
        }
1703
 
1704
        if (!page->isVisilble())
1705
            return;
1706
 
1707
        if (btnumber == 0)
1708
        {
1709
            page->show();
1710
            return;
1711
        }
1712
 
1713
        Button::TButton *button = page->getButton(btnumber);
1714
 
1715
        if (!button)
1716
        {
1717
            MSG_WARNING("Button " << btnumber << " on page " << pnumber << " not found!");
1718
            return;
1719
        }
1720
 
1721
        button->showLastButton();
1722
    }
1723
    else if (pnumber >= REGULAR_SUBPAGE_START && pnumber < SYSTEM_PAGE_START)
1724
    {
1725
        TSubPage *spage = getSubPage(pnumber);
1726
 
1727
        if (!spage)
1728
        {
1729
            MSG_WARNING("Subpage " << pnumber << " not found!");
1730
            return;
1731
        }
1732
 
1733
        if (!spage->isVisible())
1734
            return;
1735
 
1736
        if (btnumber == 0)
1737
        {
1738
            spage->show();
1739
            return;
1740
        }
1741
 
1742
        Button::TButton *button = spage->getButton(btnumber);
1743
 
1744
        if (!button)
1745
        {
1746
            MSG_WARNING("Button " << btnumber << " on subpage " << pnumber << " not found!");
1747
            return;
1748
        }
1749
 
1750
        button->showLastButton();
1751
    }
1752
    else
1753
    {
1754
        MSG_WARNING("System pages are not handled by redraw method! Ignoring page " << pnumber << ".");
1755
    }
1756
}
1757
 
198 andreas 1758
#ifdef _SCALE_SKIA_
197 andreas 1759
void TPageManager::setSetupScaleFactor(double scale, double sw, double sh)
1760
{
1761
    DECL_TRACER("TPageManager::setSetupScaleFactor(double scale, double sw, double sh)");
1762
 
1763
    mScaleSystem = scale;
1764
    mScaleSystemWidth = sw;
1765
    mScaleSystemHeight = sh;
1766
}
198 andreas 1767
#endif
197 andreas 1768
 
11 andreas 1769
/*
1770
 * The following method is called by the class TAmxNet whenever an event from
169 andreas 1771
 * the Netlinx occured.
11 andreas 1772
 */
1773
void TPageManager::doCommand(const amx::ANET_COMMAND& cmd)
1774
{
1775
    DECL_TRACER("TPageManager::doCommand(const amx::ANET_COMMAND& cmd)");
1776
 
169 andreas 1777
    if (!cmdLoop_busy)
1778
        runCommands();
1779
 
11 andreas 1780
    mCommands.push_back(cmd);
169 andreas 1781
}
11 andreas 1782
 
169 andreas 1783
void TPageManager::commandLoop()
1784
{
1785
    DECL_TRACER("TPageManager::commandLoop()");
1786
 
1787
    if (mBusy || cmdLoop_busy)
11 andreas 1788
        return;
1789
 
169 andreas 1790
    mBusy = cmdLoop_busy = true;
11 andreas 1791
    string com;
1792
 
169 andreas 1793
    while (cmdLoop_busy && !killed && !_restart_)
11 andreas 1794
    {
169 andreas 1795
        while (mCommands.size() > 0)
11 andreas 1796
        {
169 andreas 1797
            amx::ANET_COMMAND bef = mCommands.at(0);
1798
            mCommands.erase(mCommands.begin());
11 andreas 1799
 
169 andreas 1800
            switch (bef.MC)
1801
            {
1802
                case 0x0006:
1803
                case 0x0018:	// feedback channel on
1804
                    com.assign("ON-");
1805
                    com.append(to_string(bef.data.chan_state.channel));
1806
                    parseCommand(bef.device1, bef.data.chan_state.port, com);
1807
                break;
11 andreas 1808
 
169 andreas 1809
                case 0x0007:
1810
                case 0x0019:	// feedback channel off
1811
                    com.assign("OFF-");
1812
                    com.append(to_string(bef.data.chan_state.channel));
1813
                    parseCommand(bef.device1, bef.data.chan_state.port, com);
1814
                break;
11 andreas 1815
 
169 andreas 1816
                case 0x000a:	// level value change
1817
                    com = "LEVEL-";
1818
                    com += to_string(bef.data.message_value.value);
1819
                    com += ",";
11 andreas 1820
 
169 andreas 1821
                    switch (bef.data.message_value.type)
1822
                    {
1823
                        case 0x10: com += to_string(bef.data.message_value.content.byte); break;
1824
                        case 0x11: com += to_string(bef.data.message_value.content.ch); break;
1825
                        case 0x20: com += to_string(bef.data.message_value.content.integer); break;
1826
                        case 0x21: com += to_string(bef.data.message_value.content.sinteger); break;
1827
                        case 0x40: com += to_string(bef.data.message_value.content.dword); break;
1828
                        case 0x41: com += to_string(bef.data.message_value.content.sdword); break;
1829
                        case 0x4f: com += to_string(bef.data.message_value.content.fvalue); break;
1830
                        case 0x8f: com += to_string(bef.data.message_value.content.dvalue); break;
1831
                    }
11 andreas 1832
 
169 andreas 1833
                    parseCommand(bef.device1, bef.data.message_value.port, com);
1834
                break;
11 andreas 1835
 
169 andreas 1836
                case 0x000c:	// Command string
11 andreas 1837
                {
169 andreas 1838
                    amx::ANET_MSG_STRING msg = bef.data.message_string;
11 andreas 1839
 
169 andreas 1840
                    if (msg.length < strlen((char *)&msg.content))
1841
                    {
1842
                        mCmdBuffer.append((char *)&msg.content);
1843
                        break;
1844
                    }
1845
                    else if (mCmdBuffer.length() > 0)
1846
                    {
1847
                        mCmdBuffer.append((char *)&msg.content);
1848
                        size_t len = (mCmdBuffer.length() >= sizeof(msg.content)) ? (sizeof(msg.content)-1) : mCmdBuffer.length();
1849
                        strncpy((char *)&msg.content, mCmdBuffer.c_str(), len);
1850
                        msg.content[len] = 0;
1851
                    }
104 andreas 1852
 
169 andreas 1853
                    if (getCommand((char *)msg.content) == "^UTF")  // This is already UTF8!
1854
                        com.assign((char *)msg.content);
1855
                    else
1856
                        com.assign(cp1250ToUTF8((char *)&msg.content));
11 andreas 1857
 
169 andreas 1858
                    parseCommand(bef.device1, msg.port, com);
1859
                    mCmdBuffer.clear();
1860
                }
1861
                break;
15 andreas 1862
 
169 andreas 1863
                case 0x0502:    // Blink message (contains date and time)
1864
                    com = "BLINK-" + to_string(bef.data.blinkMessage.hour) + ":";
1865
                    com += to_string(bef.data.blinkMessage.minute) + ":";
1866
                    com += to_string(bef.data.blinkMessage.second) + ",";
1867
                    com += to_string(bef.data.blinkMessage.year) + "-";
1868
                    com += to_string(bef.data.blinkMessage.month) + "-";
1869
                    com += to_string(bef.data.blinkMessage.day) + ",";
1870
                    com += to_string(bef.data.blinkMessage.weekday) + ",";
1871
                    com += ((bef.data.blinkMessage.LED & 0x0001) ? "ON" : "OFF");
1872
                    parseCommand(0, 0, com);
1873
                break;
11 andreas 1874
 
169 andreas 1875
                case 0x1000:	// Filetransfer
11 andreas 1876
                {
169 andreas 1877
                    amx::ANET_FILETRANSFER ftr = bef.data.filetransfer;
1878
 
1879
                    if (ftr.ftype == 0)
11 andreas 1880
                    {
169 andreas 1881
                        switch(ftr.function)
1882
                        {
1883
                            case 0x0100:	// Syncing directory
1884
                                com = "#FTR-SYNC:0:";
1885
                                com.append((char*)&ftr.data[0]);
1886
                                parseCommand(bef.device1, bef.port1, com);
1887
                            break;
11 andreas 1888
 
169 andreas 1889
                            case 0x0104:	// Delete file
1890
                                com = "#FTR-SYNC:"+to_string(bef.count)+":Deleting files ... ("+to_string(bef.count)+"%)";
1891
                                parseCommand(bef.device1, bef.port1, com);
1892
                            break;
11 andreas 1893
 
169 andreas 1894
                            case 0x0105:	// start filetransfer
1895
                                com = "#FTR-START";
1896
                                parseCommand(bef.device1, bef.port1, com);
1897
                            break;
1898
                        }
11 andreas 1899
                    }
169 andreas 1900
                    else
11 andreas 1901
                    {
169 andreas 1902
                        switch(ftr.function)
1903
                        {
1904
                            case 0x0003:	// Received part of file
1905
                            case 0x0004:	// End of file
1906
                                com = "#FTR-FTRPART:"+to_string(bef.count)+":"+to_string(ftr.info1);
1907
                                parseCommand(bef.device1, bef.port1, com);
1908
                            break;
11 andreas 1909
 
169 andreas 1910
                            case 0x0007:	// End of file transfer
1911
                            {
1912
                                com = "#FTR-END";
1913
                                parseCommand(bef.device1, bef.port1, com);
1914
                            }
1915
                            break;
1916
 
1917
                            case 0x0102:	// Receiving file
1918
                                com = "#FTR-FTRSTART:"+to_string(bef.count)+":"+to_string(ftr.info1)+":";
1919
                                com.append((char*)&ftr.data[0]);
1920
                                parseCommand(bef.device1, bef.port1, com);
1921
                            break;
11 andreas 1922
                        }
1923
                    }
1924
                }
169 andreas 1925
                break;
11 andreas 1926
            }
1927
        }
169 andreas 1928
 
1929
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
11 andreas 1930
    }
1931
 
1932
    mBusy = false;
169 andreas 1933
    cmdLoop_busy = false;
11 andreas 1934
}
1935
 
26 andreas 1936
void TPageManager::deployCallbacks()
1937
{
1938
    DECL_TRACER("TPageManager::deployCallbacks()");
1939
 
1940
    PCHAIN_T *p = mPchain;
1941
 
1942
    while (p)
1943
    {
1944
        if (p->page)
1945
        {
1946
            if (_setBackground)
1947
                p->page->registerCallback(_setBackground);
1948
 
1949
            if (_callPlayVideo)
1950
                p->page->regCallPlayVideo(_callPlayVideo);
1951
        }
1952
 
1953
        p = p->next;
1954
    }
1955
 
1956
    SPCHAIN_T *sp = mSPchain;
1957
 
1958
    while (sp)
1959
    {
1960
        if (sp->page)
1961
        {
1962
            if (_setBackground)
1963
                sp->page->registerCallback(_setBackground);
1964
 
1965
            if (_callPlayVideo)
1966
                sp->page->regCallPlayVideo(_callPlayVideo);
1967
        }
1968
 
1969
        sp = sp->next;
1970
    }
1971
}
36 andreas 1972
 
1973
void TPageManager::regCallbackNetState(std::function<void (int)> callNetState, ulong handle)
1974
{
1975
    DECL_TRACER("TPageManager::regCallbackNetState(std::function<void (int)> callNetState, ulong handle)");
1976
 
1977
    if (handle == 0)
1978
        return;
1979
 
1980
    mNetCalls.insert(std::pair<int, std::function<void (int)> >(handle, callNetState));
1981
}
1982
 
1983
void TPageManager::unregCallbackNetState(ulong handle)
1984
{
1985
    DECL_TRACER("TPageManager::unregCallbackNetState(ulong handle)");
1986
 
83 andreas 1987
    if (mNetCalls.size() == 0)
1988
        return;
1989
 
300 andreas 1990
    std::map<int, std::function<void (int)> >::iterator iter = mNetCalls.find((int)handle);
36 andreas 1991
 
1992
    if (iter != mNetCalls.end())
1993
        mNetCalls.erase(iter);
1994
}
247 andreas 1995
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
251 andreas 1996
#ifdef Q_OS_ANDROID
38 andreas 1997
void TPageManager::regCallbackBatteryState(std::function<void (int, bool, int)> callBatteryState, ulong handle)
1998
{
1999
    DECL_TRACER("TPageManager::regCallbackBatteryState(std::function<void (int, bool, int)> callBatteryState, ulong handle)");
2000
 
2001
    if (handle == 0)
2002
        return;
2003
 
2004
    mBatteryCalls.insert(std::pair<int, std::function<void (int, bool, int)> >(handle, callBatteryState));
2005
}
247 andreas 2006
#endif
2007
#ifdef Q_OS_IOS
2008
void TPageManager::regCallbackBatteryState(std::function<void (int, int)> callBatteryState, ulong handle)
2009
{
2010
    DECL_TRACER("TPageManager::regCallbackBatteryState(std::function<void (int, int)> callBatteryState, ulong handle)");
38 andreas 2011
 
247 andreas 2012
    if (handle == 0)
2013
        return;
2014
 
2015
    mBatteryCalls.insert(std::pair<int, std::function<void (int, int)> >(handle, callBatteryState));
264 andreas 2016
#ifdef Q_OS_IOS
2017
    mLastBatteryLevel = TIOSBattery::getBatteryLeft();
2018
    mLastBatteryState = TIOSBattery::getBatteryState();
247 andreas 2019
 
264 andreas 2020
#endif
247 andreas 2021
    if (mLastBatteryLevel > 0 || mLastBatteryState > 0)
2022
        informBatteryStatus(mLastBatteryLevel, mLastBatteryState);
2023
}
2024
#endif
38 andreas 2025
void TPageManager::unregCallbackBatteryState(ulong handle)
2026
{
2027
    DECL_TRACER("TPageManager::unregCallbackBatteryState(ulong handle)");
2028
 
83 andreas 2029
    if (mBatteryCalls.size() == 0)
2030
        return;
247 andreas 2031
#ifdef Q_OS_ANDROID
38 andreas 2032
    std::map<int, std::function<void (int, bool, int)> >::iterator iter = mBatteryCalls.find(handle);
247 andreas 2033
#endif
2034
#ifdef Q_OS_IOS
300 andreas 2035
    std::map<int, std::function<void (int, int)> >::iterator iter = mBatteryCalls.find((int)handle);
247 andreas 2036
#endif
38 andreas 2037
    if (iter != mBatteryCalls.end())
2038
        mBatteryCalls.erase(iter);
2039
}
247 andreas 2040
#endif  // defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
11 andreas 2041
/*
2042
 * The following function must be called to start the "panel".
2043
 */
5 andreas 2044
bool TPageManager::run()
2045
{
2046
    DECL_TRACER("TPageManager::run()");
2047
 
2048
    if (mActualPage <= 0)
2049
        return false;
2050
 
154 andreas 2051
    TPage *pg = getPage(mActualPage);
2052
 
2053
    if (!pg || !_setPage || !mTSettings)
2054
        return false;
2055
 
14 andreas 2056
    surface_mutex.lock();
7 andreas 2057
    pg->setFonts(mFonts);
5 andreas 2058
    pg->registerCallback(_setBackground);
21 andreas 2059
    pg->regCallPlayVideo(_callPlayVideo);
5 andreas 2060
 
26 andreas 2061
    int width, height;
217 andreas 2062
    width = mTSettings->getWidth();
26 andreas 2063
    height = mTSettings->getHeight();
43 andreas 2064
#ifdef _SCALE_SKIA_
26 andreas 2065
    if (mScaleFactor != 1.0)
2066
    {
2067
        width = (int)((double)width * mScaleFactor);
2068
        height = (int)((double)height * mScaleFactor);
2069
    }
43 andreas 2070
#endif
26 andreas 2071
    _setPage((pg->getNumber() << 16) & 0xffff0000, width, height);
5 andreas 2072
    pg->show();
2073
 
2074
    TSubPage *subPg = pg->getFirstSubPage();
2075
 
2076
    while (subPg)
2077
    {
7 andreas 2078
        subPg->setFonts(mFonts);
2079
        subPg->registerCallback(_setBackground);
2080
        subPg->registerCallbackDB(_displayButton);
11 andreas 2081
        subPg->regCallDropSubPage(_callDropSubPage);
21 andreas 2082
        subPg->regCallPlayVideo(_callPlayVideo);
7 andreas 2083
 
5 andreas 2084
        if (_setSubPage)
6 andreas 2085
        {
2086
            MSG_DEBUG("Drawing page " << subPg->getNumber() << ": " << subPg->getName() << "...");
26 andreas 2087
            width = subPg->getWidth();
2088
            height = subPg->getHeight();
2089
            int left = subPg->getLeft();
2090
            int top = subPg->getTop();
43 andreas 2091
#ifdef _SCALE_SKIA_
26 andreas 2092
            if (mScaleFactor != 1.0)
2093
            {
2094
                width = (int)((double)width * mScaleFactor);
2095
                height = (int)((double)height * mScaleFactor);
2096
                left = (int)((double)left * mScaleFactor);
2097
                top = (int)((double)top * mScaleFactor);
2098
            }
43 andreas 2099
#endif
41 andreas 2100
            ANIMATION_t ani;
2101
            ani.showEffect = subPg->getShowEffect();
2102
            ani.showTime = subPg->getShowTime();
42 andreas 2103
            ani.hideEffect = subPg->getHideEffect();
2104
            ani.hideTime = subPg->getHideTime();
162 andreas 2105
 
2106
            subPg->setZOrder(pg->getNextZOrder());
217 andreas 2107
            _setSubPage(subPg->getHandle(), pg->getHandle(), left, top, width, height, ani);
6 andreas 2108
            subPg->show();
2109
        }
5 andreas 2110
 
2111
        subPg = pg->getNextSubPage();
2112
    }
2113
 
14 andreas 2114
    surface_mutex.unlock();
5 andreas 2115
    return true;
2116
}
2117
 
4 andreas 2118
TPage *TPageManager::getPage(int pageID)
2119
{
2120
    DECL_TRACER("TPageManager::getPage(int pageID)");
2121
 
209 andreas 2122
    if (pageID <= 0)
2123
        return nullptr;
2124
 
4 andreas 2125
    PCHAIN_T *p = mPchain;
2126
 
2127
    while (p)
2128
    {
349 andreas 2129
        if (p->page && p->page->getNumber() == pageID)
4 andreas 2130
            return p->page;
2131
 
2132
        p = p->next;
2133
    }
2134
 
2135
    return nullptr;
2136
}
2137
 
2138
TPage *TPageManager::getPage(const string& name)
2139
{
2140
    DECL_TRACER("TPageManager::getPage(const string& name)");
2141
 
349 andreas 2142
    if (name.empty())
2143
        return nullptr;
2144
 
4 andreas 2145
    PCHAIN_T *p = mPchain;
2146
 
2147
    while (p)
2148
    {
349 andreas 2149
        if (p->page && p->page->getName().compare(name) == 0)
4 andreas 2150
            return p->page;
2151
 
2152
        p = p->next;
2153
    }
2154
 
2155
    return nullptr;
2156
}
2157
 
209 andreas 2158
TPage *TPageManager::loadPage(PAGELIST_T& pl, bool *refresh)
15 andreas 2159
{
209 andreas 2160
    DECL_TRACER("TPageManager::loadPage(PAGELIST_T& pl, bool *refresh)");
15 andreas 2161
 
209 andreas 2162
    if (refresh)
2163
        *refresh = false;
2164
 
15 andreas 2165
    if (!pl.isValid)
2166
        return nullptr;
2167
 
2168
    TPage *pg = getPage(pl.pageID);
2169
 
2170
    if (!pg)
2171
    {
2172
        if (!readPage(pl.pageID))
2173
            return nullptr;
2174
 
2175
        pg = getPage(pl.pageID);
2176
 
2177
        if (!pg)
2178
        {
2179
            MSG_ERROR("Error loading page " << pl.pageID << ", " << pl.name << " from file " << pl.file << "!");
2180
            return nullptr;
2181
        }
209 andreas 2182
 
2183
        if (refresh)
213 andreas 2184
            *refresh = true;        // Indicate that the page was freshly loaded
15 andreas 2185
    }
2186
 
2187
    return pg;
2188
}
2189
 
209 andreas 2190
void TPageManager::reloadSystemPage(TPage *page)
2191
{
2192
    DECL_TRACER("TPageManager::reloadSystemPage(TPage *page)");
2193
 
2194
    if (!page)
2195
        return;
2196
 
2197
    vector<Button::TButton *> buttons = page->getAllButtons();
2198
    vector<Button::TButton *>::iterator iter;
210 andreas 2199
    TConfig::setTemporary(false);
209 andreas 2200
 
2201
    for (iter = buttons.begin(); iter != buttons.end(); ++iter)
2202
    {
2203
        Button::TButton *bt = *iter;
2204
 
2205
        if (bt->getAddressPort() == 0 && bt->getAddressChannel() > 0)
2206
        {
2207
            switch(bt->getAddressChannel())
2208
            {
2209
                case SYSTEM_ITEM_LOGLOGFILE:        bt->setTextOnly(TConfig::getLogFile(), -1); break;
2210
 
2211
                case SYSTEM_ITEM_NETLINX_IP:        bt->setTextOnly(TConfig::getController(), -1); break;
2212
                case SYSTEM_ITEM_NETLINX_PORT:      bt->setTextOnly(std::to_string(TConfig::getPort()), -1); break;
2213
                case SYSTEM_ITEM_NETLINX_CHANNEL:   bt->setTextOnly(std::to_string(TConfig::getChannel()), -1); break;
2214
                case SYSTEM_ITEM_NETLINX_PTYPE:     bt->setTextOnly(TConfig::getPanelType(), -1); break;
2215
                case SYSTEM_ITEM_FTPUSER:           bt->setTextOnly(TConfig::getFtpUser(), -1); break;
2216
                case SYSTEM_ITEM_FTPPASSWORD:       bt->setTextOnly(TConfig::getFtpPassword(), -1); break;
2217
                case SYSTEM_ITEM_FTPSURFACE:        bt->setTextOnly(TConfig::getFtpSurface(), -1); break;
210 andreas 2218
 
2219
                case SYSTEM_ITEM_SIPPROXY:          bt->setTextOnly(TConfig::getSIPproxy(), -1); break;
2220
                case SYSTEM_ITEM_SIPPORT:           bt->setTextOnly(std::to_string(TConfig::getSIPport()), -1); break;
2221
                case SYSTEM_ITEM_SIPSTUN:           bt->setTextOnly(TConfig::getSIPstun(), -1); break;
2222
                case SYSTEM_ITEM_SIPDOMAIN:         bt->setTextOnly(TConfig::getSIPdomain(), -1); break;
2223
                case SYSTEM_ITEM_SIPUSER:           bt->setTextOnly(TConfig::getSIPuser(), -1); break;
2224
                case SYSTEM_ITEM_SIPPASSWORD:       bt->setTextOnly(TConfig::getSIPpassword(), -1); break;
2225
 
2226
                case SYSTEM_ITEM_SYSTEMSOUND:       bt->setTextOnly(TConfig::getSystemSound(), -1); break;
2227
                case SYSTEM_ITEM_SINGLEBEEP:        bt->setTextOnly(TConfig::getSingleBeepSound(), -1); break;
2228
                case SYSTEM_ITEM_DOUBLEBEEP:        bt->setTextOnly(TConfig::getDoubleBeepSound(), -1); break;
209 andreas 2229
            }
2230
        }
210 andreas 2231
        else if (bt->getChannelPort() == 0 && bt->getChannelNumber() > 0)
2232
        {
2233
            switch(bt->getChannelNumber())
2234
            {
2235
                case SYSTEM_ITEM_DEBUGINFO:         bt->setActiveInstance(IS_LOG_INFO() ? 1 : 0); break;
2236
                case SYSTEM_ITEM_DEBUGWARNING:      bt->setActiveInstance(IS_LOG_WARNING() ? 1 : 0); break;
2237
                case SYSTEM_ITEM_DEBUGERROR:        bt->setActiveInstance(IS_LOG_ERROR() ? 1 : 0); break;
2238
                case SYSTEM_ITEM_DEBUGTRACE:        bt->setActiveInstance(IS_LOG_TRACE() ? 1 : 0); break;
2239
                case SYSTEM_ITEM_DEBUGDEBUG:        bt->setActiveInstance(IS_LOG_DEBUG() ? 1 : 0); break;
2240
                case SYSTEM_ITEM_DEBUGPROTOCOL:     bt->setActiveInstance(IS_LOG_PROTOCOL() ? 1 : 0); break;
2241
                case SYSTEM_ITEM_DEBUGALL:          bt->setActiveInstance(IS_LOG_ALL() ? 1 : 0); break;
2242
                case SYSTEM_ITEM_DEBUGLONG:         bt->setActiveInstance(TConfig::isLongFormat() ? 1 : 0); break;
2243
                case SYSTEM_ITEM_DEBUGPROFILE:      bt->setActiveInstance(TConfig::getProfiling() ? 1 : 0); break;
2244
 
2245
                case SYSTEM_ITEM_FTPPASSIVE:        bt->setActiveInstance(TConfig::getFtpPassive() ? 1 : 0); break;
2246
 
2247
                case SYSTEM_ITEM_SIPIPV4:           bt->setActiveInstance(TConfig::getSIPnetworkIPv4() ? 1 : 0); break;
2248
                case SYSTEM_ITEM_SIPIPV6:           bt->setActiveInstance(TConfig::getSIPnetworkIPv6() ? 1 : 0); break;
2249
                case SYSTEM_ITEM_SIPENABLE:         bt->setActiveInstance(TConfig::getSIPstatus() ? 1 : 0); break;
2250
                case SYSTEM_ITEM_SIPIPHONE:         bt->setActiveInstance(TConfig::getSIPiphone() ? 1 : 0); break;
2251
 
2252
                case SYSTEM_ITEM_SOUNDSWITCH:       bt->setActiveInstance(TConfig::getSystemSoundState() ? 1 : 0); break;
2253
 
2254
                case SYSTEM_ITEM_VIEWSCALEFIT:      bt->setActiveInstance(TConfig::getScale() ? 1 : 0); break;
2255
                case SYSTEM_ITEM_VIEWBANNER:        bt->setActiveInstance(TConfig::showBanner() ? 1 : 0); break;
2256
                case SYSTEM_ITEM_VIEWNOTOOLBAR:     bt->setActiveInstance(TConfig::getToolbarSuppress() ? 1 : 0); break;
2257
                case SYSTEM_ITEM_VIEWTOOLBAR:       bt->setActiveInstance(TConfig::getToolbarForce() ? 1 : 0); break;
2258
                case SYSTEM_ITEM_VIEWROTATE:        bt->setActiveInstance(TConfig::getRotationFixed() ? 1 : 0); break;
2259
            }
2260
        }
2261
        else if (bt->getLevelPort() == 0 && bt->getLevelValue() > 0)
2262
        {
2263
            switch(bt->getLevelValue())
2264
            {
2265
                case SYSTEM_ITEM_SYSVOLUME:         bt->drawBargraph(0, TConfig::getSystemVolume(), false); break;
2266
                case SYSTEM_ITEM_SYSGAIN:           bt->drawBargraph(0, TConfig::getSystemGain(), false); break;
2267
            }
2268
        }
209 andreas 2269
    }
2270
}
2271
 
198 andreas 2272
bool TPageManager::setPage(int PageID, bool forget)
15 andreas 2273
{
198 andreas 2274
    DECL_TRACER("TPageManager::setPage(int PageID, bool forget)");
15 andreas 2275
 
295 andreas 2276
    return _setPageDo(PageID, "", forget);
15 andreas 2277
}
2278
 
168 andreas 2279
bool TPageManager::setPage(const string& name, bool forget)
15 andreas 2280
{
190 andreas 2281
    DECL_TRACER("TPageManager::setPage(const string& name, bool forget)");
15 andreas 2282
 
295 andreas 2283
    return _setPageDo(0, name, forget);
15 andreas 2284
}
2285
 
295 andreas 2286
bool TPageManager::_setPageDo(int pageID, const string& name, bool forget)
2287
{
2288
    DECL_TRACER("TPageManager::_setPageDo(int pageID, const string& name, bool forget)");
2289
 
2290
    TPage *pg = nullptr;
2291
 
2292
    if (pageID > 0 && mActualPage == pageID)
343 andreas 2293
    {
2294
#if TESTMODE == 1
2295
        __success = true;
2296
        setScreenDone();
2297
#endif
295 andreas 2298
        return true;
343 andreas 2299
    }
295 andreas 2300
    else if (!name.empty())
2301
    {
2302
        pg = getPage(mActualPage);
2303
 
2304
        if (pg && pg->getName().compare(name) == 0)
343 andreas 2305
        {
2306
#if TESTMODE == 1
2307
            __success = true;
2308
            setScreenDone();
2309
#endif
295 andreas 2310
            return true;
343 andreas 2311
        }
295 andreas 2312
    }
2313
    else if (pageID > 0)
2314
        pg = getPage(mActualPage);
2315
    else
343 andreas 2316
    {
2317
#if TESTMODE == 1
2318
        setScreenDone();
2319
#endif
295 andreas 2320
        return false;
343 andreas 2321
    }
295 andreas 2322
 
2323
    // FIXME: Make this a vector array to hold a larger history!
2324
    if (!forget)
2325
        mPreviousPage = mActualPage;    // Necessary to be able to jump back to at least the last previous page
2326
 
2327
    if (pg)
2328
        pg->drop();
2329
 
2330
    mActualPage = 0;
2331
    PAGELIST_T listPg;
2332
 
2333
    if (pageID > 0)
2334
        listPg = findPage(pageID);
2335
    else
2336
        listPg = findPage(name);
2337
 
2338
    bool refresh = false;
2339
 
2340
    if ((pg = loadPage(listPg, &refresh)) == nullptr)
343 andreas 2341
    {
2342
#if TESTMODE == 1
2343
        setScreenDone();
2344
#endif
295 andreas 2345
        return false;
343 andreas 2346
    }
295 andreas 2347
 
2348
    mActualPage = pg->getNumber();
2349
 
2350
    if (mActualPage >= SYSTEM_PAGE_START && !refresh)
2351
        reloadSystemPage(pg);
2352
 
2353
    int width = (mActualPage >= SYSTEM_PAGE_START ? mSystemSettings->getWidth() : mTSettings->getWidth());
2354
    int height = (mActualPage >= SYSTEM_PAGE_START ? mSystemSettings->getHeight() : mTSettings->getHeight());
2355
 
2356
    if (_setPage)
2357
        _setPage((mActualPage << 16) & 0xffff0000, width, height);
2358
 
2359
    pg->show();
2360
    return true;
2361
}
2362
 
2363
 
4 andreas 2364
TSubPage *TPageManager::getSubPage(int pageID)
2365
{
2366
    DECL_TRACER("TPageManager::getSubPage(int pageID)");
2367
 
2368
    SPCHAIN_T *p = mSPchain;
2369
 
2370
    while(p)
2371
    {
2372
        if (p->page->getNumber() == pageID)
2373
            return p->page;
2374
 
2375
        p = p->next;
2376
    }
2377
 
2378
    return nullptr;
2379
}
2380
 
2381
TSubPage *TPageManager::getSubPage(const std::string& name)
2382
{
2383
    DECL_TRACER("TPageManager::getSubPage(const std::string& name)");
2384
 
2385
    SPCHAIN_T *p = mSPchain;
2386
 
2387
    while (p)
2388
    {
2389
        if (p->page->getName().compare(name) == 0)
2390
            return p->page;
2391
 
2392
        p = p->next;
2393
    }
2394
 
146 andreas 2395
    MSG_DEBUG("Page " << name << " not found in cache.");
4 andreas 2396
    return nullptr;
2397
}
2398
 
96 andreas 2399
TSubPage *TPageManager::deliverSubPage(const string& name, TPage **pg)
2400
{
198 andreas 2401
    DECL_TRACER("TPageManager::deliverSubPage(const string& name, TPage **pg)");
96 andreas 2402
 
2403
    TPage *page = getActualPage();
2404
 
2405
    if (!page)
2406
    {
2407
        MSG_ERROR("No actual page loaded!");
2408
        return nullptr;
2409
    }
2410
 
2411
    if (pg)
2412
        *pg = page;
2413
 
2414
    TSubPage *subPage = getSubPage(name);
2415
 
2416
    if (!subPage)
2417
    {
2418
        if (!readSubPage(name))
2419
        {
2420
            MSG_ERROR("Error reading subpage " << name);
2421
            return nullptr;
2422
        }
2423
 
2424
        subPage = getSubPage(name);
2425
 
2426
        if (!subPage)
2427
        {
2428
            MSG_ERROR("Fatal: A page with name " << name << " does not exist!");
2429
            return nullptr;
2430
        }
350 andreas 2431
 
2432
        subPage->setParent(page->getHandle());
96 andreas 2433
    }
2434
 
2435
    return subPage;
2436
}
2437
 
198 andreas 2438
TSubPage *TPageManager::deliverSubPage(int number, TPage **pg)
2439
{
2440
    DECL_TRACER("TPageManager::deliverSubPage(int number, TPage **pg)");
2441
 
2442
    TPage *page = getActualPage();
2443
 
2444
    if (!page)
2445
    {
2446
        MSG_ERROR("No actual page loaded!");
2447
        return nullptr;
2448
    }
2449
 
2450
    if (pg)
2451
        *pg = page;
2452
 
2453
    TSubPage *subPage = getSubPage(number);
2454
 
2455
    if (!subPage)
2456
    {
2457
        if (!readSubPage(number))
2458
        {
2459
            MSG_ERROR("Error reading subpage " << number);
2460
            return nullptr;
2461
        }
2462
 
2463
        subPage = getSubPage(number);
2464
 
2465
        if (!subPage)
2466
        {
2467
            MSG_ERROR("Fatal: A page with name " << number << " does not exist!");
2468
            return nullptr;
2469
        }
350 andreas 2470
 
2471
        subPage->setParent(page->getHandle());
198 andreas 2472
    }
2473
 
2474
    return subPage;
2475
}
2476
 
3 andreas 2477
bool TPageManager::readPages()
2478
{
2479
    DECL_TRACER("TPageManager::readPages()");
2480
 
2481
    if (!mPageList)
2482
    {
2483
        MSG_ERROR("Page list is not initialized!");
2484
        TError::setError();
2485
        return false;
2486
    }
2487
 
2488
    // Read all pages
2489
    vector<PAGELIST_T> pageList = mPageList->getPagelist();
2490
 
83 andreas 2491
    if (pageList.size() > 0)
3 andreas 2492
    {
83 andreas 2493
        vector<PAGELIST_T>::iterator pgIter;
14 andreas 2494
 
118 andreas 2495
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
14 andreas 2496
        {
83 andreas 2497
            TPage *page = new TPage(pgIter->name+".xml");
14 andreas 2498
 
83 andreas 2499
            if (TError::isError())
2500
            {
2501
                delete page;
2502
                return false;
2503
            }
3 andreas 2504
 
83 andreas 2505
            page->setPalette(mPalette);
2506
            page->setFonts(mFonts);
2507
            page->registerCallback(_setBackground);
2508
            page->registerCallbackDB(_displayButton);
2509
            page->regCallPlayVideo(_callPlayVideo);
2510
 
2511
            if (!addPage(page))
2512
                return false;
2513
        }
3 andreas 2514
    }
2515
 
348 andreas 2516
    vector<SUBPAGELIST_T> subPageList = mPageList->getSubPageList();
3 andreas 2517
 
83 andreas 2518
    if (subPageList.size() > 0)
3 andreas 2519
    {
83 andreas 2520
        vector<SUBPAGELIST_T>::iterator spgIter;
14 andreas 2521
 
118 andreas 2522
        for (spgIter = subPageList.begin(); spgIter != subPageList.end(); ++spgIter)
14 andreas 2523
        {
83 andreas 2524
            TSubPage *page = new TSubPage(spgIter->name+".xml");
14 andreas 2525
 
83 andreas 2526
            if (TError::isError())
2527
            {
2528
                delete page;
2529
                return false;
2530
            }
3 andreas 2531
 
83 andreas 2532
            page->setPalette(mPalette);
2533
            page->setFonts(mFonts);
2534
            page->registerCallback(_setBackground);
2535
            page->registerCallbackDB(_displayButton);
2536
            page->regCallDropSubPage(_callDropSubPage);
2537
            page->regCallPlayVideo(_callPlayVideo);
2538
            page->setGroup(spgIter->group);
2539
 
2540
            if (!addSubPage(page))
2541
                return false;
2542
        }
3 andreas 2543
    }
2544
 
2545
    return true;
2546
}
2547
 
2548
bool TPageManager::readPage(const std::string& name)
2549
{
2550
    DECL_TRACER("TPageManager::readPage(const std::string& name)");
2551
 
2552
    PAGELIST_T page = findPage(name);
2553
 
206 andreas 2554
    if ((page.pageID <= 0 || page.pageID >= MAX_PAGE_ID) && page.pageID < SYSTEM_PAGE_START && page.pageID >= SYSTEM_SUBPAGE_START)
3 andreas 2555
    {
2556
        MSG_ERROR("Page " << name << " not found!");
2557
        return false;
2558
    }
2559
 
43 andreas 2560
    TPage *pg;
14 andreas 2561
 
43 andreas 2562
    if (name.compare("_progress") == 0)
2563
        pg = new TPage(name);
2564
    else
2565
        pg = new TPage(page.name+".xml");
2566
 
14 andreas 2567
    if (TError::isError())
2568
    {
2569
        delete pg;
2570
        return false;
2571
    }
2572
 
4 andreas 2573
    pg->setPalette(mPalette);
7 andreas 2574
    pg->setFonts(mFonts);
2575
    pg->registerCallback(_setBackground);
2576
    pg->registerCallbackDB(_displayButton);
21 andreas 2577
    pg->regCallPlayVideo(_callPlayVideo);
3 andreas 2578
 
2579
    if (!addPage(pg))
2580
        return false;
2581
 
2582
    return true;
2583
}
2584
 
2585
bool TPageManager::readPage(int ID)
2586
{
2587
    DECL_TRACER("TPageManager::readPage(int ID)");
2588
 
16 andreas 2589
    TError::clear();
3 andreas 2590
    PAGELIST_T page = findPage(ID);
2591
 
2592
    if (page.pageID <= 0)
2593
    {
2594
        MSG_ERROR("Page with ID " << ID << " not found!");
2595
        return false;
2596
    }
2597
 
43 andreas 2598
    TPage *pg;
14 andreas 2599
 
43 andreas 2600
    if (ID == 300)      // Progress page of system?
2601
        pg = new TPage("_progress");
2602
    else
2603
        pg = new TPage(page.name+".xml");
2604
 
14 andreas 2605
    if (TError::isError())
2606
    {
2607
        delete pg;
2608
        return false;
2609
    }
2610
 
4 andreas 2611
    pg->setPalette(mPalette);
7 andreas 2612
    pg->setFonts(mFonts);
2613
    pg->registerCallback(_setBackground);
2614
    pg->registerCallbackDB(_displayButton);
21 andreas 2615
    pg->regCallPlayVideo(_callPlayVideo);
3 andreas 2616
 
2617
    if (!addPage(pg))
2618
        return false;
2619
 
2620
    return true;
2621
}
2622
 
2623
bool TPageManager::readSubPage(const std::string& name)
2624
{
2625
    DECL_TRACER("TPageManager::readSubPage(const std::string& name)");
2626
 
16 andreas 2627
    TError::clear();
3 andreas 2628
    SUBPAGELIST_T page = findSubPage(name);
2629
 
206 andreas 2630
    if (page.pageID < MAX_PAGE_ID || (page.pageID >= SYSTEM_PAGE_START && page.pageID < SYSTEM_SUBPAGE_START))
3 andreas 2631
    {
2632
        MSG_ERROR("Subpage " << name << " not found!");
2633
        return false;
2634
    }
2635
 
14 andreas 2636
    if (haveSubPage(name))
2637
        return true;
2638
 
3 andreas 2639
    TSubPage *pg = new TSubPage(page.name+".xml");
14 andreas 2640
 
2641
    if (TError::isError())
2642
    {
2643
        delete pg;
2644
        return false;
2645
    }
2646
 
4 andreas 2647
    pg->setPalette(mPalette);
7 andreas 2648
    pg->setFonts(mFonts);
2649
    pg->registerCallback(_setBackground);
2650
    pg->registerCallbackDB(_displayButton);
11 andreas 2651
    pg->regCallDropSubPage(_callDropSubPage);
21 andreas 2652
    pg->regCallPlayVideo(_callPlayVideo);
11 andreas 2653
    pg->setGroup(page.group);
3 andreas 2654
 
2655
    if (!addSubPage(pg))
14 andreas 2656
    {
2657
        delete pg;
3 andreas 2658
        return false;
14 andreas 2659
    }
3 andreas 2660
 
2661
    return true;
2662
}
2663
 
2664
bool TPageManager::readSubPage(int ID)
2665
{
2666
    DECL_TRACER("TPageManager::readSubPage(int ID)");
2667
 
16 andreas 2668
    TError::clear();
3 andreas 2669
    SUBPAGELIST_T page = findSubPage(ID);
2670
 
154 andreas 2671
    if (page.pageID <= MAX_PAGE_ID)
3 andreas 2672
    {
2673
        MSG_ERROR("Subpage with ID " << ID << " not found!");
2674
        return false;
2675
    }
2676
 
2677
    TSubPage *pg = new TSubPage(page.name+".xml");
14 andreas 2678
 
2679
    if (TError::isError())
2680
    {
2681
        delete pg;
2682
        return false;
2683
    }
2684
 
4 andreas 2685
    pg->setPalette(mPalette);
7 andreas 2686
    pg->setFonts(mFonts);
2687
    pg->registerCallback(_setBackground);
2688
    pg->registerCallbackDB(_displayButton);
11 andreas 2689
    pg->regCallDropSubPage(_callDropSubPage);
21 andreas 2690
    pg->regCallPlayVideo(_callPlayVideo);
11 andreas 2691
    pg->setGroup(page.group);
3 andreas 2692
 
2693
    if (!addSubPage(pg))
2694
        return false;
2695
 
2696
    return true;
2697
}
2698
 
279 andreas 2699
vector<TSubPage *> TPageManager::createSubViewList(int id)
2700
{
2701
    DECL_TRACER("TPageManager::createSubViewList(int id)");
2702
 
2703
    vector<TSubPage *> subviews;
2704
 
2705
    if (id <= 0)
2706
        return subviews;
2707
 
2708
    if (!mPageList)
2709
    {
2710
        MSG_WARNING("Missing page list and because of this can't make a subview list!");
2711
        return subviews;
2712
    }
2713
 
2714
    SUBVIEWLIST_T slist = mPageList->findSubViewList(id);
2715
 
2716
    if (slist.id <= 0 || slist.items.empty())
2717
    {
2718
        if (slist.id <= 0)
2719
        {
2720
            MSG_WARNING("Found no subview list with ID " << id);
2721
        }
2722
        else
2723
        {
300 andreas 2724
            MSG_WARNING("Subview list " << id << " has no items!");
279 andreas 2725
        }
2726
 
2727
        return subviews;
2728
    }
2729
 
2730
    vector<SUBVIEWITEM_T>::iterator iter;
2731
 
2732
    for (iter = slist.items.begin(); iter != slist.items.end(); ++iter)
2733
    {
2734
        if (!haveSubPage(iter->pageID))
2735
        {
2736
            if (!readSubPage(iter->pageID))
2737
                return vector<TSubPage *>();
2738
        }
2739
 
284 andreas 2740
        TSubPage *pg = getSubPage(iter->pageID);
279 andreas 2741
 
2742
        if (pg)
2743
            subviews.push_back(pg);
284 andreas 2744
        else
2745
        {
2746
            MSG_DEBUG("No subpage with ID " << id);
2747
        }
279 andreas 2748
    }
2749
 
300 andreas 2750
    MSG_DEBUG("Found " << subviews.size() << " subview items.");
279 andreas 2751
    return subviews;
2752
}
2753
 
280 andreas 2754
void TPageManager::showSubViewList(int id, Button::TButton *bt)
279 andreas 2755
{
280 andreas 2756
    DECL_TRACER("TPageManager::showSubViewList(int id, Button::TButton *bt)");
279 andreas 2757
 
2758
    vector<TSubPage *> subviews = createSubViewList(id);
2759
 
303 andreas 2760
    if (subviews.empty() || !_addViewButtonItems || !bt)
284 andreas 2761
    {
2762
        MSG_DEBUG("Number views: " << subviews.size() << (_addViewButtonItems ? ", addView" : ", NO addView") << (_displayViewButton ? " display" : " NO display"));
279 andreas 2763
        return;
284 andreas 2764
    }
279 andreas 2765
 
293 andreas 2766
    ulong btHandle = bt->getHandle();
2767
    MSG_DEBUG("Working on button " << handleToString(btHandle) << " (" << bt->getName() << ") with " << subviews.size() << " pages.");
289 andreas 2768
    TBitmap bm = bt->getLastBitmap();
2769
    TColor::COLOR_T fillColor = TColor::getAMXColor(bt->getFillColor());
293 andreas 2770
    _displayViewButton(btHandle, bt->getParent(), bt->isSubViewVertical(), bm, bt->getWidth(), bt->getHeight(), bt->getLeftPosition(), bt->getTopPosition(), bt->getSubViewSpace(), fillColor);
280 andreas 2771
 
2772
    vector<PGSUBVIEWITEM_T> items;
2773
    PGSUBVIEWITEM_T svItem;
2774
    PGSUBVIEWATOM_T svAtom;
279 andreas 2775
    vector<TSubPage *>::iterator iter;
2776
 
2777
    for (iter = subviews.begin(); iter != subviews.end(); ++iter)
2778
    {
280 andreas 2779
        TSubPage *sub = *iter;
306 andreas 2780
        sub->setParent(btHandle);
279 andreas 2781
 
289 andreas 2782
        svItem.clear();
2783
        Button::TButton *button = sub->getFirstButton();
2784
        SkBitmap bitmap = sub->getBgImage();
280 andreas 2785
 
2786
        svItem.handle = sub->getHandle();
289 andreas 2787
        svItem.parent = btHandle;
280 andreas 2788
        svItem.width = sub->getWidth();
2789
        svItem.height = sub->getHeight();
281 andreas 2790
        svItem.bgcolor = TColor::getAMXColor(sub->getFillColor());
300 andreas 2791
        svItem.scrollbar = bt->getSubViewScrollbar();
2792
        svItem.scrollbarOffset = bt->getSubViewScrollbarOffset();
2793
        svItem.position = bt->getSubViewAnchor();
302 andreas 2794
        svItem.wrap = bt->getWrapSubViewPages();
280 andreas 2795
 
289 andreas 2796
        if (!bitmap.empty())
2797
            svItem.image.setBitmap((unsigned char *)bitmap.getPixels(), bitmap.info().width(), bitmap.info().height(), bitmap.info().bytesPerPixel());
280 andreas 2798
 
289 andreas 2799
        while (button)
280 andreas 2800
        {
300 andreas 2801
            button->drawButton(0, false, true);
289 andreas 2802
            svAtom.clear();
2803
            svAtom.handle = button->getHandle();
280 andreas 2804
            svAtom.parent = sub->getHandle();
289 andreas 2805
            svAtom.width = button->getWidth();
2806
            svAtom.height = button->getHeight();
2807
            svAtom.left = button->getLeftPosition();
2808
            svAtom.top = button->getTopPosition();
300 andreas 2809
            svAtom.bgcolor = TColor::getAMXColor(button->getFillColor(button->getActiveInstance()));
293 andreas 2810
            svAtom.bounding = button->getBounding();
289 andreas 2811
            Button::BITMAP_t bmap = button->getLastImage();
280 andreas 2812
 
289 andreas 2813
            if (bmap.buffer)
300 andreas 2814
                svAtom.image.setBitmap(bmap.buffer, bmap.width, bmap.height, (int)(bmap.rowBytes / bmap.width));
289 andreas 2815
 
280 andreas 2816
            svItem.atoms.push_back(svAtom);
289 andreas 2817
            button = sub->getNextButton();
280 andreas 2818
        }
2819
 
2820
        items.push_back(svItem);
279 andreas 2821
    }
281 andreas 2822
 
285 andreas 2823
    _addViewButtonItems(bt->getHandle(), items);
284 andreas 2824
 
2825
    if (_pageFinished)
306 andreas 2826
        _pageFinished(bt->getHandle());
279 andreas 2827
}
2828
 
300 andreas 2829
void TPageManager::updateSubViewItem(Button::TButton *bt)
2830
{
2831
    DECL_TRACER("TPageManager::updateSubViewItem(Button::TButton *bt)");
2832
 
303 andreas 2833
    if (!bt)
300 andreas 2834
        return;
2835
 
303 andreas 2836
    updview_mutex.lock();
2837
    mUpdateViews.push_back(bt);
2838
    updview_mutex.unlock();
2839
}
2840
 
2841
void TPageManager::_updateSubViewItem(Button::TButton *bt)
2842
{
2843
    DECL_TRACER("TPageManager::_updateSubViewItem(Button::TButton *bt)");
2844
 
2845
    if (!mPageList || !_updateViewButtonItem)
2846
        return;
2847
 
300 andreas 2848
    // The parent of this kind of button is always the button of type subview.
2849
    // If we take the parent handle and extract the page ID (upper 16 bits)
2850
    // we get the page ID of the subpage or page ID of the page the button is
2851
    // ordered to.
2852
    int pageID = (bt->getParent() >> 16) & 0x0000ffff;
306 andreas 2853
    ulong parent = 0;
300 andreas 2854
    Button::TButton *button = nullptr;
2855
    PGSUBVIEWITEM_T item;
2856
    PGSUBVIEWATOM_T atom;
2857
    SkBitmap bitmap;
2858
    TPage *pg = nullptr;
2859
    TSubPage *sub = nullptr;
2860
 
2861
    if (pageID < REGULAR_SUBPAGE_START)     // Is it a page?
2862
    {
2863
        pg = getPage(pageID);
2864
 
2865
        if (!pg)
2866
        {
2867
            MSG_WARNING("Invalid page " << pageID << "!");
2868
            return;
2869
        }
2870
 
2871
        button = pg->getFirstButton();
2872
        bitmap = pg->getBgImage();
2873
 
2874
        item.handle = pg->getHandle();
2875
        item.parent = bt->getParent();
2876
        item.width = pg->getWidth();
2877
        item.height = pg->getHeight();
2878
        item.bgcolor = TColor::getAMXColor(pg->getFillColor());
2879
    }
2880
    else
2881
    {
2882
        sub = getSubPage(pageID);
2883
 
2884
        if (!sub)
2885
        {
2886
            MSG_WARNING("Couldn't find the subpage " << pageID << "!");
2887
            return;
2888
        }
2889
 
306 andreas 2890
        parent = sub->getParent();
300 andreas 2891
        button = sub->getFirstButton();
2892
        bitmap = sub->getBgImage();
2893
 
2894
        item.handle = sub->getHandle();
2895
        item.parent = bt->getParent();
2896
        item.width = sub->getWidth();
2897
        item.height = sub->getHeight();
303 andreas 2898
        item.position = bt->getSubViewAnchor();
300 andreas 2899
        item.bgcolor = TColor::getAMXColor(sub->getFillColor());
2900
    }
2901
 
2902
 
2903
    if (!bitmap.empty())
2904
        item.image.setBitmap((unsigned char *)bitmap.getPixels(), bitmap.info().width(), bitmap.info().height(), bitmap.info().bytesPerPixel());
2905
 
2906
    while (button)
2907
    {
2908
        atom.clear();
2909
        atom.handle = button->getHandle();
303 andreas 2910
        atom.parent = item.handle;
300 andreas 2911
        atom.width = button->getWidth();
2912
        atom.height = button->getHeight();
2913
        atom.left = button->getLeftPosition();
2914
        atom.top = button->getTopPosition();
2915
        atom.bgcolor = TColor::getAMXColor(button->getFillColor(button->getActiveInstance()));
2916
        atom.bounding = button->getBounding();
2917
        Button::BITMAP_t bmap = button->getLastImage();
2918
 
2919
        if (bmap.buffer)
2920
            atom.image.setBitmap(bmap.buffer, bmap.width, bmap.height, (int)(bmap.rowBytes / bmap.width));
2921
 
2922
        item.atoms.push_back(atom);
2923
        button = (pg ? pg->getNextButton() : sub->getNextButton());
2924
    }
2925
 
306 andreas 2926
    _updateViewButtonItem(item, parent);
300 andreas 2927
}
2928
 
192 andreas 2929
void TPageManager::updateActualPage()
2930
{
2931
    DECL_TRACER("TPageManager::updateActualPage()");
2932
 
2933
    if (!mActualPage)
2934
        return;
2935
 
2936
    TPage *pg = getPage(mActualPage);
2937
    Button::TButton *bt = pg->getFirstButton();
2938
 
2939
    while (bt)
2940
    {
2941
        bt->refresh();
2942
        bt = pg->getNextButton();
2943
    }
2944
}
2945
 
2946
void TPageManager::updateSubpage(int ID)
2947
{
2948
    DECL_TRACER("TPageManager::updateSubpage(int ID)");
2949
 
2950
    TSubPage *pg = getSubPage(ID);
2951
 
2952
    if (!pg)
2953
        return;
2954
 
2955
    vector<Button::TButton *> blist = pg->getAllButtons();
2956
    vector<Button::TButton *>::iterator iter;
2957
 
2958
    if (blist.empty())
2959
        return;
2960
 
2961
    for (iter = blist.begin(); iter != blist.end(); ++iter)
2962
    {
2963
        Button::TButton *bt = *iter;
2964
        bt->refresh();
2965
    }
2966
}
2967
 
2968
void TPageManager::updateSubpage(const std::string &name)
2969
{
2970
    DECL_TRACER("TPageManager::updateSubpage(const std::string &name)");
2971
 
2972
    TSubPage *pg = getSubPage(name);
2973
 
2974
    if (!pg)
2975
        return;
2976
 
2977
    vector<Button::TButton *> blist = pg->getAllButtons();
2978
    vector<Button::TButton *>::iterator iter;
2979
 
2980
    if (blist.empty())
2981
        return;
2982
 
2983
    for (iter = blist.begin(); iter != blist.end(); ++iter)
2984
    {
2985
        Button::TButton *bt = *iter;
2986
        bt->refresh();
2987
    }
2988
}
2989
 
3 andreas 2990
/******************** Internal private methods *********************/
2991
 
2992
PAGELIST_T TPageManager::findPage(const std::string& name)
2993
{
2994
    DECL_TRACER("TPageManager::findPage(const std::string& name)");
2995
 
194 andreas 2996
    vector<PAGELIST_T> pageList;
3 andreas 2997
 
194 andreas 2998
    if (!mSetupActive)
2999
        pageList = mPageList->getPagelist();
3000
    else
3001
        pageList = mPageList->getSystemPagelist();
3002
 
83 andreas 3003
    if (pageList.size() > 0)
3 andreas 3004
    {
83 andreas 3005
        vector<PAGELIST_T>::iterator pgIter;
3006
 
118 andreas 3007
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 3008
        {
3009
            if (pgIter->name.compare(name) == 0)
3010
                return *pgIter;
3011
        }
3 andreas 3012
    }
3013
 
194 andreas 3014
    MSG_WARNING("Page " << name << " not found!");
3 andreas 3015
    return PAGELIST_T();
3016
}
3017
 
3018
PAGELIST_T TPageManager::findPage(int ID)
3019
{
3020
    DECL_TRACER("TPageManager::findPage(int ID)");
3021
 
206 andreas 3022
    vector<PAGELIST_T> pageList = (ID < SYSTEM_PAGE_START ? mPageList->getPagelist() : mPageList->getSystemPagelist());
3 andreas 3023
 
83 andreas 3024
    if (pageList.size() > 0)
3 andreas 3025
    {
83 andreas 3026
        vector<PAGELIST_T>::iterator pgIter;
3027
 
118 andreas 3028
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 3029
        {
3030
            if (pgIter->pageID == ID)
3031
                return *pgIter;
3032
        }
3 andreas 3033
    }
3034
 
3035
    return PAGELIST_T();
3036
}
3037
 
3038
SUBPAGELIST_T TPageManager::findSubPage(const std::string& name)
3039
{
3040
    DECL_TRACER("TPageManager::findSubPage(const std::string& name)");
3041
 
348 andreas 3042
    vector<SUBPAGELIST_T> pageList = (mSetupActive ? mPageList->getSystemSupPageList() : mPageList->getSubPageList());
3 andreas 3043
 
83 andreas 3044
    if (pageList.size() > 0)
3 andreas 3045
    {
83 andreas 3046
        vector<SUBPAGELIST_T>::iterator pgIter;
3047
 
118 andreas 3048
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 3049
        {
3050
            if (pgIter->name.compare(name) == 0)
3051
                return *pgIter;
3052
        }
3 andreas 3053
    }
3054
 
3055
    return SUBPAGELIST_T();
3056
}
3057
 
3058
SUBPAGELIST_T TPageManager::findSubPage(int ID)
3059
{
3060
    DECL_TRACER("TPageManager::findSubPage(int ID)");
3061
 
348 andreas 3062
    vector<SUBPAGELIST_T> pageList = (ID < SYSTEM_PAGE_START ? mPageList->getSubPageList() : mPageList->getSystemSupPageList());
3 andreas 3063
 
83 andreas 3064
    if (pageList.size() > 0)
3 andreas 3065
    {
83 andreas 3066
        vector<SUBPAGELIST_T>::iterator pgIter;
3067
 
118 andreas 3068
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 3069
        {
3070
            if (pgIter->pageID == ID)
3071
                return *pgIter;
3072
        }
3 andreas 3073
    }
3074
 
3075
    return SUBPAGELIST_T();
3076
}
3077
 
3078
bool TPageManager::addPage(TPage* pg)
3079
{
3080
    DECL_TRACER("TPageManager::addPage(TPage* pg)");
3081
 
3082
    if (!pg)
3083
    {
3084
        MSG_ERROR("Parameter is NULL!");
3085
        TError::setError();
3086
        return false;
3087
    }
3088
 
3089
    PCHAIN_T *chain = new PCHAIN_T;
3090
    chain->page = pg;
5 andreas 3091
    chain->next = nullptr;
3 andreas 3092
 
3093
    if (mPchain)
3094
    {
3095
        PCHAIN_T *p = mPchain;
3096
 
3097
        while (p->next)
3098
            p = p->next;
3099
 
3100
        p->next = chain;
3101
    }
3102
    else
14 andreas 3103
    {
3 andreas 3104
        mPchain = chain;
14 andreas 3105
        setPChain(mPchain);
3106
    }
3 andreas 3107
 
156 andreas 3108
//    MSG_DEBUG("Added page " << chain->page->getName());
3 andreas 3109
    return true;
3110
}
3111
 
3112
bool TPageManager::addSubPage(TSubPage* pg)
3113
{
3114
    DECL_TRACER("TPageManager::addSubPage(TSubPage* pg)");
3115
 
3116
    if (!pg)
3117
    {
3118
        MSG_ERROR("Parameter is NULL!");
3119
        TError::setError();
3120
        return false;
3121
    }
3122
 
14 andreas 3123
    if (haveSubPage(pg->getNumber()))
3124
    {
3125
        MSG_ERROR("Subpage " << pg->getNumber() << ", " << pg->getName() << " is already in chain!");
3126
        return false;
3127
    }
3128
 
3 andreas 3129
    SPCHAIN_T *chain = new SPCHAIN_T;
3130
    chain->page = pg;
5 andreas 3131
    chain->next = nullptr;
3 andreas 3132
 
3133
    if (mSPchain)
3134
    {
3135
        SPCHAIN_T *p = mSPchain;
3136
 
3137
        while (p->next)
3138
            p = p->next;
3139
 
3140
        p->next = chain;
3141
    }
3142
    else
14 andreas 3143
    {
3 andreas 3144
        mSPchain = chain;
14 andreas 3145
        setSPChain(mSPchain);
3146
    }
3 andreas 3147
 
3148
    return true;
3149
}
4 andreas 3150
 
11 andreas 3151
void TPageManager::dropAllPages()
3152
{
3153
    DECL_TRACER("TPageManager::dropAllPages()");
3154
 
3155
    PCHAIN_T *pg = mPchain;
3156
    PCHAIN_T *next = nullptr;
3157
 
3158
    while (pg)
3159
    {
3160
        next = pg->next;
3161
 
3162
        if (pg->page)
3163
        {
3164
            if (_callDropPage)
3165
                _callDropPage((pg->page->getNumber() << 16) & 0xffff0000);
3166
 
3167
            delete pg->page;
3168
        }
3169
 
3170
        delete pg;
3171
        pg = next;
3172
    }
14 andreas 3173
 
3174
    mPchain = nullptr;
3175
    setPChain(mPchain);
11 andreas 3176
}
3177
 
3178
void TPageManager::dropAllSubPages()
3179
{
3180
    DECL_TRACER("TPageManager::dropAllSubPages()");
3181
 
3182
    SPCHAIN_T *spg = mSPchain;
3183
    SPCHAIN_T *next;
3184
 
3185
    while (spg)
3186
    {
3187
        next = spg->next;
3188
 
3189
        if (spg->page)
3190
        {
3191
            if (_callDropSubPage)
350 andreas 3192
                _callDropSubPage((spg->page->getNumber() << 16) & 0xffff0000, spg->page->getParent());
11 andreas 3193
 
3194
            delete spg->page;
3195
        }
3196
 
3197
        delete spg;
3198
        spg = next;
3199
    }
14 andreas 3200
 
3201
    mSPchain = nullptr;
3202
    setSPChain(mSPchain);
11 andreas 3203
}
3204
 
44 andreas 3205
bool TPageManager::destroyAll()
3206
{
3207
    DECL_TRACER("TPageManager::destroyAll()");
3208
 
3209
    dropAllSubPages();
3210
    dropAllPages();
3211
    mActualPage = 0;
3212
    mPreviousPage = 0;
3213
    mActualGroupName.clear();
3214
 
3215
    if (mPageList)
3216
    {
3217
        delete mPageList;
3218
        mPageList = nullptr;
3219
    }
3220
 
3221
    if (mTSettings)
3222
    {
3223
        delete mTSettings;
3224
        mTSettings = nullptr;
3225
    }
3226
 
194 andreas 3227
    if (mSystemSettings)
3228
    {
3229
        delete mSystemSettings;
3230
        mSystemSettings = nullptr;
3231
    }
3232
 
44 andreas 3233
    if (mPalette)
3234
    {
3235
        delete mPalette;
3236
        mPalette = nullptr;
3237
    }
3238
 
3239
    if (mFonts)
3240
    {
3241
        delete mFonts;
3242
        mFonts = nullptr;
3243
    }
3244
 
3245
    if (mExternal)
3246
    {
3247
        delete mExternal;
3248
        mExternal = nullptr;
3249
    }
3250
 
3251
    if (gPrjResources)
3252
    {
3253
        delete gPrjResources;
3254
        gPrjResources = nullptr;
3255
    }
3256
 
3257
    if (gIcons)
3258
    {
3259
        delete gIcons;
3260
        gIcons = nullptr;
3261
    }
3262
 
3263
    if (TError::isError())
3264
        return false;
3265
 
3266
    return true;
3267
}
3268
 
150 andreas 3269
bool TPageManager::overlap(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2)
3270
{
3271
    DECL_TRACER("TPageManager::overlap(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2)");
3272
 
3273
    struct point
3274
    {
3275
        int x;
3276
        int y;
3277
    };
3278
 
3279
    struct point l1, r1, l2, r2;
3280
 
3281
    l1.x = x1;
3282
    l1.y = y1;
3283
    r1.x = x1 + w1;
3284
    r1.y = y1 + h1;
3285
 
3286
    l2.x = x2;
3287
    l2.y = y2;
3288
    r2.x = x2 + w2;
3289
    r2.y = y2 + h2;
3290
 
3291
    if (l1.x == r1.x || l1.y == r1.y || l2.x == r2.x || l2.y == r2.y)
3292
    {
3293
        // the line cannot have positive overlap
3294
        return false;
3295
    }
3296
 
183 andreas 3297
    return std::max(l1.x, l2.x) < std::min(r1.x, r2.x) &&
150 andreas 3298
           std::max(l1.y, l2.y) < std::min(r1.y, r2.y);
3299
}
3300
 
51 andreas 3301
Button::TButton *TPageManager::findButton(ulong handle)
3302
{
3303
    DECL_TRACER("TPageManager::findButton(ulong handle)");
3304
 
209 andreas 3305
    if (!handle)
3306
        return nullptr;
3307
 
51 andreas 3308
    TPage *pg = getPage(mActualPage);
3309
 
3310
    if (!pg)
3311
        return nullptr;
3312
 
3313
    vector<Button::TButton *> pgBtList = pg->getAllButtons();
3314
    vector<Button::TButton *>::iterator iter;
83 andreas 3315
 
3316
    if (pgBtList.size() > 0)
51 andreas 3317
    {
83 andreas 3318
        // First we look into the elements of the page
3319
        for (iter = pgBtList.begin(); iter != pgBtList.end(); ++iter)
3320
        {
3321
            Button::TButton *bt = *iter;
51 andreas 3322
 
83 andreas 3323
            if (bt->getHandle() == handle)
3324
                return bt;
3325
        }
51 andreas 3326
    }
3327
 
3328
    // We've not found the wanted element in the elements of the page. So
3329
    // we're looking at the elements of the subpages.
3330
    TSubPage *sp = pg->getFirstSubPage();
3331
 
3332
    if (!sp)
3333
        return nullptr;
3334
 
3335
    while (sp)
3336
    {
3337
        vector<Button::TButton *> spBtList = sp->getAllButtons();
3338
 
83 andreas 3339
        if (spBtList.size() > 0)
51 andreas 3340
        {
83 andreas 3341
            for (iter = spBtList.begin(); iter != spBtList.end(); ++iter)
3342
            {
3343
                Button::TButton *bt = *iter;
51 andreas 3344
 
83 andreas 3345
                if (bt->getHandle() == handle)
3346
                    return bt;
3347
            }
51 andreas 3348
        }
3349
 
3350
        sp = pg->getNextSubPage();
3351
    }
3352
 
3353
    return nullptr;
3354
}
3355
 
4 andreas 3356
TPage *TPageManager::getActualPage()
3357
{
168 andreas 3358
    DECL_TRACER("TPageManager::getActualPage()");
3359
 
4 andreas 3360
    return getPage(mActualPage);
3361
}
3362
 
3363
TSubPage *TPageManager::getFirstSubPage()
3364
{
3365
    DECL_TRACER("TPageManager::getFirstSubPage()");
168 andreas 3366
 
349 andreas 3367
    mLastSubPage = 0;
4 andreas 3368
    TPage *pg = getPage(mActualPage);
3369
 
3370
    if (!pg)
3371
        return nullptr;
3372
 
349 andreas 3373
    map<int, TSubPage *> sp = pg->getSortedSubpages(true);
3374
 
3375
    if (!sp.empty())
3376
    {
3377
        map<int, TSubPage *>::iterator iter = sp.begin();
3378
        mLastSubPage = iter->first;
3379
        return iter->second;
3380
    }
3381
 
3382
    return nullptr;
4 andreas 3383
}
3384
 
3385
TSubPage *TPageManager::getNextSubPage()
3386
{
3387
    DECL_TRACER("TPageManager::getNextSubPage()");
3388
 
3389
    TPage *pg = getPage(mActualPage);
3390
 
3391
    if (pg)
349 andreas 3392
    {
3393
        map<int, TSubPage *> sp = pg->getSortedSubpages();
4 andreas 3394
 
349 andreas 3395
        if (sp.empty())
3396
        {
3397
            mLastSubPage = 0;
3398
            return nullptr;
3399
        }
3400
        else
3401
        {
3402
            map<int, TSubPage *>::iterator iter = sp.find(mLastSubPage);
3403
 
3404
            if (iter != sp.end())
3405
            {
3406
                iter++;
3407
 
3408
                if (iter != sp.end())
3409
                {
3410
                    mLastSubPage = iter->first;
3411
                    return iter->second;
3412
                }
3413
            }
3414
        }
3415
    }
3416
 
3417
    mLastSubPage = 0;
4 andreas 3418
    return nullptr;
3419
}
10 andreas 3420
 
154 andreas 3421
TSubPage *TPageManager::getPrevSubPage()
3422
{
3423
    DECL_TRACER("TPageManager::getPrevSubPage()");
3424
 
3425
    TPage *pg = getPage(mActualPage);
3426
 
3427
    if (pg)
349 andreas 3428
    {
3429
        map<int, TSubPage *> sp = pg->getSortedSubpages();
154 andreas 3430
 
349 andreas 3431
        if (sp.empty())
3432
        {
3433
            mLastSubPage = 0;
3434
            return nullptr;
3435
        }
3436
        else
3437
        {
3438
            map<int, TSubPage *>::iterator iter = sp.find(mLastSubPage);
3439
 
3440
            if (iter != sp.end() && iter != sp.begin())
3441
            {
3442
                iter--;
3443
                mLastSubPage = iter->first;
3444
                return iter->second;
3445
            }
3446
 
3447
            MSG_DEBUG("Page " << mLastSubPage << " not found!");
3448
        }
3449
    }
3450
 
3451
    mLastSubPage = 0;
154 andreas 3452
    return nullptr;
3453
}
3454
 
3455
TSubPage *TPageManager::getLastSubPage()
3456
{
3457
    DECL_TRACER("TPageManager::getLastSubPage()");
3458
 
349 andreas 3459
    mLastSubPage = 0;
154 andreas 3460
    TPage *pg = getPage(mActualPage);
3461
 
3462
    if (pg)
3463
    {
349 andreas 3464
        map<int, TSubPage *> sp = pg->getSortedSubpages(true);
3465
 
3466
        if (sp.empty())
3467
            return nullptr;
3468
        else
3469
        {
3470
            map<int, TSubPage *>::iterator iter = sp.end();
3471
            iter--;
3472
            mLastSubPage = iter->first;
3473
            return iter->second;
3474
        }
154 andreas 3475
    }
3476
    else
3477
    {
3478
        MSG_WARNING("Actual page " << mActualPage << " not found!");
3479
    }
3480
 
3481
    return nullptr;
3482
}
3483
 
11 andreas 3484
TSubPage *TPageManager::getFirstSubPageGroup(const string& group)
3485
{
3486
    DECL_TRACER("TPageManager::getFirstSubPageGroup(const string& group)");
3487
 
14 andreas 3488
    if (group.empty())
3489
    {
3490
        MSG_WARNING("Empty group name is invalid. Ignoring it!");
3491
        mActualGroupName.clear();
3492
        mActualGroupPage = nullptr;
3493
        return nullptr;
3494
    }
3495
 
11 andreas 3496
    mActualGroupName = group;
3497
    TSubPage *pg = getFirstSubPage();
3498
 
3499
    while (pg)
3500
    {
14 andreas 3501
        MSG_DEBUG("Evaluating group " << pg->getGroupName() << " with " << group);
3502
 
11 andreas 3503
        if (pg->getGroupName().compare(group) == 0)
3504
        {
3505
            mActualGroupPage = pg;
3506
            return pg;
3507
        }
3508
 
3509
        pg = getNextSubPage();
3510
    }
3511
 
3512
    mActualGroupName.clear();
3513
    mActualGroupPage = nullptr;
3514
    return nullptr;
3515
}
3516
 
3517
TSubPage *TPageManager::getNextSubPageGroup()
3518
{
3519
    DECL_TRACER("TPageManager::getNextSubPageGroup()");
3520
 
3521
    if (mActualGroupName.empty())
3522
        return nullptr;
3523
 
3524
    TSubPage *pg = getFirstSubPage();
3525
    bool found = false;
3526
 
3527
    while (pg)
3528
    {
14 andreas 3529
        MSG_DEBUG("Evaluating group " << pg->getGroupName() << " with " << mActualGroupName);
3530
 
3531
        if (!found && pg == mActualGroupPage)
11 andreas 3532
        {
3533
            pg = getNextSubPage();
14 andreas 3534
            found = true;
11 andreas 3535
            continue;
3536
        }
3537
 
14 andreas 3538
        if (found && pg->getGroupName().compare(mActualGroupName) == 0)
11 andreas 3539
        {
3540
            mActualGroupPage = pg;
3541
            return pg;
3542
        }
3543
 
3544
        pg = getNextSubPage();
3545
    }
3546
 
3547
    mActualGroupName.clear();
3548
    mActualGroupPage = nullptr;
3549
    return nullptr;
3550
}
3551
 
3552
TSubPage *TPageManager::getNextSubPageGroup(const string& group, TSubPage* pg)
3553
{
3554
    DECL_TRACER("TPageManager::getNextSubPageGroup(const string& group, TSubPage* pg)");
3555
 
3556
    if (group.empty() || !pg)
3557
        return nullptr;
3558
 
3559
    TSubPage *page = getFirstSubPage();
3560
    bool found = false;
3561
 
3562
    while (page)
3563
    {
14 andreas 3564
        MSG_DEBUG("Evaluating group " << pg->getGroupName() << " with " << group);
3565
 
3566
        if (!found && pg == page)
11 andreas 3567
        {
3568
            page = getNextSubPage();
14 andreas 3569
            found = true;
11 andreas 3570
            continue;
3571
        }
3572
 
14 andreas 3573
        if (found && page->getGroupName().compare(group) == 0)
11 andreas 3574
            return page;
3575
 
3576
        page = getNextSubPage();
3577
    }
3578
 
3579
    return nullptr;
3580
}
3581
 
3582
TSubPage *TPageManager::getTopPage()
3583
{
3584
    DECL_TRACER("TPageManager::getTopPage()");
3585
 
3586
    // Scan for all occupied regions
3587
    vector<RECT_T> regions;
3588
 
3589
    TSubPage *pg = getFirstSubPage();
3590
 
3591
    while (pg)
3592
    {
3593
        RECT_T r = pg->getRegion();
3594
        regions.push_back(r);
3595
        pg = getNextSubPage();
3596
    }
3597
 
3598
    // Now scan all pages against all regions to find the top most
3599
    pg = getFirstSubPage();
3600
    TSubPage *top = nullptr;
3601
    int zPos = 0;
3602
 
3603
    while (pg)
3604
    {
3605
        RECT_T r = pg->getRegion();
3606
 
83 andreas 3607
        if (regions.size() > 0)
11 andreas 3608
        {
83 andreas 3609
            vector<RECT_T>::iterator iter;
3610
            int zo = 0;
11 andreas 3611
 
118 andreas 3612
            for (iter = regions.begin(); iter != regions.end(); ++iter)
83 andreas 3613
            {
3614
                if (doOverlap(*iter, r) && zPos > zo)
3615
                    top = pg;
3616
 
3617
                zo++;
3618
            }
11 andreas 3619
        }
3620
 
3621
        pg = getNextSubPage();
3622
        zPos++;
3623
    }
3624
 
3625
    return top;
3626
}
3627
 
3628
TSubPage *TPageManager::getCoordMatch(int x, int y)
3629
{
3630
    DECL_TRACER("TPageManager::getCoordMatch(int x, int y)");
3631
 
26 andreas 3632
    int realX = x;
3633
    int realY = y;
3634
 
11 andreas 3635
    // Reverse order of pages
154 andreas 3636
    TSubPage *pg = getLastSubPage();
11 andreas 3637
 
154 andreas 3638
    // Iterate in reverse order through array
11 andreas 3639
    while (pg)
3640
    {
154 andreas 3641
        if (!pg->isVisible() || pg->getZOrder() == ZORDER_INVALID)
151 andreas 3642
        {
154 andreas 3643
            pg = getPrevSubPage();
3644
            continue;
151 andreas 3645
        }
14 andreas 3646
 
154 andreas 3647
        MSG_DEBUG("Scanning subpage (Z: " << pg->getZOrder() << "): " << pg->getNumber() << ", " << pg->getName());
3648
        RECT_T r = pg->getRegion();
11 andreas 3649
 
154 andreas 3650
        if (r.left <= realX && (r.left + r.width) >= realX &&
3651
            r.top <= realY && (r.top + r.height) >= realY)
11 andreas 3652
        {
154 andreas 3653
            MSG_DEBUG("Click matches subpage " << pg->getNumber() << " (" << pg->getName() << ")");
3654
            return pg;
3655
        }
83 andreas 3656
 
154 andreas 3657
        pg = getPrevSubPage();
11 andreas 3658
    }
3659
 
3660
    return nullptr;
3661
}
3662
 
40 andreas 3663
Button::TButton *TPageManager::getCoordMatchPage(int x, int y)
3664
{
3665
    DECL_TRACER("TPageManager::getCoordMatchPage(int x, int y)");
3666
 
3667
    TPage *page = getActualPage();
3668
 
3669
    if (page)
3670
    {
150 andreas 3671
        Button::TButton *bt = page->getLastButton();
40 andreas 3672
 
3673
        while (bt)
3674
        {
150 andreas 3675
            bool clickable = bt->isClickable();
3676
            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 3677
 
150 andreas 3678
            if (!clickable)
146 andreas 3679
            {
150 andreas 3680
                bt = page->getPreviousButton();
146 andreas 3681
                continue;
3682
            }
3683
 
40 andreas 3684
            if (bt->getLeftPosition() <= x && (bt->getLeftPosition() + bt->getWidth()) >= x &&
3685
                bt->getTopPosition() <= y && (bt->getTopPosition() + bt->getHeight()) >= y)
3686
            {
154 andreas 3687
                if (!bt->isClickable(x - bt->getLeftPosition(), y - bt->getTopPosition()))
3688
                {
3689
                    bt = page->getPreviousButton();
3690
                    continue;
3691
                }
3692
 
40 andreas 3693
                MSG_DEBUG("Click matches button " << bt->getButtonIndex() << " (" << bt->getButtonName() << ")");
3694
                return bt;
3695
            }
3696
 
150 andreas 3697
            bt = page->getPreviousButton();
40 andreas 3698
        }
3699
    }
3700
 
3701
    return nullptr;
3702
}
3703
 
11 andreas 3704
bool TPageManager::doOverlap(RECT_T r1, RECT_T r2)
3705
{
3706
    DECL_TRACER("TPageManager::doOverlap(RECT_T r1, RECT_T r2)");
3707
 
3708
    // If one rectangle is on left side of other
3709
    if (r1.left >= r2.left || r2.left >= r1.left)
3710
        return false;
3711
 
3712
    // If one rectangle is above other
3713
    if (r1.top <= r2.top || r2.top <= r1.top)
3714
        return false;
3715
 
3716
    return true;
3717
}
3718
 
14 andreas 3719
bool TPageManager::havePage(const string& name)
11 andreas 3720
{
14 andreas 3721
    DECL_TRACER("TPageManager::havePage(const string& name)");
11 andreas 3722
 
14 andreas 3723
    if (name.empty())
3724
        return false;
3725
 
3726
    PCHAIN_T *pg = mPchain;
3727
 
3728
    while (pg)
3729
    {
3730
        if (pg->page && pg->page->getName().compare(name) == 0)
3731
            return true;
3732
 
3733
        pg = pg->next;
3734
    }
3735
 
3736
    return false;
3737
}
3738
 
3739
bool TPageManager::haveSubPage(const string& name)
3740
{
3741
    DECL_TRACER("TPageManager::haveSubPage(const string& name)");
3742
 
3743
    if (name.empty())
3744
        return false;
3745
 
11 andreas 3746
    SPCHAIN_T *pg = mSPchain;
3747
 
3748
    while (pg)
3749
    {
14 andreas 3750
        if (pg->page && pg->page->getName().compare(name) == 0)
3751
        {
3752
            MSG_DEBUG("Subpage " << pg->page->getNumber() << ", " << name << " found.");
3753
            return true;
3754
        }
3755
 
3756
        pg = pg->next;
3757
    }
3758
 
3759
    MSG_DEBUG("Subpage " << name << " not found.");
3760
    return false;
3761
}
3762
 
3763
bool TPageManager::haveSubPage(int id)
3764
{
3765
    DECL_TRACER("TPageManager::haveSubPage(int id)");
3766
 
3767
    SPCHAIN_T *pg = mSPchain;
3768
 
3769
    while (pg)
3770
    {
3771
        if (pg->page && pg->page->getNumber() == id)
3772
        {
3773
            MSG_DEBUG("Subpage " << pg->page->getNumber() << ", " << pg->page->getName() << " found.");
3774
            return true;
3775
        }
3776
 
3777
        pg = pg->next;
3778
    }
3779
 
3780
    MSG_DEBUG("Subpage " << id << " not found.");
3781
    return false;
3782
}
3783
 
3784
bool TPageManager::haveSubPage(const string& page, const string& name)
3785
{
3786
    DECL_TRACER("TPageManager::haveSubPage(const string& page, const string& name)");
3787
 
3788
    TPage *pg = getPage(page);
3789
 
3790
    if (!pg)
3791
        return false;
3792
 
3793
    TSubPage *spg = pg->getFirstSubPage();
3794
 
3795
    while (spg)
3796
    {
3797
        if (spg->getName().compare(name) == 0)
3798
        {
3799
            MSG_DEBUG("Subpage " << spg->getNumber() << ", " << name << " found.");
3800
            return true;
3801
        }
3802
 
3803
        spg = pg->getNextSubPage();
3804
    }
3805
 
3806
    MSG_DEBUG("Subpage " << name << " not found on page " << page << ".");
3807
    return false;
3808
}
3809
 
3810
bool TPageManager::haveSubPage(const string& page, int id)
3811
{
3812
    DECL_TRACER("TPageManager::haveSubPage(const string& page, int id)");
3813
 
3814
    TPage *pg = getPage(page);
3815
 
3816
    if (!pg)
3817
        return false;
3818
 
3819
    TSubPage *spg = pg->getFirstSubPage();
3820
 
3821
    while (spg)
3822
    {
3823
        if (spg->getNumber() == id)
3824
        {
3825
            MSG_DEBUG("Subpage " << spg->getNumber() << ", " << spg->getName() << " found.");
3826
            return true;
3827
        }
3828
 
3829
        spg = pg->getNextSubPage();
3830
    }
3831
 
3832
    MSG_DEBUG("Subpage " << id << " on page " << page << " not found.");
3833
    return false;
3834
}
3835
 
3836
void TPageManager::closeGroup(const string& group)
3837
{
3838
    DECL_TRACER("TPageManager::closeGroup(const string& group)");
3839
 
3840
    SPCHAIN_T *pg = mSPchain;
3841
 
3842
    while (pg)
3843
    {
11 andreas 3844
        if (pg->page->getGroupName().compare(group) == 0 && pg->page->isVisible())
3845
        {
3846
            pg->page->regCallDropSubPage(_callDropSubPage);
3847
            pg->page->drop();
3848
            break;
3849
        }
3850
 
3851
        pg = pg->next;
3852
    }
3853
}
3854
 
14 andreas 3855
void TPageManager::showSubPage(const string& name)
3856
{
3857
    DECL_TRACER("TPageManager::showSubPage(const string& name)");
3858
 
3859
    if (name.empty())
349 andreas 3860
    {
3861
#if TESTMODE == 1
3862
        setScreenDone();
3863
#endif
14 andreas 3864
        return;
349 andreas 3865
    }
275 andreas 3866
 
152 andreas 3867
    TPage *page = nullptr;
3868
    TSubPage *pg = deliverSubPage(name, &page);
14 andreas 3869
 
96 andreas 3870
    if (!pg)
349 andreas 3871
    {
3872
#if TESTMODE == 1
3873
        setScreenDone();
3874
#endif
14 andreas 3875
        return;
349 andreas 3876
    }
14 andreas 3877
 
152 andreas 3878
    if (page)
350 andreas 3879
    {
3880
        pg->setParent(page->getHandle());
152 andreas 3881
        page->addSubPage(pg);
350 andreas 3882
    }
152 andreas 3883
 
14 andreas 3884
    string group = pg->getGroupName();
3885
 
3886
    if (!group.empty())
3887
    {
3888
        TSubPage *sub = getFirstSubPageGroup(group);
3889
 
3890
        while(sub)
3891
        {
3892
            if (sub->isVisible() && sub->getNumber() != pg->getNumber())
3893
                sub->drop();
3894
 
3895
            sub = getNextSubPageGroup(group, sub);
3896
        }
3897
    }
3898
 
150 andreas 3899
    if (pg->isVisible())
3900
    {
152 andreas 3901
        MSG_DEBUG("Page " << pg->getName() << " is already visible but maybe not on top.");
150 andreas 3902
 
3903
        TSubPage *sub = getFirstSubPage();
3904
        bool redraw = false;
3905
 
3906
        while (sub)
3907
        {
151 andreas 3908
            if (sub->isVisible() && pg->getZOrder() < sub->getZOrder() &&
3909
                overlap(sub->getLeft(), sub->getTop(), sub->getWidth(), sub->getHeight(),
150 andreas 3910
                pg->getLeft(), pg->getTop(), pg->getWidth(), pg->getHeight()))
3911
            {
3912
                MSG_DEBUG("Page " << sub->getName() << " is overlapping page " << pg->getName());
3913
                redraw = true;
3914
                break;
3915
            }
3916
 
3917
            sub = getNextSubPage();
3918
        }
3919
 
151 andreas 3920
        if (redraw && _toFront)
3921
        {
300 andreas 3922
            _toFront((uint)pg->getHandle());
151 andreas 3923
            pg->setZOrder(page->getNextZOrder());
349 andreas 3924
//            page->sortSubpages();
154 andreas 3925
            MSG_DEBUG("Setting new Z-order " << page->getActZOrder() << " on subpage " << pg->getName());
151 andreas 3926
        }
154 andreas 3927
        else if (redraw && !_toFront)
150 andreas 3928
            pg->drop();
3929
    }
3930
 
14 andreas 3931
    if (!pg->isVisible())
3932
    {
3933
        if (!page)
3934
        {
198 andreas 3935
            page = getPage(mActualPage);
3936
 
3937
            if (!page)
3938
            {
3939
                MSG_ERROR("No active page found! Internal error.");
3940
                return;
3941
            }
14 andreas 3942
        }
3943
 
3944
        if (!haveSubPage(pg->getNumber()) && !page->addSubPage(pg))
3945
            return;
3946
 
3947
        pg->setZOrder(page->getNextZOrder());
3948
 
3949
        if (_setSubPage)
26 andreas 3950
        {
3951
            int left = pg->getLeft();
3952
            int top = pg->getTop();
3953
            int width = pg->getWidth();
3954
            int height = pg->getHeight();
43 andreas 3955
#ifdef _SCALE_SKIA_
26 andreas 3956
            if (mScaleFactor != 1.0)
3957
            {
3958
                left = (int)((double)left * mScaleFactor);
3959
                top = (int)((double)top * mScaleFactor);
3960
                width = (int)((double)width * mScaleFactor);
3961
                height = (int)((double)height * mScaleFactor);
28 andreas 3962
                MSG_DEBUG("Scaled subpage: left=" << left << ", top=" << top << ", width=" << width << ", height=" << height);
26 andreas 3963
            }
43 andreas 3964
#endif
41 andreas 3965
            ANIMATION_t ani;
3966
            ani.showEffect = pg->getShowEffect();
3967
            ani.showTime = pg->getShowTime();
42 andreas 3968
            ani.hideEffect = pg->getHideEffect();
3969
            ani.hideTime = pg->getHideTime();
54 andreas 3970
            // Test for a timer on the page
3971
            if (pg->getTimeout() > 0)
3972
                pg->startTimer();
3973
 
217 andreas 3974
            _setSubPage(pg->getHandle(), page->getHandle(), left, top, width, height, ani);
26 andreas 3975
        }
293 andreas 3976
 
3977
        pg->show();
14 andreas 3978
    }
3979
}
3980
 
198 andreas 3981
void TPageManager::showSubPage(int number, bool force)
3982
{
3983
    DECL_TRACER("TPageManager::showSubPage(int number, bool force)");
3984
 
3985
    if (number <= 0)
3986
        return;
3987
 
3988
    TPage *page = nullptr;
3989
    TSubPage *pg = deliverSubPage(number, &page);
3990
 
3991
    if (!pg)
3992
        return;
3993
 
3994
    if (page)
350 andreas 3995
    {
3996
        pg->setParent(page->getHandle());
198 andreas 3997
        page->addSubPage(pg);
350 andreas 3998
    }
198 andreas 3999
 
4000
    string group = pg->getGroupName();
4001
 
4002
    if (!group.empty())
4003
    {
4004
        TSubPage *sub = getFirstSubPageGroup(group);
4005
 
4006
        while(sub)
4007
        {
4008
            if (sub->isVisible() && sub->getNumber() != pg->getNumber())
4009
                sub->drop();
4010
 
4011
            sub = getNextSubPageGroup(group, sub);
4012
        }
4013
    }
4014
 
4015
    if (pg->isVisible() && !force)
4016
    {
4017
        MSG_DEBUG("Page " << pg->getName() << " is already visible but maybe not on top.");
4018
 
4019
        TSubPage *sub = getFirstSubPage();
4020
        bool redraw = false;
4021
 
4022
        while (sub)
4023
        {
4024
            if (sub->isVisible() && pg->getZOrder() < sub->getZOrder() &&
4025
                overlap(sub->getLeft(), sub->getTop(), sub->getWidth(), sub->getHeight(),
4026
                        pg->getLeft(), pg->getTop(), pg->getWidth(), pg->getHeight()))
4027
            {
4028
                MSG_DEBUG("Page " << sub->getName() << " is overlapping page " << pg->getName());
4029
                redraw = true;
4030
                break;
4031
            }
4032
 
4033
            sub = getNextSubPage();
4034
        }
4035
 
4036
        if (redraw && _toFront)
4037
        {
300 andreas 4038
            _toFront((uint)pg->getHandle());
198 andreas 4039
            pg->setZOrder(page->getNextZOrder());
4040
            page->sortSubpages();
4041
            MSG_DEBUG("Setting new Z-order " << page->getActZOrder() << " on subpage " << pg->getName());
4042
        }
4043
        else if (redraw && !_toFront)
4044
            pg->drop();
4045
    }
4046
 
4047
    if (!pg->isVisible() || force)
4048
    {
4049
        if (!page)
4050
        {
4051
            MSG_ERROR("No active page found! Internal error.");
4052
            return;
4053
        }
4054
 
4055
        if (!haveSubPage(pg->getNumber()) && !page->addSubPage(pg))
4056
            return;
4057
 
4058
        if (!pg->isVisible())
4059
            pg->setZOrder(page->getNextZOrder());
4060
 
4061
        if (_setSubPage)
4062
        {
4063
            int left = pg->getLeft();
4064
            int top = pg->getTop();
4065
            int width = pg->getWidth();
4066
            int height = pg->getHeight();
262 andreas 4067
#ifdef _SCALE_SKIA_
198 andreas 4068
            if (mScaleFactor != 1.0)
4069
            {
4070
                left = (int)((double)left * mScaleFactor);
4071
                top = (int)((double)top * mScaleFactor);
4072
                width = (int)((double)width * mScaleFactor);
4073
                height = (int)((double)height * mScaleFactor);
4074
                MSG_DEBUG("Scaled subpage: left=" << left << ", top=" << top << ", width=" << width << ", height=" << height);
4075
            }
262 andreas 4076
#endif
198 andreas 4077
            ANIMATION_t ani;
4078
            ani.showEffect = pg->getShowEffect();
4079
            ani.showTime = pg->getShowTime();
4080
            ani.hideEffect = pg->getHideEffect();
4081
            ani.hideTime = pg->getHideTime();
4082
            // Test for a timer on the page
4083
            if (pg->getTimeout() > 0)
4084
                pg->startTimer();
4085
 
217 andreas 4086
            _setSubPage(pg->getHandle(), page->getHandle(), left, top, width, height, ani);
198 andreas 4087
        }
4088
    }
4089
 
4090
    pg->show();
4091
}
4092
 
14 andreas 4093
void TPageManager::hideSubPage(const string& name)
4094
{
4095
    DECL_TRACER("TPageManager::hideSubPage(const string& name)");
4096
 
4097
    if (name.empty())
335 andreas 4098
    {
4099
#if TESTMODE == 1
4100
        setScreenDone();
4101
#endif
14 andreas 4102
        return;
335 andreas 4103
    }
14 andreas 4104
 
4105
    TPage *page = getPage(mActualPage);
4106
 
4107
    if (!page)
4108
    {
4109
        MSG_ERROR("No active page found! Internal error.");
335 andreas 4110
#if TESTMODE == 1
4111
        setScreenDone();
4112
#endif
14 andreas 4113
        return;
4114
    }
4115
 
4116
    TSubPage *pg = getSubPage(name);
4117
 
4118
    if (pg)
4119
    {
4120
        pg->drop();
154 andreas 4121
        page->decZOrder();
14 andreas 4122
    }
4123
}
4124
 
299 andreas 4125
/**
4126
 * @brief TPageManager::runClickQueue - Processing mouse clicks
4127
 * The following method is starting a thread which tests a queue containing
4128
 * the mouse clicks. To not drain the CPU, it sleeps for a short time if there
4129
 * are no more events in the queue.
4130
 * If there is an entry in the queue, it copies it to a local struct and
4131
 * deletes it from the queue. It take always the oldest antry (first entry)
4132
 * and removes this entry from the queue until the queue is empty. This makes
4133
 * it to a FIFO (first in, first out).
4134
 * Depending on the state of the variable "coords" the method for mouse
4135
 * coordinate click is executed or the method for a handle.
4136
 * The thread runs as long as the variable "mClickQueueRun" is TRUE and the
4137
 * variable "prg_stopped" is FALSE.
4138
 */
4139
void TPageManager::runClickQueue()
4140
{
4141
    DECL_TRACER("TPageManager::runClickQueue()");
4142
 
4143
    if (mClickQueueRun)
4144
        return;
4145
 
4146
    mClickQueueRun = true;
4147
 
4148
    try
4149
    {
4150
        std::thread thr = std::thread([=] {
300 andreas 4151
            MSG_PROTOCOL("Thread \"TPageManager::runClickQueue()\" was started.");
4152
 
299 andreas 4153
            while (mClickQueueRun && !prg_stopped)
4154
            {
300 andreas 4155
                while (!mClickQueue.empty())
299 andreas 4156
                {
4157
#ifdef QT_DEBUG
300 andreas 4158
                    if (mClickQueue[0].coords)
4159
                        MSG_TRACE("TPageManager::runClickQueue() -- executing: _mouseEvent(" << mClickQueue[0].x << ", " << mClickQueue[0].y << ", " << (mClickQueue[0].pressed ? "TRUE" : "FALSE") << ")")
299 andreas 4160
                    else
300 andreas 4161
                        MSG_TRACE("TPageManager::runClickQueue() -- executing: _mouseEvent(" << handleToString(mClickQueue[0].handle) << ", " << (mClickQueue[0].pressed ? "TRUE" : "FALSE") << ")")
299 andreas 4162
#endif
300 andreas 4163
                    if (mClickQueue[0].coords)
4164
                        _mouseEvent(mClickQueue[0].x, mClickQueue[0].y, mClickQueue[0].pressed);
4165
                    else
4166
                        _mouseEvent(mClickQueue[0].handle, mClickQueue[0].handle);
4167
 
299 andreas 4168
                    mClickQueue.erase(mClickQueue.begin()); // Remove first entry
4169
                }
4170
 
4171
                std::this_thread::sleep_for(std::chrono::microseconds(10));
4172
            }
4173
 
303 andreas 4174
            mClickQueueRun = false;
299 andreas 4175
            return;
4176
        });
4177
 
4178
        thr.detach();
4179
    }
4180
    catch (std::exception& e)
4181
    {
300 andreas 4182
        MSG_ERROR("Error starting a thread to handle the click queue: " << e.what());
299 andreas 4183
        mClickQueueRun = false;
4184
    }
4185
}
4186
 
303 andreas 4187
void TPageManager::runUpdateSubViewItem()
4188
{
4189
    DECL_TRACER("TPageManager::runUpdateSubViewItem()");
299 andreas 4190
 
303 andreas 4191
    if (mUpdateViewsRun)
4192
        return;
4193
 
4194
    mUpdateViewsRun = true;
4195
 
4196
    try
4197
    {
4198
        std::thread thr = std::thread([=] {
4199
            MSG_PROTOCOL("Thread \"TPageManager::runUpdateSubViewItem()\" was started.");
4200
 
4201
            while (mUpdateViewsRun && !prg_stopped)
4202
            {
4203
                while (!mUpdateViews.empty())
4204
                {
4205
                    _updateSubViewItem(mUpdateViews[0]);
4206
                    mUpdateViews.erase(mUpdateViews.begin()); // Remove first entry
4207
                }
4208
 
4209
                std::this_thread::sleep_for(std::chrono::microseconds(10));
4210
            }
4211
 
4212
            mUpdateViewsRun = false;
4213
            return;
4214
        });
4215
 
4216
        thr.detach();
4217
    }
4218
    catch (std::exception& e)
4219
    {
4220
        MSG_ERROR("Error starting a thread to handle the click queue: " << e.what());
4221
        mUpdateViewsRun = false;
4222
    }
4223
}
4224
 
11 andreas 4225
/*
4226
 * Catch the mouse presses and scan all pages and subpages for an element to
4227
 * receive the klick.
4228
 */
10 andreas 4229
void TPageManager::mouseEvent(int x, int y, bool pressed)
4230
{
4231
    DECL_TRACER("TPageManager::mouseEvent(int x, int y, bool pressed)");
4232
 
316 andreas 4233
    TTRYLOCK(click_mutex);
299 andreas 4234
 
4235
    _CLICK_QUEUE_t cq;
4236
    cq.x = x;
4237
    cq.y = y;
4238
    cq.pressed = pressed;
4239
    cq.coords = true;
4240
    mClickQueue.push_back(cq);
334 andreas 4241
#if TESTMODE == 1
4242
    setScreenDone();
4243
#endif
299 andreas 4244
}
4245
 
4246
void TPageManager::_mouseEvent(int x, int y, bool pressed)
4247
{
4248
    DECL_TRACER("TPageManager::_mouseEvent(int x, int y, bool pressed)");
4249
 
16 andreas 4250
    TError::clear();
334 andreas 4251
#if TESTMODE == 1
4252
    if (_gTestMode)
4253
        _gTestMode->setMouseClick(x, y, pressed);
4254
#endif
11 andreas 4255
    int realX = x - mFirstLeftPixel;
4256
    int realY = y - mFirstTopPixel;
263 andreas 4257
 
31 andreas 4258
    MSG_DEBUG("Mouse at " << realX << ", " << realY << ", state " << ((pressed) ? "PRESSED" : "RELEASED") << ", [ " << x << " | " << y << " ]");
43 andreas 4259
#ifdef _SCALE_SKIA_
100 andreas 4260
    if (mScaleFactor != 1.0 && mScaleFactor > 0.0)
26 andreas 4261
    {
4262
        realX = (int)((double)realX / mScaleFactor);
4263
        realY = (int)((double)realY / mScaleFactor);
31 andreas 4264
        MSG_DEBUG("Scaled coordinates: x=" << realX << ", y=" << realY);
26 andreas 4265
    }
43 andreas 4266
#endif
70 andreas 4267
 
154 andreas 4268
    TSubPage *subPage = nullptr;
11 andreas 4269
 
154 andreas 4270
    if (pressed)
4271
        subPage = getCoordMatch(realX, realY);
318 andreas 4272
    else if (mLastPagePush)
154 andreas 4273
        subPage = getSubPage(mLastPagePush);
4274
    else
4275
        subPage = getCoordMatch(realX, realY);
4276
 
11 andreas 4277
    if (!subPage)
14 andreas 4278
    {
146 andreas 4279
        Button::TButton *bt = getCoordMatchPage(realX, realY);
40 andreas 4280
 
4281
        if (bt)
4282
        {
4283
            MSG_DEBUG("Button on page " << bt->getButtonIndex() << ": size: left=" << bt->getLeftPosition() << ", top=" << bt->getTopPosition() << ", width=" << bt->getWidth() << ", height=" << bt->getHeight());
4284
            bt->doClick(x - bt->getLeftPosition(), y - bt->getTopPosition(), pressed);
4285
        }
4286
 
11 andreas 4287
        return;
14 andreas 4288
    }
11 andreas 4289
 
154 andreas 4290
    MSG_DEBUG("Subpage " << subPage->getNumber() << " [" << subPage->getName() << "]: size: left=" << subPage->getLeft() << ", top=" << subPage->getTop() << ", width=" << subPage->getWidth() << ", height=" << subPage->getHeight());
4291
 
4292
    if (pressed)
4293
        mLastPagePush = subPage->getNumber();
4294
    else
4295
        mLastPagePush = 0;
4296
 
11 andreas 4297
    subPage->doClick(realX - subPage->getLeft(), realY - subPage->getTop(), pressed);
10 andreas 4298
}
11 andreas 4299
 
289 andreas 4300
void TPageManager::mouseEvent(ulong handle, bool pressed)
4301
{
4302
    DECL_TRACER("TPageManager::mouseEvent(ulong handle, bool pressed)");
4303
 
320 andreas 4304
    if (!mClickQueue.empty() && mClickQueue.back().handle == handle && mClickQueue.back().pressed == pressed)
4305
        return;
4306
 
299 andreas 4307
    TLOCKER(click_mutex);
293 andreas 4308
 
299 andreas 4309
    _CLICK_QUEUE_t cq;
4310
    cq.handle = handle;
4311
    cq.pressed = pressed;
4312
    mClickQueue.push_back(cq);
4313
    MSG_DEBUG("Queued click for handle " << handleToString(cq.handle) << " state " << (cq.pressed ? "PRESSED" : "RELEASED"));
4314
}
4315
 
4316
void TPageManager::_mouseEvent(ulong handle, bool pressed)
4317
{
4318
    DECL_TRACER("TPageManager::_mouseEvent(ulong handle, bool pressed)");
4319
 
293 andreas 4320
    MSG_DEBUG("Doing click for handle " << handleToString(handle) << " state " << (pressed ? "PRESSED" : "RELEASED"));
4321
 
289 andreas 4322
    if (!handle)
4323
        return;
4324
 
4325
    int pageID = (handle >> 16) & 0x0000ffff;
4326
    int buttonID = (handle & 0x0000ffff);
4327
 
318 andreas 4328
    if (pageID < REGULAR_SUBPAGE_START || buttonID == 0)
289 andreas 4329
        return;
4330
 
4331
    TSubPage *subPage = getSubPage(pageID);
4332
 
4333
    if (subPage)
4334
    {
4335
        Button::TButton *bt = subPage->getButton(buttonID);
4336
 
4337
        if (bt)
4338
        {
318 andreas 4339
            MSG_DEBUG("Button on subpage " << pageID << ": " << buttonID);
289 andreas 4340
            bt->doClick(bt->getLeftPosition() + bt->getWidth() / 2, bt->getTopPosition() + bt->getHeight() / 2, pressed);
4341
        }
4342
    }
4343
}
4344
 
192 andreas 4345
void TPageManager::inputButtonFinished(ulong handle, const std::string &content)
4346
{
4347
    DECL_TRACER("TPageManager::inputButtonFinished(ulong handle, const std::string &content)");
4348
 
4349
    Button::TButton *bt = findButton(handle);
4350
 
4351
    if (!bt)
4352
    {
271 andreas 4353
        MSG_WARNING("Invalid button handle " << handleToString(handle));
192 andreas 4354
        return;
4355
    }
4356
 
4357
    bt->setTextOnly(content, -1);
4358
}
4359
 
309 andreas 4360
void TPageManager::inputCursorPositionChanged(ulong handle, int oldPos, int newPos)
4361
{
4362
    DECL_TRACER("TPageManager::inputCursorPositionChanged(ulong handle, int oldPos, int newPos)");
4363
 
4364
    Button::TButton *bt = findButton(handle);
4365
 
4366
    if (!bt)
4367
    {
4368
        MSG_WARNING("Invalid button handle " << handleToString(handle));
4369
        return;
4370
    }
4371
 
310 andreas 4372
    ulong pageID = (bt->getHandle() >> 16) & 0x0000ffff;
309 andreas 4373
 
4374
    if (pageID < REGULAR_SUBPAGE_START)
4375
    {
368 andreas 4376
        TPage *pg = getPage((int)pageID);
309 andreas 4377
 
4378
        if (!pg)
4379
            return;
4380
 
4381
        pg->setCursorPosition(handle, oldPos, newPos);
4382
    }
4383
    else
4384
    {
368 andreas 4385
        TSubPage *pg = getSubPage((int)pageID);
309 andreas 4386
 
4387
        if (!pg)
4388
            return;
4389
 
4390
        pg->setCursorPosition(handle, oldPos, newPos);
4391
    }
4392
}
4393
 
4394
void TPageManager::inputFocusChanged(ulong handle, bool in)
4395
{
4396
    DECL_TRACER("TPageManager::inputFocusChanged(ulong handle, bool in)");
4397
 
4398
    Button::TButton *bt = findButton(handle);
4399
 
4400
    if (!bt)
4401
    {
4402
        MSG_WARNING("Invalid button handle " << handleToString(handle));
4403
        return;
4404
    }
4405
 
310 andreas 4406
    ulong pageID = (bt->getHandle() >> 16) & 0x0000ffff;
4407
    MSG_DEBUG("Searching for page " << pageID);
309 andreas 4408
 
4409
    if (pageID < REGULAR_SUBPAGE_START)
4410
    {
368 andreas 4411
        TPage *pg = getPage((int)pageID);
309 andreas 4412
 
4413
        if (!pg)
4414
            return;
4415
 
4416
        pg->setInputFocus(handle, in);
4417
    }
4418
    else
4419
    {
368 andreas 4420
        TSubPage *pg = getSubPage((int)pageID);
309 andreas 4421
 
4422
        if (!pg)
4423
            return;
4424
 
4425
        pg->setInputFocus(handle, in);
4426
    }
4427
}
4428
 
208 andreas 4429
void TPageManager::setTextToButton(ulong handle, const string& txt, bool redraw)
51 andreas 4430
{
208 andreas 4431
    DECL_TRACER("TPageManager::setTextToButton(ulong handle, const string& txt, bool redraw)");
51 andreas 4432
 
4433
    // First we search for the button the handle points to
4434
    Button::TButton *button = findButton(handle);
4435
 
4436
    if (!button)
4437
    {
271 andreas 4438
        MSG_ERROR("No button with handle " << handleToString(handle) << " found!");
51 andreas 4439
        return;
4440
    }
4441
 
4442
    // Now we search for all buttons with the same channel and port number
4443
    vector<int> channels;
4444
    channels.push_back(button->getAddressChannel());
193 andreas 4445
    vector<TMap::MAP_T> map = findButtons(button->getAddressPort(), channels);
51 andreas 4446
 
4447
    if (TError::isError() || map.empty())
4448
        return;
4449
 
4450
    // Here we load all buttons found.
4451
    vector<Button::TButton *> buttons = collectButtons(map);
83 andreas 4452
 
4453
    if (buttons.size() > 0)
51 andreas 4454
    {
83 andreas 4455
        vector<Button::TButton *>::iterator mapIter;
4456
        // Finaly we iterate through all found buttons and set the text
118 andreas 4457
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
83 andreas 4458
        {
4459
            Button::TButton *bt = *mapIter;
51 andreas 4460
 
208 andreas 4461
            if (redraw)
4462
                bt->setText(txt, -1);
4463
            else
4464
                bt->setTextOnly(txt, -1);
83 andreas 4465
        }
51 andreas 4466
    }
4467
}
4468
 
193 andreas 4469
vector<Button::TButton *> TPageManager::collectButtons(vector<TMap::MAP_T>& map)
14 andreas 4470
{
193 andreas 4471
    DECL_TRACER("TPageManager::collectButtons(vector<TMap::MAP_T>& map)");
14 andreas 4472
 
4473
    vector<Button::TButton *> buttons;
83 andreas 4474
 
4475
    if (map.size() == 0)
4476
        return buttons;
4477
 
193 andreas 4478
    vector<TMap::MAP_T>::iterator iter;
14 andreas 4479
 
118 andreas 4480
    for (iter = map.begin(); iter != map.end(); ++iter)
14 andreas 4481
    {
209 andreas 4482
        if (iter->pg < REGULAR_SUBPAGE_START || (iter->pg >= SYSTEM_PAGE_START && iter->pg < SYSTEM_SUBPAGE_START))     // Main page?
14 andreas 4483
        {
4484
            TPage *page;
4485
 
4486
            if ((page = getPage(iter->pg)) == nullptr)
4487
            {
4488
                MSG_TRACE("Page " << iter->pg << ", " << iter->pn << " not found in memory. Reading it ...");
4489
 
4490
                if (!readPage(iter->pg))
4491
                    return buttons;
4492
 
4493
                page = getPage(iter->pg);
4494
            }
4495
 
4496
            Button::TButton *bt = page->getButton(iter->bt);
4497
 
4498
            if (bt)
4499
                buttons.push_back(bt);
4500
        }
4501
        else
4502
        {
4503
            TSubPage *subpage;
4504
 
4505
            if ((subpage = getSubPage(iter->pg)) == nullptr)
4506
            {
4507
                MSG_TRACE("Subpage " << iter->pg << ", " << iter->pn << " not found in memory. Reading it ...");
4508
 
4509
                if (!readSubPage(iter->pg))
4510
                    return buttons;
4511
 
4512
                subpage = getSubPage(iter->pg);
4513
                TPage *page = getActualPage();
4514
 
4515
                if (!page)
4516
                {
4517
                    MSG_ERROR("No actual page loaded!");
4518
                    return buttons;
4519
                }
4520
            }
4521
 
4522
            Button::TButton *bt = subpage->getButton(iter->bt);
4523
 
4524
            if (bt)
4525
                buttons.push_back(bt);
4526
        }
4527
    }
4528
 
4529
    return buttons;
4530
}
4531
 
11 andreas 4532
/****************************************************************************
36 andreas 4533
 * Calls from a Java activity. This is only available for Android OS.
4534
 ****************************************************************************/
182 andreas 4535
#ifdef Q_OS_ANDROID
36 andreas 4536
void TPageManager::initNetworkState()
4537
{
4538
    DECL_TRACER("TPageManager::initNetworkState()");
264 andreas 4539
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
36 andreas 4540
    QAndroidJniObject activity = QtAndroid::androidActivity();
4541
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "Init", "(Landroid/app/Activity;)V", activity.object());
4542
    activity.callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "InstallNetworkListener", "()V");
182 andreas 4543
#else
4544
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4545
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "Init", "(Landroid/app/Activity;)V", activity.object());
4546
    activity.callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "InstallNetworkListener", "()V");
4547
#endif
36 andreas 4548
}
4549
 
4550
void TPageManager::stopNetworkState()
4551
{
4552
    DECL_TRACER("TPageManager::stopNetworkState()");
264 andreas 4553
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
36 andreas 4554
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "destroyNetworkListener", "()V");
182 andreas 4555
#else
4556
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "destroyNetworkListener", "()V");
4557
#endif
36 andreas 4558
}
38 andreas 4559
 
4560
void TPageManager::initBatteryState()
4561
{
4562
    DECL_TRACER("TPageManager::initBatteryState()");
264 andreas 4563
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
38 andreas 4564
    QAndroidJniObject activity = QtAndroid::androidActivity();
4565
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "Init", "(Landroid/app/Activity;)V", activity.object());
182 andreas 4566
#else
4567
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4568
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "Init", "(Landroid/app/Activity;)V", activity.object());
4569
#endif
38 andreas 4570
    activity.callStaticMethod<void>("org/qtproject/theosys/BatteryState", "InstallBatteryListener", "()V");
4571
}
4572
 
61 andreas 4573
void TPageManager::initPhoneState()
4574
{
4575
    DECL_TRACER("TPageManager::initPhoneState()");
264 andreas 4576
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
61 andreas 4577
    QAndroidJniObject activity = QtAndroid::androidActivity();
4578
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/PhoneCallState", "Init", "(Landroid/app/Activity;)V", activity.object());
182 andreas 4579
#else
4580
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4581
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/PhoneCallState", "Init", "(Landroid/app/Activity;)V", activity.object());
4582
#endif
61 andreas 4583
    activity.callStaticMethod<void>("org/qtproject/theosys/PhoneCallState", "InstallPhoneListener", "()V");
4584
}
4585
 
38 andreas 4586
void TPageManager::stopBatteryState()
4587
{
4588
    DECL_TRACER("TPageManager::stopBatteryState()");
264 andreas 4589
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
38 andreas 4590
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "destroyBatteryListener", "()V");
182 andreas 4591
#else
4592
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "destroyBatteryListener", "()V");
4593
#endif
38 andreas 4594
}
4595
 
36 andreas 4596
void TPageManager::informTPanelNetwork(jboolean conn, jint level, jint type)
4597
{
250 andreas 4598
    DECL_TRACER("TPageManager::informTPanelNetwork(jboolean conn, jint level, jint type)");
36 andreas 4599
 
4600
    int l = 0;
4601
    string sType;
4602
 
4603
    switch (type)
4604
    {
4605
        case 1: sType = "Wifi"; break;
4606
        case 2: sType = "Mobile"; break;
4607
 
4608
        default:
4609
            sType = "Unknown"; break;
4610
    }
4611
 
4612
    if (conn)
4613
        l = level;
4614
 
93 andreas 4615
    if (mNetState && mNetState != type)     // Has the connection type changed?
4616
    {
4617
        if (gAmxNet)
4618
            gAmxNet->reconnect();
4619
    }
4620
 
4621
    mNetState = type;
4622
 
36 andreas 4623
    MSG_INFO("Connection status: " << (conn ? "Connected" : "Disconnected") << ", level: " << level << ", type: " << sType);
4624
 
83 andreas 4625
    if (mNetCalls.size() > 0)
36 andreas 4626
    {
83 andreas 4627
        std::map<int, std::function<void (int level)> >::iterator iter;
4628
 
4629
        for (iter = mNetCalls.begin(); iter != mNetCalls.end(); ++iter)
4630
            iter->second(l);
36 andreas 4631
    }
4632
}
38 andreas 4633
 
4634
void TPageManager::informBatteryStatus(jint level, jboolean charging, jint chargeType)
4635
{
4636
    DECL_TRACER("TPageManager::informBatteryStatus(jint level, jboolean charging, jint chargeType)");
4637
 
59 andreas 4638
    MSG_INFO("Battery status: level: " << level << ", " << (charging ? "Charging" : "not charging") << ", type: " << chargeType << ", Elements: " << mBatteryCalls.size());
38 andreas 4639
 
83 andreas 4640
    if (mBatteryCalls.size() > 0)
38 andreas 4641
    {
83 andreas 4642
        std::map<int, std::function<void (int, bool, int)> >::iterator iter;
4643
 
4644
        for (iter = mBatteryCalls.begin(); iter != mBatteryCalls.end(); ++iter)
4645
            iter->second(level, charging, chargeType);
38 andreas 4646
    }
4647
}
61 andreas 4648
 
4649
void TPageManager::informPhoneState(bool call, const string &pnumber)
4650
{
4651
    DECL_TRACER("TPageManager::informPhoneState(bool call, const string &pnumber)");
4652
 
4653
    MSG_INFO("Call state: " << (call ? "Call in progress" : "No call") << ", phone number: " << pnumber);
4654
 
4655
    if (!gAmxNet)
4656
    {
4657
        MSG_WARNING("The network manager for the AMX controller is not initialized!");
4658
        return;
4659
    }
4660
}
130 andreas 4661
 
4662
void TPageManager::initOrientation()
4663
{
4664
    DECL_TRACER("TPageManager::initOrientation()");
4665
 
131 andreas 4666
    int rotate = getSettings()->getRotate();
264 andreas 4667
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
130 andreas 4668
    QAndroidJniObject activity = QtAndroid::androidActivity();
131 andreas 4669
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Orientation", "Init", "(Landroid/app/Activity;I)V", activity.object(), rotate);
182 andreas 4670
#else
4671
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4672
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Orientation", "Init", "(Landroid/app/Activity;I)V", activity.object(), rotate);
4673
#endif
130 andreas 4674
    activity.callStaticMethod<void>("org/qtproject/theosys/Orientation", "InstallOrientationListener", "()V");
4675
}
255 andreas 4676
 
4677
void TPageManager::enterSetup()
4678
{
260 andreas 4679
    DECL_TRACER("TPageManager::enterSetup()");
264 andreas 4680
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
255 andreas 4681
    QAndroidJniObject activity = QtAndroid::androidActivity();
4682
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "callSettings", "(Landroid/app/Activity;)V", activity.object());
4683
#else
4684
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4685
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "callSettings", "(Landroid/app/Activity;)V", activity.object());
4686
#endif
4687
}
59 andreas 4688
#endif  // __ANDROID__
247 andreas 4689
#ifdef Q_OS_IOS
4690
void TPageManager::informBatteryStatus(int level, int state)
4691
{
4692
    DECL_TRACER("TPageManager::informBatteryStatus(int level, int state)");
36 andreas 4693
 
247 andreas 4694
    MSG_INFO("Battery status: level: " << level << ", " << state);
4695
 
4696
    if (mBatteryCalls.size() > 0)
4697
    {
4698
        std::map<int, std::function<void (int, int)> >::iterator iter;
4699
 
4700
        for (iter = mBatteryCalls.begin(); iter != mBatteryCalls.end(); ++iter)
4701
            iter->second(level, state);
4702
    }
4703
}
250 andreas 4704
 
4705
void TPageManager::informTPanelNetwork(bool conn, int level, int type)
4706
{
4707
    DECL_TRACER("TPageManager::informTPanelNetwork(bool conn, int level, int type)");
4708
 
4709
    int l = 0;
4710
    string sType;
4711
 
4712
    switch (type)
4713
    {
4714
        case 1: sType = "Ethernet"; break;
4715
        case 2: sType = "Mobile"; break;
4716
        case 3: sType = "WiFi"; break;
4717
        case 4: sType = "Bluetooth"; break;
4718
 
4719
        default:
4720
            sType = "Unknown"; break;
4721
    }
4722
 
4723
    if (conn)
4724
        l = level;
4725
 
4726
    if (mNetState && mNetState != type)     // Has the connection type changed?
4727
    {
4728
        if (gAmxNet)
4729
            gAmxNet->reconnect();
4730
    }
4731
 
4732
    mNetState = type;
4733
 
4734
    MSG_INFO("Connection status: " << (conn ? "Connected" : "Disconnected") << ", level: " << level << ", type: " << sType);
4735
 
4736
    if (mNetCalls.size() > 0)
4737
    {
4738
        std::map<int, std::function<void (int level)> >::iterator iter;
4739
 
4740
        for (iter = mNetCalls.begin(); iter != mNetCalls.end(); ++iter)
4741
            iter->second(l);
4742
    }
4743
}
4744
 
247 andreas 4745
#endif
4746
 
60 andreas 4747
void TPageManager::setButtonCallbacks(Button::TButton *bt)
4748
{
227 andreas 4749
    DECL_TRACER("TPageManager::setButtonCallbacks(Button::TButton *bt)");
4750
 
162 andreas 4751
    if (!bt)
4752
        return;
4753
 
60 andreas 4754
    bt->registerCallback(_displayButton);
4755
    bt->regCallPlayVideo(_callPlayVideo);
4756
    bt->setFonts(mFonts);
4757
    bt->setPalette(mPalette);
4758
}
4759
 
4760
void TPageManager::externalButton(extButtons_t bt, bool checked)
4761
{
4762
    DECL_TRACER("TPageManager::externalButton(extButtons_t bt)");
4763
 
4764
    if (!mExternal)
4765
        return;
4766
 
4767
    EXTBUTTON_t button = mExternal->getButton(bt);
4768
 
4769
    if (button.type == EXT_NOBUTTON)
4770
        return;
4771
 
4772
    if (button.cp && button.ch)
4773
    {
4774
        amx::ANET_SEND scmd;
4775
 
4776
        scmd.device = TConfig::getChannel();
4777
        scmd.port = button.cp;
4778
        scmd.channel = button.ch;
4779
 
4780
        if (checked)
4781
            scmd.MC = 0x0084;   // push button
134 andreas 4782
        else
4783
            scmd.MC = 0x0085;   // release button
60 andreas 4784
 
134 andreas 4785
        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 4786
 
134 andreas 4787
        if (gAmxNet)
4788
            gAmxNet->sendCommand(scmd);
4789
        else
4790
        {
4791
            MSG_WARNING("Missing global class TAmxNet. Can't send a message!");
4792
        }
60 andreas 4793
    }
4794
}
4795
 
62 andreas 4796
void TPageManager::sendKeyboard(const std::string& text)
4797
{
4798
    DECL_TRACER("TPageManager::sendKeyboard(const std::string& text)");
4799
 
4800
    amx::ANET_SEND scmd;
4801
    scmd.port = 1;
4802
    scmd.channel = 0;
4803
    scmd.msg = UTF8ToCp1250(text);
4804
    scmd.MC = 0x008b;
4805
 
4806
    if (gAmxNet)
4807
        gAmxNet->sendCommand(scmd);
4808
    else
4809
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4810
}
4811
 
4812
void TPageManager::sendKeypad(const std::string& text)
4813
{
4814
    DECL_TRACER("TPageManager::sendKeypad(const std::string& text)");
4815
 
269 andreas 4816
    sendKeyboard(text);
62 andreas 4817
}
4818
 
4819
void TPageManager::sendString(uint handle, const std::string& text)
4820
{
4821
    DECL_TRACER("TPageManager::sendString(uint handle, const std::string& text)");
4822
 
4823
    Button::TButton *bt = findButton(handle);
4824
 
4825
    if (!bt)
4826
    {
271 andreas 4827
        MSG_WARNING("Button " << handleToString(handle) << " not found!");
62 andreas 4828
        return;
4829
    }
4830
 
4831
    amx::ANET_SEND scmd;
4832
    scmd.port = bt->getAddressPort();
4833
    scmd.channel = bt->getAddressChannel();
4834
    scmd.msg = UTF8ToCp1250(text);
4835
    scmd.MC = 0x008b;
4836
 
4837
    if (gAmxNet)
4838
        gAmxNet->sendCommand(scmd);
4839
    else
4840
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4841
}
4842
 
134 andreas 4843
void TPageManager::sendGlobalString(const string& text)
4844
{
4845
    DECL_TRACER("TPageManager::sendGlobalString(const string& text)");
4846
 
4847
    if (text.empty() || text.find("-") == string::npos)
4848
        return;
4849
 
4850
    amx::ANET_SEND scmd;
4851
    scmd.port = 1;
4852
    scmd.channel = 0;
4853
    scmd.msg = text;
4854
    scmd.MC = 0x008b;
4855
 
4856
    if (gAmxNet)
4857
        gAmxNet->sendCommand(scmd);
4858
    else
4859
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4860
}
4861
 
147 andreas 4862
void TPageManager::sendCommandString(int port, const string& cmd)
4863
{
4864
    DECL_TRACER("TPageManager::sendGlobalString(const string& text)");
4865
 
4866
    if (cmd.empty())
4867
        return;
4868
 
4869
    amx::ANET_SEND scmd;
4870
    scmd.port = port;
4871
    scmd.channel = 0;
4872
    scmd.msg = cmd;
4873
    scmd.MC = 0x008c;
4874
 
4875
    if (gAmxNet)
4876
        gAmxNet->sendCommand(scmd);
4877
    else
4878
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4879
}
4880
 
123 andreas 4881
void TPageManager::sendPHNcommand(const std::string& cmd)
4882
{
4883
    DECL_TRACER("TPageManager::sendPHNcommand(const std::string& cmd)");
4884
 
4885
    amx::ANET_SEND scmd;
144 andreas 4886
    scmd.port = mTSettings->getSettings().voipCommandPort;
123 andreas 4887
    scmd.channel = TConfig::getChannel();
4888
    scmd.msg = "^PHN-" + cmd;
127 andreas 4889
    scmd.MC = 0x008c;
4890
    MSG_DEBUG("Sending PHN command: ^PHN-" << cmd);
123 andreas 4891
 
4892
    if (gAmxNet)
4893
        gAmxNet->sendCommand(scmd);
4894
    else
4895
        MSG_WARNING("Missing global class TAmxNet. Can't send ^PHN command!");
4896
}
4897
 
111 andreas 4898
void TPageManager::sendKeyStroke(char key)
4899
{
4900
    DECL_TRACER("TPageManager::sendKeyStroke(char key)");
4901
 
4902
    if (!key)
4903
        return;
4904
 
4905
    char msg[2];
4906
    msg[0] = key;
4907
    msg[1] = 0;
4908
 
4909
    amx::ANET_SEND scmd;
4910
    scmd.port = 1;
4911
    scmd.channel = 0;
4912
    scmd.msg.assign(msg);
127 andreas 4913
    scmd.MC = 0x008c;
111 andreas 4914
 
4915
    if (gAmxNet)
4916
        gAmxNet->sendCommand(scmd);
4917
    else
4918
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4919
}
4920
 
110 andreas 4921
/**
4922
 * Sending a custom event is identical in all cases. Because of this I
4923
 * implemented this method to send a custom event. This is called in all cases
4924
 * where a ?XXX command is received.
4925
 *
4926
 * @param value1    The instance of the button.
4927
 * @param value2    The value of a numeric request or the length of the string.
4928
 * @param value3    Always 0
4929
 * @param msg       In case of a string this contains the string.
4930
 * @param evType    This is the event type, a number between 1001 and 1099.
4931
 * @param cp        Channel port of button.
4932
 * @param cn        Channel number. of button.
4933
 *
4934
 * @return If all parameters are valid it returns TRUE.
4935
 */
4936
bool TPageManager::sendCustomEvent(int value1, int value2, int value3, const string& msg, int evType, int cp, int cn)
4937
{
4938
    DECL_TRACER("TPageManager::sendCustomEvent(int value1, int value2, int value3, const string& msg, int evType)");
4939
 
4940
    if (value1 < 1)
4941
        return false;
4942
 
4943
    amx::ANET_SEND scmd;
4944
    scmd.port = cp;
4945
    scmd.channel = cn;
4946
    scmd.ID = scmd.channel;
4947
    scmd.flag = 0;
4948
    scmd.type = evType;
4949
    scmd.value1 = value1;   // instance
4950
    scmd.value2 = value2;
4951
    scmd.value3 = value3;
4952
    scmd.msg = msg;
4953
 
4954
    if (!msg.empty())
4955
        scmd.dtype = 0x0001;// Char array
4956
 
4957
    scmd.MC = 0x008d;       // custom event
4958
 
4959
    if (gAmxNet)
4960
        gAmxNet->sendCommand(scmd);
4961
    else
4962
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4963
 
4964
    return true;
4965
}
129 andreas 4966
#ifndef _NOSIP_
127 andreas 4967
string TPageManager::sipStateToString(TSIPClient::SIP_STATE_t s)
4968
{
4969
    DECL_TRACER("TPageManager::sipStateToString(TSIPClient::SIP_STATE_t s)");
4970
 
4971
    switch(s)
4972
    {
4973
        case TSIPClient::SIP_CONNECTED:     return "CONNECTED";
4974
        case TSIPClient::SIP_DISCONNECTED:  return "DISCONNECTED";
4975
        case TSIPClient::SIP_HOLD:          return "HOLD";
4976
        case TSIPClient::SIP_RINGING:       return "RINGING";
4977
        case TSIPClient::SIP_TRYING:        return "TRYING";
4978
 
4979
        default:
4980
            return "IDLE";
4981
    }
4982
 
4983
    return "IDLE";
4984
}
129 andreas 4985
#endif
134 andreas 4986
void TPageManager::sendOrientation()
4987
{
4988
    string ori;
4989
 
4990
    switch(mOrientation)
4991
    {
4992
        case O_PORTRAIT:            ori = "DeviceOrientationPortrait"; break;
4993
        case O_REVERSE_PORTRAIT:    ori = "DeviceOrientationPortraitUpsideDown"; break;
4994
        case O_LANDSCAPE:           ori = "DeviceOrientationLandscapeLeft"; break;
4995
        case O_REVERSE_LANDSCAPE:   ori = "DeviceOrientationLandscapeRight"; break;
4996
        case O_FACE_UP:             ori = "DeviceOrientationFaceUp"; break;
4997
        case O_FACE_DOWN:           ori = "DeviceOrientationFaceDown"; break;
4998
        default:
4999
            return;
5000
    }
5001
 
5002
    sendGlobalString("TPCACC-" + ori);
5003
}
5004
 
153 andreas 5005
void TPageManager::onSwipeEvent(TPageManager::SWIPES sw)
5006
{
5007
    DECL_TRACER("TPageManager::onSwipeEvent(TPageManager::SWIPES sw)");
5008
 
5009
    // Swipes are defined in "external".
5010
    if (!mExternal)
5011
        return;
5012
 
5013
    extButtons_t eBt;
5014
    string dbg;
5015
 
5016
    switch(sw)
5017
    {
5018
        case SW_LEFT:   eBt = EXT_GESTURE_LEFT; dbg.assign("LEFT"); break;
5019
        case SW_RIGHT:  eBt = EXT_GESTURE_RIGHT; dbg.assign("RIGHT"); break;
5020
        case SW_UP:     eBt = EXT_GESTURE_UP; dbg.assign("UP"); break;
5021
        case SW_DOWN:   eBt = EXT_GESTURE_DOWN; dbg.assign("DOWN"); break;
5022
 
5023
        default:
5024
            return;
5025
    }
5026
 
5027
    int pgNum = getActualPageNumber();
5028
    EXTBUTTON_t bt = mExternal->getButton(pgNum, eBt);
5029
 
5030
    if (bt.bi == 0)
5031
        return;
5032
 
5033
    MSG_DEBUG("Received swipe " << dbg << " event for page " << pgNum << " on button " << bt.bi << " \"" << bt.na << "\"");
5034
 
5035
    if (!bt.cm.empty() && bt.co == 0)           // Feed command to ourself?
5036
    {                                           // Yes, then feed it into command queue.
5037
        MSG_DEBUG("Button has a self feed command");
5038
 
5039
        int channel = TConfig::getChannel();
5040
        int system = TConfig::getSystem();
5041
 
5042
        amx::ANET_COMMAND cmd;
5043
        cmd.MC = 0x000c;
5044
        cmd.device1 = channel;
5045
        cmd.port1 = bt.ap;
5046
        cmd.system = system;
5047
        cmd.data.message_string.device = channel;
5048
        cmd.data.message_string.port = bt.ap;  // Must be the address port of button
5049
        cmd.data.message_string.system = system;
5050
        cmd.data.message_string.type = 1;   // 8 bit char string
5051
 
5052
        vector<string>::iterator iter;
5053
 
5054
        for (iter = bt.cm.begin(); iter != bt.cm.end(); ++iter)
5055
        {
5056
            cmd.data.message_string.length = iter->length();
5057
            memset(&cmd.data.message_string.content, 0, sizeof(cmd.data.message_string.content));
5058
            strncpy((char *)&cmd.data.message_string.content, iter->c_str(), sizeof(cmd.data.message_string.content));
5059
            doCommand(cmd);
5060
        }
5061
    }
5062
    else if (!bt.cm.empty())
5063
    {
5064
        MSG_DEBUG("Button sends a command on port " << bt.co);
5065
 
5066
        vector<string>::iterator iter;
5067
 
5068
        for (iter = bt.cm.begin(); iter != bt.cm.end(); ++iter)
5069
            sendCommandString(bt.co, *iter);
5070
    }
5071
}
5072
 
36 andreas 5073
/****************************************************************************
11 andreas 5074
 * The following functions implements one of the commands the panel accepts.
5075
 ****************************************************************************/
43 andreas 5076
 
5077
/**
5078
 * This is a special function handling the progress bars when the files of the
5079
 * panel are updated. Instead of simply displaying a ready page, it fakes one
5080
 * with the actual dimensions of the main page. This is possible, because we've
5081
 * always a main page even if the panel is started for the first time.
5082
 */
5083
void TPageManager::doFTR(int port, vector<int>& channels, vector<string>& pars)
23 andreas 5084
{
43 andreas 5085
    DECL_TRACER("TPageManager::doFTR(int, vector<int>&, vector<string>& pars)");
14 andreas 5086
 
23 andreas 5087
    if (pars.empty())
5088
    {
5089
        MSG_WARNING("Command #FTR needs at least 1 parameter! Ignoring command.");
5090
        return;
5091
    }
5092
 
96 andreas 5093
    if (TStreamError::checkFilter(HLOG_DEBUG))
23 andreas 5094
    {
96 andreas 5095
        for (size_t i = 0; i < pars.size(); i++)
5096
        {
5097
            MSG_DEBUG("[" << i << "]: " << pars.at(i));
5098
        }
23 andreas 5099
    }
43 andreas 5100
 
5101
    if (pars.at(0).compare("START") == 0)
5102
    {
5103
        // Here we have to drop all pages and subpages first and then display
5104
        // the faked page with the progress bars.
5105
        MSG_DEBUG("Starting file transfer ...");
5106
        doPPX(port, channels, pars);
5107
        TPage *pg = getPage("_progress");
5108
 
5109
        if (!pg)
5110
        {
5111
            if (!readPage("_progress"))
5112
            {
5113
                MSG_ERROR("Error creating the system page _progress!");
5114
                return;
5115
            }
5116
 
5117
            pg = getPage("_progress");
5118
 
5119
            if (!pg)
5120
            {
5121
                MSG_ERROR("Error getting system page _progress!");
5122
                return;
5123
            }
5124
        }
5125
 
5126
        pg->setFonts(mFonts);
5127
        pg->registerCallback(_setBackground);
5128
        pg->regCallPlayVideo(_callPlayVideo);
5129
 
5130
        if (!pg || !_setPage || !mTSettings)
5131
            return;
5132
 
5133
        int width, height;
217 andreas 5134
        width = mTSettings->getWidth();
43 andreas 5135
        height = mTSettings->getHeight();
5136
#ifdef _SCALE_SKIA_
5137
        if (mScaleFactor != 1.0)
5138
        {
5139
            width = (int)((double)width * mScaleFactor);
5140
            height = (int)((double)height * mScaleFactor);
5141
        }
5142
#endif
5143
        _setPage((pg->getNumber() << 16) & 0xffff0000, width, height);
5144
        pg->show();
5145
        MSG_DEBUG("Page _progress on screen");
5146
    }
5147
    else if (pars.at(0).compare("SYNC") == 0)
5148
    {
5149
        TPage *pg = getPage("_progress");
5150
 
5151
        if (!pg)
5152
        {
5153
            MSG_ERROR("Page _progress not found!");
5154
            return;
5155
        }
5156
 
5157
        Button::TButton *bt = pg->getButton(1);   // Line 1
5158
 
5159
        if (!bt)
5160
        {
5161
            MSG_ERROR("Button 160 of page _progress not found!");
5162
            return;
5163
        }
5164
 
5165
        bt->setText(pars.at(2), 0);
5166
        bt->show();
5167
    }
5168
    else if (pars.at(0).compare("FTRSTART") == 0)
5169
    {
5170
        TPage *pg = getPage("_progress");
5171
 
5172
        if (!pg)
5173
        {
5174
            MSG_ERROR("Page _progress not found!");
5175
            return;
5176
        }
5177
 
5178
        Button::TButton *bt1 = pg->getButton(1);   // Line 1
5179
        Button::TButton *bt2 = pg->getButton(2);   // Line 2
5180
        Button::TButton *bt3 = pg->getButton(3);   // Bargraph 1
5181
        Button::TButton *bt4 = pg->getButton(4);   // Bargraph 2
5182
 
5183
        if (!bt1 || !bt2 || !bt3 || !bt4)
5184
        {
5185
            MSG_ERROR("Buttons of page _progress not found!");
5186
            return;
5187
        }
5188
 
5189
        bt1->setText("Transfering files ...", 0);
5190
        bt1->show();
5191
        bt2->setText(pars.at(3), 0);
5192
        bt2->show();
5193
        bt3->drawBargraph(0, atoi(pars.at(1).c_str()), true);
5194
        bt4->drawBargraph(0, atoi(pars.at(2).c_str()), true);
5195
    }
5196
    else if (pars.at(0).compare("FTRPART") == 0)
5197
    {
5198
        TPage *pg = getPage("_progress");
5199
 
5200
        if (!pg)
5201
        {
5202
            MSG_ERROR("Page _progress not found!");
5203
            return;
5204
        }
5205
 
5206
        Button::TButton *bt = pg->getButton(4);   // Bargraph 2
5207
 
5208
        if (!bt)
5209
        {
5210
            MSG_ERROR("Buttons of page _progress not found!");
5211
            return;
5212
        }
5213
 
5214
        bt->drawBargraph(0, atoi(pars.at(2).c_str()), true);
5215
    }
5216
    else if (pars.at(0).compare("END") == 0)
5217
    {
5218
        MSG_TRACE("End of file transfer reached.");
44 andreas 5219
 
155 andreas 5220
        // To make sure the new surface will not be deleted and replaced by the
5221
        // default build in surface, we must delete the "virgin" marker first.
5222
        // This is a file called <project path>/.system.
5223
        string virgin = TConfig::getProjectPath() + "/.system";
5224
        remove(virgin.c_str());     // Because this file may not exist we don't care about the result code.
5225
 
44 andreas 5226
        if (_resetSurface)
5227
            _resetSurface();
5228
        else
5229
        {
5230
            MSG_WARNING("Missing callback function \"resetSurface\"!");
5231
        }
43 andreas 5232
    }
23 andreas 5233
}
5234
 
318 andreas 5235
void TPageManager::doLEVON(int, vector<int>&, vector<string>&)
5236
{
5237
    DECL_TRACER("TPageManager::doLEVON(int, vector<int>&, vector<string>&)");
5238
 
5239
    mLevelSend = true;
343 andreas 5240
#if TESTMODE == 1
5241
    __success = true;
5242
    setAllDone();
5243
#endif
318 andreas 5244
}
5245
 
5246
void TPageManager::doLEVOF(int, vector<int>&, vector<string>&)
5247
{
5248
    DECL_TRACER("TPageManager::doLEVOF(int, vector<int>&, vector<string>&)");
5249
 
5250
    mLevelSend = false;
343 andreas 5251
#if TESTMODE == 1
5252
    __success = true;
5253
    setAllDone();
5254
#endif
318 andreas 5255
}
5256
 
5257
void TPageManager::doRXON(int, vector<int>&, vector<string>&)
5258
{
5259
    DECL_TRACER("TPageManager::doRXON(int, vector<int>&, vector<string>&)");
5260
 
5261
    mRxOn = true;
343 andreas 5262
#if TESTMODE == 1
5263
    __success = true;
5264
    setAllDone();
5265
#endif
318 andreas 5266
}
5267
 
5268
void TPageManager::doRXOF(int, vector<int>&, vector<string>&)
5269
{
5270
    DECL_TRACER("TPageManager::doRXOF(int, vector<int>&, vector<string>&)");
5271
 
5272
    mRxOn = false;
343 andreas 5273
#if TESTMODE == 1
5274
    __success = true;
5275
    setAllDone();
5276
#endif
318 andreas 5277
}
5278
 
22 andreas 5279
void TPageManager::doON(int port, vector<int>&, vector<string>& pars)
14 andreas 5280
{
5281
    DECL_TRACER("TPageManager::doON(int port, vector<int>& channels, vector<string>& pars)");
5282
 
5283
    if (pars.empty())
5284
    {
5285
        MSG_WARNING("Command ON needs 1 parameter! Ignoring command.");
343 andreas 5286
#if TESTMODE == 1
5287
        setAllDone();
5288
#endif
14 andreas 5289
        return;
5290
    }
5291
 
16 andreas 5292
    TError::clear();
14 andreas 5293
    int c = atoi(pars[0].c_str());
5294
 
5295
    if (c <= 0)
5296
    {
5297
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
343 andreas 5298
#if TESTMODE == 1
5299
        setAllDone();
5300
#endif
14 andreas 5301
        return;
5302
    }
5303
 
5304
    vector<int> chans = { c };
193 andreas 5305
    vector<TMap::MAP_T> map = findButtons(port, chans, TMap::TYPE_CM);
14 andreas 5306
 
5307
    if (TError::isError() || map.empty())
343 andreas 5308
    {
5309
#if TESTMODE == 1
5310
        setAllDone();
5311
#endif
14 andreas 5312
        return;
343 andreas 5313
    }
14 andreas 5314
 
5315
    vector<Button::TButton *> buttons = collectButtons(map);
5316
 
83 andreas 5317
    if (buttons.size() > 0)
14 andreas 5318
    {
83 andreas 5319
        vector<Button::TButton *>::iterator mapIter;
14 andreas 5320
 
118 andreas 5321
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
83 andreas 5322
        {
5323
            Button::TButton *bt = *mapIter;
5324
 
195 andreas 5325
            if (bt->getButtonType() == GENERAL)
343 andreas 5326
            {
83 andreas 5327
                bt->setActive(1);
343 andreas 5328
#if TESTMODE == 1
5329
                if (_gTestMode)
5330
                    _gTestMode->setResult(intToString(bt->getActiveInstance() + 1));
5331
#endif
5332
            }
83 andreas 5333
        }
14 andreas 5334
    }
343 andreas 5335
#if TESTMODE == 1
5336
    setDone();
5337
#endif
14 andreas 5338
}
5339
 
22 andreas 5340
void TPageManager::doOFF(int port, vector<int>&, vector<string>& pars)
14 andreas 5341
{
5342
    DECL_TRACER("TPageManager::doOFF(int port, vector<int>& channels, vector<string>& pars)");
5343
 
5344
    if (pars.empty())
5345
    {
5346
        MSG_WARNING("Command OFF needs 1 parameter! Ignoring command.");
343 andreas 5347
#if TESTMODE == 1
5348
        setAllDone();
5349
#endif
14 andreas 5350
        return;
5351
    }
5352
 
16 andreas 5353
    TError::clear();
14 andreas 5354
    int c = atoi(pars[0].c_str());
5355
 
5356
    if (c <= 0)
5357
    {
5358
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
343 andreas 5359
#if TESTMODE == 1
5360
        setAllDone();
5361
#endif
14 andreas 5362
        return;
5363
    }
5364
 
5365
    vector<int> chans = { c };
193 andreas 5366
    vector<TMap::MAP_T> map = findButtons(port, chans, TMap::TYPE_CM);
14 andreas 5367
 
5368
    if (TError::isError() || map.empty())
5369
        return;
5370
 
5371
    vector<Button::TButton *> buttons = collectButtons(map);
5372
 
83 andreas 5373
    if (buttons.size() > 0)
14 andreas 5374
    {
83 andreas 5375
        vector<Button::TButton *>::iterator mapIter;
14 andreas 5376
 
118 andreas 5377
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
83 andreas 5378
        {
5379
            Button::TButton *bt = *mapIter;
5380
 
195 andreas 5381
            if (bt->getButtonType() == GENERAL)
83 andreas 5382
                bt->setActive(0);
343 andreas 5383
#if TESTMODE == 1
5384
                if (_gTestMode)
5385
                    _gTestMode->setResult(intToString(bt->getActiveInstance() + 1));
5386
#endif
83 andreas 5387
        }
14 andreas 5388
    }
343 andreas 5389
#if TESTMODE == 1
5390
    setDone();
5391
#endif
14 andreas 5392
}
5393
 
22 andreas 5394
void TPageManager::doLEVEL(int port, vector<int>&, vector<string>& pars)
15 andreas 5395
{
5396
    DECL_TRACER("TPageManager::doLEVEL(int port, vector<int>& channels, vector<string>& pars)");
5397
 
5398
    if (pars.size() < 2)
5399
    {
5400
        MSG_WARNING("Command LEVEL needs 2 parameters! Ignoring command.");
343 andreas 5401
#if TESTMODE == 1
5402
        setAllDone();
5403
#endif
15 andreas 5404
        return;
5405
    }
5406
 
16 andreas 5407
    TError::clear();
15 andreas 5408
    int c = atoi(pars[0].c_str());
5409
    int level = atoi(pars[1].c_str());
5410
 
5411
    if (c <= 0)
5412
    {
5413
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
343 andreas 5414
#if TESTMODE == 1
5415
        setAllDone();
5416
#endif
15 andreas 5417
        return;
5418
    }
5419
 
5420
    vector<int> chans = { c };
193 andreas 5421
    vector<TMap::MAP_T> map = findBargraphs(port, chans);
15 andreas 5422
 
5423
    if (TError::isError() || map.empty())
5424
    {
5425
        MSG_WARNING("No bargraphs found!");
343 andreas 5426
#if TESTMODE == 1
5427
        setAllDone();
5428
#endif
15 andreas 5429
        return;
5430
    }
5431
 
5432
    vector<Button::TButton *> buttons = collectButtons(map);
5433
 
83 andreas 5434
    if (buttons.size() > 0)
15 andreas 5435
    {
83 andreas 5436
        vector<Button::TButton *>::iterator mapIter;
15 andreas 5437
 
118 andreas 5438
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
15 andreas 5439
        {
83 andreas 5440
            Button::TButton *bt = *mapIter;
5441
 
195 andreas 5442
            if (bt->getButtonType() == BARGRAPH)
343 andreas 5443
            {
83 andreas 5444
                bt->drawBargraph(bt->getActiveInstance(), level);
343 andreas 5445
#if TESTMODE == 1
5446
                if (_gTestMode)
5447
                    _gTestMode->setResult(intToString(bt->getLevelValue()));
5448
#endif
5449
            }
195 andreas 5450
            else if (bt->getButtonType() == MULTISTATE_BARGRAPH)
83 andreas 5451
            {
5452
                int state = (int)((double)bt->getStateCount() / (double)(bt->getRangeHigh() - bt->getRangeLow()) * (double)level);
5453
                bt->setActive(state);
343 andreas 5454
#if TESTMODE == 1
5455
                if (_gTestMode)
5456
                    _gTestMode->setResult(intToString(bt->getActiveInstance()));
5457
#endif
83 andreas 5458
            }
15 andreas 5459
        }
5460
    }
343 andreas 5461
#if TESTMODE == 1
5462
    setDone();
5463
#endif
15 andreas 5464
}
5465
 
22 andreas 5466
void TPageManager::doBLINK(int, vector<int>&, vector<string>& pars)
15 andreas 5467
{
5468
    DECL_TRACER("TPageManager::doBLINK(int port, vector<int>& channels, vector<string>& pars)");
5469
 
5470
    if (pars.size() < 4)
5471
    {
5472
        MSG_WARNING("Command BLINK expects 4 parameters! Command ignored.");
343 andreas 5473
#if TESTMODE == 1
5474
        setAllDone();
5475
#endif
15 andreas 5476
        return;
5477
    }
5478
 
16 andreas 5479
    TError::clear();
15 andreas 5480
    vector<int> sysButtons = { 141, 142, 143, 151, 152, 153, 154, 155, 156, 157, 158 };
193 andreas 5481
    vector<TMap::MAP_T> map = findButtons(0, sysButtons);
15 andreas 5482
 
5483
    if (TError::isError() || map.empty())
5484
    {
5485
        MSG_WARNING("No system buttons found.");
343 andreas 5486
#if TESTMODE == 1
5487
        setAllDone();
5488
#endif
15 andreas 5489
        return;
5490
    }
5491
 
5492
    vector<Button::TButton *> buttons = collectButtons(map);
5493
    vector<Button::TButton *>::iterator mapIter;
5494
 
5495
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
5496
    {
5497
        Button::TButton *bt = *mapIter;
5498
        bt->setActive(0);
343 andreas 5499
#if TESTMODE == 1
5500
                if (_gTestMode)
5501
                    _gTestMode->setResult(intToString(bt->getActiveInstance() + 1));
5502
#endif
15 andreas 5503
    }
343 andreas 5504
#if TESTMODE == 1
5505
    setDone();
5506
#endif
15 andreas 5507
}
5508
 
162 andreas 5509
/**
5510
 * Send the version of the panel to the NetLinx. This is the real application
5511
 * version.
5512
 */
127 andreas 5513
void TPageManager::doVER(int, vector<int>&, vector<string>&)
5514
{
5515
    DECL_TRACER("TPageManager::doVER(int, vector<int>&, vector<string>&)");
5516
 
5517
    amx::ANET_SEND scmd;
5518
    scmd.port = 1;
5519
    scmd.channel = 0;
5520
    scmd.msg.assign(string("^VER-")+VERSION_STRING());
5521
    scmd.MC = 0x008c;
5522
 
5523
    if (gAmxNet)
343 andreas 5524
    {
127 andreas 5525
        gAmxNet->sendCommand(scmd);
343 andreas 5526
#if TESTMODE == 1
5527
        __success = true;
347 andreas 5528
 
5529
        if (_gTestMode)
5530
            _gTestMode->setResult(VERSION_STRING());
343 andreas 5531
#endif
5532
    }
127 andreas 5533
    else
5534
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
343 andreas 5535
#if TESTMODE == 1
5536
    setAllDone();
5537
#endif
127 andreas 5538
}
5539
 
162 andreas 5540
/**
5541
 * Returns the user name used to connect to a SIP server. An empty string is
5542
 * returned if there is no user defined.
5543
 */
279 andreas 5544
#ifndef _NOSIP_
127 andreas 5545
void TPageManager::doWCN(int, vector<int>&, vector<string>&)
5546
{
5547
    DECL_TRACER("TPageManager::doWCN(int, vector<int>&, vector<string>&)");
5548
 
5549
    if (!TConfig::getSIPstatus())
343 andreas 5550
    {
5551
#if TESTMODE == 1
5552
        setAllDone();
5553
#endif
127 andreas 5554
        return;
343 andreas 5555
    }
127 andreas 5556
 
5557
    amx::ANET_SEND scmd;
5558
    scmd.port = 1;
5559
    scmd.channel = 0;
5560
    scmd.msg.assign("^WCN-" + TConfig::getSIPuser());
5561
    scmd.MC = 0x008c;
5562
 
5563
    if (gAmxNet)
343 andreas 5564
    {
127 andreas 5565
        gAmxNet->sendCommand(scmd);
343 andreas 5566
#if TESTMODE == 1
5567
        __success = true;
347 andreas 5568
 
5569
        if (_gTestMode)
5570
            _gTestMode->setResult(TConfig::getSIPuser());
343 andreas 5571
#endif
5572
    }
127 andreas 5573
    else
5574
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
343 andreas 5575
#if TESTMODE == 1
5576
        setAllDone();
5577
#endif
127 andreas 5578
}
279 andreas 5579
#endif
14 andreas 5580
/**
147 andreas 5581
 * Flip to specified page using the named animation.
5582
 * FIXME: Implement animation for pages.
5583
 */
5584
void TPageManager::doAFP(int, vector<int>&, vector<string>& pars)
5585
{
5586
    DECL_TRACER("TPageManager::doAFP(int, vector<int>&, vector<string>& pars)");
5587
 
5588
    if (pars.size() < 4)
5589
    {
5590
        MSG_ERROR("Less than 4 parameters!");
343 andreas 5591
#if TESTMODE == 1
5592
        setAllDone();
5593
#endif
147 andreas 5594
        return;
5595
    }
5596
 
5597
    TError::clear();
5598
    string pname = pars[0];
5599
//    string ani = pars[1];
5600
//    int origin = atoi(pars[2].c_str());
5601
//    int duration = atoi(pars[3].c_str());
5602
 
5603
    // FIXME: Animation of pages is currently not implemented.
5604
 
5605
    if (!pname.empty())
5606
        setPage(pname);
5607
    else if (mPreviousPage)
5608
        setPage(mPreviousPage);
343 andreas 5609
#if TESTMODE == 1
5610
    if (_gTestMode)
5611
        _gTestMode->setResult(getActualPage()->getName());
5612
 
5613
    setDone();
5614
#endif
147 andreas 5615
}
5616
 
5617
/**
14 andreas 5618
 * Add a specific popup page to a specified popup group if it does not already
5619
 * exist. If the new popup is added to a group which has a popup displayed on
5620
 * the current page along with the new pop-up, the displayed popup will be
5621
 * hidden and the new popup will be displayed.
5622
 */
22 andreas 5623
void TPageManager::doAPG(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 5624
{
5625
    DECL_TRACER("TPageManager::doAPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5626
 
5627
    if (pars.size() < 2)
5628
    {
5629
        MSG_ERROR("Less than 2 parameters!");
343 andreas 5630
#if TESTMODE == 1
5631
        setAllDone();
5632
#endif
11 andreas 5633
        return;
5634
    }
5635
 
16 andreas 5636
    TError::clear();
11 andreas 5637
    closeGroup(pars[1]);
14 andreas 5638
 
96 andreas 5639
    TPage *page = nullptr;
5640
    TSubPage *subPage = deliverSubPage(pars[0], &page);
14 andreas 5641
 
11 andreas 5642
    if (!subPage)
5643
    {
5644
        MSG_ERROR("Subpage " << pars[0] << " couldn't either found or created!");
343 andreas 5645
#if TESTMODE == 1
5646
        setAllDone();
5647
#endif
11 andreas 5648
        return;
5649
    }
5650
 
162 andreas 5651
    if (!page)
5652
    {
5653
        MSG_ERROR("There seems to be no page for subpage " << pars[0]);
343 andreas 5654
#if TESTMODE == 1
5655
        setAllDone();
5656
#endif
162 andreas 5657
        return;
5658
    }
5659
 
152 andreas 5660
    page->addSubPage(subPage);
11 andreas 5661
    subPage->setGroup(pars[1]);
14 andreas 5662
    subPage->setZOrder(page->getNextZOrder());
152 andreas 5663
    MSG_DEBUG("Setting new Z-order " << page->getActZOrder() << " on page " << page->getName());
11 andreas 5664
    subPage->show();
343 andreas 5665
#if TESTMODE == 1
347 andreas 5666
    if (_gTestMode)
5667
        _gTestMode->setResult(subPage->getGroupName() + ":" + subPage->getName());
5668
 
343 andreas 5669
    setDone();
5670
#endif
11 andreas 5671
}
5672
 
14 andreas 5673
/**
5674
 * Clear all popup pages from specified popup group.
5675
 */
22 andreas 5676
void TPageManager::doCPG(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 5677
{
5678
    DECL_TRACER("TPageManager::doCPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5679
 
5680
    if (pars.size() < 1)
5681
    {
5682
        MSG_ERROR("Expecting 1 parameter but got only 1!");
343 andreas 5683
#if TESTMODE == 1
5684
        setAllDone();
5685
#endif
11 andreas 5686
        return;
5687
    }
5688
 
16 andreas 5689
    TError::clear();
348 andreas 5690
    vector<SUBPAGELIST_T> pageList = mPageList->getSubPageList();
11 andreas 5691
 
83 andreas 5692
    if (pageList.size() > 0)
11 andreas 5693
    {
83 andreas 5694
        vector<SUBPAGELIST_T>::iterator pgIter;
5695
 
5696
        for (pgIter = pageList.begin(); pgIter != pageList.end(); pgIter++)
11 andreas 5697
        {
83 andreas 5698
            if (pgIter->group.compare(pars[0]) == 0)
5699
            {
5700
                pgIter->group.clear();
5701
                TSubPage *pg = getSubPage(pgIter->pageID);
11 andreas 5702
 
83 andreas 5703
                if (pg)
5704
                    pg->setGroup(pgIter->group);
343 andreas 5705
#if TESTMODE == 1
5706
                __success = true;
5707
#endif
83 andreas 5708
            }
11 andreas 5709
        }
5710
    }
343 andreas 5711
#if TESTMODE == 1
5712
    setDone();
5713
#endif
11 andreas 5714
}
5715
 
14 andreas 5716
/**
5717
 * Delete a specific popup page from specified popup group if it exists.
5718
 */
22 andreas 5719
void TPageManager::doDPG(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 5720
{
5721
    DECL_TRACER("TPageManager::doDPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5722
 
5723
    if (pars.size() < 2)
5724
    {
5725
        MSG_ERROR("Less than 2 parameters!");
348 andreas 5726
#if TESTMODE == 1
5727
        setAllDone();
5728
#endif
11 andreas 5729
        return;
5730
    }
5731
 
16 andreas 5732
    TError::clear();
11 andreas 5733
    SUBPAGELIST_T listPg = findSubPage(pars[0]);
5734
 
5735
    if (!listPg.isValid)
348 andreas 5736
    {
5737
#if TESTMODE == 1
5738
        setAllDone();
5739
#endif
11 andreas 5740
        return;
348 andreas 5741
    }
11 andreas 5742
 
5743
    if (listPg.group.compare(pars[1]) == 0)
5744
    {
5745
        listPg.group.clear();
5746
        TSubPage *pg = getSubPage(listPg.pageID);
5747
 
5748
        if (pg)
5749
            pg->setGroup(listPg.group);
348 andreas 5750
#if TESTMODE == 1
5751
        __success = true;
5752
#endif
11 andreas 5753
    }
348 andreas 5754
#if TESTMODE == 1
5755
    setDone();
5756
#endif
11 andreas 5757
}
5758
 
14 andreas 5759
/**
15 andreas 5760
 * Set the hide effect for the specified popup page to the named hide effect.
5761
 */
22 andreas 5762
void TPageManager::doPHE(int, vector<int>&, vector<string>& pars)
15 andreas 5763
{
5764
    DECL_TRACER("TPageManager::doPHE(int port, vector<int>& channels, vector<string>& pars)");
5765
 
5766
    if (pars.size() < 2)
5767
    {
5768
        MSG_ERROR("Less than 2 parameters!");
348 andreas 5769
#if TESTMODE == 1
5770
        setAllDone();
5771
#endif
15 andreas 5772
        return;
5773
    }
5774
 
16 andreas 5775
    TError::clear();
96 andreas 5776
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 5777
 
5778
    if (!pg)
348 andreas 5779
    {
5780
#if TESTMODE == 1
5781
        setAllDone();
5782
#endif
96 andreas 5783
        return;
348 andreas 5784
    }
15 andreas 5785
 
162 andreas 5786
    if (strCaseCompare(pars[1], "fade") == 0)
15 andreas 5787
        pg->setHideEffect(SE_FADE);
162 andreas 5788
    else if (strCaseCompare(pars[1], "slide to left") == 0)
15 andreas 5789
        pg->setHideEffect(SE_SLIDE_LEFT);
162 andreas 5790
    else if (strCaseCompare(pars[1], "slide to right") == 0)
15 andreas 5791
        pg->setHideEffect(SE_SLIDE_RIGHT);
162 andreas 5792
    else if (strCaseCompare(pars[1], "slide to top") == 0)
15 andreas 5793
        pg->setHideEffect(SE_SLIDE_TOP);
162 andreas 5794
    else if (strCaseCompare(pars[1], "slide to bottom") == 0)
15 andreas 5795
        pg->setHideEffect(SE_SLIDE_BOTTOM);
162 andreas 5796
    else if (strCaseCompare(pars[1], "slide to left fade") == 0)
15 andreas 5797
        pg->setHideEffect(SE_SLIDE_LEFT_FADE);
162 andreas 5798
    else if (strCaseCompare(pars[1], "slide to right fade") == 0)
15 andreas 5799
        pg->setHideEffect(SE_SLIDE_RIGHT_FADE);
162 andreas 5800
    else if (strCaseCompare(pars[1], "slide to top fade") == 0)
15 andreas 5801
        pg->setHideEffect(SE_SLIDE_TOP_FADE);
162 andreas 5802
    else if (strCaseCompare(pars[1], "slide to bottom fade") == 0)
15 andreas 5803
        pg->setHideEffect(SE_SLIDE_BOTTOM_FADE);
5804
    else
5805
        pg->setHideEffect(SE_NONE);
348 andreas 5806
#if TESTMODE == 1
5807
    if (_gTestMode)
5808
        _gTestMode->setResult(intToString(pg->getHideEffect()));
5809
 
5810
    __success = true;
5811
    setAllDone();
5812
#endif
15 andreas 5813
}
5814
 
5815
/**
5816
 * Set the hide effect position. Only 1 coordinate is ever needed for an effect;
5817
 * however, the command will specify both. This command sets the location at
5818
 * which the effect will end at.
5819
 */
22 andreas 5820
void TPageManager::doPHP(int, vector<int>&, vector<string>& pars)
15 andreas 5821
{
5822
    DECL_TRACER("TPageManager::doPHP(int port, vector<int>& channels, vector<string>& pars)");
5823
 
5824
    if (pars.size() < 2)
5825
    {
5826
        MSG_ERROR("Less than 2 parameters!");
348 andreas 5827
#if TESTMODE == 1
5828
        setAllDone();
5829
#endif
15 andreas 5830
        return;
5831
    }
5832
 
16 andreas 5833
    TError::clear();
15 andreas 5834
    size_t pos = pars[1].find(",");
5835
    int x, y;
5836
 
5837
    if (pos == string::npos)
5838
    {
5839
        x = atoi(pars[1].c_str());
5840
        y = 0;
5841
    }
5842
    else
5843
    {
5844
        x = atoi(pars[1].substr(0, pos).c_str());
5845
        y = atoi(pars[1].substr(pos+1).c_str());
5846
    }
5847
 
96 andreas 5848
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 5849
 
5850
    if (!pg)
348 andreas 5851
    {
5852
#if TESTMODE == 1
5853
        setAllDone();
5854
#endif
96 andreas 5855
        return;
348 andreas 5856
    }
15 andreas 5857
 
5858
    pg->setHideEndPosition(x, y);
348 andreas 5859
#if TESTMODE == 1
5860
    if (_gTestMode)
5861
    {
5862
        int x, y;
5863
        pg->getHideEndPosition(&x, &y);
5864
        _gTestMode->setResult(intToString(x) + "," + intToString(y));
5865
    }
5866
 
5867
    __success = true;
5868
    setAllDone();
5869
#endif
15 andreas 5870
}
5871
 
5872
/**
5873
 * Set the hide effect time for the specified popup page.
5874
 */
22 andreas 5875
void TPageManager::doPHT(int, vector<int>&, vector<string>& pars)
15 andreas 5876
{
5877
    DECL_TRACER("TPageManager::doPHT(int port, vector<int>& channels, vector<string>& pars)");
5878
 
5879
    if (pars.size() < 2)
5880
    {
5881
        MSG_ERROR("Less than 2 parameters!");
348 andreas 5882
#if TESTMODE == 1
5883
        setAllDone();
5884
#endif
15 andreas 5885
        return;
5886
    }
5887
 
16 andreas 5888
    TError::clear();
96 andreas 5889
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 5890
 
5891
    if (!pg)
348 andreas 5892
    {
5893
#if TESTMODE == 1
5894
        setAllDone();
5895
#endif
96 andreas 5896
        return;
348 andreas 5897
    }
15 andreas 5898
 
5899
    pg->setHideTime(atoi(pars[1].c_str()));
348 andreas 5900
#if TESTMODE == 1
5901
    if (_gTestMode)
5902
        _gTestMode->setResult(intToString(pg->getHideTime()));
5903
 
5904
    __success = true;
5905
    setAllDone();
5906
#endif
15 andreas 5907
}
5908
 
5909
/**
14 andreas 5910
 * Close all popups on a specified page. If the page name is empty, the current
5911
 * page is used. Same as the ’Clear Page’ command in TPDesign4.
5912
 */
22 andreas 5913
void TPageManager::doPPA(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 5914
{
5915
    DECL_TRACER("TPageManager::doPPA(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5916
 
16 andreas 5917
    TError::clear();
11 andreas 5918
    TPage *pg;
5919
 
5920
    if (pars.size() == 0)
5921
        pg = getPage(mActualPage);
5922
    else
5923
        pg = getPage(pars[0]);
5924
 
5925
    if (!pg)
348 andreas 5926
    {
5927
#if TESTMODE == 1
5928
        setAllDone();
5929
#endif
11 andreas 5930
        return;
348 andreas 5931
    }
11 andreas 5932
 
12 andreas 5933
    pg->drop();
14 andreas 5934
    pg->resetZOrder();
348 andreas 5935
#if TESTMODE == 1
5936
    setDone();
5937
#endif
11 andreas 5938
}
5939
 
14 andreas 5940
/**
5941
 * Deactivate a specific popup page on either a specified page or the current
5942
 * page. If the page name is empty, the current page is used. If the popup page
5943
 * is part of a group, the whole group is deactivated. This command works in
5944
 * the same way as the ’Hide Popup’ command in TPDesign4.
5945
 */
22 andreas 5946
void TPageManager::doPPF(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 5947
{
5948
    DECL_TRACER("TPageManager::doPPF(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5949
 
5950
    if (pars.size() < 1)
5951
    {
5952
        MSG_ERROR("At least 1 parameter is expected!");
349 andreas 5953
#if TESTMODE == 1
5954
        setAllDone();
5955
#endif
12 andreas 5956
        return;
5957
    }
5958
 
16 andreas 5959
    TError::clear();
14 andreas 5960
    hideSubPage(pars[0]);
335 andreas 5961
#if TESTMODE == 1
5962
    setDone();
5963
#endif
12 andreas 5964
}
5965
 
14 andreas 5966
/**
5967
 * Toggle a specific popup page on either a specified page or the current page.
5968
 * If the page name is empty, the current page is used. Toggling refers to the
5969
 * activating/deactivating (On/Off) of a popup page. This command works in the
5970
 * same way as the ’Toggle Popup’ command in TPDesign4.
5971
 */
22 andreas 5972
void TPageManager::doPPG(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 5973
{
5974
    DECL_TRACER("TPageManager::doPPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 5975
 
12 andreas 5976
    if (pars.size() < 1)
5977
    {
5978
        MSG_ERROR("At least 1 parameter is expected!");
349 andreas 5979
#if TESTMODE == 1
5980
        setAllDone();
5981
#endif
12 andreas 5982
        return;
5983
    }
5984
 
16 andreas 5985
    TError::clear();
14 andreas 5986
    TPage *page = getPage(mActualPage);
5987
 
5988
    if (!page)
5989
    {
5990
        MSG_ERROR("No active page found! Internal error.");
349 andreas 5991
#if TESTMODE == 1
5992
        setAllDone();
5993
#endif
14 andreas 5994
        return;
5995
    }
5996
 
12 andreas 5997
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 5998
 
12 andreas 5999
    if (!pg)
349 andreas 6000
    {
6001
#if TESTMODE == 1
6002
        setAllDone();
6003
#endif
12 andreas 6004
        return;
349 andreas 6005
    }
14 andreas 6006
 
12 andreas 6007
    if (pg->isVisible())
6008
    {
6009
        pg->drop();
162 andreas 6010
        page->decZOrder();
349 andreas 6011
#if TESTMODE == 1
6012
        setDone();
6013
#endif
12 andreas 6014
        return;
6015
    }
6016
 
6017
    TSubPage *sub = getFirstSubPageGroup(pg->getGroupName());
14 andreas 6018
 
12 andreas 6019
    while(sub)
6020
    {
6021
        if (sub->getGroupName().compare(pg->getGroupName()) == 0 && sub->isVisible())
6022
            sub->drop();
14 andreas 6023
 
12 andreas 6024
        sub = getNextSubPageGroup(pg->getGroupName(), sub);
6025
    }
6026
 
152 andreas 6027
    pg->setZOrder(page->getNextZOrder());
6028
    MSG_DEBUG("Setting new Z-order " << page->getActZOrder() << " on page " << page->getName());
12 andreas 6029
    pg->show();
349 andreas 6030
#if TESTMODE == 1
6031
    setDone();
6032
#endif
12 andreas 6033
}
6034
 
14 andreas 6035
/**
6036
 * Kill refers to the deactivating (Off) of a popup window from all pages. If
6037
 * the pop-up page is part of a group, the whole group is deactivated. This
6038
 * command works in the same way as the 'Clear Group' command in TPDesign 4.
6039
 */
22 andreas 6040
void TPageManager::doPPK(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6041
{
6042
    DECL_TRACER("TPageManager::doPPK(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 6043
 
12 andreas 6044
    if (pars.size() < 1)
6045
    {
6046
        MSG_ERROR("At least 1 parameter is expected!");
349 andreas 6047
#if TESTMODE == 1
6048
        setAllDone();
6049
#endif
12 andreas 6050
        return;
6051
    }
6052
 
16 andreas 6053
    TError::clear();
14 andreas 6054
    TPage *page = getPage(mActualPage);
6055
 
6056
    if (!page)
6057
    {
6058
        MSG_ERROR("No active page found! Internal error.");
349 andreas 6059
#if TESTMODE == 1
6060
        setAllDone();
6061
#endif
14 andreas 6062
        return;
6063
    }
6064
 
12 andreas 6065
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 6066
 
12 andreas 6067
    if (pg)
14 andreas 6068
    {
6069
        pg->drop();
162 andreas 6070
        page->decZOrder();
14 andreas 6071
    }
349 andreas 6072
#if TESTMODE == 1
6073
        setDone();
6074
#endif
12 andreas 6075
}
6076
 
14 andreas 6077
/**
6078
 * Set the modality of a specific popup page to Modal or NonModal.
6079
 * A Modal popup page, when active, only allows you to use the buttons and
6080
 * features on that popup page. All other buttons on the panel page are
6081
 * inactivated.
6082
 */
22 andreas 6083
void TPageManager::doPPM(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6084
{
6085
    DECL_TRACER("TPageManager::doPPM(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 6086
 
12 andreas 6087
    if (pars.size() < 2)
6088
    {
6089
        MSG_ERROR("Expecting 2 parameters!");
349 andreas 6090
#if TESTMODE == 1
6091
        setAllDone();
6092
#endif
12 andreas 6093
        return;
6094
    }
14 andreas 6095
 
16 andreas 6096
    TError::clear();
12 andreas 6097
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 6098
 
12 andreas 6099
    if (pg)
6100
    {
162 andreas 6101
        if (pars[1] == "1" || strCaseCompare(pars[1], "modal") == 0)
12 andreas 6102
            pg->setModal(1);
6103
        else
6104
            pg->setModal(0);
349 andreas 6105
#if TESTMODE == 1
6106
        if (_gTestMode)
6107
            _gTestMode->setResult(pg->isModal() ? "TRUE" : "FALSE");
6108
#endif
12 andreas 6109
    }
349 andreas 6110
#if TESTMODE == 1
6111
        setAllDone();
6112
#endif
12 andreas 6113
}
6114
 
14 andreas 6115
/**
6116
 * Activate a specific popup page to launch on either a specified page or the
6117
 * current page. If the page name is empty, the current page is used. If the
6118
 * popup page is already on, do not re-draw it. This command works in the same
6119
 * way as the ’Show Popup’ command in TPDesign4.
6120
 */
22 andreas 6121
void TPageManager::doPPN(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6122
{
6123
    DECL_TRACER("TPageManager::doPPN(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
6124
 
6125
    if (pars.size() < 1)
6126
    {
6127
        MSG_ERROR("At least 1 parameter is expected!");
349 andreas 6128
#if TESTMODE == 1
6129
        setAllDone();
6130
#endif
12 andreas 6131
        return;
6132
    }
6133
 
16 andreas 6134
    TError::clear();
14 andreas 6135
    showSubPage(pars[0]);
349 andreas 6136
#if TESTMODE == 1
6137
    setDone();
6138
#endif
12 andreas 6139
}
6140
 
14 andreas 6141
/**
15 andreas 6142
 * Set a specific popup page to timeout within a specified time. If timeout is
6143
 * empty, popup page will clear the timeout.
6144
 */
22 andreas 6145
void TPageManager::doPPT(int, vector<int>&, vector<string>& pars)
15 andreas 6146
{
6147
    DECL_TRACER("TPageManager::doPPT(int port, vector<int>& channels, vector<string>& pars)");
6148
 
6149
    if (pars.size() < 2)
6150
    {
6151
        MSG_ERROR("Expecting 2 parameters!");
351 andreas 6152
#if TESTMODE == 1
6153
        setAllDone();
6154
#endif
15 andreas 6155
        return;
6156
    }
6157
 
16 andreas 6158
    TError::clear();
96 andreas 6159
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6160
 
6161
    if (!pg)
351 andreas 6162
    {
6163
#if TESTMODE == 1
6164
        setAllDone();
6165
#endif
96 andreas 6166
        return;
351 andreas 6167
    }
15 andreas 6168
 
6169
    pg->setTimeout(atoi(pars[1].c_str()));
351 andreas 6170
#if TESTMODE == 1
6171
    if (_gTestMode)
6172
        _gTestMode->setResult(intToString(pg->getTimeout()));
6173
 
6174
    __success = true;
6175
    setAllDone();
6176
#endif
15 andreas 6177
}
6178
 
6179
/**
14 andreas 6180
 * Close all popups on all pages. This command works in the same way as the
6181
 * 'Clear All' command in TPDesign 4.
6182
 */
22 andreas 6183
void TPageManager::doPPX(int, std::vector<int>&, std::vector<std::string>&)
12 andreas 6184
{
6185
    DECL_TRACER("TPageManager::doPPX(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
6186
 
16 andreas 6187
    TError::clear();
12 andreas 6188
    PCHAIN_T *chain = mPchain;
14 andreas 6189
 
12 andreas 6190
    while(chain)
6191
    {
6192
        TSubPage *sub = chain->page->getFirstSubPage();
14 andreas 6193
 
12 andreas 6194
        while (sub)
6195
        {
351 andreas 6196
            MSG_DEBUG("Dropping subpage " << sub->getNumber() << ", \"" << sub->getName() << "\".");
12 andreas 6197
            sub->drop();
6198
            sub = chain->page->getNextSubPage();
6199
        }
14 andreas 6200
 
12 andreas 6201
        chain = chain->next;
6202
    }
14 andreas 6203
 
6204
    TPage *page = getPage(mActualPage);
6205
 
6206
    if (!page)
6207
    {
6208
        MSG_ERROR("No active page found! Internal error.");
351 andreas 6209
#if TESTMODE == 1
6210
        setAllDone();
6211
#endif
14 andreas 6212
        return;
6213
    }
6214
 
6215
    page->resetZOrder();
351 andreas 6216
#if TESTMODE == 1
6217
    setDone();
6218
#endif
12 andreas 6219
}
6220
 
14 andreas 6221
/**
15 andreas 6222
 * Set the show effect for the specified popup page to the named show effect.
6223
 */
22 andreas 6224
void TPageManager::doPSE(int, vector<int>&, vector<string>& pars)
15 andreas 6225
{
6226
    DECL_TRACER("TPageManager::doPSE(int port, vector<int>& channels, vector<string>& pars)");
6227
 
6228
    if (pars.size() < 2)
6229
    {
6230
        MSG_ERROR("Less than 2 parameters!");
351 andreas 6231
#if TESTMODE == 1
6232
        setAllDone();
6233
#endif
15 andreas 6234
        return;
6235
    }
6236
 
16 andreas 6237
    TError::clear();
96 andreas 6238
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6239
 
6240
    if (!pg)
351 andreas 6241
    {
6242
#if TESTMODE == 1
6243
        setAllDone();
6244
#endif
96 andreas 6245
        return;
351 andreas 6246
    }
15 andreas 6247
 
162 andreas 6248
    if (strCaseCompare(pars[1], "fade") == 0)
15 andreas 6249
        pg->setShowEffect(SE_FADE);
162 andreas 6250
    else if (strCaseCompare(pars[1], "slide to left") == 0)
15 andreas 6251
        pg->setShowEffect(SE_SLIDE_LEFT);
162 andreas 6252
    else if (strCaseCompare(pars[1], "slide to right") == 0)
15 andreas 6253
        pg->setShowEffect(SE_SLIDE_RIGHT);
162 andreas 6254
    else if (strCaseCompare(pars[1], "slide to top") == 0)
15 andreas 6255
        pg->setShowEffect(SE_SLIDE_TOP);
162 andreas 6256
    else if (strCaseCompare(pars[1], "slide to bottom") == 0)
15 andreas 6257
        pg->setShowEffect(SE_SLIDE_BOTTOM);
162 andreas 6258
    else if (strCaseCompare(pars[1], "slide to left fade") == 0)
15 andreas 6259
        pg->setShowEffect(SE_SLIDE_LEFT_FADE);
162 andreas 6260
    else if (strCaseCompare(pars[1], "slide to right fade") == 0)
15 andreas 6261
        pg->setShowEffect(SE_SLIDE_RIGHT_FADE);
162 andreas 6262
    else if (strCaseCompare(pars[1], "slide to top fade") == 0)
15 andreas 6263
        pg->setShowEffect(SE_SLIDE_TOP_FADE);
162 andreas 6264
    else if (strCaseCompare(pars[1], "slide to bottom fade") == 0)
15 andreas 6265
        pg->setShowEffect(SE_SLIDE_BOTTOM_FADE);
6266
    else
6267
        pg->setShowEffect(SE_NONE);
351 andreas 6268
#if TESTMODE == 1
6269
    if (_gTestMode)
6270
        _gTestMode->setResult(intToString(pg->getShowEffect()));
6271
 
6272
    __success = true;
6273
    setAllDone();
6274
#endif
15 andreas 6275
}
6276
 
162 andreas 6277
/**
6278
 * Set the show effect position. Only 1 coordinate is ever needed for an effect;
6279
 * however, the command will specify both. This command sets the location at
6280
 * which the effect will begin.
6281
 */
22 andreas 6282
void TPageManager::doPSP(int, vector<int>&, vector<string>& pars)
15 andreas 6283
{
6284
    DECL_TRACER("TPageManager::doPSP(int port, vector<int>& channels, vector<string>& pars)");
6285
 
6286
    if (pars.size() < 2)
6287
    {
6288
        MSG_ERROR("Less than 2 parameters!");
351 andreas 6289
#if TESTMODE == 1
6290
        setAllDone();
6291
#endif
15 andreas 6292
        return;
6293
    }
6294
 
16 andreas 6295
    TError::clear();
15 andreas 6296
    size_t pos = pars[1].find(",");
6297
    int x, y;
6298
 
6299
    if (pos == string::npos)
6300
    {
6301
        x = atoi(pars[1].c_str());
6302
        y = 0;
6303
    }
6304
    else
6305
    {
6306
        x = atoi(pars[1].substr(0, pos).c_str());
6307
        y = atoi(pars[1].substr(pos+1).c_str());
6308
    }
6309
 
96 andreas 6310
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6311
 
6312
    if (!pg)
351 andreas 6313
    {
6314
#if TESTMODE == 1
6315
        setAllDone();
6316
#endif
96 andreas 6317
        return;
351 andreas 6318
    }
15 andreas 6319
 
6320
    pg->setShowEndPosition(x, y);
351 andreas 6321
#if TESTMODE == 1
6322
    pg->getShowEndPosition(&x, &y);
6323
 
6324
    if (_gTestMode)
6325
        _gTestMode->setResult(intToString(x) + "," + intToString(y));
6326
 
6327
    __success = true;
6328
    setAllDone();
6329
#endif
15 andreas 6330
}
6331
 
6332
/**
6333
 * Set the show effect time for the specified popup page.
6334
 */
22 andreas 6335
void TPageManager::doPST(int, vector<int>&, vector<string>& pars)
15 andreas 6336
{
6337
    DECL_TRACER("TPageManager::doPST(int port, vector<int>& channels, vector<string>& pars)");
6338
 
6339
    if (pars.size() < 2)
6340
    {
6341
        MSG_ERROR("Less than 2 parameters!");
351 andreas 6342
#if TESTMODE == 1
6343
        setAllDone();
6344
#endif
15 andreas 6345
        return;
6346
    }
6347
 
16 andreas 6348
    TError::clear();
96 andreas 6349
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6350
 
6351
    if (!pg)
351 andreas 6352
    {
6353
#if TESTMODE == 1
6354
        setAllDone();
6355
#endif
96 andreas 6356
        return;
351 andreas 6357
    }
15 andreas 6358
 
6359
    pg->setShowTime(atoi(pars[1].c_str()));
351 andreas 6360
#if TESTMODE == 1
6361
    if (_gTestMode)
6362
        _gTestMode->setResult(intToString(pg->getShowTime()));
6363
 
6364
    __success = 1;
6365
    setAllDone();
6366
#endif
15 andreas 6367
}
6368
 
6369
/**
14 andreas 6370
 * Flips to a page with a specified page name. If the page is currently active,
6371
 * it will not redraw the page.
6372
 */
22 andreas 6373
void TPageManager::doPAGE(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6374
{
6375
    DECL_TRACER("TPageManager::doPAGE(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 6376
 
15 andreas 6377
    if (pars.empty())
6378
    {
6379
        MSG_WARNING("Got no page parameter!");
351 andreas 6380
#if TESTMODE == 1
6381
        setAllDone();
6382
#endif
15 andreas 6383
        return;
6384
    }
14 andreas 6385
 
16 andreas 6386
    TError::clear();
15 andreas 6387
    setPage(pars[0]);
351 andreas 6388
#if TESTMODE == 1
6389
    if (_gTestMode)
6390
        _gTestMode->setResult(intToString(getActualPageNumber()));
6391
 
6392
    setDone();
6393
#endif
15 andreas 6394
}
6395
 
6396
/**
38 andreas 6397
 * @brief TPageManager::doANI Run a button animation (in 1/10 second).
6398
 * Syntax:
6399
 *      ^ANI-<vt addr range>,<start state>,<end state>,<time>
6400
 * Variable:
6401
 *      variable text address range = 1 - 4000.
6402
 *      start state = Beginning of button state (0= current state).
6403
 *      end state = End of button state.
6404
 *      time = In 1/10 second intervals.
6405
 * Example:
6406
 *      SEND_COMMAND Panel,"'^ANI-500,1,25,100'"
6407
 * Runs a button animation at text range 500 from state 1 to state 25 for 10 seconds.
6408
 *
6409
 * @param port      The port number
6410
 * @param channels  The channels of the buttons
6411
 * @param pars      The parameters
6412
 */
6413
void TPageManager::doANI(int port, std::vector<int> &channels, std::vector<std::string> &pars)
6414
{
6415
    DECL_TRACER("TPageManager::doANI(int port, std::vector<int> &channels, std::vector<std::string> &pars)");
6416
 
6417
    if (pars.size() < 3)
6418
    {
6419
        MSG_ERROR("Expecting 3 parameters but got " << pars.size() << "! Ignoring command.");
6420
        return;
6421
    }
6422
 
6423
    TError::clear();
6424
    int stateStart = atoi(pars[0].c_str());
6425
    int endState = atoi(pars[1].c_str());
6426
    int runTime = atoi(pars[2].c_str());
6427
 
193 andreas 6428
    vector<TMap::MAP_T> map = findButtons(port, channels);
38 andreas 6429
 
6430
    if (TError::isError() || map.empty())
6431
        return;
6432
 
6433
    vector<Button::TButton *> buttons = collectButtons(map);
6434
 
83 andreas 6435
    if (buttons.size() > 0)
38 andreas 6436
    {
83 andreas 6437
        vector<Button::TButton *>::iterator mapIter;
6438
 
6439
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
6440
        {
6441
            Button::TButton *bt = *mapIter;
6442
            bt->startAnimation(stateStart, endState, runTime);
6443
        }
38 andreas 6444
    }
351 andreas 6445
#if TESTMODE == 1
6446
    if (_gTestMode)
6447
        _gTestMode->setResult(intToString(stateStart) + "," + intToString(endState) + "," + intToString(runTime));
6448
 
6449
    setDone();
6450
#endif
38 andreas 6451
}
6452
 
6453
/**
15 andreas 6454
 * Add page flip action to a button if it does not already exist.
6455
 */
6456
void TPageManager::doAPF(int port, vector<int>& channels, vector<string>& pars)
6457
{
6458
    DECL_TRACER("TPageManager::doAPF(int port, vector<int>& channels, vector<string>& pars)");
6459
 
6460
    if (pars.size() < 2)
6461
    {
6462
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
351 andreas 6463
#if TESTMODE == 1
6464
        setAllDone();
6465
#endif
14 andreas 6466
        return;
15 andreas 6467
    }
14 andreas 6468
 
16 andreas 6469
    TError::clear();
15 andreas 6470
    string action = pars[0];
6471
    string pname = pars[1];
14 andreas 6472
 
193 andreas 6473
    vector<TMap::MAP_T> map = findButtons(port, channels);
14 andreas 6474
 
15 andreas 6475
    if (TError::isError() || map.empty())
351 andreas 6476
    {
6477
#if TESTMODE == 1
6478
        setAllDone();
6479
#endif
15 andreas 6480
        return;
351 andreas 6481
    }
15 andreas 6482
 
6483
    vector<Button::TButton *> buttons = collectButtons(map);
6484
 
83 andreas 6485
    if (buttons.size() > 0)
12 andreas 6486
    {
83 andreas 6487
        vector<Button::TButton *>::iterator mapIter;
6488
 
6489
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
6490
        {
6491
            Button::TButton *bt = *mapIter;
6492
            bt->addPushFunction(action, pname);
6493
        }
15 andreas 6494
    }
351 andreas 6495
#if TESTMODE == 1
6496
    if (_gTestMode)
6497
        _gTestMode->setResult(toUpper(action) + "," + toUpper(pname));
6498
 
6499
    __success = true;
6500
    setAllDone();
6501
#endif
15 andreas 6502
}
12 andreas 6503
 
15 andreas 6504
/**
43 andreas 6505
 * Append non-unicode text.
6506
 */
6507
void TPageManager::doBAT(int port, vector<int> &channels, vector<string> &pars)
6508
{
6509
    DECL_TRACER("TPageManager::doBAT(int port, vector<int> &channels, vector<string> &pars)");
6510
 
6511
    if (pars.size() < 1)
6512
    {
6513
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
330 andreas 6514
#if TESTMODE == 1
334 andreas 6515
        setAllDone();
330 andreas 6516
#endif
43 andreas 6517
        return;
6518
    }
6519
 
6520
    TError::clear();
6521
    int btState = atoi(pars[0].c_str());
6522
    string text;
6523
 
6524
    if (pars.size() > 1)
6525
        text = pars[1];
6526
 
193 andreas 6527
    vector<TMap::MAP_T> map = findButtons(port, channels);
43 andreas 6528
 
6529
    if (TError::isError() || map.empty())
330 andreas 6530
    {
6531
#if TESTMODE == 1
334 andreas 6532
        setAllDone();
330 andreas 6533
#endif
43 andreas 6534
        return;
330 andreas 6535
    }
43 andreas 6536
 
6537
    vector<Button::TButton *> buttons = collectButtons(map);
6538
 
162 andreas 6539
    if (buttons.empty())
330 andreas 6540
    {
6541
#if TESTMODE == 1
334 andreas 6542
        setAllDone();
330 andreas 6543
#endif
162 andreas 6544
        return;
330 andreas 6545
    }
162 andreas 6546
 
6547
    vector<Button::TButton *>::iterator mapIter;
6548
 
6549
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
43 andreas 6550
    {
162 andreas 6551
        Button::TButton *bt = *mapIter;
43 andreas 6552
 
331 andreas 6553
        bt->appendText(text, btState - 1);
330 andreas 6554
#if TESTMODE == 1
331 andreas 6555
        if (_gTestMode)
330 andreas 6556
        {
331 andreas 6557
            int st = (btState > 0 ? (btState - 1) : 0);
6558
            _gTestMode->setResult(bt->getText(st));
333 andreas 6559
        }
330 andreas 6560
 
331 andreas 6561
        __success = true;
330 andreas 6562
#endif
43 andreas 6563
    }
334 andreas 6564
#if TESTMODE == 1
6565
    setDone();
6566
#endif
43 andreas 6567
}
6568
 
6569
/**
60 andreas 6570
 * @brief Append unicode text. Same format as ^UNI.
6571
 * This command allows to set up to 50 characters of ASCII code. The unicode
6572
 * characters must be set as hex numbers.
6573
 */
6574
void TPageManager::doBAU(int port, vector<int>& channels, vector<string>& pars)
6575
{
6576
    DECL_TRACER("TPageManager::doBAU(int port, vector<int>& channels, vector<string>& pars)");
6577
 
6578
    if (pars.size() < 1)
6579
    {
6580
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 6581
#if TESTMODE == 1
6582
        setAllDone();
6583
#endif
60 andreas 6584
        return;
6585
    }
6586
 
6587
    TError::clear();
6588
    int btState = atoi(pars[0].c_str());
6589
    string text;
6590
    char ch[3];
6591
 
331 andreas 6592
    if (pars.size() > 1)
6593
        text = pars[1];
6594
 
6595
    if ((text.size() % 4) == 0)
60 andreas 6596
    {
162 andreas 6597
        try
60 andreas 6598
        {
162 andreas 6599
            text = pars[1];
331 andreas 6600
            MSG_DEBUG("Processing UTF16 string: " << text);
162 andreas 6601
            // Because the unicode characters are hex numbers, we scan the text
6602
            // and convert the hex numbers into real numbers.
6603
            size_t len = text.length();
6604
            bool inHex = false;
6605
            int lastChar = 0;
331 andreas 6606
            uint16_t *numstr = new uint16_t[len / 4];
162 andreas 6607
            int uniPos = 0;
331 andreas 6608
            int cntCount = 0;
60 andreas 6609
 
162 andreas 6610
            for (size_t i = 0; i < len; i++)
60 andreas 6611
            {
162 andreas 6612
                int c = text.at(i);
60 andreas 6613
 
162 andreas 6614
                if (!inHex && isHex(c))
6615
                {
6616
                    inHex = true;
6617
                    lastChar = c;
6618
                    continue;
6619
                }
6620
 
6621
                if (inHex && !isHex(c))
6622
                    break;
6623
 
6624
                if (inHex && isHex(c))
6625
                {
6626
                    ch[0] = lastChar;
6627
                    ch[1] = c;
6628
                    ch[2] = 0;
6629
                    uint16_t num = (uint16_t)strtol(ch, NULL, 16);
331 andreas 6630
 
6631
                    if ((cntCount % 2) != 0)
6632
                    {
6633
                        numstr[uniPos] |= num;
6634
                        uniPos++;
6635
                    }
6636
                    else
6637
                        numstr[uniPos] = (num << 8) & 0xff00;
6638
 
6639
                    cntCount++;
162 andreas 6640
                    inHex = false;
6641
 
6642
                    if (uniPos >= 50)
6643
                        break;
331 andreas 6644
                }
6645
            }
162 andreas 6646
 
331 andreas 6647
            text.clear();
6648
            // Here we make from the real numbers a UTF8 string
6649
            for (size_t i = 0; i < len / 4; ++i)
6650
            {
6651
                if (numstr[i] <= 0x00ff)
6652
                {
6653
                    ch[0] = numstr[i];
6654
                    ch[1] = 0;
6655
                    text.append(ch);
162 andreas 6656
                }
331 andreas 6657
                else
6658
                {
6659
                    ch[0] = (numstr[i] >> 8) & 0x00ff;
6660
                    ch[1] = numstr[i] & 0x00ff;
6661
                    ch[2] = 0;
6662
                    text.append(ch);
6663
                }
60 andreas 6664
            }
6665
 
331 andreas 6666
            delete[] numstr;
60 andreas 6667
        }
162 andreas 6668
        catch (std::exception const & e)
6669
        {
6670
            MSG_ERROR("Character conversion error: " << e.what());
351 andreas 6671
#if TESTMODE == 1
6672
            setAllDone();
6673
#endif
162 andreas 6674
            return;
6675
        }
60 andreas 6676
    }
331 andreas 6677
    else
6678
    {
6679
        MSG_WARNING("No or invalid UTF16 string: " << text);
351 andreas 6680
#if TESTMODE == 1
6681
        setAllDone();
6682
#endif
331 andreas 6683
        return;
6684
    }
60 andreas 6685
 
193 andreas 6686
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 6687
 
6688
    if (TError::isError() || map.empty())
351 andreas 6689
    {
6690
#if TESTMODE == 1
6691
        setAllDone();
6692
#endif
60 andreas 6693
        return;
351 andreas 6694
    }
60 andreas 6695
 
6696
    vector<Button::TButton *> buttons = collectButtons(map);
6697
 
83 andreas 6698
    if (buttons.size() > 0)
60 andreas 6699
    {
83 andreas 6700
        vector<Button::TButton *>::iterator mapIter;
60 andreas 6701
 
83 andreas 6702
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 6703
        {
83 andreas 6704
            Button::TButton *bt = *mapIter;
60 andreas 6705
 
331 andreas 6706
            bt->appendText(text, btState - 1);
330 andreas 6707
#if TESTMODE == 1
331 andreas 6708
            if (_gTestMode)
6709
                _gTestMode->setResult(bt->getText(btState - 1));
330 andreas 6710
 
331 andreas 6711
            __success = true;
330 andreas 6712
#endif
60 andreas 6713
        }
6714
    }
330 andreas 6715
#if TESTMODE == 1
334 andreas 6716
    setDone();
330 andreas 6717
#endif
60 andreas 6718
}
6719
 
6720
/**
43 andreas 6721
 * @brief TPageManager::doBCB Set the border color.
6722
 * Set the border color to the specified color. Only if the specified border
6723
 * color is not the same as the current color.
6724
 * Note: Color can be assigned by color name (without spaces), number or
6725
 * R,G,B value (RRGGBB or RRGGBBAA).
6726
 */
6727
void TPageManager::doBCB(int port, vector<int> &channels, vector<string> &pars)
6728
{
6729
    DECL_TRACER("TPageManager::doBCB(int port, vector<int> &channels, vector<string> &pars)");
6730
 
6731
    if (pars.size() < 1)
6732
    {
6733
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 6734
#if TESTMODE == 1
6735
        setAllDone();
6736
#endif
43 andreas 6737
        return;
6738
    }
6739
 
6740
    TError::clear();
6741
    int btState = atoi(pars[0].c_str());
6742
    string color;
6743
 
6744
    if (pars.size() > 1)
6745
        color = pars[1];
6746
 
193 andreas 6747
    vector<TMap::MAP_T> map = findButtons(port, channels);
43 andreas 6748
 
6749
    if (TError::isError() || map.empty())
351 andreas 6750
    {
6751
#if TESTMODE == 1
6752
        setAllDone();
6753
#endif
43 andreas 6754
        return;
351 andreas 6755
    }
43 andreas 6756
 
6757
    vector<Button::TButton *> buttons = collectButtons(map);
6758
 
83 andreas 6759
    if (buttons.size() > 0)
43 andreas 6760
    {
83 andreas 6761
        vector<Button::TButton *>::iterator mapIter;
43 andreas 6762
 
83 andreas 6763
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
43 andreas 6764
        {
83 andreas 6765
            Button::TButton *bt = *mapIter;
351 andreas 6766
            bt->setBorderColor(color, btState - 1);
6767
#if TESTMODE == 1
6768
            if (_gTestMode)
6769
                _gTestMode->setResult(bt->getBorderColor(btState == 0 ? 0 : btState - 1));
6770
#endif
43 andreas 6771
        }
6772
    }
351 andreas 6773
#if TESTMODE == 1
6774
    setDone();
6775
#endif
43 andreas 6776
}
60 andreas 6777
 
351 andreas 6778
/*
6779
 * Get the border color and send it as a custom event.
6780
 */
82 andreas 6781
void TPageManager::getBCB(int port, vector<int> &channels, vector<string> &pars)
6782
{
6783
    DECL_TRACER("TPageManager::getBCB(int port, vector<int> &channels, vector<string> &pars)");
6784
 
6785
    if (pars.size() < 1)
6786
    {
6787
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 6788
#if TESTMODE == 1
6789
        setAllDone();
6790
#endif
82 andreas 6791
        return;
6792
    }
6793
 
6794
    TError::clear();
6795
    int btState = atoi(pars[0].c_str());
6796
    string color;
6797
 
193 andreas 6798
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 6799
 
6800
    if (TError::isError() || map.empty())
351 andreas 6801
    {
6802
#if TESTMODE == 1
6803
        setAllDone();
6804
#endif
82 andreas 6805
        return;
351 andreas 6806
    }
82 andreas 6807
 
6808
    vector<Button::TButton *> buttons = collectButtons(map);
6809
 
351 andreas 6810
    if (buttons.empty())
82 andreas 6811
    {
351 andreas 6812
#if TESTMODE == 1
6813
        setAllDone();
6814
#endif
6815
        return;
6816
    }
82 andreas 6817
 
351 andreas 6818
    vector<Button::TButton *>::iterator iter;
6819
 
6820
    for (iter = buttons.begin(); iter != buttons.end(); ++iter)
6821
    {
6822
        Button::TButton *bt = *iter;
6823
 
110 andreas 6824
        if (btState == 0)       // All instances?
82 andreas 6825
        {
110 andreas 6826
            int bst = bt->getNumberInstances();
82 andreas 6827
 
110 andreas 6828
            for (int i = 0; i < bst; i++)
82 andreas 6829
            {
110 andreas 6830
                color = bt->getBorderColor(i);
82 andreas 6831
 
110 andreas 6832
                if (color.empty())
6833
                    continue;
83 andreas 6834
 
300 andreas 6835
                sendCustomEvent(i + 1, (int)color.length(), 0, color, 1011, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 6836
#if TESTMODE == 1
6837
                __success = true;
6838
 
6839
                if (_gTestMode)
6840
                    _gTestMode->setResult(color);
6841
#endif
83 andreas 6842
            }
110 andreas 6843
        }
6844
        else
6845
        {
6846
            color = bt->getBorderColor(btState - 1);
83 andreas 6847
 
110 andreas 6848
            if (color.empty())
351 andreas 6849
                continue;
82 andreas 6850
 
300 andreas 6851
            sendCustomEvent(btState, (int)color.length(), 0, color, 1011, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 6852
#if TESTMODE == 1
6853
            __success = true;
6854
 
6855
            if (_gTestMode)
6856
                _gTestMode->setResult(color);
6857
#endif
82 andreas 6858
        }
6859
    }
351 andreas 6860
#if TESTMODE == 1
6861
    setAllDone();
6862
#endif
82 andreas 6863
}
6864
 
43 andreas 6865
/**
60 andreas 6866
 * @brief Set the fill color to the specified color.
6867
 * Only if the specified fill color is not the same as the current color.
6868
 * Note: Color can be assigned by color name (without spaces), number or R,G,B value (RRGGBB or RRGGBBAA).
15 andreas 6869
 */
60 andreas 6870
void TPageManager::doBCF(int port, vector<int>& channels, vector<std::string>& pars)
15 andreas 6871
{
60 andreas 6872
    DECL_TRACER("TPageManager::doBCF(int port, vector<int>& channels, vector<std::string>& pars)");
15 andreas 6873
 
60 andreas 6874
    if (pars.size() < 1)
15 andreas 6875
    {
60 andreas 6876
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 6877
#if TESTMODE == 1
6878
        setAllDone();
6879
#endif
12 andreas 6880
        return;
6881
    }
14 andreas 6882
 
16 andreas 6883
    TError::clear();
15 andreas 6884
    int btState = atoi(pars[0].c_str());
60 andreas 6885
    string color;
14 andreas 6886
 
60 andreas 6887
    if (pars.size() > 1)
6888
        color = pars[1];
6889
 
193 andreas 6890
    vector<TMap::MAP_T> map = findButtons(port, channels);
15 andreas 6891
 
6892
    if (TError::isError() || map.empty())
351 andreas 6893
    {
6894
#if TESTMODE == 1
6895
        setAllDone();
6896
#endif
15 andreas 6897
        return;
351 andreas 6898
    }
15 andreas 6899
 
6900
    vector<Button::TButton *> buttons = collectButtons(map);
6901
 
83 andreas 6902
    if (buttons.size() > 0)
15 andreas 6903
    {
83 andreas 6904
        vector<Button::TButton *>::iterator mapIter;
15 andreas 6905
 
83 andreas 6906
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
15 andreas 6907
        {
83 andreas 6908
            Button::TButton *bt = *mapIter;
351 andreas 6909
            bt->setFillColor(color, btState - 1);
6910
#if TESTMODE == 1
6911
            if (_gTestMode)
6912
                _gTestMode->setResult(bt->getFillColor(btState == 0 ? 0 : btState - 1));
6913
#endif
15 andreas 6914
        }
6915
    }
351 andreas 6916
#if TESTMODE == 1
6917
    setDone();
6918
#endif
12 andreas 6919
}
6920
 
351 andreas 6921
/*
6922
 * Get the fill color and send it via a custom event to the NetLinx.
6923
 */
82 andreas 6924
void TPageManager::getBCF(int port, vector<int> &channels, vector<string> &pars)
6925
{
6926
    DECL_TRACER("TPageManager::getBCF(int port, vector<int> &channels, vector<string> &pars)");
6927
 
6928
    if (pars.size() < 1)
6929
    {
6930
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 6931
#if TESTMODE == 1
6932
        setAllDone();
6933
#endif
82 andreas 6934
        return;
6935
    }
6936
 
6937
    TError::clear();
6938
    int btState = atoi(pars[0].c_str());
6939
    string color;
6940
 
193 andreas 6941
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 6942
 
6943
    if (TError::isError() || map.empty())
351 andreas 6944
    {
6945
#if TESTMODE == 1
6946
        setAllDone();
6947
#endif
82 andreas 6948
        return;
351 andreas 6949
    }
82 andreas 6950
 
6951
    vector<Button::TButton *> buttons = collectButtons(map);
6952
 
351 andreas 6953
    if (buttons.empty())
82 andreas 6954
    {
351 andreas 6955
#if TESTMODE == 1
6956
        setAllDone();
6957
#endif
6958
        return;
6959
    }
82 andreas 6960
 
351 andreas 6961
    vector<Button::TButton *>::iterator iter;
6962
 
6963
    for (iter = buttons.begin(); iter != buttons.end(); ++iter)
6964
    {
6965
        Button::TButton *bt = *iter;
6966
 
110 andreas 6967
        if (btState == 0)       // All instances?
82 andreas 6968
        {
110 andreas 6969
            int bst = bt->getNumberInstances();
82 andreas 6970
 
110 andreas 6971
            for (int i = 0; i < bst; i++)
82 andreas 6972
            {
110 andreas 6973
                color = bt->getFillColor(i);
82 andreas 6974
 
110 andreas 6975
                if (color.empty())
6976
                    continue;
82 andreas 6977
 
300 andreas 6978
                sendCustomEvent(i + 1, (int)color.length(), 0, color, 1012, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 6979
#if TESTMODE == 1
6980
                __success = true;
6981
 
6982
                if (_gTestMode)
6983
                    _gTestMode->setResult(color);
6984
#endif
83 andreas 6985
            }
82 andreas 6986
        }
110 andreas 6987
        else
6988
        {
6989
            color = bt->getFillColor(btState-1);
351 andreas 6990
 
6991
            if (color.empty())
6992
                continue;
6993
 
300 andreas 6994
            sendCustomEvent(btState, (int)color.length(), 0, color, 1012, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 6995
#if TESTMODE == 1
6996
            __success = true;
6997
 
6998
            if (_gTestMode)
6999
                _gTestMode->setResult(color);
7000
#endif
110 andreas 7001
        }
82 andreas 7002
    }
351 andreas 7003
#if TESTMODE == 1
7004
    setAllDone();
7005
#endif
82 andreas 7006
}
7007
 
60 andreas 7008
/**
7009
 * @brief Set the text color to the specified color.
7010
 * Only if the specified text color is not the same as the current color.
7011
 * Note: Color can be assigned by color name (without spaces), number or R,G,B value (RRGGBB or RRGGBBAA).
7012
 */
7013
void TPageManager::doBCT(int port, vector<int>& channels, vector<string>& pars)
18 andreas 7014
{
60 andreas 7015
    DECL_TRACER("TPageManager::doBCT(int port, vector<int>& channels, vector<string>& pars)");
7016
 
7017
    if (pars.size() < 1)
7018
    {
7019
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7020
#if TESTMODE == 1
7021
        setAllDone();
7022
#endif
60 andreas 7023
        return;
7024
    }
7025
 
7026
    TError::clear();
7027
    int btState = atoi(pars[0].c_str());
7028
    string color;
7029
 
7030
    if (pars.size() > 1)
7031
        color = pars[1];
7032
 
193 andreas 7033
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 7034
 
7035
    if (TError::isError() || map.empty())
351 andreas 7036
    {
7037
#if TESTMODE == 1
7038
        setAllDone();
7039
#endif
60 andreas 7040
        return;
351 andreas 7041
    }
60 andreas 7042
 
7043
    vector<Button::TButton *> buttons = collectButtons(map);
7044
 
83 andreas 7045
    if (buttons.size() > 0)
60 andreas 7046
    {
83 andreas 7047
        vector<Button::TButton *>::iterator mapIter;
60 andreas 7048
 
83 andreas 7049
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 7050
        {
83 andreas 7051
            Button::TButton *bt = *mapIter;
351 andreas 7052
            bt->setTextColor(color, btState - 1);
7053
#if TESTMODE == 1
7054
            if (_gTestMode)
7055
                _gTestMode->setResult(bt->getTextColor(btState == 0 ? 0 : btState - 1));
7056
#endif
60 andreas 7057
        }
7058
    }
351 andreas 7059
#if TESTMODE == 1
7060
    setDone();
7061
#endif
18 andreas 7062
}
7063
 
351 andreas 7064
/*
7065
 * Get the text color of a button and send it via a custom event to the NetLinx.
7066
 */
82 andreas 7067
void TPageManager::getBCT(int port, vector<int> &channels, vector<string> &pars)
7068
{
7069
    DECL_TRACER("TPageManager::getBCT(int port, vector<int> &channels, vector<string> &pars)");
7070
 
7071
    if (pars.size() < 1)
7072
    {
7073
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7074
#if TESTMODE == 1
7075
        setAllDone();
7076
#endif
82 andreas 7077
        return;
7078
    }
7079
 
7080
    TError::clear();
7081
    int btState = atoi(pars[0].c_str());
7082
    string color;
7083
 
193 andreas 7084
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 7085
 
7086
    if (TError::isError() || map.empty())
351 andreas 7087
    {
7088
#if TESTMODE == 1
7089
        setAllDone();
7090
#endif
82 andreas 7091
        return;
351 andreas 7092
    }
82 andreas 7093
 
7094
    vector<Button::TButton *> buttons = collectButtons(map);
7095
 
351 andreas 7096
    if (buttons.empty())
82 andreas 7097
    {
351 andreas 7098
#if TESTMODE == 1
7099
        setAllDone();
7100
#endif
7101
        return;
7102
    }
82 andreas 7103
 
351 andreas 7104
    vector<Button::TButton *>::iterator iter;
7105
 
7106
    for (iter = buttons.begin(); iter != buttons.end(); ++iter)
7107
    {
7108
        Button::TButton *bt = *iter;
7109
 
110 andreas 7110
        if (btState == 0)       // All instances?
82 andreas 7111
        {
110 andreas 7112
            int bst = bt->getNumberInstances();
82 andreas 7113
 
110 andreas 7114
            for (int i = 0; i < bst; i++)
82 andreas 7115
            {
110 andreas 7116
                color = bt->getTextColor(i);
82 andreas 7117
 
110 andreas 7118
                if (color.empty())
7119
                    continue;
82 andreas 7120
 
300 andreas 7121
                sendCustomEvent(i + 1, (int)color.length(), 0, color, 1013, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 7122
#if TESTMODE == 1
7123
                __success = true;
7124
 
7125
                if (_gTestMode)
7126
                    _gTestMode->setResult(color);
7127
#endif
83 andreas 7128
            }
82 andreas 7129
        }
110 andreas 7130
        else
7131
        {
7132
            color = bt->getTextColor(btState - 1);
351 andreas 7133
 
7134
            if (color.empty())
7135
                continue;
7136
 
300 andreas 7137
            sendCustomEvent(btState, (int)color.length(), 0, color, 1013, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 7138
#if TESTMODE == 1
7139
            __success = true;
7140
 
7141
            if (_gTestMode)
7142
                _gTestMode->setResult(color);
7143
#endif
110 andreas 7144
        }
82 andreas 7145
    }
351 andreas 7146
#if TESTMODE == 1
7147
    setAllDone();
7148
#endif
82 andreas 7149
}
7150
 
60 andreas 7151
/**
7152
 * Set the button draw order
7153
 * Determines what order each layer of the button is drawn.
7154
 */
7155
void TPageManager::doBDO(int port, vector<int>& channels, vector<std::string>& pars)
32 andreas 7156
{
60 andreas 7157
    DECL_TRACER("TPageManager::doBDO(int port, vector<int>& channels, vector<std::string>& pars)");
32 andreas 7158
 
60 andreas 7159
    if (pars.size() < 1)
7160
    {
7161
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7162
#if TESTMODE == 1
7163
        setAllDone();
7164
#endif
32 andreas 7165
        return;
60 andreas 7166
    }
32 andreas 7167
 
60 andreas 7168
    TError::clear();
7169
    int btState = atoi(pars[0].c_str());
7170
    string order;
32 andreas 7171
 
60 andreas 7172
    if (pars.size() > 1)
7173
    {
7174
        string ord = pars[1];
7175
        // Convert the numbers into the expected draw order
7176
        for (size_t i = 0; i < ord.length(); i++)
7177
        {
7178
            if (ord.at(i) >= '1' && ord.at(i) <= '5')
7179
            {
7180
                char hv0[32];
7181
                snprintf(hv0, sizeof(hv0), "%02d", (int)(ord.at(i) - '0'));
7182
                order.append(hv0);
7183
            }
7184
            else
7185
            {
7186
                MSG_ERROR("Illegal order number " << ord.substr(i, 1) << "!");
7187
                return;
7188
            }
7189
        }
7190
 
7191
        if (order.length() != 10)
7192
        {
7193
            MSG_ERROR("Expected 5 order numbers but got " << (order.length() / 2)<< "!");
7194
            return;
7195
        }
7196
    }
7197
 
193 andreas 7198
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 7199
 
7200
    if (TError::isError() || map.empty())
351 andreas 7201
    {
7202
#if TESTMODE == 1
7203
        setAllDone();
7204
#endif
32 andreas 7205
        return;
351 andreas 7206
    }
32 andreas 7207
 
60 andreas 7208
    vector<Button::TButton *> buttons = collectButtons(map);
7209
 
83 andreas 7210
    if (buttons.size() > 0)
32 andreas 7211
    {
83 andreas 7212
        vector<Button::TButton *>::iterator mapIter;
32 andreas 7213
 
83 andreas 7214
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 7215
        {
83 andreas 7216
            Button::TButton *bt = *mapIter;
351 andreas 7217
            bt->setDrawOrder(order, btState - 1);
7218
#if TESTMODE == 1
7219
            if (_gTestMode)
7220
                _gTestMode->setResult(bt->getDrawOrder(btState == 0 ? 0 : btState - 1));
7221
#endif
60 andreas 7222
        }
7223
    }
351 andreas 7224
#if TESTMODE == 1
7225
    setDone();
7226
#endif
60 andreas 7227
}
32 andreas 7228
 
60 andreas 7229
/**
7230
 * Set the feedback type of the button.
7231
 * ONLY works on General-type buttons.
7232
 */
7233
void TPageManager::doBFB(int port, vector<int>& channels, vector<std::string>& pars)
7234
{
7235
    DECL_TRACER("TPageManager::doBFB(int port, vector<int>& channels, vector<std::string>& pars)");
32 andreas 7236
 
60 andreas 7237
    if (pars.size() < 1)
7238
    {
7239
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7240
#if TESTMODE == 1
7241
        setAllDone();
7242
#endif
60 andreas 7243
        return;
7244
    }
7245
 
7246
    TError::clear();
7247
    Button::FEEDBACK type = Button::FB_NONE;
7248
    string stype = pars[0];
7249
    vector<string> stypes = { "None", "Channel", "Invert", "On", "Momentary", "Blink" };
7250
    vector<string>::iterator iter;
7251
    int i = 0;
7252
 
7253
    for (iter = stypes.begin(); iter != stypes.end(); ++iter)
7254
    {
7255
        if (strCaseCompare(stype, *iter) == 0)
33 andreas 7256
        {
60 andreas 7257
            type = (Button::FEEDBACK)i;
7258
            break;
32 andreas 7259
        }
60 andreas 7260
 
7261
        i++;
32 andreas 7262
    }
7263
 
193 andreas 7264
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 7265
 
7266
    if (TError::isError() || map.empty())
351 andreas 7267
    {
7268
#if TESTMODE == 1
7269
        setAllDone();
7270
#endif
60 andreas 7271
        return;
351 andreas 7272
    }
60 andreas 7273
 
7274
    vector<Button::TButton *> buttons = collectButtons(map);
7275
 
83 andreas 7276
    if (buttons.size() > 0)
60 andreas 7277
    {
83 andreas 7278
        vector<Button::TButton *>::iterator mapIter;
7279
 
7280
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
7281
        {
7282
            Button::TButton *bt = *mapIter;
7283
            bt->setFeedback(type);
351 andreas 7284
#if TESTMODE == 1
7285
            if (_gTestMode)
7286
                _gTestMode->setResult(intToString(bt->getFeedback()));
7287
#endif
83 andreas 7288
        }
60 andreas 7289
    }
335 andreas 7290
#if TESTMODE == 1
7291
    setDone();
7292
#endif
32 andreas 7293
}
7294
 
224 andreas 7295
/*
7296
 * Set the input mask for the specified address.
7297
 */
7298
void TPageManager::doBIM(int port, vector<int>& channels, vector<std::string>& pars)
7299
{
7300
    DECL_TRACER("TPageManager::doBIM(int port, vector<int>& channels, vector<std::string>& pars)");
7301
 
7302
    if (pars.size() < 1)
7303
    {
7304
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7305
#if TESTMODE == 1
7306
        setAllDone();
7307
#endif
224 andreas 7308
        return;
7309
    }
7310
 
7311
    TError::clear();
7312
    string mask = pars[0];
7313
    vector<TMap::MAP_T> map = findButtons(port, channels);
7314
 
7315
    if (TError::isError() || map.empty())
351 andreas 7316
    {
7317
#if TESTMODE == 1
7318
        setAllDone();
7319
#endif
224 andreas 7320
        return;
351 andreas 7321
    }
224 andreas 7322
 
7323
    vector<Button::TButton *> buttons = collectButtons(map);
7324
 
7325
    if (buttons.size() > 0)
7326
    {
7327
        vector<Button::TButton *>::iterator mapIter;
7328
 
7329
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
7330
        {
7331
            Button::TButton *bt = *mapIter;
7332
            bt->setInputMask(mask);
351 andreas 7333
#if TESTMODE == 1
7334
            if (_gTestMode)
7335
                _gTestMode->setResult(bt->getInputMask());
7336
#endif
224 andreas 7337
        }
7338
    }
351 andreas 7339
#if TESTMODE == 1
7340
    setDone();
7341
#endif
224 andreas 7342
}
7343
 
351 andreas 7344
/**
7345
 * @brief Button copy command.
7346
 * Copy attributes of the source button to all the
7347
 * destination buttons. Note that the source is a single button state. Each
7348
 * state must be copied as a separate command. The <codes> section represents
7349
 * what attributes will be copied. All codes are 2 char pairs that can be
7350
 * separated by comma, space, percent or just ran together.
7351
 */
106 andreas 7352
void TPageManager::doBMC(int port, vector<int>& channels, vector<std::string>& pars)
7353
{
7354
    DECL_TRACER("TPageManager::doBMC(int port, vector<int>& channels, vector<std::string>& pars)");
7355
 
7356
    if (pars.size() < 5)
7357
    {
7358
        MSG_ERROR("Expecting 5 parameters but got " << pars.size() << ". Ignoring command.");
351 andreas 7359
#if TESTMODE == 1
7360
        setAllDone();
7361
#endif
106 andreas 7362
        return;
7363
    }
7364
 
7365
    TError::clear();
7366
    int btState = atoi(pars[0].c_str());
7367
    int src_port = atoi(pars[1].c_str());
7368
    int src_addr = atoi(pars[2].c_str());
7369
    int src_state = atoi(pars[3].c_str());
7370
    string src_codes = pars[4];
7371
    vector<int> src_channel;
7372
    src_channel.push_back(src_addr);
7373
 
193 andreas 7374
    vector<TMap::MAP_T> src_map = findButtons(src_port, src_channel);
106 andreas 7375
 
7376
    if (src_map.size() == 0)
7377
    {
7378
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " does not exist!");
351 andreas 7379
#if TESTMODE == 1
7380
        setAllDone();
7381
#endif
106 andreas 7382
        return;
7383
    }
7384
 
7385
    vector<Button::TButton *>src_buttons = collectButtons(src_map);
7386
 
7387
    if (src_buttons.size() == 0)
7388
    {
7389
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " does not exist!");
351 andreas 7390
#if TESTMODE == 1
7391
        setAllDone();
7392
#endif
106 andreas 7393
        return;
7394
    }
7395
 
7396
    if (src_buttons[0]->getNumberInstances() < src_state)
7397
    {
7398
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " has less then " << src_state << " elements.");
351 andreas 7399
#if TESTMODE == 1
7400
        setAllDone();
7401
#endif
106 andreas 7402
        return;
7403
    }
7404
 
7405
    if (src_state < 1)
7406
    {
7407
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " has invalid source state " << src_state << ".");
351 andreas 7408
#if TESTMODE == 1
7409
        setAllDone();
7410
#endif
106 andreas 7411
        return;
7412
    }
7413
 
7414
    src_state--;
7415
 
7416
    if (btState > 0)
7417
        btState--;
7418
 
193 andreas 7419
    vector<TMap::MAP_T> map = findButtons(port, channels);
106 andreas 7420
    vector<Button::TButton *> buttons = collectButtons(map);
7421
    //                        0     1     2     3     4     5     6     7
7422
    vector<string>codes = { "BM", "BR", "CB", "CF", "CT", "EC", "EF", "FT",
7423
                            "IC", "JB", "JI", "JT", "LN", "OP", "SO", "TX", // 8 - 15
7424
                            "VI", "WW" };   // 16, 17
7425
 
7426
    for (size_t ibuttons = 0; ibuttons < buttons.size(); ibuttons++)
7427
    {
7428
        vector<string>::iterator iter;
7429
        int idx = 0;
7430
 
7431
        for (iter = codes.begin(); iter != codes.end(); ++iter)
7432
        {
7433
            if (src_codes.find(*iter) != string::npos)
7434
            {
7435
                int j, x, y;
7436
 
7437
                switch(idx)
7438
                {
7439
                    case 0: buttons[ibuttons]->setBitmap(src_buttons[0]->getBitmapName(src_state), btState); break;
7440
                    case 1: buttons[ibuttons]->setBorderStyle(src_buttons[0]->getBorderStyle(src_state), btState); break;
7441
                    case 2: buttons[ibuttons]->setBorderColor(src_buttons[0]->getBorderColor(src_state), btState); break;
7442
                    case 3: buttons[ibuttons]->setFillColor(src_buttons[0]->getFillColor(src_state), btState); break;
7443
                    case 4: buttons[ibuttons]->setTextColor(src_buttons[0]->getTextColor(src_state), btState); break;
7444
                    case 5: buttons[ibuttons]->setTextEffectColor(src_buttons[0]->getTextEffectColor(src_state), btState); break;
7445
                    case 6: buttons[ibuttons]->setTextEffect(src_buttons[0]->getTextEffect(src_state), btState); break;
7446
                    case 7: buttons[ibuttons]->setFontIndex(src_buttons[0]->getFontIndex(src_state), btState); break;
110 andreas 7447
                    case 8: buttons[ibuttons]->setIcon(src_buttons[0]->getIconIndex(src_state), btState); break;
106 andreas 7448
 
7449
                    case 9:
7450
                        j = src_buttons[0]->getBitmapJustification(&x, &y, src_state);
7451
                        buttons[ibuttons]->setBitmapJustification(j, x, y, btState);
7452
                    break;
7453
 
7454
                    case 10:
7455
                        j = src_buttons[0]->getIconJustification(&x, &y, src_state);
7456
                        buttons[ibuttons]->setIconJustification(j, x, y, btState);
7457
                    break;
7458
 
7459
                    case 11:
7460
                        j = src_buttons[0]->getTextJustification(&x, &y, src_state);
7461
                        buttons[ibuttons]->setTextJustification(j, x, y, btState);
7462
                    break;
7463
 
7464
                    case 12: MSG_INFO("\"Lines of video removed\" not supported!"); break;
7465
                    case 13: buttons[ibuttons]->setOpacity(src_buttons[0]->getOpacity(src_state), btState); break;
7466
                    case 14: buttons[ibuttons]->setSound(src_buttons[0]->getSound(src_state), btState); break;
7467
                    case 15: buttons[ibuttons]->setText(src_buttons [0]->getText(src_state), btState); break;
7468
                    case 16: MSG_INFO("\"Video slot ID\" not supported!"); break;
7469
                    case 17: buttons[ibuttons]->setTextWordWrap(src_buttons[0]->getTextWordWrap(src_state), btState); break;
7470
                }
7471
            }
7472
 
7473
            idx++;
7474
        }
7475
    }
7476
}
7477
 
149 andreas 7478
void TPageManager::doBMF (int port, vector<int>& channels, vector<string>& pars)
7479
{
7480
    DECL_TRACER("TPageManager::doBMF (int port, vector<int>& channels, vector<string>& pars)");
7481
 
7482
    if (pars.size() < 2)
332 andreas 7483
    {
7484
        MSG_ERROR("Less then 2 parameters!");
7485
#if TESTMODE == 1
334 andreas 7486
        setAllDone();
332 andreas 7487
#endif
149 andreas 7488
        return;
332 andreas 7489
    }
149 andreas 7490
 
7491
    TError::clear();
7492
    int btState = atoi(pars[0].c_str()) - 1;
150 andreas 7493
    string commands;
149 andreas 7494
 
150 andreas 7495
    for (size_t i = 1; i < pars.size(); ++i)
7496
    {
7497
        if (i > 1)
7498
            commands += ",";
7499
 
7500
        commands += pars[i];
7501
    }
7502
 
193 andreas 7503
    vector<TMap::MAP_T> map = findButtons(port, channels);
149 andreas 7504
 
7505
    if (TError::isError() || map.empty())
332 andreas 7506
    {
7507
#if TESTMODE == 1
334 andreas 7508
        setAllDone();
332 andreas 7509
#endif
149 andreas 7510
        return;
332 andreas 7511
    }
149 andreas 7512
 
7513
    // Start of parsing the command line
162 andreas 7514
    // We splitt the command line into parts by searching for a percent (%) sign.
149 andreas 7515
    vector<string> parts = StrSplit(commands, "%");
7516
 
162 andreas 7517
    if (parts.empty())
332 andreas 7518
        parts.push_back(commands);
334 andreas 7519
 
149 andreas 7520
    // Search for all buttons who need to be updated
7521
    vector<Button::TButton *> buttons = collectButtons(map);
7522
 
7523
    if (buttons.size() > 0)
7524
    {
7525
        vector<Button::TButton *>::iterator mapIter;
7526
 
7527
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
7528
        {
7529
            Button::TButton *bt = *mapIter;
162 andreas 7530
 
7531
            if (!bt)
7532
            {
7533
                MSG_WARNING("Command ^BMF found an invalid pointer to a button!")
7534
                continue;
7535
            }
7536
 
149 andreas 7537
            // Iterate through commands and apply them to button
7538
            vector<string>::iterator iter;
7539
 
7540
            for (iter = parts.begin(); iter != parts.end(); ++iter)
7541
            {
7542
                char cmd = iter->at(0);
7543
                char cmd2;
7544
                string content;
7545
 
7546
                switch(cmd)
7547
                {
7548
                    case 'B':   // Border style
361 andreas 7549
                        if (iter->at(1) == ',')
7550
                            content = iter->substr(2);
7551
                        else
7552
                            content = iter->substr(1);
332 andreas 7553
 
7554
                        if (!content.empty() && isdigit(content[0]))
334 andreas 7555
                            bt->setBorderStyle(atoi(content.c_str()), btState);
332 andreas 7556
                        else
7557
                            bt->setBorderStyle(content, btState);
7558
#if TESTMODE == 1
7559
                        if (_gTestMode)
7560
                            _gTestMode->setResult(bt->getBorderStyle(btState < 0 ? 0 : btState));
7561
#endif
149 andreas 7562
                    break;
7563
 
7564
                    case 'C':   // Colors
7565
                        cmd2 = iter->at(1);
7566
                        content = iter->substr(2);
7567
 
7568
                        switch(cmd2)
7569
                        {
7570
                            case 'B':   // Border color
7571
                                bt->setBorderColor(content, btState);
332 andreas 7572
#if TESTMODE == 1
7573
                                if (_gTestMode)
7574
                                    _gTestMode->setResult(bt->getBorderColor(btState < 0 ? 0 : btState));
7575
#endif
149 andreas 7576
                            break;
7577
 
7578
                            case 'F':   // Fill color
7579
                                bt->setFillColor(content, btState);
332 andreas 7580
#if TESTMODE == 1
7581
                                if (_gTestMode)
7582
                                    _gTestMode->setResult(bt->getFillColor(btState < 0 ? 0 : btState));
7583
#endif
149 andreas 7584
                            break;
7585
 
7586
                            case 'T':   // Text color
7587
                                bt->setTextColor(content, btState);
332 andreas 7588
#if TESTMODE == 1
7589
                                if (_gTestMode)
7590
                                    _gTestMode->setResult(bt->getTextColor(btState < 0 ? 0 : btState));
7591
#endif
149 andreas 7592
                            break;
7593
                        }
7594
                    break;
7595
 
150 andreas 7596
                    case 'D':   // Draw order
7597
                        cmd2 = iter->at(1);
7598
                        content = iter->substr(2);
7599
 
7600
                        if (cmd2 == 'O')
332 andreas 7601
                        {
150 andreas 7602
                            bt->setDrawOrder(content, btState);
332 andreas 7603
#if TESTMODE == 1
7604
                            if (_gTestMode)
7605
                                _gTestMode->setResult(bt->getDrawOrder(btState < 0 ? 0 : btState));
7606
#endif
7607
                        }
150 andreas 7608
                    break;
7609
 
149 andreas 7610
                    case 'E':   // Text effect
7611
                        cmd2 = iter->at(1);
7612
                        content = iter->substr(2);
7613
 
7614
                        switch(cmd2)
7615
                        {
7616
                            case 'C':   // Text effect color
7617
                                bt->setTextEffectColor(content, btState);
332 andreas 7618
#if TESTMODE == 1
7619
                                if (_gTestMode)
7620
                                    _gTestMode->setResult(bt->getTextEffectColor(btState < 0 ? 0 : btState));
7621
#endif
149 andreas 7622
                            break;
7623
 
7624
                            case 'F':   // Text effect name
7625
                                bt->setTextEffectName(content, btState);
332 andreas 7626
#if TESTMODE == 1
7627
                                if (_gTestMode)
7628
                                    _gTestMode->setResult(bt->getTextEffectName(btState < 0 ? 0 : btState));
7629
#endif
149 andreas 7630
                            break;
7631
 
7632
                            case 'N':   // Enable/disable button
7633
                                bt->setEnable((content[0] == '1' ? true : false));
332 andreas 7634
#if TESTMODE == 1
7635
                                if (_gTestMode)
334 andreas 7636
                                {
332 andreas 7637
                                    _gTestMode->setResult(bt->isEnabled() ? "TRUE" : "FALSE");
334 andreas 7638
                                    __success = true;
7639
                                    setScreenDone();
7640
                                }
332 andreas 7641
#endif
149 andreas 7642
                            break;
7643
                        }
7644
                    break;
7645
 
7646
                    case 'F':   // Set font file name
361 andreas 7647
                        if (iter->at(1) == ',')
7648
                            content = iter->substr(2);
7649
                        else
7650
                            content = iter->substr(1);
150 andreas 7651
 
7652
                        if (!isdigit(content[0]))
334 andreas 7653
                            bt->setFontName(content, btState);
150 andreas 7654
                        else
7655
                            bt->setFontIndex(atoi(content.c_str()), btState);
334 andreas 7656
#if TESTMODE == 1
7657
                        if (_gTestMode)
7658
                            _gTestMode->setResult(intToString(bt->getFontIndex(btState < 0 ? 0 : btState)));
7659
#endif
149 andreas 7660
                    break;
7661
 
7662
                    case 'G':   // Bargraphs
7663
                        cmd2 = iter->at(1);
7664
                        content = iter->substr(2);
7665
 
7666
                        switch(cmd2)
7667
                        {
7668
                            case 'C':   // Bargraph slider color
7669
                                bt->setBargraphSliderColor(content);
7670
                            break;
7671
 
7672
                            case 'D':   // Ramp down time
387 andreas 7673
                                bt->setBargraphRampDownTime(atoi(content.c_str()));
149 andreas 7674
                            break;
7675
 
7676
                            case 'G':   // Drag increment
387 andreas 7677
                                bt->setBargraphDragIncrement(atoi(content.c_str()));
149 andreas 7678
                            break;
7679
 
7680
                            case 'H':   // Upper limit
7681
                                bt->setBargraphUpperLimit(atoi(content.c_str()));
7682
                            break;
7683
 
7684
                            case 'I':   // Invert/noninvert
387 andreas 7685
                                if (bt->getButtonType() == BARGRAPH || bt->getButtonType() == MULTISTATE_BARGRAPH)
7686
                                    bt->setBargraphInvert(atoi(content.c_str()) > 0 ? true : false);
149 andreas 7687
                            break;
7688
 
7689
                            case 'L':   // Lower limit
7690
                                bt->setBargraphLowerLimit(atoi(content.c_str()));
7691
                            break;
7692
 
7693
                            case 'N':   // Slider name
361 andreas 7694
                                bt->setBargraphSliderName(content);
149 andreas 7695
                            break;
7696
 
7697
                            case 'R':   // Repeat interval
7698
                                // FIXME: Add function to set repeat interval
7699
                            break;
7700
 
7701
                            case 'U':   // Ramp up time
387 andreas 7702
                                bt->setBargraphRampUpTime(atoi(content.c_str()));
149 andreas 7703
                            break;
7704
 
7705
                            case 'V':   // Bargraph value
387 andreas 7706
                                bt->setBargraphLevel(atoi(content.c_str()));
149 andreas 7707
                            break;
7708
                        }
7709
                    break;
7710
 
152 andreas 7711
                    case 'I':   // Set the icon
7712
                        content = iter->substr(1);
7713
                        bt->setIcon(atoi(content.c_str()), btState);
332 andreas 7714
#if TESTMODE == 1
7715
                        if (_gTestMode)
7716
                            _gTestMode->setResult(intToString(bt->getIconIndex()));
7717
#endif
152 andreas 7718
                    break;
7719
 
149 andreas 7720
                    case 'J':   // Set text justification
150 andreas 7721
                        cmd2 = iter->at(1);
7722
 
361 andreas 7723
                        if (cmd2 == ',')
150 andreas 7724
                        {
7725
                            content = iter->substr(1);
152 andreas 7726
                            int just = atoi(content.c_str());
7727
                            int x = 0, y = 0;
7728
 
7729
                            if (just == 0)
7730
                            {
7731
                                vector<string> coords = StrSplit(content, ",");
7732
 
7733
                                if (coords.size() >= 3)
7734
                                {
7735
                                    x = atoi(coords[1].c_str());
7736
                                    y = atoi(coords[2].c_str());
7737
                                }
7738
                            }
7739
 
7740
                            bt->setTextJustification(atoi(content.c_str()), x, y, btState);
334 andreas 7741
#if TESTMODE == 1
7742
                            if (_gTestMode)
7743
                            {
7744
                                just = bt->getTextJustification(&x, &y, btState < 0 ? 0 : btState);
7745
                                string s = intToString(just) + "," + intToString(x) + "," + intToString(y);
7746
                                _gTestMode->setResult(s);
7747
                            }
7748
#endif
150 andreas 7749
                        }
361 andreas 7750
                        else if (cmd2 == 'T' || cmd2 == 'B' || cmd2 == 'I')
150 andreas 7751
                        {
7752
                            content = iter->substr(2);
152 andreas 7753
                            int x = 0, y = 0;
7754
                            int just = atoi(content.c_str());
150 andreas 7755
 
152 andreas 7756
                            if (just == 0)
7757
                            {
7758
                                vector<string> coords = StrSplit(content, ",");
7759
 
7760
                                if (coords.size() >= 3)
7761
                                {
7762
                                    x = atoi(coords[1].c_str());
7763
                                    y = atoi(coords[2].c_str());
7764
                                }
7765
                            }
7766
 
150 andreas 7767
                            switch(cmd2)
7768
                            {
7769
                                case 'B':   // Alignment of bitmap
152 andreas 7770
                                    bt->setBitmapJustification(atoi(content.c_str()), x, y, btState);
334 andreas 7771
#if TESTMODE == 1
7772
                                    just = bt->getBitmapJustification(&x, &y, btState < 0 ? 0 : btState);
7773
#endif
150 andreas 7774
                                break;
7775
 
7776
                                case 'I':   // Alignment of icon
152 andreas 7777
                                    bt->setIconJustification(atoi(content.c_str()), x, y, btState);
334 andreas 7778
#if TESTMODE == 1
7779
                                    just = bt->getIconJustification(&x, &y, btState < 0 ? 0 : btState);
7780
#endif
150 andreas 7781
                                break;
7782
 
7783
                                case 'T':   // Alignment of text
152 andreas 7784
                                    bt->setTextJustification(atoi(content.c_str()), x, y, btState);
334 andreas 7785
#if TESTMODE == 1
7786
                                    just = bt->getTextJustification(&x, &y, btState < 0 ? 0 : btState);
7787
#endif
150 andreas 7788
                                break;
7789
                            }
334 andreas 7790
#if TESTMODE == 1
7791
                            if (_gTestMode)
7792
                            {
7793
                                string s = intToString(just) + "," + intToString(x) + "," + intToString(y);
7794
                                _gTestMode->setResult(s);
7795
                            }
7796
#endif
150 andreas 7797
                        }
7798
                    break;
7799
 
7800
                    case 'M':   // Text area
7801
                        cmd2 = iter->at(1);
7802
                        content = iter->substr(2);
7803
 
7804
                        switch(cmd2)
7805
                        {
152 andreas 7806
                            case 'I':   // Set mask image
7807
                                // FIXME: Add code for image mask
7808
                            break;
7809
 
150 andreas 7810
                            case 'K':   // Input mask of text area
7811
                                // FIXME: Add input mask
7812
                            break;
7813
 
7814
                            case 'L':   // Maximum length of text area
7815
                                // FIXME: Add code to set maximum length
7816
                            break;
7817
                        }
7818
                    break;
7819
 
7820
                    case 'O':   // Set feedback typ, opacity
7821
                        cmd2 = iter->at(1);
7822
 
7823
                        switch(cmd2)
7824
                        {
7825
                            case 'P':   // Set opacity
7826
                                bt->setOpacity(atoi(iter->substr(2).c_str()), btState);
7827
                            break;
7828
 
7829
                            case 'T':   // Set feedback type
7830
                                content = iter->substr(2);
7831
                                content = toUpper(content);
7832
 
7833
                                if (content == "NONE")
7834
                                    bt->setFeedback(Button::FB_NONE);
7835
                                else if (content == "CHANNEL")
7836
                                    bt->setFeedback(Button::FB_CHANNEL);
7837
                                else if (content == "INVERT")
7838
                                    bt->setFeedback(Button::FB_INV_CHANNEL);
7839
                                else if (content == "ON")
7840
                                    bt->setFeedback(Button::FB_ALWAYS_ON);
7841
                                else if (content == "MOMENTARY")
7842
                                    bt->setFeedback(Button::FB_MOMENTARY);
7843
                                else if (content == "BLINK")
7844
                                    bt->setFeedback(Button::FB_BLINK);
7845
                                else
7846
                                {
7847
                                    MSG_WARNING("Unknown feedback type " << content);
7848
                                }
335 andreas 7849
#if TESTMODE == 1
7850
                                if (_gTestMode)
7851
                                    _gTestMode->setResult(intToString(bt->getFeedback()));
7852
#endif
150 andreas 7853
                            break;
7854
 
7855
                            default:
7856
                                content = iter->substr(1);
7857
                                // FIXME: Add code to set the feedback type
7858
                        }
7859
                    break;
7860
 
152 andreas 7861
                    case 'P':   // Set picture/bitmap file name
7862
                        content = iter->substr(1);
165 andreas 7863
 
7864
                        if (content.find(".") == string::npos)  // If the image has no extension ...
7865
                        {                                       // we must find the image in the map
7866
                            string iname = findImage(content);
7867
 
7868
                            if (!iname.empty())
7869
                                content = iname;
7870
                        }
7871
 
152 andreas 7872
                        bt->setBitmap(content, btState);
7873
                    break;
7874
 
7875
                    case 'R':   // Set rectangle
7876
                    {
7877
                        content = iter->substr(1);
7878
                        vector<string> corners = StrSplit(content, ",");
7879
 
7880
                        if (corners.size() > 0)
7881
                        {
7882
                            vector<string>::iterator itcorn;
7883
                            int pos = 0;
7884
                            int left, top, right, bottom;
7885
                            left = top = right = bottom = 0;
7886
 
7887
                            for (itcorn = corners.begin(); itcorn != corners.end(); ++itcorn)
7888
                            {
7889
                                switch(pos)
7890
                                {
7891
                                    case 0: left   = atoi(itcorn->c_str()); break;
7892
                                    case 1: top    = atoi(itcorn->c_str()); break;
7893
                                    case 2: right  = atoi(itcorn->c_str()); break;
7894
                                    case 3: bottom = atoi(itcorn->c_str()); break;
7895
                                }
7896
 
7897
                                pos++;
7898
                            }
7899
 
7900
                            if (pos >= 4)
334 andreas 7901
                            {
152 andreas 7902
                                bt->setRectangle(left, top, right, bottom);
334 andreas 7903
                                bt->refresh();
7904
                            }
152 andreas 7905
                        }
334 andreas 7906
#if TESTMODE == 1
7907
                        if (_gTestMode)
7908
                        {
7909
                            int left, top, width, height;
7910
                            bt->getRectangle(&left, &top, &height, &width);
7911
                            string res(intToString(left) + "," + intToString(top) + "," + intToString(width) + "," + intToString(height));
7912
                            _gTestMode->setResult(res);
7913
                        }
7914
#endif
152 andreas 7915
                    }
7916
                    break;
7917
 
150 andreas 7918
                    case 'S':   // show/hide, style, sound
7919
                        cmd2 = iter->at(1);
7920
                        content = iter->substr(2);
7921
 
7922
                        switch(cmd2)
7923
                        {
7924
                            case 'F':   // Set focus of text area button
7925
                                // FIXME: Add code to set the focus of text area button
7926
                            break;
7927
 
7928
                            case 'M':   // Submit text
169 andreas 7929
                                if (content.find("|"))  // To be replaced by LF (0x0a)?
7930
                                {
7931
                                    size_t pos = 0;
7932
 
7933
                                    while ((pos = content.find("|")) != string::npos)
7934
                                        content = content.replace(pos, 1, "\n");
7935
                                }
7936
 
150 andreas 7937
                                bt->setText(content, btState);
7938
                            break;
7939
 
7940
                            case 'O':   // Sound
7941
                                bt->setSound(content, btState);
335 andreas 7942
#if TESTMODE == 1
7943
                                if (_gTestMode)
7944
                                    _gTestMode->setResult(bt->getSound(btState < 0 ? 0 : btState));
7945
#endif
150 andreas 7946
                            break;
7947
 
7948
                            case 'T':   // Button style
7949
                                // FIXME: Add code to set the button style
7950
                            break;
7951
 
7952
                            case 'W':   // Show / hide button
7953
                                if (content[0] == '0')
334 andreas 7954
                                    bt->hide(true);
150 andreas 7955
                                else
7956
                                    bt->show();
334 andreas 7957
#if TESTMODE == 1
7958
                                if (_gTestMode)
7959
                                    _gTestMode->setResult(bt->isVisible() ? "TRUE" : "FALSE");
7960
#endif
150 andreas 7961
                            break;
7962
                        }
7963
                    break;
7964
 
152 andreas 7965
                    case 'T':   // Set text
7966
                        content = iter->substr(1);
169 andreas 7967
 
7968
                        if (content.find("|"))  // To be replaced by LF (0x0a)?
7969
                        {
7970
                            size_t pos = 0;
7971
 
7972
                            while ((pos = content.find("|")) != string::npos)
7973
                                content = content.replace(pos, 1, "\n");
7974
                        }
7975
 
152 andreas 7976
                        bt->setText(content, btState);
334 andreas 7977
#if TESTMODE == 1
7978
                        if (_gTestMode)
7979
                            _gTestMode->setResult(bt->getText(btState < 0 ? 0 : btState));
7980
#endif
152 andreas 7981
                    break;
7982
 
150 andreas 7983
                    case 'U':   // Set the unicode text
7984
                        if (iter->at(1) == 'N')
7985
                        {
7986
                            content = iter->substr(2);
152 andreas 7987
                            string byte, text;
7988
                            size_t pos = 0;
7989
 
7990
                            while (pos < content.length())
7991
                            {
7992
                                byte = content.substr(pos, 2);
7993
                                char ch = (char)strtol(byte.c_str(), NULL, 16);
7994
                                text += ch;
7995
                                pos += 2;
7996
                            }
7997
 
169 andreas 7998
                            if (text.find("|"))  // To be replaced by LF (0x0a)?
7999
                            {
8000
                                size_t pos = 0;
8001
 
8002
                                while ((pos = text.find("|")) != string::npos)
8003
                                    text = text.replace(pos, 1, "\n");
8004
                            }
8005
 
152 andreas 8006
                            bt->setText(text, btState);
150 andreas 8007
                        }
8008
                    break;
8009
 
8010
                    case 'V':   // Video on / off
8011
                        cmd2 = iter->at(1);
8012
                        // Controlling a computer remotely is not supported.
8013
                        if (cmd2 != 'L' && cmd2 != 'N' && cmd2 != 'P')
8014
                        {
8015
                            content = iter->substr(2);
8016
                            // FIXME: Add code to switch video on or off
8017
                        }
8018
                    break;
8019
 
8020
                    case 'W':   // Word wrap
152 andreas 8021
                        if (iter->at(1) == 'W')
8022
                        {
8023
                            content = iter->substr(2);
8024
                            bt->setTextWordWrap(content[0] == '1' ? true : false, btState);
8025
                        }
149 andreas 8026
                    break;
8027
                }
8028
            }
8029
        }
8030
    }
332 andreas 8031
#if TESTMODE == 1
334 andreas 8032
    setDone();
332 andreas 8033
#endif
149 andreas 8034
}
8035
 
14 andreas 8036
/**
110 andreas 8037
 * Set the maximum length of the text area button. If this value is set to
8038
 * zero (0), the text area has no max length. The maximum length available is
8039
 * 2000. This is only for a Text area input button and not for a Text area input
8040
 * masking button.
8041
 */
8042
void TPageManager::doBML(int port, vector<int>& channels, vector<string>& pars)
8043
{
8044
    DECL_TRACER("TPageManager::doBML(int port, vector<int>& channels, vector<string>& pars)");
8045
 
8046
    if (pars.size() < 1)
8047
    {
8048
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
8049
        return;
8050
    }
8051
 
8052
    TError::clear();
8053
    int maxLen = atoi(pars[0].c_str());
8054
 
8055
    if (maxLen < 0 || maxLen > 2000)
8056
    {
8057
        MSG_WARNING("Got illegal length of text area! [" << maxLen << "]");
8058
        return;
8059
    }
8060
 
193 andreas 8061
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 8062
 
8063
    if (TError::isError() || map.empty())
8064
        return;
8065
 
8066
    vector<Button::TButton *> buttons = collectButtons(map);
8067
 
8068
    if (buttons.size() > 0)
8069
    {
8070
        vector<Button::TButton *>::iterator mapIter;
8071
 
8072
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8073
        {
8074
            Button::TButton *bt = *mapIter;
8075
            bt->setTextMaxChars(maxLen);
8076
        }
8077
    }
8078
}
8079
 
8080
/**
60 andreas 8081
 * Assign a picture to those buttons with a defined address range.
8082
 */
8083
void TPageManager::doBMP(int port, vector<int>& channels, vector<string>& pars)
8084
{
8085
    DECL_TRACER("TPageManager::doBMP(int port, vector<int>& channels, vector<string>& pars)");
8086
 
8087
    if (pars.size() < 2)
8088
    {
8089
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
8090
        return;
8091
    }
8092
 
8093
    TError::clear();
8094
    int btState = atoi(pars[0].c_str());
8095
    string bitmap = pars[1];
104 andreas 8096
    // If this is a G5 command, we may have up to 2 additional parameters.
8097
    int slot = -1, justify = -1, jx = 0, jy = 0;
60 andreas 8098
 
104 andreas 8099
    if (pars.size() > 2)
8100
    {
8101
        slot = atoi(pars[2].c_str());
8102
 
8103
        if (pars.size() >= 4)
8104
        {
8105
            justify = atoi(pars[4].c_str());
8106
 
8107
            if (justify == 0)
8108
            {
8109
                if (pars.size() >= 5)
8110
                    jx = atoi(pars[5].c_str());
8111
 
8112
                if (pars.size() >= 6)
8113
                    jy = atoi(pars[6].c_str());
8114
            }
8115
        }
8116
    }
8117
 
193 andreas 8118
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 8119
 
8120
    if (TError::isError() || map.empty())
8121
        return;
8122
 
8123
    vector<Button::TButton *> buttons = collectButtons(map);
8124
 
83 andreas 8125
    if (buttons.size() > 0)
60 andreas 8126
    {
83 andreas 8127
        vector<Button::TButton *>::iterator mapIter;
60 andreas 8128
 
83 andreas 8129
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 8130
        {
83 andreas 8131
            Button::TButton *bt = *mapIter;
252 andreas 8132
//            setButtonCallbacks(bt);
60 andreas 8133
 
83 andreas 8134
            if (btState == 0)       // All instances?
8135
            {
8136
                int bst = bt->getNumberInstances();
96 andreas 8137
                MSG_DEBUG("Setting bitmap " << bitmap << " on all " << bst << " instances...");
83 andreas 8138
 
8139
                for (int i = 0; i < bst; i++)
104 andreas 8140
                {
8141
                    if (justify >= 0)
8142
                    {
8143
                        if (slot == 2)
8144
                            bt->setIconJustification(justify, jx, jy, i);
8145
                        else
106 andreas 8146
                            bt->setBitmapJustification(justify, jx, jy, i);
104 andreas 8147
                    }
8148
 
8149
                    if (slot >= 0)
8150
                    {
8151
                        switch(slot)
8152
                        {
8153
                            case 0: bt->setCameleon(bitmap, i); break;
8154
                            case 2: bt->setIcon(bitmap, i); break;  // On G4 we have no bitmap layer. Therefor we use layer 2 as icon layer.
8155
                            default:
8156
                                bt->setBitmap(bitmap, i);
8157
                        }
8158
                    }
8159
                    else
8160
                        bt->setBitmap(bitmap, i);
8161
                }
83 andreas 8162
            }
8163
            else
104 andreas 8164
            {
8165
                if (justify >= 0)
8166
                {
8167
                    if (slot == 2)
8168
                        bt->setIconJustification(justify, jx, jy, btState);
8169
                    else
106 andreas 8170
                        bt->setBitmapJustification(justify, jx, jy, btState);
104 andreas 8171
                }
8172
 
8173
                if (slot >= 0)
8174
                {
8175
                    switch(slot)
8176
                    {
8177
                        case 0: bt->setCameleon(bitmap, btState); break;
8178
                        case 2: bt->setIcon(bitmap, btState); break;      // On G4 we have no bitmap layer. Therefor we use layer 2 as icon layer.
8179
                        default:
8180
                            bt->setBitmap(bitmap, btState);
8181
                    }
8182
                }
8183
                else
8184
                    bt->setBitmap(bitmap, btState);
8185
            }
60 andreas 8186
        }
8187
    }
8188
}
8189
 
82 andreas 8190
void TPageManager::getBMP(int port, vector<int> &channels, vector<string> &pars)
8191
{
8192
    DECL_TRACER("TPageManager::getBMP(int port, vector<int> &channels, vector<string> &pars)");
8193
 
8194
    if (pars.size() < 1)
8195
    {
8196
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
8197
        return;
8198
    }
8199
 
8200
    TError::clear();
8201
    int btState = atoi(pars[0].c_str());
8202
    string bmp;
8203
 
193 andreas 8204
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 8205
 
8206
    if (TError::isError() || map.empty())
8207
        return;
8208
 
8209
    vector<Button::TButton *> buttons = collectButtons(map);
8210
 
83 andreas 8211
    if (buttons.size() > 0)
82 andreas 8212
    {
110 andreas 8213
        Button::TButton *bt = buttons[0];
82 andreas 8214
 
110 andreas 8215
        if (btState == 0)       // All instances?
82 andreas 8216
        {
110 andreas 8217
            int bst = bt->getNumberInstances();
82 andreas 8218
 
110 andreas 8219
            for (int i = 0; i < bst; i++)
82 andreas 8220
            {
110 andreas 8221
                bmp = bt->getBitmapName(i);
82 andreas 8222
 
110 andreas 8223
                if (bmp.empty())
8224
                    continue;
82 andreas 8225
 
300 andreas 8226
                sendCustomEvent(i + 1, (int)bmp.length(), 0, bmp, 1002, bt->getChannelPort(), bt->getChannelNumber());
83 andreas 8227
            }
82 andreas 8228
        }
110 andreas 8229
        else
8230
        {
8231
            bmp = bt->getTextColor(btState-1);
300 andreas 8232
            sendCustomEvent(btState, (int)bmp.length(), 0, bmp, 1002, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 8233
        }
82 andreas 8234
    }
8235
}
8236
 
60 andreas 8237
/**
16 andreas 8238
 * Set the button opacity. The button opacity can be specified as a decimal
8239
 * between 0 - 255, where zero (0) is invisible and 255 is opaque, or as a
8240
 * HEX code, as used in the color commands by preceding the HEX code with
8241
 * the # sign. In this case, #00 becomes invisible and #FF becomes opaque.
8242
 * If the opacity is set to zero (0), this does not make the button inactive,
8243
 * only invisible.
8244
 */
8245
void TPageManager::doBOP(int port, vector<int>& channels, vector<string>& pars)
8246
{
8247
    DECL_TRACER("TPageManager::doBOP(int port, vector<int>& channels, vector<string>& pars)");
8248
 
8249
    if (pars.size() < 2)
8250
    {
8251
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
335 andreas 8252
#if TESTMODE == 1
8253
        setAllDone();
8254
#endif
16 andreas 8255
        return;
8256
    }
8257
 
8258
    TError::clear();
335 andreas 8259
    int btState = atoi(pars[0].c_str()) - 1;
16 andreas 8260
    int btOpacity = 0;
8261
 
8262
    if (pars[1].at(0) == '#')
8263
        btOpacity = (int)strtol(pars[1].substr(1).c_str(), NULL, 16);
8264
    else
8265
        btOpacity = atoi(pars[1].c_str());
8266
 
193 andreas 8267
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8268
 
8269
    if (TError::isError() || map.empty())
335 andreas 8270
    {
8271
#if TESTMODE == 1
8272
        setAllDone();
8273
#endif
16 andreas 8274
        return;
335 andreas 8275
    }
16 andreas 8276
 
8277
    vector<Button::TButton *> buttons = collectButtons(map);
8278
 
83 andreas 8279
    if (buttons.size() > 0)
16 andreas 8280
    {
83 andreas 8281
        vector<Button::TButton *>::iterator mapIter;
16 andreas 8282
 
83 andreas 8283
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
16 andreas 8284
        {
83 andreas 8285
            Button::TButton *bt = *mapIter;
335 andreas 8286
            bt->setOpacity(btOpacity, btState);
8287
#if TESTMODE == 1
8288
            if (_gTestMode)
8289
                _gTestMode->setResult(intToString(bt->getOpacity(btState < 0 ? 0 : btState)));
342 andreas 8290
#endif
16 andreas 8291
        }
8292
    }
335 andreas 8293
#if TESTMODE == 1
8294
    setDone();
8295
#endif
16 andreas 8296
}
8297
 
106 andreas 8298
void TPageManager::getBOP(int port, vector<int>& channels, vector<string>& pars)
8299
{
8300
    DECL_TRACER("TPageManager::getBOP(int port, vector<int>& channels, vector<string>& pars)");
8301
 
8302
    if (pars.size() < 1)
8303
    {
8304
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
8305
        return;
8306
    }
8307
 
8308
    TError::clear();
8309
    int btState = atoi(pars[0].c_str());
8310
 
193 andreas 8311
    vector<TMap::MAP_T> map = findButtons(port, channels);
106 andreas 8312
 
8313
    if (TError::isError() || map.empty())
8314
        return;
8315
 
8316
    vector<Button::TButton *> buttons = collectButtons(map);
8317
 
8318
    if (buttons.size() > 0)
8319
    {
110 andreas 8320
        Button::TButton *bt = buttons[0];
106 andreas 8321
 
110 andreas 8322
        if (btState == 0)       // All instances?
106 andreas 8323
        {
110 andreas 8324
            int bst = bt->getNumberInstances();
106 andreas 8325
 
110 andreas 8326
            for (int i = 0; i < bst; i++)
106 andreas 8327
            {
110 andreas 8328
                int oo = bt->getOpacity(i);
8329
                sendCustomEvent(i + 1, oo, 0, "", 1015, bt->getChannelPort(), bt->getChannelNumber());
106 andreas 8330
            }
8331
        }
110 andreas 8332
        else
8333
        {
8334
            int oo = bt->getOpacity(btState-1);
8335
            sendCustomEvent(btState, oo, 0, "", 1015, bt->getChannelPort(), bt->getChannelNumber());
8336
        }
106 andreas 8337
    }
8338
}
8339
 
60 andreas 8340
void TPageManager::doBOR(int port, vector<int>& channels, vector<string>& pars)
8341
{
8342
    DECL_TRACER("TPageManager::doBOR(int port, vector<int>& channels, vector<string>& pars)");
8343
 
8344
    if (pars.size() < 1)
8345
    {
8346
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
335 andreas 8347
#if TESTMODE == 1
8348
        setAllDone();
8349
#endif
60 andreas 8350
        return;
8351
    }
8352
 
8353
    TError::clear();
8354
    // Numbers of styles from 0 to 41
8355
    string bor = pars[0];
8356
    string border = "None";
8357
    int ibor = -1;
336 andreas 8358
    Border::TIntBorder borders;
60 andreas 8359
 
8360
    if (bor.at(0) >= '0' && bor.at(0) <= '9')
336 andreas 8361
    {
60 andreas 8362
        ibor = atoi(bor.c_str());
8363
 
336 andreas 8364
        if (ibor >= 0 && ibor <= 41)
8365
            border = borders.getTP4BorderName(ibor);
8366
        else
60 andreas 8367
        {
336 andreas 8368
            MSG_WARNING("Invalid border style ID " << ibor);
8369
#if TESTMODE == 1
8370
            setAllDone();
8371
#endif
8372
            return;
8373
        }
60 andreas 8374
 
336 andreas 8375
        MSG_DEBUG("Id " << ibor << " is border " << border);
60 andreas 8376
    }
336 andreas 8377
    else
60 andreas 8378
    {
336 andreas 8379
        if (!borders.isTP4BorderValid(bor))
8380
        {
8381
            MSG_WARNING("Unknown border style " << bor);
335 andreas 8382
#if TESTMODE == 1
336 andreas 8383
            setAllDone();
335 andreas 8384
#endif
336 andreas 8385
            return;
8386
        }
60 andreas 8387
 
336 andreas 8388
        border = bor;
60 andreas 8389
    }
8390
 
193 andreas 8391
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 8392
 
8393
    if (TError::isError() || map.empty())
335 andreas 8394
    {
8395
#if TESTMODE == 1
8396
        setAllDone();
8397
#endif
60 andreas 8398
        return;
335 andreas 8399
    }
60 andreas 8400
 
8401
    vector<Button::TButton *> buttons = collectButtons(map);
8402
 
83 andreas 8403
    if (buttons.size() > 0)
60 andreas 8404
    {
83 andreas 8405
        vector<Button::TButton *>::iterator mapIter;
8406
 
8407
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8408
        {
8409
            Button::TButton *bt = *mapIter;
8410
            bt->setBorderStyle(border);
335 andreas 8411
#if TESTMODE == 1
8412
            if (_gTestMode)
8413
                _gTestMode->setResult(bt->getBorderStyle(0));
8414
#endif
83 andreas 8415
        }
60 andreas 8416
    }
335 andreas 8417
#if TESTMODE == 1
8418
    setDone();
8419
#endif
60 andreas 8420
}
8421
 
107 andreas 8422
void TPageManager::doBOS(int port, vector<int>& channels, vector<string>& pars)
8423
{
8424
    DECL_TRACER("TPageManager::doBOS(int port, vector<int>& channels, vector<string>& pars)");
8425
 
8426
    if (pars.size() < 2)
8427
    {
8428
        MSG_ERROR("Expecting at least 2 parameters but got " << pars.size() << "! Ignoring command.");
8429
        return;
8430
    }
8431
 
8432
    TError::clear();
8433
    int btState = atoi(pars[0].c_str());
8434
    int videoState = atoi(pars[1].c_str());
8435
 
193 andreas 8436
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 8437
 
8438
    if (TError::isError() || map.empty())
8439
        return;
8440
 
8441
    vector<Button::TButton *> buttons = collectButtons(map);
8442
 
8443
    if (buttons.size() > 0)
8444
    {
8445
        vector<Button::TButton *>::iterator mapIter;
8446
 
8447
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8448
        {
8449
            Button::TButton *bt = *mapIter;
8450
 
8451
            if (btState == 0)       // All instances?
8452
                bt->setDynamic(videoState);
8453
            else
8454
                bt->setDynamic(videoState, btState-1);
8455
        }
8456
    }
8457
}
8458
 
16 andreas 8459
/**
60 andreas 8460
 * Set the border of a button state/states.
8461
 * The border names are available through the TPDesign4 border-name drop-down
8462
 * list.
8463
 */
8464
void TPageManager::doBRD(int port, vector<int>& channels, vector<string>& pars)
8465
{
8466
    DECL_TRACER("TPageManager::doBRD(int port, vector<int>& channels, vector<string>& pars)");
8467
 
8468
    if (pars.size() < 1)
8469
    {
8470
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8471
        return;
8472
    }
8473
 
8474
    TError::clear();
8475
    int btState = atoi(pars[0].c_str());
8476
    string border = "None";
8477
 
8478
    if (pars.size() > 1)
8479
        border = pars[1];
8480
 
193 andreas 8481
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 8482
 
8483
    if (TError::isError() || map.empty())
8484
        return;
8485
 
8486
    vector<Button::TButton *> buttons = collectButtons(map);
8487
 
83 andreas 8488
    if (buttons.size() > 0)
60 andreas 8489
    {
83 andreas 8490
        vector<Button::TButton *>::iterator mapIter;
60 andreas 8491
 
83 andreas 8492
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 8493
        {
83 andreas 8494
            Button::TButton *bt = *mapIter;
252 andreas 8495
//            setButtonCallbacks(bt);
60 andreas 8496
 
83 andreas 8497
            if (btState == 0)       // All instances?
8498
            {
8499
                int bst = bt->getNumberInstances();
8500
 
8501
                for (int i = 0; i < bst; i++)
106 andreas 8502
                    bt->setBorderStyle(border, i+1);
83 andreas 8503
            }
8504
            else
106 andreas 8505
                bt->setBorderStyle(border, btState);
60 andreas 8506
        }
8507
    }
8508
}
8509
 
107 andreas 8510
void TPageManager::getBRD(int port, vector<int>& channels, vector<string>& pars)
8511
{
8512
    DECL_TRACER("TPageManager::getBRD(int port, vector<int>& channels, vector<string>& pars)");
8513
 
8514
    if (pars.size() < 1)
8515
    {
8516
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8517
        return;
8518
    }
8519
 
8520
    TError::clear();
8521
    int btState = atoi(pars[0].c_str());
8522
 
193 andreas 8523
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 8524
 
8525
    if (TError::isError() || map.empty())
8526
        return;
8527
 
8528
    vector<Button::TButton *> buttons = collectButtons(map);
8529
 
8530
    if (buttons.size() > 0)
8531
    {
110 andreas 8532
        Button::TButton *bt = buttons[0];
107 andreas 8533
 
110 andreas 8534
        if (btState == 0)       // All instances?
107 andreas 8535
        {
110 andreas 8536
            int bst = bt->getNumberInstances();
107 andreas 8537
 
110 andreas 8538
            for (int i = 0; i < bst; i++)
107 andreas 8539
            {
110 andreas 8540
                string bname = bt->getBorderStyle(i);
300 andreas 8541
                sendCustomEvent(i + 1, (int)bname.length(), 0, bname, 1014, bt->getChannelPort(), bt->getChannelNumber());
107 andreas 8542
            }
8543
        }
110 andreas 8544
        else
8545
        {
8546
            string bname = bt->getBorderStyle(btState-1);
300 andreas 8547
            sendCustomEvent(btState, (int)bname.length(), 0, bname, 1014, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 8548
        }
107 andreas 8549
    }
8550
}
8551
 
60 andreas 8552
/**
16 andreas 8553
 * Set the button size and its position on the page.
8554
 */
8555
void TPageManager::doBSP(int port, vector<int>& channels, vector<string>& pars)
8556
{
8557
    DECL_TRACER("TPageManager::doBSP(int port, vector<int>& channels, vector<string>& pars)");
8558
 
8559
    if (pars.size() < 1)
8560
    {
8561
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
341 andreas 8562
#if TESTMODE == 1
8563
        setAllDone();
8564
#endif
16 andreas 8565
        return;
8566
    }
8567
 
8568
    TError::clear();
8569
    bool bLeft = false, bTop = false, bRight = false, bBottom = false;
8570
    int x, y;
8571
 
83 andreas 8572
    if (pars.size() > 0)
16 andreas 8573
    {
83 andreas 8574
        vector<string>::iterator iter;
8575
 
8576
        for (iter = pars.begin(); iter != pars.end(); iter++)
8577
        {
8578
            if (iter->compare("left") == 0)
8579
                bLeft = true;
8580
            else if (iter->compare("top") == 0)
8581
                bTop = true;
8582
            else if (iter->compare("right") == 0)
8583
                bRight = true;
8584
            else if (iter->compare("bottom") == 0)
8585
                bBottom = true;
8586
        }
16 andreas 8587
    }
8588
 
193 andreas 8589
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8590
 
8591
    if (TError::isError() || map.empty())
8592
        return;
8593
 
8594
    vector<Button::TButton *> buttons = collectButtons(map);
8595
 
83 andreas 8596
    if (buttons.size() > 0)
16 andreas 8597
    {
83 andreas 8598
        vector<Button::TButton *>::iterator mapIter;
16 andreas 8599
 
83 andreas 8600
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8601
        {
8602
            Button::TButton *bt = *mapIter;
341 andreas 8603
//            setButtonCallbacks(bt);
16 andreas 8604
 
83 andreas 8605
            if (bLeft)
8606
                x = 0;
16 andreas 8607
 
83 andreas 8608
            if (bTop)
8609
                y = 0;
16 andreas 8610
 
341 andreas 8611
            if (bRight || bBottom)
16 andreas 8612
            {
83 andreas 8613
                ulong handle = bt->getHandle();
8614
                int parentID = (handle >> 16) & 0x0000ffff;
8615
                int pwidth = 0;
341 andreas 8616
                int pheight = 0;
16 andreas 8617
 
83 andreas 8618
                if (parentID < 500)
16 andreas 8619
                {
83 andreas 8620
                    TPage *pg = getPage(parentID);
8621
 
8622
                    if (!pg)
8623
                    {
8624
                        MSG_ERROR("Internal error: Page " << parentID << " not found!");
8625
                        return;
8626
                    }
8627
 
8628
                    pwidth = pg->getWidth();
341 andreas 8629
                    pheight = pg->getHeight();
16 andreas 8630
                }
83 andreas 8631
                else
8632
                {
8633
                    TSubPage *spg = getSubPage(parentID);
16 andreas 8634
 
83 andreas 8635
                    if (!spg)
8636
                    {
8637
                        MSG_ERROR("Internal error: Subpage " << parentID << " not found!");
8638
                        return;
8639
                    }
16 andreas 8640
 
83 andreas 8641
                    pwidth = spg->getWidth();
341 andreas 8642
                    pheight = spg->getHeight();
16 andreas 8643
                }
8644
 
341 andreas 8645
                if (bRight)
8646
                    x = pwidth - bt->getWidth();
8647
 
8648
                if (bBottom)
8649
                    y = pheight - bt->getHeight();
16 andreas 8650
            }
8651
 
341 andreas 8652
            bt->setLeftTop(x, y);
8653
#if TESTMODE == 1
8654
            if (_gTestMode)
83 andreas 8655
            {
341 andreas 8656
                int left = bt->getLeftPosition();
8657
                int top = bt->getTopPosition();
8658
                string res = intToString(left) + "," + intToString(top);
8659
                _gTestMode->setResult(res);
16 andreas 8660
            }
341 andreas 8661
#endif
16 andreas 8662
        }
8663
    }
341 andreas 8664
#if TESTMODE == 1
8665
    setDone();
8666
#endif
16 andreas 8667
}
8668
 
8669
/**
107 andreas 8670
 * Submit text for text area buttons. This command causes the text areas to
8671
 * send their text as strings to the NetLinx Master.
8672
 */
8673
void TPageManager::doBSM(int port, vector<int>& channels, vector<string>&)
8674
{
8675
    DECL_TRACER("TPageManager::doBSM(int port, vector<int>& channels, vector<string>& pars)");
8676
 
8677
    TError::clear();
193 andreas 8678
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 8679
 
8680
    if (TError::isError() || map.empty())
341 andreas 8681
    {
8682
#if TESTMODE == 1
8683
        setAllDone();
8684
#endif
107 andreas 8685
        return;
341 andreas 8686
    }
107 andreas 8687
 
8688
    vector<Button::TButton *> buttons = collectButtons(map);
8689
 
8690
    if (buttons.size() > 0)
8691
    {
8692
        vector<Button::TButton *>::iterator mapIter;
8693
 
8694
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8695
        {
8696
            Button::TButton *bt = *mapIter;
8697
 
195 andreas 8698
            if (bt->getButtonType() != TEXT_INPUT && bt->getButtonType() != GENERAL)
341 andreas 8699
            {
8700
#if TESTMODE == 1
8701
                setAllDone();
8702
#endif
107 andreas 8703
                return;
341 andreas 8704
            }
107 andreas 8705
 
8706
            amx::ANET_SEND scmd;
8707
            scmd.port = bt->getChannelPort();
8708
            scmd.channel = bt->getChannelNumber();
8709
            scmd.ID = scmd.channel;
8710
            scmd.msg = bt->getText(0);
8711
            scmd.MC = 0x008b;       // string value
8712
 
8713
            if (gAmxNet)
8714
                gAmxNet->sendCommand(scmd);
8715
            else
8716
                MSG_WARNING("Missing global class TAmxNet. Can't send message!");
8717
 
8718
        }
8719
    }
8720
}
8721
 
8722
/**
8723
 * Set the sound played when a button is pressed. If the sound name is blank
8724
 * the sound is then cleared. If the sound name is not matched, the button
8725
 * sound is not changed.
8726
 */
8727
void TPageManager::doBSO(int port, vector<int>& channels, vector<string>& pars)
8728
{
8729
    DECL_TRACER("TPageManager::doBSO(int port, vector<int>& channels, vector<string>& pars)");
8730
 
8731
    if (pars.size() < 2)
8732
    {
8733
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
8734
        return;
8735
    }
8736
 
8737
    if (!gPrjResources)
8738
        return;
8739
 
8740
    TError::clear();
8741
    int btState = atoi(pars[0].c_str());
8742
    string sound = pars[1];
8743
 
8744
    if (!soundExist(sound))
8745
        return;
8746
 
193 andreas 8747
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 8748
 
8749
    if (TError::isError() || map.empty())
8750
        return;
8751
 
8752
    vector<Button::TButton *> buttons = collectButtons(map);
8753
 
8754
    if (buttons.size() > 0)
8755
    {
8756
        vector<Button::TButton *>::iterator mapIter;
8757
 
8758
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8759
        {
8760
            Button::TButton *bt = *mapIter;
8761
 
8762
            if (btState == 0)
8763
            {
8764
                int bst = bt->getNumberInstances();
8765
 
8766
                for (int i = 0; i < bst; i++)
8767
                    bt->setSound(sound, i);
8768
            }
8769
            else
8770
                bt->setSound(sound, btState-1);
8771
        }
8772
    }
8773
}
8774
 
8775
/**
16 andreas 8776
 * Set the button word wrap feature to those buttons with a defined address
8777
 * range. By default, word-wrap is Off.
8778
 */
8779
void TPageManager::doBWW(int port, vector<int>& channels, vector<string>& pars)
8780
{
8781
    DECL_TRACER("TPageManager::doBWW(int port, vector<int>& channels, vector<string>& pars)");
8782
 
8783
    if (pars.size() < 1)
8784
    {
8785
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
8786
        return;
8787
    }
8788
 
8789
    TError::clear();
8790
    int btState = atoi(pars[0].c_str());
8791
 
193 andreas 8792
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8793
 
8794
    if (TError::isError() || map.empty())
8795
        return;
8796
 
8797
    vector<Button::TButton *> buttons = collectButtons(map);
8798
 
83 andreas 8799
    if (buttons.size() > 0)
16 andreas 8800
    {
83 andreas 8801
        vector<Button::TButton *>::iterator mapIter;
16 andreas 8802
 
83 andreas 8803
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
16 andreas 8804
        {
83 andreas 8805
            Button::TButton *bt = *mapIter;
252 andreas 8806
//            setButtonCallbacks(bt);
16 andreas 8807
 
83 andreas 8808
            if (btState == 0)       // All instances?
8809
            {
8810
                int bst = bt->getNumberInstances();
8811
                MSG_DEBUG("Setting word wrap on all " << bst << " instances...");
8812
 
8813
                for (int i = 0; i < bst; i++)
110 andreas 8814
                    bt->setTextWordWrap(true, i);
83 andreas 8815
            }
8816
            else
110 andreas 8817
                bt->setTextWordWrap(true, btState - 1);
16 andreas 8818
        }
8819
    }
8820
}
8821
 
108 andreas 8822
void TPageManager::getBWW(int port, vector<int>& channels, vector<string>& pars)
8823
{
8824
    DECL_TRACER("TPageManager::getBWW(int port, vector<int>& channels, vector<string>& pars)");
8825
 
8826
    if (pars.size() < 1)
8827
    {
8828
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8829
        return;
8830
    }
8831
 
8832
    TError::clear();
8833
    int btState = atoi(pars[0].c_str());
8834
 
193 andreas 8835
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 8836
 
8837
    if (TError::isError() || map.empty())
8838
        return;
8839
 
8840
    vector<Button::TButton *> buttons = collectButtons(map);
8841
 
8842
    if (buttons.size() > 0)
8843
    {
110 andreas 8844
        Button::TButton *bt = buttons[0];
108 andreas 8845
 
110 andreas 8846
        if (btState == 0)       // All instances?
108 andreas 8847
        {
110 andreas 8848
            int bst = bt->getNumberInstances();
108 andreas 8849
 
110 andreas 8850
            for (int i = 0; i < bst; i++)
8851
                sendCustomEvent(i + 1, bt->getTextWordWrap(i), 0, "", 1010, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 8852
        }
110 andreas 8853
        else
8854
            sendCustomEvent(btState, bt->getTextWordWrap(btState-1), 0, "", 1010, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 8855
    }
8856
}
8857
 
16 andreas 8858
/**
8859
 * Clear all page flips from a button.
8860
 */
22 andreas 8861
void TPageManager::doCPF(int port, vector<int>& channels, vector<string>&)
16 andreas 8862
{
8863
    DECL_TRACER("TPageManager::doCPF(int port, vector<int>& channels, vector<string>& pars)");
8864
 
8865
    TError::clear();
193 andreas 8866
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8867
 
8868
    if (TError::isError() || map.empty())
8869
        return;
8870
 
8871
    vector<Button::TButton *> buttons = collectButtons(map);
8872
 
83 andreas 8873
    if (buttons.size() > 0)
16 andreas 8874
    {
83 andreas 8875
        vector<Button::TButton *>::iterator mapIter;
8876
 
8877
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8878
        {
8879
            Button::TButton *bt = *mapIter;
252 andreas 8880
//            setButtonCallbacks(bt);
83 andreas 8881
            bt->clearPushFunctions();
8882
        }
16 andreas 8883
    }
8884
}
8885
 
8886
/**
8887
 * Delete page flips from button if it already exists.
8888
 */
8889
void TPageManager::doDPF(int port, vector<int>& channels, vector<string>& pars)
8890
{
8891
    DECL_TRACER("TPageManager::doDPF(int port, vector<int>& channels, vector<string>& pars)");
8892
 
8893
    if (pars.size() < 1)
8894
    {
8895
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8896
        return;
8897
    }
8898
 
8899
    TError::clear();
8900
    string action = pars[0];
8901
    string pname;
8902
 
8903
    if (pars.size() >= 2)
8904
    {
8905
        pname = pars[1];
8906
        vector<Button::TButton *> list;
8907
        // First we search for a subpage because this is more likely
8908
        TSubPage *spg = getSubPage(pname);
8909
 
8910
        if (spg)
8911
            list = spg->getButtons(port, channels[0]);
8912
        else    // Then for a page
8913
        {
8914
            TPage *pg = getPage(pname);
8915
 
8916
            if (pg)
8917
                list = pg->getButtons(port, channels[0]);
8918
            else
8919
            {
8920
                MSG_WARNING("The name " << pname << " doesn't name either a page or a subpage!");
8921
                return;
8922
            }
8923
        }
8924
 
8925
        if (list.empty())
8926
            return;
8927
 
8928
        vector<Button::TButton *>::iterator it;
8929
 
8930
        for (it = list.begin(); it != list.end(); it++)
8931
        {
8932
            Button::TButton *bt = *it;
252 andreas 8933
//            setButtonCallbacks(bt);
16 andreas 8934
            bt->clearPushFunction(action);
8935
        }
8936
 
8937
        return;
8938
    }
8939
 
8940
    // Here we don't have a page name
193 andreas 8941
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8942
 
8943
    if (TError::isError() || map.empty())
8944
        return;
8945
 
8946
    vector<Button::TButton *> buttons = collectButtons(map);
8947
 
83 andreas 8948
    if (buttons.size() > 0)
16 andreas 8949
    {
83 andreas 8950
        vector<Button::TButton *>::iterator mapIter;
8951
 
8952
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8953
        {
8954
            Button::TButton *bt = *mapIter;
252 andreas 8955
//            setButtonCallbacks(bt);
83 andreas 8956
            bt->clearPushFunction(action);
8957
        }
16 andreas 8958
    }
8959
}
8960
 
8961
/**
8962
 * Enable or disable buttons with a set variable text range.
8963
 */
8964
void TPageManager::doENA(int port, vector<int>& channels, vector<string>& pars)
8965
{
8966
    DECL_TRACER("TPageManager::doENA(int port, vector<int>& channels, vector<string>& pars)");
8967
 
8968
    if (pars.empty())
8969
    {
8970
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
341 andreas 8971
#if TESTMODE == 1
8972
        setAllDone();
8973
#endif
16 andreas 8974
        return;
8975
    }
8976
 
8977
    TError::clear();
8978
    int cvalue = atoi(pars[0].c_str());
8979
 
193 andreas 8980
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8981
 
8982
    if (TError::isError() || map.empty())
341 andreas 8983
    {
8984
#if TESTMODE == 1
8985
        setAllDone();
8986
#endif
16 andreas 8987
        return;
341 andreas 8988
    }
16 andreas 8989
 
8990
    vector<Button::TButton *> buttons = collectButtons(map);
8991
 
83 andreas 8992
    if (buttons.size() > 0)
16 andreas 8993
    {
83 andreas 8994
        vector<Button::TButton *>::iterator mapIter;
8995
 
8996
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8997
        {
8998
            Button::TButton *bt = *mapIter;
8999
            bt->setEnable(((cvalue)?true:false));
341 andreas 9000
#if TESTMODE == 1
9001
            __success = true;
9002
 
9003
            if (_gTestMode)
9004
                _gTestMode->setResult(intToString(cvalue));
9005
#endif
83 andreas 9006
        }
16 andreas 9007
    }
341 andreas 9008
#if TESTMODE == 1
9009
    setAllDone();
9010
#endif
16 andreas 9011
}
9012
 
9013
/**
9014
 * Set a font to a specific Font ID value for those buttons with a defined
9015
 * address range. Font ID numbers are generated by the TPDesign4 programmers
9016
 * report.
9017
 */
9018
void TPageManager::doFON(int port, vector<int>& channels, vector<string>& pars)
9019
{
9020
    DECL_TRACER("TPageManager::doFON(int port, vector<int>& channels, vector<string>& pars)");
9021
 
9022
    if (pars.size() < 2)
9023
    {
9024
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
342 andreas 9025
#if TESTMODE == 1
9026
        setAllDone();
9027
#endif
16 andreas 9028
        return;
9029
    }
9030
 
9031
    TError::clear();
342 andreas 9032
    int btState = atoi(pars[0].c_str()) - 1;
16 andreas 9033
    int fvalue = atoi(pars[1].c_str());
9034
 
193 andreas 9035
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 9036
 
9037
    if (TError::isError() || map.empty())
9038
        return;
9039
 
9040
    vector<Button::TButton *> buttons = collectButtons(map);
9041
 
83 andreas 9042
    if (buttons.size() > 0)
16 andreas 9043
    {
83 andreas 9044
        vector<Button::TButton *>::iterator mapIter;
16 andreas 9045
 
83 andreas 9046
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
16 andreas 9047
        {
83 andreas 9048
            Button::TButton *bt = *mapIter;
342 andreas 9049
            bt->setFont(fvalue, btState);
9050
#if TESTMODE == 1
9051
            if (_gTestMode)
9052
                _gTestMode->setResult(intToString(bt->getFontIndex(btState < 0 ? 0 : btState)));
9053
#endif
16 andreas 9054
        }
9055
    }
342 andreas 9056
#if TESTMODE == 1
9057
    setDone();
9058
#endif
16 andreas 9059
}
9060
 
108 andreas 9061
void TPageManager::getFON(int port, vector<int>& channels, vector<string>& pars)
9062
{
9063
    DECL_TRACER("TPageManager::getFON(int port, vector<int>& channels, vector<string>& pars)");
9064
 
9065
    if (pars.size() < 1)
9066
    {
9067
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
342 andreas 9068
#if TESTMODE == 1
9069
        setAllDone();
9070
#endif
108 andreas 9071
        return;
9072
    }
9073
 
9074
    TError::clear();
9075
    int btState = atoi(pars[0].c_str());
9076
 
193 andreas 9077
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9078
 
9079
    if (TError::isError() || map.empty())
342 andreas 9080
    {
9081
#if TESTMODE == 1
9082
        setAllDone();
9083
#endif
108 andreas 9084
        return;
342 andreas 9085
    }
108 andreas 9086
 
9087
    vector<Button::TButton *> buttons = collectButtons(map);
9088
 
9089
    if (buttons.size() > 0)
9090
    {
110 andreas 9091
        Button::TButton *bt = buttons[0];
108 andreas 9092
 
110 andreas 9093
        if (btState == 0)       // All instances?
108 andreas 9094
        {
110 andreas 9095
            int bst = bt->getNumberInstances();
108 andreas 9096
 
110 andreas 9097
            for (int i = 0; i < bst; i++)
9098
                sendCustomEvent(i + 1, bt->getFontIndex(i), 0, "", 1007, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9099
        }
110 andreas 9100
        else
9101
            sendCustomEvent(btState, bt->getFontIndex(btState - 1), 0, "", 1007, bt->getChannelPort(), bt->getChannelNumber());
342 andreas 9102
#if TESTMODE == 1
9103
        if (_gTestMode)
9104
            _gTestMode->setResult(intToString(bt->getFontIndex(btState < 0 ? 0 : btState)));
9105
#endif
108 andreas 9106
    }
342 andreas 9107
#if TESTMODE == 1
9108
    __success = true;
9109
    setAllDone();
9110
#endif
108 andreas 9111
}
9112
 
388 andreas 9113
void TPageManager::doGDI(int port, vector<int>& channels, vector<std::string>& pars)
9114
{
9115
    DECL_TRACER("TPageManager::doGDI(int port, vector<int>& channels, vector<std::string>& pars)");
9116
 
9117
    if (pars.size() < 1)
9118
    {
9119
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9120
        return;
9121
    }
9122
 
9123
    TError::clear();
9124
    int inc = atoi(pars[0].c_str());
9125
 
9126
    if (inc < 0)
9127
    {
9128
        MSG_ERROR("Invalid drag increment of " << inc << "!");
9129
        return;
9130
    }
9131
 
9132
    vector<TMap::MAP_T> map = findButtons(port, channels);
9133
 
9134
    if (TError::isError() || map.empty())
9135
        return;
9136
 
9137
    vector<Button::TButton *> buttons = collectButtons(map);
9138
 
9139
    if (buttons.size() > 0)
9140
    {
9141
        vector<Button::TButton *>::iterator mapIter;
9142
 
9143
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9144
        {
9145
            Button::TButton *bt = *mapIter;
9146
            bt->setBargraphDragIncrement(inc);
9147
        }
9148
    }
9149
}
9150
/* Currently not implemented
9151
void TPageManager::doGDV(int port, vector<int>& channels, vector<std::string>& pars)
9152
{
9153
    DECL_TRACER("TPageManager::doGDV(int port, vector<int>& channels, vector<std::string>& pars)");
9154
}
9155
*/
16 andreas 9156
/**
60 andreas 9157
 * Change the bargraph upper limit.
9158
 */
9159
void TPageManager::doGLH(int port, vector<int>& channels, vector<std::string>& pars)
9160
{
9161
    DECL_TRACER("TPageManager::doGLH(int port, vector<int>& channels, vector<std::string>& pars)");
9162
 
9163
    if (pars.size() < 1)
9164
    {
9165
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9166
        return;
9167
    }
9168
 
9169
    TError::clear();
9170
    int limit = atoi(pars[0].c_str());
9171
 
9172
    if (limit < 1)
9173
    {
9174
        MSG_ERROR("Invalid upper limit " << limit << "!");
9175
        return;
9176
    }
9177
 
193 andreas 9178
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 9179
 
9180
    if (TError::isError() || map.empty())
9181
        return;
9182
 
9183
    vector<Button::TButton *> buttons = collectButtons(map);
9184
 
83 andreas 9185
    if (buttons.size() > 0)
60 andreas 9186
    {
83 andreas 9187
        vector<Button::TButton *>::iterator mapIter;
9188
 
9189
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9190
        {
9191
            Button::TButton *bt = *mapIter;
252 andreas 9192
//            setButtonCallbacks(bt);
83 andreas 9193
            bt->setBargraphUpperLimit(limit);
9194
        }
60 andreas 9195
    }
9196
}
9197
 
9198
/**
9199
 * Change the bargraph lower limit.
9200
 */
9201
void TPageManager::doGLL(int port, vector<int>& channels, vector<std::string>& pars)
9202
{
9203
    DECL_TRACER("TPageManager::doGLL(int port, vector<int>& channels, vector<std::string>& pars)");
9204
 
9205
    if (pars.size() < 1)
9206
    {
9207
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9208
        return;
9209
    }
9210
 
9211
    TError::clear();
9212
    int limit = atoi(pars[0].c_str());
9213
 
9214
    if (limit < 1)
9215
    {
9216
        MSG_ERROR("Invalid lower limit " << limit << "!");
9217
        return;
9218
    }
9219
 
193 andreas 9220
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 9221
 
9222
    if (TError::isError() || map.empty())
9223
        return;
9224
 
9225
    vector<Button::TButton *> buttons = collectButtons(map);
9226
 
83 andreas 9227
    if (buttons.size() > 0)
60 andreas 9228
    {
83 andreas 9229
        vector<Button::TButton *>::iterator mapIter;
9230
 
9231
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9232
        {
9233
            Button::TButton *bt = *mapIter;
252 andreas 9234
//            setButtonCallbacks(bt);
83 andreas 9235
            bt->setBargraphLowerLimit(limit);
9236
        }
60 andreas 9237
    }
9238
}
9239
 
108 andreas 9240
void TPageManager::doGSC(int port, vector<int>& channels, vector<string>& pars)
9241
{
9242
    DECL_TRACER("TPageManager::doGSC(int port, vector<int>& channels, vector<string>& pars)");
9243
 
9244
    if (pars.size() < 1)
9245
    {
9246
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9247
        return;
9248
    }
9249
 
9250
    TError::clear();
9251
    string color = pars[0];
193 andreas 9252
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9253
 
9254
    if (TError::isError() || map.empty())
9255
        return;
9256
 
9257
    vector<Button::TButton *> buttons = collectButtons(map);
9258
 
9259
    if (buttons.size() > 0)
9260
    {
9261
        vector<Button::TButton *>::iterator mapIter;
9262
 
9263
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9264
        {
9265
            Button::TButton *bt = *mapIter;
9266
            bt->setBargraphSliderColor(color);
9267
        }
9268
    }
9269
}
9270
 
361 andreas 9271
/*
388 andreas 9272
 * Set bargraph ramp down time in 1/10 seconds.
9273
 */
9274
void TPageManager::doGRD(int port, vector<int>& channels, vector<string>& pars)
9275
{
9276
    DECL_TRACER("TPageManager::doGRD(int port, vector<int>& channels, vector<string>& pars)");
9277
 
9278
    if (pars.size() < 1)
9279
    {
9280
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9281
        return;
9282
    }
9283
 
9284
    TError::clear();
9285
    int t = atoi(pars[0].c_str());
9286
 
9287
    if (t < 0)
9288
    {
9289
        MSG_ERROR("Invalid ramp down time limit " << t << "!");
9290
        return;
9291
    }
9292
 
9293
    vector<TMap::MAP_T> map = findButtons(port, channels);
9294
 
9295
    if (TError::isError() || map.empty())
9296
        return;
9297
 
9298
    vector<Button::TButton *> buttons = collectButtons(map);
9299
 
9300
    if (buttons.size() > 0)
9301
    {
9302
        vector<Button::TButton *>::iterator mapIter;
9303
 
9304
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9305
        {
9306
            Button::TButton *bt = *mapIter;
9307
            bt->setBargraphRampDownTime(t);
9308
        }
9309
    }
9310
}
9311
 
9312
/*
9313
 * Set bargraph ramp up time in 1/10 seconds.
9314
 */
9315
void TPageManager::doGRU(int port, vector<int>& channels, vector<string>& pars)
9316
{
9317
    DECL_TRACER("TPageManager::doGRU(int port, vector<int>& channels, vector<string>& pars)");
9318
 
9319
    if (pars.size() < 1)
9320
    {
9321
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9322
        return;
9323
    }
9324
 
9325
    TError::clear();
9326
    int t = atoi(pars[0].c_str());
9327
 
9328
    if (t < 0)
9329
    {
9330
        MSG_ERROR("Invalid ramp up time limit " << t << "!");
9331
        return;
9332
    }
9333
 
9334
    vector<TMap::MAP_T> map = findButtons(port, channels);
9335
 
9336
    if (TError::isError() || map.empty())
9337
        return;
9338
 
9339
    vector<Button::TButton *> buttons = collectButtons(map);
9340
 
9341
    if (buttons.size() > 0)
9342
    {
9343
        vector<Button::TButton *>::iterator mapIter;
9344
 
9345
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9346
        {
9347
            Button::TButton *bt = *mapIter;
9348
            bt->setBargraphRampUpTime(t);
9349
        }
9350
    }
9351
}
9352
 
9353
/*
361 andreas 9354
 * Change the bargraph slider name or joystick cursor name.
9355
 */
9356
void TPageManager::doGSN(int port, vector<int>& channels, vector<string>& pars)
9357
{
9358
    DECL_TRACER("TPageManager::doGSN(int port, vector<int>& channels, vector<string>& pars)");
9359
 
9360
    if (pars.size() < 1)
9361
    {
9362
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9363
        return;
9364
    }
9365
 
9366
    TError::clear();
9367
    string name = pars[0];
9368
    vector<TMap::MAP_T> map = findButtons(port, channels);
9369
 
9370
    if (TError::isError() || map.empty())
9371
        return;
9372
 
9373
    vector<Button::TButton *> buttons = collectButtons(map);
9374
 
9375
    if (buttons.size() > 0)
9376
    {
9377
        vector<Button::TButton *>::iterator mapIter;
9378
 
9379
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9380
        {
9381
            Button::TButton *bt = *mapIter;
9382
            bt->setBargraphSliderName(name);
9383
        }
9384
    }
9385
}
9386
 
60 andreas 9387
/**
14 andreas 9388
 * Set the icon to a button.
9389
 */
9390
void TPageManager::doICO(int port, vector<int>& channels, vector<string>& pars)
9391
{
9392
    DECL_TRACER("TPageManager::doICO(int port, vector<int>& channels, vector<string>& pars)");
9393
 
9394
    if (pars.size() < 2)
9395
    {
9396
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
9397
        return;
9398
    }
9399
 
16 andreas 9400
    TError::clear();
14 andreas 9401
    int btState = atoi(pars[0].c_str());
9402
    int iconIdx = atoi(pars[1].c_str());
9403
 
193 andreas 9404
    vector<TMap::MAP_T> map = findButtons(port, channels);
14 andreas 9405
 
9406
    if (TError::isError() || map.empty())
9407
        return;
9408
 
9409
    vector<Button::TButton *> buttons = collectButtons(map);
9410
 
83 andreas 9411
    if (buttons.size() > 0)
14 andreas 9412
    {
83 andreas 9413
        vector<Button::TButton *>::iterator mapIter;
14 andreas 9414
 
83 andreas 9415
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
14 andreas 9416
        {
83 andreas 9417
            Button::TButton *bt = *mapIter;
14 andreas 9418
 
83 andreas 9419
            if (btState == 0)       // All instances?
14 andreas 9420
            {
316 andreas 9421
                if (iconIdx > 0)
9422
                    bt->setIcon(iconIdx, -1);
9423
                else
9424
                    bt->revokeIcon(-1);
14 andreas 9425
            }
83 andreas 9426
            else if (iconIdx > 0)
9427
                bt->setIcon(iconIdx, btState - 1);
9428
            else
9429
                bt->revokeIcon(btState - 1);
14 andreas 9430
        }
9431
    }
9432
}
9433
 
108 andreas 9434
void TPageManager::getICO(int port, vector<int>& channels, vector<string>& pars)
9435
{
9436
    DECL_TRACER("TPageManager::getICO(int port, vector<int>& channels, vector<string>& pars)");
9437
 
9438
    if (pars.size() < 1)
9439
    {
9440
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9441
        return;
9442
    }
9443
 
9444
    TError::clear();
9445
    int btState = atoi(pars[0].c_str());
9446
 
193 andreas 9447
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9448
 
9449
    if (TError::isError() || map.empty())
9450
        return;
9451
 
9452
    vector<Button::TButton *> buttons = collectButtons(map);
9453
 
9454
    if (buttons.size() > 0)
9455
    {
110 andreas 9456
        Button::TButton *bt = buttons[0];
108 andreas 9457
 
110 andreas 9458
        if (btState == 0)       // All instances?
108 andreas 9459
        {
110 andreas 9460
            int bst = bt->getNumberInstances();
108 andreas 9461
 
110 andreas 9462
            for (int i = 0; i < bst; i++)
9463
                sendCustomEvent(i + 1, bt->getIconIndex(i), 0, "", 1003, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9464
        }
110 andreas 9465
        else
9466
            sendCustomEvent(btState, bt->getIconIndex(btState - 1), 0, "", 1003, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9467
    }
9468
}
9469
 
14 andreas 9470
/**
108 andreas 9471
 * Set bitmap/picture alignment using a numeric keypad layout for those buttons
9472
 * with a defined address range. The alignment of 0 is followed by
9473
 * ',<left>,<top>'. The left and top coordinates are relative to the upper left
9474
 * corner of the button.
9475
 */
9476
void TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)
9477
{
9478
    DECL_TRACER("TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)");
9479
 
9480
    if (pars.size() < 2)
9481
    {
9482
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
9483
        return;
9484
    }
9485
 
9486
    TError::clear();
9487
    int btState = atoi(pars[0].c_str());
9488
    int align = atoi(pars[1].c_str());
9489
    int x = 0, y = 0;
9490
 
9491
    if (!align && pars.size() >= 3)
9492
    {
9493
        x = atoi(pars[2].c_str());
9494
 
9495
        if (pars.size() >= 4)
9496
            y = atoi(pars[3].c_str());
9497
    }
9498
 
193 andreas 9499
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9500
 
9501
    if (TError::isError() || map.empty())
9502
        return;
9503
 
9504
    vector<Button::TButton *> buttons = collectButtons(map);
9505
 
9506
    if (buttons.size() > 0)
9507
    {
9508
        vector<Button::TButton *>::iterator mapIter;
9509
 
9510
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9511
        {
9512
            Button::TButton *bt = *mapIter;
9513
 
9514
            if (btState == 0)
9515
                bt->setBitmapJustification(align, x, y, -1);
9516
            else
9517
                bt->setBitmapJustification(align, x, y, btState-1);
9518
        }
9519
    }
9520
}
9521
 
9522
void TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)
9523
{
9524
    DECL_TRACER("TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)");
9525
 
9526
    if (pars.size() < 1)
9527
    {
9528
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9529
        return;
9530
    }
9531
 
9532
    TError::clear();
9533
    int btState = atoi(pars[0].c_str());
9534
    int j, x, y;
9535
 
193 andreas 9536
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9537
 
9538
    if (TError::isError() || map.empty())
9539
        return;
9540
 
9541
    vector<Button::TButton *> buttons = collectButtons(map);
9542
 
9543
    if (buttons.size() > 0)
9544
    {
110 andreas 9545
        Button::TButton *bt = buttons[0];
108 andreas 9546
 
110 andreas 9547
        if (btState == 0)       // All instances?
108 andreas 9548
        {
110 andreas 9549
            int bst = bt->getNumberInstances();
108 andreas 9550
 
110 andreas 9551
            for (int i = 0; i < bst; i++)
108 andreas 9552
            {
110 andreas 9553
                j = bt->getBitmapJustification(&x, &y, i);
9554
                sendCustomEvent(i + 1, j, 0, "", 1005, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9555
            }
9556
        }
110 andreas 9557
        else
9558
        {
9559
            j = bt->getBitmapJustification(&x, &y, btState-1);
9560
            sendCustomEvent(btState, j, 0, "", 1005, bt->getChannelPort(), bt->getChannelNumber());
9561
        }
108 andreas 9562
    }
9563
}
9564
 
9565
/**
9566
 * Set icon alignment using a numeric keypad layout for those buttons with a
9567
 * defined address range. The alignment of 0 is followed by ',<left>,<top>'.
9568
 * The left and top coordinates are relative to the upper left corner of the
9569
 * button.
9570
 */
9571
void TPageManager::doJSI(int port, vector<int>& channels, vector<string>& pars)
9572
{
9573
    DECL_TRACER("TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)");
9574
 
9575
    if (pars.size() < 2)
9576
    {
9577
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
9578
        return;
9579
    }
9580
 
9581
    TError::clear();
9582
    int btState = atoi(pars[0].c_str());
9583
    int align = atoi(pars[1].c_str());
9584
    int x = 0, y = 0;
9585
 
9586
    if (!align && pars.size() >= 3)
9587
    {
9588
        x = atoi(pars[2].c_str());
9589
 
9590
        if (pars.size() >= 4)
9591
            y = atoi(pars[3].c_str());
9592
    }
9593
 
193 andreas 9594
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9595
 
9596
    if (TError::isError() || map.empty())
9597
        return;
9598
 
9599
    vector<Button::TButton *> buttons = collectButtons(map);
9600
 
9601
    if (buttons.size() > 0)
9602
    {
9603
        vector<Button::TButton *>::iterator mapIter;
9604
 
9605
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9606
        {
9607
            Button::TButton *bt = *mapIter;
9608
 
9609
            if (btState == 0)
9610
                bt->setIconJustification(align, x, y, -1);
9611
            else
9612
                bt->setIconJustification(align, x, y, btState-1);
9613
        }
9614
    }
9615
}
9616
 
9617
void TPageManager::getJSI(int port, vector<int>& channels, vector<string>& pars)
9618
{
9619
    DECL_TRACER("TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)");
9620
 
9621
    if (pars.size() < 1)
9622
    {
9623
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9624
        return;
9625
    }
9626
 
9627
    TError::clear();
9628
    int btState = atoi(pars[0].c_str());
9629
    int j, x, y;
9630
 
193 andreas 9631
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9632
 
9633
    if (TError::isError() || map.empty())
9634
        return;
9635
 
9636
    vector<Button::TButton *> buttons = collectButtons(map);
9637
 
9638
    if (buttons.size() > 0)
9639
    {
110 andreas 9640
        Button::TButton *bt = buttons[0];
108 andreas 9641
 
110 andreas 9642
        if (btState == 0)       // All instances?
108 andreas 9643
        {
110 andreas 9644
            int bst = bt->getNumberInstances();
108 andreas 9645
 
110 andreas 9646
            for (int i = 0; i < bst; i++)
108 andreas 9647
            {
110 andreas 9648
                j = bt->getIconJustification(&x, &y, i);
9649
                sendCustomEvent(i + 1, j, 0, "", 1006, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9650
            }
9651
        }
110 andreas 9652
        else
9653
        {
9654
            j = bt->getIconJustification(&x, &y, btState-1);
9655
            sendCustomEvent(btState, j, 0, "", 1006, bt->getChannelPort(), bt->getChannelNumber());
9656
        }
108 andreas 9657
    }
9658
}
9659
 
9660
void TPageManager::doJST(int port, vector<int>& channels, vector<string>& pars)
9661
{
9662
    DECL_TRACER("TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)");
9663
 
9664
    if (pars.size() < 2)
9665
    {
9666
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
9667
        return;
9668
    }
9669
 
9670
    TError::clear();
9671
    int btState = atoi(pars[0].c_str());
9672
    int align = atoi(pars[1].c_str());
9673
    int x = 0, y = 0;
9674
 
9675
    if (!align && pars.size() >= 3)
9676
    {
9677
        x = atoi(pars[2].c_str());
9678
 
9679
        if (pars.size() >= 4)
9680
            y = atoi(pars[3].c_str());
9681
    }
9682
 
193 andreas 9683
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9684
 
9685
    if (TError::isError() || map.empty())
9686
        return;
9687
 
9688
    vector<Button::TButton *> buttons = collectButtons(map);
9689
 
9690
    if (buttons.size() > 0)
9691
    {
9692
        vector<Button::TButton *>::iterator mapIter;
9693
 
9694
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9695
        {
9696
            Button::TButton *bt = *mapIter;
9697
 
9698
            if (btState == 0)
9699
                bt->setTextJustification(align, x, y, -1);
9700
            else
9701
                bt->setTextJustification(align, x, y, btState-1);
9702
        }
9703
    }
9704
}
9705
 
9706
void TPageManager::getJST(int port, vector<int>& channels, vector<string>& pars)
9707
{
9708
    DECL_TRACER("TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)");
9709
 
9710
    if (pars.size() < 1)
9711
    {
9712
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9713
        return;
9714
    }
9715
 
9716
    TError::clear();
9717
    int btState = atoi(pars[0].c_str());
9718
    int j, x, y;
9719
 
193 andreas 9720
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9721
 
9722
    if (TError::isError() || map.empty())
9723
        return;
9724
 
9725
    vector<Button::TButton *> buttons = collectButtons(map);
9726
 
9727
    if (buttons.size() > 0)
9728
    {
110 andreas 9729
        Button::TButton *bt = buttons[0];
108 andreas 9730
 
110 andreas 9731
        if (btState == 0)       // All instances?
108 andreas 9732
        {
110 andreas 9733
            int bst = bt->getNumberInstances();
108 andreas 9734
 
110 andreas 9735
            for (int i = 0; i < bst; i++)
108 andreas 9736
            {
110 andreas 9737
                j = bt->getTextJustification(&x, &y, i);
9738
                sendCustomEvent(i + 1, j, 0, "", 1004, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9739
            }
9740
        }
110 andreas 9741
        else
9742
        {
9743
            j = bt->getTextJustification(&x, &y, btState-1);
9744
            sendCustomEvent(btState, j, 0, "", 1004, bt->getChannelPort(), bt->getChannelNumber());
9745
        }
108 andreas 9746
    }
9747
}
9748
 
9749
/**
16 andreas 9750
 * Show or hide a button with a set variable text range.
9751
 */
9752
void TPageManager::doSHO(int port, vector<int>& channels, vector<string>& pars)
9753
{
9754
    DECL_TRACER("TPageManager::doSHO(int port, vector<int>& channels, vector<string>& pars)");
9755
 
9756
    if (pars.empty())
9757
    {
9758
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
9759
        return;
9760
    }
9761
 
9762
    TError::clear();
9763
    int cvalue = atoi(pars[0].c_str());
9764
 
193 andreas 9765
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 9766
 
9767
    if (TError::isError() || map.empty())
9768
        return;
9769
 
9770
    vector<Button::TButton *> buttons = collectButtons(map);
9771
 
83 andreas 9772
    if (buttons.size() > 0)
16 andreas 9773
    {
83 andreas 9774
        vector<Button::TButton *>::iterator mapIter;
9775
 
9776
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9777
        {
9778
            Button::TButton *bt = *mapIter;
318 andreas 9779
 
100 andreas 9780
            int pgID = (bt->getParent() >> 16) & 0x0000ffff;
9781
            bool pVisible = false;
9782
 
9783
            if (pgID < 500)
9784
            {
9785
                TPage *pg = getPage(pgID);
9786
 
9787
                if (pg && pg->isVisilble())
9788
                    pVisible = true;
9789
            }
9790
            else
9791
            {
9792
                TSubPage *pg = getSubPage(pgID);
9793
 
9794
                if (pg && pg->isVisible())
9795
                    pVisible = true;
9796
            }
9797
 
151 andreas 9798
            bool oldV = bt->isVisible();
9799
            bool visible = cvalue ? true : false;
9800
            MSG_DEBUG("Button " << bt->getButtonIndex() << ", \"" << bt->getButtonName() << "\" set " << (visible ? "VISIBLE" : "HIDDEN") << " (Previous: " << (oldV ? "VISIBLE" : "HIDDEN") << ")");
98 andreas 9801
 
151 andreas 9802
            if (visible != oldV)
100 andreas 9803
            {
151 andreas 9804
                bt->setVisible(visible);
100 andreas 9805
 
151 andreas 9806
                if (pVisible)
9807
                {
9808
                    setButtonCallbacks(bt);
9809
 
9810
                    if (_setVisible)
9811
                        _setVisible(bt->getHandle(), visible);
9812
                    else
9813
                        bt->refresh();
9814
                }
100 andreas 9815
            }
83 andreas 9816
        }
16 andreas 9817
    }
9818
}
9819
 
108 andreas 9820
void TPageManager::doTEC(int port, vector<int>& channels, vector<string>& pars)
9821
{
9822
    DECL_TRACER("TPageManager::doTEC(int port, vector<int>& channels, vector<string>& pars)");
9823
 
9824
    if (pars.size() < 2)
9825
    {
9826
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
9827
        return;
9828
    }
9829
 
9830
    TError::clear();
9831
    int btState = atoi(pars[0].c_str());
9832
    string color = pars[1];
9833
 
193 andreas 9834
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9835
 
9836
    if (TError::isError() || map.empty())
9837
        return;
9838
 
9839
    vector<Button::TButton *> buttons = collectButtons(map);
9840
 
9841
    if (buttons.size() > 0)
9842
    {
9843
        vector<Button::TButton *>::iterator mapIter;
9844
 
9845
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9846
        {
9847
            Button::TButton *bt = *mapIter;
9848
 
9849
            if (btState == 0)
9850
                bt->setTextEffectColor(color);
9851
            else
9852
                bt->setTextEffectColor(color, btState-1);
9853
        }
9854
    }
9855
}
9856
 
9857
void TPageManager::getTEC(int port, vector<int>& channels, vector<string>& pars)
9858
{
9859
    DECL_TRACER("TPageManager::getTEC(int port, vector<int>& channels, vector<string>& pars)");
9860
 
9861
    if (pars.size() < 1)
9862
    {
9863
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9864
        return;
9865
    }
9866
 
9867
    TError::clear();
9868
    int btState = atoi(pars[0].c_str());
9869
 
193 andreas 9870
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9871
 
9872
    if (TError::isError() || map.empty())
9873
        return;
9874
 
9875
    vector<Button::TButton *> buttons = collectButtons(map);
9876
 
9877
    if (buttons.size() > 0)
9878
    {
110 andreas 9879
        Button::TButton *bt = buttons[0];
9880
 
9881
        if (btState == 0)       // All instances?
9882
        {
9883
            int bst = bt->getNumberInstances();
9884
 
9885
            for (int i = 0; i < bst; i++)
9886
            {
9887
                string c = bt->getTextEffectColor(i);
300 andreas 9888
                sendCustomEvent(i + 1, (int)c.length(), 0, c, 1009, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 9889
            }
9890
        }
9891
        else
9892
        {
9893
            string c = bt->getTextEffectColor(btState-1);
300 andreas 9894
            sendCustomEvent(btState, (int)c.length(), 0, c, 1009, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 9895
        }
9896
    }
9897
}
9898
 
9899
void TPageManager::doTEF(int port, vector<int>& channels, vector<string>& pars)
9900
{
9901
    DECL_TRACER("TPageManager::doTEF(int port, vector<int>& channels, vector<string>& pars)");
9902
 
9903
    if (pars.size() < 2)
9904
    {
9905
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
9906
        return;
9907
    }
9908
 
9909
    TError::clear();
9910
    int btState = atoi(pars[0].c_str());
9911
    string tef = pars[1];
9912
 
193 andreas 9913
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 9914
 
9915
    if (TError::isError() || map.empty())
9916
        return;
9917
 
9918
    vector<Button::TButton *> buttons = collectButtons(map);
9919
 
9920
    if (buttons.size() > 0)
9921
    {
108 andreas 9922
        vector<Button::TButton *>::iterator mapIter;
9923
 
9924
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9925
        {
9926
            Button::TButton *bt = *mapIter;
9927
 
110 andreas 9928
            if (btState == 0)
9929
                bt->setTextEffectName(tef);
9930
            else
9931
                bt->setTextEffectName(tef, btState-1);
9932
        }
9933
    }
9934
}
108 andreas 9935
 
110 andreas 9936
void TPageManager::getTEF(int port, vector<int>& channels, vector<string>& pars)
9937
{
9938
    DECL_TRACER("TPageManager::getTEF(int port, vector<int>& channels, vector<string>& pars)");
108 andreas 9939
 
110 andreas 9940
    if (pars.size() < 1)
9941
    {
9942
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9943
        return;
9944
    }
108 andreas 9945
 
110 andreas 9946
    TError::clear();
9947
    int btState = atoi(pars[0].c_str());
9948
 
193 andreas 9949
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 9950
 
9951
    if (TError::isError() || map.empty())
9952
        return;
9953
 
9954
    vector<Button::TButton *> buttons = collectButtons(map);
9955
 
9956
    if (buttons.size() > 0)
9957
    {
9958
        Button::TButton *bt = buttons[0];
9959
 
9960
        if (btState == 0)       // All instances?
9961
        {
9962
            int bst = bt->getNumberInstances();
9963
 
9964
            for (int i = 0; i < bst; i++)
108 andreas 9965
            {
110 andreas 9966
                string c = bt->getTextEffectName(i);
300 andreas 9967
                sendCustomEvent(i + 1, (int)c.length(), 0, c, 1008, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9968
            }
9969
        }
110 andreas 9970
        else
9971
        {
9972
            string c = bt->getTextEffectName(btState-1);
300 andreas 9973
            sendCustomEvent(btState, (int)c.length(), 0, c, 1008, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 9974
        }
108 andreas 9975
    }
9976
}
9977
 
16 andreas 9978
/**
14 andreas 9979
 * Assign a text string to those buttons with a defined address range.
9980
 * Sets Non-Unicode text.
9981
 */
9982
void TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)
9983
{
9984
    DECL_TRACER("TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)");
9985
 
9986
    if (pars.size() < 1)
9987
    {
9988
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
331 andreas 9989
#if TESTMODE == 1
334 andreas 9990
        setAllDone();
331 andreas 9991
#endif
14 andreas 9992
        return;
9993
    }
9994
 
16 andreas 9995
    TError::clear();
333 andreas 9996
    int btState = atoi(pars[0].c_str()) - 1;
14 andreas 9997
    string text;
9998
 
333 andreas 9999
    // Every comma (,) in the text produces a new parameter. Therefor we must
10000
    // concatenate this parameters together and insert the comma.
14 andreas 10001
    if (pars.size() > 1)
150 andreas 10002
    {
10003
        for (size_t i = 1; i < pars.size(); ++i)
10004
        {
10005
            if (i > 1)
10006
                text += ",";
14 andreas 10007
 
150 andreas 10008
            text += pars[i];
10009
        }
10010
    }
10011
 
193 andreas 10012
    vector<TMap::MAP_T> map = findButtons(port, channels);
14 andreas 10013
 
10014
    if (TError::isError() || map.empty())
331 andreas 10015
    {
10016
#if TESTMODE == 1
334 andreas 10017
        setAllDone();
331 andreas 10018
#endif
14 andreas 10019
        return;
331 andreas 10020
    }
14 andreas 10021
 
10022
    vector<Button::TButton *> buttons = collectButtons(map);
10023
 
83 andreas 10024
    if (buttons.size() > 0)
14 andreas 10025
    {
83 andreas 10026
        vector<Button::TButton *>::iterator mapIter;
14 andreas 10027
 
333 andreas 10028
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
14 andreas 10029
        {
83 andreas 10030
            Button::TButton *bt = *mapIter;
14 andreas 10031
 
252 andreas 10032
            if (!bt)
333 andreas 10033
                continue;
252 andreas 10034
 
333 andreas 10035
            bt->setText(text, btState);
331 andreas 10036
#if TESTMODE == 1
333 andreas 10037
            if (_gTestMode)
10038
                _gTestMode->setResult(bt->getText(btState < 0 ? 0 : btState));
331 andreas 10039
 
333 andreas 10040
            __success = true;
331 andreas 10041
#endif
14 andreas 10042
        }
10043
    }
331 andreas 10044
#if TESTMODE == 1
334 andreas 10045
    setDone();
331 andreas 10046
#endif
14 andreas 10047
}
21 andreas 10048
 
110 andreas 10049
void TPageManager::getTXT(int port, vector<int>& channels, vector<string>& pars)
10050
{
10051
    DECL_TRACER("TPageManager::getTXT(int port, vector<int>& channels, vector<string>& pars)");
10052
 
10053
    if (pars.size() < 1)
10054
    {
10055
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
10056
        return;
10057
    }
10058
 
10059
    TError::clear();
10060
    int btState = atoi(pars[0].c_str());
10061
 
193 andreas 10062
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 10063
 
10064
    if (TError::isError() || map.empty())
10065
        return;
10066
 
10067
    vector<Button::TButton *> buttons = collectButtons(map);
10068
 
10069
    if (buttons.size() > 0)
10070
    {
10071
        Button::TButton *bt = buttons[0];
10072
 
10073
        if (btState == 0)       // All instances?
10074
        {
10075
            int bst = bt->getNumberInstances();
10076
 
10077
            for (int i = 0; i < bst; i++)
10078
            {
10079
                string c = bt->getText(i);
300 andreas 10080
                sendCustomEvent(i + 1, (int)c.length(), 0, c, 1001, bt->getChannelPort(), bt->getChannelNumber());
333 andreas 10081
#if TESTMODE == 1
10082
                if (_gTestMode)
10083
                    _gTestMode->setResult(c);
10084
#endif
110 andreas 10085
            }
10086
        }
10087
        else
10088
        {
10089
            string c = bt->getText(btState-1);
300 andreas 10090
            sendCustomEvent(btState, (int)c.length(), 0, c, 1001, bt->getChannelPort(), bt->getChannelNumber());
333 andreas 10091
#if TESTMODE == 1
10092
            if (_gTestMode)
10093
                _gTestMode->setResult(c);
10094
#endif
110 andreas 10095
        }
10096
    }
334 andreas 10097
#if TESTMODE == 1
10098
    setAllDone();
10099
#endif
110 andreas 10100
}
10101
 
97 andreas 10102
/*
104 andreas 10103
 * Set button state legacy unicode text command.
10104
 *
10105
 * Set Unicode text in the legacy G4 format. For the ^UNI command, the Unicode
10106
 * text is sent as ASCII-HEX nibbles.
10107
 */
10108
void TPageManager::doUNI(int port, vector<int>& channels, vector<string>& pars)
10109
{
10110
    DECL_TRACER("TPageManager::doUNI(int port, vector<int>& channels, vector<string>& pars)");
10111
 
10112
    if (pars.size() < 1)
10113
    {
10114
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
331 andreas 10115
#if TESTMODE == 1
334 andreas 10116
        setAllDone();
331 andreas 10117
#endif
104 andreas 10118
        return;
10119
    }
10120
 
10121
    TError::clear();
333 andreas 10122
    int btState = atoi(pars[0].c_str()) - 1;
104 andreas 10123
    string text;
10124
 
361 andreas 10125
    // Unicode is the stadard character set used by Windows internally. It
10126
    // consists of 16 bit unsiged numbers. This can't be transported into a
10127
    // standard character string because a NULL byte means end of string.
10128
    // Therefor we must convert it to UFT-8.
104 andreas 10129
    if (pars.size() > 1)
10130
    {
10131
        string byte;
361 andreas 10132
        std::wstring uni;
104 andreas 10133
        size_t pos = 0;
10134
 
10135
        while (pos < pars[1].length())
10136
        {
361 andreas 10137
            byte = pars[1].substr(pos, 4);
10138
            wchar_t ch = (char)strtol(byte.c_str(), NULL, 16);
10139
            uni += ch;
10140
            pos += 4;
104 andreas 10141
        }
361 andreas 10142
 
10143
        text = UnicodeToUTF8(uni);
104 andreas 10144
    }
10145
 
193 andreas 10146
    vector<TMap::MAP_T> map = findButtons(port, channels);
104 andreas 10147
 
10148
    if (TError::isError() || map.empty())
331 andreas 10149
    {
10150
#if TESTMODE == 1
334 andreas 10151
        setAllDone();
331 andreas 10152
#endif
104 andreas 10153
        return;
331 andreas 10154
    }
104 andreas 10155
 
10156
    vector<Button::TButton *> buttons = collectButtons(map);
10157
 
10158
    if (buttons.size() > 0)
10159
    {
10160
        vector<Button::TButton *>::iterator mapIter;
10161
 
10162
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10163
        {
10164
            Button::TButton *bt = *mapIter;
10165
 
331 andreas 10166
#if TESTMODE == 1
333 andreas 10167
            bool res = bt->setText(text, btState);
104 andreas 10168
 
333 andreas 10169
            if (_gTestMode)
10170
                _gTestMode->setResult(bt->getText(btState < 0 ? 0 : btState));
331 andreas 10171
 
333 andreas 10172
            __success = res;
10173
#else
10174
            bt->setText(text, btState);
331 andreas 10175
#endif
104 andreas 10176
        }
10177
    }
334 andreas 10178
#if TESTMODE == 1
10179
    setDone();
10180
#endif
104 andreas 10181
}
10182
 
10183
void TPageManager::doUTF(int port, vector<int>& channels, vector<string>& pars)
10184
{
10185
    DECL_TRACER("TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)");
10186
 
10187
    if (pars.size() < 1)
10188
    {
10189
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
10190
        return;
10191
    }
10192
 
10193
    TError::clear();
10194
    int btState = atoi(pars[0].c_str());
10195
    string text;
10196
 
10197
    if (pars.size() > 1)
150 andreas 10198
    {
10199
        for (size_t i = 1; i < pars.size(); ++i)
10200
        {
10201
            if (i > 1)
10202
                text += ",";
104 andreas 10203
 
150 andreas 10204
            text += pars[i];
10205
        }
10206
    }
10207
 
193 andreas 10208
    vector<TMap::MAP_T> map = findButtons(port, channels);
104 andreas 10209
 
10210
    if (TError::isError() || map.empty())
10211
        return;
10212
 
10213
    vector<Button::TButton *> buttons = collectButtons(map);
10214
 
10215
    if (buttons.size() > 0)
10216
    {
10217
        vector<Button::TButton *>::iterator mapIter;
10218
 
10219
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10220
        {
10221
            Button::TButton *bt = *mapIter;
10222
 
10223
            if (btState == 0)       // All instances?
10224
            {
10225
                int bst = bt->getNumberInstances();
10226
 
10227
                for (int i = 0; i < bst; i++)
10228
                    bt->setText(text, i);
10229
            }
10230
            else
10231
                bt->setText(text, btState - 1);
10232
        }
10233
    }
10234
}
111 andreas 10235
 
361 andreas 10236
/**
10237
 * Simulates a touch/release/pulse at the given coordinate. If the push event
10238
 * is less then 0 or grater than 2 the command is ignored. It is also ignored
10239
 * if the x and y coordinate is out of range. The range must be between 0 and
10240
 * the maximum with and height.
10241
 */
148 andreas 10242
void TPageManager::doVTP (int, vector<int>&, vector<string>& pars)
10243
{
10244
    DECL_TRACER("TPageManager::doVTP (int, vector<int>&, vector<string>& pars)");
10245
 
10246
    if (pars.size() < 3)
10247
    {
10248
        MSG_ERROR("Expected 3 parameters but got only " << pars.size() << " parameters!");
10249
        return;
10250
    }
10251
 
10252
    int pushType = atoi(pars[0].c_str());
10253
    int x = atoi(pars[1].c_str());
10254
    int y = atoi(pars[2].c_str());
10255
 
10256
    if (pushType < 0 || pushType > 2)
10257
    {
10258
        MSG_ERROR("Invalid push type " << pushType << ". Ignoring command!");
10259
        return;
10260
    }
10261
 
217 andreas 10262
    if (x < 0 || x > mTSettings->getWidth() || y < 0 || y > mTSettings->getHeight())
148 andreas 10263
    {
10264
        MSG_ERROR("Illegal coordinates " << x << " x " << y << ". Ignoring command!");
10265
        return;
10266
    }
10267
 
10268
    if (pushType == 0 || pushType == 2)
10269
        mouseEvent(x, y, true);
10270
 
10271
    if (pushType == 1 || pushType == 2)
10272
        mouseEvent(x, y, false);
10273
}
10274
 
111 andreas 10275
/**
10276
 * Set the keyboard passthru.
10277
 */
10278
void TPageManager::doKPS(int, vector<int>&, vector<string>& pars)
10279
{
10280
    DECL_TRACER("TPageManager::doKPS(int, vector<int>&, vector<string>& pars)");
10281
 
10282
    if (pars.size() < 1)
10283
    {
10284
        MSG_ERROR("Got no parameter. Ignoring command!");
10285
        return;
10286
    }
10287
 
10288
    int state = atoi(pars[0].c_str());
10289
 
10290
    if (state == 0)
10291
        mPassThrough = false;
10292
    else if (state == 5)
10293
        mPassThrough = true;
10294
}
10295
 
10296
void TPageManager::doVKS(int, std::vector<int>&, vector<string>& pars)
10297
{
10298
    DECL_TRACER("TPageManager::doVKS(int, std::vector<int>&, vector<string>& pars)");
10299
 
10300
    if (pars.size() < 1)
10301
    {
10302
        MSG_ERROR("Got no parameter. Ignoring command!");
10303
        return;
10304
    }
10305
 
10306
    if (_sendVirtualKeys)
10307
        _sendVirtualKeys(pars[0]);
10308
}
10309
 
104 andreas 10310
/*
97 andreas 10311
 * Set the bitmap of a button to use a particular resource.
10312
 * Syntax:
10313
 *    "'^BBR-<vt addr range>,<button states range>,<resource name>'"
10314
 * Variable:
10315
 *    variable text address range = 1 - 4000.
10316
 *    button states range = 1 - 256 for multi-state buttons (0 = All states, for General buttons 1 = Off state and 2 = On state).
10317
 *    resource name = 1 - 50 ASCII characters.
10318
 * Example:
10319
 *    SEND_COMMAND Panel,"'^BBR-700,1,Sports_Image'"
10320
 *    Sets the resource name of the button to ’Sports_Image’.
10321
 */
21 andreas 10322
void TPageManager::doBBR(int port, vector<int>& channels, vector<string>& pars)
10323
{
10324
    DECL_TRACER("TPageManager::doBBR(int port, vector<int>& channels, vector<string>& pars)");
10325
 
10326
    if (pars.size() < 2)
10327
    {
10328
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
10329
        return;
10330
    }
10331
 
10332
    TError::clear();
10333
    int btState = atoi(pars[0].c_str());
10334
    string resName = pars[1];
10335
 
193 andreas 10336
    vector<TMap::MAP_T> map = findButtons(port, channels);
21 andreas 10337
 
10338
    if (TError::isError() || map.empty())
10339
        return;
10340
 
10341
    vector<Button::TButton *> buttons = collectButtons(map);
10342
 
83 andreas 10343
    if (buttons.size() > 0)
21 andreas 10344
    {
83 andreas 10345
        vector<Button::TButton *>::iterator mapIter;
21 andreas 10346
 
83 andreas 10347
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
21 andreas 10348
        {
83 andreas 10349
            Button::TButton *bt = *mapIter;
252 andreas 10350
//            setButtonCallbacks(bt);
21 andreas 10351
 
83 andreas 10352
            if (btState == 0)       // All instances?
10353
            {
10354
                int bst = bt->getNumberInstances();
10355
                MSG_DEBUG("Setting BBR on all " << bst << " instances...");
10356
 
10357
                for (int i = 0; i < bst; i++)
10358
                    bt->setResourceName(resName, i);
10359
            }
10360
            else
10361
                bt->setResourceName(resName, btState - 1);
97 andreas 10362
 
10363
            if (bt->isVisible())
10364
                bt->refresh();
99 andreas 10365
            else if (_setVisible)
10366
                _setVisible(bt->getHandle(), false);
21 andreas 10367
        }
10368
    }
10369
}
10370
 
97 andreas 10371
/*
10372
 * Add new resources
10373
 * Adds any and all resource parameters by sending embedded codes and data.
10374
 * Since the embedded codes are preceded by a '%' character, any '%' character
10375
 * contained in* the URL must be escaped with a second '%' character (see
10376
 * example).
10377
 * The file name field (indicated by a %F embedded code) may contain special
10378
 * escape sequences as shown in the ^RAF, ^RMF.
10379
 * Syntax:
10380
 *    "'^RAF-<resource name>,<data>'"
10381
 * Variables:
10382
 *    resource name = 1 - 50 ASCII characters.
10383
 *    data = Refers to the embedded codes, see the ^RAF, ^RMF.
10384
 * Example:
10385
 *    SEND_COMMAND Panel,"'^RAF-New Image,%P0%HAMX.COM%ALab/Test%%5Ffile%Ftest.jpg'"
10386
 *    Adds a new resource.
10387
 *    The resource name is ’New Image’
10388
 *    %P (protocol) is an HTTP
10389
 *    %H (host name) is AMX.COM
10390
 *    %A (file path) is Lab/Test_f ile
10391
 *    %F (file name) is test.jpg.
10392
 *    Note that the %%5F in the file path is actually encoded as %5F.
10393
 */
10394
void TPageManager::doRAF(int, vector<int>&, vector<string>& pars)
10395
{
10396
    DECL_TRACER("TPageManager::doRAF(int port, vector<int>& channels, vector<string>& pars)");
10397
 
10398
    if (pars.size() < 2)
10399
    {
10400
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
10401
        return;
10402
    }
10403
 
10404
    string name = pars[0];
10405
    string data = pars[1];
10406
 
10407
    vector<string> parts = StrSplit(data, "%");
10408
    RESOURCE_T res;
10409
 
10410
    if (parts.size() > 0)
10411
    {
10412
        vector<string>::iterator sIter;
10413
 
10414
        for (sIter = parts.begin(); sIter != parts.end(); sIter++)
10415
        {
10416
            const char *s = sIter->c_str();
10417
            string ss = *sIter;
10418
            MSG_DEBUG("Parsing \"" << ss << "\" with token << " << ss[0]);
10419
 
10420
            switch(*s)
10421
            {
10422
                case 'P':
10423
                    if (*(s+1) == '0')
10424
                        res.protocol = "HTTP";
10425
                    else
10426
                        res.protocol = "FTP";
10427
                    break;
10428
 
10429
                case 'U': res.user = sIter->substr(1); break;
10430
                case 'S': res.password = sIter->substr(1); break;
10431
                case 'H': res.host = sIter->substr(1); break;
10432
                case 'F': res.file = sIter->substr(1); break;
10433
                case 'A': res.path = sIter->substr(1); break;
10434
                case 'R': res.refresh = atoi(sIter->substr(1).c_str()); break;
10435
 
10436
                default:
10437
                    MSG_WARNING("Option " << sIter->at(0) << " is currently not implemented!");
10438
            }
10439
        }
10440
 
10441
        if (gPrjResources)
10442
            gPrjResources->addResource(name, res.protocol, res.host, res.path, res.file, res.user, res.password, res.refresh);
10443
    }
10444
}
10445
 
111 andreas 10446
void TPageManager::doRFR(int, vector<int>&, vector<string>& pars)
97 andreas 10447
{
10448
    DECL_TRACER("TPageManager::doRFR(int port, vector<int>& channels, vector<string>& pars)");
10449
 
10450
    if (pars.size() < 1)
10451
    {
10452
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
10453
        return;
10454
    }
10455
 
10456
    string name = pars[0];
193 andreas 10457
    vector<TMap::MAP_T> map = findButtonByName(name);
97 andreas 10458
 
10459
    if (TError::isError() || map.empty())
10460
        return;
10461
 
10462
    vector<Button::TButton *> buttons = collectButtons(map);
10463
 
10464
    if (buttons.size() > 0)
10465
    {
10466
        vector<Button::TButton *>::iterator mapIter;
10467
 
10468
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10469
        {
10470
            Button::TButton *bt = *mapIter;
10471
 
10472
            if (bt->isVisible())
10473
            {
252 andreas 10474
//                setButtonCallbacks(bt);
97 andreas 10475
                bt->refresh();
10476
            }
10477
        }
10478
    }
10479
}
10480
 
10481
/*
10482
 * Modify an existing resource
10483
 *
10484
 * Modifies any and all resource parameters by sending embedded codes and data.
10485
 * Since the embedded codes are preceded by a '%' character, any '%' character
10486
 * contained in the URL must be escaped with a second '%' character (see
10487
 * example).
10488
 * The file name field (indicated by a %F embedded code) may contain special
10489
 * escape sequences as shown in the ^RAF.
10490
 *
10491
 * Syntax:
10492
 * "'^RMF-<resource name>,<data>'"
10493
 * Variables:
10494
 *   • resource name = 1 - 50 ASCII characters
10495
 *   • data = Refers to the embedded codes, see the ^RAF, ^RMF.
10496
 * Example:
10497
 *   SEND_COMMAND Panel,"'^RMF-Sports_Image,%ALab%%5FTest/Images%Ftest.jpg'"
10498
 * Changes the resource ’Sports_Image’ file name to ’test.jpg’ and the path to
10499
 * ’Lab_Test/Images’.
10500
 * Note that the %%5F in the file path is actually encoded as %5F.
10501
 */
22 andreas 10502
void TPageManager::doRMF(int, vector<int>&, vector<string>& pars)
21 andreas 10503
{
10504
    DECL_TRACER("TPageManager::doRMF(int port, vector<int>& channels, vector<string>& pars)");
10505
 
10506
    if (pars.size() < 2)
10507
    {
10508
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
10509
        return;
10510
    }
10511
 
10512
    string name = pars[0];
10513
    string data = pars[1];
10514
 
10515
    vector<string> parts = StrSplit(data, "%");
10516
    RESOURCE_T res;
10517
 
83 andreas 10518
    if (parts.size() > 0)
21 andreas 10519
    {
83 andreas 10520
        vector<string>::iterator sIter;
21 andreas 10521
 
83 andreas 10522
        for (sIter = parts.begin(); sIter != parts.end(); sIter++)
21 andreas 10523
        {
83 andreas 10524
            const char *s = sIter->c_str();
10525
            string ss = *sIter;
10526
            MSG_DEBUG("Parsing \"" << ss << "\" with token << " << ss[0]);
21 andreas 10527
 
83 andreas 10528
            switch(*s)
10529
            {
10530
                case 'P':
10531
                    if (*(s+1) == '0')
10532
                        res.protocol = "HTTP";
10533
                    else
10534
                        res.protocol = "FTP";
10535
                break;
21 andreas 10536
 
83 andreas 10537
                case 'U': res.user = sIter->substr(1); break;
10538
                case 'S': res.password = sIter->substr(1); break;
10539
                case 'H': res.host = sIter->substr(1); break;
10540
                case 'F': res.file = sIter->substr(1); break;
10541
                case 'A': res.path = sIter->substr(1); break;
10542
                case 'R': res.refresh = atoi(sIter->substr(1).c_str()); break;
10543
 
10544
                default:
10545
                    MSG_WARNING("Option " << sIter->at(0) << " is currently not implemented!");
10546
            }
21 andreas 10547
        }
83 andreas 10548
 
10549
        if (gPrjResources)
10550
            gPrjResources->setResource(name, res.protocol, res.host, res.path, res.file, res.user, res.password, res.refresh);
21 andreas 10551
    }
10552
}
62 andreas 10553
 
10554
/**
111 andreas 10555
 * Change the refresh rate for a given resource.
10556
 */
10557
void TPageManager::doRSR(int, vector<int>&, vector<string>& pars)
10558
{
10559
    DECL_TRACER("TPageManager::doRSR(int, vector<int>&, vector<string>& pars)");
10560
 
10561
    if (pars.size() < 2)
10562
    {
10563
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
10564
        return;
10565
    }
10566
 
10567
    string resName = pars[0];
10568
    int resRefresh = atoi(pars[1].c_str());
10569
 
10570
    if (!gPrjResources)
10571
    {
10572
        MSG_ERROR("Missing the resource module. Ignoring command!");
10573
        return;
10574
    }
10575
 
10576
    RESOURCE_T res = gPrjResources->findResource(resName);
10577
 
10578
    if (res.name.empty() || res.refresh == resRefresh)
10579
        return;
10580
 
10581
    gPrjResources->setResource(resName, res.protocol, res.host, res.path, res.file, res.user, res.password, resRefresh);
10582
}
10583
 
10584
/**
62 andreas 10585
 * @brief TPageManager::doAKB - Pop up the keyboard icon
10586
 * Pop up the keyboard icon and initialize the text string to that specified.
10587
 * Keyboard string is set to null on power up and is stored until power is lost.
10588
 * The Prompt Text is optional.
10589
 */
10590
void TPageManager::doAKB(int, vector<int>&, vector<string> &pars)
10591
{
10592
    DECL_TRACER("TPageManager::doAKB(int, vector<int>&, vector<string> &pars)");
10593
 
10594
    if (pars.size() < 1)
10595
    {
10596
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
10597
        return;
10598
    }
10599
 
10600
    string initText = pars[0];
10601
    string promptText;
10602
 
10603
    if (pars.size() > 1)
10604
        promptText = pars[1];
10605
 
63 andreas 10606
    if (initText.empty())
10607
        initText = mAkbText;
10608
    else
10609
        mAkbText = initText;
62 andreas 10610
 
10611
    if (_callKeyboard)
63 andreas 10612
        _callKeyboard(initText, promptText, false);
62 andreas 10613
}
10614
 
63 andreas 10615
/**
10616
 * Pop up the keyboard icon and initialize the text string to that
10617
 * specified.
10618
 */
62 andreas 10619
void TPageManager::doAKEYB(int port, vector<int>& channels, vector<string>& pars)
10620
{
10621
    DECL_TRACER("TPageManager::doAKEYB(int port, vector<int>& channels, vector<string>& pars)");
10622
 
10623
    doAKB(port, channels, pars);
10624
}
10625
 
63 andreas 10626
void TPageManager::doAKEYP(int port, std::vector<int>& channels, std::vector<std::string>& pars)
10627
{
10628
    DECL_TRACER("TPageManager::doAKEYP(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
10629
 
10630
    doAKP(port, channels, pars);
10631
}
10632
 
62 andreas 10633
/**
63 andreas 10634
 * Remove keyboard or keypad that was displayed using 'AKEYB', 'AKEYP', 'PKEYP',
10635
 * @AKB, @AKP, @PKP, @EKP, or @TKP commands.
10636
 */
10637
void TPageManager::doAKEYR(int, vector<int>&, vector<string>&)
10638
{
10639
    DECL_TRACER("TPageManager::doAKEYR(int, vector<int>&, vector<string>&)");
10640
 
10641
    if (_callResetKeyboard)
10642
        _callResetKeyboard();
10643
}
10644
 
10645
/**
62 andreas 10646
 * @brief TPageManager::doAKP - Pop up the keypad icon
10647
 * Pop up the keypad icon and initialize the text string to that specified.
10648
 * Keypad string is set to null on power up and is stored until power is lost.
10649
 * The Prompt Text is optional.
10650
 */
10651
void TPageManager::doAKP(int, std::vector<int>&, std::vector<std::string> &pars)
10652
{
10653
    DECL_TRACER("TPageManager::doAKP(int, vector<int>&, vector<string> &pars)");
10654
 
10655
    if (pars.size() < 1)
10656
    {
10657
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
10658
        return;
10659
    }
10660
 
10661
    string initText = pars[0];
10662
    string promptText;
10663
 
10664
    if (pars.size() > 1)
10665
        promptText = pars[1];
10666
 
63 andreas 10667
    if (initText.empty())
10668
        initText = mAkpText;
10669
    else
10670
        mAkpText = initText;
62 andreas 10671
 
10672
    if (_callKeypad)
63 andreas 10673
        _callKeypad(initText, promptText, false);
62 andreas 10674
}
10675
 
63 andreas 10676
/**
10677
 * Remove keyboard or keypad that was displayed using 'AKEYB', 'AKEYP', 'PKEYP',
10678
 * @AKB, @AKP, @PKP, @EKP, or @TKP commands.
10679
 */
10680
void TPageManager::doAKR(int port, vector<int>& channels, vector<string>& pars)
62 andreas 10681
{
63 andreas 10682
    DECL_TRACER("TPageManager::doAKR(int, vector<int>&, vector<string>&)");
62 andreas 10683
 
63 andreas 10684
    doAKEYR(port, channels, pars);
62 andreas 10685
}
10686
 
108 andreas 10687
void TPageManager::doABEEP(int, std::vector<int>&, vector<string>&)
10688
{
10689
    DECL_TRACER("TPageManager::doBEEP(int, std::vector<int>&, vector<string>&)");
10690
 
10691
    if (!_playSound)
334 andreas 10692
    {
10693
#if TESTMODE == 1
10694
        setAllDone();
10695
#endif
108 andreas 10696
        return;
334 andreas 10697
    }
108 andreas 10698
 
10699
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getSingleBeepSound();
10700
    TValidateFile vf;
10701
 
326 andreas 10702
    if (vf.isValidFile(snd))
108 andreas 10703
        _playSound(snd);
326 andreas 10704
#if TESTMODE == 1
10705
    else
10706
    {
10707
        MSG_PROTOCOL("Sound file invalid!");
334 andreas 10708
        setAllDone();
326 andreas 10709
    }
10710
#endif
108 andreas 10711
}
10712
 
10713
void TPageManager::doADBEEP(int, std::vector<int>&, vector<string>&)
10714
{
10715
    DECL_TRACER("TPageManager::doDBEEP(int, std::vector<int>&, vector<string>&)");
10716
 
10717
    if (!_playSound)
10718
        return;
10719
 
10720
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getDoubleBeepSound();
10721
    TValidateFile vf;
10722
 
326 andreas 10723
    if (vf.isValidFile(snd))
108 andreas 10724
        _playSound(snd);
326 andreas 10725
#if TESTMODE == 1
10726
    else
10727
    {
10728
        MSG_PROTOCOL("Sound file invalid!");
334 andreas 10729
        setAllDone();
326 andreas 10730
    }
10731
#endif
108 andreas 10732
}
10733
 
71 andreas 10734
void TPageManager::doBEEP(int, std::vector<int>&, vector<string>&)
10735
{
10736
    DECL_TRACER("TPageManager::doBEEP(int, std::vector<int>&, vector<string>&)");
10737
 
10738
    if (!_playSound)
326 andreas 10739
    {
10740
#if TESTMODE == 1
10741
        MSG_PROTOCOL("Method \"playSound()\" not initialized!");
334 andreas 10742
        setAllDone();
326 andreas 10743
#endif
71 andreas 10744
        return;
326 andreas 10745
    }
71 andreas 10746
 
10747
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getSingleBeepSound();
10748
    TValidateFile vf;
108 andreas 10749
    TSystemSound sysSound(TConfig::getSystemPath(TConfig::SOUNDS));
71 andreas 10750
 
326 andreas 10751
    if (sysSound.getSystemSoundState() && vf.isValidFile(snd))
71 andreas 10752
        _playSound(snd);
326 andreas 10753
#if TESTMODE == 1
10754
    else
10755
    {
10756
        if (!sysSound.getSystemSoundState())
10757
        {
10758
            MSG_PROTOCOL("Sound state disabled!")
10759
        }
10760
        else
10761
        {
10762
            MSG_PROTOCOL("Sound file invalid!");
10763
        }
10764
 
334 andreas 10765
        setAllDone();
326 andreas 10766
    }
10767
#endif
71 andreas 10768
}
10769
 
10770
void TPageManager::doDBEEP(int, std::vector<int>&, vector<string>&)
10771
{
10772
    DECL_TRACER("TPageManager::doDBEEP(int, std::vector<int>&, vector<string>&)");
10773
 
10774
    if (!_playSound)
10775
        return;
10776
 
10777
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getDoubleBeepSound();
10778
    TValidateFile vf;
108 andreas 10779
    TSystemSound sysSound(TConfig::getSystemPath(TConfig::SOUNDS));
71 andreas 10780
 
326 andreas 10781
    if (sysSound.getSystemSoundState() && vf.isValidFile(snd))
71 andreas 10782
        _playSound(snd);
326 andreas 10783
#if TESTMODE == 1
10784
    else
10785
    {
10786
        if (!sysSound.getSystemSoundState())
10787
        {
10788
            MSG_PROTOCOL("Sound state disabled!")
10789
        }
10790
        else
10791
        {
10792
            MSG_PROTOCOL("Sound file invalid!");
10793
        }
10794
 
334 andreas 10795
        setAllDone();
326 andreas 10796
    }
10797
#endif
71 andreas 10798
}
10799
 
63 andreas 10800
/**
10801
 * @brief Pop up the keypad icon and initialize the text string to that specified.
10802
 * Keypad string is set to null on power up and is stored until power is lost.
10803
 * The Prompt Text is optional.
10804
 */
62 andreas 10805
void TPageManager::doEKP(int port, std::vector<int>& channels, std::vector<std::string>& pars)
10806
{
10807
    DECL_TRACER("TPageManager::doEKP(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
10808
 
10809
    doAKP(port, channels, pars);
10810
}
63 andreas 10811
 
10812
/**
10813
 * @brief Present a private keyboard.
10814
 * Pops up the keyboard icon and initializes the text string to that specified.
10815
 * Keyboard displays a '*' instead of the letters typed. The Prompt Text is optional.
10816
 */
10817
void TPageManager::doPKB(int, vector<int>&, vector<string>& pars)
10818
{
10819
    DECL_TRACER("TPageManager::doPKB(int, vector<int>&, vector<string>& pars)");
10820
 
10821
    if (pars.size() < 1)
10822
    {
10823
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
10824
        return;
10825
    }
10826
 
10827
    string initText = pars[0];
10828
    string promptText;
10829
 
10830
    if (pars.size() > 1)
10831
        promptText = pars[1];
10832
 
10833
    if (_callKeyboard)
10834
        _callKeyboard(initText, promptText, true);
10835
}
10836
 
10837
/**
10838
 * @brief Present a private keypad.
10839
 * Pops up the keypad icon and initializes the text string to that specified.
10840
 * Keypad displays a '*' instead of the numbers typed. The Prompt Text is optional.
10841
 */
10842
void TPageManager::doPKP(int, vector<int>&, vector<string>& pars)
10843
{
10844
    DECL_TRACER("TPageManager::doPKP(int, vector<int>&, vector<string>& pars)");
10845
 
10846
    if (pars.size() < 1)
10847
    {
10848
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
10849
        return;
10850
    }
10851
 
10852
    string initText = pars[0];
10853
    string promptText;
10854
 
10855
    if (pars.size() > 1)
10856
        promptText = pars[1];
10857
 
10858
    if (_callKeypad)
10859
        _callKeypad(initText, promptText, true);
10860
}
10861
 
10862
/**
64 andreas 10863
 * Send panel to SETUP page.
10864
 */
10865
void TPageManager::doSetup(int, vector<int>&, vector<string>&)
10866
{
10867
    DECL_TRACER("TPageManager::doSetup(int, vector<int>&, vector<string>&)");
10868
 
10869
    if (_callShowSetup)
10870
        _callShowSetup();
10871
}
10872
 
10873
/**
10874
 * Shut down the App
10875
 */
10876
void TPageManager::doShutdown(int, vector<int>&, vector<string>&)
10877
{
10878
    DECL_TRACER("TPageManager::doShutdown(int, vector<int>&, vector<string>&)");
10879
 
97 andreas 10880
    MSG_PROTOCOL("Received shutdown ...");
64 andreas 10881
#ifdef __ANDROID__
10882
    stopNetworkState();
10883
#endif
10884
    prg_stopped = true;
10885
    killed = true;
10886
 
10887
    if (_shutdown)
10888
        _shutdown();
10889
}
10890
 
82 andreas 10891
void TPageManager::doSOU(int, vector<int>&, vector<string>& pars)
10892
{
10893
    DECL_TRACER("TPageManager::doSOU(int, vector<int>&, vector<string>& pars)");
10894
 
10895
    if (pars.size() < 1)
10896
    {
10897
        MSG_ERROR("@SOU: Expecting a sound file as parameter! Ignoring command.");
10898
        return;
10899
    }
10900
 
10901
    if (!_playSound)
10902
    {
10903
        MSG_ERROR("@SOU: Missing sound module!");
10904
        return;
10905
    }
10906
 
165 andreas 10907
    if (pars[0].empty() || strCaseCompare(pars[0], "None") == 0)
10908
        return;
10909
 
82 andreas 10910
    _playSound(pars[0]);
10911
}
10912
 
326 andreas 10913
void TPageManager::doMUT(int, vector<int>&, vector<string>& pars)
10914
{
10915
    DECL_TRACER("TPageManager::doMUT(int, vector<int>&, vector<string>& pars)");
10916
 
10917
    if (pars.size() < 1)
10918
    {
10919
        MSG_ERROR("^MUT: Expecting a state parameter! Ignoring command.");
10920
        return;
10921
    }
10922
 
10923
    bool mute = 0;
10924
 
10925
    if (pars[0] == "0")
10926
        mute = false;
10927
    else
10928
        mute = true;
10929
 
10930
    TConfig::setMuteState(mute);
10931
#if TESTMODE == 1
327 andreas 10932
    if (_gTestMode)
10933
    {
10934
        bool st = TConfig::getMuteState();
10935
        _gTestMode->setResult(st ? "1" : "0");
10936
    }
10937
 
326 andreas 10938
    __success = true;
334 andreas 10939
    setAllDone();
326 andreas 10940
#endif
10941
}
10942
 
64 andreas 10943
/**
63 andreas 10944
 * @brief Present a telephone keypad.
10945
 * Pops up the keypad icon and initializes the text string to that specified.
10946
 * The Prompt Text is optional.
10947
 */
10948
void TPageManager::doTKP(int port, vector<int>& channels, vector<string>& pars)
10949
{
10950
    DECL_TRACER("TPageManager::doTKP(int port, vector<int>& channels, vector<string>& pars)");
10951
 
10952
    // TODO: Implement a real telefone keypad.
10953
    doAKP(port, channels, pars);
10954
}
10955
 
10956
/**
10957
 * Popup the virtual keyboard
10958
 */
123 andreas 10959
void TPageManager::doVKB(int port, vector<int>& channels, vector<string>& pars)
63 andreas 10960
{
123 andreas 10961
    DECL_TRACER("TPageManager::doVKB(int port, vector<int>& channels, vector<string>& pars)");
63 andreas 10962
 
10963
    doAKP(port, channels, pars);
10964
}
129 andreas 10965
#ifndef _NOSIP_
123 andreas 10966
void TPageManager::sendPHN(vector<string>& cmds)
10967
{
10968
    DECL_TRACER("TPageManager::sendPHN(const vector<string>& cmds)");
10969
 
10970
    vector<int> channels;
10971
    doPHN(-1, channels, cmds);
10972
}
10973
 
141 andreas 10974
void TPageManager::actPHN(vector<string>& cmds)
10975
{
10976
    DECL_TRACER("TPageManager::actPHN(const vector<string>& cmds)");
10977
 
10978
    vector<int> channels;
10979
    doPHN(1, channels, cmds);
10980
}
10981
 
140 andreas 10982
void TPageManager::phonePickup(int id)
10983
{
10984
    DECL_TRACER("TPageManager::phonePickup(int id)");
10985
 
10986
    if (id < 0 || id >= 4)
10987
        return;
10988
 
10989
    if (mSIPClient)
10990
        mSIPClient->pickup(id);
10991
}
10992
 
10993
void TPageManager::phoneHangup(int id)
10994
{
10995
    DECL_TRACER("TPageManager::phoneHangup(int id)");
10996
 
10997
    if (id < 0 || id >= 4)
10998
        return;
10999
 
11000
    if (mSIPClient)
11001
        mSIPClient->terminate(id);
11002
}
11003
 
123 andreas 11004
/**
11005
 * @brief Phone commands.
11006
 * The phone commands could come from the master or are send to the master.
11007
 * If the parameter \p port is less then 0 (zero) a command is send to the
11008
 * master. In any other case the command came from the mater.
125 andreas 11009
 *
11010
 * @param port  This is used to signal if the command was sent by the master
11011
 *              or generated from the panel. If ths is less then 0, then the
11012
 *              method was called because of an event happen in the panel.
11013
 *              If this is grater or equal 0, then the event is comming from
11014
 *              the master.
11015
 * @param pars  This are parameters. The first parameter defines the action
11016
 *              to be done. According to the command this parameter may have a
11017
 *              different number of arguments.
123 andreas 11018
 */
11019
void TPageManager::doPHN(int port, vector<int>&, vector<string>& pars)
11020
{
11021
    DECL_TRACER("TPageManager::doPHN(int port, vector<int>&, vector<string>& pars)");
11022
 
11023
    if (pars.size() < 1)
11024
    {
11025
        MSG_ERROR("Expecting at least 1 parameter but got none! Ignoring command.");
11026
        return;
11027
    }
11028
 
11029
    string sCommand;
11030
    string cmd = toUpper(pars[0]);
11031
 
11032
    // Master to panel
11033
    if (port >= 0)
11034
    {
11035
        if (!mSIPClient)
11036
        {
11037
            MSG_ERROR("SIP client class was not initialized!")
11038
            return;
11039
        }
11040
 
11041
        if (cmd == "ANSWER")
11042
        {
11043
            if (pars.size() >= 2)
11044
            {
124 andreas 11045
                int id = atoi(pars[1].c_str());
11046
 
11047
                if (mSIPClient->getSIPState(id) == TSIPClient::SIP_HOLD)
11048
                    mSIPClient->resume(id);
11049
                else
135 andreas 11050
                    mSIPClient->pickup(id);
123 andreas 11051
            }
11052
        }
11053
        else if (cmd == "AUTOANSWER")
11054
        {
11055
            if (pars.size() >= 2)
11056
            {
11057
                if (pars[1].at(0) == '0')
11058
                    mPHNautoanswer = false;
11059
                else
11060
                    mPHNautoanswer = true;
127 andreas 11061
 
11062
                vector<string> cmds;
11063
                cmds = { "AUTOANSWER", to_string(mPHNautoanswer ? 1 : 0) };
128 andreas 11064
                sendPHN(cmds);
123 andreas 11065
            }
11066
        }
11067
        else if (cmd == "CALL")     // Initiate a call
11068
        {
11069
            if (pars.size() >= 2)
127 andreas 11070
                mSIPClient->call(pars[1]);
123 andreas 11071
        }
11072
        else if (cmd == "DTMF")     // Send tone modified codes
11073
        {
127 andreas 11074
            if (pars.size() >= 2)
11075
                mSIPClient->sendDTMF(pars[1]);
123 andreas 11076
        }
11077
        else if (cmd == "HANGUP")   // terminate a call
11078
        {
124 andreas 11079
            if (pars.size() >= 2)
11080
            {
11081
                int id = atoi(pars[1].c_str());
11082
                mSIPClient->terminate(id);
11083
            }
123 andreas 11084
        }
11085
        else if (cmd == "HOLD")     // Hold the line
11086
        {
124 andreas 11087
            if (pars.size() >= 2)
11088
            {
11089
                int id = atoi(pars[1].c_str());
11090
                mSIPClient->hold(id);
11091
            }
123 andreas 11092
        }
128 andreas 11093
        else if (cmd == "LINESTATE") // State of all line
127 andreas 11094
        {
128 andreas 11095
            mSIPClient->sendLinestate();
127 andreas 11096
        }
123 andreas 11097
        else if (cmd == "PRIVACY")  // Set/unset "do not disturb"
11098
        {
128 andreas 11099
            if (pars.size() >= 2)
11100
            {
11101
                bool state = (pars[1].at(0) == '1' ? true : false);
11102
                mSIPClient->sendPrivate(state);
11103
            }
123 andreas 11104
        }
11105
        else if (cmd == "REDIAL")   // Redials the last number
11106
        {
128 andreas 11107
            mSIPClient->redial();
123 andreas 11108
        }
11109
        else if (cmd == "TRANSFER") // Transfer call to provided number
11110
        {
128 andreas 11111
            if (pars.size() >= 3)
11112
            {
11113
                int id = atoi(pars[1].c_str());
11114
                string num = pars[2];
11115
 
11116
                if (mSIPClient->transfer(id, num))
11117
                {
11118
                    vector<string> cmds;
11119
                    cmds.push_back("TRANSFERRED");
11120
                    sendPHN(cmds);
11121
                }
11122
            }
123 andreas 11123
        }
144 andreas 11124
        else if (cmd == "IM")
11125
        {
11126
            if (pars.size() < 3)
11127
                return;
11128
 
11129
            string to = pars[1];
11130
            string msg = pars[2];
11131
            string toUri;
11132
 
11133
            if (to.find("sip:") == string::npos)
11134
                toUri = "sip:";
11135
 
11136
            toUri += to;
11137
 
11138
            if (to.find("@") == string::npos)
11139
                toUri += "@" + TConfig::getSIPproxy();
11140
 
11141
            mSIPClient->sendIM(toUri, msg);
11142
        }
123 andreas 11143
        else if (cmd == "SETUP")    // Some temporary settings
11144
        {
11145
            if (pars.size() < 2)
11146
                return;
11147
 
11148
            if (pars[1] == "DOMAIN" && pars.size() >= 3)
11149
                TConfig::setSIPdomain(pars[2]);
11150
            else if (pars[1] == "DTMFDURATION")
11151
            {
138 andreas 11152
                unsigned int ms = atoi(pars[2].c_str());
11153
                mSIPClient->setDTMFduration(ms);
123 andreas 11154
            }
11155
            else if (pars[1] == "ENABLE")   // (re)register user
11156
            {
11157
                TConfig::setSIPstatus(true);
127 andreas 11158
                mSIPClient->cleanUp();
135 andreas 11159
                mSIPClient->init();
123 andreas 11160
            }
127 andreas 11161
            else if (pars[1] == "DOMAIN" && pars.size() >= 3)
11162
                TConfig::setSIPdomain(pars[2]);
123 andreas 11163
            else if (pars[1] == "PASSWORD" && pars.size() >= 3)
11164
                TConfig::setSIPpassword(pars[2]);
11165
            else if (pars[1] == "PORT" && pars.size() != 3)
11166
                TConfig::setSIPport(atoi(pars[2].c_str()));
11167
            else if (pars[1] == "PROXYADDR" && pars.size() >= 3)
11168
                TConfig::setSIPproxy(pars[2]);
11169
            else if (pars[1] == "STUNADDR" && pars.size() >= 3)
11170
                TConfig::setSIPstun(pars[2]);
11171
            else if (pars[1] == "USERNAME" && pars.size() >= 3)
11172
                TConfig::setSIPuser(pars[2]);
11173
        }
11174
        else
11175
        {
11176
            MSG_ERROR("Unknown command ^PHN-" << cmd << " ignored!");
11177
        }
11178
    }
11179
    else   // Panel to master
11180
    {
11181
        vector<string>::iterator iter;
11182
 
11183
        for (iter = pars.begin(); iter != pars.end(); ++iter)
11184
        {
11185
            if (!sCommand.empty())
11186
                sCommand += ",";
11187
 
11188
            sCommand += *iter;
11189
        }
11190
 
11191
        sendPHNcommand(sCommand);
11192
    }
11193
}
127 andreas 11194
 
11195
void TPageManager::getPHN(int, vector<int>&, vector<string>& pars)
11196
{
11197
    DECL_TRACER("TPageManager::getPHN(int, vector<int>&, vector<string>& pars)");
11198
 
11199
    if (pars.size() < 1)
11200
    {
11201
        MSG_ERROR("Invalid number of arguments!");
11202
        return;
11203
    }
11204
 
11205
    string cmd = pars[0];
11206
 
11207
    if (cmd == "AUTOANSWER")
11208
        sendPHNcommand(cmd + "," + (mPHNautoanswer ? "1" : "0"));
11209
    else if (cmd == "LINESTATE")
11210
    {
11211
        if (!mSIPClient)
11212
            return;
11213
 
138 andreas 11214
        mSIPClient->sendLinestate();
127 andreas 11215
    }
11216
    else if (cmd == "MSGWAITING")
11217
    {
144 andreas 11218
        size_t num = mSIPClient->getNumberMessages();
11219
        sendPHNcommand(cmd + "," + (num > 0 ? "1" : "0") + "," + std::to_string(num) + "0,0,0");
127 andreas 11220
    }
11221
    else if (cmd == "PRIVACY")
11222
    {
138 andreas 11223
        if (mSIPClient->getPrivate())
11224
            sendPHNcommand(cmd + ",1");
11225
        else
11226
            sendPHNcommand(cmd + ",0");
127 andreas 11227
    }
144 andreas 11228
    else if (cmd == "REDIAL")
11229
    {
11230
        if (pars.size() < 2)
11231
            return;
11232
 
11233
        sendPHNcommand(cmd + "," + pars[1]);
11234
    }
127 andreas 11235
    else
11236
    {
11237
        MSG_WARNING("Unknown command " << cmd << " found!");
11238
    }
11239
}
129 andreas 11240
#endif  // _NOSIP_
134 andreas 11241
 
300 andreas 11242
/*
318 andreas 11243
 *  Hide all subpages in a subpage viewer button.
11244
 */
11245
void TPageManager::doSHA(int port, vector<int> &channels, vector<string> &pars)
11246
{
11247
    DECL_TRACER("TPageManager::doSHA(int port, vector<int> &channels, vector<string> &pars)");
11248
 
343 andreas 11249
    Q_UNUSED(pars);
318 andreas 11250
    vector<TMap::MAP_T> map = findButtons(port, channels);
11251
 
11252
    if (TError::isError() || map.empty())
11253
        return;
11254
 
11255
    vector<Button::TButton *> buttons = collectButtons(map);
11256
 
11257
    if (!buttons.empty())
11258
    {
11259
        vector<Button::TButton *>::iterator mapIter;
11260
 
11261
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11262
        {
11263
            Button::TButton *bt = *mapIter;
11264
 
11265
            if (_hideAllSubViewItems)
11266
                _hideAllSubViewItems(bt->getHandle());
11267
        }
11268
    }
11269
}
11270
 
11271
void TPageManager::doSHD(int port, vector<int>& channels, vector<string>& pars)
11272
{
11273
    DECL_TRACER("TPageManager::doSHD(int port, vector<int>& channels, vector<string>& pars)");
11274
 
11275
    if (pars.size() < 1)
11276
        return;
11277
 
11278
    string name = pars[0];
11279
 
11280
    vector<TMap::MAP_T> map = findButtons(port, channels);
11281
 
11282
    if (TError::isError() || map.empty())
11283
        return;
11284
 
11285
    vector<Button::TButton *> buttons = collectButtons(map);
11286
 
11287
    if (!buttons.empty())
11288
    {
11289
        vector<Button::TButton *>::iterator mapIter;
11290
 
11291
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11292
        {
11293
            Button::TButton *bt = *mapIter;
11294
 
11295
            vector<TSubPage *> subviews = createSubViewList(bt->getSubViewID());
11296
 
11297
            if (subviews.empty())
11298
                continue;
11299
 
11300
            vector<TSubPage *>::iterator itSub;
11301
 
11302
            for (itSub = subviews.begin(); itSub != subviews.end(); ++itSub)
11303
            {
11304
                TSubPage *sub = *itSub;
11305
 
11306
                if (sub && sub->getName() == name)
11307
                {
11308
                    if (_hideSubViewItem)
11309
                        _hideSubViewItem(bt->getHandle(), sub->getHandle());
11310
 
11311
                    break;
11312
                }
11313
            }
11314
        }
11315
    }
11316
}
11317
 
11318
void TPageManager::doSPD(int port, vector<int>& channels, vector<string>& pars)
11319
{
11320
    DECL_TRACER("TPageManager::doSPD(int port, vector<int>& channel, vector<string>& pars)");
11321
 
11322
    if (pars.size() < 1)
11323
        return;
11324
 
11325
    TError::clear();
11326
    int padding = atoi(pars[0].c_str());
11327
 
11328
    if (padding < 0 || padding > 100)
11329
        return;
11330
 
11331
    vector<TMap::MAP_T> map = findButtons(port, channels);
11332
 
11333
    if (TError::isError() || map.empty())
11334
        return;
11335
 
11336
    vector<Button::TButton *> buttons = collectButtons(map);
11337
 
11338
    if (!buttons.empty())
11339
    {
11340
        vector<Button::TButton *>::iterator mapIter;
11341
 
11342
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11343
        {
11344
            Button::TButton *bt = *mapIter;
11345
 
11346
            if (_setSubViewPadding)
11347
                _setSubViewPadding(bt->getHandle(), padding);
11348
        }
11349
    }
11350
}
11351
 
11352
/*
300 andreas 11353
 * This command will perform one of three different operations based on the following conditions:
11354
 * 1. If the named subpage is hidden in the set associated with the viewer button it will be shown in the anchor position.
11355
 * 2. If the named subpage is not present in the set it will be added to the set and shown in the anchor position.
11356
 * 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
11357
 * position. The anchor position is the location on the subpage viewer button specified by its weighting. This will either be
11358
 * left, center or right for horizontal subpage viewer buttons or top, center or bottom for vertical subpage viewer buttons.
11359
 * Surrounding subpages are relocated on the viewer button as needed to accommodate the described operations
11360
 */
11361
void TPageManager::doSSH(int port, vector<int> &channels, vector<string> &pars)
11362
{
11363
    DECL_TRACER("TPageManager::doSSH(int port, vector<int> &channels, vector<string> &pars)");
11364
 
11365
    if (pars.size() < 1)
11366
    {
11367
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
11368
        return;
11369
    }
11370
 
11371
    TError::clear();
11372
    string name = pars[0];
11373
    int position = 0;   // optional
11374
    int time = 0;       // optional
11375
 
11376
    if (pars.size() > 1)
11377
        position = atoi(pars[1].c_str());
11378
 
11379
    if (pars.size() > 2)
11380
        time = atoi(pars[2].c_str());
11381
 
11382
    vector<TMap::MAP_T> map = findButtons(port, channels);
11383
 
11384
    if (TError::isError() || map.empty())
11385
        return;
11386
 
11387
    vector<Button::TButton *> buttons = collectButtons(map);
11388
 
11389
    if (!buttons.empty())
11390
    {
11391
        vector<Button::TButton *>::iterator mapIter;
11392
 
11393
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11394
        {
11395
            Button::TButton *bt = *mapIter;
11396
            vector<TSubPage *> subviews = createSubViewList(bt->getSubViewID());
11397
 
11398
            if (subviews.empty() || !bt)
11399
                continue;
11400
 
11401
            vector<TSubPage *>::iterator itSub;
11402
 
11403
            for (itSub = subviews.begin(); itSub != subviews.end(); ++itSub)
11404
            {
11405
                TSubPage *sub = *itSub;
11406
 
11407
                if (sub && sub->getName() == name)
11408
                {
11409
                    if (_showSubViewItem)
11410
                        _showSubViewItem(sub->getHandle(), bt->getHandle(), position, time);
11411
 
11412
                    break;
11413
                }
11414
            }
11415
        }
11416
    }
11417
}
11418
 
318 andreas 11419
void TPageManager::doSTG(int port, vector<int>& channels, vector<string>& pars)
11420
{
11421
    DECL_TRACER("TPageManager::doSTG(int port, vector<int>& channels, vector<string>& pars)");
11422
 
11423
    if (pars.empty())
11424
    {
11425
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
11426
        return;
11427
    }
11428
 
11429
    TError::clear();
11430
    string name = pars[0];
11431
    int position = 0;   // optional
11432
    int time = 0;       // optional
11433
 
11434
    if (pars.size() > 1)
11435
        position = atoi(pars[1].c_str());
11436
 
11437
    if (pars.size() > 2)
11438
        time = atoi(pars[2].c_str());
11439
 
11440
    vector<TMap::MAP_T> map = findButtons(port, channels);
11441
 
11442
    if (TError::isError() || map.empty())
11443
        return;
11444
 
11445
    vector<Button::TButton *> buttons = collectButtons(map);
11446
 
11447
    if (!buttons.empty())
11448
    {
11449
        vector<Button::TButton *>::iterator mapIter;
11450
 
11451
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11452
        {
11453
            Button::TButton *bt = *mapIter;
11454
            vector<TSubPage *> subviews = createSubViewList(bt->getSubViewID());
11455
 
11456
            if (subviews.empty() || !bt)
11457
                continue;
11458
 
11459
            vector<TSubPage *>::iterator itSub;
11460
 
11461
            for (itSub = subviews.begin(); itSub != subviews.end(); ++itSub)
11462
            {
11463
                TSubPage *sub = *itSub;
11464
 
11465
                if (sub && sub->getName() == name)
11466
                {
11467
                    if (_toggleSubViewItem)
11468
                        _toggleSubViewItem(sub->getHandle(), bt->getHandle(), position, time);
11469
 
11470
                    break;
11471
                }
11472
            }
11473
        }
11474
    }
11475
}
11476
 
227 andreas 11477
void TPageManager::doLVD(int port, vector<int> &channels, vector<string> &pars)
225 andreas 11478
{
227 andreas 11479
    DECL_TRACER("TPageManager::doLVD(int port, vector<int> &channels, vector<string> &pars)");
225 andreas 11480
 
11481
    if (pars.size() < 1)
11482
    {
11483
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
11484
        return;
11485
    }
11486
 
11487
    TError::clear();
11488
    string source = pars[0];
11489
    vector<string> configs;
11490
 
11491
    if (pars.size() > 1)
11492
    {
11493
        for (size_t i = 1; i < pars.size(); ++i)
227 andreas 11494
        {
11495
            string low = toLower(pars[i]);
11496
 
11497
            if (low.find_first_of("user=") != string::npos ||
11498
                low.find_first_of("pass=") != string::npos ||
11499
                low.find_first_of("csv=")  != string::npos ||
11500
                low.find_first_of("has_headers=") != string::npos)
11501
            {
11502
                configs.push_back(pars[i]);
11503
            }
11504
        }
225 andreas 11505
    }
11506
 
11507
    vector<TMap::MAP_T> map = findButtons(port, channels);
11508
 
11509
    if (TError::isError() || map.empty())
11510
        return;
11511
 
11512
    vector<Button::TButton *> buttons = collectButtons(map);
11513
 
11514
    if (buttons.size() > 0)
11515
    {
11516
        vector<Button::TButton *>::iterator mapIter;
11517
 
11518
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11519
        {
11520
            Button::TButton *bt = *mapIter;
11521
            bt->setListSource(source, configs);
11522
        }
11523
    }
11524
 
11525
}
11526
 
230 andreas 11527
void TPageManager::doLVE(int port, vector<int> &channels, vector<string> &pars)
11528
{
11529
    DECL_TRACER("TPageManager::doLVE(int port, vector<int> &channels, vector<string> &pars)");
11530
 
11531
    if (pars.size() < 1)
11532
    {
11533
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
11534
        return;
11535
    }
11536
 
11537
    TError::clear();
11538
    int num = atoi(pars[0].c_str());
11539
 
11540
    vector<TMap::MAP_T> map = findButtons(port, channels);
11541
 
11542
    if (TError::isError() || map.empty())
11543
        return;
11544
 
11545
    vector<Button::TButton *> buttons = collectButtons(map);
11546
 
11547
    if (buttons.size() > 0)
11548
    {
11549
        vector<Button::TButton *>::iterator mapIter;
11550
 
11551
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11552
        {
11553
            Button::TButton *bt = *mapIter;
11554
            bt->setListViewEventNumber(num);
11555
        }
11556
    }
11557
 
11558
}
11559
 
227 andreas 11560
void TPageManager::doLVF(int port, vector<int> &channels, vector<string> &pars)
11561
{
11562
    DECL_TRACER("TPageManager::doLVF(int port, vector<int> &channels, vector<string> &pars)");
11563
 
11564
    if (pars.size() < 1)
11565
    {
11566
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
11567
        return;
11568
    }
11569
 
11570
    TError::clear();
11571
    string filter;
11572
 
11573
    vector<string>::iterator iter;
11574
 
11575
    for (iter = pars.begin(); iter != pars.end(); ++iter)
11576
    {
11577
        if (filter.length() > 0)
11578
            filter += ",";
11579
 
11580
        filter += *iter;
11581
    }
11582
 
11583
    vector<TMap::MAP_T> map = findButtons(port, channels);
11584
 
11585
    if (TError::isError() || map.empty())
11586
        return;
11587
 
11588
    vector<Button::TButton *> buttons = collectButtons(map);
11589
 
11590
    if (buttons.size() > 0)
11591
    {
11592
        vector<Button::TButton *>::iterator mapIter;
11593
 
11594
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11595
        {
11596
            Button::TButton *bt = *mapIter;
11597
            bt->setListSourceFilter(filter);
11598
        }
11599
    }
11600
}
11601
 
230 andreas 11602
void TPageManager::doLVL(int port, vector<int> &channels, vector<string> &pars)
11603
{
11604
    DECL_TRACER("TPageManager::doLVL(int port, vector<int> &channels, vector<string> &pars)");
11605
 
11606
    if (pars.size() < 1)
11607
    {
11608
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
11609
        return;
11610
    }
11611
 
11612
    TError::clear();
233 andreas 11613
    bool hasColumns = false;
230 andreas 11614
    int columns = 0;
233 andreas 11615
    bool hasLayout = false;
230 andreas 11616
    int layout = 0;
233 andreas 11617
    bool hasComponent = false;
11618
    int component = 0;
11619
    bool hasCellHeight = false;
11620
    bool cellHeightPercent = false;
11621
    int cellheight = 0;
11622
    bool hasP1 = false;
11623
    int p1 = 0;
11624
    bool hasP2 = false;
11625
    int p2 = 0;
11626
    bool hasFilter = false;
11627
    bool filter = false;
11628
    bool hasFilterHeight = false;
11629
    bool filterHeightPercent = false;
11630
    int filterheight = 0;
11631
    bool hasAlphaScroll = false;
11632
    bool alphascroll = false;
230 andreas 11633
 
11634
    vector<string>::iterator iter;
11635
 
11636
    for (iter = pars.begin(); iter != pars.end(); ++iter)
11637
    {
11638
        string low = toLower(*iter);
11639
 
11640
        if (low.find("columns=") != string::npos ||
11641
            low.find("nc=") != string::npos ||
11642
            low.find("numcol=") != string::npos)
11643
        {
11644
            size_t pos = low.find("=");
11645
            string sCols = low.substr(pos + 1);
11646
            columns = atoi(sCols.c_str());
233 andreas 11647
            hasColumns = true;
11648
        }
11649
        else if (low.find("c=") != string::npos || low.find("comp=") != string::npos)
11650
        {
11651
            size_t pos = low.find("=");
11652
            string sComp = low.substr(pos + 1);
11653
            component |= atoi(sComp.c_str());
11654
            hasComponent = true;
11655
        }
11656
        else if (low.find("l=") != string::npos || low.find("layout=") != string::npos)
11657
        {
11658
            size_t pos = low.find("=");
11659
            string sLay = low.substr(pos + 1);
11660
            layout = atoi(sLay.c_str());
11661
            hasLayout = true;
11662
        }
11663
        else if (low.find("ch=") != string::npos || low.find("cellheight=") != string::npos)
11664
        {
11665
            size_t pos = low.find("=");
11666
            string sCh = low.substr(pos + 1);
11667
            cellheight = atoi(sCh.c_str());
230 andreas 11668
 
233 andreas 11669
            if (low.find("%") != string::npos)
11670
                cellHeightPercent = true;
11671
 
11672
            hasCellHeight = true;
230 andreas 11673
        }
233 andreas 11674
        else if (low.find("p1=") != string::npos)
11675
        {
11676
            size_t pos = low.find("=");
11677
            string sP1 = low.substr(pos + 1);
11678
            p1 = atoi(sP1.c_str());
11679
            hasP1 = true;
11680
        }
11681
        else if (low.find("p2=") != string::npos)
11682
        {
11683
            size_t pos = low.find("=");
11684
            string sP2 = low.substr(pos + 1);
11685
            p2 = atoi(sP2.c_str());
11686
            hasP2 = true;
11687
        }
11688
        else if (low.find("f=") != string::npos || low.find("filter=") != string::npos)
11689
        {
11690
            size_t pos = low.find("=");
11691
            string sFilter = low.substr(pos + 1);
11692
            filter = isTrue(sFilter);
11693
            hasFilter = true;
11694
        }
11695
        else if (low.find("fh=") != string::npos || low.find("filterheight=") != string::npos)
11696
        {
11697
            size_t pos = low.find("=");
11698
            string sFilter = low.substr(pos + 1);
11699
            filterheight = atoi(sFilter.c_str());
11700
 
11701
            if (low.find("%") != string::npos)
11702
                filterHeightPercent = true;
11703
 
11704
            hasFilterHeight = true;
11705
        }
11706
        else if (low.find("as=") != string::npos || low.find("alphascroll=") != string::npos)
11707
        {
11708
            size_t pos = low.find("=");
11709
            string sAlpha = low.substr(pos + 1);
11710
            alphascroll = isTrue(sAlpha);
11711
            hasAlphaScroll = true;
11712
        }
230 andreas 11713
    }
11714
 
11715
    vector<TMap::MAP_T> map = findButtons(port, channels);
11716
 
11717
    if (TError::isError() || map.empty())
11718
        return;
11719
 
11720
    vector<Button::TButton *> buttons = collectButtons(map);
11721
 
11722
    if (buttons.size() > 0)
11723
    {
11724
        vector<Button::TButton *>::iterator mapIter;
11725
 
11726
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11727
        {
11728
            Button::TButton *bt = *mapIter;
233 andreas 11729
 
11730
            if (hasColumns)         bt->setListViewColumns(columns);
11731
            if (hasComponent)       bt->setListViewComponent(component);
11732
            if (hasLayout)          bt->setListViewLayout(layout);
11733
            if (hasCellHeight)      bt->setListViewCellheight(cellheight, cellHeightPercent);
11734
            if (hasP1)              bt->setListViewP1(p1);
11735
            if (hasP2)              bt->setListViewP2(p2);
11736
            if (hasFilter)          bt->setListViewColumnFilter(filter);
11737
            if (hasFilterHeight)    bt->setListViewFilterHeight(filterheight, filterHeightPercent);
11738
            if (hasAlphaScroll)     bt->setListViewAlphaScroll(alphascroll);
230 andreas 11739
        }
11740
    }
11741
}
11742
 
233 andreas 11743
void TPageManager::doLVM(int port, vector<int> &channels, vector<string> &pars)
11744
{
11745
    DECL_TRACER("TPageManager::doLVM(int port, vector<int> &channels, vector<string> &pars)");
11746
 
11747
    if (pars.size() < 1)
11748
    {
11749
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
11750
        return;
11751
    }
11752
 
11753
    TError::clear();
11754
    map<string,string> mapField;
11755
 
11756
    vector<string>::iterator iter;
11757
 
11758
    for (iter = pars.begin(); iter != pars.end(); ++iter)
11759
    {
11760
        string left, right;
11761
        size_t pos = 0;
11762
 
11763
        if ((pos = iter->find("=")) != string::npos)
11764
        {
11765
            string left = iter->substr(0, pos);
11766
            left = toLower(left);
11767
            string right = iter->substr(pos + 1);
11768
 
11769
            if (left == "t1" || left == "t2" || left == "i1")
11770
                mapField.insert(pair<string,string>(left, right));
11771
        }
11772
    }
11773
 
11774
    vector<TMap::MAP_T> map = findButtons(port, channels);
11775
 
11776
    if (TError::isError() || map.empty())
11777
        return;
11778
 
11779
    vector<Button::TButton *> buttons = collectButtons(map);
11780
 
11781
    if (buttons.size() > 0)
11782
    {
11783
        vector<Button::TButton *>::iterator mapIter;
11784
 
11785
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11786
        {
11787
            Button::TButton *bt = *mapIter;
11788
            bt->setListViewFieldMap(mapField);
11789
        }
11790
    }
11791
}
11792
 
11793
void TPageManager::doLVN(int port, vector<int> &channels, vector<string> &pars)
11794
{
11795
    DECL_TRACER("TPageManager::doLVN(int port, vector<int> &channels, vector<string> &pars)");
11796
 
11797
    if (pars.size() < 1)
11798
    {
11799
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
11800
        return;
11801
    }
11802
 
11803
    TError::clear();
11804
    string command = pars[0];
11805
    bool select = false;
11806
 
11807
    if (pars.size() > 1)
11808
    {
11809
        if (isTrue(pars[1]))
11810
            select = true;
11811
    }
11812
 
11813
    vector<TMap::MAP_T> map = findButtons(port, channels);
11814
 
11815
    if (TError::isError() || map.empty())
11816
        return;
11817
 
11818
    vector<Button::TButton *> buttons = collectButtons(map);
11819
 
11820
    if (buttons.size() > 0)
11821
    {
11822
        vector<Button::TButton *>::iterator mapIter;
11823
 
11824
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11825
        {
11826
            Button::TButton *bt = *mapIter;
11827
            bt->listViewNavigate(command, select);
11828
        }
11829
    }
11830
}
11831
 
11832
void TPageManager::doLVR(int port, vector<int> &channels, vector<string> &pars)
11833
{
11834
    DECL_TRACER("TPageManager::doLVR(int port, vector<int> &channels, vector<string> &pars)");
11835
 
11836
    TError::clear();
11837
    int interval = -1;
11838
    bool force = false;
11839
 
11840
    if (pars.size() > 0)
11841
        interval = atoi(pars[0].c_str());
11842
 
11843
    if (pars.size() > 1)
11844
        force = isTrue(pars[1]);
11845
 
11846
    vector<TMap::MAP_T> map = findButtons(port, channels);
11847
 
11848
    if (TError::isError() || map.empty())
11849
        return;
11850
 
11851
    vector<Button::TButton *> buttons = collectButtons(map);
11852
 
11853
    if (buttons.size() > 0)
11854
    {
11855
        vector<Button::TButton *>::iterator mapIter;
11856
 
11857
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11858
        {
11859
            Button::TButton *bt = *mapIter;
11860
            bt->listViewRefresh(interval, force);
11861
        }
11862
    }
11863
}
11864
 
11865
void TPageManager::doLVS(int port, vector<int> &channels, vector<string> &pars)
11866
{
11867
    DECL_TRACER("TPageManager::doLVS(int port, vector<int> &channels, vector<string> &pars)");
11868
 
11869
    TError::clear();
11870
    vector<string> sortColumns;
11871
    Button::LIST_SORT sort = Button::LIST_SORT_NONE;
11872
    string override;
11873
 
11874
    if (pars.size() > 0)
11875
    {
11876
        vector<string>::iterator iter;
11877
 
11878
        for (iter = pars.begin(); iter != pars.end(); ++iter)
11879
        {
11880
            if (iter->find(";") == string::npos)
11881
                sortColumns.push_back(*iter);
11882
            else
11883
            {
11884
                vector<string> parts = StrSplit(*iter, ";");
11885
                sortColumns.push_back(parts[0]);
11886
 
11887
                if (parts[1].find("a") != string::npos || parts[1].find("A") != string::npos)
11888
                    sort = Button::LIST_SORT_ASC;
11889
                else if (parts[1].find("d") != string::npos || parts[1].find("D") != string::npos)
11890
                    sort = Button::LIST_SORT_DESC;
11891
                else if (parts[1].find("*") != string::npos)
11892
                {
11893
                    if (parts.size() > 2 && !parts[2].empty())
11894
                    {
11895
                        override = parts[2];
11896
                        sort = Button::LIST_SORT_OVERRIDE;
11897
                    }
11898
                }
11899
                else if (parts[1].find("n") != string::npos || parts[1].find("N") != string::npos)
11900
                    sort = Button::LIST_SORT_NONE;
11901
            }
11902
        }
11903
    }
11904
 
11905
    vector<TMap::MAP_T> map = findButtons(port, channels);
11906
 
11907
    if (TError::isError() || map.empty())
11908
        return;
11909
 
11910
    vector<Button::TButton *> buttons = collectButtons(map);
11911
 
11912
    if (buttons.size() > 0)
11913
    {
11914
        vector<Button::TButton *>::iterator mapIter;
11915
 
11916
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11917
        {
11918
            Button::TButton *bt = *mapIter;
11919
            bt->listViewSortData(sortColumns, sort, override);
11920
        }
11921
    }
11922
}
11923
 
134 andreas 11924
void TPageManager::doTPCCMD(int, vector<int>&, vector<string>& pars)
11925
{
11926
    DECL_TRACER("TPageManager::doTPCCMD(int, vector<int>&, vector<string>& pars)");
11927
 
11928
    if (pars.size() < 1)
11929
    {
11930
        MSG_ERROR("Too few arguments for TPCCMD!");
11931
        return;
11932
    }
11933
 
11934
    string cmd = pars[0];
11935
 
11936
    if (strCaseCompare(cmd, "LocalHost") == 0)
11937
    {
11938
        if (pars.size() < 2 || pars[1].empty())
11939
        {
11940
            MSG_ERROR("The command \"LocalHost\" requires an additional parameter!");
11941
            return;
11942
        }
11943
 
11944
        TConfig::saveController(pars[1]);
11945
    }
11946
    else if (strCaseCompare(cmd, "LocalPort") == 0)
11947
    {
11948
        if (pars.size() < 2 || pars[1].empty())
11949
        {
11950
            MSG_ERROR("The command \"LocalPort\" requires an additional parameter!");
11951
            return;
11952
        }
11953
 
11954
        int port = atoi(pars[1].c_str());
11955
 
11956
        if (port > 0 && port < 65536)
11957
            TConfig::savePort(port);
11958
        else
11959
        {
11960
            MSG_ERROR("Invalid network port " << port);
11961
        }
11962
    }
11963
    else if (strCaseCompare(cmd, "DeviceID") == 0)
11964
    {
11965
        if (pars.size() < 2 || pars[1].empty())
11966
        {
11967
            MSG_ERROR("The command \"DeviceID\" requires an additional parameter!");
11968
            return;
11969
        }
11970
 
11971
        int id = atoi(pars[1].c_str());
11972
 
11973
        if (id >= 10000 && id < 30000)
11974
            TConfig::setSystemChannel(id);
11975
    }
11976
    else if (strCaseCompare(cmd, "ApplyProfile") == 0)
11977
    {
11978
        // We restart the network connection only
11979
        if (gAmxNet)
11980
            gAmxNet->reconnect();
11981
    }
11982
    else if (strCaseCompare(cmd, "QueryDeviceInfo") == 0)
11983
    {
11984
        string info = "DEVICEINFO-TPANELID," + TConfig::getPanelType();
11985
        info += ";HOSTNAME,";
11986
        char hostname[HOST_NAME_MAX];
11987
 
11988
        if (gethostname(hostname, HOST_NAME_MAX) != 0)
11989
        {
11990
            MSG_ERROR("Can't get host name: " << strerror(errno));
11991
            return;
11992
        }
11993
 
11994
        info.append(hostname);
11995
        info += ";UUID," + TConfig::getUUID();
11996
        sendGlobalString(info);
11997
    }
11998
    else if (strCaseCompare(cmd, "LockRotation") == 0)
11999
    {
12000
        if (pars.size() < 2 || pars[1].empty())
12001
        {
12002
            MSG_ERROR("The command \"LockRotation\" requires an additional parameter!");
12003
            return;
12004
        }
12005
 
12006
        if (strCaseCompare(pars[1], "true") == 0)
12007
            TConfig::setRotationFixed(true);
12008
        else
12009
            TConfig::setRotationFixed(false);
12010
    }
12011
    else if (strCaseCompare(cmd, "ButtonHit") == 0)
12012
    {
12013
        if (pars.size() < 2 || pars[1].empty())
12014
        {
12015
            MSG_ERROR("The command \"ButtonHit\" requires an additional parameter!");
12016
            return;
12017
        }
12018
 
12019
        if (strCaseCompare(pars[1], "true") == 0)
12020
            TConfig::saveSystemSoundState(true);
12021
        else
12022
            TConfig::saveSystemSoundState(false);
12023
    }
12024
    else if (strCaseCompare(cmd, "ReprocessTP4") == 0)
12025
    {
12026
        if (_resetSurface)
12027
            _resetSurface();
12028
    }
12029
}
12030
 
12031
void TPageManager::doTPCACC(int, vector<int>&, vector<string>& pars)
12032
{
12033
    DECL_TRACER("TPageManager::doTPCACC(int, vector<int>&, vector<string>& pars)");
12034
 
12035
    if (pars.size() < 1)
12036
    {
12037
        MSG_ERROR("Too few arguments for TPCACC!");
12038
        return;
12039
    }
12040
 
12041
    string cmd = pars[0];
12042
 
12043
    if (strCaseCompare(cmd, "ENABLE") == 0)
12044
    {
12045
        mInformOrientation = true;
12046
        sendOrientation();
12047
    }
12048
    else if (strCaseCompare(cmd, "DISABLE") == 0)
12049
    {
12050
        mInformOrientation = false;
12051
    }
12052
    else if (strCaseCompare(cmd, "QUERY") == 0)
12053
    {
12054
        sendOrientation();
12055
    }
12056
}
153 andreas 12057
 
279 andreas 12058
#ifndef _NOSIP_
153 andreas 12059
void TPageManager::doTPCSIP(int, vector<int>&, vector<string>& pars)
12060
{
12061
    DECL_TRACER("TPageManager::doTPCSIP(int port, vector<int>& channels, vector<string>& pars)");
12062
 
12063
    if (pars.empty())
12064
        return;
12065
 
12066
    string cmd = toUpper(pars[0]);
12067
 
12068
    if (cmd == "SHOW" && _showPhoneDialog)
12069
        _showPhoneDialog(true);
12070
    else if (!_showPhoneDialog)
12071
    {
12072
        MSG_ERROR("There is no phone dialog registered!");
12073
    }
12074
}
279 andreas 12075
#endif