Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 andreas 1
/*
269 andreas 2
 * Copyright (C) 2020 to 2023 by Andreas Theofilu <andreas@theosys.at>
3 andreas 3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software Foundation,
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
17
 */
18
 
270 andreas 19
#include <QtGlobal>
20
 
3 andreas 21
#include <vector>
14 andreas 22
#include <thread>
23
#include <mutex>
186 andreas 24
 
36 andreas 25
#ifdef __ANDROID__
264 andreas 26
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
183 andreas 27
#       include <QtAndroidExtras/QAndroidJniObject>
28
#       include <QtAndroidExtras/QtAndroid>
216 andreas 29
#   else
30
#       include <QJniObject>
31
#       include <QCoreApplication>
183 andreas 32
#   endif
33
#   include <android/log.h>
182 andreas 34
#endif
134 andreas 35
#include <unistd.h>
36
#ifndef __ANDROID__
183 andreas 37
#   include <fstab.h>
134 andreas 38
#endif
14 andreas 39
 
186 andreas 40
#if __cplusplus < 201402L
41
#   error "This module requires at least C++14 standard!"
42
#else
43
#   if __cplusplus < 201703L
44
#       include <experimental/filesystem>
45
namespace fs = std::experimental::filesystem;
46
#       warning "Support for C++14 and experimental filesystem will be removed in a future version!"
47
#   else
48
#       include <filesystem>
49
#       ifdef __ANDROID__
50
namespace fs = std::__fs::filesystem;
51
#       else
52
namespace fs = std::filesystem;
53
#       endif
54
#   endif
55
#endif
56
 
235 andreas 57
#ifdef __APPLE__
58
#   include <unistd.h>
59
#   ifndef HOST_NAME_MAX
60
#       ifdef MAXHOSTNAMELEN
61
#           define HOST_NAME_MAX    MAXHOSTNAMELEN
62
#       else
63
#           define HOST_NAME_MAX    64
64
#       endif   // MAXHOSTNAMELEN
65
#   endif       // HOST_NAME_MAX
66
#endif          // __APPLE__
67
 
3 andreas 68
#include "tpagemanager.h"
4 andreas 69
#include "tcolor.h"
3 andreas 70
#include "terror.h"
8 andreas 71
#include "ticons.h"
14 andreas 72
#include "tbutton.h"
8 andreas 73
#include "tprjresources.h"
11 andreas 74
#include "tresources.h"
271 andreas 75
#include "tresources.h"
71 andreas 76
#include "tsystemsound.h"
77
#include "tvalidatefile.h"
122 andreas 78
#include "ttpinit.h"
211 andreas 79
#include "tconfig.h"
299 andreas 80
#include "tlock.h"
336 andreas 81
#include "tintborder.h"
264 andreas 82
#ifdef Q_OS_IOS
83
#include "ios/tiosbattery.h"
84
#endif
326 andreas 85
#if TESTMODE == 1
86
#include "testmode.h"
87
#endif
3 andreas 88
 
89
using std::vector;
90
using std::string;
11 andreas 91
using std::map;
92
using std::pair;
93
using std::to_string;
14 andreas 94
using std::thread;
95
using std::atomic;
96
using std::mutex;
21 andreas 97
using std::bind;
3 andreas 98
 
8 andreas 99
TIcons *gIcons = nullptr;
100
TPrjResources *gPrjResources = nullptr;
14 andreas 101
TPageManager *gPageManager = nullptr;
169 andreas 102
//std::vector<amx::ANET_COMMAND> TPageManager::mCommands;
103
 
14 andreas 104
extern amx::TAmxNet *gAmxNet;
90 andreas 105
extern std::atomic<bool> _netRunning;
92 andreas 106
extern bool _restart_;                          //!< If this is set to true then the whole program will start over.
8 andreas 107
 
21 andreas 108
bool prg_stopped = false;
14 andreas 109
 
37 andreas 110
#ifdef __ANDROID__
255 andreas 111
string javaJStringToString(JNIEnv *env, jstring str)
112
{
113
    if (!str)
114
        return string();
115
 
116
    const jclass stringClass = env->GetObjectClass(str);
117
    const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
118
    const jbyteArray stringJbytes = (jbyteArray) env->CallObjectMethod(str, getBytes, env->NewStringUTF("UTF-8"));
119
 
120
    size_t length = (size_t) env->GetArrayLength(stringJbytes);
121
    jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL);
122
 
123
    string ret = std::string((char *)pBytes, length);
124
    env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT);
125
 
126
    env->DeleteLocalRef(stringJbytes);
127
    env->DeleteLocalRef(stringClass);
128
    return ret;
129
}
130
 
38 andreas 131
JNIEXPORT void JNICALL Java_org_qtproject_theosys_BatteryState_informBatteryStatus(JNIEnv *, jclass, jint level, jboolean charging, jint chargeType)
132
{
61 andreas 133
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_BatteryState_informBatteryStatus(JNIEnv *, jclass, jint level, jboolean charging, jint chargeType)");
134
 
38 andreas 135
    if (gPageManager)
136
        gPageManager->informBatteryStatus(level, charging, chargeType);
137
}
138
 
36 andreas 139
JNIEXPORT void JNICALL Java_org_qtproject_theosys_NetworkStatus_informTPanelNetwork(JNIEnv */*env*/, jclass /*clazz*/, jboolean conn, jint level, jint type)
140
{
61 andreas 141
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_NetworkStatus_informTPanelNetwork(JNIEnv */*env*/, jclass /*clazz*/, jboolean conn, jint level, jint type)");
365 andreas 142
 
143
    //Call native side conterpart
144
    if (gPageManager)
36 andreas 145
        gPageManager->informTPanelNetwork(conn, level, type);
146
}
47 andreas 147
 
61 andreas 148
JNIEXPORT void JNICALL Java_org_qtproject_theosys_PhoneCallState_informPhoneState(JNIEnv *env, jclass, jboolean call, jstring pnumber)
47 andreas 149
{
61 andreas 150
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_PhoneCallState_informPhoneState(JNIEnv *env, jclass, jboolean call, jstring pnumber)");
151
 
152
    string phoneNumber;
153
 
154
    if (pnumber)
255 andreas 155
        phoneNumber = javaJStringToString(env, pnumber);
61 andreas 156
 
157
    if (gPageManager)
158
        gPageManager->informPhoneState(call, phoneNumber);
47 andreas 159
}
160
 
61 andreas 161
JNIEXPORT void JNICALL Java_org_qtproject_theosys_Logger_logger(JNIEnv *env, jclass, jint mode, jstring msg)
47 andreas 162
{
163
    if (!msg)
164
        return;
165
 
255 andreas 166
    string ret = javaJStringToString(env, msg);
47 andreas 167
 
61 andreas 168
    try
169
    {
170
        if (TStreamError::checkFilter(mode))
260 andreas 171
        {
172
            *TError::Current()->getStream() << TError::append(mode) << ret << std::endl;
173
            TStreamError::resetFlags();
174
        }
61 andreas 175
    }
176
    catch (std::exception& e)
177
    {
178
        __android_log_print(ANDROID_LOG_ERROR, "tpanel", "%s", e.what());
179
    }
47 andreas 180
}
130 andreas 181
 
182
JNIEXPORT void JNICALL Java_org_qtproject_theosys_Orientation_informTPanelOrientation(JNIEnv */*env*/, jclass /*clazz*/, jint orientation)
183
{
184
    DECL_TRACER("Java_org_qtproject_theosys_Orientation_informTPanelOrientation(JNIEnv */*env*/, jclass /*clazz*/, jint orientation)");
185
 
134 andreas 186
    if (!gPageManager)
187
        return;
188
 
189
    if (gPageManager->onOrientationChange())
130 andreas 190
        gPageManager->onOrientationChange()(orientation);
134 andreas 191
 
192
    gPageManager->setOrientation(orientation);
193
 
194
    if (gPageManager->getInformOrientation())
195
        gPageManager->sendOrientation();
130 andreas 196
}
255 andreas 197
 
198
/* -------- Settings -------- */
256 andreas 199
 
200
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_saveSettings(JNIEnv *env, jclass clazz)
255 andreas 201
{
256 andreas 202
    DECL_TRACER("Java_org_qtproject_theosys_SettingsActivity_saveSettings(JNIEnv *env, jclass clazz)");
255 andreas 203
 
256 andreas 204
    Q_UNUSED(env);
255 andreas 205
    Q_UNUSED(clazz);
206
 
259 andreas 207
    TConfig::setTemporary(true);
208
    string oldNetlinx = TConfig::getController();
209
    int oldPort = TConfig::getPort();
210
    int oldChannelID = TConfig::getChannel();
211
    string oldSurface = TConfig::getFtpSurface();
212
    bool oldToolbarSuppress = TConfig::getToolbarSuppress();
213
    bool oldToolbarForce = TConfig::getToolbarForce();
214
    TConfig::setTemporary(false);
215
    MSG_DEBUG("Old values:\n" <<
216
              "   NetLinx: " << oldNetlinx << "\n" <<
217
              "   Port:    " << oldPort << "\n" <<
218
              "   Channel: " << oldChannelID << "\n" <<
219
              "   Surface: " << oldSurface << "\n" <<
220
              "   TB suppr:" << oldToolbarSuppress << "\n" <<
221
              "   TB force:" << oldToolbarForce);
256 andreas 222
    TConfig::saveSettings();
259 andreas 223
 
224
    MSG_DEBUG("New values:\n" <<
225
              "   NetLinx: " << TConfig::getController() << "\n" <<
226
              "   Port:    " << TConfig::getPort() << "\n" <<
227
              "   Channel: " << TConfig::getChannel() << "\n" <<
228
              "   Surface: " << TConfig::getFtpSurface() << "\n" <<
229
              "   TB suppr:" << TConfig::getToolbarSuppress() << "\n" <<
230
              "   TB force:" << TConfig::getToolbarForce());
231
 
232
    if (gPageManager && gPageManager->onSettingsChanged())
233
        gPageManager->onSettingsChanged()(oldNetlinx, oldPort, oldChannelID, oldSurface, oldToolbarSuppress, oldToolbarForce);
256 andreas 234
}
235
 
236
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxIp(JNIEnv *env, jclass clazz, jstring ip)
237
{
238
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxIp(JNIEnv *env, jclass clazz, jstring ip)");
239
 
240
    Q_UNUSED(clazz);
241
 
255 andreas 242
    string netlinxIp = javaJStringToString(env, ip);
243
 
244
    if (TConfig::getController() != netlinxIp)
245
        TConfig::saveController(netlinxIp);
246
}
247
 
256 andreas 248
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxPort(JNIEnv *env, jclass clazz, jint port)
255 andreas 249
{
256 andreas 250
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxPort(JNIEnv *env, jclass clazz, jint port)");
255 andreas 251
 
252
    Q_UNUSED(env);
253
    Q_UNUSED(clazz);
254
 
255
    if (port > 0 && port < 65535 && TConfig::getPort() != port)
256
        TConfig::savePort(port);
257
}
258
 
256 andreas 259
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxChannel(JNIEnv *env, jclass clazz, jint channel)
255 andreas 260
{
256 andreas 261
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxChannel(JNIEnv *env, jclass clazz, jint channel)");
255 andreas 262
 
263
    Q_UNUSED(env);
264
    Q_UNUSED(clazz);
265
 
266
    if (channel >= 10000 && channel < 20000 && TConfig::getChannel() != channel)
271 andreas 267
        TConfig::saveChannel(channel);
255 andreas 268
}
256 andreas 269
 
270
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxType(JNIEnv *env, jclass clazz, jstring type)
271
{
272
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxType(JNIEnv *env, jclass clazz, jstring type)");
273
 
274
    Q_UNUSED(clazz);
275
 
276
    string netlinxType = javaJStringToString(env, type);
277
 
278
    if (TConfig::getPanelType() != netlinxType)
279
        TConfig::savePanelType(netlinxType);
280
}
281
 
282
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxFtpUser(JNIEnv *env, jclass clazz, jstring user)
283
{
284
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxFtpUser(JNIEnv *env, jclass clazz, jstring user)");
285
 
286
    Q_UNUSED(clazz);
287
 
288
    string netlinxFtpUser = javaJStringToString(env, user);
289
 
290
    if (TConfig::getFtpUser() != netlinxFtpUser)
291
        TConfig::saveFtpUser(netlinxFtpUser);
292
}
293
 
294
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxFtpPassword(JNIEnv *env, jclass clazz, jstring pw)
295
{
296
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxFtpPassword(JNIEnv *env, jclass clazz, jstring pw)");
297
 
298
    Q_UNUSED(clazz);
299
 
300
    string netlinxPw = javaJStringToString(env, pw);
301
 
302
    if (TConfig::getFtpPassword() != netlinxPw)
303
        TConfig::saveFtpPassword(netlinxPw);
304
}
305
 
306
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxSurface(JNIEnv *env, jclass clazz, jstring surface)
307
{
308
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxIp(JNIEnv *env, jclass clazz, jstring surface)");
309
 
310
    Q_UNUSED(clazz);
311
 
312
    string netlinxSurface = javaJStringToString(env, surface);
313
 
314
    if (TConfig::getFtpSurface() != netlinxSurface)
315
        TConfig::saveFtpSurface(netlinxSurface);
316
}
317
 
318
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setNetlinxFtpPassive(JNIEnv *env, jclass clazz, jboolean passive)
319
{
320
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setNetlinxIp(JNIEnv *env, jclass clazz, jboolean passive)");
321
 
322
    Q_UNUSED(env);
323
    Q_UNUSED(clazz);
324
 
325
    if (TConfig::getFtpPassive() != passive)
326
        TConfig::saveFtpPassive(passive);
327
}
328
 
329
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setViewScale(JNIEnv *env, jclass clazz, jboolean scale)
330
{
331
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setViewScale(JNIEnv *env, jclass clazz, jboolean scale)");
332
 
333
    Q_UNUSED(env);
334
    Q_UNUSED(clazz);
335
 
336
    if (TConfig::getScale() != scale)
337
        TConfig::saveScale(scale);
338
}
339
 
340
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setViewToolbar(JNIEnv *env, jclass clazz, jboolean bar)
341
{
342
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setViewToolbar(JNIEnv *env, jclass clazz, jboolean bar)");
343
 
344
    Q_UNUSED(env);
345
    Q_UNUSED(clazz);
346
 
260 andreas 347
    if (TConfig::getToolbarSuppress() == bar)
348
        TConfig::saveToolbarSuppress(!bar);
256 andreas 349
}
350
 
351
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setViewToolbarForce(JNIEnv *env, jclass clazz, jboolean bar)
352
{
353
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setViewToolbarForce(JNIEnv *env, jclass clazz, jboolean bar)");
354
 
355
    Q_UNUSED(env);
356
    Q_UNUSED(clazz);
357
 
358
    if (TConfig::getToolbarForce() != bar)
359
        TConfig::saveToolbarForce(bar);
360
}
361
 
362
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setViewRotation(JNIEnv *env, jclass clazz, jboolean rotate)
363
{
364
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setViewRotation(JNIEnv *env, jclass clazz, jboolean rotate)");
365
 
366
    Q_UNUSED(env);
367
    Q_UNUSED(clazz);
368
 
369
    if (TConfig::getRotationFixed() != rotate)
370
        TConfig::setRotationFixed(rotate);
371
}
372
 
373
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundSystem(JNIEnv *env, jclass clazz, jstring sound)
374
{
375
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundSystem(JNIEnv *env, jclass clazz, jstring sound)");
376
 
377
    Q_UNUSED(clazz);
378
 
379
    string s = javaJStringToString(env, sound);
380
 
381
    if (TConfig::getSystemSound() != s)
382
        TConfig::saveSystemSoundFile(s);
383
}
384
 
385
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundSingle(JNIEnv *env, jclass clazz, jstring sound)
386
{
387
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundSingle(JNIEnv *env, jclass clazz, jstring sound)");
388
 
389
    Q_UNUSED(clazz);
390
 
391
    string s = javaJStringToString(env, sound);
392
 
393
    if (TConfig::getSingleBeepSound() != s)
394
        TConfig::saveSingleBeepFile(s);
395
}
396
 
397
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundDouble(JNIEnv *env, jclass clazz, jstring sound)
398
{
399
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundDouble(JNIEnv *env, jclass clazz, jstring sound)");
400
 
401
    Q_UNUSED(clazz);
402
 
403
    string s = javaJStringToString(env, sound);
404
 
405
    if (TConfig::getDoubleBeepSound() != s)
406
        TConfig::saveDoubleBeepFile(s);
407
}
408
 
409
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundEnable(JNIEnv *env, jclass clazz, jboolean sound)
410
{
411
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundEnable(JNIEnv *env, jclass clazz, jboolean sound)");
412
 
413
    Q_UNUSED(env);
414
    Q_UNUSED(clazz);
415
 
416
    if (TConfig::getSystemSoundState() != sound)
417
        TConfig::saveSystemSoundState(sound);
418
}
419
 
420
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundVolume(JNIEnv *env, jclass clazz, jint sound)
421
{
422
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundVolume(JNIEnv *env, jclass clazz, jint sound)");
423
 
424
    Q_UNUSED(env);
425
    Q_UNUSED(clazz);
426
 
427
    if (TConfig::getSystemVolume() != sound)
428
        TConfig::saveSystemVolume(sound);
429
}
430
 
431
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSoundGain(JNIEnv *env, jclass clazz, jint sound)
432
{
433
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSoundGain(JNIEnv *env, jclass clazz, jint sound)");
434
 
435
    Q_UNUSED(env);
436
    Q_UNUSED(clazz);
437
 
438
    if (TConfig::getSystemGain() != sound)
439
        TConfig::saveSystemGain(sound);
440
}
257 andreas 441
 
442
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipProxy(JNIEnv *env, jclass clazz, jstring sip)
443
{
444
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipProxy(JNIEnv *env, jclass clazz, jstring sip)");
445
 
446
    Q_UNUSED(clazz);
447
 
448
    string sipStr = javaJStringToString(env, sip);
449
 
450
    if (TConfig::getSIPproxy() != sipStr)
451
        TConfig::setSIPproxy(sipStr);
452
}
453
 
454
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipPort(JNIEnv *env, jclass clazz, jint sip)
455
{
456
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipPort(JNIEnv *env, jclass clazz, jint sip)");
457
 
458
    Q_UNUSED(env);
459
    Q_UNUSED(clazz);
460
 
461
    if (TConfig::getSIPport() != sip)
462
        TConfig::setSIPport(sip);
463
}
464
 
465
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipTlsPort(JNIEnv *env, jclass clazz, jint sip)
466
{
467
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipTlsPort(JNIEnv *env, jclass clazz, jint sip)");
468
 
469
    Q_UNUSED(env);
470
    Q_UNUSED(clazz);
471
 
472
    if (TConfig::getSIPportTLS() != sip)
473
        TConfig::setSIPportTLS(sip);
474
}
475
 
476
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipStun(JNIEnv *env, jclass clazz, jstring sip)
477
{
478
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipStun(JNIEnv *env, jclass clazz, jstring sip)");
479
 
480
    Q_UNUSED(clazz);
481
 
482
    string sipStr = javaJStringToString(env, sip);
483
 
484
    if (TConfig::getSIPstun() != sipStr)
485
        TConfig::setSIPstun(sipStr);
486
}
487
 
488
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipDomain(JNIEnv *env, jclass clazz, jstring sip)
489
{
490
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipDomain(JNIEnv *env, jclass clazz, jstring sip)");
491
 
492
    Q_UNUSED(clazz);
493
 
494
    string sipStr = javaJStringToString(env, sip);
495
 
496
    if (TConfig::getSIPdomain() != sipStr)
497
        TConfig::setSIPdomain(sipStr);
498
}
499
 
500
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipUser(JNIEnv *env, jclass clazz, jstring sip)
501
{
502
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipUser(JNIEnv *env, jclass clazz, jstring sip)");
503
 
504
    Q_UNUSED(clazz);
505
 
506
    string sipStr = javaJStringToString(env, sip);
507
 
508
    if (TConfig::getSIPuser() != sipStr)
509
        TConfig::setSIPuser(sipStr);
510
}
511
 
512
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipPassword(JNIEnv *env, jclass clazz, jstring sip)
513
{
514
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipPassword(JNIEnv *env, jclass clazz, jstring sip)");
515
 
516
    Q_UNUSED(clazz);
517
 
518
    string sipStr = javaJStringToString(env, sip);
519
 
520
    if (TConfig::getSIPpassword() != sipStr)
521
        TConfig::setSIPpassword(sipStr);
522
}
523
 
524
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipIpv4(JNIEnv *env, jclass clazz, jboolean sip)
525
{
526
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipIpv4(JNIEnv *env, jclass clazz, jboolean sip)");
527
 
528
    Q_UNUSED(env);
529
    Q_UNUSED(clazz);
530
 
531
    if (TConfig::getSIPnetworkIPv4() != sip)
532
        TConfig::setSIPnetworkIPv4(sip);
533
}
534
 
535
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipIpv6(JNIEnv *env, jclass clazz, jboolean sip)
536
{
537
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipIpv6(JNIEnv *env, jclass clazz, jboolean sip)");
538
 
539
    Q_UNUSED(env);
540
    Q_UNUSED(clazz);
541
 
542
    if (TConfig::getSIPnetworkIPv6() != sip)
543
        TConfig::setSIPnetworkIPv6(sip);
544
}
545
 
546
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipEnabled(JNIEnv *env, jclass clazz, jboolean sip)
547
{
548
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipEnabled(JNIEnv *env, jclass clazz, jboolean sip)");
549
 
550
    Q_UNUSED(env);
551
    Q_UNUSED(clazz);
552
 
553
    if (TConfig::getSIPstatus() != sip)
554
        TConfig::setSIPstatus(sip);
555
}
556
 
557
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setSipIphone(JNIEnv *env, jclass clazz, jboolean sip)
558
{
559
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setSipIphone(JNIEnv *env, jclass clazz, jboolean sip)");
560
 
561
    Q_UNUSED(env);
562
    Q_UNUSED(clazz);
563
 
564
    if (TConfig::getSIPiphone() != sip)
565
        TConfig::setSIPiphone(sip);
566
}
567
 
568
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogInfo(JNIEnv *env, jclass clazz, jboolean log)
569
{
570
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogInfo(JNIEnv *env, jclass clazz, jboolean log)");
571
 
572
    Q_UNUSED(env);
573
    Q_UNUSED(clazz);
574
 
575
    uint logSwitch = (log ? HLOG_INFO : 0);
576
 
577
    if ((TConfig::getLogLevelBits() & HLOG_INFO) != logSwitch)
578
    {
579
        if (!(TConfig::getLogLevelBits() & HLOG_INFO))
580
            TConfig::saveLogLevel(TConfig::getLogLevelBits() | HLOG_INFO);
581
        else
582
            TConfig::saveLogLevel(TConfig::getLogLevelBits() ^ HLOG_INFO);
583
    }
584
}
585
 
586
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogWarning(JNIEnv *env, jclass clazz, jboolean log)
587
{
588
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogWarning(JNIEnv *env, jclass clazz, jboolean log)");
589
 
590
    Q_UNUSED(env);
591
    Q_UNUSED(clazz);
592
 
593
    uint logSwitch = (log ? HLOG_WARNING : 0);
594
 
595
    if ((TConfig::getLogLevelBits() & HLOG_WARNING) != logSwitch)
596
    {
597
        if (!(TConfig::getLogLevelBits() & HLOG_INFO))
598
            TConfig::saveLogLevel(TConfig::getLogLevelBits() | HLOG_WARNING);
599
        else
600
            TConfig::saveLogLevel(TConfig::getLogLevelBits() ^ HLOG_WARNING);
601
    }
602
}
603
 
604
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogError(JNIEnv *env, jclass clazz, jboolean log)
605
{
606
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogError(JNIEnv *env, jclass clazz, jboolean log)");
607
 
608
    Q_UNUSED(env);
609
    Q_UNUSED(clazz);
610
 
611
    uint logSwitch = (log ? HLOG_ERROR : 0);
612
 
613
    if ((TConfig::getLogLevelBits() & HLOG_ERROR) != logSwitch)
614
    {
615
        if (!(TConfig::getLogLevelBits() & HLOG_ERROR))
616
            TConfig::saveLogLevel(TConfig::getLogLevelBits() | HLOG_ERROR);
617
        else
618
            TConfig::saveLogLevel(TConfig::getLogLevelBits() ^ HLOG_ERROR);
619
    }
620
}
621
 
622
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogTrace(JNIEnv *env, jclass clazz, jboolean log)
623
{
624
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogTrace(JNIEnv *env, jclass clazz, jboolean log)");
625
 
626
    Q_UNUSED(env);
627
    Q_UNUSED(clazz);
628
 
629
    uint logSwitch = (log ? HLOG_TRACE : 0);
630
 
631
    if ((TConfig::getLogLevelBits() & HLOG_TRACE) != logSwitch)
632
    {
633
        if (!(TConfig::getLogLevelBits() & HLOG_TRACE))
634
            TConfig::saveLogLevel(TConfig::getLogLevelBits() | HLOG_TRACE);
635
        else
636
            TConfig::saveLogLevel(TConfig::getLogLevelBits() ^ HLOG_TRACE);
637
    }
638
}
639
 
640
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogDebug(JNIEnv *env, jclass clazz, jboolean log)
641
{
642
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogDebug(JNIEnv *env, jclass clazz, jboolean log)");
643
 
644
    Q_UNUSED(env);
645
    Q_UNUSED(clazz);
646
 
647
    uint logSwitch = (log ? HLOG_DEBUG : 0);
648
 
649
    if ((TConfig::getLogLevelBits() & HLOG_DEBUG) != logSwitch)
650
    {
651
        if (!(TConfig::getLogLevelBits() & HLOG_DEBUG))
652
            TConfig::saveLogLevel(TConfig::getLogLevelBits() | HLOG_DEBUG);
653
        else
654
            TConfig::saveLogLevel(TConfig::getLogLevelBits() ^ HLOG_DEBUG);
655
    }
656
}
657
 
658
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogProfile(JNIEnv *env, jclass clazz, jboolean log)
659
{
660
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogProfile(JNIEnv *env, jclass clazz, jboolean log)");
661
 
662
    Q_UNUSED(env);
663
    Q_UNUSED(clazz);
664
 
665
    if (TConfig::getProfiling() != log)
666
        TConfig::saveProfiling(log);
667
}
668
 
669
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogLongFormat(JNIEnv *env, jclass clazz, jboolean log)
670
{
671
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogLongFormat(JNIEnv *env, jclass clazz, jboolean log)");
672
 
673
    Q_UNUSED(env);
674
    Q_UNUSED(clazz);
675
 
676
    if (TConfig::isLongFormat() != log)
677
        TConfig::saveFormat(log);
678
}
679
 
680
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogEnableFile(JNIEnv *env, jclass clazz, jboolean log)
681
{
682
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogEnableFile(JNIEnv *env, jclass clazz, jboolean log)");
683
 
684
    Q_UNUSED(env);
685
    Q_UNUSED(clazz);
686
 
383 andreas 687
    TConfig::setLogFileEnabled(log);
385 andreas 688
    TStreamError::setLogFileEnabled(log);
689
    string logFile = TConfig::getLogFile();
383 andreas 690
 
385 andreas 691
    if (log && !logFile.empty() && fs::is_regular_file(logFile))
692
        TStreamError::setLogFile(logFile);
693
    else if (!log)
694
        TStreamError::setLogFile("");
383 andreas 695
 
385 andreas 696
    __android_log_print(ANDROID_LOG_DEBUG, "tpanel", "JAVA::setLogEnableFile: Logfile was %s", (log ? "ENABLED" : "DISABLED"));
257 andreas 697
}
698
 
699
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setLogFile(JNIEnv *env, jclass clazz, jstring log)
700
{
701
    DECL_TRACER("Java_org_qtproject_theosys_Settings_setLogFile(JNIEnv *env, jclass clazz, jstring sip)");
702
 
703
    Q_UNUSED(clazz);
704
 
705
    string logStr = javaJStringToString(env, log);
706
 
707
    if (TConfig::getLogFile() != logStr)
385 andreas 708
    {
257 andreas 709
        TConfig::saveLogFile(logStr);
385 andreas 710
        __android_log_print(ANDROID_LOG_DEBUG, "tpanel", "JAVA::setLogFile: Logfile set to: %s", logStr.c_str());
711
 
712
        if (fs::is_regular_file(logStr))
713
            TStreamError::setLogFile(logStr);
714
        else
715
        {
716
            TStreamError::setLogFile("");
717
            __android_log_print(ANDROID_LOG_WARN, "tpanel", "JAVA::setLogFile: Logfile \"%s\" is not accessible!", logStr.c_str());
718
        }
719
    }
257 andreas 720
}
397 andreas 721
 
722
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setPassword1(JNIEnv *env, jclass clazz, jstring pw)
723
{
724
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_SettingsActivity_setPassword1(JNIEnv *env, jclass clazz, jstring pw)");
725
 
726
    Q_UNUSED(clazz);
727
 
728
    string password = javaJStringToString(env, pw);
729
    TConfig::savePassword1(password);
730
}
731
 
732
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setPassword2(JNIEnv *env, jclass clazz, jstring pw)
733
{
734
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_SettingsActivity_setPassword2(JNIEnv *env, jclass clazz, jstring pw)");
735
 
736
    Q_UNUSED(clazz);
737
 
738
    string password = javaJStringToString(env, pw);
739
    TConfig::savePassword2(password);
740
}
741
 
742
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setPassword3(JNIEnv *env, jclass clazz, jstring pw)
743
{
744
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_SettingsActivity_setPassword3(JNIEnv *env, jclass clazz, jstring pw)");
745
 
746
    Q_UNUSED(clazz);
747
 
748
    string password = javaJStringToString(env, pw);
749
    TConfig::savePassword3(password);
750
}
751
 
752
JNIEXPORT void JNICALL Java_org_qtproject_theosys_SettingsActivity_setPassword4(JNIEnv *env, jclass clazz, jstring pw)
753
{
754
    DECL_TRACER("JNICALL Java_org_qtproject_theosys_SettingsActivity_setPassword4(JNIEnv *env, jclass clazz, jstring pw)");
755
 
756
    Q_UNUSED(clazz);
757
 
758
    string password = javaJStringToString(env, pw);
759
    TConfig::savePassword4(password);
760
}
37 andreas 761
#endif
36 andreas 762
 
3 andreas 763
TPageManager::TPageManager()
764
{
299 andreas 765
    TLOCKER(surface_mutex);
3 andreas 766
    DECL_TRACER("TPageManager::TPageManager()");
767
 
14 andreas 768
    gPageManager = this;
122 andreas 769
    TTPInit *tinit = new TTPInit;
186 andreas 770
    string projectPath = TConfig::getProjectPath();
197 andreas 771
    string pp = projectPath + "/prj.xma";
186 andreas 772
 
773
    tinit->setPath(projectPath);
156 andreas 774
    bool haveSurface = false;
122 andreas 775
 
776
    if (tinit->isVirgin())
156 andreas 777
        haveSurface = tinit->loadSurfaceFromController();
778
    else
779
        haveSurface = true;
122 andreas 780
 
197 andreas 781
    if (!fs::exists(pp))
193 andreas 782
    {
197 andreas 783
        projectPath = TConfig::getSystemProjectPath();
784
        pp = projectPath + "/prj.xma";
193 andreas 785
        mSetupActive = true;
786
    }
186 andreas 787
 
156 andreas 788
    if (!haveSurface)
789
    {
271 andreas 790
        if (!isValidFile(pp))
791
            tinit->reinitialize();
156 andreas 792
    }
159 andreas 793
    else
794
        tinit->makeSystemFiles();
156 andreas 795
 
122 andreas 796
    delete tinit;
156 andreas 797
 
43 andreas 798
    // Read the AMX panel settings.
186 andreas 799
    mTSettings = new TSettings(projectPath);
3 andreas 800
 
801
    if (TError::isError())
14 andreas 802
    {
23 andreas 803
        MSG_ERROR("Settings were not read successfull!");
3 andreas 804
        return;
14 andreas 805
    }
3 andreas 806
 
193 andreas 807
    if (!mSetupActive)
808
    {
197 andreas 809
        mSystemSettings = new TSettings(TConfig::getSystemProjectPath());
193 andreas 810
 
811
        if (TError::isError())
812
        {
813
            MSG_ERROR("System settings were not read successfull!");
814
            delete mTSettings;
815
            mTSettings = nullptr;
816
            return;
817
        }
818
    }
819
    else
820
        mSystemSettings = mTSettings;
821
 
178 andreas 822
    // Set the panel type from the project information
193 andreas 823
    if (!mSetupActive)
824
        TConfig::savePanelType(mTSettings->getPanelType());
178 andreas 825
 
122 andreas 826
    readMap();  // Start the initialisation of the AMX part.
827
 
8 andreas 828
    gPrjResources = new TPrjResources(mTSettings->getResourcesList());
4 andreas 829
    mPalette = new TPalette();
830
    vector<PALETTE_SETUP> pal = mTSettings->getSettings().palettes;
831
 
83 andreas 832
    if (pal.size() > 0)
833
    {
834
        vector<PALETTE_SETUP>::iterator iterPal;
4 andreas 835
 
118 andreas 836
        for (iterPal = pal.begin(); iterPal != pal.end(); ++iterPal)
83 andreas 837
            mPalette->initialize(iterPal->file);
838
    }
839
 
4 andreas 840
    if (!TError::isError())
841
        TColor::setPalette(mPalette);
842
 
7 andreas 843
    mFonts = new TFont();
844
 
845
    if (TError::isError())
846
    {
847
        MSG_ERROR("Initializing fonts was not successfull!");
848
    }
849
 
8 andreas 850
    gIcons = new TIcons();
851
 
852
    if (TError::isError())
853
    {
854
        MSG_ERROR("Initializing icons was not successfull!");
855
    }
856
 
3 andreas 857
    mPageList = new TPageList();
32 andreas 858
    mExternal = new TExternal();
4 andreas 859
    PAGELIST_T page;
860
 
194 andreas 861
    if (!mSetupActive)
3 andreas 862
    {
194 andreas 863
        if (!mTSettings->getSettings().powerUpPage.empty())
14 andreas 864
        {
194 andreas 865
            if (readPage(mTSettings->getSettings().powerUpPage))
866
            {
867
                MSG_TRACE("Found power up page " << mTSettings->getSettings().powerUpPage);
868
                page = findPage(mTSettings->getSettings().powerUpPage);
869
                mActualPage = page.pageID;
870
            }
14 andreas 871
        }
194 andreas 872
        else
873
        {
874
            MSG_WARNING("No power up page defined! Setting default page to 1.");
875
            mActualPage = 1;
876
        }
3 andreas 877
    }
23 andreas 878
    else
879
    {
194 andreas 880
        if (!mSystemSettings->getSettings().powerUpPage.empty())
881
        {
882
            if (readPage(mSystemSettings->getSettings().powerUpPage))
883
            {
884
                MSG_TRACE("Found power up page " << mSystemSettings->getSettings().powerUpPage);
885
                page = findPage(mSystemSettings->getSettings().powerUpPage);
886
                mActualPage = page.pageID;
887
            }
888
        }
889
        else
890
        {
891
            MSG_WARNING("No power up page defined! Setting default page to 5001.");
892
            mActualPage = 5001;
893
        }
23 andreas 894
    }
3 andreas 895
 
4 andreas 896
    TPage *pg = getPage(mActualPage);
897
 
194 andreas 898
    vector<string> popups;
3 andreas 899
 
194 andreas 900
    if (!mSetupActive)
901
        popups = mTSettings->getSettings().powerUpPopup;
902
    else
903
        popups = mSystemSettings->getSettings().powerUpPopup;
904
 
83 andreas 905
    if (popups.size() > 0)
3 andreas 906
    {
83 andreas 907
        vector<string>::iterator iter;
908
 
118 andreas 909
        for (iter = popups.begin(); iter != popups.end(); ++iter)
14 andreas 910
        {
88 andreas 911
            if (readSubPage(*iter))
83 andreas 912
            {
88 andreas 913
                MSG_TRACE("Found power up popup " << *iter);
3 andreas 914
 
88 andreas 915
                if (pg)
916
                {
917
                    TSubPage *spage = getSubPage(*iter);
350 andreas 918
                    spage->setParent(pg->getHandle());
88 andreas 919
                    pg->addSubPage(spage);
920
                }
83 andreas 921
            }
4 andreas 922
        }
3 andreas 923
    }
11 andreas 924
 
73 andreas 925
    // Here we initialize the system resources like borders, cursors, sliders, ...
926
    mSystemDraw = new TSystemDraw(TConfig::getSystemPath(TConfig::BASE));
927
 
928
    // Here are the commands supported by this emulation.
13 andreas 929
    MSG_INFO("Registering commands ...");
318 andreas 930
    REG_CMD(doLEVON, "LEVON");  // Enable device to send level changes to the master.
931
    REG_CMD(doLEVOF, "LEVOF");  // Disable the device from sending level changes to the master.
932
    REG_CMD(doRXON, "RXON");    // Enable device to send STRING changes to the master.
933
    REG_CMD(doRXOF, "RXOF");    // Disable the device from sending STRING changes to the master.
147 andreas 934
    REG_CMD(doAFP, "@AFP");     // Flips to a page with the specified page name using an animated transition.
935
    REG_CMD(doAFP, "^AFP");     // Flips to a page with the specified page name using an animated transition.
38 andreas 936
    REG_CMD(doAPG, "@APG");     // Add a specific popup page to a specified popup group.
937
    REG_CMD(doCPG, "@CPG");     // Clear all popup pages from specified popup group.
938
    REG_CMD(doDPG, "@DPG");     // Delete a specific popup page from specified popup group if it exists
939
//    REG_CMD(doPDR, "@PDR");     // Set the popup location reset flag.
940
    REG_CMD(doPHE, "@PHE");     // Set the hide effect for the specified popup page to the named hide effect.
941
    REG_CMD(doPHP, "@PHP");     // Set the hide effect position.
942
    REG_CMD(doPHT, "@PHT");     // Set the hide effect time for the specified popup page.
943
    REG_CMD(doPPA, "@PPA");     // Close all popups on a specified page.
104 andreas 944
    REG_CMD(doPPA, "^PPA");     // G5: Close all popups on a specified page.
38 andreas 945
    REG_CMD(doPPF, "@PPF");     // Deactivate a specific popup page on either a specified page or the current page.
104 andreas 946
    REG_CMD(doPPF, "^PPF");     // G5: Deactivate a specific popup page on either a specified page or the current page.
38 andreas 947
    REG_CMD(doPPF, "PPOF");     // Deactivate a specific popup page on either a specified page or the current page
948
    REG_CMD(doPPG, "@PPG");     // Toggle a specific popup page on either a specified page or the current page.
104 andreas 949
    REG_CMD(doPPG, "^PPG");     // G5: Toggle a specific popup page on either a specified page or the current page.
38 andreas 950
    REG_CMD(doPPG, "PPOG");     // Toggle a specific popup page on either a specified page or the current page.
951
    REG_CMD(doPPK, "@PPK");     // Kill a specific popup page from all pages.
104 andreas 952
    REG_CMD(doPPK, "^PPK");     // G5: Kill a specific popup page from all pages.
38 andreas 953
    REG_CMD(doPPM, "@PPM");     // Set the modality of a specific popup page to Modal or NonModal.
104 andreas 954
    REG_CMD(doPPM, "^PPM");     // G5: Set the modality of a specific popup page to Modal or NonModal.
38 andreas 955
    REG_CMD(doPPN, "@PPN");     // Activate a specific popup page to launch on either a specified page or the current page.
104 andreas 956
    REG_CMD(doPPN, "^PPN");     // G5: Activate a specific popup page to launch on either a specified page or the current page.
38 andreas 957
    REG_CMD(doPPN, "PPON");     // Activate a specific popup page to launch on either a specified page or the current page.
958
    REG_CMD(doPPT, "@PPT");     // Set a specific popup page to timeout within a specified time.
104 andreas 959
    REG_CMD(doPPT, "^PPT");     // G5: Set a specific popup page to timeout within a specified time.
38 andreas 960
    REG_CMD(doPPX, "@PPX");     // Close all popups on all pages.
104 andreas 961
    REG_CMD(doPPX, "^PPX");     // G5: Close all popups on all pages.
38 andreas 962
    REG_CMD(doPSE, "@PSE");     // Set the show effect for the specified popup page to the named show effect.
963
    REG_CMD(doPSP, "@PSP");     // Set the show effect position.
964
    REG_CMD(doPST, "@PST");     // Set the show effect time for the specified popup page.
965
    REG_CMD(doPAGE, "PAGE");    // Flip to a specified page.
104 andreas 966
    REG_CMD(doPAGE, "^PGE");    // G5: Flip to a specified page.
11 andreas 967
 
38 andreas 968
    REG_CMD(doANI, "^ANI");     // Run a button animation (in 1/10 second).
969
    REG_CMD(doAPF, "^APF");     // Add page flip action to a button if it does not already exist.
43 andreas 970
    REG_CMD(doBAT, "^BAT");     // Append non-unicode text.
60 andreas 971
    REG_CMD(doBAU, "^BAU");     // Append unicode text. Same format as ^UNI.
43 andreas 972
    REG_CMD(doBCB, "^BCB");     // Set the border color.
82 andreas 973
    REG_CMD(getBCB, "?BCB");    // Get the current border color.
60 andreas 974
    REG_CMD(doBCF, "^BCF");     // Set the fill color to the specified color.
82 andreas 975
    REG_CMD(getBCF, "?BCF");    // Get the current fill color.
60 andreas 976
    REG_CMD(doBCT, "^BCT");     // Set the text color to the specified color.
82 andreas 977
    REG_CMD(getBCT, "?BCT");    // Get the current text color.
60 andreas 978
    REG_CMD(doBDO, "^BDO");     // Set the button draw order
979
    REG_CMD(doBFB, "^BFB");     // Set the feedback type of the button.
224 andreas 980
    REG_CMD(doBIM, "^BIM");     // Set the input mask for the specified address
149 andreas 981
    REG_CMD(doBMC, "^BMC");     // Button copy command.
982
    REG_CMD(doBMF, "^BMF");     // Button Modify Command - Set any/all button parameters by sending embedded codes and data.
106 andreas 983
//    REG_CMD(doBMI, "^BMI");    // Set the button mask image.
149 andreas 984
    REG_CMD(doBML, "^BML");     // Set the maximum length of the text area button.
38 andreas 985
    REG_CMD(doBMP, "^BMP");     // Assign a picture to those buttons with a defined addressrange.
82 andreas 986
    REG_CMD(getBMP, "?BMP");    // Get the current bitmap name.
38 andreas 987
    REG_CMD(doBOP, "^BOP");     // Set the button opacity.
106 andreas 988
    REG_CMD(getBOP, "?BOP");    // Get the button opacity.
60 andreas 989
    REG_CMD(doBOR, "^BOR");     // Set a border to a specific border style.
107 andreas 990
    REG_CMD(doBOS, "^BOS");     // Set the button to display either a Video or Non-Video window.
60 andreas 991
    REG_CMD(doBRD, "^BRD");     // Set the border of a button state/states.
107 andreas 992
    REG_CMD(getBRD, "?BRD");    // Get the border of a button state/states.
103 andreas 993
//    REG_CMD(doBSF, "^BSF");     // Set the focus to the text area.
38 andreas 994
    REG_CMD(doBSP, "^BSP");     // Set the button size and position.
107 andreas 995
    REG_CMD(doBSM, "^BSM");     // Submit text for text area buttons.
996
    REG_CMD(doBSO, "^BSO");     // Set the sound played when a button is pressed.
38 andreas 997
    REG_CMD(doBWW, "^BWW");     // Set the button word wrap feature to those buttons with a defined address range.
108 andreas 998
    REG_CMD(getBWW, "?BWW");    // Get the button word wrap feature to those buttons with a defined address range.
38 andreas 999
    REG_CMD(doCPF, "^CPF");     // Clear all page flips from a button.
1000
    REG_CMD(doDPF, "^DPF");     // Delete page flips from button if it already exists.
1001
    REG_CMD(doENA, "^ENA");     // Enable or disable buttons with a set variable text range.
1002
    REG_CMD(doFON, "^FON");     // Set a font to a specific Font ID value for those buttons with a range.
108 andreas 1003
    REG_CMD(getFON, "?FON");    // Get the current font index.
388 andreas 1004
    REG_CMD(doGDI, "^GDI");     // Change the bargraph drag increment.
103 andreas 1005
//    REG_CMD(doGDV, "^GDV");     // Invert the joystick axis to move the origin to another corner.
60 andreas 1006
    REG_CMD(doGLH, "^GLH");     // Change the bargraph upper limit.
1007
    REG_CMD(doGLL, "^GLL");     // Change the bargraph lower limit.
388 andreas 1008
    REG_CMD(doGRD, "^GRD");     // Change the bargraph ramp down time.
1009
    REG_CMD(doGRU, "^GRU");     // Change the bargraph ramp up time.
361 andreas 1010
    REG_CMD(doGSN, "^GSN");     // Set slider/cursor name.
108 andreas 1011
    REG_CMD(doGSC, "^GSC");     // Change the bargraph slider color or joystick cursor color.
38 andreas 1012
    REG_CMD(doICO, "^ICO");     // Set the icon to a button.
108 andreas 1013
    REG_CMD(getICO, "?ICO");    // Get the current icon index.
1014
    REG_CMD(doJSB, "^JSB");     // Set bitmap/picture alignment using a numeric keypad layout for those buttons with a defined address range.
1015
    REG_CMD(getJSB, "?JSB");    // Get the current bitmap justification.
1016
    REG_CMD(doJSI, "^JSI");     // Set icon alignment using a numeric keypad layout for those buttons with a defined address range.
1017
    REG_CMD(getJSI, "?JSI");    // Get the current icon justification.
1018
    REG_CMD(doJST, "^JST");     // Set text alignment using a numeric keypad layout for those buttons with a defined address range.
1019
    REG_CMD(getJST, "?JST");    // Get the current text justification.
395 andreas 1020
    REG_CMD(doMSP, "^MSP");     // Set marquee line speed.
38 andreas 1021
    REG_CMD(doSHO, "^SHO");     // Show or hide a button with a set variable text range.
108 andreas 1022
    REG_CMD(doTEC, "^TEC");     // Set the text effect color for the specified addresses/states to the specified color.
1023
    REG_CMD(getTEC, "?TEC");    // Get the current text effect color.
110 andreas 1024
    REG_CMD(doTEF, "^TEF");     // Set the text effect. The Text Effect is specified by name and can be found in TPD4.
1025
    REG_CMD(getTEF, "?TEF");    // Get the current text effect name.
103 andreas 1026
//    REG_CMD(doTOP, "^TOP");     // Send events to the Master as string events.
38 andreas 1027
    REG_CMD(doTXT, "^TXT");     // Assign a text string to those buttons with a defined address range.
110 andreas 1028
    REG_CMD(getTXT, "?TXT");    // Get the current text information.
104 andreas 1029
    REG_CMD(doUNI, "^UNI");     // Set Unicode text.
1030
    REG_CMD(doUTF, "^UTF");     // G5: Set button state text using UTF-8 text command.
148 andreas 1031
    REG_CMD(doVTP, "^VTP");     // Simulates a touch/release/pulse at the given coordinate
14 andreas 1032
 
400 andreas 1033
    REG_CMD(doLPB, "^LPB");     // Assigns a user name to a button.
1034
    REG_CMD(doLPC, "^LPC");     // Clear all users from the User Access Passwords list on the Password Setup page.
1035
    REG_CMD(doLPR, "^LPR");     // Remove a given user from the User Access Passwords list on the Password Setup page.
1036
    REG_CMD(doLPS, "^LPS");     // Set the user name and password.
103 andreas 1037
 
111 andreas 1038
    REG_CMD(doKPS, "^KPS");     // Set the keyboard passthru.
1039
    REG_CMD(doVKS, "^VKS");     // Send one or more virtual key strokes to the G4 application.
103 andreas 1040
 
400 andreas 1041
    REG_CMD(doAPWD, "@PWD");    // Set the page flip password.
1042
    REG_CMD(doPWD, "^PWD");     // Set the page flip password. Password level is required and must be 1 - 4.
103 andreas 1043
 
38 andreas 1044
    REG_CMD(doBBR, "^BBR");     // Set the bitmap of a button to use a particular resource.
97 andreas 1045
    REG_CMD(doRAF, "^RAF");     // Add new resources
1046
    REG_CMD(doRFR, "^RFR");     // Force a refresh for a given resource.
38 andreas 1047
    REG_CMD(doRMF, "^RMF");     // Modify an existing resource.
111 andreas 1048
    REG_CMD(doRSR, "^RSR");     // Change the refresh rate for a given resource.
21 andreas 1049
 
108 andreas 1050
    REG_CMD(doABEEP, "ABEEP");  // Output a single beep even if beep is Off.
1051
    REG_CMD(doADBEEP, "ADBEEP");// Output a double beep even if beep is Off.
62 andreas 1052
    REG_CMD(doAKB, "@AKB");     // Pop up the keyboard icon and initialize the text string to that specified.
1053
    REG_CMD(doAKEYB, "AKEYB");  // Pop up the keyboard icon and initialize the text string to that specified.
1054
    REG_CMD(doAKP, "@AKP");     // Pop up the keypad icon and initialize the text string to that specified.
1055
    REG_CMD(doAKEYP, "AKEYP");  // Pop up the keypad icon and initialize the text string to that specified.
63 andreas 1056
    REG_CMD(doAKEYR, "AKEYR");  // Remove the Keyboard/Keypad.
1057
    REG_CMD(doAKR, "@AKR");     // Remove the Keyboard/Keypad.
71 andreas 1058
    REG_CMD(doBEEP, "BEEP");    // Play a single beep.
104 andreas 1059
    REG_CMD(doBEEP, "^ABP");    // G5: Play a single beep.
71 andreas 1060
    REG_CMD(doDBEEP, "DBEEP");  // Play a double beep.
104 andreas 1061
    REG_CMD(doDBEEP, "^ADB");   // G5: Play a double beep.
62 andreas 1062
    REG_CMD(doEKP, "@EKP");     // Pop up the keypad icon and initialize the text string to that specified.
63 andreas 1063
    REG_CMD(doPKP, "@PKB");     // Present a private keyboard.
1064
    REG_CMD(doPKP, "PKEYP");    // Present a private keypad.
1065
    REG_CMD(doPKP, "@PKP");     // Present a private keypad.
64 andreas 1066
    REG_CMD(doSetup, "SETUP");  // Send panel to SETUP page.
104 andreas 1067
    REG_CMD(doSetup, "^STP");   // G5: Open setup page.
64 andreas 1068
    REG_CMD(doShutdown, "SHUTDOWN");// Shut down the App
82 andreas 1069
    REG_CMD(doSOU, "@SOU");     // Play a sound file.
104 andreas 1070
    REG_CMD(doSOU, "^SOU");     // G5: Play a sound file.
326 andreas 1071
    REG_CMD(doMUT, "^MUT");     // G5: Panel Volume Mute
63 andreas 1072
    REG_CMD(doTKP, "@TKP");     // Present a telephone keypad.
104 andreas 1073
    REG_CMD(doTKP, "^TKP");     // G5: Bring up a telephone keypad.
63 andreas 1074
    REG_CMD(doTKP, "@VKB");     // Present a virtual keyboard
104 andreas 1075
    REG_CMD(doTKP, "^VKB");     // G5: Bring up a virtual keyboard.
129 andreas 1076
#ifndef _NOSIP_
103 andreas 1077
    // Here the SIP commands will take place
123 andreas 1078
    REG_CMD(doPHN, "^PHN");     // SIP commands
127 andreas 1079
    REG_CMD(getPHN, "?PHN");    // SIP state commands
129 andreas 1080
#endif
300 andreas 1081
    // SubView commands
1082
//    REG_CMD(doEPR, "^EPR");     // Execute Push on Release.
1083
//    REG_CMD(doSCE, "^SCE");     // Configures subpage custom events.
1084
//    REG_CMD(doSDR, "^SDR");     // Enabling subpage dynamic reordering.
318 andreas 1085
    REG_CMD(doSHA, "^SHA");     // Subpage Hide All Command
1086
    REG_CMD(doSHD, "^SHD");     // Hides subpage
1087
    REG_CMD(doSPD, "^SPD");     //  Set the padding between subpages on a subpage viewer button
300 andreas 1088
    REG_CMD(doSSH, "^SSH");     // Subpage show command.
318 andreas 1089
    REG_CMD(doSTG, "^STG");     // Subpage toggle command
300 andreas 1090
 
225 andreas 1091
    // ListView commands (G5)
1092
    REG_CMD(doLVD, "^LVD");     // G5: Set Listview Data Source
230 andreas 1093
    REG_CMD(doLVE, "^LVE");     // G5: Set ListView custom event number
227 andreas 1094
    REG_CMD(doLVF, "^LVF");     // G5: Listview Filter
230 andreas 1095
    REG_CMD(doLVL, "^LVL");     // G5: ListView layout
233 andreas 1096
    REG_CMD(doLVM, "^LVM");     // G5: ListView map fields
1097
    REG_CMD(doLVN, "^LVN");     // G5: ListView navigate
1098
    REG_CMD(doLVR, "^LVR");     // G5: ListView refresh data
1099
    REG_CMD(doLVS, "^LVS");     // G5: ListView sort data
225 andreas 1100
 
103 andreas 1101
    // State commands
14 andreas 1102
    REG_CMD(doON, "ON");
1103
    REG_CMD(doOFF, "OFF");
15 andreas 1104
    REG_CMD(doLEVEL, "LEVEL");
1105
    REG_CMD(doBLINK, "BLINK");
127 andreas 1106
    REG_CMD(doVER, "^VER?");    // Return version string to master
279 andreas 1107
#ifndef _NOSIP_
127 andreas 1108
    REG_CMD(doWCN, "^WCN?");    // Return SIP phone number
279 andreas 1109
#endif
134 andreas 1110
    // TPControl commands
1111
    REG_CMD(doTPCCMD, "TPCCMD");    // Profile related options
1112
    REG_CMD(doTPCACC, "TPCACC");    // Device orientation
279 andreas 1113
#ifndef _NOSIP_
153 andreas 1114
    REG_CMD(doTPCSIP, "TPCSIP");    // Show the built in SIP phone
279 andreas 1115
#endif
134 andreas 1116
    // Virtual internal commands
26 andreas 1117
    REG_CMD(doFTR, "#FTR");     // File transfer (virtual internal command)
23 andreas 1118
 
123 andreas 1119
    // At least we must add the SIP client
129 andreas 1120
#ifndef _NOSIP_
127 andreas 1121
    mSIPClient = new TSIPClient;
123 andreas 1122
 
1123
    if (TError::isError())
1124
    {
1125
        MSG_ERROR("Error initializing the SIP client!");
1126
        TConfig::setSIPstatus(false);
1127
    }
129 andreas 1128
#endif
88 andreas 1129
    TError::clear();
299 andreas 1130
    runClickQueue();
303 andreas 1131
    runUpdateSubViewItem();
3 andreas 1132
}
1133
 
1134
TPageManager::~TPageManager()
1135
{
1136
    DECL_TRACER("TPageManager::~TPageManager()");
129 andreas 1137
#ifndef _NOSIP_
127 andreas 1138
    if (mSIPClient)
1139
    {
1140
        delete mSIPClient;
1141
        mSIPClient = nullptr;
1142
    }
129 andreas 1143
#endif
3 andreas 1144
    PCHAIN_T *p = mPchain;
1145
    PCHAIN_T *next = nullptr;
37 andreas 1146
#ifdef __ANDROID__
36 andreas 1147
    stopNetworkState();
37 andreas 1148
#endif
3 andreas 1149
    try
1150
    {
1151
        while (p)
1152
        {
1153
            next = p->next;
1154
 
1155
            if (p->page)
1156
                delete p->page;
1157
 
1158
            delete p;
1159
            p = next;
1160
        }
1161
 
1162
        SPCHAIN_T *sp = mSPchain;
1163
        SPCHAIN_T *snext = nullptr;
1164
 
1165
        while (sp)
1166
        {
1167
            snext = sp->next;
1168
 
1169
            if (sp->page)
1170
                delete sp->page;
1171
 
1172
            delete sp;
5 andreas 1173
            sp = snext;
3 andreas 1174
        }
1175
 
1176
        mPchain = nullptr;
1177
        mSPchain = nullptr;
14 andreas 1178
        setPChain(mPchain);
1179
        setSPChain(mSPchain);
3 andreas 1180
 
13 andreas 1181
        if (mAmxNet)
1182
        {
1183
            delete mAmxNet;
1184
            mAmxNet = nullptr;
1185
        }
1186
 
3 andreas 1187
        if (mTSettings)
1188
        {
1189
            delete mTSettings;
1190
            mTSettings = nullptr;
1191
        }
1192
 
1193
        if (mPageList)
1194
        {
1195
            delete mPageList;
1196
            mPageList = nullptr;
1197
        }
5 andreas 1198
 
1199
        if (mPalette)
1200
        {
1201
            delete mPalette;
1202
            mPalette = nullptr;
1203
        }
7 andreas 1204
 
1205
        if (mFonts)
1206
        {
1207
            delete mFonts;
1208
            mFonts = nullptr;
1209
        }
8 andreas 1210
 
1211
        if (gIcons)
1212
        {
1213
            delete gIcons;
1214
            gIcons = nullptr;
1215
        }
1216
 
1217
        if (gPrjResources)
1218
        {
1219
            delete gPrjResources;
1220
            gPrjResources = nullptr;
1221
        }
40 andreas 1222
 
33 andreas 1223
        if (mExternal)
1224
        {
1225
            delete mExternal;
1226
            mExternal = nullptr;
1227
        }
3 andreas 1228
    }
1229
    catch (std::exception& e)
1230
    {
1231
        MSG_ERROR("Memory error: " << e.what());
1232
    }
90 andreas 1233
 
1234
    gPageManager = nullptr;
3 andreas 1235
}
1236
 
11 andreas 1237
void TPageManager::initialize()
1238
{
1239
    DECL_TRACER("TPageManager::initialize()");
1240
 
14 andreas 1241
    surface_mutex.lock();
11 andreas 1242
    dropAllSubPages();
1243
    dropAllPages();
1244
 
186 andreas 1245
    string projectPath = TConfig::getProjectPath();
1246
 
1247
    if (!fs::exists(projectPath + "/prj.xma"))
1248
        projectPath += "/__system";
1249
 
90 andreas 1250
    if (mAmxNet && mAmxNet->isConnected())
1251
        mAmxNet->close();
88 andreas 1252
 
11 andreas 1253
    if (mTSettings)
1254
        mTSettings->loadSettings();
1255
    else
186 andreas 1256
        mTSettings = new TSettings(projectPath);
11 andreas 1257
 
1258
    if (TError::isError())
14 andreas 1259
    {
1260
        surface_mutex.unlock();
11 andreas 1261
        return;
14 andreas 1262
    }
11 andreas 1263
 
178 andreas 1264
    // Set the panel type from the project information
1265
    TConfig::savePanelType(mTSettings->getPanelType());
1266
 
88 andreas 1267
    if (gPrjResources)
1268
        delete gPrjResources;
11 andreas 1269
 
88 andreas 1270
    gPrjResources = new TPrjResources(mTSettings->getResourcesList());
11 andreas 1271
 
88 andreas 1272
    if (mPalette)
1273
        delete mPalette;
1274
 
1275
    mPalette = new TPalette();
1276
 
11 andreas 1277
    vector<PALETTE_SETUP> pal = mTSettings->getSettings().palettes;
1278
 
83 andreas 1279
    if (pal.size() > 0)
1280
    {
1281
        vector<PALETTE_SETUP>::iterator iterPal;
11 andreas 1282
 
118 andreas 1283
        for (iterPal = pal.begin(); iterPal != pal.end(); ++iterPal)
83 andreas 1284
            mPalette->initialize(iterPal->file);
1285
    }
1286
 
11 andreas 1287
    if (!TError::isError())
1288
        TColor::setPalette(mPalette);
1289
 
88 andreas 1290
    if (mFonts)
1291
        delete mFonts;
11 andreas 1292
 
88 andreas 1293
    mFonts = new TFont();
1294
 
11 andreas 1295
    if (TError::isError())
1296
    {
1297
        MSG_ERROR("Initializing fonts was not successfull!");
14 andreas 1298
        surface_mutex.unlock();
11 andreas 1299
        return;
1300
    }
1301
 
88 andreas 1302
    if (gIcons)
1303
        delete gIcons;
11 andreas 1304
 
88 andreas 1305
    gIcons = new TIcons();
1306
 
11 andreas 1307
    if (TError::isError())
1308
    {
1309
        MSG_ERROR("Initializing icons was not successfull!");
14 andreas 1310
        surface_mutex.unlock();
11 andreas 1311
        return;
1312
    }
1313
 
88 andreas 1314
    if (mPageList)
1315
        delete mPageList;
11 andreas 1316
 
88 andreas 1317
    mPageList = new TPageList();
11 andreas 1318
 
88 andreas 1319
    if (mExternal)
1320
        delete mExternal;
1321
 
1322
    mExternal = new TExternal();
1323
 
11 andreas 1324
    PAGELIST_T page;
1325
 
1326
    if (!mTSettings->getSettings().powerUpPage.empty())
1327
    {
88 andreas 1328
        if (readPage(mTSettings->getSettings().powerUpPage))
14 andreas 1329
        {
88 andreas 1330
            MSG_TRACE("Found power up page " << mTSettings->getSettings().powerUpPage);
1331
            page = findPage(mTSettings->getSettings().powerUpPage);
1332
            mActualPage = page.pageID;
14 andreas 1333
        }
11 andreas 1334
    }
1335
 
1336
    TPage *pg = getPage(mActualPage);
1337
 
1338
    vector<string> popups = mTSettings->getSettings().powerUpPopup;
1339
 
83 andreas 1340
    if (popups.size() > 0)
11 andreas 1341
    {
83 andreas 1342
        vector<string>::iterator iter;
1343
 
118 andreas 1344
        for (iter = popups.begin(); iter != popups.end(); ++iter)
14 andreas 1345
        {
88 andreas 1346
            if (readSubPage(*iter))
83 andreas 1347
            {
88 andreas 1348
                MSG_TRACE("Found power up popup " << *iter);
11 andreas 1349
 
88 andreas 1350
                if (pg)
1351
                {
1352
                    TSubPage *spage = getSubPage(*iter);
350 andreas 1353
                    spage->setParent(pg->getHandle());
88 andreas 1354
                    pg->addSubPage(spage);
1355
                }
83 andreas 1356
            }
11 andreas 1357
        }
1358
    }
1359
 
88 andreas 1360
    // Here we initialize the system resources like borders, cursors, sliders, ...
1361
    if (mSystemDraw)
1362
        delete mSystemDraw;
1363
 
1364
    mSystemDraw = new TSystemDraw(TConfig::getSystemPath(TConfig::BASE));
1365
 
1366
    TError::clear();        // Clear all errors who may be occured until here
1367
 
11 andreas 1368
    // Start the thread
92 andreas 1369
    startComm();
1370
 
1371
    surface_mutex.unlock();
1372
}
1373
 
1374
bool TPageManager::startComm()
1375
{
1376
    DECL_TRACER("TPageManager::startComm()");
1377
 
1378
    if (mAmxNet && mAmxNet->isNetRun())
1379
        return true;
1380
 
1381
    try
11 andreas 1382
    {
92 andreas 1383
        if (!mAmxNet)
13 andreas 1384
        {
92 andreas 1385
            if (_netRunning)
13 andreas 1386
            {
92 andreas 1387
                // Wait until previous connection thread ended
1388
                while (_netRunning)
1389
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
13 andreas 1390
            }
14 andreas 1391
 
92 andreas 1392
            mAmxNet = new amx::TAmxNet();
1393
            mAmxNet->setCallback(bind(&TPageManager::doCommand, this, std::placeholders::_1));
1394
            mAmxNet->setPanelID(TConfig::getChannel());
134 andreas 1395
            mAmxNet->setSerialNum(V_SERIAL);
13 andreas 1396
        }
90 andreas 1397
 
1398
        if (!mAmxNet->isNetRun())
1399
            mAmxNet->Run();
85 andreas 1400
    }
92 andreas 1401
    catch (std::exception& e)
1402
    {
1403
        MSG_ERROR("Error starting the AmxNet thread: " << e.what());
1404
        return false;
1405
    }
14 andreas 1406
 
92 andreas 1407
    return true;
11 andreas 1408
}
1409
 
38 andreas 1410
void TPageManager::startUp()
1411
{
1412
    DECL_TRACER("TPageManager::startUp()");
1413
 
44 andreas 1414
    if (mAmxNet)
90 andreas 1415
    {
1416
        MSG_WARNING("Communication with controller already initialized!");
44 andreas 1417
        return;
90 andreas 1418
    }
44 andreas 1419
 
92 andreas 1420
    if (!startComm())
1421
        return;
90 andreas 1422
 
38 andreas 1423
#ifdef __ANDROID__
130 andreas 1424
    initOrientation();
38 andreas 1425
    initNetworkState();
1426
#endif
1427
}
89 andreas 1428
 
1429
void TPageManager::reset()
1430
{
1431
    DECL_TRACER("TPageManager::reset()");
1432
 
100 andreas 1433
    // Freshly initialize everything.
89 andreas 1434
    initialize();
1435
}
1436
 
169 andreas 1437
void TPageManager::runCommands()
1438
{
1439
    DECL_TRACER("TPageManager::runCommands()");
1440
 
1441
    if (mBusy || cmdLoop_busy)
1442
        return;
1443
 
1444
    try
1445
    {
1446
        mThreadCommand = std::thread([=] { this->commandLoop(); });
1447
        mThreadCommand.detach();
1448
    }
1449
    catch (std::exception& e)
1450
    {
1451
        MSG_ERROR("Error starting thread for command loop: " << e.what());
1452
        _netRunning = false;
1453
    }
1454
}
1455
 
197 andreas 1456
void TPageManager::showSetup()
1457
{
1458
    DECL_TRACER("TPageManager::showSetup()");
251 andreas 1459
#ifdef Q_OS_ANDROID
260 andreas 1460
    // Scan Netlinx for TP4 files and update the list of setup.
1461
    if (TConfig::getController().compare("0.0.0.0") != 0)
1462
    {
1463
        if (_startWait)
1464
            _startWait(string("Please wait while I try to load the list of surface files from Netlinx (") + TConfig::getController() + ")");
1465
 
1466
        TTPInit tpinit;
1467
        std::vector<TTPInit::FILELIST_t> fileList;
1468
        tpinit.setPath(TConfig::getProjectPath());
1469
        fileList = tpinit.getFileList(".tp4");
1470
 
1471
        if (fileList.size() > 0)
1472
        {
1473
            vector<TTPInit::FILELIST_t>::iterator iter;
264 andreas 1474
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
260 andreas 1475
            QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "clearSurfaces");
1476
#else
1477
            QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "clearSurfaces");
1478
#endif
1479
            for (iter = fileList.begin(); iter != fileList.end(); ++iter)
1480
            {
264 andreas 1481
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
260 andreas 1482
                QAndroidJniObject str = QAndroidJniObject::fromString(iter->fname.c_str());
1483
                QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "addSurface", "(Ljava/lang/String;)V", str.object<jstring>());
1484
#else
1485
                QJniObject str = QJniObject::fromString(iter->fname.c_str());
1486
                QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "addSurface", "(Ljava/lang/String;)V", str.object<jstring>());
1487
#endif
1488
            }
1489
        }
1490
 
1491
        if (_stopWait)
1492
            _stopWait();
1493
    }
1494
 
367 andreas 1495
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1496
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogLevel", "(Ljava/lang/Integer;)V", TConfig::getLogLevelBits());
383 andreas 1497
    QAndroidJniObject strPath = QAndroidJniObject::fromString(TConfig::getLogFile().c_str());
385 andreas 1498
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogEnableFile", "(Z)V", TConfig::getLogFileEnabled());
383 andreas 1499
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogPath", "(Ljava/lang/String;)V", strPath.object<jstring>());
367 andreas 1500
#else
1501
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogLevel", "(I)V", TConfig::getLogLevelBits());
385 andreas 1502
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogEnableFile", "(I)V", (TConfig::getLogFileEnabled() ? 1 : 0));
383 andreas 1503
    QJniObject strPath = QJniObject::fromString(TConfig::getLogFile().c_str());
1504
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setLogPath", "(Ljava/lang/String;)V", strPath.object<jstring>());
397 andreas 1505
 
1506
    QJniObject pw1 = QJniObject::fromString(TConfig::getPassword1().c_str());
1507
    QJniObject pw2 = QJniObject::fromString(TConfig::getPassword2().c_str());
1508
    QJniObject pw3 = QJniObject::fromString(TConfig::getPassword3().c_str());
1509
    QJniObject pw4 = QJniObject::fromString(TConfig::getPassword4().c_str());
1510
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setPassword", "(ILjava/lang/String;)V", 1, pw1.object<jstring>());
1511
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setPassword", "(ILjava/lang/String;)V", 2, pw2.object<jstring>());
1512
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setPassword", "(ILjava/lang/String;)V", 3, pw3.object<jstring>());
1513
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "setPassword", "(ILjava/lang/String;)V", 4, pw4.object<jstring>());
367 andreas 1514
#endif
1515
 
255 andreas 1516
    enterSetup();
1517
/*    if (mSetupActive)
197 andreas 1518
        return;
1519
 
1520
    mSetupActive = true;
1521
    mSavedPage = mActualPage;
1522
 
198 andreas 1523
    TPage *pg = getPage(mActualPage);
197 andreas 1524
 
198 andreas 1525
    if (pg)
1526
    {
1527
        TSubPage *spage = pg->getFirstSubPage();
1528
        mSavedSubpages.clear();
197 andreas 1529
 
198 andreas 1530
        while (spage)
197 andreas 1531
        {
198 andreas 1532
            if (spage->isVisible())
1533
                mSavedSubpages.push_back(spage->getNumber());
1534
 
1535
            spage = pg->getNextSubPage();
197 andreas 1536
        }
1537
    }
1538
 
209 andreas 1539
    setPage(SYSTEM_PAGE_CONTROLLER, true);    // Call the page "Controller" (NetLinx settings)
255 andreas 1540
*/
250 andreas 1541
#else
1542
        if (_callShowSetup)
1543
            _callShowSetup();
1544
#endif
197 andreas 1545
}
1546
 
1547
void TPageManager::hideSetup()
1548
{
1549
    DECL_TRACER("TPageManager::hideSetup()");
1550
 
206 andreas 1551
    if (!mSetupActive || mSavedPage >= SYSTEM_PAGE_START)
197 andreas 1552
        return;
1553
 
198 andreas 1554
    mSetupActive = false;
197 andreas 1555
 
198 andreas 1556
    if (!mSavedPage)
1557
    {
1558
        string sPage = mTSettings->getPowerUpPage();
197 andreas 1559
 
198 andreas 1560
        if (!setPage(sPage, true))
1561
            setPage(1, true);
197 andreas 1562
 
1563
        return;
1564
    }
1565
 
198 andreas 1566
    setPage(mSavedPage, true);
213 andreas 1567
    MSG_PROTOCOL("Activated page: " << mSavedPage);
197 andreas 1568
 
198 andreas 1569
    if (mSavedSubpages.size() > 0)
197 andreas 1570
    {
198 andreas 1571
        vector<int>::iterator iter;
197 andreas 1572
 
198 andreas 1573
        for (iter = mSavedSubpages.begin(); iter != mSavedSubpages.end(); ++iter)
1574
        {
1575
            showSubPage(*iter);
213 andreas 1576
            MSG_PROTOCOL("Activated subpage: " << *iter);
198 andreas 1577
        }
217 andreas 1578
 
1579
        mSavedSubpages.clear();
197 andreas 1580
    }
1581
}
1582
 
205 andreas 1583
int TPageManager::getSelectedRow(ulong handle)
1584
{
1585
    DECL_TRACER("TPageManager::getSelectedRow(ulong handle)");
1586
 
300 andreas 1587
    int nPage = (handle >> 16) & 0x0000ffff;
205 andreas 1588
 
206 andreas 1589
    if ((nPage && TPage::isRegularPage(nPage)) || TPage::isSystemPage(nPage)) // Do we have a page?
205 andreas 1590
    {                                                   // Yes, then look on page
1591
        TPage *pg = getPage(nPage);
1592
 
1593
        if (!pg)
1594
            return -1;
1595
 
1596
        return pg->getSelectedRow(handle);
1597
    }
206 andreas 1598
    else if (TPage::isRegularSubPage(nPage) || TPage::isSystemSubPage(nPage))
205 andreas 1599
    {
1600
        TSubPage *subPg = getSubPage(nPage);
1601
 
1602
        if (!subPg)
1603
            return -1;
1604
 
1605
        return subPg->getSelectedRow(handle);
1606
    }
1607
 
271 andreas 1608
    MSG_WARNING("Invalid handle " << handleToString(handle) << " detected!");
205 andreas 1609
    return -1;
1610
}
1611
 
1612
string TPageManager::getSelectedItem(ulong handle)
1613
{
1614
    DECL_TRACER("TPageManager::getSelectedItem(ulong handle)");
1615
 
300 andreas 1616
    int nPage = (handle >> 16) & 0x0000ffff;
205 andreas 1617
 
206 andreas 1618
    if ((nPage && TPage::isRegularPage(nPage)) || TPage::isSystemPage(nPage)) // Do we have a page?
205 andreas 1619
    {                                                   // Yes, then look on page
1620
        TPage *pg = getPage(nPage);
1621
 
1622
        if (!pg)
1623
            return string();
1624
 
1625
        return pg->getSelectedItem(handle);
1626
    }
206 andreas 1627
    else if (TPage::isRegularSubPage(nPage) || TPage::isSystemSubPage(nPage))
205 andreas 1628
    {
1629
        TSubPage *subPg = getSubPage(nPage);
1630
 
1631
        if (!subPg)
1632
            return string();
1633
 
1634
        return subPg->getSelectedItem(handle);
1635
    }
1636
 
271 andreas 1637
    MSG_WARNING("Invalid handle " << handleToString(handle) << " detected!");
205 andreas 1638
    return string();
1639
}
1640
 
206 andreas 1641
void TPageManager::setSelectedRow(ulong handle, int row, const std::string& text)
205 andreas 1642
{
1643
    DECL_TRACER("TPageManager::setSelectedRow(ulong handle, int row)");
1644
 
300 andreas 1645
    int nPage = (handle >> 16) & 0x0000ffff;
205 andreas 1646
 
206 andreas 1647
    if (TPage::isRegularPage(nPage) || TPage::isSystemPage(nPage)) // Do we have a page?
205 andreas 1648
    {                                                   // Yes, then look on page
1649
        TPage *pg = getPage(nPage);
1650
 
1651
        if (!pg)
1652
            return;
1653
 
1654
        pg->setSelectedRow(handle, row);
1655
    }
206 andreas 1656
    else if (TPage::isRegularSubPage(nPage) || TPage::isSystemSubPage(nPage))   // Do we have a subpage?
1657
    {                                                   // Yes, then look on subpage
205 andreas 1658
        TSubPage *subPg = getSubPage(nPage);
1659
 
1660
        if (!subPg)
1661
            return;
1662
 
1663
        subPg->setSelectedRow(handle, row);
206 andreas 1664
        // Check if this is a system list. If so we must set the selected
1665
        // text to the input line or "label".
1666
        TPage *mainPage = nullptr;
1667
 
1668
        if (nPage >= SYSTEM_SUBPAGE_START)  // System subpage?
1669
        {
1670
            switch(nPage)
1671
            {
1672
                case SYSTEM_SUBPAGE_SYSTEMSOUND:
1673
                case SYSTEM_SUBPAGE_SINGLEBEEP:
1674
                case SYSTEM_SUBPAGE_DOUBLEBEEP:
1675
                    mainPage = getPage(SYSTEM_PAGE_SOUND);
1676
                break;
1677
 
1678
                case SYSTEM_SUBPAGE_SURFACE:
1679
                    mainPage = getPage(SYSTEM_PAGE_CONTROLLER);
1680
                break;
1681
            }
1682
        }
1683
 
1684
        if (mainPage)
1685
        {
1686
            if (nPage == SYSTEM_SUBPAGE_SYSTEMSOUND)  // System sound beep
1687
            {
1688
                Button::TButton *bt = mainPage->getButton(SYSTEM_PAGE_SOUND_TXSYSSOUND);
1689
 
1690
                if (bt)
1691
                {
1692
                    bt->setText(text, -1);
1693
                    TConfig::setTemporary(true);
1694
                    TConfig::saveSystemSoundFile(text);
1695
                }
1696
            }
1697
            else if (nPage == SYSTEM_SUBPAGE_SINGLEBEEP) // System sound single beep
1698
            {
1699
                Button::TButton *bt = mainPage->getButton(SYSTEM_PAGE_SOUND_TXSINGLEBEEP);
1700
 
1701
                if (bt)
1702
                {
1703
                    bt->setText(text, -1);
1704
                    TConfig::setTemporary(true);
1705
                    TConfig::saveSingleBeepFile(text);
1706
                }
1707
            }
1708
            else if (nPage == SYSTEM_SUBPAGE_DOUBLEBEEP) // System sound double beep
1709
            {
1710
                Button::TButton *bt = mainPage->getButton(SYSTEM_PAGE_SOUND_TXDOUBLEBEEP);
1711
 
1712
                if (bt)
1713
                {
1714
                    bt->setText(text, -1);
1715
                    TConfig::setTemporary(true);
1716
                    TConfig::saveDoubleBeepFile(text);
1717
                }
1718
            }
1719
            else if (nPage == SYSTEM_SUBPAGE_SURFACE)   // System TP4 files (surface files)
1720
            {
1721
                Button::TButton *bt = mainPage->getButton(SYSTEM_PAGE_CTRL_SURFACE);
1722
 
1723
                if (bt)
1724
                {
1725
                    MSG_DEBUG("Setting text: " << text);
1726
                    bt->setText(text, -1);
1727
                    TConfig::setTemporary(true);
1728
                    TConfig::saveFtpSurface(text);
1729
                }
1730
            }
1731
 
1732
            // Close the list subpage
1733
            subPg->drop();
1734
        }
205 andreas 1735
    }
1736
}
1737
 
383 andreas 1738
void TPageManager::redrawObject(ulong handle)
1739
{
1740
    DECL_TRACER("TPageManager::redrawObject(ulong handle)");
1741
 
1742
    int pnumber = (int)((handle >> 16) & 0x0000ffff);
1743
    int btnumber = (int)(handle & 0x0000ffff);
1744
 
1745
    if (pnumber < REGULAR_SUBPAGE_START)    // Is it a page?
1746
    {
1747
        TPage *page = getPage(pnumber);
1748
 
1749
        if (!page)
1750
        {
1751
            MSG_WARNING("Page " << pnumber << " not found!");
1752
            return;
1753
        }
1754
 
1755
        if (!page->isVisilble())
1756
            return;
1757
 
1758
        if (btnumber == 0)
1759
        {
1760
            page->show();
1761
            return;
1762
        }
1763
 
1764
        Button::TButton *button = page->getButton(btnumber);
1765
 
1766
        if (!button)
1767
        {
1768
            MSG_WARNING("Button " << btnumber << " on page " << pnumber << " not found!");
1769
            return;
1770
        }
1771
 
1772
        button->showLastButton();
1773
    }
1774
    else if (pnumber >= REGULAR_SUBPAGE_START && pnumber < SYSTEM_PAGE_START)
1775
    {
1776
        TSubPage *spage = getSubPage(pnumber);
1777
 
1778
        if (!spage)
1779
        {
1780
            MSG_WARNING("Subpage " << pnumber << " not found!");
1781
            return;
1782
        }
1783
 
1784
        if (!spage->isVisible())
1785
            return;
1786
 
1787
        if (btnumber == 0)
1788
        {
1789
            spage->show();
1790
            return;
1791
        }
1792
 
1793
        Button::TButton *button = spage->getButton(btnumber);
1794
 
1795
        if (!button)
1796
        {
1797
            MSG_WARNING("Button " << btnumber << " on subpage " << pnumber << " not found!");
1798
            return;
1799
        }
1800
 
1801
        button->showLastButton();
1802
    }
1803
    else
1804
    {
1805
        MSG_WARNING("System pages are not handled by redraw method! Ignoring page " << pnumber << ".");
1806
    }
1807
}
1808
 
198 andreas 1809
#ifdef _SCALE_SKIA_
197 andreas 1810
void TPageManager::setSetupScaleFactor(double scale, double sw, double sh)
1811
{
1812
    DECL_TRACER("TPageManager::setSetupScaleFactor(double scale, double sw, double sh)");
1813
 
1814
    mScaleSystem = scale;
1815
    mScaleSystemWidth = sw;
1816
    mScaleSystemHeight = sh;
1817
}
198 andreas 1818
#endif
197 andreas 1819
 
11 andreas 1820
/*
1821
 * The following method is called by the class TAmxNet whenever an event from
169 andreas 1822
 * the Netlinx occured.
11 andreas 1823
 */
1824
void TPageManager::doCommand(const amx::ANET_COMMAND& cmd)
1825
{
1826
    DECL_TRACER("TPageManager::doCommand(const amx::ANET_COMMAND& cmd)");
1827
 
169 andreas 1828
    if (!cmdLoop_busy)
1829
        runCommands();
1830
 
11 andreas 1831
    mCommands.push_back(cmd);
169 andreas 1832
}
11 andreas 1833
 
169 andreas 1834
void TPageManager::commandLoop()
1835
{
1836
    DECL_TRACER("TPageManager::commandLoop()");
1837
 
1838
    if (mBusy || cmdLoop_busy)
11 andreas 1839
        return;
1840
 
169 andreas 1841
    mBusy = cmdLoop_busy = true;
11 andreas 1842
    string com;
1843
 
169 andreas 1844
    while (cmdLoop_busy && !killed && !_restart_)
11 andreas 1845
    {
169 andreas 1846
        while (mCommands.size() > 0)
11 andreas 1847
        {
169 andreas 1848
            amx::ANET_COMMAND bef = mCommands.at(0);
1849
            mCommands.erase(mCommands.begin());
11 andreas 1850
 
169 andreas 1851
            switch (bef.MC)
1852
            {
1853
                case 0x0006:
1854
                case 0x0018:	// feedback channel on
1855
                    com.assign("ON-");
1856
                    com.append(to_string(bef.data.chan_state.channel));
1857
                    parseCommand(bef.device1, bef.data.chan_state.port, com);
1858
                break;
11 andreas 1859
 
169 andreas 1860
                case 0x0007:
1861
                case 0x0019:	// feedback channel off
1862
                    com.assign("OFF-");
1863
                    com.append(to_string(bef.data.chan_state.channel));
1864
                    parseCommand(bef.device1, bef.data.chan_state.port, com);
1865
                break;
11 andreas 1866
 
169 andreas 1867
                case 0x000a:	// level value change
1868
                    com = "LEVEL-";
1869
                    com += to_string(bef.data.message_value.value);
1870
                    com += ",";
11 andreas 1871
 
169 andreas 1872
                    switch (bef.data.message_value.type)
1873
                    {
1874
                        case 0x10: com += to_string(bef.data.message_value.content.byte); break;
1875
                        case 0x11: com += to_string(bef.data.message_value.content.ch); break;
1876
                        case 0x20: com += to_string(bef.data.message_value.content.integer); break;
1877
                        case 0x21: com += to_string(bef.data.message_value.content.sinteger); break;
1878
                        case 0x40: com += to_string(bef.data.message_value.content.dword); break;
1879
                        case 0x41: com += to_string(bef.data.message_value.content.sdword); break;
1880
                        case 0x4f: com += to_string(bef.data.message_value.content.fvalue); break;
1881
                        case 0x8f: com += to_string(bef.data.message_value.content.dvalue); break;
1882
                    }
11 andreas 1883
 
169 andreas 1884
                    parseCommand(bef.device1, bef.data.message_value.port, com);
1885
                break;
11 andreas 1886
 
169 andreas 1887
                case 0x000c:	// Command string
11 andreas 1888
                {
169 andreas 1889
                    amx::ANET_MSG_STRING msg = bef.data.message_string;
11 andreas 1890
 
169 andreas 1891
                    if (msg.length < strlen((char *)&msg.content))
1892
                    {
1893
                        mCmdBuffer.append((char *)&msg.content);
1894
                        break;
1895
                    }
1896
                    else if (mCmdBuffer.length() > 0)
1897
                    {
1898
                        mCmdBuffer.append((char *)&msg.content);
1899
                        size_t len = (mCmdBuffer.length() >= sizeof(msg.content)) ? (sizeof(msg.content)-1) : mCmdBuffer.length();
1900
                        strncpy((char *)&msg.content, mCmdBuffer.c_str(), len);
1901
                        msg.content[len] = 0;
1902
                    }
104 andreas 1903
 
169 andreas 1904
                    if (getCommand((char *)msg.content) == "^UTF")  // This is already UTF8!
1905
                        com.assign((char *)msg.content);
1906
                    else
1907
                        com.assign(cp1250ToUTF8((char *)&msg.content));
11 andreas 1908
 
169 andreas 1909
                    parseCommand(bef.device1, msg.port, com);
1910
                    mCmdBuffer.clear();
1911
                }
1912
                break;
15 andreas 1913
 
169 andreas 1914
                case 0x0502:    // Blink message (contains date and time)
1915
                    com = "BLINK-" + to_string(bef.data.blinkMessage.hour) + ":";
1916
                    com += to_string(bef.data.blinkMessage.minute) + ":";
1917
                    com += to_string(bef.data.blinkMessage.second) + ",";
1918
                    com += to_string(bef.data.blinkMessage.year) + "-";
1919
                    com += to_string(bef.data.blinkMessage.month) + "-";
1920
                    com += to_string(bef.data.blinkMessage.day) + ",";
1921
                    com += to_string(bef.data.blinkMessage.weekday) + ",";
1922
                    com += ((bef.data.blinkMessage.LED & 0x0001) ? "ON" : "OFF");
1923
                    parseCommand(0, 0, com);
1924
                break;
11 andreas 1925
 
169 andreas 1926
                case 0x1000:	// Filetransfer
11 andreas 1927
                {
169 andreas 1928
                    amx::ANET_FILETRANSFER ftr = bef.data.filetransfer;
1929
 
1930
                    if (ftr.ftype == 0)
11 andreas 1931
                    {
169 andreas 1932
                        switch(ftr.function)
1933
                        {
1934
                            case 0x0100:	// Syncing directory
1935
                                com = "#FTR-SYNC:0:";
1936
                                com.append((char*)&ftr.data[0]);
1937
                                parseCommand(bef.device1, bef.port1, com);
1938
                            break;
11 andreas 1939
 
169 andreas 1940
                            case 0x0104:	// Delete file
1941
                                com = "#FTR-SYNC:"+to_string(bef.count)+":Deleting files ... ("+to_string(bef.count)+"%)";
1942
                                parseCommand(bef.device1, bef.port1, com);
1943
                            break;
11 andreas 1944
 
169 andreas 1945
                            case 0x0105:	// start filetransfer
1946
                                com = "#FTR-START";
1947
                                parseCommand(bef.device1, bef.port1, com);
1948
                            break;
1949
                        }
11 andreas 1950
                    }
169 andreas 1951
                    else
11 andreas 1952
                    {
169 andreas 1953
                        switch(ftr.function)
1954
                        {
1955
                            case 0x0003:	// Received part of file
1956
                            case 0x0004:	// End of file
1957
                                com = "#FTR-FTRPART:"+to_string(bef.count)+":"+to_string(ftr.info1);
1958
                                parseCommand(bef.device1, bef.port1, com);
1959
                            break;
11 andreas 1960
 
169 andreas 1961
                            case 0x0007:	// End of file transfer
1962
                            {
1963
                                com = "#FTR-END";
1964
                                parseCommand(bef.device1, bef.port1, com);
1965
                            }
1966
                            break;
1967
 
1968
                            case 0x0102:	// Receiving file
1969
                                com = "#FTR-FTRSTART:"+to_string(bef.count)+":"+to_string(ftr.info1)+":";
1970
                                com.append((char*)&ftr.data[0]);
1971
                                parseCommand(bef.device1, bef.port1, com);
1972
                            break;
11 andreas 1973
                        }
1974
                    }
1975
                }
169 andreas 1976
                break;
11 andreas 1977
            }
1978
        }
169 andreas 1979
 
1980
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
11 andreas 1981
    }
1982
 
1983
    mBusy = false;
169 andreas 1984
    cmdLoop_busy = false;
11 andreas 1985
}
1986
 
26 andreas 1987
void TPageManager::deployCallbacks()
1988
{
1989
    DECL_TRACER("TPageManager::deployCallbacks()");
1990
 
1991
    PCHAIN_T *p = mPchain;
1992
 
1993
    while (p)
1994
    {
1995
        if (p->page)
1996
        {
1997
            if (_setBackground)
1998
                p->page->registerCallback(_setBackground);
1999
 
2000
            if (_callPlayVideo)
2001
                p->page->regCallPlayVideo(_callPlayVideo);
2002
        }
2003
 
2004
        p = p->next;
2005
    }
2006
 
2007
    SPCHAIN_T *sp = mSPchain;
2008
 
2009
    while (sp)
2010
    {
2011
        if (sp->page)
2012
        {
2013
            if (_setBackground)
2014
                sp->page->registerCallback(_setBackground);
2015
 
2016
            if (_callPlayVideo)
2017
                sp->page->regCallPlayVideo(_callPlayVideo);
2018
        }
2019
 
2020
        sp = sp->next;
2021
    }
2022
}
36 andreas 2023
 
2024
void TPageManager::regCallbackNetState(std::function<void (int)> callNetState, ulong handle)
2025
{
2026
    DECL_TRACER("TPageManager::regCallbackNetState(std::function<void (int)> callNetState, ulong handle)");
2027
 
2028
    if (handle == 0)
2029
        return;
2030
 
2031
    mNetCalls.insert(std::pair<int, std::function<void (int)> >(handle, callNetState));
2032
}
2033
 
2034
void TPageManager::unregCallbackNetState(ulong handle)
2035
{
2036
    DECL_TRACER("TPageManager::unregCallbackNetState(ulong handle)");
2037
 
83 andreas 2038
    if (mNetCalls.size() == 0)
2039
        return;
2040
 
300 andreas 2041
    std::map<int, std::function<void (int)> >::iterator iter = mNetCalls.find((int)handle);
36 andreas 2042
 
2043
    if (iter != mNetCalls.end())
2044
        mNetCalls.erase(iter);
2045
}
247 andreas 2046
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
251 andreas 2047
#ifdef Q_OS_ANDROID
38 andreas 2048
void TPageManager::regCallbackBatteryState(std::function<void (int, bool, int)> callBatteryState, ulong handle)
2049
{
2050
    DECL_TRACER("TPageManager::regCallbackBatteryState(std::function<void (int, bool, int)> callBatteryState, ulong handle)");
2051
 
2052
    if (handle == 0)
2053
        return;
2054
 
2055
    mBatteryCalls.insert(std::pair<int, std::function<void (int, bool, int)> >(handle, callBatteryState));
2056
}
247 andreas 2057
#endif
2058
#ifdef Q_OS_IOS
2059
void TPageManager::regCallbackBatteryState(std::function<void (int, int)> callBatteryState, ulong handle)
2060
{
2061
    DECL_TRACER("TPageManager::regCallbackBatteryState(std::function<void (int, int)> callBatteryState, ulong handle)");
38 andreas 2062
 
247 andreas 2063
    if (handle == 0)
2064
        return;
2065
 
2066
    mBatteryCalls.insert(std::pair<int, std::function<void (int, int)> >(handle, callBatteryState));
264 andreas 2067
#ifdef Q_OS_IOS
2068
    mLastBatteryLevel = TIOSBattery::getBatteryLeft();
2069
    mLastBatteryState = TIOSBattery::getBatteryState();
247 andreas 2070
 
264 andreas 2071
#endif
247 andreas 2072
    if (mLastBatteryLevel > 0 || mLastBatteryState > 0)
2073
        informBatteryStatus(mLastBatteryLevel, mLastBatteryState);
2074
}
2075
#endif
38 andreas 2076
void TPageManager::unregCallbackBatteryState(ulong handle)
2077
{
2078
    DECL_TRACER("TPageManager::unregCallbackBatteryState(ulong handle)");
2079
 
83 andreas 2080
    if (mBatteryCalls.size() == 0)
2081
        return;
247 andreas 2082
#ifdef Q_OS_ANDROID
38 andreas 2083
    std::map<int, std::function<void (int, bool, int)> >::iterator iter = mBatteryCalls.find(handle);
247 andreas 2084
#endif
2085
#ifdef Q_OS_IOS
300 andreas 2086
    std::map<int, std::function<void (int, int)> >::iterator iter = mBatteryCalls.find((int)handle);
247 andreas 2087
#endif
38 andreas 2088
    if (iter != mBatteryCalls.end())
2089
        mBatteryCalls.erase(iter);
2090
}
247 andreas 2091
#endif  // defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
11 andreas 2092
/*
2093
 * The following function must be called to start the "panel".
2094
 */
5 andreas 2095
bool TPageManager::run()
2096
{
2097
    DECL_TRACER("TPageManager::run()");
2098
 
2099
    if (mActualPage <= 0)
2100
        return false;
2101
 
154 andreas 2102
    TPage *pg = getPage(mActualPage);
2103
 
2104
    if (!pg || !_setPage || !mTSettings)
2105
        return false;
2106
 
14 andreas 2107
    surface_mutex.lock();
7 andreas 2108
    pg->setFonts(mFonts);
5 andreas 2109
    pg->registerCallback(_setBackground);
21 andreas 2110
    pg->regCallPlayVideo(_callPlayVideo);
5 andreas 2111
 
26 andreas 2112
    int width, height;
217 andreas 2113
    width = mTSettings->getWidth();
26 andreas 2114
    height = mTSettings->getHeight();
43 andreas 2115
#ifdef _SCALE_SKIA_
26 andreas 2116
    if (mScaleFactor != 1.0)
2117
    {
2118
        width = (int)((double)width * mScaleFactor);
2119
        height = (int)((double)height * mScaleFactor);
2120
    }
43 andreas 2121
#endif
26 andreas 2122
    _setPage((pg->getNumber() << 16) & 0xffff0000, width, height);
5 andreas 2123
    pg->show();
2124
 
2125
    TSubPage *subPg = pg->getFirstSubPage();
2126
 
2127
    while (subPg)
2128
    {
7 andreas 2129
        subPg->setFonts(mFonts);
2130
        subPg->registerCallback(_setBackground);
2131
        subPg->registerCallbackDB(_displayButton);
11 andreas 2132
        subPg->regCallDropSubPage(_callDropSubPage);
21 andreas 2133
        subPg->regCallPlayVideo(_callPlayVideo);
7 andreas 2134
 
5 andreas 2135
        if (_setSubPage)
6 andreas 2136
        {
2137
            MSG_DEBUG("Drawing page " << subPg->getNumber() << ": " << subPg->getName() << "...");
26 andreas 2138
            width = subPg->getWidth();
2139
            height = subPg->getHeight();
2140
            int left = subPg->getLeft();
2141
            int top = subPg->getTop();
43 andreas 2142
#ifdef _SCALE_SKIA_
26 andreas 2143
            if (mScaleFactor != 1.0)
2144
            {
2145
                width = (int)((double)width * mScaleFactor);
2146
                height = (int)((double)height * mScaleFactor);
2147
                left = (int)((double)left * mScaleFactor);
2148
                top = (int)((double)top * mScaleFactor);
2149
            }
43 andreas 2150
#endif
41 andreas 2151
            ANIMATION_t ani;
2152
            ani.showEffect = subPg->getShowEffect();
2153
            ani.showTime = subPg->getShowTime();
42 andreas 2154
            ani.hideEffect = subPg->getHideEffect();
2155
            ani.hideTime = subPg->getHideTime();
162 andreas 2156
 
2157
            subPg->setZOrder(pg->getNextZOrder());
217 andreas 2158
            _setSubPage(subPg->getHandle(), pg->getHandle(), left, top, width, height, ani);
6 andreas 2159
            subPg->show();
2160
        }
5 andreas 2161
 
2162
        subPg = pg->getNextSubPage();
2163
    }
2164
 
14 andreas 2165
    surface_mutex.unlock();
5 andreas 2166
    return true;
2167
}
2168
 
4 andreas 2169
TPage *TPageManager::getPage(int pageID)
2170
{
2171
    DECL_TRACER("TPageManager::getPage(int pageID)");
2172
 
209 andreas 2173
    if (pageID <= 0)
2174
        return nullptr;
2175
 
4 andreas 2176
    PCHAIN_T *p = mPchain;
2177
 
2178
    while (p)
2179
    {
349 andreas 2180
        if (p->page && p->page->getNumber() == pageID)
4 andreas 2181
            return p->page;
2182
 
2183
        p = p->next;
2184
    }
2185
 
2186
    return nullptr;
2187
}
2188
 
2189
TPage *TPageManager::getPage(const string& name)
2190
{
2191
    DECL_TRACER("TPageManager::getPage(const string& name)");
2192
 
349 andreas 2193
    if (name.empty())
2194
        return nullptr;
2195
 
4 andreas 2196
    PCHAIN_T *p = mPchain;
2197
 
2198
    while (p)
2199
    {
349 andreas 2200
        if (p->page && p->page->getName().compare(name) == 0)
4 andreas 2201
            return p->page;
2202
 
2203
        p = p->next;
2204
    }
2205
 
2206
    return nullptr;
2207
}
2208
 
209 andreas 2209
TPage *TPageManager::loadPage(PAGELIST_T& pl, bool *refresh)
15 andreas 2210
{
209 andreas 2211
    DECL_TRACER("TPageManager::loadPage(PAGELIST_T& pl, bool *refresh)");
15 andreas 2212
 
209 andreas 2213
    if (refresh)
2214
        *refresh = false;
2215
 
15 andreas 2216
    if (!pl.isValid)
2217
        return nullptr;
2218
 
2219
    TPage *pg = getPage(pl.pageID);
2220
 
2221
    if (!pg)
2222
    {
2223
        if (!readPage(pl.pageID))
2224
            return nullptr;
2225
 
2226
        pg = getPage(pl.pageID);
2227
 
2228
        if (!pg)
2229
        {
2230
            MSG_ERROR("Error loading page " << pl.pageID << ", " << pl.name << " from file " << pl.file << "!");
2231
            return nullptr;
2232
        }
209 andreas 2233
 
2234
        if (refresh)
213 andreas 2235
            *refresh = true;        // Indicate that the page was freshly loaded
15 andreas 2236
    }
2237
 
2238
    return pg;
2239
}
2240
 
209 andreas 2241
void TPageManager::reloadSystemPage(TPage *page)
2242
{
2243
    DECL_TRACER("TPageManager::reloadSystemPage(TPage *page)");
2244
 
2245
    if (!page)
2246
        return;
2247
 
2248
    vector<Button::TButton *> buttons = page->getAllButtons();
2249
    vector<Button::TButton *>::iterator iter;
210 andreas 2250
    TConfig::setTemporary(false);
209 andreas 2251
 
2252
    for (iter = buttons.begin(); iter != buttons.end(); ++iter)
2253
    {
2254
        Button::TButton *bt = *iter;
2255
 
2256
        if (bt->getAddressPort() == 0 && bt->getAddressChannel() > 0)
2257
        {
2258
            switch(bt->getAddressChannel())
2259
            {
2260
                case SYSTEM_ITEM_LOGLOGFILE:        bt->setTextOnly(TConfig::getLogFile(), -1); break;
2261
 
2262
                case SYSTEM_ITEM_NETLINX_IP:        bt->setTextOnly(TConfig::getController(), -1); break;
2263
                case SYSTEM_ITEM_NETLINX_PORT:      bt->setTextOnly(std::to_string(TConfig::getPort()), -1); break;
2264
                case SYSTEM_ITEM_NETLINX_CHANNEL:   bt->setTextOnly(std::to_string(TConfig::getChannel()), -1); break;
2265
                case SYSTEM_ITEM_NETLINX_PTYPE:     bt->setTextOnly(TConfig::getPanelType(), -1); break;
2266
                case SYSTEM_ITEM_FTPUSER:           bt->setTextOnly(TConfig::getFtpUser(), -1); break;
2267
                case SYSTEM_ITEM_FTPPASSWORD:       bt->setTextOnly(TConfig::getFtpPassword(), -1); break;
2268
                case SYSTEM_ITEM_FTPSURFACE:        bt->setTextOnly(TConfig::getFtpSurface(), -1); break;
210 andreas 2269
 
2270
                case SYSTEM_ITEM_SIPPROXY:          bt->setTextOnly(TConfig::getSIPproxy(), -1); break;
2271
                case SYSTEM_ITEM_SIPPORT:           bt->setTextOnly(std::to_string(TConfig::getSIPport()), -1); break;
2272
                case SYSTEM_ITEM_SIPSTUN:           bt->setTextOnly(TConfig::getSIPstun(), -1); break;
2273
                case SYSTEM_ITEM_SIPDOMAIN:         bt->setTextOnly(TConfig::getSIPdomain(), -1); break;
2274
                case SYSTEM_ITEM_SIPUSER:           bt->setTextOnly(TConfig::getSIPuser(), -1); break;
2275
                case SYSTEM_ITEM_SIPPASSWORD:       bt->setTextOnly(TConfig::getSIPpassword(), -1); break;
2276
 
2277
                case SYSTEM_ITEM_SYSTEMSOUND:       bt->setTextOnly(TConfig::getSystemSound(), -1); break;
2278
                case SYSTEM_ITEM_SINGLEBEEP:        bt->setTextOnly(TConfig::getSingleBeepSound(), -1); break;
2279
                case SYSTEM_ITEM_DOUBLEBEEP:        bt->setTextOnly(TConfig::getDoubleBeepSound(), -1); break;
209 andreas 2280
            }
2281
        }
210 andreas 2282
        else if (bt->getChannelPort() == 0 && bt->getChannelNumber() > 0)
2283
        {
2284
            switch(bt->getChannelNumber())
2285
            {
2286
                case SYSTEM_ITEM_DEBUGINFO:         bt->setActiveInstance(IS_LOG_INFO() ? 1 : 0); break;
2287
                case SYSTEM_ITEM_DEBUGWARNING:      bt->setActiveInstance(IS_LOG_WARNING() ? 1 : 0); break;
2288
                case SYSTEM_ITEM_DEBUGERROR:        bt->setActiveInstance(IS_LOG_ERROR() ? 1 : 0); break;
2289
                case SYSTEM_ITEM_DEBUGTRACE:        bt->setActiveInstance(IS_LOG_TRACE() ? 1 : 0); break;
2290
                case SYSTEM_ITEM_DEBUGDEBUG:        bt->setActiveInstance(IS_LOG_DEBUG() ? 1 : 0); break;
2291
                case SYSTEM_ITEM_DEBUGPROTOCOL:     bt->setActiveInstance(IS_LOG_PROTOCOL() ? 1 : 0); break;
2292
                case SYSTEM_ITEM_DEBUGALL:          bt->setActiveInstance(IS_LOG_ALL() ? 1 : 0); break;
2293
                case SYSTEM_ITEM_DEBUGLONG:         bt->setActiveInstance(TConfig::isLongFormat() ? 1 : 0); break;
2294
                case SYSTEM_ITEM_DEBUGPROFILE:      bt->setActiveInstance(TConfig::getProfiling() ? 1 : 0); break;
2295
 
2296
                case SYSTEM_ITEM_FTPPASSIVE:        bt->setActiveInstance(TConfig::getFtpPassive() ? 1 : 0); break;
2297
 
2298
                case SYSTEM_ITEM_SIPIPV4:           bt->setActiveInstance(TConfig::getSIPnetworkIPv4() ? 1 : 0); break;
2299
                case SYSTEM_ITEM_SIPIPV6:           bt->setActiveInstance(TConfig::getSIPnetworkIPv6() ? 1 : 0); break;
2300
                case SYSTEM_ITEM_SIPENABLE:         bt->setActiveInstance(TConfig::getSIPstatus() ? 1 : 0); break;
2301
                case SYSTEM_ITEM_SIPIPHONE:         bt->setActiveInstance(TConfig::getSIPiphone() ? 1 : 0); break;
2302
 
2303
                case SYSTEM_ITEM_SOUNDSWITCH:       bt->setActiveInstance(TConfig::getSystemSoundState() ? 1 : 0); break;
2304
 
2305
                case SYSTEM_ITEM_VIEWSCALEFIT:      bt->setActiveInstance(TConfig::getScale() ? 1 : 0); break;
2306
                case SYSTEM_ITEM_VIEWBANNER:        bt->setActiveInstance(TConfig::showBanner() ? 1 : 0); break;
2307
                case SYSTEM_ITEM_VIEWNOTOOLBAR:     bt->setActiveInstance(TConfig::getToolbarSuppress() ? 1 : 0); break;
2308
                case SYSTEM_ITEM_VIEWTOOLBAR:       bt->setActiveInstance(TConfig::getToolbarForce() ? 1 : 0); break;
2309
                case SYSTEM_ITEM_VIEWROTATE:        bt->setActiveInstance(TConfig::getRotationFixed() ? 1 : 0); break;
2310
            }
2311
        }
2312
        else if (bt->getLevelPort() == 0 && bt->getLevelValue() > 0)
2313
        {
2314
            switch(bt->getLevelValue())
2315
            {
2316
                case SYSTEM_ITEM_SYSVOLUME:         bt->drawBargraph(0, TConfig::getSystemVolume(), false); break;
2317
                case SYSTEM_ITEM_SYSGAIN:           bt->drawBargraph(0, TConfig::getSystemGain(), false); break;
2318
            }
2319
        }
209 andreas 2320
    }
2321
}
2322
 
198 andreas 2323
bool TPageManager::setPage(int PageID, bool forget)
15 andreas 2324
{
198 andreas 2325
    DECL_TRACER("TPageManager::setPage(int PageID, bool forget)");
15 andreas 2326
 
295 andreas 2327
    return _setPageDo(PageID, "", forget);
15 andreas 2328
}
2329
 
168 andreas 2330
bool TPageManager::setPage(const string& name, bool forget)
15 andreas 2331
{
190 andreas 2332
    DECL_TRACER("TPageManager::setPage(const string& name, bool forget)");
15 andreas 2333
 
295 andreas 2334
    return _setPageDo(0, name, forget);
15 andreas 2335
}
2336
 
295 andreas 2337
bool TPageManager::_setPageDo(int pageID, const string& name, bool forget)
2338
{
2339
    DECL_TRACER("TPageManager::_setPageDo(int pageID, const string& name, bool forget)");
2340
 
2341
    TPage *pg = nullptr;
2342
 
2343
    if (pageID > 0 && mActualPage == pageID)
343 andreas 2344
    {
2345
#if TESTMODE == 1
2346
        __success = true;
2347
        setScreenDone();
2348
#endif
295 andreas 2349
        return true;
343 andreas 2350
    }
295 andreas 2351
    else if (!name.empty())
2352
    {
2353
        pg = getPage(mActualPage);
2354
 
2355
        if (pg && pg->getName().compare(name) == 0)
343 andreas 2356
        {
2357
#if TESTMODE == 1
2358
            __success = true;
2359
            setScreenDone();
2360
#endif
295 andreas 2361
            return true;
343 andreas 2362
        }
295 andreas 2363
    }
2364
    else if (pageID > 0)
2365
        pg = getPage(mActualPage);
2366
    else
343 andreas 2367
    {
2368
#if TESTMODE == 1
2369
        setScreenDone();
2370
#endif
295 andreas 2371
        return false;
343 andreas 2372
    }
295 andreas 2373
 
2374
    // FIXME: Make this a vector array to hold a larger history!
2375
    if (!forget)
2376
        mPreviousPage = mActualPage;    // Necessary to be able to jump back to at least the last previous page
2377
 
2378
    if (pg)
2379
        pg->drop();
2380
 
2381
    mActualPage = 0;
2382
    PAGELIST_T listPg;
2383
 
2384
    if (pageID > 0)
2385
        listPg = findPage(pageID);
2386
    else
2387
        listPg = findPage(name);
2388
 
2389
    bool refresh = false;
2390
 
2391
    if ((pg = loadPage(listPg, &refresh)) == nullptr)
343 andreas 2392
    {
2393
#if TESTMODE == 1
2394
        setScreenDone();
2395
#endif
295 andreas 2396
        return false;
343 andreas 2397
    }
295 andreas 2398
 
2399
    mActualPage = pg->getNumber();
2400
 
2401
    if (mActualPage >= SYSTEM_PAGE_START && !refresh)
2402
        reloadSystemPage(pg);
2403
 
2404
    int width = (mActualPage >= SYSTEM_PAGE_START ? mSystemSettings->getWidth() : mTSettings->getWidth());
2405
    int height = (mActualPage >= SYSTEM_PAGE_START ? mSystemSettings->getHeight() : mTSettings->getHeight());
2406
 
2407
    if (_setPage)
2408
        _setPage((mActualPage << 16) & 0xffff0000, width, height);
2409
 
2410
    pg->show();
2411
    return true;
2412
}
2413
 
2414
 
4 andreas 2415
TSubPage *TPageManager::getSubPage(int pageID)
2416
{
2417
    DECL_TRACER("TPageManager::getSubPage(int pageID)");
2418
 
2419
    SPCHAIN_T *p = mSPchain;
2420
 
2421
    while(p)
2422
    {
2423
        if (p->page->getNumber() == pageID)
2424
            return p->page;
2425
 
2426
        p = p->next;
2427
    }
2428
 
2429
    return nullptr;
2430
}
2431
 
2432
TSubPage *TPageManager::getSubPage(const std::string& name)
2433
{
2434
    DECL_TRACER("TPageManager::getSubPage(const std::string& name)");
2435
 
2436
    SPCHAIN_T *p = mSPchain;
2437
 
2438
    while (p)
2439
    {
2440
        if (p->page->getName().compare(name) == 0)
2441
            return p->page;
2442
 
2443
        p = p->next;
2444
    }
2445
 
146 andreas 2446
    MSG_DEBUG("Page " << name << " not found in cache.");
4 andreas 2447
    return nullptr;
2448
}
2449
 
96 andreas 2450
TSubPage *TPageManager::deliverSubPage(const string& name, TPage **pg)
2451
{
198 andreas 2452
    DECL_TRACER("TPageManager::deliverSubPage(const string& name, TPage **pg)");
96 andreas 2453
 
2454
    TPage *page = getActualPage();
2455
 
2456
    if (!page)
2457
    {
2458
        MSG_ERROR("No actual page loaded!");
2459
        return nullptr;
2460
    }
2461
 
2462
    if (pg)
2463
        *pg = page;
2464
 
2465
    TSubPage *subPage = getSubPage(name);
2466
 
2467
    if (!subPage)
2468
    {
2469
        if (!readSubPage(name))
2470
        {
2471
            MSG_ERROR("Error reading subpage " << name);
2472
            return nullptr;
2473
        }
2474
 
2475
        subPage = getSubPage(name);
2476
 
2477
        if (!subPage)
2478
        {
2479
            MSG_ERROR("Fatal: A page with name " << name << " does not exist!");
2480
            return nullptr;
2481
        }
350 andreas 2482
 
2483
        subPage->setParent(page->getHandle());
96 andreas 2484
    }
2485
 
2486
    return subPage;
2487
}
2488
 
198 andreas 2489
TSubPage *TPageManager::deliverSubPage(int number, TPage **pg)
2490
{
2491
    DECL_TRACER("TPageManager::deliverSubPage(int number, TPage **pg)");
2492
 
2493
    TPage *page = getActualPage();
2494
 
2495
    if (!page)
2496
    {
2497
        MSG_ERROR("No actual page loaded!");
2498
        return nullptr;
2499
    }
2500
 
2501
    if (pg)
2502
        *pg = page;
2503
 
2504
    TSubPage *subPage = getSubPage(number);
2505
 
2506
    if (!subPage)
2507
    {
2508
        if (!readSubPage(number))
2509
        {
2510
            MSG_ERROR("Error reading subpage " << number);
2511
            return nullptr;
2512
        }
2513
 
2514
        subPage = getSubPage(number);
2515
 
2516
        if (!subPage)
2517
        {
2518
            MSG_ERROR("Fatal: A page with name " << number << " does not exist!");
2519
            return nullptr;
2520
        }
350 andreas 2521
 
2522
        subPage->setParent(page->getHandle());
198 andreas 2523
    }
2524
 
2525
    return subPage;
2526
}
2527
 
3 andreas 2528
bool TPageManager::readPages()
2529
{
2530
    DECL_TRACER("TPageManager::readPages()");
2531
 
2532
    if (!mPageList)
2533
    {
2534
        MSG_ERROR("Page list is not initialized!");
2535
        TError::setError();
2536
        return false;
2537
    }
2538
 
2539
    // Read all pages
2540
    vector<PAGELIST_T> pageList = mPageList->getPagelist();
2541
 
83 andreas 2542
    if (pageList.size() > 0)
3 andreas 2543
    {
83 andreas 2544
        vector<PAGELIST_T>::iterator pgIter;
14 andreas 2545
 
118 andreas 2546
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
14 andreas 2547
        {
83 andreas 2548
            TPage *page = new TPage(pgIter->name+".xml");
14 andreas 2549
 
83 andreas 2550
            if (TError::isError())
2551
            {
2552
                delete page;
2553
                return false;
2554
            }
3 andreas 2555
 
83 andreas 2556
            page->setPalette(mPalette);
2557
            page->setFonts(mFonts);
2558
            page->registerCallback(_setBackground);
2559
            page->registerCallbackDB(_displayButton);
2560
            page->regCallPlayVideo(_callPlayVideo);
2561
 
2562
            if (!addPage(page))
2563
                return false;
2564
        }
3 andreas 2565
    }
2566
 
348 andreas 2567
    vector<SUBPAGELIST_T> subPageList = mPageList->getSubPageList();
3 andreas 2568
 
83 andreas 2569
    if (subPageList.size() > 0)
3 andreas 2570
    {
83 andreas 2571
        vector<SUBPAGELIST_T>::iterator spgIter;
14 andreas 2572
 
118 andreas 2573
        for (spgIter = subPageList.begin(); spgIter != subPageList.end(); ++spgIter)
14 andreas 2574
        {
83 andreas 2575
            TSubPage *page = new TSubPage(spgIter->name+".xml");
14 andreas 2576
 
83 andreas 2577
            if (TError::isError())
2578
            {
2579
                delete page;
2580
                return false;
2581
            }
3 andreas 2582
 
83 andreas 2583
            page->setPalette(mPalette);
2584
            page->setFonts(mFonts);
2585
            page->registerCallback(_setBackground);
2586
            page->registerCallbackDB(_displayButton);
2587
            page->regCallDropSubPage(_callDropSubPage);
2588
            page->regCallPlayVideo(_callPlayVideo);
2589
            page->setGroup(spgIter->group);
2590
 
2591
            if (!addSubPage(page))
2592
                return false;
2593
        }
3 andreas 2594
    }
2595
 
2596
    return true;
2597
}
2598
 
2599
bool TPageManager::readPage(const std::string& name)
2600
{
2601
    DECL_TRACER("TPageManager::readPage(const std::string& name)");
2602
 
2603
    PAGELIST_T page = findPage(name);
2604
 
206 andreas 2605
    if ((page.pageID <= 0 || page.pageID >= MAX_PAGE_ID) && page.pageID < SYSTEM_PAGE_START && page.pageID >= SYSTEM_SUBPAGE_START)
3 andreas 2606
    {
2607
        MSG_ERROR("Page " << name << " not found!");
2608
        return false;
2609
    }
2610
 
43 andreas 2611
    TPage *pg;
14 andreas 2612
 
43 andreas 2613
    if (name.compare("_progress") == 0)
2614
        pg = new TPage(name);
2615
    else
2616
        pg = new TPage(page.name+".xml");
2617
 
14 andreas 2618
    if (TError::isError())
2619
    {
2620
        delete pg;
2621
        return false;
2622
    }
2623
 
4 andreas 2624
    pg->setPalette(mPalette);
7 andreas 2625
    pg->setFonts(mFonts);
2626
    pg->registerCallback(_setBackground);
2627
    pg->registerCallbackDB(_displayButton);
21 andreas 2628
    pg->regCallPlayVideo(_callPlayVideo);
3 andreas 2629
 
2630
    if (!addPage(pg))
2631
        return false;
2632
 
2633
    return true;
2634
}
2635
 
2636
bool TPageManager::readPage(int ID)
2637
{
2638
    DECL_TRACER("TPageManager::readPage(int ID)");
2639
 
16 andreas 2640
    TError::clear();
3 andreas 2641
    PAGELIST_T page = findPage(ID);
2642
 
2643
    if (page.pageID <= 0)
2644
    {
2645
        MSG_ERROR("Page with ID " << ID << " not found!");
2646
        return false;
2647
    }
2648
 
43 andreas 2649
    TPage *pg;
14 andreas 2650
 
43 andreas 2651
    if (ID == 300)      // Progress page of system?
2652
        pg = new TPage("_progress");
2653
    else
2654
        pg = new TPage(page.name+".xml");
2655
 
14 andreas 2656
    if (TError::isError())
2657
    {
2658
        delete pg;
2659
        return false;
2660
    }
2661
 
4 andreas 2662
    pg->setPalette(mPalette);
7 andreas 2663
    pg->setFonts(mFonts);
2664
    pg->registerCallback(_setBackground);
2665
    pg->registerCallbackDB(_displayButton);
21 andreas 2666
    pg->regCallPlayVideo(_callPlayVideo);
3 andreas 2667
 
2668
    if (!addPage(pg))
2669
        return false;
2670
 
2671
    return true;
2672
}
2673
 
2674
bool TPageManager::readSubPage(const std::string& name)
2675
{
2676
    DECL_TRACER("TPageManager::readSubPage(const std::string& name)");
2677
 
16 andreas 2678
    TError::clear();
3 andreas 2679
    SUBPAGELIST_T page = findSubPage(name);
2680
 
206 andreas 2681
    if (page.pageID < MAX_PAGE_ID || (page.pageID >= SYSTEM_PAGE_START && page.pageID < SYSTEM_SUBPAGE_START))
3 andreas 2682
    {
2683
        MSG_ERROR("Subpage " << name << " not found!");
2684
        return false;
2685
    }
2686
 
14 andreas 2687
    if (haveSubPage(name))
2688
        return true;
2689
 
3 andreas 2690
    TSubPage *pg = new TSubPage(page.name+".xml");
14 andreas 2691
 
2692
    if (TError::isError())
2693
    {
2694
        delete pg;
2695
        return false;
2696
    }
2697
 
4 andreas 2698
    pg->setPalette(mPalette);
7 andreas 2699
    pg->setFonts(mFonts);
2700
    pg->registerCallback(_setBackground);
2701
    pg->registerCallbackDB(_displayButton);
11 andreas 2702
    pg->regCallDropSubPage(_callDropSubPage);
21 andreas 2703
    pg->regCallPlayVideo(_callPlayVideo);
11 andreas 2704
    pg->setGroup(page.group);
3 andreas 2705
 
2706
    if (!addSubPage(pg))
14 andreas 2707
    {
2708
        delete pg;
3 andreas 2709
        return false;
14 andreas 2710
    }
3 andreas 2711
 
2712
    return true;
2713
}
2714
 
2715
bool TPageManager::readSubPage(int ID)
2716
{
2717
    DECL_TRACER("TPageManager::readSubPage(int ID)");
2718
 
16 andreas 2719
    TError::clear();
3 andreas 2720
    SUBPAGELIST_T page = findSubPage(ID);
2721
 
154 andreas 2722
    if (page.pageID <= MAX_PAGE_ID)
3 andreas 2723
    {
2724
        MSG_ERROR("Subpage with ID " << ID << " not found!");
2725
        return false;
2726
    }
2727
 
2728
    TSubPage *pg = new TSubPage(page.name+".xml");
14 andreas 2729
 
2730
    if (TError::isError())
2731
    {
2732
        delete pg;
2733
        return false;
2734
    }
2735
 
4 andreas 2736
    pg->setPalette(mPalette);
7 andreas 2737
    pg->setFonts(mFonts);
2738
    pg->registerCallback(_setBackground);
2739
    pg->registerCallbackDB(_displayButton);
11 andreas 2740
    pg->regCallDropSubPage(_callDropSubPage);
21 andreas 2741
    pg->regCallPlayVideo(_callPlayVideo);
11 andreas 2742
    pg->setGroup(page.group);
3 andreas 2743
 
2744
    if (!addSubPage(pg))
2745
        return false;
2746
 
2747
    return true;
2748
}
2749
 
279 andreas 2750
vector<TSubPage *> TPageManager::createSubViewList(int id)
2751
{
2752
    DECL_TRACER("TPageManager::createSubViewList(int id)");
2753
 
2754
    vector<TSubPage *> subviews;
2755
 
2756
    if (id <= 0)
2757
        return subviews;
2758
 
2759
    if (!mPageList)
2760
    {
2761
        MSG_WARNING("Missing page list and because of this can't make a subview list!");
2762
        return subviews;
2763
    }
2764
 
2765
    SUBVIEWLIST_T slist = mPageList->findSubViewList(id);
2766
 
2767
    if (slist.id <= 0 || slist.items.empty())
2768
    {
2769
        if (slist.id <= 0)
2770
        {
2771
            MSG_WARNING("Found no subview list with ID " << id);
2772
        }
2773
        else
2774
        {
300 andreas 2775
            MSG_WARNING("Subview list " << id << " has no items!");
279 andreas 2776
        }
2777
 
2778
        return subviews;
2779
    }
2780
 
2781
    vector<SUBVIEWITEM_T>::iterator iter;
2782
 
2783
    for (iter = slist.items.begin(); iter != slist.items.end(); ++iter)
2784
    {
2785
        if (!haveSubPage(iter->pageID))
2786
        {
2787
            if (!readSubPage(iter->pageID))
2788
                return vector<TSubPage *>();
2789
        }
2790
 
284 andreas 2791
        TSubPage *pg = getSubPage(iter->pageID);
279 andreas 2792
 
2793
        if (pg)
2794
            subviews.push_back(pg);
284 andreas 2795
        else
2796
        {
2797
            MSG_DEBUG("No subpage with ID " << id);
2798
        }
279 andreas 2799
    }
2800
 
300 andreas 2801
    MSG_DEBUG("Found " << subviews.size() << " subview items.");
279 andreas 2802
    return subviews;
2803
}
2804
 
280 andreas 2805
void TPageManager::showSubViewList(int id, Button::TButton *bt)
279 andreas 2806
{
280 andreas 2807
    DECL_TRACER("TPageManager::showSubViewList(int id, Button::TButton *bt)");
279 andreas 2808
 
2809
    vector<TSubPage *> subviews = createSubViewList(id);
2810
 
303 andreas 2811
    if (subviews.empty() || !_addViewButtonItems || !bt)
284 andreas 2812
    {
2813
        MSG_DEBUG("Number views: " << subviews.size() << (_addViewButtonItems ? ", addView" : ", NO addView") << (_displayViewButton ? " display" : " NO display"));
279 andreas 2814
        return;
284 andreas 2815
    }
279 andreas 2816
 
293 andreas 2817
    ulong btHandle = bt->getHandle();
2818
    MSG_DEBUG("Working on button " << handleToString(btHandle) << " (" << bt->getName() << ") with " << subviews.size() << " pages.");
289 andreas 2819
    TBitmap bm = bt->getLastBitmap();
2820
    TColor::COLOR_T fillColor = TColor::getAMXColor(bt->getFillColor());
293 andreas 2821
    _displayViewButton(btHandle, bt->getParent(), bt->isSubViewVertical(), bm, bt->getWidth(), bt->getHeight(), bt->getLeftPosition(), bt->getTopPosition(), bt->getSubViewSpace(), fillColor);
280 andreas 2822
 
2823
    vector<PGSUBVIEWITEM_T> items;
2824
    PGSUBVIEWITEM_T svItem;
2825
    PGSUBVIEWATOM_T svAtom;
279 andreas 2826
    vector<TSubPage *>::iterator iter;
2827
 
2828
    for (iter = subviews.begin(); iter != subviews.end(); ++iter)
2829
    {
280 andreas 2830
        TSubPage *sub = *iter;
306 andreas 2831
        sub->setParent(btHandle);
279 andreas 2832
 
289 andreas 2833
        svItem.clear();
2834
        Button::TButton *button = sub->getFirstButton();
2835
        SkBitmap bitmap = sub->getBgImage();
280 andreas 2836
 
2837
        svItem.handle = sub->getHandle();
289 andreas 2838
        svItem.parent = btHandle;
280 andreas 2839
        svItem.width = sub->getWidth();
2840
        svItem.height = sub->getHeight();
281 andreas 2841
        svItem.bgcolor = TColor::getAMXColor(sub->getFillColor());
300 andreas 2842
        svItem.scrollbar = bt->getSubViewScrollbar();
2843
        svItem.scrollbarOffset = bt->getSubViewScrollbarOffset();
2844
        svItem.position = bt->getSubViewAnchor();
302 andreas 2845
        svItem.wrap = bt->getWrapSubViewPages();
280 andreas 2846
 
289 andreas 2847
        if (!bitmap.empty())
2848
            svItem.image.setBitmap((unsigned char *)bitmap.getPixels(), bitmap.info().width(), bitmap.info().height(), bitmap.info().bytesPerPixel());
280 andreas 2849
 
289 andreas 2850
        while (button)
280 andreas 2851
        {
300 andreas 2852
            button->drawButton(0, false, true);
289 andreas 2853
            svAtom.clear();
2854
            svAtom.handle = button->getHandle();
280 andreas 2855
            svAtom.parent = sub->getHandle();
289 andreas 2856
            svAtom.width = button->getWidth();
2857
            svAtom.height = button->getHeight();
2858
            svAtom.left = button->getLeftPosition();
2859
            svAtom.top = button->getTopPosition();
300 andreas 2860
            svAtom.bgcolor = TColor::getAMXColor(button->getFillColor(button->getActiveInstance()));
293 andreas 2861
            svAtom.bounding = button->getBounding();
289 andreas 2862
            Button::BITMAP_t bmap = button->getLastImage();
280 andreas 2863
 
289 andreas 2864
            if (bmap.buffer)
300 andreas 2865
                svAtom.image.setBitmap(bmap.buffer, bmap.width, bmap.height, (int)(bmap.rowBytes / bmap.width));
289 andreas 2866
 
280 andreas 2867
            svItem.atoms.push_back(svAtom);
289 andreas 2868
            button = sub->getNextButton();
280 andreas 2869
        }
2870
 
2871
        items.push_back(svItem);
279 andreas 2872
    }
281 andreas 2873
 
285 andreas 2874
    _addViewButtonItems(bt->getHandle(), items);
284 andreas 2875
 
2876
    if (_pageFinished)
306 andreas 2877
        _pageFinished(bt->getHandle());
279 andreas 2878
}
2879
 
300 andreas 2880
void TPageManager::updateSubViewItem(Button::TButton *bt)
2881
{
2882
    DECL_TRACER("TPageManager::updateSubViewItem(Button::TButton *bt)");
2883
 
303 andreas 2884
    if (!bt)
300 andreas 2885
        return;
2886
 
303 andreas 2887
    updview_mutex.lock();
2888
    mUpdateViews.push_back(bt);
2889
    updview_mutex.unlock();
2890
}
2891
 
2892
void TPageManager::_updateSubViewItem(Button::TButton *bt)
2893
{
2894
    DECL_TRACER("TPageManager::_updateSubViewItem(Button::TButton *bt)");
2895
 
2896
    if (!mPageList || !_updateViewButtonItem)
2897
        return;
2898
 
300 andreas 2899
    // The parent of this kind of button is always the button of type subview.
2900
    // If we take the parent handle and extract the page ID (upper 16 bits)
2901
    // we get the page ID of the subpage or page ID of the page the button is
2902
    // ordered to.
2903
    int pageID = (bt->getParent() >> 16) & 0x0000ffff;
306 andreas 2904
    ulong parent = 0;
300 andreas 2905
    Button::TButton *button = nullptr;
2906
    PGSUBVIEWITEM_T item;
2907
    PGSUBVIEWATOM_T atom;
2908
    SkBitmap bitmap;
2909
    TPage *pg = nullptr;
2910
    TSubPage *sub = nullptr;
2911
 
2912
    if (pageID < REGULAR_SUBPAGE_START)     // Is it a page?
2913
    {
2914
        pg = getPage(pageID);
2915
 
2916
        if (!pg)
2917
        {
2918
            MSG_WARNING("Invalid page " << pageID << "!");
2919
            return;
2920
        }
2921
 
2922
        button = pg->getFirstButton();
2923
        bitmap = pg->getBgImage();
2924
 
2925
        item.handle = pg->getHandle();
2926
        item.parent = bt->getParent();
2927
        item.width = pg->getWidth();
2928
        item.height = pg->getHeight();
2929
        item.bgcolor = TColor::getAMXColor(pg->getFillColor());
2930
    }
2931
    else
2932
    {
2933
        sub = getSubPage(pageID);
2934
 
2935
        if (!sub)
2936
        {
2937
            MSG_WARNING("Couldn't find the subpage " << pageID << "!");
2938
            return;
2939
        }
2940
 
306 andreas 2941
        parent = sub->getParent();
300 andreas 2942
        button = sub->getFirstButton();
2943
        bitmap = sub->getBgImage();
2944
 
2945
        item.handle = sub->getHandle();
2946
        item.parent = bt->getParent();
2947
        item.width = sub->getWidth();
2948
        item.height = sub->getHeight();
303 andreas 2949
        item.position = bt->getSubViewAnchor();
300 andreas 2950
        item.bgcolor = TColor::getAMXColor(sub->getFillColor());
2951
    }
2952
 
2953
 
2954
    if (!bitmap.empty())
2955
        item.image.setBitmap((unsigned char *)bitmap.getPixels(), bitmap.info().width(), bitmap.info().height(), bitmap.info().bytesPerPixel());
2956
 
2957
    while (button)
2958
    {
2959
        atom.clear();
2960
        atom.handle = button->getHandle();
303 andreas 2961
        atom.parent = item.handle;
300 andreas 2962
        atom.width = button->getWidth();
2963
        atom.height = button->getHeight();
2964
        atom.left = button->getLeftPosition();
2965
        atom.top = button->getTopPosition();
2966
        atom.bgcolor = TColor::getAMXColor(button->getFillColor(button->getActiveInstance()));
2967
        atom.bounding = button->getBounding();
2968
        Button::BITMAP_t bmap = button->getLastImage();
2969
 
2970
        if (bmap.buffer)
2971
            atom.image.setBitmap(bmap.buffer, bmap.width, bmap.height, (int)(bmap.rowBytes / bmap.width));
2972
 
2973
        item.atoms.push_back(atom);
2974
        button = (pg ? pg->getNextButton() : sub->getNextButton());
2975
    }
2976
 
306 andreas 2977
    _updateViewButtonItem(item, parent);
300 andreas 2978
}
2979
 
192 andreas 2980
void TPageManager::updateActualPage()
2981
{
2982
    DECL_TRACER("TPageManager::updateActualPage()");
2983
 
2984
    if (!mActualPage)
2985
        return;
2986
 
2987
    TPage *pg = getPage(mActualPage);
2988
    Button::TButton *bt = pg->getFirstButton();
2989
 
2990
    while (bt)
2991
    {
2992
        bt->refresh();
2993
        bt = pg->getNextButton();
2994
    }
2995
}
2996
 
2997
void TPageManager::updateSubpage(int ID)
2998
{
2999
    DECL_TRACER("TPageManager::updateSubpage(int ID)");
3000
 
3001
    TSubPage *pg = getSubPage(ID);
3002
 
3003
    if (!pg)
3004
        return;
3005
 
3006
    vector<Button::TButton *> blist = pg->getAllButtons();
3007
    vector<Button::TButton *>::iterator iter;
3008
 
3009
    if (blist.empty())
3010
        return;
3011
 
3012
    for (iter = blist.begin(); iter != blist.end(); ++iter)
3013
    {
3014
        Button::TButton *bt = *iter;
3015
        bt->refresh();
3016
    }
3017
}
3018
 
3019
void TPageManager::updateSubpage(const std::string &name)
3020
{
3021
    DECL_TRACER("TPageManager::updateSubpage(const std::string &name)");
3022
 
3023
    TSubPage *pg = getSubPage(name);
3024
 
3025
    if (!pg)
3026
        return;
3027
 
3028
    vector<Button::TButton *> blist = pg->getAllButtons();
3029
    vector<Button::TButton *>::iterator iter;
3030
 
3031
    if (blist.empty())
3032
        return;
3033
 
3034
    for (iter = blist.begin(); iter != blist.end(); ++iter)
3035
    {
3036
        Button::TButton *bt = *iter;
3037
        bt->refresh();
3038
    }
3039
}
3040
 
3 andreas 3041
/******************** Internal private methods *********************/
3042
 
3043
PAGELIST_T TPageManager::findPage(const std::string& name)
3044
{
3045
    DECL_TRACER("TPageManager::findPage(const std::string& name)");
3046
 
194 andreas 3047
    vector<PAGELIST_T> pageList;
3 andreas 3048
 
194 andreas 3049
    if (!mSetupActive)
3050
        pageList = mPageList->getPagelist();
3051
    else
3052
        pageList = mPageList->getSystemPagelist();
3053
 
83 andreas 3054
    if (pageList.size() > 0)
3 andreas 3055
    {
83 andreas 3056
        vector<PAGELIST_T>::iterator pgIter;
3057
 
118 andreas 3058
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 3059
        {
3060
            if (pgIter->name.compare(name) == 0)
3061
                return *pgIter;
3062
        }
3 andreas 3063
    }
3064
 
194 andreas 3065
    MSG_WARNING("Page " << name << " not found!");
3 andreas 3066
    return PAGELIST_T();
3067
}
3068
 
3069
PAGELIST_T TPageManager::findPage(int ID)
3070
{
3071
    DECL_TRACER("TPageManager::findPage(int ID)");
3072
 
206 andreas 3073
    vector<PAGELIST_T> pageList = (ID < SYSTEM_PAGE_START ? mPageList->getPagelist() : mPageList->getSystemPagelist());
3 andreas 3074
 
83 andreas 3075
    if (pageList.size() > 0)
3 andreas 3076
    {
83 andreas 3077
        vector<PAGELIST_T>::iterator pgIter;
3078
 
118 andreas 3079
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 3080
        {
3081
            if (pgIter->pageID == ID)
3082
                return *pgIter;
3083
        }
3 andreas 3084
    }
3085
 
3086
    return PAGELIST_T();
3087
}
3088
 
3089
SUBPAGELIST_T TPageManager::findSubPage(const std::string& name)
3090
{
3091
    DECL_TRACER("TPageManager::findSubPage(const std::string& name)");
3092
 
348 andreas 3093
    vector<SUBPAGELIST_T> pageList = (mSetupActive ? mPageList->getSystemSupPageList() : mPageList->getSubPageList());
3 andreas 3094
 
83 andreas 3095
    if (pageList.size() > 0)
3 andreas 3096
    {
83 andreas 3097
        vector<SUBPAGELIST_T>::iterator pgIter;
3098
 
118 andreas 3099
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 3100
        {
3101
            if (pgIter->name.compare(name) == 0)
3102
                return *pgIter;
3103
        }
3 andreas 3104
    }
3105
 
3106
    return SUBPAGELIST_T();
3107
}
3108
 
3109
SUBPAGELIST_T TPageManager::findSubPage(int ID)
3110
{
3111
    DECL_TRACER("TPageManager::findSubPage(int ID)");
3112
 
348 andreas 3113
    vector<SUBPAGELIST_T> pageList = (ID < SYSTEM_PAGE_START ? mPageList->getSubPageList() : mPageList->getSystemSupPageList());
3 andreas 3114
 
83 andreas 3115
    if (pageList.size() > 0)
3 andreas 3116
    {
83 andreas 3117
        vector<SUBPAGELIST_T>::iterator pgIter;
3118
 
118 andreas 3119
        for (pgIter = pageList.begin(); pgIter != pageList.end(); ++pgIter)
83 andreas 3120
        {
3121
            if (pgIter->pageID == ID)
3122
                return *pgIter;
3123
        }
3 andreas 3124
    }
3125
 
3126
    return SUBPAGELIST_T();
3127
}
3128
 
3129
bool TPageManager::addPage(TPage* pg)
3130
{
3131
    DECL_TRACER("TPageManager::addPage(TPage* pg)");
3132
 
3133
    if (!pg)
3134
    {
3135
        MSG_ERROR("Parameter is NULL!");
3136
        TError::setError();
3137
        return false;
3138
    }
3139
 
3140
    PCHAIN_T *chain = new PCHAIN_T;
3141
    chain->page = pg;
5 andreas 3142
    chain->next = nullptr;
3 andreas 3143
 
3144
    if (mPchain)
3145
    {
3146
        PCHAIN_T *p = mPchain;
3147
 
3148
        while (p->next)
3149
            p = p->next;
3150
 
3151
        p->next = chain;
3152
    }
3153
    else
14 andreas 3154
    {
3 andreas 3155
        mPchain = chain;
14 andreas 3156
        setPChain(mPchain);
3157
    }
3 andreas 3158
 
156 andreas 3159
//    MSG_DEBUG("Added page " << chain->page->getName());
3 andreas 3160
    return true;
3161
}
3162
 
3163
bool TPageManager::addSubPage(TSubPage* pg)
3164
{
3165
    DECL_TRACER("TPageManager::addSubPage(TSubPage* pg)");
3166
 
3167
    if (!pg)
3168
    {
3169
        MSG_ERROR("Parameter is NULL!");
3170
        TError::setError();
3171
        return false;
3172
    }
3173
 
14 andreas 3174
    if (haveSubPage(pg->getNumber()))
3175
    {
3176
        MSG_ERROR("Subpage " << pg->getNumber() << ", " << pg->getName() << " is already in chain!");
3177
        return false;
3178
    }
3179
 
3 andreas 3180
    SPCHAIN_T *chain = new SPCHAIN_T;
3181
    chain->page = pg;
5 andreas 3182
    chain->next = nullptr;
3 andreas 3183
 
3184
    if (mSPchain)
3185
    {
3186
        SPCHAIN_T *p = mSPchain;
3187
 
3188
        while (p->next)
3189
            p = p->next;
3190
 
3191
        p->next = chain;
3192
    }
3193
    else
14 andreas 3194
    {
3 andreas 3195
        mSPchain = chain;
14 andreas 3196
        setSPChain(mSPchain);
3197
    }
3 andreas 3198
 
3199
    return true;
3200
}
4 andreas 3201
 
11 andreas 3202
void TPageManager::dropAllPages()
3203
{
3204
    DECL_TRACER("TPageManager::dropAllPages()");
3205
 
3206
    PCHAIN_T *pg = mPchain;
3207
    PCHAIN_T *next = nullptr;
3208
 
3209
    while (pg)
3210
    {
3211
        next = pg->next;
3212
 
3213
        if (pg->page)
3214
        {
3215
            if (_callDropPage)
3216
                _callDropPage((pg->page->getNumber() << 16) & 0xffff0000);
3217
 
3218
            delete pg->page;
3219
        }
3220
 
3221
        delete pg;
3222
        pg = next;
3223
    }
14 andreas 3224
 
3225
    mPchain = nullptr;
3226
    setPChain(mPchain);
11 andreas 3227
}
3228
 
3229
void TPageManager::dropAllSubPages()
3230
{
3231
    DECL_TRACER("TPageManager::dropAllSubPages()");
3232
 
3233
    SPCHAIN_T *spg = mSPchain;
3234
    SPCHAIN_T *next;
3235
 
3236
    while (spg)
3237
    {
3238
        next = spg->next;
3239
 
3240
        if (spg->page)
3241
        {
3242
            if (_callDropSubPage)
350 andreas 3243
                _callDropSubPage((spg->page->getNumber() << 16) & 0xffff0000, spg->page->getParent());
11 andreas 3244
 
3245
            delete spg->page;
3246
        }
3247
 
3248
        delete spg;
3249
        spg = next;
3250
    }
14 andreas 3251
 
3252
    mSPchain = nullptr;
3253
    setSPChain(mSPchain);
11 andreas 3254
}
3255
 
44 andreas 3256
bool TPageManager::destroyAll()
3257
{
3258
    DECL_TRACER("TPageManager::destroyAll()");
3259
 
3260
    dropAllSubPages();
3261
    dropAllPages();
3262
    mActualPage = 0;
3263
    mPreviousPage = 0;
3264
    mActualGroupName.clear();
3265
 
3266
    if (mPageList)
3267
    {
3268
        delete mPageList;
3269
        mPageList = nullptr;
3270
    }
3271
 
3272
    if (mTSettings)
3273
    {
3274
        delete mTSettings;
3275
        mTSettings = nullptr;
3276
    }
3277
 
194 andreas 3278
    if (mSystemSettings)
3279
    {
3280
        delete mSystemSettings;
3281
        mSystemSettings = nullptr;
3282
    }
3283
 
44 andreas 3284
    if (mPalette)
3285
    {
3286
        delete mPalette;
3287
        mPalette = nullptr;
3288
    }
3289
 
3290
    if (mFonts)
3291
    {
3292
        delete mFonts;
3293
        mFonts = nullptr;
3294
    }
3295
 
3296
    if (mExternal)
3297
    {
3298
        delete mExternal;
3299
        mExternal = nullptr;
3300
    }
3301
 
3302
    if (gPrjResources)
3303
    {
3304
        delete gPrjResources;
3305
        gPrjResources = nullptr;
3306
    }
3307
 
3308
    if (gIcons)
3309
    {
3310
        delete gIcons;
3311
        gIcons = nullptr;
3312
    }
3313
 
3314
    if (TError::isError())
3315
        return false;
3316
 
3317
    return true;
3318
}
3319
 
150 andreas 3320
bool TPageManager::overlap(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2)
3321
{
3322
    DECL_TRACER("TPageManager::overlap(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2)");
3323
 
3324
    struct point
3325
    {
3326
        int x;
3327
        int y;
3328
    };
3329
 
3330
    struct point l1, r1, l2, r2;
3331
 
3332
    l1.x = x1;
3333
    l1.y = y1;
3334
    r1.x = x1 + w1;
3335
    r1.y = y1 + h1;
3336
 
3337
    l2.x = x2;
3338
    l2.y = y2;
3339
    r2.x = x2 + w2;
3340
    r2.y = y2 + h2;
3341
 
3342
    if (l1.x == r1.x || l1.y == r1.y || l2.x == r2.x || l2.y == r2.y)
3343
    {
3344
        // the line cannot have positive overlap
3345
        return false;
3346
    }
3347
 
183 andreas 3348
    return std::max(l1.x, l2.x) < std::min(r1.x, r2.x) &&
150 andreas 3349
           std::max(l1.y, l2.y) < std::min(r1.y, r2.y);
3350
}
3351
 
51 andreas 3352
Button::TButton *TPageManager::findButton(ulong handle)
3353
{
3354
    DECL_TRACER("TPageManager::findButton(ulong handle)");
3355
 
209 andreas 3356
    if (!handle)
3357
        return nullptr;
3358
 
51 andreas 3359
    TPage *pg = getPage(mActualPage);
3360
 
3361
    if (!pg)
3362
        return nullptr;
3363
 
3364
    vector<Button::TButton *> pgBtList = pg->getAllButtons();
3365
    vector<Button::TButton *>::iterator iter;
83 andreas 3366
 
3367
    if (pgBtList.size() > 0)
51 andreas 3368
    {
83 andreas 3369
        // First we look into the elements of the page
3370
        for (iter = pgBtList.begin(); iter != pgBtList.end(); ++iter)
3371
        {
3372
            Button::TButton *bt = *iter;
51 andreas 3373
 
83 andreas 3374
            if (bt->getHandle() == handle)
3375
                return bt;
3376
        }
51 andreas 3377
    }
3378
 
3379
    // We've not found the wanted element in the elements of the page. So
3380
    // we're looking at the elements of the subpages.
3381
    TSubPage *sp = pg->getFirstSubPage();
3382
 
3383
    if (!sp)
3384
        return nullptr;
3385
 
3386
    while (sp)
3387
    {
3388
        vector<Button::TButton *> spBtList = sp->getAllButtons();
3389
 
83 andreas 3390
        if (spBtList.size() > 0)
51 andreas 3391
        {
83 andreas 3392
            for (iter = spBtList.begin(); iter != spBtList.end(); ++iter)
3393
            {
3394
                Button::TButton *bt = *iter;
51 andreas 3395
 
83 andreas 3396
                if (bt->getHandle() == handle)
3397
                    return bt;
3398
            }
51 andreas 3399
        }
3400
 
3401
        sp = pg->getNextSubPage();
3402
    }
3403
 
3404
    return nullptr;
3405
}
3406
 
4 andreas 3407
TPage *TPageManager::getActualPage()
3408
{
168 andreas 3409
    DECL_TRACER("TPageManager::getActualPage()");
3410
 
4 andreas 3411
    return getPage(mActualPage);
3412
}
3413
 
3414
TSubPage *TPageManager::getFirstSubPage()
3415
{
3416
    DECL_TRACER("TPageManager::getFirstSubPage()");
168 andreas 3417
 
349 andreas 3418
    mLastSubPage = 0;
4 andreas 3419
    TPage *pg = getPage(mActualPage);
3420
 
3421
    if (!pg)
3422
        return nullptr;
3423
 
349 andreas 3424
    map<int, TSubPage *> sp = pg->getSortedSubpages(true);
3425
 
3426
    if (!sp.empty())
3427
    {
3428
        map<int, TSubPage *>::iterator iter = sp.begin();
3429
        mLastSubPage = iter->first;
3430
        return iter->second;
3431
    }
3432
 
3433
    return nullptr;
4 andreas 3434
}
3435
 
3436
TSubPage *TPageManager::getNextSubPage()
3437
{
3438
    DECL_TRACER("TPageManager::getNextSubPage()");
3439
 
3440
    TPage *pg = getPage(mActualPage);
3441
 
3442
    if (pg)
349 andreas 3443
    {
3444
        map<int, TSubPage *> sp = pg->getSortedSubpages();
4 andreas 3445
 
349 andreas 3446
        if (sp.empty())
3447
        {
3448
            mLastSubPage = 0;
3449
            return nullptr;
3450
        }
3451
        else
3452
        {
3453
            map<int, TSubPage *>::iterator iter = sp.find(mLastSubPage);
3454
 
3455
            if (iter != sp.end())
3456
            {
3457
                iter++;
3458
 
3459
                if (iter != sp.end())
3460
                {
3461
                    mLastSubPage = iter->first;
3462
                    return iter->second;
3463
                }
3464
            }
3465
        }
3466
    }
3467
 
3468
    mLastSubPage = 0;
4 andreas 3469
    return nullptr;
3470
}
10 andreas 3471
 
154 andreas 3472
TSubPage *TPageManager::getPrevSubPage()
3473
{
3474
    DECL_TRACER("TPageManager::getPrevSubPage()");
3475
 
3476
    TPage *pg = getPage(mActualPage);
3477
 
3478
    if (pg)
349 andreas 3479
    {
3480
        map<int, TSubPage *> sp = pg->getSortedSubpages();
154 andreas 3481
 
349 andreas 3482
        if (sp.empty())
3483
        {
3484
            mLastSubPage = 0;
3485
            return nullptr;
3486
        }
3487
        else
3488
        {
3489
            map<int, TSubPage *>::iterator iter = sp.find(mLastSubPage);
3490
 
3491
            if (iter != sp.end() && iter != sp.begin())
3492
            {
3493
                iter--;
3494
                mLastSubPage = iter->first;
3495
                return iter->second;
3496
            }
3497
 
3498
            MSG_DEBUG("Page " << mLastSubPage << " not found!");
3499
        }
3500
    }
3501
 
3502
    mLastSubPage = 0;
154 andreas 3503
    return nullptr;
3504
}
3505
 
3506
TSubPage *TPageManager::getLastSubPage()
3507
{
3508
    DECL_TRACER("TPageManager::getLastSubPage()");
3509
 
349 andreas 3510
    mLastSubPage = 0;
154 andreas 3511
    TPage *pg = getPage(mActualPage);
3512
 
3513
    if (pg)
3514
    {
349 andreas 3515
        map<int, TSubPage *> sp = pg->getSortedSubpages(true);
3516
 
3517
        if (sp.empty())
3518
            return nullptr;
3519
        else
3520
        {
3521
            map<int, TSubPage *>::iterator iter = sp.end();
3522
            iter--;
3523
            mLastSubPage = iter->first;
3524
            return iter->second;
3525
        }
154 andreas 3526
    }
3527
    else
3528
    {
3529
        MSG_WARNING("Actual page " << mActualPage << " not found!");
3530
    }
3531
 
3532
    return nullptr;
3533
}
3534
 
11 andreas 3535
TSubPage *TPageManager::getFirstSubPageGroup(const string& group)
3536
{
3537
    DECL_TRACER("TPageManager::getFirstSubPageGroup(const string& group)");
3538
 
14 andreas 3539
    if (group.empty())
3540
    {
3541
        MSG_WARNING("Empty group name is invalid. Ignoring it!");
3542
        mActualGroupName.clear();
3543
        mActualGroupPage = nullptr;
3544
        return nullptr;
3545
    }
3546
 
11 andreas 3547
    mActualGroupName = group;
3548
    TSubPage *pg = getFirstSubPage();
3549
 
3550
    while (pg)
3551
    {
14 andreas 3552
        MSG_DEBUG("Evaluating group " << pg->getGroupName() << " with " << group);
3553
 
11 andreas 3554
        if (pg->getGroupName().compare(group) == 0)
3555
        {
3556
            mActualGroupPage = pg;
3557
            return pg;
3558
        }
3559
 
3560
        pg = getNextSubPage();
3561
    }
3562
 
3563
    mActualGroupName.clear();
3564
    mActualGroupPage = nullptr;
3565
    return nullptr;
3566
}
3567
 
3568
TSubPage *TPageManager::getNextSubPageGroup()
3569
{
3570
    DECL_TRACER("TPageManager::getNextSubPageGroup()");
3571
 
3572
    if (mActualGroupName.empty())
3573
        return nullptr;
3574
 
3575
    TSubPage *pg = getFirstSubPage();
3576
    bool found = false;
3577
 
3578
    while (pg)
3579
    {
14 andreas 3580
        MSG_DEBUG("Evaluating group " << pg->getGroupName() << " with " << mActualGroupName);
3581
 
3582
        if (!found && pg == mActualGroupPage)
11 andreas 3583
        {
3584
            pg = getNextSubPage();
14 andreas 3585
            found = true;
11 andreas 3586
            continue;
3587
        }
3588
 
14 andreas 3589
        if (found && pg->getGroupName().compare(mActualGroupName) == 0)
11 andreas 3590
        {
3591
            mActualGroupPage = pg;
3592
            return pg;
3593
        }
3594
 
3595
        pg = getNextSubPage();
3596
    }
3597
 
3598
    mActualGroupName.clear();
3599
    mActualGroupPage = nullptr;
3600
    return nullptr;
3601
}
3602
 
3603
TSubPage *TPageManager::getNextSubPageGroup(const string& group, TSubPage* pg)
3604
{
3605
    DECL_TRACER("TPageManager::getNextSubPageGroup(const string& group, TSubPage* pg)");
3606
 
3607
    if (group.empty() || !pg)
3608
        return nullptr;
3609
 
3610
    TSubPage *page = getFirstSubPage();
3611
    bool found = false;
3612
 
3613
    while (page)
3614
    {
14 andreas 3615
        MSG_DEBUG("Evaluating group " << pg->getGroupName() << " with " << group);
3616
 
3617
        if (!found && pg == page)
11 andreas 3618
        {
3619
            page = getNextSubPage();
14 andreas 3620
            found = true;
11 andreas 3621
            continue;
3622
        }
3623
 
14 andreas 3624
        if (found && page->getGroupName().compare(group) == 0)
11 andreas 3625
            return page;
3626
 
3627
        page = getNextSubPage();
3628
    }
3629
 
3630
    return nullptr;
3631
}
3632
 
3633
TSubPage *TPageManager::getTopPage()
3634
{
3635
    DECL_TRACER("TPageManager::getTopPage()");
3636
 
3637
    // Scan for all occupied regions
3638
    vector<RECT_T> regions;
3639
 
3640
    TSubPage *pg = getFirstSubPage();
3641
 
3642
    while (pg)
3643
    {
3644
        RECT_T r = pg->getRegion();
3645
        regions.push_back(r);
3646
        pg = getNextSubPage();
3647
    }
3648
 
3649
    // Now scan all pages against all regions to find the top most
3650
    pg = getFirstSubPage();
3651
    TSubPage *top = nullptr;
3652
    int zPos = 0;
3653
 
3654
    while (pg)
3655
    {
3656
        RECT_T r = pg->getRegion();
3657
 
83 andreas 3658
        if (regions.size() > 0)
11 andreas 3659
        {
83 andreas 3660
            vector<RECT_T>::iterator iter;
3661
            int zo = 0;
11 andreas 3662
 
118 andreas 3663
            for (iter = regions.begin(); iter != regions.end(); ++iter)
83 andreas 3664
            {
3665
                if (doOverlap(*iter, r) && zPos > zo)
3666
                    top = pg;
3667
 
3668
                zo++;
3669
            }
11 andreas 3670
        }
3671
 
3672
        pg = getNextSubPage();
3673
        zPos++;
3674
    }
3675
 
3676
    return top;
3677
}
3678
 
3679
TSubPage *TPageManager::getCoordMatch(int x, int y)
3680
{
3681
    DECL_TRACER("TPageManager::getCoordMatch(int x, int y)");
3682
 
26 andreas 3683
    int realX = x;
3684
    int realY = y;
3685
 
11 andreas 3686
    // Reverse order of pages
154 andreas 3687
    TSubPage *pg = getLastSubPage();
11 andreas 3688
 
154 andreas 3689
    // Iterate in reverse order through array
11 andreas 3690
    while (pg)
3691
    {
154 andreas 3692
        if (!pg->isVisible() || pg->getZOrder() == ZORDER_INVALID)
151 andreas 3693
        {
154 andreas 3694
            pg = getPrevSubPage();
3695
            continue;
151 andreas 3696
        }
14 andreas 3697
 
154 andreas 3698
        MSG_DEBUG("Scanning subpage (Z: " << pg->getZOrder() << "): " << pg->getNumber() << ", " << pg->getName());
3699
        RECT_T r = pg->getRegion();
11 andreas 3700
 
154 andreas 3701
        if (r.left <= realX && (r.left + r.width) >= realX &&
3702
            r.top <= realY && (r.top + r.height) >= realY)
11 andreas 3703
        {
154 andreas 3704
            MSG_DEBUG("Click matches subpage " << pg->getNumber() << " (" << pg->getName() << ")");
3705
            return pg;
3706
        }
83 andreas 3707
 
154 andreas 3708
        pg = getPrevSubPage();
11 andreas 3709
    }
3710
 
3711
    return nullptr;
3712
}
3713
 
40 andreas 3714
Button::TButton *TPageManager::getCoordMatchPage(int x, int y)
3715
{
3716
    DECL_TRACER("TPageManager::getCoordMatchPage(int x, int y)");
3717
 
3718
    TPage *page = getActualPage();
3719
 
3720
    if (page)
3721
    {
150 andreas 3722
        Button::TButton *bt = page->getLastButton();
40 andreas 3723
 
3724
        while (bt)
3725
        {
150 andreas 3726
            bool clickable = bt->isClickable();
3727
            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 3728
 
150 andreas 3729
            if (!clickable)
146 andreas 3730
            {
150 andreas 3731
                bt = page->getPreviousButton();
146 andreas 3732
                continue;
3733
            }
3734
 
40 andreas 3735
            if (bt->getLeftPosition() <= x && (bt->getLeftPosition() + bt->getWidth()) >= x &&
3736
                bt->getTopPosition() <= y && (bt->getTopPosition() + bt->getHeight()) >= y)
3737
            {
154 andreas 3738
                if (!bt->isClickable(x - bt->getLeftPosition(), y - bt->getTopPosition()))
3739
                {
3740
                    bt = page->getPreviousButton();
3741
                    continue;
3742
                }
3743
 
40 andreas 3744
                MSG_DEBUG("Click matches button " << bt->getButtonIndex() << " (" << bt->getButtonName() << ")");
3745
                return bt;
3746
            }
3747
 
150 andreas 3748
            bt = page->getPreviousButton();
40 andreas 3749
        }
3750
    }
3751
 
3752
    return nullptr;
3753
}
3754
 
11 andreas 3755
bool TPageManager::doOverlap(RECT_T r1, RECT_T r2)
3756
{
3757
    DECL_TRACER("TPageManager::doOverlap(RECT_T r1, RECT_T r2)");
3758
 
3759
    // If one rectangle is on left side of other
3760
    if (r1.left >= r2.left || r2.left >= r1.left)
3761
        return false;
3762
 
3763
    // If one rectangle is above other
3764
    if (r1.top <= r2.top || r2.top <= r1.top)
3765
        return false;
3766
 
3767
    return true;
3768
}
3769
 
14 andreas 3770
bool TPageManager::havePage(const string& name)
11 andreas 3771
{
14 andreas 3772
    DECL_TRACER("TPageManager::havePage(const string& name)");
11 andreas 3773
 
14 andreas 3774
    if (name.empty())
3775
        return false;
3776
 
3777
    PCHAIN_T *pg = mPchain;
3778
 
3779
    while (pg)
3780
    {
3781
        if (pg->page && pg->page->getName().compare(name) == 0)
3782
            return true;
3783
 
3784
        pg = pg->next;
3785
    }
3786
 
3787
    return false;
3788
}
3789
 
3790
bool TPageManager::haveSubPage(const string& name)
3791
{
3792
    DECL_TRACER("TPageManager::haveSubPage(const string& name)");
3793
 
3794
    if (name.empty())
3795
        return false;
3796
 
11 andreas 3797
    SPCHAIN_T *pg = mSPchain;
3798
 
3799
    while (pg)
3800
    {
14 andreas 3801
        if (pg->page && pg->page->getName().compare(name) == 0)
3802
        {
3803
            MSG_DEBUG("Subpage " << pg->page->getNumber() << ", " << name << " found.");
3804
            return true;
3805
        }
3806
 
3807
        pg = pg->next;
3808
    }
3809
 
3810
    MSG_DEBUG("Subpage " << name << " not found.");
3811
    return false;
3812
}
3813
 
3814
bool TPageManager::haveSubPage(int id)
3815
{
3816
    DECL_TRACER("TPageManager::haveSubPage(int id)");
3817
 
3818
    SPCHAIN_T *pg = mSPchain;
3819
 
3820
    while (pg)
3821
    {
3822
        if (pg->page && pg->page->getNumber() == id)
3823
        {
3824
            MSG_DEBUG("Subpage " << pg->page->getNumber() << ", " << pg->page->getName() << " found.");
3825
            return true;
3826
        }
3827
 
3828
        pg = pg->next;
3829
    }
3830
 
3831
    MSG_DEBUG("Subpage " << id << " not found.");
3832
    return false;
3833
}
3834
 
3835
bool TPageManager::haveSubPage(const string& page, const string& name)
3836
{
3837
    DECL_TRACER("TPageManager::haveSubPage(const string& page, const string& name)");
3838
 
3839
    TPage *pg = getPage(page);
3840
 
3841
    if (!pg)
3842
        return false;
3843
 
3844
    TSubPage *spg = pg->getFirstSubPage();
3845
 
3846
    while (spg)
3847
    {
3848
        if (spg->getName().compare(name) == 0)
3849
        {
3850
            MSG_DEBUG("Subpage " << spg->getNumber() << ", " << name << " found.");
3851
            return true;
3852
        }
3853
 
3854
        spg = pg->getNextSubPage();
3855
    }
3856
 
3857
    MSG_DEBUG("Subpage " << name << " not found on page " << page << ".");
3858
    return false;
3859
}
3860
 
3861
bool TPageManager::haveSubPage(const string& page, int id)
3862
{
3863
    DECL_TRACER("TPageManager::haveSubPage(const string& page, int id)");
3864
 
3865
    TPage *pg = getPage(page);
3866
 
3867
    if (!pg)
3868
        return false;
3869
 
3870
    TSubPage *spg = pg->getFirstSubPage();
3871
 
3872
    while (spg)
3873
    {
3874
        if (spg->getNumber() == id)
3875
        {
3876
            MSG_DEBUG("Subpage " << spg->getNumber() << ", " << spg->getName() << " found.");
3877
            return true;
3878
        }
3879
 
3880
        spg = pg->getNextSubPage();
3881
    }
3882
 
3883
    MSG_DEBUG("Subpage " << id << " on page " << page << " not found.");
3884
    return false;
3885
}
3886
 
3887
void TPageManager::closeGroup(const string& group)
3888
{
3889
    DECL_TRACER("TPageManager::closeGroup(const string& group)");
3890
 
3891
    SPCHAIN_T *pg = mSPchain;
3892
 
3893
    while (pg)
3894
    {
11 andreas 3895
        if (pg->page->getGroupName().compare(group) == 0 && pg->page->isVisible())
3896
        {
3897
            pg->page->regCallDropSubPage(_callDropSubPage);
3898
            pg->page->drop();
3899
            break;
3900
        }
3901
 
3902
        pg = pg->next;
3903
    }
3904
}
3905
 
14 andreas 3906
void TPageManager::showSubPage(const string& name)
3907
{
3908
    DECL_TRACER("TPageManager::showSubPage(const string& name)");
3909
 
3910
    if (name.empty())
349 andreas 3911
    {
3912
#if TESTMODE == 1
3913
        setScreenDone();
3914
#endif
14 andreas 3915
        return;
349 andreas 3916
    }
275 andreas 3917
 
152 andreas 3918
    TPage *page = nullptr;
3919
    TSubPage *pg = deliverSubPage(name, &page);
14 andreas 3920
 
96 andreas 3921
    if (!pg)
349 andreas 3922
    {
3923
#if TESTMODE == 1
3924
        setScreenDone();
3925
#endif
14 andreas 3926
        return;
349 andreas 3927
    }
14 andreas 3928
 
152 andreas 3929
    if (page)
350 andreas 3930
    {
3931
        pg->setParent(page->getHandle());
152 andreas 3932
        page->addSubPage(pg);
350 andreas 3933
    }
152 andreas 3934
 
14 andreas 3935
    string group = pg->getGroupName();
3936
 
3937
    if (!group.empty())
3938
    {
3939
        TSubPage *sub = getFirstSubPageGroup(group);
3940
 
3941
        while(sub)
3942
        {
3943
            if (sub->isVisible() && sub->getNumber() != pg->getNumber())
3944
                sub->drop();
3945
 
3946
            sub = getNextSubPageGroup(group, sub);
3947
        }
3948
    }
3949
 
150 andreas 3950
    if (pg->isVisible())
3951
    {
152 andreas 3952
        MSG_DEBUG("Page " << pg->getName() << " is already visible but maybe not on top.");
150 andreas 3953
 
3954
        TSubPage *sub = getFirstSubPage();
3955
        bool redraw = false;
3956
 
3957
        while (sub)
3958
        {
151 andreas 3959
            if (sub->isVisible() && pg->getZOrder() < sub->getZOrder() &&
3960
                overlap(sub->getLeft(), sub->getTop(), sub->getWidth(), sub->getHeight(),
150 andreas 3961
                pg->getLeft(), pg->getTop(), pg->getWidth(), pg->getHeight()))
3962
            {
3963
                MSG_DEBUG("Page " << sub->getName() << " is overlapping page " << pg->getName());
3964
                redraw = true;
3965
                break;
3966
            }
3967
 
3968
            sub = getNextSubPage();
3969
        }
3970
 
151 andreas 3971
        if (redraw && _toFront)
3972
        {
300 andreas 3973
            _toFront((uint)pg->getHandle());
151 andreas 3974
            pg->setZOrder(page->getNextZOrder());
349 andreas 3975
//            page->sortSubpages();
154 andreas 3976
            MSG_DEBUG("Setting new Z-order " << page->getActZOrder() << " on subpage " << pg->getName());
151 andreas 3977
        }
154 andreas 3978
        else if (redraw && !_toFront)
150 andreas 3979
            pg->drop();
3980
    }
3981
 
14 andreas 3982
    if (!pg->isVisible())
3983
    {
3984
        if (!page)
3985
        {
198 andreas 3986
            page = getPage(mActualPage);
3987
 
3988
            if (!page)
3989
            {
3990
                MSG_ERROR("No active page found! Internal error.");
3991
                return;
3992
            }
14 andreas 3993
        }
3994
 
3995
        if (!haveSubPage(pg->getNumber()) && !page->addSubPage(pg))
3996
            return;
3997
 
3998
        pg->setZOrder(page->getNextZOrder());
3999
 
4000
        if (_setSubPage)
26 andreas 4001
        {
4002
            int left = pg->getLeft();
4003
            int top = pg->getTop();
4004
            int width = pg->getWidth();
4005
            int height = pg->getHeight();
43 andreas 4006
#ifdef _SCALE_SKIA_
26 andreas 4007
            if (mScaleFactor != 1.0)
4008
            {
4009
                left = (int)((double)left * mScaleFactor);
4010
                top = (int)((double)top * mScaleFactor);
4011
                width = (int)((double)width * mScaleFactor);
4012
                height = (int)((double)height * mScaleFactor);
28 andreas 4013
                MSG_DEBUG("Scaled subpage: left=" << left << ", top=" << top << ", width=" << width << ", height=" << height);
26 andreas 4014
            }
43 andreas 4015
#endif
41 andreas 4016
            ANIMATION_t ani;
4017
            ani.showEffect = pg->getShowEffect();
4018
            ani.showTime = pg->getShowTime();
42 andreas 4019
            ani.hideEffect = pg->getHideEffect();
4020
            ani.hideTime = pg->getHideTime();
54 andreas 4021
            // Test for a timer on the page
4022
            if (pg->getTimeout() > 0)
4023
                pg->startTimer();
4024
 
217 andreas 4025
            _setSubPage(pg->getHandle(), page->getHandle(), left, top, width, height, ani);
26 andreas 4026
        }
293 andreas 4027
 
4028
        pg->show();
14 andreas 4029
    }
4030
}
4031
 
198 andreas 4032
void TPageManager::showSubPage(int number, bool force)
4033
{
4034
    DECL_TRACER("TPageManager::showSubPage(int number, bool force)");
4035
 
4036
    if (number <= 0)
4037
        return;
4038
 
4039
    TPage *page = nullptr;
4040
    TSubPage *pg = deliverSubPage(number, &page);
4041
 
4042
    if (!pg)
4043
        return;
4044
 
4045
    if (page)
350 andreas 4046
    {
4047
        pg->setParent(page->getHandle());
198 andreas 4048
        page->addSubPage(pg);
350 andreas 4049
    }
198 andreas 4050
 
4051
    string group = pg->getGroupName();
4052
 
4053
    if (!group.empty())
4054
    {
4055
        TSubPage *sub = getFirstSubPageGroup(group);
4056
 
4057
        while(sub)
4058
        {
4059
            if (sub->isVisible() && sub->getNumber() != pg->getNumber())
4060
                sub->drop();
4061
 
4062
            sub = getNextSubPageGroup(group, sub);
4063
        }
4064
    }
4065
 
4066
    if (pg->isVisible() && !force)
4067
    {
4068
        MSG_DEBUG("Page " << pg->getName() << " is already visible but maybe not on top.");
4069
 
4070
        TSubPage *sub = getFirstSubPage();
4071
        bool redraw = false;
4072
 
4073
        while (sub)
4074
        {
4075
            if (sub->isVisible() && pg->getZOrder() < sub->getZOrder() &&
4076
                overlap(sub->getLeft(), sub->getTop(), sub->getWidth(), sub->getHeight(),
4077
                        pg->getLeft(), pg->getTop(), pg->getWidth(), pg->getHeight()))
4078
            {
4079
                MSG_DEBUG("Page " << sub->getName() << " is overlapping page " << pg->getName());
4080
                redraw = true;
4081
                break;
4082
            }
4083
 
4084
            sub = getNextSubPage();
4085
        }
4086
 
4087
        if (redraw && _toFront)
4088
        {
300 andreas 4089
            _toFront((uint)pg->getHandle());
198 andreas 4090
            pg->setZOrder(page->getNextZOrder());
4091
            page->sortSubpages();
4092
            MSG_DEBUG("Setting new Z-order " << page->getActZOrder() << " on subpage " << pg->getName());
4093
        }
4094
        else if (redraw && !_toFront)
4095
            pg->drop();
4096
    }
4097
 
4098
    if (!pg->isVisible() || force)
4099
    {
4100
        if (!page)
4101
        {
4102
            MSG_ERROR("No active page found! Internal error.");
4103
            return;
4104
        }
4105
 
4106
        if (!haveSubPage(pg->getNumber()) && !page->addSubPage(pg))
4107
            return;
4108
 
4109
        if (!pg->isVisible())
4110
            pg->setZOrder(page->getNextZOrder());
4111
 
4112
        if (_setSubPage)
4113
        {
4114
            int left = pg->getLeft();
4115
            int top = pg->getTop();
4116
            int width = pg->getWidth();
4117
            int height = pg->getHeight();
262 andreas 4118
#ifdef _SCALE_SKIA_
198 andreas 4119
            if (mScaleFactor != 1.0)
4120
            {
4121
                left = (int)((double)left * mScaleFactor);
4122
                top = (int)((double)top * mScaleFactor);
4123
                width = (int)((double)width * mScaleFactor);
4124
                height = (int)((double)height * mScaleFactor);
4125
                MSG_DEBUG("Scaled subpage: left=" << left << ", top=" << top << ", width=" << width << ", height=" << height);
4126
            }
262 andreas 4127
#endif
198 andreas 4128
            ANIMATION_t ani;
4129
            ani.showEffect = pg->getShowEffect();
4130
            ani.showTime = pg->getShowTime();
4131
            ani.hideEffect = pg->getHideEffect();
4132
            ani.hideTime = pg->getHideTime();
4133
            // Test for a timer on the page
4134
            if (pg->getTimeout() > 0)
4135
                pg->startTimer();
4136
 
217 andreas 4137
            _setSubPage(pg->getHandle(), page->getHandle(), left, top, width, height, ani);
198 andreas 4138
        }
4139
    }
4140
 
4141
    pg->show();
4142
}
4143
 
14 andreas 4144
void TPageManager::hideSubPage(const string& name)
4145
{
4146
    DECL_TRACER("TPageManager::hideSubPage(const string& name)");
4147
 
4148
    if (name.empty())
335 andreas 4149
    {
4150
#if TESTMODE == 1
4151
        setScreenDone();
4152
#endif
14 andreas 4153
        return;
335 andreas 4154
    }
14 andreas 4155
 
4156
    TPage *page = getPage(mActualPage);
4157
 
4158
    if (!page)
4159
    {
4160
        MSG_ERROR("No active page found! Internal error.");
335 andreas 4161
#if TESTMODE == 1
4162
        setScreenDone();
4163
#endif
14 andreas 4164
        return;
4165
    }
4166
 
4167
    TSubPage *pg = getSubPage(name);
4168
 
4169
    if (pg)
4170
    {
4171
        pg->drop();
154 andreas 4172
        page->decZOrder();
14 andreas 4173
    }
4174
}
4175
 
299 andreas 4176
/**
4177
 * @brief TPageManager::runClickQueue - Processing mouse clicks
4178
 * The following method is starting a thread which tests a queue containing
4179
 * the mouse clicks. To not drain the CPU, it sleeps for a short time if there
4180
 * are no more events in the queue.
4181
 * If there is an entry in the queue, it copies it to a local struct and
4182
 * deletes it from the queue. It take always the oldest antry (first entry)
4183
 * and removes this entry from the queue until the queue is empty. This makes
4184
 * it to a FIFO (first in, first out).
4185
 * Depending on the state of the variable "coords" the method for mouse
4186
 * coordinate click is executed or the method for a handle.
4187
 * The thread runs as long as the variable "mClickQueueRun" is TRUE and the
4188
 * variable "prg_stopped" is FALSE.
4189
 */
4190
void TPageManager::runClickQueue()
4191
{
4192
    DECL_TRACER("TPageManager::runClickQueue()");
4193
 
4194
    if (mClickQueueRun)
4195
        return;
4196
 
4197
    mClickQueueRun = true;
4198
 
4199
    try
4200
    {
4201
        std::thread thr = std::thread([=] {
300 andreas 4202
            MSG_PROTOCOL("Thread \"TPageManager::runClickQueue()\" was started.");
4203
 
299 andreas 4204
            while (mClickQueueRun && !prg_stopped)
4205
            {
300 andreas 4206
                while (!mClickQueue.empty())
299 andreas 4207
                {
4208
#ifdef QT_DEBUG
300 andreas 4209
                    if (mClickQueue[0].coords)
4210
                        MSG_TRACE("TPageManager::runClickQueue() -- executing: _mouseEvent(" << mClickQueue[0].x << ", " << mClickQueue[0].y << ", " << (mClickQueue[0].pressed ? "TRUE" : "FALSE") << ")")
299 andreas 4211
                    else
300 andreas 4212
                        MSG_TRACE("TPageManager::runClickQueue() -- executing: _mouseEvent(" << handleToString(mClickQueue[0].handle) << ", " << (mClickQueue[0].pressed ? "TRUE" : "FALSE") << ")")
299 andreas 4213
#endif
300 andreas 4214
                    if (mClickQueue[0].coords)
4215
                        _mouseEvent(mClickQueue[0].x, mClickQueue[0].y, mClickQueue[0].pressed);
4216
                    else
4217
                        _mouseEvent(mClickQueue[0].handle, mClickQueue[0].handle);
4218
 
299 andreas 4219
                    mClickQueue.erase(mClickQueue.begin()); // Remove first entry
4220
                }
4221
 
4222
                std::this_thread::sleep_for(std::chrono::microseconds(10));
4223
            }
4224
 
303 andreas 4225
            mClickQueueRun = false;
299 andreas 4226
            return;
4227
        });
4228
 
4229
        thr.detach();
4230
    }
4231
    catch (std::exception& e)
4232
    {
300 andreas 4233
        MSG_ERROR("Error starting a thread to handle the click queue: " << e.what());
299 andreas 4234
        mClickQueueRun = false;
4235
    }
4236
}
4237
 
303 andreas 4238
void TPageManager::runUpdateSubViewItem()
4239
{
4240
    DECL_TRACER("TPageManager::runUpdateSubViewItem()");
299 andreas 4241
 
303 andreas 4242
    if (mUpdateViewsRun)
4243
        return;
4244
 
4245
    mUpdateViewsRun = true;
4246
 
4247
    try
4248
    {
4249
        std::thread thr = std::thread([=] {
4250
            MSG_PROTOCOL("Thread \"TPageManager::runUpdateSubViewItem()\" was started.");
4251
 
4252
            while (mUpdateViewsRun && !prg_stopped)
4253
            {
4254
                while (!mUpdateViews.empty())
4255
                {
4256
                    _updateSubViewItem(mUpdateViews[0]);
4257
                    mUpdateViews.erase(mUpdateViews.begin()); // Remove first entry
4258
                }
4259
 
4260
                std::this_thread::sleep_for(std::chrono::microseconds(10));
4261
            }
4262
 
4263
            mUpdateViewsRun = false;
4264
            return;
4265
        });
4266
 
4267
        thr.detach();
4268
    }
4269
    catch (std::exception& e)
4270
    {
4271
        MSG_ERROR("Error starting a thread to handle the click queue: " << e.what());
4272
        mUpdateViewsRun = false;
4273
    }
4274
}
4275
 
11 andreas 4276
/*
4277
 * Catch the mouse presses and scan all pages and subpages for an element to
4278
 * receive the klick.
4279
 */
10 andreas 4280
void TPageManager::mouseEvent(int x, int y, bool pressed)
4281
{
4282
    DECL_TRACER("TPageManager::mouseEvent(int x, int y, bool pressed)");
4283
 
316 andreas 4284
    TTRYLOCK(click_mutex);
299 andreas 4285
 
4286
    _CLICK_QUEUE_t cq;
4287
    cq.x = x;
4288
    cq.y = y;
4289
    cq.pressed = pressed;
4290
    cq.coords = true;
4291
    mClickQueue.push_back(cq);
334 andreas 4292
#if TESTMODE == 1
4293
    setScreenDone();
4294
#endif
299 andreas 4295
}
4296
 
4297
void TPageManager::_mouseEvent(int x, int y, bool pressed)
4298
{
4299
    DECL_TRACER("TPageManager::_mouseEvent(int x, int y, bool pressed)");
4300
 
16 andreas 4301
    TError::clear();
334 andreas 4302
#if TESTMODE == 1
4303
    if (_gTestMode)
4304
        _gTestMode->setMouseClick(x, y, pressed);
4305
#endif
11 andreas 4306
    int realX = x - mFirstLeftPixel;
4307
    int realY = y - mFirstTopPixel;
263 andreas 4308
 
31 andreas 4309
    MSG_DEBUG("Mouse at " << realX << ", " << realY << ", state " << ((pressed) ? "PRESSED" : "RELEASED") << ", [ " << x << " | " << y << " ]");
43 andreas 4310
#ifdef _SCALE_SKIA_
100 andreas 4311
    if (mScaleFactor != 1.0 && mScaleFactor > 0.0)
26 andreas 4312
    {
4313
        realX = (int)((double)realX / mScaleFactor);
4314
        realY = (int)((double)realY / mScaleFactor);
31 andreas 4315
        MSG_DEBUG("Scaled coordinates: x=" << realX << ", y=" << realY);
26 andreas 4316
    }
43 andreas 4317
#endif
70 andreas 4318
 
154 andreas 4319
    TSubPage *subPage = nullptr;
11 andreas 4320
 
154 andreas 4321
    if (pressed)
4322
        subPage = getCoordMatch(realX, realY);
318 andreas 4323
    else if (mLastPagePush)
154 andreas 4324
        subPage = getSubPage(mLastPagePush);
4325
    else
4326
        subPage = getCoordMatch(realX, realY);
4327
 
11 andreas 4328
    if (!subPage)
14 andreas 4329
    {
146 andreas 4330
        Button::TButton *bt = getCoordMatchPage(realX, realY);
40 andreas 4331
 
4332
        if (bt)
4333
        {
4334
            MSG_DEBUG("Button on page " << bt->getButtonIndex() << ": size: left=" << bt->getLeftPosition() << ", top=" << bt->getTopPosition() << ", width=" << bt->getWidth() << ", height=" << bt->getHeight());
4335
            bt->doClick(x - bt->getLeftPosition(), y - bt->getTopPosition(), pressed);
4336
        }
4337
 
11 andreas 4338
        return;
14 andreas 4339
    }
11 andreas 4340
 
154 andreas 4341
    MSG_DEBUG("Subpage " << subPage->getNumber() << " [" << subPage->getName() << "]: size: left=" << subPage->getLeft() << ", top=" << subPage->getTop() << ", width=" << subPage->getWidth() << ", height=" << subPage->getHeight());
4342
 
4343
    if (pressed)
4344
        mLastPagePush = subPage->getNumber();
4345
    else
4346
        mLastPagePush = 0;
4347
 
11 andreas 4348
    subPage->doClick(realX - subPage->getLeft(), realY - subPage->getTop(), pressed);
10 andreas 4349
}
11 andreas 4350
 
289 andreas 4351
void TPageManager::mouseEvent(ulong handle, bool pressed)
4352
{
4353
    DECL_TRACER("TPageManager::mouseEvent(ulong handle, bool pressed)");
4354
 
320 andreas 4355
    if (!mClickQueue.empty() && mClickQueue.back().handle == handle && mClickQueue.back().pressed == pressed)
4356
        return;
4357
 
299 andreas 4358
    TLOCKER(click_mutex);
293 andreas 4359
 
299 andreas 4360
    _CLICK_QUEUE_t cq;
4361
    cq.handle = handle;
4362
    cq.pressed = pressed;
4363
    mClickQueue.push_back(cq);
4364
    MSG_DEBUG("Queued click for handle " << handleToString(cq.handle) << " state " << (cq.pressed ? "PRESSED" : "RELEASED"));
4365
}
4366
 
4367
void TPageManager::_mouseEvent(ulong handle, bool pressed)
4368
{
4369
    DECL_TRACER("TPageManager::_mouseEvent(ulong handle, bool pressed)");
4370
 
293 andreas 4371
    MSG_DEBUG("Doing click for handle " << handleToString(handle) << " state " << (pressed ? "PRESSED" : "RELEASED"));
4372
 
289 andreas 4373
    if (!handle)
4374
        return;
4375
 
4376
    int pageID = (handle >> 16) & 0x0000ffff;
4377
    int buttonID = (handle & 0x0000ffff);
4378
 
318 andreas 4379
    if (pageID < REGULAR_SUBPAGE_START || buttonID == 0)
289 andreas 4380
        return;
4381
 
4382
    TSubPage *subPage = getSubPage(pageID);
4383
 
4384
    if (subPage)
4385
    {
4386
        Button::TButton *bt = subPage->getButton(buttonID);
4387
 
4388
        if (bt)
4389
        {
318 andreas 4390
            MSG_DEBUG("Button on subpage " << pageID << ": " << buttonID);
289 andreas 4391
            bt->doClick(bt->getLeftPosition() + bt->getWidth() / 2, bt->getTopPosition() + bt->getHeight() / 2, pressed);
4392
        }
4393
    }
4394
}
4395
 
192 andreas 4396
void TPageManager::inputButtonFinished(ulong handle, const std::string &content)
4397
{
4398
    DECL_TRACER("TPageManager::inputButtonFinished(ulong handle, const std::string &content)");
4399
 
4400
    Button::TButton *bt = findButton(handle);
4401
 
4402
    if (!bt)
4403
    {
271 andreas 4404
        MSG_WARNING("Invalid button handle " << handleToString(handle));
192 andreas 4405
        return;
4406
    }
4407
 
4408
    bt->setTextOnly(content, -1);
4409
}
4410
 
309 andreas 4411
void TPageManager::inputCursorPositionChanged(ulong handle, int oldPos, int newPos)
4412
{
4413
    DECL_TRACER("TPageManager::inputCursorPositionChanged(ulong handle, int oldPos, int newPos)");
4414
 
4415
    Button::TButton *bt = findButton(handle);
4416
 
4417
    if (!bt)
4418
    {
4419
        MSG_WARNING("Invalid button handle " << handleToString(handle));
4420
        return;
4421
    }
4422
 
310 andreas 4423
    ulong pageID = (bt->getHandle() >> 16) & 0x0000ffff;
309 andreas 4424
 
4425
    if (pageID < REGULAR_SUBPAGE_START)
4426
    {
368 andreas 4427
        TPage *pg = getPage((int)pageID);
309 andreas 4428
 
4429
        if (!pg)
4430
            return;
4431
 
4432
        pg->setCursorPosition(handle, oldPos, newPos);
4433
    }
4434
    else
4435
    {
368 andreas 4436
        TSubPage *pg = getSubPage((int)pageID);
309 andreas 4437
 
4438
        if (!pg)
4439
            return;
4440
 
4441
        pg->setCursorPosition(handle, oldPos, newPos);
4442
    }
4443
}
4444
 
4445
void TPageManager::inputFocusChanged(ulong handle, bool in)
4446
{
4447
    DECL_TRACER("TPageManager::inputFocusChanged(ulong handle, bool in)");
4448
 
4449
    Button::TButton *bt = findButton(handle);
4450
 
4451
    if (!bt)
4452
    {
4453
        MSG_WARNING("Invalid button handle " << handleToString(handle));
4454
        return;
4455
    }
4456
 
310 andreas 4457
    ulong pageID = (bt->getHandle() >> 16) & 0x0000ffff;
4458
    MSG_DEBUG("Searching for page " << pageID);
309 andreas 4459
 
4460
    if (pageID < REGULAR_SUBPAGE_START)
4461
    {
368 andreas 4462
        TPage *pg = getPage((int)pageID);
309 andreas 4463
 
4464
        if (!pg)
4465
            return;
4466
 
4467
        pg->setInputFocus(handle, in);
4468
    }
4469
    else
4470
    {
368 andreas 4471
        TSubPage *pg = getSubPage((int)pageID);
309 andreas 4472
 
4473
        if (!pg)
4474
            return;
4475
 
4476
        pg->setInputFocus(handle, in);
4477
    }
4478
}
4479
 
208 andreas 4480
void TPageManager::setTextToButton(ulong handle, const string& txt, bool redraw)
51 andreas 4481
{
208 andreas 4482
    DECL_TRACER("TPageManager::setTextToButton(ulong handle, const string& txt, bool redraw)");
51 andreas 4483
 
4484
    // First we search for the button the handle points to
4485
    Button::TButton *button = findButton(handle);
4486
 
4487
    if (!button)
4488
    {
271 andreas 4489
        MSG_ERROR("No button with handle " << handleToString(handle) << " found!");
51 andreas 4490
        return;
4491
    }
4492
 
4493
    // Now we search for all buttons with the same channel and port number
4494
    vector<int> channels;
4495
    channels.push_back(button->getAddressChannel());
193 andreas 4496
    vector<TMap::MAP_T> map = findButtons(button->getAddressPort(), channels);
51 andreas 4497
 
4498
    if (TError::isError() || map.empty())
4499
        return;
4500
 
4501
    // Here we load all buttons found.
4502
    vector<Button::TButton *> buttons = collectButtons(map);
83 andreas 4503
 
4504
    if (buttons.size() > 0)
51 andreas 4505
    {
83 andreas 4506
        vector<Button::TButton *>::iterator mapIter;
4507
        // Finaly we iterate through all found buttons and set the text
118 andreas 4508
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
83 andreas 4509
        {
4510
            Button::TButton *bt = *mapIter;
51 andreas 4511
 
208 andreas 4512
            if (redraw)
4513
                bt->setText(txt, -1);
4514
            else
4515
                bt->setTextOnly(txt, -1);
83 andreas 4516
        }
51 andreas 4517
    }
4518
}
4519
 
193 andreas 4520
vector<Button::TButton *> TPageManager::collectButtons(vector<TMap::MAP_T>& map)
14 andreas 4521
{
193 andreas 4522
    DECL_TRACER("TPageManager::collectButtons(vector<TMap::MAP_T>& map)");
14 andreas 4523
 
4524
    vector<Button::TButton *> buttons;
83 andreas 4525
 
4526
    if (map.size() == 0)
4527
        return buttons;
4528
 
193 andreas 4529
    vector<TMap::MAP_T>::iterator iter;
14 andreas 4530
 
118 andreas 4531
    for (iter = map.begin(); iter != map.end(); ++iter)
14 andreas 4532
    {
209 andreas 4533
        if (iter->pg < REGULAR_SUBPAGE_START || (iter->pg >= SYSTEM_PAGE_START && iter->pg < SYSTEM_SUBPAGE_START))     // Main page?
14 andreas 4534
        {
4535
            TPage *page;
4536
 
4537
            if ((page = getPage(iter->pg)) == nullptr)
4538
            {
4539
                MSG_TRACE("Page " << iter->pg << ", " << iter->pn << " not found in memory. Reading it ...");
4540
 
4541
                if (!readPage(iter->pg))
4542
                    return buttons;
4543
 
4544
                page = getPage(iter->pg);
4545
            }
4546
 
4547
            Button::TButton *bt = page->getButton(iter->bt);
4548
 
4549
            if (bt)
4550
                buttons.push_back(bt);
4551
        }
4552
        else
4553
        {
4554
            TSubPage *subpage;
4555
 
4556
            if ((subpage = getSubPage(iter->pg)) == nullptr)
4557
            {
4558
                MSG_TRACE("Subpage " << iter->pg << ", " << iter->pn << " not found in memory. Reading it ...");
4559
 
4560
                if (!readSubPage(iter->pg))
4561
                    return buttons;
4562
 
4563
                subpage = getSubPage(iter->pg);
4564
                TPage *page = getActualPage();
4565
 
4566
                if (!page)
4567
                {
4568
                    MSG_ERROR("No actual page loaded!");
4569
                    return buttons;
4570
                }
4571
            }
4572
 
4573
            Button::TButton *bt = subpage->getButton(iter->bt);
4574
 
4575
            if (bt)
4576
                buttons.push_back(bt);
4577
        }
4578
    }
4579
 
4580
    return buttons;
4581
}
4582
 
11 andreas 4583
/****************************************************************************
36 andreas 4584
 * Calls from a Java activity. This is only available for Android OS.
4585
 ****************************************************************************/
182 andreas 4586
#ifdef Q_OS_ANDROID
36 andreas 4587
void TPageManager::initNetworkState()
4588
{
4589
    DECL_TRACER("TPageManager::initNetworkState()");
264 andreas 4590
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
36 andreas 4591
    QAndroidJniObject activity = QtAndroid::androidActivity();
4592
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "Init", "(Landroid/app/Activity;)V", activity.object());
4593
    activity.callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "InstallNetworkListener", "()V");
182 andreas 4594
#else
4595
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4596
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "Init", "(Landroid/app/Activity;)V", activity.object());
4597
    activity.callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "InstallNetworkListener", "()V");
4598
#endif
36 andreas 4599
}
4600
 
4601
void TPageManager::stopNetworkState()
4602
{
4603
    DECL_TRACER("TPageManager::stopNetworkState()");
264 andreas 4604
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
36 andreas 4605
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "destroyNetworkListener", "()V");
182 andreas 4606
#else
4607
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/NetworkStatus", "destroyNetworkListener", "()V");
4608
#endif
36 andreas 4609
}
38 andreas 4610
 
4611
void TPageManager::initBatteryState()
4612
{
4613
    DECL_TRACER("TPageManager::initBatteryState()");
264 andreas 4614
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
38 andreas 4615
    QAndroidJniObject activity = QtAndroid::androidActivity();
4616
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "Init", "(Landroid/app/Activity;)V", activity.object());
182 andreas 4617
#else
4618
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4619
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "Init", "(Landroid/app/Activity;)V", activity.object());
4620
#endif
38 andreas 4621
    activity.callStaticMethod<void>("org/qtproject/theosys/BatteryState", "InstallBatteryListener", "()V");
4622
}
4623
 
61 andreas 4624
void TPageManager::initPhoneState()
4625
{
4626
    DECL_TRACER("TPageManager::initPhoneState()");
264 andreas 4627
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
61 andreas 4628
    QAndroidJniObject activity = QtAndroid::androidActivity();
4629
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/PhoneCallState", "Init", "(Landroid/app/Activity;)V", activity.object());
182 andreas 4630
#else
4631
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4632
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/PhoneCallState", "Init", "(Landroid/app/Activity;)V", activity.object());
4633
#endif
61 andreas 4634
    activity.callStaticMethod<void>("org/qtproject/theosys/PhoneCallState", "InstallPhoneListener", "()V");
4635
}
4636
 
38 andreas 4637
void TPageManager::stopBatteryState()
4638
{
4639
    DECL_TRACER("TPageManager::stopBatteryState()");
264 andreas 4640
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
38 andreas 4641
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "destroyBatteryListener", "()V");
182 andreas 4642
#else
4643
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/BatteryState", "destroyBatteryListener", "()V");
4644
#endif
38 andreas 4645
}
4646
 
36 andreas 4647
void TPageManager::informTPanelNetwork(jboolean conn, jint level, jint type)
4648
{
250 andreas 4649
    DECL_TRACER("TPageManager::informTPanelNetwork(jboolean conn, jint level, jint type)");
36 andreas 4650
 
4651
    int l = 0;
4652
    string sType;
4653
 
4654
    switch (type)
4655
    {
4656
        case 1: sType = "Wifi"; break;
4657
        case 2: sType = "Mobile"; break;
4658
 
4659
        default:
4660
            sType = "Unknown"; break;
4661
    }
4662
 
4663
    if (conn)
4664
        l = level;
4665
 
93 andreas 4666
    if (mNetState && mNetState != type)     // Has the connection type changed?
4667
    {
4668
        if (gAmxNet)
4669
            gAmxNet->reconnect();
4670
    }
4671
 
4672
    mNetState = type;
4673
 
36 andreas 4674
    MSG_INFO("Connection status: " << (conn ? "Connected" : "Disconnected") << ", level: " << level << ", type: " << sType);
4675
 
83 andreas 4676
    if (mNetCalls.size() > 0)
36 andreas 4677
    {
83 andreas 4678
        std::map<int, std::function<void (int level)> >::iterator iter;
4679
 
4680
        for (iter = mNetCalls.begin(); iter != mNetCalls.end(); ++iter)
4681
            iter->second(l);
36 andreas 4682
    }
4683
}
38 andreas 4684
 
4685
void TPageManager::informBatteryStatus(jint level, jboolean charging, jint chargeType)
4686
{
4687
    DECL_TRACER("TPageManager::informBatteryStatus(jint level, jboolean charging, jint chargeType)");
4688
 
59 andreas 4689
    MSG_INFO("Battery status: level: " << level << ", " << (charging ? "Charging" : "not charging") << ", type: " << chargeType << ", Elements: " << mBatteryCalls.size());
38 andreas 4690
 
83 andreas 4691
    if (mBatteryCalls.size() > 0)
38 andreas 4692
    {
83 andreas 4693
        std::map<int, std::function<void (int, bool, int)> >::iterator iter;
4694
 
4695
        for (iter = mBatteryCalls.begin(); iter != mBatteryCalls.end(); ++iter)
4696
            iter->second(level, charging, chargeType);
38 andreas 4697
    }
4698
}
61 andreas 4699
 
4700
void TPageManager::informPhoneState(bool call, const string &pnumber)
4701
{
4702
    DECL_TRACER("TPageManager::informPhoneState(bool call, const string &pnumber)");
4703
 
4704
    MSG_INFO("Call state: " << (call ? "Call in progress" : "No call") << ", phone number: " << pnumber);
4705
 
4706
    if (!gAmxNet)
4707
    {
4708
        MSG_WARNING("The network manager for the AMX controller is not initialized!");
4709
        return;
4710
    }
4711
}
130 andreas 4712
 
4713
void TPageManager::initOrientation()
4714
{
4715
    DECL_TRACER("TPageManager::initOrientation()");
4716
 
131 andreas 4717
    int rotate = getSettings()->getRotate();
264 andreas 4718
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
130 andreas 4719
    QAndroidJniObject activity = QtAndroid::androidActivity();
131 andreas 4720
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Orientation", "Init", "(Landroid/app/Activity;I)V", activity.object(), rotate);
182 andreas 4721
#else
4722
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4723
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Orientation", "Init", "(Landroid/app/Activity;I)V", activity.object(), rotate);
4724
#endif
130 andreas 4725
    activity.callStaticMethod<void>("org/qtproject/theosys/Orientation", "InstallOrientationListener", "()V");
4726
}
255 andreas 4727
 
4728
void TPageManager::enterSetup()
4729
{
260 andreas 4730
    DECL_TRACER("TPageManager::enterSetup()");
264 andreas 4731
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
255 andreas 4732
    QAndroidJniObject activity = QtAndroid::androidActivity();
4733
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "callSettings", "(Landroid/app/Activity;)V", activity.object());
4734
#else
4735
    QJniObject activity = QNativeInterface::QAndroidApplication::context();
4736
    QJniObject::callStaticMethod<void>("org/qtproject/theosys/Settings", "callSettings", "(Landroid/app/Activity;)V", activity.object());
4737
#endif
4738
}
59 andreas 4739
#endif  // __ANDROID__
247 andreas 4740
#ifdef Q_OS_IOS
4741
void TPageManager::informBatteryStatus(int level, int state)
4742
{
4743
    DECL_TRACER("TPageManager::informBatteryStatus(int level, int state)");
36 andreas 4744
 
247 andreas 4745
    MSG_INFO("Battery status: level: " << level << ", " << state);
4746
 
4747
    if (mBatteryCalls.size() > 0)
4748
    {
4749
        std::map<int, std::function<void (int, int)> >::iterator iter;
4750
 
4751
        for (iter = mBatteryCalls.begin(); iter != mBatteryCalls.end(); ++iter)
4752
            iter->second(level, state);
4753
    }
4754
}
250 andreas 4755
 
4756
void TPageManager::informTPanelNetwork(bool conn, int level, int type)
4757
{
4758
    DECL_TRACER("TPageManager::informTPanelNetwork(bool conn, int level, int type)");
4759
 
4760
    int l = 0;
4761
    string sType;
4762
 
4763
    switch (type)
4764
    {
4765
        case 1: sType = "Ethernet"; break;
4766
        case 2: sType = "Mobile"; break;
4767
        case 3: sType = "WiFi"; break;
4768
        case 4: sType = "Bluetooth"; break;
4769
 
4770
        default:
4771
            sType = "Unknown"; break;
4772
    }
4773
 
4774
    if (conn)
4775
        l = level;
4776
 
4777
    if (mNetState && mNetState != type)     // Has the connection type changed?
4778
    {
4779
        if (gAmxNet)
4780
            gAmxNet->reconnect();
4781
    }
4782
 
4783
    mNetState = type;
4784
 
4785
    MSG_INFO("Connection status: " << (conn ? "Connected" : "Disconnected") << ", level: " << level << ", type: " << sType);
4786
 
4787
    if (mNetCalls.size() > 0)
4788
    {
4789
        std::map<int, std::function<void (int level)> >::iterator iter;
4790
 
4791
        for (iter = mNetCalls.begin(); iter != mNetCalls.end(); ++iter)
4792
            iter->second(l);
4793
    }
4794
}
4795
 
247 andreas 4796
#endif
4797
 
60 andreas 4798
void TPageManager::setButtonCallbacks(Button::TButton *bt)
4799
{
227 andreas 4800
    DECL_TRACER("TPageManager::setButtonCallbacks(Button::TButton *bt)");
4801
 
162 andreas 4802
    if (!bt)
4803
        return;
4804
 
60 andreas 4805
    bt->registerCallback(_displayButton);
4806
    bt->regCallPlayVideo(_callPlayVideo);
4807
    bt->setFonts(mFonts);
4808
    bt->setPalette(mPalette);
4809
}
4810
 
4811
void TPageManager::externalButton(extButtons_t bt, bool checked)
4812
{
4813
    DECL_TRACER("TPageManager::externalButton(extButtons_t bt)");
4814
 
4815
    if (!mExternal)
4816
        return;
4817
 
4818
    EXTBUTTON_t button = mExternal->getButton(bt);
4819
 
4820
    if (button.type == EXT_NOBUTTON)
4821
        return;
4822
 
4823
    if (button.cp && button.ch)
4824
    {
4825
        amx::ANET_SEND scmd;
4826
 
4827
        scmd.device = TConfig::getChannel();
4828
        scmd.port = button.cp;
4829
        scmd.channel = button.ch;
4830
 
4831
        if (checked)
4832
            scmd.MC = 0x0084;   // push button
134 andreas 4833
        else
4834
            scmd.MC = 0x0085;   // release button
60 andreas 4835
 
134 andreas 4836
        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 4837
 
134 andreas 4838
        if (gAmxNet)
4839
            gAmxNet->sendCommand(scmd);
4840
        else
4841
        {
4842
            MSG_WARNING("Missing global class TAmxNet. Can't send a message!");
4843
        }
60 andreas 4844
    }
4845
}
4846
 
62 andreas 4847
void TPageManager::sendKeyboard(const std::string& text)
4848
{
4849
    DECL_TRACER("TPageManager::sendKeyboard(const std::string& text)");
4850
 
4851
    amx::ANET_SEND scmd;
4852
    scmd.port = 1;
4853
    scmd.channel = 0;
4854
    scmd.msg = UTF8ToCp1250(text);
4855
    scmd.MC = 0x008b;
4856
 
4857
    if (gAmxNet)
4858
        gAmxNet->sendCommand(scmd);
4859
    else
4860
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4861
}
4862
 
4863
void TPageManager::sendKeypad(const std::string& text)
4864
{
4865
    DECL_TRACER("TPageManager::sendKeypad(const std::string& text)");
4866
 
269 andreas 4867
    sendKeyboard(text);
62 andreas 4868
}
4869
 
4870
void TPageManager::sendString(uint handle, const std::string& text)
4871
{
4872
    DECL_TRACER("TPageManager::sendString(uint handle, const std::string& text)");
4873
 
4874
    Button::TButton *bt = findButton(handle);
4875
 
4876
    if (!bt)
4877
    {
271 andreas 4878
        MSG_WARNING("Button " << handleToString(handle) << " not found!");
62 andreas 4879
        return;
4880
    }
4881
 
4882
    amx::ANET_SEND scmd;
4883
    scmd.port = bt->getAddressPort();
4884
    scmd.channel = bt->getAddressChannel();
4885
    scmd.msg = UTF8ToCp1250(text);
4886
    scmd.MC = 0x008b;
4887
 
4888
    if (gAmxNet)
4889
        gAmxNet->sendCommand(scmd);
4890
    else
4891
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4892
}
4893
 
134 andreas 4894
void TPageManager::sendGlobalString(const string& text)
4895
{
4896
    DECL_TRACER("TPageManager::sendGlobalString(const string& text)");
4897
 
4898
    if (text.empty() || text.find("-") == string::npos)
4899
        return;
4900
 
4901
    amx::ANET_SEND scmd;
4902
    scmd.port = 1;
4903
    scmd.channel = 0;
4904
    scmd.msg = text;
4905
    scmd.MC = 0x008b;
4906
 
4907
    if (gAmxNet)
4908
        gAmxNet->sendCommand(scmd);
4909
    else
4910
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4911
}
4912
 
147 andreas 4913
void TPageManager::sendCommandString(int port, const string& cmd)
4914
{
4915
    DECL_TRACER("TPageManager::sendGlobalString(const string& text)");
4916
 
4917
    if (cmd.empty())
4918
        return;
4919
 
4920
    amx::ANET_SEND scmd;
4921
    scmd.port = port;
4922
    scmd.channel = 0;
4923
    scmd.msg = cmd;
4924
    scmd.MC = 0x008c;
4925
 
4926
    if (gAmxNet)
4927
        gAmxNet->sendCommand(scmd);
4928
    else
4929
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4930
}
4931
 
123 andreas 4932
void TPageManager::sendPHNcommand(const std::string& cmd)
4933
{
4934
    DECL_TRACER("TPageManager::sendPHNcommand(const std::string& cmd)");
4935
 
4936
    amx::ANET_SEND scmd;
144 andreas 4937
    scmd.port = mTSettings->getSettings().voipCommandPort;
123 andreas 4938
    scmd.channel = TConfig::getChannel();
4939
    scmd.msg = "^PHN-" + cmd;
127 andreas 4940
    scmd.MC = 0x008c;
4941
    MSG_DEBUG("Sending PHN command: ^PHN-" << cmd);
123 andreas 4942
 
4943
    if (gAmxNet)
4944
        gAmxNet->sendCommand(scmd);
4945
    else
4946
        MSG_WARNING("Missing global class TAmxNet. Can't send ^PHN command!");
4947
}
4948
 
111 andreas 4949
void TPageManager::sendKeyStroke(char key)
4950
{
4951
    DECL_TRACER("TPageManager::sendKeyStroke(char key)");
4952
 
4953
    if (!key)
4954
        return;
4955
 
4956
    char msg[2];
4957
    msg[0] = key;
4958
    msg[1] = 0;
4959
 
4960
    amx::ANET_SEND scmd;
4961
    scmd.port = 1;
4962
    scmd.channel = 0;
4963
    scmd.msg.assign(msg);
127 andreas 4964
    scmd.MC = 0x008c;
111 andreas 4965
 
4966
    if (gAmxNet)
4967
        gAmxNet->sendCommand(scmd);
4968
    else
4969
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
4970
}
4971
 
110 andreas 4972
/**
4973
 * Sending a custom event is identical in all cases. Because of this I
4974
 * implemented this method to send a custom event. This is called in all cases
4975
 * where a ?XXX command is received.
4976
 *
4977
 * @param value1    The instance of the button.
4978
 * @param value2    The value of a numeric request or the length of the string.
4979
 * @param value3    Always 0
4980
 * @param msg       In case of a string this contains the string.
4981
 * @param evType    This is the event type, a number between 1001 and 1099.
4982
 * @param cp        Channel port of button.
4983
 * @param cn        Channel number. of button.
4984
 *
4985
 * @return If all parameters are valid it returns TRUE.
4986
 */
4987
bool TPageManager::sendCustomEvent(int value1, int value2, int value3, const string& msg, int evType, int cp, int cn)
4988
{
4989
    DECL_TRACER("TPageManager::sendCustomEvent(int value1, int value2, int value3, const string& msg, int evType)");
4990
 
4991
    if (value1 < 1)
4992
        return false;
4993
 
4994
    amx::ANET_SEND scmd;
4995
    scmd.port = cp;
4996
    scmd.channel = cn;
4997
    scmd.ID = scmd.channel;
4998
    scmd.flag = 0;
4999
    scmd.type = evType;
5000
    scmd.value1 = value1;   // instance
5001
    scmd.value2 = value2;
5002
    scmd.value3 = value3;
5003
    scmd.msg = msg;
5004
 
5005
    if (!msg.empty())
5006
        scmd.dtype = 0x0001;// Char array
5007
 
5008
    scmd.MC = 0x008d;       // custom event
5009
 
5010
    if (gAmxNet)
5011
        gAmxNet->sendCommand(scmd);
5012
    else
5013
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
5014
 
5015
    return true;
5016
}
129 andreas 5017
#ifndef _NOSIP_
127 andreas 5018
string TPageManager::sipStateToString(TSIPClient::SIP_STATE_t s)
5019
{
5020
    DECL_TRACER("TPageManager::sipStateToString(TSIPClient::SIP_STATE_t s)");
5021
 
5022
    switch(s)
5023
    {
5024
        case TSIPClient::SIP_CONNECTED:     return "CONNECTED";
5025
        case TSIPClient::SIP_DISCONNECTED:  return "DISCONNECTED";
5026
        case TSIPClient::SIP_HOLD:          return "HOLD";
5027
        case TSIPClient::SIP_RINGING:       return "RINGING";
5028
        case TSIPClient::SIP_TRYING:        return "TRYING";
5029
 
5030
        default:
5031
            return "IDLE";
5032
    }
5033
 
5034
    return "IDLE";
5035
}
129 andreas 5036
#endif
134 andreas 5037
void TPageManager::sendOrientation()
5038
{
5039
    string ori;
5040
 
5041
    switch(mOrientation)
5042
    {
5043
        case O_PORTRAIT:            ori = "DeviceOrientationPortrait"; break;
5044
        case O_REVERSE_PORTRAIT:    ori = "DeviceOrientationPortraitUpsideDown"; break;
5045
        case O_LANDSCAPE:           ori = "DeviceOrientationLandscapeLeft"; break;
5046
        case O_REVERSE_LANDSCAPE:   ori = "DeviceOrientationLandscapeRight"; break;
5047
        case O_FACE_UP:             ori = "DeviceOrientationFaceUp"; break;
5048
        case O_FACE_DOWN:           ori = "DeviceOrientationFaceDown"; break;
5049
        default:
5050
            return;
5051
    }
5052
 
5053
    sendGlobalString("TPCACC-" + ori);
5054
}
5055
 
401 andreas 5056
void TPageManager::callSetPassword(ulong handle, const string& pw, int x, int y)
396 andreas 5057
{
401 andreas 5058
    DECL_TRACER("TPageManager::callSetPassword(ulong handle, const string& pw, int x, int y)");
396 andreas 5059
 
5060
    Button::TButton *bt = findButton(handle);
5061
 
5062
    if (!bt)
5063
    {
5064
        MSG_WARNING("callSetPassword: Button " << handleToString(handle) << " not found!");
5065
        return;
5066
    }
5067
 
5068
    string pass = pw;
5069
 
5070
    if (pass.empty())
5071
        pass = "\x01";
5072
 
5073
    bt->setPassword(pass);
401 andreas 5074
    bt->doClick(x, y, true);
5075
    bt->doClick(x, y, false);
396 andreas 5076
}
5077
 
153 andreas 5078
void TPageManager::onSwipeEvent(TPageManager::SWIPES sw)
5079
{
5080
    DECL_TRACER("TPageManager::onSwipeEvent(TPageManager::SWIPES sw)");
5081
 
5082
    // Swipes are defined in "external".
5083
    if (!mExternal)
5084
        return;
5085
 
5086
    extButtons_t eBt;
5087
    string dbg;
5088
 
5089
    switch(sw)
5090
    {
5091
        case SW_LEFT:   eBt = EXT_GESTURE_LEFT; dbg.assign("LEFT"); break;
5092
        case SW_RIGHT:  eBt = EXT_GESTURE_RIGHT; dbg.assign("RIGHT"); break;
5093
        case SW_UP:     eBt = EXT_GESTURE_UP; dbg.assign("UP"); break;
5094
        case SW_DOWN:   eBt = EXT_GESTURE_DOWN; dbg.assign("DOWN"); break;
5095
 
5096
        default:
5097
            return;
5098
    }
5099
 
5100
    int pgNum = getActualPageNumber();
5101
    EXTBUTTON_t bt = mExternal->getButton(pgNum, eBt);
5102
 
5103
    if (bt.bi == 0)
5104
        return;
5105
 
5106
    MSG_DEBUG("Received swipe " << dbg << " event for page " << pgNum << " on button " << bt.bi << " \"" << bt.na << "\"");
5107
 
5108
    if (!bt.cm.empty() && bt.co == 0)           // Feed command to ourself?
5109
    {                                           // Yes, then feed it into command queue.
5110
        MSG_DEBUG("Button has a self feed command");
5111
 
5112
        int channel = TConfig::getChannel();
5113
        int system = TConfig::getSystem();
5114
 
5115
        amx::ANET_COMMAND cmd;
5116
        cmd.MC = 0x000c;
5117
        cmd.device1 = channel;
5118
        cmd.port1 = bt.ap;
5119
        cmd.system = system;
5120
        cmd.data.message_string.device = channel;
5121
        cmd.data.message_string.port = bt.ap;  // Must be the address port of button
5122
        cmd.data.message_string.system = system;
5123
        cmd.data.message_string.type = 1;   // 8 bit char string
5124
 
5125
        vector<string>::iterator iter;
5126
 
5127
        for (iter = bt.cm.begin(); iter != bt.cm.end(); ++iter)
5128
        {
5129
            cmd.data.message_string.length = iter->length();
5130
            memset(&cmd.data.message_string.content, 0, sizeof(cmd.data.message_string.content));
5131
            strncpy((char *)&cmd.data.message_string.content, iter->c_str(), sizeof(cmd.data.message_string.content));
5132
            doCommand(cmd);
5133
        }
5134
    }
5135
    else if (!bt.cm.empty())
5136
    {
5137
        MSG_DEBUG("Button sends a command on port " << bt.co);
5138
 
5139
        vector<string>::iterator iter;
5140
 
5141
        for (iter = bt.cm.begin(); iter != bt.cm.end(); ++iter)
5142
            sendCommandString(bt.co, *iter);
5143
    }
5144
}
5145
 
36 andreas 5146
/****************************************************************************
11 andreas 5147
 * The following functions implements one of the commands the panel accepts.
5148
 ****************************************************************************/
43 andreas 5149
 
5150
/**
5151
 * This is a special function handling the progress bars when the files of the
5152
 * panel are updated. Instead of simply displaying a ready page, it fakes one
5153
 * with the actual dimensions of the main page. This is possible, because we've
5154
 * always a main page even if the panel is started for the first time.
5155
 */
5156
void TPageManager::doFTR(int port, vector<int>& channels, vector<string>& pars)
23 andreas 5157
{
43 andreas 5158
    DECL_TRACER("TPageManager::doFTR(int, vector<int>&, vector<string>& pars)");
14 andreas 5159
 
23 andreas 5160
    if (pars.empty())
5161
    {
5162
        MSG_WARNING("Command #FTR needs at least 1 parameter! Ignoring command.");
5163
        return;
5164
    }
5165
 
96 andreas 5166
    if (TStreamError::checkFilter(HLOG_DEBUG))
23 andreas 5167
    {
96 andreas 5168
        for (size_t i = 0; i < pars.size(); i++)
5169
        {
5170
            MSG_DEBUG("[" << i << "]: " << pars.at(i));
5171
        }
23 andreas 5172
    }
43 andreas 5173
 
5174
    if (pars.at(0).compare("START") == 0)
5175
    {
5176
        // Here we have to drop all pages and subpages first and then display
5177
        // the faked page with the progress bars.
5178
        MSG_DEBUG("Starting file transfer ...");
5179
        doPPX(port, channels, pars);
5180
        TPage *pg = getPage("_progress");
5181
 
5182
        if (!pg)
5183
        {
5184
            if (!readPage("_progress"))
5185
            {
5186
                MSG_ERROR("Error creating the system page _progress!");
5187
                return;
5188
            }
5189
 
5190
            pg = getPage("_progress");
5191
 
5192
            if (!pg)
5193
            {
5194
                MSG_ERROR("Error getting system page _progress!");
5195
                return;
5196
            }
5197
        }
5198
 
5199
        pg->setFonts(mFonts);
5200
        pg->registerCallback(_setBackground);
5201
        pg->regCallPlayVideo(_callPlayVideo);
5202
 
5203
        if (!pg || !_setPage || !mTSettings)
5204
            return;
5205
 
5206
        int width, height;
217 andreas 5207
        width = mTSettings->getWidth();
43 andreas 5208
        height = mTSettings->getHeight();
5209
#ifdef _SCALE_SKIA_
5210
        if (mScaleFactor != 1.0)
5211
        {
5212
            width = (int)((double)width * mScaleFactor);
5213
            height = (int)((double)height * mScaleFactor);
5214
        }
5215
#endif
5216
        _setPage((pg->getNumber() << 16) & 0xffff0000, width, height);
5217
        pg->show();
5218
        MSG_DEBUG("Page _progress on screen");
5219
    }
5220
    else if (pars.at(0).compare("SYNC") == 0)
5221
    {
5222
        TPage *pg = getPage("_progress");
5223
 
5224
        if (!pg)
5225
        {
5226
            MSG_ERROR("Page _progress not found!");
5227
            return;
5228
        }
5229
 
5230
        Button::TButton *bt = pg->getButton(1);   // Line 1
5231
 
5232
        if (!bt)
5233
        {
5234
            MSG_ERROR("Button 160 of page _progress not found!");
5235
            return;
5236
        }
5237
 
5238
        bt->setText(pars.at(2), 0);
5239
        bt->show();
5240
    }
5241
    else if (pars.at(0).compare("FTRSTART") == 0)
5242
    {
5243
        TPage *pg = getPage("_progress");
5244
 
5245
        if (!pg)
5246
        {
5247
            MSG_ERROR("Page _progress not found!");
5248
            return;
5249
        }
5250
 
5251
        Button::TButton *bt1 = pg->getButton(1);   // Line 1
5252
        Button::TButton *bt2 = pg->getButton(2);   // Line 2
5253
        Button::TButton *bt3 = pg->getButton(3);   // Bargraph 1
5254
        Button::TButton *bt4 = pg->getButton(4);   // Bargraph 2
5255
 
5256
        if (!bt1 || !bt2 || !bt3 || !bt4)
5257
        {
5258
            MSG_ERROR("Buttons of page _progress not found!");
5259
            return;
5260
        }
5261
 
5262
        bt1->setText("Transfering files ...", 0);
5263
        bt1->show();
5264
        bt2->setText(pars.at(3), 0);
5265
        bt2->show();
5266
        bt3->drawBargraph(0, atoi(pars.at(1).c_str()), true);
5267
        bt4->drawBargraph(0, atoi(pars.at(2).c_str()), true);
5268
    }
5269
    else if (pars.at(0).compare("FTRPART") == 0)
5270
    {
5271
        TPage *pg = getPage("_progress");
5272
 
5273
        if (!pg)
5274
        {
5275
            MSG_ERROR("Page _progress not found!");
5276
            return;
5277
        }
5278
 
5279
        Button::TButton *bt = pg->getButton(4);   // Bargraph 2
5280
 
5281
        if (!bt)
5282
        {
5283
            MSG_ERROR("Buttons of page _progress not found!");
5284
            return;
5285
        }
5286
 
5287
        bt->drawBargraph(0, atoi(pars.at(2).c_str()), true);
5288
    }
5289
    else if (pars.at(0).compare("END") == 0)
5290
    {
5291
        MSG_TRACE("End of file transfer reached.");
44 andreas 5292
 
155 andreas 5293
        // To make sure the new surface will not be deleted and replaced by the
5294
        // default build in surface, we must delete the "virgin" marker first.
5295
        // This is a file called <project path>/.system.
5296
        string virgin = TConfig::getProjectPath() + "/.system";
5297
        remove(virgin.c_str());     // Because this file may not exist we don't care about the result code.
5298
 
44 andreas 5299
        if (_resetSurface)
5300
            _resetSurface();
5301
        else
5302
        {
5303
            MSG_WARNING("Missing callback function \"resetSurface\"!");
5304
        }
43 andreas 5305
    }
23 andreas 5306
}
5307
 
318 andreas 5308
void TPageManager::doLEVON(int, vector<int>&, vector<string>&)
5309
{
5310
    DECL_TRACER("TPageManager::doLEVON(int, vector<int>&, vector<string>&)");
5311
 
5312
    mLevelSend = true;
343 andreas 5313
#if TESTMODE == 1
5314
    __success = true;
5315
    setAllDone();
5316
#endif
318 andreas 5317
}
5318
 
5319
void TPageManager::doLEVOF(int, vector<int>&, vector<string>&)
5320
{
5321
    DECL_TRACER("TPageManager::doLEVOF(int, vector<int>&, vector<string>&)");
5322
 
5323
    mLevelSend = false;
343 andreas 5324
#if TESTMODE == 1
5325
    __success = true;
5326
    setAllDone();
5327
#endif
318 andreas 5328
}
5329
 
5330
void TPageManager::doRXON(int, vector<int>&, vector<string>&)
5331
{
5332
    DECL_TRACER("TPageManager::doRXON(int, vector<int>&, vector<string>&)");
5333
 
5334
    mRxOn = true;
343 andreas 5335
#if TESTMODE == 1
5336
    __success = true;
5337
    setAllDone();
5338
#endif
318 andreas 5339
}
5340
 
5341
void TPageManager::doRXOF(int, vector<int>&, vector<string>&)
5342
{
5343
    DECL_TRACER("TPageManager::doRXOF(int, vector<int>&, vector<string>&)");
5344
 
5345
    mRxOn = false;
343 andreas 5346
#if TESTMODE == 1
5347
    __success = true;
5348
    setAllDone();
5349
#endif
318 andreas 5350
}
5351
 
22 andreas 5352
void TPageManager::doON(int port, vector<int>&, vector<string>& pars)
14 andreas 5353
{
5354
    DECL_TRACER("TPageManager::doON(int port, vector<int>& channels, vector<string>& pars)");
5355
 
5356
    if (pars.empty())
5357
    {
5358
        MSG_WARNING("Command ON needs 1 parameter! Ignoring command.");
343 andreas 5359
#if TESTMODE == 1
5360
        setAllDone();
5361
#endif
14 andreas 5362
        return;
5363
    }
5364
 
16 andreas 5365
    TError::clear();
14 andreas 5366
    int c = atoi(pars[0].c_str());
5367
 
5368
    if (c <= 0)
5369
    {
5370
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
343 andreas 5371
#if TESTMODE == 1
5372
        setAllDone();
5373
#endif
14 andreas 5374
        return;
5375
    }
5376
 
5377
    vector<int> chans = { c };
193 andreas 5378
    vector<TMap::MAP_T> map = findButtons(port, chans, TMap::TYPE_CM);
14 andreas 5379
 
5380
    if (TError::isError() || map.empty())
343 andreas 5381
    {
5382
#if TESTMODE == 1
5383
        setAllDone();
5384
#endif
14 andreas 5385
        return;
343 andreas 5386
    }
14 andreas 5387
 
5388
    vector<Button::TButton *> buttons = collectButtons(map);
5389
 
83 andreas 5390
    if (buttons.size() > 0)
14 andreas 5391
    {
83 andreas 5392
        vector<Button::TButton *>::iterator mapIter;
14 andreas 5393
 
118 andreas 5394
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
83 andreas 5395
        {
5396
            Button::TButton *bt = *mapIter;
5397
 
195 andreas 5398
            if (bt->getButtonType() == GENERAL)
343 andreas 5399
            {
83 andreas 5400
                bt->setActive(1);
343 andreas 5401
#if TESTMODE == 1
5402
                if (_gTestMode)
5403
                    _gTestMode->setResult(intToString(bt->getActiveInstance() + 1));
5404
#endif
5405
            }
83 andreas 5406
        }
14 andreas 5407
    }
343 andreas 5408
#if TESTMODE == 1
5409
    setDone();
5410
#endif
14 andreas 5411
}
5412
 
22 andreas 5413
void TPageManager::doOFF(int port, vector<int>&, vector<string>& pars)
14 andreas 5414
{
5415
    DECL_TRACER("TPageManager::doOFF(int port, vector<int>& channels, vector<string>& pars)");
5416
 
5417
    if (pars.empty())
5418
    {
5419
        MSG_WARNING("Command OFF needs 1 parameter! Ignoring command.");
343 andreas 5420
#if TESTMODE == 1
5421
        setAllDone();
5422
#endif
14 andreas 5423
        return;
5424
    }
5425
 
16 andreas 5426
    TError::clear();
14 andreas 5427
    int c = atoi(pars[0].c_str());
5428
 
5429
    if (c <= 0)
5430
    {
5431
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
343 andreas 5432
#if TESTMODE == 1
5433
        setAllDone();
5434
#endif
14 andreas 5435
        return;
5436
    }
5437
 
5438
    vector<int> chans = { c };
193 andreas 5439
    vector<TMap::MAP_T> map = findButtons(port, chans, TMap::TYPE_CM);
14 andreas 5440
 
5441
    if (TError::isError() || map.empty())
5442
        return;
5443
 
5444
    vector<Button::TButton *> buttons = collectButtons(map);
5445
 
83 andreas 5446
    if (buttons.size() > 0)
14 andreas 5447
    {
83 andreas 5448
        vector<Button::TButton *>::iterator mapIter;
14 andreas 5449
 
118 andreas 5450
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
83 andreas 5451
        {
5452
            Button::TButton *bt = *mapIter;
5453
 
195 andreas 5454
            if (bt->getButtonType() == GENERAL)
83 andreas 5455
                bt->setActive(0);
343 andreas 5456
#if TESTMODE == 1
5457
                if (_gTestMode)
5458
                    _gTestMode->setResult(intToString(bt->getActiveInstance() + 1));
5459
#endif
83 andreas 5460
        }
14 andreas 5461
    }
343 andreas 5462
#if TESTMODE == 1
5463
    setDone();
5464
#endif
14 andreas 5465
}
5466
 
22 andreas 5467
void TPageManager::doLEVEL(int port, vector<int>&, vector<string>& pars)
15 andreas 5468
{
5469
    DECL_TRACER("TPageManager::doLEVEL(int port, vector<int>& channels, vector<string>& pars)");
5470
 
5471
    if (pars.size() < 2)
5472
    {
5473
        MSG_WARNING("Command LEVEL needs 2 parameters! Ignoring command.");
343 andreas 5474
#if TESTMODE == 1
5475
        setAllDone();
5476
#endif
15 andreas 5477
        return;
5478
    }
5479
 
16 andreas 5480
    TError::clear();
15 andreas 5481
    int c = atoi(pars[0].c_str());
5482
    int level = atoi(pars[1].c_str());
5483
 
5484
    if (c <= 0)
5485
    {
5486
        MSG_WARNING("Invalid channel " << c << "! Ignoring command.");
343 andreas 5487
#if TESTMODE == 1
5488
        setAllDone();
5489
#endif
15 andreas 5490
        return;
5491
    }
5492
 
5493
    vector<int> chans = { c };
193 andreas 5494
    vector<TMap::MAP_T> map = findBargraphs(port, chans);
15 andreas 5495
 
5496
    if (TError::isError() || map.empty())
5497
    {
5498
        MSG_WARNING("No bargraphs found!");
343 andreas 5499
#if TESTMODE == 1
5500
        setAllDone();
5501
#endif
15 andreas 5502
        return;
5503
    }
5504
 
5505
    vector<Button::TButton *> buttons = collectButtons(map);
5506
 
83 andreas 5507
    if (buttons.size() > 0)
15 andreas 5508
    {
83 andreas 5509
        vector<Button::TButton *>::iterator mapIter;
15 andreas 5510
 
118 andreas 5511
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
15 andreas 5512
        {
83 andreas 5513
            Button::TButton *bt = *mapIter;
5514
 
195 andreas 5515
            if (bt->getButtonType() == BARGRAPH)
343 andreas 5516
            {
83 andreas 5517
                bt->drawBargraph(bt->getActiveInstance(), level);
343 andreas 5518
#if TESTMODE == 1
5519
                if (_gTestMode)
5520
                    _gTestMode->setResult(intToString(bt->getLevelValue()));
5521
#endif
5522
            }
195 andreas 5523
            else if (bt->getButtonType() == MULTISTATE_BARGRAPH)
83 andreas 5524
            {
5525
                int state = (int)((double)bt->getStateCount() / (double)(bt->getRangeHigh() - bt->getRangeLow()) * (double)level);
5526
                bt->setActive(state);
343 andreas 5527
#if TESTMODE == 1
5528
                if (_gTestMode)
5529
                    _gTestMode->setResult(intToString(bt->getActiveInstance()));
5530
#endif
83 andreas 5531
            }
15 andreas 5532
        }
5533
    }
343 andreas 5534
#if TESTMODE == 1
5535
    setDone();
5536
#endif
15 andreas 5537
}
5538
 
22 andreas 5539
void TPageManager::doBLINK(int, vector<int>&, vector<string>& pars)
15 andreas 5540
{
5541
    DECL_TRACER("TPageManager::doBLINK(int port, vector<int>& channels, vector<string>& pars)");
5542
 
5543
    if (pars.size() < 4)
5544
    {
5545
        MSG_WARNING("Command BLINK expects 4 parameters! Command ignored.");
343 andreas 5546
#if TESTMODE == 1
5547
        setAllDone();
5548
#endif
15 andreas 5549
        return;
5550
    }
5551
 
16 andreas 5552
    TError::clear();
15 andreas 5553
    vector<int> sysButtons = { 141, 142, 143, 151, 152, 153, 154, 155, 156, 157, 158 };
193 andreas 5554
    vector<TMap::MAP_T> map = findButtons(0, sysButtons);
15 andreas 5555
 
5556
    if (TError::isError() || map.empty())
5557
    {
5558
        MSG_WARNING("No system buttons found.");
343 andreas 5559
#if TESTMODE == 1
5560
        setAllDone();
5561
#endif
15 andreas 5562
        return;
5563
    }
5564
 
5565
    vector<Button::TButton *> buttons = collectButtons(map);
5566
    vector<Button::TButton *>::iterator mapIter;
5567
 
5568
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
5569
    {
5570
        Button::TButton *bt = *mapIter;
5571
        bt->setActive(0);
343 andreas 5572
#if TESTMODE == 1
5573
                if (_gTestMode)
5574
                    _gTestMode->setResult(intToString(bt->getActiveInstance() + 1));
5575
#endif
15 andreas 5576
    }
343 andreas 5577
#if TESTMODE == 1
5578
    setDone();
5579
#endif
15 andreas 5580
}
5581
 
162 andreas 5582
/**
5583
 * Send the version of the panel to the NetLinx. This is the real application
5584
 * version.
5585
 */
127 andreas 5586
void TPageManager::doVER(int, vector<int>&, vector<string>&)
5587
{
5588
    DECL_TRACER("TPageManager::doVER(int, vector<int>&, vector<string>&)");
5589
 
5590
    amx::ANET_SEND scmd;
5591
    scmd.port = 1;
5592
    scmd.channel = 0;
5593
    scmd.msg.assign(string("^VER-")+VERSION_STRING());
5594
    scmd.MC = 0x008c;
5595
 
5596
    if (gAmxNet)
343 andreas 5597
    {
127 andreas 5598
        gAmxNet->sendCommand(scmd);
343 andreas 5599
#if TESTMODE == 1
5600
        __success = true;
347 andreas 5601
 
5602
        if (_gTestMode)
5603
            _gTestMode->setResult(VERSION_STRING());
343 andreas 5604
#endif
5605
    }
127 andreas 5606
    else
5607
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
343 andreas 5608
#if TESTMODE == 1
5609
    setAllDone();
5610
#endif
127 andreas 5611
}
5612
 
162 andreas 5613
/**
5614
 * Returns the user name used to connect to a SIP server. An empty string is
5615
 * returned if there is no user defined.
5616
 */
279 andreas 5617
#ifndef _NOSIP_
127 andreas 5618
void TPageManager::doWCN(int, vector<int>&, vector<string>&)
5619
{
5620
    DECL_TRACER("TPageManager::doWCN(int, vector<int>&, vector<string>&)");
5621
 
5622
    if (!TConfig::getSIPstatus())
343 andreas 5623
    {
5624
#if TESTMODE == 1
5625
        setAllDone();
5626
#endif
127 andreas 5627
        return;
343 andreas 5628
    }
127 andreas 5629
 
5630
    amx::ANET_SEND scmd;
5631
    scmd.port = 1;
5632
    scmd.channel = 0;
5633
    scmd.msg.assign("^WCN-" + TConfig::getSIPuser());
5634
    scmd.MC = 0x008c;
5635
 
5636
    if (gAmxNet)
343 andreas 5637
    {
127 andreas 5638
        gAmxNet->sendCommand(scmd);
343 andreas 5639
#if TESTMODE == 1
5640
        __success = true;
347 andreas 5641
 
5642
        if (_gTestMode)
5643
            _gTestMode->setResult(TConfig::getSIPuser());
343 andreas 5644
#endif
5645
    }
127 andreas 5646
    else
5647
        MSG_WARNING("Missing global class TAmxNet. Can't send message!");
343 andreas 5648
#if TESTMODE == 1
5649
        setAllDone();
5650
#endif
127 andreas 5651
}
279 andreas 5652
#endif
14 andreas 5653
/**
147 andreas 5654
 * Flip to specified page using the named animation.
5655
 * FIXME: Implement animation for pages.
5656
 */
5657
void TPageManager::doAFP(int, vector<int>&, vector<string>& pars)
5658
{
5659
    DECL_TRACER("TPageManager::doAFP(int, vector<int>&, vector<string>& pars)");
5660
 
5661
    if (pars.size() < 4)
5662
    {
5663
        MSG_ERROR("Less than 4 parameters!");
343 andreas 5664
#if TESTMODE == 1
5665
        setAllDone();
5666
#endif
147 andreas 5667
        return;
5668
    }
5669
 
5670
    TError::clear();
5671
    string pname = pars[0];
5672
//    string ani = pars[1];
5673
//    int origin = atoi(pars[2].c_str());
5674
//    int duration = atoi(pars[3].c_str());
5675
 
5676
    // FIXME: Animation of pages is currently not implemented.
5677
 
5678
    if (!pname.empty())
5679
        setPage(pname);
5680
    else if (mPreviousPage)
5681
        setPage(mPreviousPage);
343 andreas 5682
#if TESTMODE == 1
5683
    if (_gTestMode)
5684
        _gTestMode->setResult(getActualPage()->getName());
5685
 
5686
    setDone();
5687
#endif
147 andreas 5688
}
5689
 
5690
/**
14 andreas 5691
 * Add a specific popup page to a specified popup group if it does not already
5692
 * exist. If the new popup is added to a group which has a popup displayed on
5693
 * the current page along with the new pop-up, the displayed popup will be
5694
 * hidden and the new popup will be displayed.
5695
 */
22 andreas 5696
void TPageManager::doAPG(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 5697
{
5698
    DECL_TRACER("TPageManager::doAPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5699
 
5700
    if (pars.size() < 2)
5701
    {
5702
        MSG_ERROR("Less than 2 parameters!");
343 andreas 5703
#if TESTMODE == 1
5704
        setAllDone();
5705
#endif
11 andreas 5706
        return;
5707
    }
5708
 
16 andreas 5709
    TError::clear();
11 andreas 5710
    closeGroup(pars[1]);
14 andreas 5711
 
96 andreas 5712
    TPage *page = nullptr;
5713
    TSubPage *subPage = deliverSubPage(pars[0], &page);
14 andreas 5714
 
11 andreas 5715
    if (!subPage)
5716
    {
5717
        MSG_ERROR("Subpage " << pars[0] << " couldn't either found or created!");
343 andreas 5718
#if TESTMODE == 1
5719
        setAllDone();
5720
#endif
11 andreas 5721
        return;
5722
    }
5723
 
162 andreas 5724
    if (!page)
5725
    {
5726
        MSG_ERROR("There seems to be no page for subpage " << pars[0]);
343 andreas 5727
#if TESTMODE == 1
5728
        setAllDone();
5729
#endif
162 andreas 5730
        return;
5731
    }
5732
 
152 andreas 5733
    page->addSubPage(subPage);
11 andreas 5734
    subPage->setGroup(pars[1]);
14 andreas 5735
    subPage->setZOrder(page->getNextZOrder());
152 andreas 5736
    MSG_DEBUG("Setting new Z-order " << page->getActZOrder() << " on page " << page->getName());
11 andreas 5737
    subPage->show();
343 andreas 5738
#if TESTMODE == 1
347 andreas 5739
    if (_gTestMode)
5740
        _gTestMode->setResult(subPage->getGroupName() + ":" + subPage->getName());
5741
 
343 andreas 5742
    setDone();
5743
#endif
11 andreas 5744
}
5745
 
14 andreas 5746
/**
5747
 * Clear all popup pages from specified popup group.
5748
 */
22 andreas 5749
void TPageManager::doCPG(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 5750
{
5751
    DECL_TRACER("TPageManager::doCPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5752
 
5753
    if (pars.size() < 1)
5754
    {
5755
        MSG_ERROR("Expecting 1 parameter but got only 1!");
343 andreas 5756
#if TESTMODE == 1
5757
        setAllDone();
5758
#endif
11 andreas 5759
        return;
5760
    }
5761
 
16 andreas 5762
    TError::clear();
348 andreas 5763
    vector<SUBPAGELIST_T> pageList = mPageList->getSubPageList();
11 andreas 5764
 
83 andreas 5765
    if (pageList.size() > 0)
11 andreas 5766
    {
83 andreas 5767
        vector<SUBPAGELIST_T>::iterator pgIter;
5768
 
5769
        for (pgIter = pageList.begin(); pgIter != pageList.end(); pgIter++)
11 andreas 5770
        {
83 andreas 5771
            if (pgIter->group.compare(pars[0]) == 0)
5772
            {
5773
                pgIter->group.clear();
5774
                TSubPage *pg = getSubPage(pgIter->pageID);
11 andreas 5775
 
83 andreas 5776
                if (pg)
5777
                    pg->setGroup(pgIter->group);
343 andreas 5778
#if TESTMODE == 1
5779
                __success = true;
5780
#endif
83 andreas 5781
            }
11 andreas 5782
        }
5783
    }
343 andreas 5784
#if TESTMODE == 1
5785
    setDone();
5786
#endif
11 andreas 5787
}
5788
 
14 andreas 5789
/**
5790
 * Delete a specific popup page from specified popup group if it exists.
5791
 */
22 andreas 5792
void TPageManager::doDPG(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 5793
{
5794
    DECL_TRACER("TPageManager::doDPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5795
 
5796
    if (pars.size() < 2)
5797
    {
5798
        MSG_ERROR("Less than 2 parameters!");
348 andreas 5799
#if TESTMODE == 1
5800
        setAllDone();
5801
#endif
11 andreas 5802
        return;
5803
    }
5804
 
16 andreas 5805
    TError::clear();
11 andreas 5806
    SUBPAGELIST_T listPg = findSubPage(pars[0]);
5807
 
5808
    if (!listPg.isValid)
348 andreas 5809
    {
5810
#if TESTMODE == 1
5811
        setAllDone();
5812
#endif
11 andreas 5813
        return;
348 andreas 5814
    }
11 andreas 5815
 
5816
    if (listPg.group.compare(pars[1]) == 0)
5817
    {
5818
        listPg.group.clear();
5819
        TSubPage *pg = getSubPage(listPg.pageID);
5820
 
5821
        if (pg)
5822
            pg->setGroup(listPg.group);
348 andreas 5823
#if TESTMODE == 1
5824
        __success = true;
5825
#endif
11 andreas 5826
    }
348 andreas 5827
#if TESTMODE == 1
5828
    setDone();
5829
#endif
11 andreas 5830
}
5831
 
14 andreas 5832
/**
15 andreas 5833
 * Set the hide effect for the specified popup page to the named hide effect.
5834
 */
22 andreas 5835
void TPageManager::doPHE(int, vector<int>&, vector<string>& pars)
15 andreas 5836
{
5837
    DECL_TRACER("TPageManager::doPHE(int port, vector<int>& channels, vector<string>& pars)");
5838
 
5839
    if (pars.size() < 2)
5840
    {
5841
        MSG_ERROR("Less than 2 parameters!");
348 andreas 5842
#if TESTMODE == 1
5843
        setAllDone();
5844
#endif
15 andreas 5845
        return;
5846
    }
5847
 
16 andreas 5848
    TError::clear();
96 andreas 5849
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 5850
 
5851
    if (!pg)
348 andreas 5852
    {
5853
#if TESTMODE == 1
5854
        setAllDone();
5855
#endif
96 andreas 5856
        return;
348 andreas 5857
    }
15 andreas 5858
 
162 andreas 5859
    if (strCaseCompare(pars[1], "fade") == 0)
15 andreas 5860
        pg->setHideEffect(SE_FADE);
162 andreas 5861
    else if (strCaseCompare(pars[1], "slide to left") == 0)
15 andreas 5862
        pg->setHideEffect(SE_SLIDE_LEFT);
162 andreas 5863
    else if (strCaseCompare(pars[1], "slide to right") == 0)
15 andreas 5864
        pg->setHideEffect(SE_SLIDE_RIGHT);
162 andreas 5865
    else if (strCaseCompare(pars[1], "slide to top") == 0)
15 andreas 5866
        pg->setHideEffect(SE_SLIDE_TOP);
162 andreas 5867
    else if (strCaseCompare(pars[1], "slide to bottom") == 0)
15 andreas 5868
        pg->setHideEffect(SE_SLIDE_BOTTOM);
162 andreas 5869
    else if (strCaseCompare(pars[1], "slide to left fade") == 0)
15 andreas 5870
        pg->setHideEffect(SE_SLIDE_LEFT_FADE);
162 andreas 5871
    else if (strCaseCompare(pars[1], "slide to right fade") == 0)
15 andreas 5872
        pg->setHideEffect(SE_SLIDE_RIGHT_FADE);
162 andreas 5873
    else if (strCaseCompare(pars[1], "slide to top fade") == 0)
15 andreas 5874
        pg->setHideEffect(SE_SLIDE_TOP_FADE);
162 andreas 5875
    else if (strCaseCompare(pars[1], "slide to bottom fade") == 0)
15 andreas 5876
        pg->setHideEffect(SE_SLIDE_BOTTOM_FADE);
5877
    else
5878
        pg->setHideEffect(SE_NONE);
348 andreas 5879
#if TESTMODE == 1
5880
    if (_gTestMode)
5881
        _gTestMode->setResult(intToString(pg->getHideEffect()));
5882
 
5883
    __success = true;
5884
    setAllDone();
5885
#endif
15 andreas 5886
}
5887
 
5888
/**
5889
 * Set the hide effect position. Only 1 coordinate is ever needed for an effect;
5890
 * however, the command will specify both. This command sets the location at
5891
 * which the effect will end at.
5892
 */
22 andreas 5893
void TPageManager::doPHP(int, vector<int>&, vector<string>& pars)
15 andreas 5894
{
5895
    DECL_TRACER("TPageManager::doPHP(int port, vector<int>& channels, vector<string>& pars)");
5896
 
5897
    if (pars.size() < 2)
5898
    {
5899
        MSG_ERROR("Less than 2 parameters!");
348 andreas 5900
#if TESTMODE == 1
5901
        setAllDone();
5902
#endif
15 andreas 5903
        return;
5904
    }
5905
 
16 andreas 5906
    TError::clear();
15 andreas 5907
    size_t pos = pars[1].find(",");
5908
    int x, y;
5909
 
5910
    if (pos == string::npos)
5911
    {
5912
        x = atoi(pars[1].c_str());
5913
        y = 0;
5914
    }
5915
    else
5916
    {
5917
        x = atoi(pars[1].substr(0, pos).c_str());
5918
        y = atoi(pars[1].substr(pos+1).c_str());
5919
    }
5920
 
96 andreas 5921
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 5922
 
5923
    if (!pg)
348 andreas 5924
    {
5925
#if TESTMODE == 1
5926
        setAllDone();
5927
#endif
96 andreas 5928
        return;
348 andreas 5929
    }
15 andreas 5930
 
5931
    pg->setHideEndPosition(x, y);
348 andreas 5932
#if TESTMODE == 1
5933
    if (_gTestMode)
5934
    {
5935
        int x, y;
5936
        pg->getHideEndPosition(&x, &y);
5937
        _gTestMode->setResult(intToString(x) + "," + intToString(y));
5938
    }
5939
 
5940
    __success = true;
5941
    setAllDone();
5942
#endif
15 andreas 5943
}
5944
 
5945
/**
5946
 * Set the hide effect time for the specified popup page.
5947
 */
22 andreas 5948
void TPageManager::doPHT(int, vector<int>&, vector<string>& pars)
15 andreas 5949
{
5950
    DECL_TRACER("TPageManager::doPHT(int port, vector<int>& channels, vector<string>& pars)");
5951
 
5952
    if (pars.size() < 2)
5953
    {
5954
        MSG_ERROR("Less than 2 parameters!");
348 andreas 5955
#if TESTMODE == 1
5956
        setAllDone();
5957
#endif
15 andreas 5958
        return;
5959
    }
5960
 
16 andreas 5961
    TError::clear();
96 andreas 5962
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 5963
 
5964
    if (!pg)
348 andreas 5965
    {
5966
#if TESTMODE == 1
5967
        setAllDone();
5968
#endif
96 andreas 5969
        return;
348 andreas 5970
    }
15 andreas 5971
 
5972
    pg->setHideTime(atoi(pars[1].c_str()));
348 andreas 5973
#if TESTMODE == 1
5974
    if (_gTestMode)
5975
        _gTestMode->setResult(intToString(pg->getHideTime()));
5976
 
5977
    __success = true;
5978
    setAllDone();
5979
#endif
15 andreas 5980
}
5981
 
5982
/**
14 andreas 5983
 * Close all popups on a specified page. If the page name is empty, the current
5984
 * page is used. Same as the ’Clear Page’ command in TPDesign4.
5985
 */
22 andreas 5986
void TPageManager::doPPA(int, std::vector<int>&, std::vector<std::string>& pars)
11 andreas 5987
{
5988
    DECL_TRACER("TPageManager::doPPA(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
5989
 
16 andreas 5990
    TError::clear();
11 andreas 5991
    TPage *pg;
5992
 
5993
    if (pars.size() == 0)
5994
        pg = getPage(mActualPage);
5995
    else
5996
        pg = getPage(pars[0]);
5997
 
5998
    if (!pg)
348 andreas 5999
    {
6000
#if TESTMODE == 1
6001
        setAllDone();
6002
#endif
11 andreas 6003
        return;
348 andreas 6004
    }
11 andreas 6005
 
12 andreas 6006
    pg->drop();
14 andreas 6007
    pg->resetZOrder();
348 andreas 6008
#if TESTMODE == 1
6009
    setDone();
6010
#endif
11 andreas 6011
}
6012
 
14 andreas 6013
/**
6014
 * Deactivate a specific popup page on either a specified page or the current
6015
 * page. If the page name is empty, the current page is used. If the popup page
6016
 * is part of a group, the whole group is deactivated. This command works in
6017
 * the same way as the ’Hide Popup’ command in TPDesign4.
6018
 */
22 andreas 6019
void TPageManager::doPPF(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6020
{
6021
    DECL_TRACER("TPageManager::doPPF(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
6022
 
6023
    if (pars.size() < 1)
6024
    {
6025
        MSG_ERROR("At least 1 parameter is expected!");
349 andreas 6026
#if TESTMODE == 1
6027
        setAllDone();
6028
#endif
12 andreas 6029
        return;
6030
    }
6031
 
16 andreas 6032
    TError::clear();
14 andreas 6033
    hideSubPage(pars[0]);
335 andreas 6034
#if TESTMODE == 1
6035
    setDone();
6036
#endif
12 andreas 6037
}
6038
 
14 andreas 6039
/**
6040
 * Toggle a specific popup page on either a specified page or the current page.
6041
 * If the page name is empty, the current page is used. Toggling refers to the
6042
 * activating/deactivating (On/Off) of a popup page. This command works in the
6043
 * same way as the ’Toggle Popup’ command in TPDesign4.
6044
 */
22 andreas 6045
void TPageManager::doPPG(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6046
{
6047
    DECL_TRACER("TPageManager::doPPG(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 6048
 
12 andreas 6049
    if (pars.size() < 1)
6050
    {
6051
        MSG_ERROR("At least 1 parameter is expected!");
349 andreas 6052
#if TESTMODE == 1
6053
        setAllDone();
6054
#endif
12 andreas 6055
        return;
6056
    }
6057
 
16 andreas 6058
    TError::clear();
14 andreas 6059
    TPage *page = getPage(mActualPage);
6060
 
6061
    if (!page)
6062
    {
6063
        MSG_ERROR("No active page found! Internal error.");
349 andreas 6064
#if TESTMODE == 1
6065
        setAllDone();
6066
#endif
14 andreas 6067
        return;
6068
    }
6069
 
12 andreas 6070
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 6071
 
12 andreas 6072
    if (!pg)
349 andreas 6073
    {
6074
#if TESTMODE == 1
6075
        setAllDone();
6076
#endif
12 andreas 6077
        return;
349 andreas 6078
    }
14 andreas 6079
 
12 andreas 6080
    if (pg->isVisible())
6081
    {
6082
        pg->drop();
162 andreas 6083
        page->decZOrder();
349 andreas 6084
#if TESTMODE == 1
6085
        setDone();
6086
#endif
12 andreas 6087
        return;
6088
    }
6089
 
6090
    TSubPage *sub = getFirstSubPageGroup(pg->getGroupName());
14 andreas 6091
 
12 andreas 6092
    while(sub)
6093
    {
6094
        if (sub->getGroupName().compare(pg->getGroupName()) == 0 && sub->isVisible())
6095
            sub->drop();
14 andreas 6096
 
12 andreas 6097
        sub = getNextSubPageGroup(pg->getGroupName(), sub);
6098
    }
6099
 
152 andreas 6100
    pg->setZOrder(page->getNextZOrder());
6101
    MSG_DEBUG("Setting new Z-order " << page->getActZOrder() << " on page " << page->getName());
12 andreas 6102
    pg->show();
349 andreas 6103
#if TESTMODE == 1
6104
    setDone();
6105
#endif
12 andreas 6106
}
6107
 
14 andreas 6108
/**
6109
 * Kill refers to the deactivating (Off) of a popup window from all pages. If
6110
 * the pop-up page is part of a group, the whole group is deactivated. This
6111
 * command works in the same way as the 'Clear Group' command in TPDesign 4.
6112
 */
22 andreas 6113
void TPageManager::doPPK(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6114
{
6115
    DECL_TRACER("TPageManager::doPPK(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 6116
 
12 andreas 6117
    if (pars.size() < 1)
6118
    {
6119
        MSG_ERROR("At least 1 parameter is expected!");
349 andreas 6120
#if TESTMODE == 1
6121
        setAllDone();
6122
#endif
12 andreas 6123
        return;
6124
    }
6125
 
16 andreas 6126
    TError::clear();
14 andreas 6127
    TPage *page = getPage(mActualPage);
6128
 
6129
    if (!page)
6130
    {
6131
        MSG_ERROR("No active page found! Internal error.");
349 andreas 6132
#if TESTMODE == 1
6133
        setAllDone();
6134
#endif
14 andreas 6135
        return;
6136
    }
6137
 
12 andreas 6138
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 6139
 
12 andreas 6140
    if (pg)
14 andreas 6141
    {
6142
        pg->drop();
162 andreas 6143
        page->decZOrder();
14 andreas 6144
    }
349 andreas 6145
#if TESTMODE == 1
6146
        setDone();
6147
#endif
12 andreas 6148
}
6149
 
14 andreas 6150
/**
6151
 * Set the modality of a specific popup page to Modal or NonModal.
6152
 * A Modal popup page, when active, only allows you to use the buttons and
6153
 * features on that popup page. All other buttons on the panel page are
6154
 * inactivated.
6155
 */
22 andreas 6156
void TPageManager::doPPM(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6157
{
6158
    DECL_TRACER("TPageManager::doPPM(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 6159
 
12 andreas 6160
    if (pars.size() < 2)
6161
    {
6162
        MSG_ERROR("Expecting 2 parameters!");
349 andreas 6163
#if TESTMODE == 1
6164
        setAllDone();
6165
#endif
12 andreas 6166
        return;
6167
    }
14 andreas 6168
 
16 andreas 6169
    TError::clear();
12 andreas 6170
    TSubPage *pg = getSubPage(pars[0]);
14 andreas 6171
 
12 andreas 6172
    if (pg)
6173
    {
162 andreas 6174
        if (pars[1] == "1" || strCaseCompare(pars[1], "modal") == 0)
12 andreas 6175
            pg->setModal(1);
6176
        else
6177
            pg->setModal(0);
349 andreas 6178
#if TESTMODE == 1
6179
        if (_gTestMode)
6180
            _gTestMode->setResult(pg->isModal() ? "TRUE" : "FALSE");
6181
#endif
12 andreas 6182
    }
349 andreas 6183
#if TESTMODE == 1
6184
        setAllDone();
6185
#endif
12 andreas 6186
}
6187
 
14 andreas 6188
/**
6189
 * Activate a specific popup page to launch on either a specified page or the
6190
 * current page. If the page name is empty, the current page is used. If the
6191
 * popup page is already on, do not re-draw it. This command works in the same
6192
 * way as the ’Show Popup’ command in TPDesign4.
6193
 */
22 andreas 6194
void TPageManager::doPPN(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6195
{
6196
    DECL_TRACER("TPageManager::doPPN(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
6197
 
6198
    if (pars.size() < 1)
6199
    {
6200
        MSG_ERROR("At least 1 parameter is expected!");
349 andreas 6201
#if TESTMODE == 1
6202
        setAllDone();
6203
#endif
12 andreas 6204
        return;
6205
    }
6206
 
16 andreas 6207
    TError::clear();
14 andreas 6208
    showSubPage(pars[0]);
349 andreas 6209
#if TESTMODE == 1
6210
    setDone();
6211
#endif
12 andreas 6212
}
6213
 
14 andreas 6214
/**
15 andreas 6215
 * Set a specific popup page to timeout within a specified time. If timeout is
6216
 * empty, popup page will clear the timeout.
6217
 */
22 andreas 6218
void TPageManager::doPPT(int, vector<int>&, vector<string>& pars)
15 andreas 6219
{
6220
    DECL_TRACER("TPageManager::doPPT(int port, vector<int>& channels, vector<string>& pars)");
6221
 
6222
    if (pars.size() < 2)
6223
    {
6224
        MSG_ERROR("Expecting 2 parameters!");
351 andreas 6225
#if TESTMODE == 1
6226
        setAllDone();
6227
#endif
15 andreas 6228
        return;
6229
    }
6230
 
16 andreas 6231
    TError::clear();
96 andreas 6232
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6233
 
6234
    if (!pg)
351 andreas 6235
    {
6236
#if TESTMODE == 1
6237
        setAllDone();
6238
#endif
96 andreas 6239
        return;
351 andreas 6240
    }
15 andreas 6241
 
6242
    pg->setTimeout(atoi(pars[1].c_str()));
351 andreas 6243
#if TESTMODE == 1
6244
    if (_gTestMode)
6245
        _gTestMode->setResult(intToString(pg->getTimeout()));
6246
 
6247
    __success = true;
6248
    setAllDone();
6249
#endif
15 andreas 6250
}
6251
 
6252
/**
14 andreas 6253
 * Close all popups on all pages. This command works in the same way as the
6254
 * 'Clear All' command in TPDesign 4.
6255
 */
22 andreas 6256
void TPageManager::doPPX(int, std::vector<int>&, std::vector<std::string>&)
12 andreas 6257
{
6258
    DECL_TRACER("TPageManager::doPPX(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
6259
 
16 andreas 6260
    TError::clear();
12 andreas 6261
    PCHAIN_T *chain = mPchain;
14 andreas 6262
 
12 andreas 6263
    while(chain)
6264
    {
6265
        TSubPage *sub = chain->page->getFirstSubPage();
14 andreas 6266
 
12 andreas 6267
        while (sub)
6268
        {
351 andreas 6269
            MSG_DEBUG("Dropping subpage " << sub->getNumber() << ", \"" << sub->getName() << "\".");
12 andreas 6270
            sub->drop();
6271
            sub = chain->page->getNextSubPage();
6272
        }
14 andreas 6273
 
12 andreas 6274
        chain = chain->next;
6275
    }
14 andreas 6276
 
6277
    TPage *page = getPage(mActualPage);
6278
 
6279
    if (!page)
6280
    {
6281
        MSG_ERROR("No active page found! Internal error.");
351 andreas 6282
#if TESTMODE == 1
6283
        setAllDone();
6284
#endif
14 andreas 6285
        return;
6286
    }
6287
 
6288
    page->resetZOrder();
351 andreas 6289
#if TESTMODE == 1
6290
    setDone();
6291
#endif
12 andreas 6292
}
6293
 
14 andreas 6294
/**
15 andreas 6295
 * Set the show effect for the specified popup page to the named show effect.
6296
 */
22 andreas 6297
void TPageManager::doPSE(int, vector<int>&, vector<string>& pars)
15 andreas 6298
{
6299
    DECL_TRACER("TPageManager::doPSE(int port, vector<int>& channels, vector<string>& pars)");
6300
 
6301
    if (pars.size() < 2)
6302
    {
6303
        MSG_ERROR("Less than 2 parameters!");
351 andreas 6304
#if TESTMODE == 1
6305
        setAllDone();
6306
#endif
15 andreas 6307
        return;
6308
    }
6309
 
16 andreas 6310
    TError::clear();
96 andreas 6311
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6312
 
6313
    if (!pg)
351 andreas 6314
    {
6315
#if TESTMODE == 1
6316
        setAllDone();
6317
#endif
96 andreas 6318
        return;
351 andreas 6319
    }
15 andreas 6320
 
162 andreas 6321
    if (strCaseCompare(pars[1], "fade") == 0)
15 andreas 6322
        pg->setShowEffect(SE_FADE);
162 andreas 6323
    else if (strCaseCompare(pars[1], "slide to left") == 0)
15 andreas 6324
        pg->setShowEffect(SE_SLIDE_LEFT);
162 andreas 6325
    else if (strCaseCompare(pars[1], "slide to right") == 0)
15 andreas 6326
        pg->setShowEffect(SE_SLIDE_RIGHT);
162 andreas 6327
    else if (strCaseCompare(pars[1], "slide to top") == 0)
15 andreas 6328
        pg->setShowEffect(SE_SLIDE_TOP);
162 andreas 6329
    else if (strCaseCompare(pars[1], "slide to bottom") == 0)
15 andreas 6330
        pg->setShowEffect(SE_SLIDE_BOTTOM);
162 andreas 6331
    else if (strCaseCompare(pars[1], "slide to left fade") == 0)
15 andreas 6332
        pg->setShowEffect(SE_SLIDE_LEFT_FADE);
162 andreas 6333
    else if (strCaseCompare(pars[1], "slide to right fade") == 0)
15 andreas 6334
        pg->setShowEffect(SE_SLIDE_RIGHT_FADE);
162 andreas 6335
    else if (strCaseCompare(pars[1], "slide to top fade") == 0)
15 andreas 6336
        pg->setShowEffect(SE_SLIDE_TOP_FADE);
162 andreas 6337
    else if (strCaseCompare(pars[1], "slide to bottom fade") == 0)
15 andreas 6338
        pg->setShowEffect(SE_SLIDE_BOTTOM_FADE);
6339
    else
6340
        pg->setShowEffect(SE_NONE);
351 andreas 6341
#if TESTMODE == 1
6342
    if (_gTestMode)
6343
        _gTestMode->setResult(intToString(pg->getShowEffect()));
6344
 
6345
    __success = true;
6346
    setAllDone();
6347
#endif
15 andreas 6348
}
6349
 
162 andreas 6350
/**
6351
 * Set the show effect position. Only 1 coordinate is ever needed for an effect;
6352
 * however, the command will specify both. This command sets the location at
6353
 * which the effect will begin.
6354
 */
22 andreas 6355
void TPageManager::doPSP(int, vector<int>&, vector<string>& pars)
15 andreas 6356
{
6357
    DECL_TRACER("TPageManager::doPSP(int port, vector<int>& channels, vector<string>& pars)");
6358
 
6359
    if (pars.size() < 2)
6360
    {
6361
        MSG_ERROR("Less than 2 parameters!");
351 andreas 6362
#if TESTMODE == 1
6363
        setAllDone();
6364
#endif
15 andreas 6365
        return;
6366
    }
6367
 
16 andreas 6368
    TError::clear();
15 andreas 6369
    size_t pos = pars[1].find(",");
6370
    int x, y;
6371
 
6372
    if (pos == string::npos)
6373
    {
6374
        x = atoi(pars[1].c_str());
6375
        y = 0;
6376
    }
6377
    else
6378
    {
6379
        x = atoi(pars[1].substr(0, pos).c_str());
6380
        y = atoi(pars[1].substr(pos+1).c_str());
6381
    }
6382
 
96 andreas 6383
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6384
 
6385
    if (!pg)
351 andreas 6386
    {
6387
#if TESTMODE == 1
6388
        setAllDone();
6389
#endif
96 andreas 6390
        return;
351 andreas 6391
    }
15 andreas 6392
 
6393
    pg->setShowEndPosition(x, y);
351 andreas 6394
#if TESTMODE == 1
6395
    pg->getShowEndPosition(&x, &y);
6396
 
6397
    if (_gTestMode)
6398
        _gTestMode->setResult(intToString(x) + "," + intToString(y));
6399
 
6400
    __success = true;
6401
    setAllDone();
6402
#endif
15 andreas 6403
}
6404
 
6405
/**
6406
 * Set the show effect time for the specified popup page.
6407
 */
22 andreas 6408
void TPageManager::doPST(int, vector<int>&, vector<string>& pars)
15 andreas 6409
{
6410
    DECL_TRACER("TPageManager::doPST(int port, vector<int>& channels, vector<string>& pars)");
6411
 
6412
    if (pars.size() < 2)
6413
    {
6414
        MSG_ERROR("Less than 2 parameters!");
351 andreas 6415
#if TESTMODE == 1
6416
        setAllDone();
6417
#endif
15 andreas 6418
        return;
6419
    }
6420
 
16 andreas 6421
    TError::clear();
96 andreas 6422
    TSubPage *pg = deliverSubPage(pars[0]);
15 andreas 6423
 
6424
    if (!pg)
351 andreas 6425
    {
6426
#if TESTMODE == 1
6427
        setAllDone();
6428
#endif
96 andreas 6429
        return;
351 andreas 6430
    }
15 andreas 6431
 
6432
    pg->setShowTime(atoi(pars[1].c_str()));
351 andreas 6433
#if TESTMODE == 1
6434
    if (_gTestMode)
6435
        _gTestMode->setResult(intToString(pg->getShowTime()));
6436
 
6437
    __success = 1;
6438
    setAllDone();
6439
#endif
15 andreas 6440
}
6441
 
6442
/**
14 andreas 6443
 * Flips to a page with a specified page name. If the page is currently active,
6444
 * it will not redraw the page.
6445
 */
22 andreas 6446
void TPageManager::doPAGE(int, std::vector<int>&, std::vector<std::string>& pars)
12 andreas 6447
{
6448
    DECL_TRACER("TPageManager::doPAGE(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
14 andreas 6449
 
15 andreas 6450
    if (pars.empty())
6451
    {
6452
        MSG_WARNING("Got no page parameter!");
351 andreas 6453
#if TESTMODE == 1
6454
        setAllDone();
6455
#endif
15 andreas 6456
        return;
6457
    }
14 andreas 6458
 
16 andreas 6459
    TError::clear();
15 andreas 6460
    setPage(pars[0]);
351 andreas 6461
#if TESTMODE == 1
6462
    if (_gTestMode)
6463
        _gTestMode->setResult(intToString(getActualPageNumber()));
6464
 
6465
    setDone();
6466
#endif
15 andreas 6467
}
6468
 
6469
/**
38 andreas 6470
 * @brief TPageManager::doANI Run a button animation (in 1/10 second).
6471
 * Syntax:
6472
 *      ^ANI-<vt addr range>,<start state>,<end state>,<time>
6473
 * Variable:
6474
 *      variable text address range = 1 - 4000.
6475
 *      start state = Beginning of button state (0= current state).
6476
 *      end state = End of button state.
6477
 *      time = In 1/10 second intervals.
6478
 * Example:
6479
 *      SEND_COMMAND Panel,"'^ANI-500,1,25,100'"
6480
 * Runs a button animation at text range 500 from state 1 to state 25 for 10 seconds.
6481
 *
6482
 * @param port      The port number
6483
 * @param channels  The channels of the buttons
6484
 * @param pars      The parameters
6485
 */
6486
void TPageManager::doANI(int port, std::vector<int> &channels, std::vector<std::string> &pars)
6487
{
6488
    DECL_TRACER("TPageManager::doANI(int port, std::vector<int> &channels, std::vector<std::string> &pars)");
6489
 
6490
    if (pars.size() < 3)
6491
    {
6492
        MSG_ERROR("Expecting 3 parameters but got " << pars.size() << "! Ignoring command.");
6493
        return;
6494
    }
6495
 
6496
    TError::clear();
6497
    int stateStart = atoi(pars[0].c_str());
6498
    int endState = atoi(pars[1].c_str());
6499
    int runTime = atoi(pars[2].c_str());
6500
 
193 andreas 6501
    vector<TMap::MAP_T> map = findButtons(port, channels);
38 andreas 6502
 
6503
    if (TError::isError() || map.empty())
6504
        return;
6505
 
6506
    vector<Button::TButton *> buttons = collectButtons(map);
6507
 
83 andreas 6508
    if (buttons.size() > 0)
38 andreas 6509
    {
83 andreas 6510
        vector<Button::TButton *>::iterator mapIter;
6511
 
6512
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
6513
        {
6514
            Button::TButton *bt = *mapIter;
6515
            bt->startAnimation(stateStart, endState, runTime);
6516
        }
38 andreas 6517
    }
351 andreas 6518
#if TESTMODE == 1
6519
    if (_gTestMode)
6520
        _gTestMode->setResult(intToString(stateStart) + "," + intToString(endState) + "," + intToString(runTime));
6521
 
6522
    setDone();
6523
#endif
38 andreas 6524
}
6525
 
6526
/**
15 andreas 6527
 * Add page flip action to a button if it does not already exist.
6528
 */
6529
void TPageManager::doAPF(int port, vector<int>& channels, vector<string>& pars)
6530
{
6531
    DECL_TRACER("TPageManager::doAPF(int port, vector<int>& channels, vector<string>& pars)");
6532
 
6533
    if (pars.size() < 2)
6534
    {
6535
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
351 andreas 6536
#if TESTMODE == 1
6537
        setAllDone();
6538
#endif
14 andreas 6539
        return;
15 andreas 6540
    }
14 andreas 6541
 
16 andreas 6542
    TError::clear();
15 andreas 6543
    string action = pars[0];
6544
    string pname = pars[1];
14 andreas 6545
 
193 andreas 6546
    vector<TMap::MAP_T> map = findButtons(port, channels);
14 andreas 6547
 
15 andreas 6548
    if (TError::isError() || map.empty())
351 andreas 6549
    {
6550
#if TESTMODE == 1
6551
        setAllDone();
6552
#endif
15 andreas 6553
        return;
351 andreas 6554
    }
15 andreas 6555
 
6556
    vector<Button::TButton *> buttons = collectButtons(map);
6557
 
83 andreas 6558
    if (buttons.size() > 0)
12 andreas 6559
    {
83 andreas 6560
        vector<Button::TButton *>::iterator mapIter;
6561
 
6562
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
6563
        {
6564
            Button::TButton *bt = *mapIter;
6565
            bt->addPushFunction(action, pname);
6566
        }
15 andreas 6567
    }
351 andreas 6568
#if TESTMODE == 1
6569
    if (_gTestMode)
6570
        _gTestMode->setResult(toUpper(action) + "," + toUpper(pname));
6571
 
6572
    __success = true;
6573
    setAllDone();
6574
#endif
15 andreas 6575
}
12 andreas 6576
 
15 andreas 6577
/**
43 andreas 6578
 * Append non-unicode text.
6579
 */
6580
void TPageManager::doBAT(int port, vector<int> &channels, vector<string> &pars)
6581
{
6582
    DECL_TRACER("TPageManager::doBAT(int port, vector<int> &channels, vector<string> &pars)");
6583
 
6584
    if (pars.size() < 1)
6585
    {
6586
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
330 andreas 6587
#if TESTMODE == 1
334 andreas 6588
        setAllDone();
330 andreas 6589
#endif
43 andreas 6590
        return;
6591
    }
6592
 
6593
    TError::clear();
6594
    int btState = atoi(pars[0].c_str());
6595
    string text;
6596
 
6597
    if (pars.size() > 1)
6598
        text = pars[1];
6599
 
193 andreas 6600
    vector<TMap::MAP_T> map = findButtons(port, channels);
43 andreas 6601
 
6602
    if (TError::isError() || map.empty())
330 andreas 6603
    {
6604
#if TESTMODE == 1
334 andreas 6605
        setAllDone();
330 andreas 6606
#endif
43 andreas 6607
        return;
330 andreas 6608
    }
43 andreas 6609
 
6610
    vector<Button::TButton *> buttons = collectButtons(map);
6611
 
162 andreas 6612
    if (buttons.empty())
330 andreas 6613
    {
6614
#if TESTMODE == 1
334 andreas 6615
        setAllDone();
330 andreas 6616
#endif
162 andreas 6617
        return;
330 andreas 6618
    }
162 andreas 6619
 
6620
    vector<Button::TButton *>::iterator mapIter;
6621
 
6622
    for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
43 andreas 6623
    {
162 andreas 6624
        Button::TButton *bt = *mapIter;
43 andreas 6625
 
331 andreas 6626
        bt->appendText(text, btState - 1);
330 andreas 6627
#if TESTMODE == 1
331 andreas 6628
        if (_gTestMode)
330 andreas 6629
        {
331 andreas 6630
            int st = (btState > 0 ? (btState - 1) : 0);
6631
            _gTestMode->setResult(bt->getText(st));
333 andreas 6632
        }
330 andreas 6633
 
331 andreas 6634
        __success = true;
330 andreas 6635
#endif
43 andreas 6636
    }
334 andreas 6637
#if TESTMODE == 1
6638
    setDone();
6639
#endif
43 andreas 6640
}
6641
 
6642
/**
60 andreas 6643
 * @brief Append unicode text. Same format as ^UNI.
6644
 * This command allows to set up to 50 characters of ASCII code. The unicode
6645
 * characters must be set as hex numbers.
6646
 */
6647
void TPageManager::doBAU(int port, vector<int>& channels, vector<string>& pars)
6648
{
6649
    DECL_TRACER("TPageManager::doBAU(int port, vector<int>& channels, vector<string>& pars)");
6650
 
6651
    if (pars.size() < 1)
6652
    {
6653
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 6654
#if TESTMODE == 1
6655
        setAllDone();
6656
#endif
60 andreas 6657
        return;
6658
    }
6659
 
6660
    TError::clear();
6661
    int btState = atoi(pars[0].c_str());
6662
    string text;
6663
    char ch[3];
6664
 
331 andreas 6665
    if (pars.size() > 1)
6666
        text = pars[1];
6667
 
6668
    if ((text.size() % 4) == 0)
60 andreas 6669
    {
162 andreas 6670
        try
60 andreas 6671
        {
162 andreas 6672
            text = pars[1];
331 andreas 6673
            MSG_DEBUG("Processing UTF16 string: " << text);
162 andreas 6674
            // Because the unicode characters are hex numbers, we scan the text
6675
            // and convert the hex numbers into real numbers.
6676
            size_t len = text.length();
6677
            bool inHex = false;
6678
            int lastChar = 0;
331 andreas 6679
            uint16_t *numstr = new uint16_t[len / 4];
162 andreas 6680
            int uniPos = 0;
331 andreas 6681
            int cntCount = 0;
60 andreas 6682
 
162 andreas 6683
            for (size_t i = 0; i < len; i++)
60 andreas 6684
            {
162 andreas 6685
                int c = text.at(i);
60 andreas 6686
 
162 andreas 6687
                if (!inHex && isHex(c))
6688
                {
6689
                    inHex = true;
6690
                    lastChar = c;
6691
                    continue;
6692
                }
6693
 
6694
                if (inHex && !isHex(c))
6695
                    break;
6696
 
6697
                if (inHex && isHex(c))
6698
                {
6699
                    ch[0] = lastChar;
6700
                    ch[1] = c;
6701
                    ch[2] = 0;
6702
                    uint16_t num = (uint16_t)strtol(ch, NULL, 16);
331 andreas 6703
 
6704
                    if ((cntCount % 2) != 0)
6705
                    {
6706
                        numstr[uniPos] |= num;
6707
                        uniPos++;
6708
                    }
6709
                    else
6710
                        numstr[uniPos] = (num << 8) & 0xff00;
6711
 
6712
                    cntCount++;
162 andreas 6713
                    inHex = false;
6714
 
6715
                    if (uniPos >= 50)
6716
                        break;
331 andreas 6717
                }
6718
            }
162 andreas 6719
 
331 andreas 6720
            text.clear();
6721
            // Here we make from the real numbers a UTF8 string
6722
            for (size_t i = 0; i < len / 4; ++i)
6723
            {
6724
                if (numstr[i] <= 0x00ff)
6725
                {
6726
                    ch[0] = numstr[i];
6727
                    ch[1] = 0;
6728
                    text.append(ch);
162 andreas 6729
                }
331 andreas 6730
                else
6731
                {
6732
                    ch[0] = (numstr[i] >> 8) & 0x00ff;
6733
                    ch[1] = numstr[i] & 0x00ff;
6734
                    ch[2] = 0;
6735
                    text.append(ch);
6736
                }
60 andreas 6737
            }
6738
 
331 andreas 6739
            delete[] numstr;
60 andreas 6740
        }
162 andreas 6741
        catch (std::exception const & e)
6742
        {
6743
            MSG_ERROR("Character conversion error: " << e.what());
351 andreas 6744
#if TESTMODE == 1
6745
            setAllDone();
6746
#endif
162 andreas 6747
            return;
6748
        }
60 andreas 6749
    }
331 andreas 6750
    else
6751
    {
6752
        MSG_WARNING("No or invalid UTF16 string: " << text);
351 andreas 6753
#if TESTMODE == 1
6754
        setAllDone();
6755
#endif
331 andreas 6756
        return;
6757
    }
60 andreas 6758
 
193 andreas 6759
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 6760
 
6761
    if (TError::isError() || map.empty())
351 andreas 6762
    {
6763
#if TESTMODE == 1
6764
        setAllDone();
6765
#endif
60 andreas 6766
        return;
351 andreas 6767
    }
60 andreas 6768
 
6769
    vector<Button::TButton *> buttons = collectButtons(map);
6770
 
83 andreas 6771
    if (buttons.size() > 0)
60 andreas 6772
    {
83 andreas 6773
        vector<Button::TButton *>::iterator mapIter;
60 andreas 6774
 
83 andreas 6775
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 6776
        {
83 andreas 6777
            Button::TButton *bt = *mapIter;
60 andreas 6778
 
331 andreas 6779
            bt->appendText(text, btState - 1);
330 andreas 6780
#if TESTMODE == 1
331 andreas 6781
            if (_gTestMode)
6782
                _gTestMode->setResult(bt->getText(btState - 1));
330 andreas 6783
 
331 andreas 6784
            __success = true;
330 andreas 6785
#endif
60 andreas 6786
        }
6787
    }
330 andreas 6788
#if TESTMODE == 1
334 andreas 6789
    setDone();
330 andreas 6790
#endif
60 andreas 6791
}
6792
 
6793
/**
43 andreas 6794
 * @brief TPageManager::doBCB Set the border color.
6795
 * Set the border color to the specified color. Only if the specified border
6796
 * color is not the same as the current color.
6797
 * Note: Color can be assigned by color name (without spaces), number or
6798
 * R,G,B value (RRGGBB or RRGGBBAA).
6799
 */
6800
void TPageManager::doBCB(int port, vector<int> &channels, vector<string> &pars)
6801
{
6802
    DECL_TRACER("TPageManager::doBCB(int port, vector<int> &channels, vector<string> &pars)");
6803
 
6804
    if (pars.size() < 1)
6805
    {
6806
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 6807
#if TESTMODE == 1
6808
        setAllDone();
6809
#endif
43 andreas 6810
        return;
6811
    }
6812
 
6813
    TError::clear();
6814
    int btState = atoi(pars[0].c_str());
6815
    string color;
6816
 
6817
    if (pars.size() > 1)
6818
        color = pars[1];
6819
 
193 andreas 6820
    vector<TMap::MAP_T> map = findButtons(port, channels);
43 andreas 6821
 
6822
    if (TError::isError() || map.empty())
351 andreas 6823
    {
6824
#if TESTMODE == 1
6825
        setAllDone();
6826
#endif
43 andreas 6827
        return;
351 andreas 6828
    }
43 andreas 6829
 
6830
    vector<Button::TButton *> buttons = collectButtons(map);
6831
 
83 andreas 6832
    if (buttons.size() > 0)
43 andreas 6833
    {
83 andreas 6834
        vector<Button::TButton *>::iterator mapIter;
43 andreas 6835
 
83 andreas 6836
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
43 andreas 6837
        {
83 andreas 6838
            Button::TButton *bt = *mapIter;
351 andreas 6839
            bt->setBorderColor(color, btState - 1);
6840
#if TESTMODE == 1
6841
            if (_gTestMode)
6842
                _gTestMode->setResult(bt->getBorderColor(btState == 0 ? 0 : btState - 1));
6843
#endif
43 andreas 6844
        }
6845
    }
351 andreas 6846
#if TESTMODE == 1
6847
    setDone();
6848
#endif
43 andreas 6849
}
60 andreas 6850
 
351 andreas 6851
/*
6852
 * Get the border color and send it as a custom event.
6853
 */
82 andreas 6854
void TPageManager::getBCB(int port, vector<int> &channels, vector<string> &pars)
6855
{
6856
    DECL_TRACER("TPageManager::getBCB(int port, vector<int> &channels, vector<string> &pars)");
6857
 
6858
    if (pars.size() < 1)
6859
    {
6860
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 6861
#if TESTMODE == 1
6862
        setAllDone();
6863
#endif
82 andreas 6864
        return;
6865
    }
6866
 
6867
    TError::clear();
6868
    int btState = atoi(pars[0].c_str());
6869
    string color;
6870
 
193 andreas 6871
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 6872
 
6873
    if (TError::isError() || map.empty())
351 andreas 6874
    {
6875
#if TESTMODE == 1
6876
        setAllDone();
6877
#endif
82 andreas 6878
        return;
351 andreas 6879
    }
82 andreas 6880
 
6881
    vector<Button::TButton *> buttons = collectButtons(map);
6882
 
351 andreas 6883
    if (buttons.empty())
82 andreas 6884
    {
351 andreas 6885
#if TESTMODE == 1
6886
        setAllDone();
6887
#endif
6888
        return;
6889
    }
82 andreas 6890
 
351 andreas 6891
    vector<Button::TButton *>::iterator iter;
6892
 
6893
    for (iter = buttons.begin(); iter != buttons.end(); ++iter)
6894
    {
6895
        Button::TButton *bt = *iter;
6896
 
110 andreas 6897
        if (btState == 0)       // All instances?
82 andreas 6898
        {
110 andreas 6899
            int bst = bt->getNumberInstances();
82 andreas 6900
 
110 andreas 6901
            for (int i = 0; i < bst; i++)
82 andreas 6902
            {
110 andreas 6903
                color = bt->getBorderColor(i);
82 andreas 6904
 
110 andreas 6905
                if (color.empty())
6906
                    continue;
83 andreas 6907
 
300 andreas 6908
                sendCustomEvent(i + 1, (int)color.length(), 0, color, 1011, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 6909
#if TESTMODE == 1
6910
                __success = true;
6911
 
6912
                if (_gTestMode)
6913
                    _gTestMode->setResult(color);
6914
#endif
83 andreas 6915
            }
110 andreas 6916
        }
6917
        else
6918
        {
6919
            color = bt->getBorderColor(btState - 1);
83 andreas 6920
 
110 andreas 6921
            if (color.empty())
351 andreas 6922
                continue;
82 andreas 6923
 
300 andreas 6924
            sendCustomEvent(btState, (int)color.length(), 0, color, 1011, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 6925
#if TESTMODE == 1
6926
            __success = true;
6927
 
6928
            if (_gTestMode)
6929
                _gTestMode->setResult(color);
6930
#endif
82 andreas 6931
        }
6932
    }
351 andreas 6933
#if TESTMODE == 1
6934
    setAllDone();
6935
#endif
82 andreas 6936
}
6937
 
43 andreas 6938
/**
60 andreas 6939
 * @brief Set the fill color to the specified color.
6940
 * Only if the specified fill color is not the same as the current color.
6941
 * Note: Color can be assigned by color name (without spaces), number or R,G,B value (RRGGBB or RRGGBBAA).
15 andreas 6942
 */
60 andreas 6943
void TPageManager::doBCF(int port, vector<int>& channels, vector<std::string>& pars)
15 andreas 6944
{
60 andreas 6945
    DECL_TRACER("TPageManager::doBCF(int port, vector<int>& channels, vector<std::string>& pars)");
15 andreas 6946
 
60 andreas 6947
    if (pars.size() < 1)
15 andreas 6948
    {
60 andreas 6949
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 6950
#if TESTMODE == 1
6951
        setAllDone();
6952
#endif
12 andreas 6953
        return;
6954
    }
14 andreas 6955
 
16 andreas 6956
    TError::clear();
15 andreas 6957
    int btState = atoi(pars[0].c_str());
60 andreas 6958
    string color;
14 andreas 6959
 
60 andreas 6960
    if (pars.size() > 1)
6961
        color = pars[1];
6962
 
193 andreas 6963
    vector<TMap::MAP_T> map = findButtons(port, channels);
15 andreas 6964
 
6965
    if (TError::isError() || map.empty())
351 andreas 6966
    {
6967
#if TESTMODE == 1
6968
        setAllDone();
6969
#endif
15 andreas 6970
        return;
351 andreas 6971
    }
15 andreas 6972
 
6973
    vector<Button::TButton *> buttons = collectButtons(map);
6974
 
83 andreas 6975
    if (buttons.size() > 0)
15 andreas 6976
    {
83 andreas 6977
        vector<Button::TButton *>::iterator mapIter;
15 andreas 6978
 
83 andreas 6979
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
15 andreas 6980
        {
83 andreas 6981
            Button::TButton *bt = *mapIter;
351 andreas 6982
            bt->setFillColor(color, btState - 1);
6983
#if TESTMODE == 1
6984
            if (_gTestMode)
6985
                _gTestMode->setResult(bt->getFillColor(btState == 0 ? 0 : btState - 1));
6986
#endif
15 andreas 6987
        }
6988
    }
351 andreas 6989
#if TESTMODE == 1
6990
    setDone();
6991
#endif
12 andreas 6992
}
6993
 
351 andreas 6994
/*
6995
 * Get the fill color and send it via a custom event to the NetLinx.
6996
 */
82 andreas 6997
void TPageManager::getBCF(int port, vector<int> &channels, vector<string> &pars)
6998
{
6999
    DECL_TRACER("TPageManager::getBCF(int port, vector<int> &channels, vector<string> &pars)");
7000
 
7001
    if (pars.size() < 1)
7002
    {
7003
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7004
#if TESTMODE == 1
7005
        setAllDone();
7006
#endif
82 andreas 7007
        return;
7008
    }
7009
 
7010
    TError::clear();
7011
    int btState = atoi(pars[0].c_str());
7012
    string color;
7013
 
193 andreas 7014
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 7015
 
7016
    if (TError::isError() || map.empty())
351 andreas 7017
    {
7018
#if TESTMODE == 1
7019
        setAllDone();
7020
#endif
82 andreas 7021
        return;
351 andreas 7022
    }
82 andreas 7023
 
7024
    vector<Button::TButton *> buttons = collectButtons(map);
7025
 
351 andreas 7026
    if (buttons.empty())
82 andreas 7027
    {
351 andreas 7028
#if TESTMODE == 1
7029
        setAllDone();
7030
#endif
7031
        return;
7032
    }
82 andreas 7033
 
351 andreas 7034
    vector<Button::TButton *>::iterator iter;
7035
 
7036
    for (iter = buttons.begin(); iter != buttons.end(); ++iter)
7037
    {
7038
        Button::TButton *bt = *iter;
7039
 
110 andreas 7040
        if (btState == 0)       // All instances?
82 andreas 7041
        {
110 andreas 7042
            int bst = bt->getNumberInstances();
82 andreas 7043
 
110 andreas 7044
            for (int i = 0; i < bst; i++)
82 andreas 7045
            {
110 andreas 7046
                color = bt->getFillColor(i);
82 andreas 7047
 
110 andreas 7048
                if (color.empty())
7049
                    continue;
82 andreas 7050
 
300 andreas 7051
                sendCustomEvent(i + 1, (int)color.length(), 0, color, 1012, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 7052
#if TESTMODE == 1
7053
                __success = true;
7054
 
7055
                if (_gTestMode)
7056
                    _gTestMode->setResult(color);
7057
#endif
83 andreas 7058
            }
82 andreas 7059
        }
110 andreas 7060
        else
7061
        {
7062
            color = bt->getFillColor(btState-1);
351 andreas 7063
 
7064
            if (color.empty())
7065
                continue;
7066
 
300 andreas 7067
            sendCustomEvent(btState, (int)color.length(), 0, color, 1012, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 7068
#if TESTMODE == 1
7069
            __success = true;
7070
 
7071
            if (_gTestMode)
7072
                _gTestMode->setResult(color);
7073
#endif
110 andreas 7074
        }
82 andreas 7075
    }
351 andreas 7076
#if TESTMODE == 1
7077
    setAllDone();
7078
#endif
82 andreas 7079
}
7080
 
60 andreas 7081
/**
7082
 * @brief Set the text color to the specified color.
7083
 * Only if the specified text color is not the same as the current color.
7084
 * Note: Color can be assigned by color name (without spaces), number or R,G,B value (RRGGBB or RRGGBBAA).
7085
 */
7086
void TPageManager::doBCT(int port, vector<int>& channels, vector<string>& pars)
18 andreas 7087
{
60 andreas 7088
    DECL_TRACER("TPageManager::doBCT(int port, vector<int>& channels, vector<string>& pars)");
7089
 
7090
    if (pars.size() < 1)
7091
    {
7092
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7093
#if TESTMODE == 1
7094
        setAllDone();
7095
#endif
60 andreas 7096
        return;
7097
    }
7098
 
7099
    TError::clear();
7100
    int btState = atoi(pars[0].c_str());
7101
    string color;
7102
 
7103
    if (pars.size() > 1)
7104
        color = pars[1];
7105
 
193 andreas 7106
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 7107
 
7108
    if (TError::isError() || map.empty())
351 andreas 7109
    {
7110
#if TESTMODE == 1
7111
        setAllDone();
7112
#endif
60 andreas 7113
        return;
351 andreas 7114
    }
60 andreas 7115
 
7116
    vector<Button::TButton *> buttons = collectButtons(map);
7117
 
83 andreas 7118
    if (buttons.size() > 0)
60 andreas 7119
    {
83 andreas 7120
        vector<Button::TButton *>::iterator mapIter;
60 andreas 7121
 
83 andreas 7122
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 7123
        {
83 andreas 7124
            Button::TButton *bt = *mapIter;
351 andreas 7125
            bt->setTextColor(color, btState - 1);
7126
#if TESTMODE == 1
7127
            if (_gTestMode)
7128
                _gTestMode->setResult(bt->getTextColor(btState == 0 ? 0 : btState - 1));
7129
#endif
60 andreas 7130
        }
7131
    }
351 andreas 7132
#if TESTMODE == 1
7133
    setDone();
7134
#endif
18 andreas 7135
}
7136
 
351 andreas 7137
/*
7138
 * Get the text color of a button and send it via a custom event to the NetLinx.
7139
 */
82 andreas 7140
void TPageManager::getBCT(int port, vector<int> &channels, vector<string> &pars)
7141
{
7142
    DECL_TRACER("TPageManager::getBCT(int port, vector<int> &channels, vector<string> &pars)");
7143
 
7144
    if (pars.size() < 1)
7145
    {
7146
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7147
#if TESTMODE == 1
7148
        setAllDone();
7149
#endif
82 andreas 7150
        return;
7151
    }
7152
 
7153
    TError::clear();
7154
    int btState = atoi(pars[0].c_str());
7155
    string color;
7156
 
193 andreas 7157
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 7158
 
7159
    if (TError::isError() || map.empty())
351 andreas 7160
    {
7161
#if TESTMODE == 1
7162
        setAllDone();
7163
#endif
82 andreas 7164
        return;
351 andreas 7165
    }
82 andreas 7166
 
7167
    vector<Button::TButton *> buttons = collectButtons(map);
7168
 
351 andreas 7169
    if (buttons.empty())
82 andreas 7170
    {
351 andreas 7171
#if TESTMODE == 1
7172
        setAllDone();
7173
#endif
7174
        return;
7175
    }
82 andreas 7176
 
351 andreas 7177
    vector<Button::TButton *>::iterator iter;
7178
 
7179
    for (iter = buttons.begin(); iter != buttons.end(); ++iter)
7180
    {
7181
        Button::TButton *bt = *iter;
7182
 
110 andreas 7183
        if (btState == 0)       // All instances?
82 andreas 7184
        {
110 andreas 7185
            int bst = bt->getNumberInstances();
82 andreas 7186
 
110 andreas 7187
            for (int i = 0; i < bst; i++)
82 andreas 7188
            {
110 andreas 7189
                color = bt->getTextColor(i);
82 andreas 7190
 
110 andreas 7191
                if (color.empty())
7192
                    continue;
82 andreas 7193
 
300 andreas 7194
                sendCustomEvent(i + 1, (int)color.length(), 0, color, 1013, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 7195
#if TESTMODE == 1
7196
                __success = true;
7197
 
7198
                if (_gTestMode)
7199
                    _gTestMode->setResult(color);
7200
#endif
83 andreas 7201
            }
82 andreas 7202
        }
110 andreas 7203
        else
7204
        {
7205
            color = bt->getTextColor(btState - 1);
351 andreas 7206
 
7207
            if (color.empty())
7208
                continue;
7209
 
300 andreas 7210
            sendCustomEvent(btState, (int)color.length(), 0, color, 1013, bt->getChannelPort(), bt->getChannelNumber());
351 andreas 7211
#if TESTMODE == 1
7212
            __success = true;
7213
 
7214
            if (_gTestMode)
7215
                _gTestMode->setResult(color);
7216
#endif
110 andreas 7217
        }
82 andreas 7218
    }
351 andreas 7219
#if TESTMODE == 1
7220
    setAllDone();
7221
#endif
82 andreas 7222
}
7223
 
60 andreas 7224
/**
7225
 * Set the button draw order
7226
 * Determines what order each layer of the button is drawn.
7227
 */
7228
void TPageManager::doBDO(int port, vector<int>& channels, vector<std::string>& pars)
32 andreas 7229
{
60 andreas 7230
    DECL_TRACER("TPageManager::doBDO(int port, vector<int>& channels, vector<std::string>& pars)");
32 andreas 7231
 
60 andreas 7232
    if (pars.size() < 1)
7233
    {
7234
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7235
#if TESTMODE == 1
7236
        setAllDone();
7237
#endif
32 andreas 7238
        return;
60 andreas 7239
    }
32 andreas 7240
 
60 andreas 7241
    TError::clear();
7242
    int btState = atoi(pars[0].c_str());
7243
    string order;
32 andreas 7244
 
60 andreas 7245
    if (pars.size() > 1)
7246
    {
7247
        string ord = pars[1];
7248
        // Convert the numbers into the expected draw order
7249
        for (size_t i = 0; i < ord.length(); i++)
7250
        {
7251
            if (ord.at(i) >= '1' && ord.at(i) <= '5')
7252
            {
7253
                char hv0[32];
7254
                snprintf(hv0, sizeof(hv0), "%02d", (int)(ord.at(i) - '0'));
7255
                order.append(hv0);
7256
            }
7257
            else
7258
            {
7259
                MSG_ERROR("Illegal order number " << ord.substr(i, 1) << "!");
7260
                return;
7261
            }
7262
        }
7263
 
7264
        if (order.length() != 10)
7265
        {
7266
            MSG_ERROR("Expected 5 order numbers but got " << (order.length() / 2)<< "!");
7267
            return;
7268
        }
7269
    }
7270
 
193 andreas 7271
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 7272
 
7273
    if (TError::isError() || map.empty())
351 andreas 7274
    {
7275
#if TESTMODE == 1
7276
        setAllDone();
7277
#endif
32 andreas 7278
        return;
351 andreas 7279
    }
32 andreas 7280
 
60 andreas 7281
    vector<Button::TButton *> buttons = collectButtons(map);
7282
 
83 andreas 7283
    if (buttons.size() > 0)
32 andreas 7284
    {
83 andreas 7285
        vector<Button::TButton *>::iterator mapIter;
32 andreas 7286
 
83 andreas 7287
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 7288
        {
83 andreas 7289
            Button::TButton *bt = *mapIter;
351 andreas 7290
            bt->setDrawOrder(order, btState - 1);
7291
#if TESTMODE == 1
7292
            if (_gTestMode)
7293
                _gTestMode->setResult(bt->getDrawOrder(btState == 0 ? 0 : btState - 1));
7294
#endif
60 andreas 7295
        }
7296
    }
351 andreas 7297
#if TESTMODE == 1
7298
    setDone();
7299
#endif
60 andreas 7300
}
32 andreas 7301
 
60 andreas 7302
/**
7303
 * Set the feedback type of the button.
7304
 * ONLY works on General-type buttons.
7305
 */
7306
void TPageManager::doBFB(int port, vector<int>& channels, vector<std::string>& pars)
7307
{
7308
    DECL_TRACER("TPageManager::doBFB(int port, vector<int>& channels, vector<std::string>& pars)");
32 andreas 7309
 
60 andreas 7310
    if (pars.size() < 1)
7311
    {
7312
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7313
#if TESTMODE == 1
7314
        setAllDone();
7315
#endif
60 andreas 7316
        return;
7317
    }
7318
 
7319
    TError::clear();
7320
    Button::FEEDBACK type = Button::FB_NONE;
7321
    string stype = pars[0];
7322
    vector<string> stypes = { "None", "Channel", "Invert", "On", "Momentary", "Blink" };
7323
    vector<string>::iterator iter;
7324
    int i = 0;
7325
 
7326
    for (iter = stypes.begin(); iter != stypes.end(); ++iter)
7327
    {
7328
        if (strCaseCompare(stype, *iter) == 0)
33 andreas 7329
        {
60 andreas 7330
            type = (Button::FEEDBACK)i;
7331
            break;
32 andreas 7332
        }
60 andreas 7333
 
7334
        i++;
32 andreas 7335
    }
7336
 
193 andreas 7337
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 7338
 
7339
    if (TError::isError() || map.empty())
351 andreas 7340
    {
7341
#if TESTMODE == 1
7342
        setAllDone();
7343
#endif
60 andreas 7344
        return;
351 andreas 7345
    }
60 andreas 7346
 
7347
    vector<Button::TButton *> buttons = collectButtons(map);
7348
 
83 andreas 7349
    if (buttons.size() > 0)
60 andreas 7350
    {
83 andreas 7351
        vector<Button::TButton *>::iterator mapIter;
7352
 
7353
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
7354
        {
7355
            Button::TButton *bt = *mapIter;
7356
            bt->setFeedback(type);
351 andreas 7357
#if TESTMODE == 1
7358
            if (_gTestMode)
7359
                _gTestMode->setResult(intToString(bt->getFeedback()));
7360
#endif
83 andreas 7361
        }
60 andreas 7362
    }
335 andreas 7363
#if TESTMODE == 1
7364
    setDone();
7365
#endif
32 andreas 7366
}
7367
 
224 andreas 7368
/*
7369
 * Set the input mask for the specified address.
7370
 */
7371
void TPageManager::doBIM(int port, vector<int>& channels, vector<std::string>& pars)
7372
{
7373
    DECL_TRACER("TPageManager::doBIM(int port, vector<int>& channels, vector<std::string>& pars)");
7374
 
7375
    if (pars.size() < 1)
7376
    {
7377
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
351 andreas 7378
#if TESTMODE == 1
7379
        setAllDone();
7380
#endif
224 andreas 7381
        return;
7382
    }
7383
 
7384
    TError::clear();
7385
    string mask = pars[0];
7386
    vector<TMap::MAP_T> map = findButtons(port, channels);
7387
 
7388
    if (TError::isError() || map.empty())
351 andreas 7389
    {
7390
#if TESTMODE == 1
7391
        setAllDone();
7392
#endif
224 andreas 7393
        return;
351 andreas 7394
    }
224 andreas 7395
 
7396
    vector<Button::TButton *> buttons = collectButtons(map);
7397
 
7398
    if (buttons.size() > 0)
7399
    {
7400
        vector<Button::TButton *>::iterator mapIter;
7401
 
7402
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
7403
        {
7404
            Button::TButton *bt = *mapIter;
7405
            bt->setInputMask(mask);
351 andreas 7406
#if TESTMODE == 1
7407
            if (_gTestMode)
7408
                _gTestMode->setResult(bt->getInputMask());
7409
#endif
224 andreas 7410
        }
7411
    }
351 andreas 7412
#if TESTMODE == 1
7413
    setDone();
7414
#endif
224 andreas 7415
}
7416
 
351 andreas 7417
/**
7418
 * @brief Button copy command.
7419
 * Copy attributes of the source button to all the
7420
 * destination buttons. Note that the source is a single button state. Each
7421
 * state must be copied as a separate command. The <codes> section represents
7422
 * what attributes will be copied. All codes are 2 char pairs that can be
7423
 * separated by comma, space, percent or just ran together.
7424
 */
106 andreas 7425
void TPageManager::doBMC(int port, vector<int>& channels, vector<std::string>& pars)
7426
{
7427
    DECL_TRACER("TPageManager::doBMC(int port, vector<int>& channels, vector<std::string>& pars)");
7428
 
7429
    if (pars.size() < 5)
7430
    {
7431
        MSG_ERROR("Expecting 5 parameters but got " << pars.size() << ". Ignoring command.");
351 andreas 7432
#if TESTMODE == 1
7433
        setAllDone();
7434
#endif
106 andreas 7435
        return;
7436
    }
7437
 
7438
    TError::clear();
7439
    int btState = atoi(pars[0].c_str());
7440
    int src_port = atoi(pars[1].c_str());
7441
    int src_addr = atoi(pars[2].c_str());
7442
    int src_state = atoi(pars[3].c_str());
7443
    string src_codes = pars[4];
7444
    vector<int> src_channel;
7445
    src_channel.push_back(src_addr);
7446
 
193 andreas 7447
    vector<TMap::MAP_T> src_map = findButtons(src_port, src_channel);
106 andreas 7448
 
7449
    if (src_map.size() == 0)
7450
    {
7451
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " does not exist!");
351 andreas 7452
#if TESTMODE == 1
7453
        setAllDone();
7454
#endif
106 andreas 7455
        return;
7456
    }
7457
 
7458
    vector<Button::TButton *>src_buttons = collectButtons(src_map);
7459
 
7460
    if (src_buttons.size() == 0)
7461
    {
7462
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " does not exist!");
351 andreas 7463
#if TESTMODE == 1
7464
        setAllDone();
7465
#endif
106 andreas 7466
        return;
7467
    }
7468
 
7469
    if (src_buttons[0]->getNumberInstances() < src_state)
7470
    {
7471
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " has less then " << src_state << " elements.");
351 andreas 7472
#if TESTMODE == 1
7473
        setAllDone();
7474
#endif
106 andreas 7475
        return;
7476
    }
7477
 
7478
    if (src_state < 1)
7479
    {
7480
        MSG_WARNING("Button <" << TConfig::getChannel() << ":" << src_port << ":" << TConfig::getSystem() << ">:" << src_addr << " has invalid source state " << src_state << ".");
351 andreas 7481
#if TESTMODE == 1
7482
        setAllDone();
7483
#endif
106 andreas 7484
        return;
7485
    }
7486
 
7487
    src_state--;
7488
 
7489
    if (btState > 0)
7490
        btState--;
7491
 
193 andreas 7492
    vector<TMap::MAP_T> map = findButtons(port, channels);
106 andreas 7493
    vector<Button::TButton *> buttons = collectButtons(map);
7494
    //                        0     1     2     3     4     5     6     7
7495
    vector<string>codes = { "BM", "BR", "CB", "CF", "CT", "EC", "EF", "FT",
7496
                            "IC", "JB", "JI", "JT", "LN", "OP", "SO", "TX", // 8 - 15
7497
                            "VI", "WW" };   // 16, 17
7498
 
7499
    for (size_t ibuttons = 0; ibuttons < buttons.size(); ibuttons++)
7500
    {
7501
        vector<string>::iterator iter;
7502
        int idx = 0;
7503
 
7504
        for (iter = codes.begin(); iter != codes.end(); ++iter)
7505
        {
7506
            if (src_codes.find(*iter) != string::npos)
7507
            {
7508
                int j, x, y;
7509
 
7510
                switch(idx)
7511
                {
7512
                    case 0: buttons[ibuttons]->setBitmap(src_buttons[0]->getBitmapName(src_state), btState); break;
7513
                    case 1: buttons[ibuttons]->setBorderStyle(src_buttons[0]->getBorderStyle(src_state), btState); break;
7514
                    case 2: buttons[ibuttons]->setBorderColor(src_buttons[0]->getBorderColor(src_state), btState); break;
7515
                    case 3: buttons[ibuttons]->setFillColor(src_buttons[0]->getFillColor(src_state), btState); break;
7516
                    case 4: buttons[ibuttons]->setTextColor(src_buttons[0]->getTextColor(src_state), btState); break;
7517
                    case 5: buttons[ibuttons]->setTextEffectColor(src_buttons[0]->getTextEffectColor(src_state), btState); break;
7518
                    case 6: buttons[ibuttons]->setTextEffect(src_buttons[0]->getTextEffect(src_state), btState); break;
7519
                    case 7: buttons[ibuttons]->setFontIndex(src_buttons[0]->getFontIndex(src_state), btState); break;
110 andreas 7520
                    case 8: buttons[ibuttons]->setIcon(src_buttons[0]->getIconIndex(src_state), btState); break;
106 andreas 7521
 
7522
                    case 9:
7523
                        j = src_buttons[0]->getBitmapJustification(&x, &y, src_state);
7524
                        buttons[ibuttons]->setBitmapJustification(j, x, y, btState);
7525
                    break;
7526
 
7527
                    case 10:
7528
                        j = src_buttons[0]->getIconJustification(&x, &y, src_state);
7529
                        buttons[ibuttons]->setIconJustification(j, x, y, btState);
7530
                    break;
7531
 
7532
                    case 11:
7533
                        j = src_buttons[0]->getTextJustification(&x, &y, src_state);
7534
                        buttons[ibuttons]->setTextJustification(j, x, y, btState);
7535
                    break;
7536
 
7537
                    case 12: MSG_INFO("\"Lines of video removed\" not supported!"); break;
7538
                    case 13: buttons[ibuttons]->setOpacity(src_buttons[0]->getOpacity(src_state), btState); break;
7539
                    case 14: buttons[ibuttons]->setSound(src_buttons[0]->getSound(src_state), btState); break;
7540
                    case 15: buttons[ibuttons]->setText(src_buttons [0]->getText(src_state), btState); break;
7541
                    case 16: MSG_INFO("\"Video slot ID\" not supported!"); break;
7542
                    case 17: buttons[ibuttons]->setTextWordWrap(src_buttons[0]->getTextWordWrap(src_state), btState); break;
7543
                }
7544
            }
7545
 
7546
            idx++;
7547
        }
7548
    }
7549
}
7550
 
149 andreas 7551
void TPageManager::doBMF (int port, vector<int>& channels, vector<string>& pars)
7552
{
7553
    DECL_TRACER("TPageManager::doBMF (int port, vector<int>& channels, vector<string>& pars)");
7554
 
7555
    if (pars.size() < 2)
332 andreas 7556
    {
7557
        MSG_ERROR("Less then 2 parameters!");
7558
#if TESTMODE == 1
334 andreas 7559
        setAllDone();
332 andreas 7560
#endif
149 andreas 7561
        return;
332 andreas 7562
    }
149 andreas 7563
 
7564
    TError::clear();
7565
    int btState = atoi(pars[0].c_str()) - 1;
150 andreas 7566
    string commands;
149 andreas 7567
 
150 andreas 7568
    for (size_t i = 1; i < pars.size(); ++i)
7569
    {
7570
        if (i > 1)
7571
            commands += ",";
7572
 
7573
        commands += pars[i];
7574
    }
7575
 
193 andreas 7576
    vector<TMap::MAP_T> map = findButtons(port, channels);
149 andreas 7577
 
7578
    if (TError::isError() || map.empty())
332 andreas 7579
    {
7580
#if TESTMODE == 1
334 andreas 7581
        setAllDone();
332 andreas 7582
#endif
149 andreas 7583
        return;
332 andreas 7584
    }
149 andreas 7585
 
7586
    // Start of parsing the command line
162 andreas 7587
    // We splitt the command line into parts by searching for a percent (%) sign.
149 andreas 7588
    vector<string> parts = StrSplit(commands, "%");
7589
 
162 andreas 7590
    if (parts.empty())
332 andreas 7591
        parts.push_back(commands);
334 andreas 7592
 
149 andreas 7593
    // Search for all buttons who need to be updated
7594
    vector<Button::TButton *> buttons = collectButtons(map);
7595
 
7596
    if (buttons.size() > 0)
7597
    {
7598
        vector<Button::TButton *>::iterator mapIter;
7599
 
7600
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
7601
        {
7602
            Button::TButton *bt = *mapIter;
162 andreas 7603
 
7604
            if (!bt)
7605
            {
7606
                MSG_WARNING("Command ^BMF found an invalid pointer to a button!")
7607
                continue;
7608
            }
7609
 
149 andreas 7610
            // Iterate through commands and apply them to button
7611
            vector<string>::iterator iter;
7612
 
7613
            for (iter = parts.begin(); iter != parts.end(); ++iter)
7614
            {
7615
                char cmd = iter->at(0);
7616
                char cmd2;
7617
                string content;
7618
 
7619
                switch(cmd)
7620
                {
7621
                    case 'B':   // Border style
361 andreas 7622
                        if (iter->at(1) == ',')
7623
                            content = iter->substr(2);
7624
                        else
7625
                            content = iter->substr(1);
332 andreas 7626
 
7627
                        if (!content.empty() && isdigit(content[0]))
334 andreas 7628
                            bt->setBorderStyle(atoi(content.c_str()), btState);
332 andreas 7629
                        else
7630
                            bt->setBorderStyle(content, btState);
7631
#if TESTMODE == 1
7632
                        if (_gTestMode)
7633
                            _gTestMode->setResult(bt->getBorderStyle(btState < 0 ? 0 : btState));
7634
#endif
149 andreas 7635
                    break;
7636
 
7637
                    case 'C':   // Colors
7638
                        cmd2 = iter->at(1);
7639
                        content = iter->substr(2);
7640
 
7641
                        switch(cmd2)
7642
                        {
7643
                            case 'B':   // Border color
7644
                                bt->setBorderColor(content, btState);
332 andreas 7645
#if TESTMODE == 1
7646
                                if (_gTestMode)
7647
                                    _gTestMode->setResult(bt->getBorderColor(btState < 0 ? 0 : btState));
7648
#endif
149 andreas 7649
                            break;
7650
 
7651
                            case 'F':   // Fill color
7652
                                bt->setFillColor(content, btState);
332 andreas 7653
#if TESTMODE == 1
7654
                                if (_gTestMode)
7655
                                    _gTestMode->setResult(bt->getFillColor(btState < 0 ? 0 : btState));
7656
#endif
149 andreas 7657
                            break;
7658
 
7659
                            case 'T':   // Text color
7660
                                bt->setTextColor(content, btState);
332 andreas 7661
#if TESTMODE == 1
7662
                                if (_gTestMode)
7663
                                    _gTestMode->setResult(bt->getTextColor(btState < 0 ? 0 : btState));
7664
#endif
149 andreas 7665
                            break;
7666
                        }
7667
                    break;
7668
 
150 andreas 7669
                    case 'D':   // Draw order
7670
                        cmd2 = iter->at(1);
7671
                        content = iter->substr(2);
7672
 
7673
                        if (cmd2 == 'O')
332 andreas 7674
                        {
150 andreas 7675
                            bt->setDrawOrder(content, btState);
332 andreas 7676
#if TESTMODE == 1
7677
                            if (_gTestMode)
7678
                                _gTestMode->setResult(bt->getDrawOrder(btState < 0 ? 0 : btState));
7679
#endif
7680
                        }
150 andreas 7681
                    break;
7682
 
149 andreas 7683
                    case 'E':   // Text effect
7684
                        cmd2 = iter->at(1);
7685
                        content = iter->substr(2);
7686
 
7687
                        switch(cmd2)
7688
                        {
7689
                            case 'C':   // Text effect color
7690
                                bt->setTextEffectColor(content, btState);
332 andreas 7691
#if TESTMODE == 1
7692
                                if (_gTestMode)
7693
                                    _gTestMode->setResult(bt->getTextEffectColor(btState < 0 ? 0 : btState));
7694
#endif
149 andreas 7695
                            break;
7696
 
7697
                            case 'F':   // Text effect name
7698
                                bt->setTextEffectName(content, btState);
332 andreas 7699
#if TESTMODE == 1
7700
                                if (_gTestMode)
7701
                                    _gTestMode->setResult(bt->getTextEffectName(btState < 0 ? 0 : btState));
7702
#endif
149 andreas 7703
                            break;
7704
 
7705
                            case 'N':   // Enable/disable button
7706
                                bt->setEnable((content[0] == '1' ? true : false));
332 andreas 7707
#if TESTMODE == 1
7708
                                if (_gTestMode)
334 andreas 7709
                                {
332 andreas 7710
                                    _gTestMode->setResult(bt->isEnabled() ? "TRUE" : "FALSE");
334 andreas 7711
                                    __success = true;
7712
                                    setScreenDone();
7713
                                }
332 andreas 7714
#endif
149 andreas 7715
                            break;
7716
                        }
7717
                    break;
7718
 
7719
                    case 'F':   // Set font file name
361 andreas 7720
                        if (iter->at(1) == ',')
7721
                            content = iter->substr(2);
7722
                        else
7723
                            content = iter->substr(1);
150 andreas 7724
 
7725
                        if (!isdigit(content[0]))
334 andreas 7726
                            bt->setFontName(content, btState);
150 andreas 7727
                        else
7728
                            bt->setFontIndex(atoi(content.c_str()), btState);
334 andreas 7729
#if TESTMODE == 1
7730
                        if (_gTestMode)
7731
                            _gTestMode->setResult(intToString(bt->getFontIndex(btState < 0 ? 0 : btState)));
7732
#endif
149 andreas 7733
                    break;
7734
 
7735
                    case 'G':   // Bargraphs
7736
                        cmd2 = iter->at(1);
7737
                        content = iter->substr(2);
7738
 
7739
                        switch(cmd2)
7740
                        {
7741
                            case 'C':   // Bargraph slider color
7742
                                bt->setBargraphSliderColor(content);
7743
                            break;
7744
 
7745
                            case 'D':   // Ramp down time
387 andreas 7746
                                bt->setBargraphRampDownTime(atoi(content.c_str()));
149 andreas 7747
                            break;
7748
 
7749
                            case 'G':   // Drag increment
387 andreas 7750
                                bt->setBargraphDragIncrement(atoi(content.c_str()));
149 andreas 7751
                            break;
7752
 
7753
                            case 'H':   // Upper limit
7754
                                bt->setBargraphUpperLimit(atoi(content.c_str()));
7755
                            break;
7756
 
7757
                            case 'I':   // Invert/noninvert
387 andreas 7758
                                if (bt->getButtonType() == BARGRAPH || bt->getButtonType() == MULTISTATE_BARGRAPH)
7759
                                    bt->setBargraphInvert(atoi(content.c_str()) > 0 ? true : false);
149 andreas 7760
                            break;
7761
 
7762
                            case 'L':   // Lower limit
7763
                                bt->setBargraphLowerLimit(atoi(content.c_str()));
7764
                            break;
7765
 
7766
                            case 'N':   // Slider name
361 andreas 7767
                                bt->setBargraphSliderName(content);
149 andreas 7768
                            break;
7769
 
7770
                            case 'R':   // Repeat interval
7771
                                // FIXME: Add function to set repeat interval
7772
                            break;
7773
 
7774
                            case 'U':   // Ramp up time
387 andreas 7775
                                bt->setBargraphRampUpTime(atoi(content.c_str()));
149 andreas 7776
                            break;
7777
 
7778
                            case 'V':   // Bargraph value
387 andreas 7779
                                bt->setBargraphLevel(atoi(content.c_str()));
149 andreas 7780
                            break;
7781
                        }
7782
                    break;
7783
 
152 andreas 7784
                    case 'I':   // Set the icon
7785
                        content = iter->substr(1);
7786
                        bt->setIcon(atoi(content.c_str()), btState);
332 andreas 7787
#if TESTMODE == 1
7788
                        if (_gTestMode)
7789
                            _gTestMode->setResult(intToString(bt->getIconIndex()));
7790
#endif
152 andreas 7791
                    break;
7792
 
149 andreas 7793
                    case 'J':   // Set text justification
150 andreas 7794
                        cmd2 = iter->at(1);
7795
 
361 andreas 7796
                        if (cmd2 == ',')
150 andreas 7797
                        {
7798
                            content = iter->substr(1);
152 andreas 7799
                            int just = atoi(content.c_str());
7800
                            int x = 0, y = 0;
7801
 
7802
                            if (just == 0)
7803
                            {
7804
                                vector<string> coords = StrSplit(content, ",");
7805
 
7806
                                if (coords.size() >= 3)
7807
                                {
7808
                                    x = atoi(coords[1].c_str());
7809
                                    y = atoi(coords[2].c_str());
7810
                                }
7811
                            }
7812
 
7813
                            bt->setTextJustification(atoi(content.c_str()), x, y, btState);
334 andreas 7814
#if TESTMODE == 1
7815
                            if (_gTestMode)
7816
                            {
7817
                                just = bt->getTextJustification(&x, &y, btState < 0 ? 0 : btState);
7818
                                string s = intToString(just) + "," + intToString(x) + "," + intToString(y);
7819
                                _gTestMode->setResult(s);
7820
                            }
7821
#endif
150 andreas 7822
                        }
361 andreas 7823
                        else if (cmd2 == 'T' || cmd2 == 'B' || cmd2 == 'I')
150 andreas 7824
                        {
7825
                            content = iter->substr(2);
152 andreas 7826
                            int x = 0, y = 0;
7827
                            int just = atoi(content.c_str());
150 andreas 7828
 
152 andreas 7829
                            if (just == 0)
7830
                            {
7831
                                vector<string> coords = StrSplit(content, ",");
7832
 
7833
                                if (coords.size() >= 3)
7834
                                {
7835
                                    x = atoi(coords[1].c_str());
7836
                                    y = atoi(coords[2].c_str());
7837
                                }
7838
                            }
7839
 
150 andreas 7840
                            switch(cmd2)
7841
                            {
7842
                                case 'B':   // Alignment of bitmap
152 andreas 7843
                                    bt->setBitmapJustification(atoi(content.c_str()), x, y, btState);
334 andreas 7844
#if TESTMODE == 1
7845
                                    just = bt->getBitmapJustification(&x, &y, btState < 0 ? 0 : btState);
7846
#endif
150 andreas 7847
                                break;
7848
 
7849
                                case 'I':   // Alignment of icon
152 andreas 7850
                                    bt->setIconJustification(atoi(content.c_str()), x, y, btState);
334 andreas 7851
#if TESTMODE == 1
7852
                                    just = bt->getIconJustification(&x, &y, btState < 0 ? 0 : btState);
7853
#endif
150 andreas 7854
                                break;
7855
 
7856
                                case 'T':   // Alignment of text
152 andreas 7857
                                    bt->setTextJustification(atoi(content.c_str()), x, y, btState);
334 andreas 7858
#if TESTMODE == 1
7859
                                    just = bt->getTextJustification(&x, &y, btState < 0 ? 0 : btState);
7860
#endif
150 andreas 7861
                                break;
7862
                            }
334 andreas 7863
#if TESTMODE == 1
7864
                            if (_gTestMode)
7865
                            {
7866
                                string s = intToString(just) + "," + intToString(x) + "," + intToString(y);
7867
                                _gTestMode->setResult(s);
7868
                            }
7869
#endif
150 andreas 7870
                        }
7871
                    break;
7872
 
7873
                    case 'M':   // Text area
7874
                        cmd2 = iter->at(1);
7875
                        content = iter->substr(2);
7876
 
7877
                        switch(cmd2)
7878
                        {
152 andreas 7879
                            case 'I':   // Set mask image
7880
                                // FIXME: Add code for image mask
7881
                            break;
7882
 
150 andreas 7883
                            case 'K':   // Input mask of text area
7884
                                // FIXME: Add input mask
7885
                            break;
7886
 
7887
                            case 'L':   // Maximum length of text area
7888
                                // FIXME: Add code to set maximum length
7889
                            break;
7890
                        }
7891
                    break;
7892
 
7893
                    case 'O':   // Set feedback typ, opacity
7894
                        cmd2 = iter->at(1);
7895
 
7896
                        switch(cmd2)
7897
                        {
7898
                            case 'P':   // Set opacity
7899
                                bt->setOpacity(atoi(iter->substr(2).c_str()), btState);
7900
                            break;
7901
 
7902
                            case 'T':   // Set feedback type
7903
                                content = iter->substr(2);
7904
                                content = toUpper(content);
7905
 
7906
                                if (content == "NONE")
7907
                                    bt->setFeedback(Button::FB_NONE);
7908
                                else if (content == "CHANNEL")
7909
                                    bt->setFeedback(Button::FB_CHANNEL);
7910
                                else if (content == "INVERT")
7911
                                    bt->setFeedback(Button::FB_INV_CHANNEL);
7912
                                else if (content == "ON")
7913
                                    bt->setFeedback(Button::FB_ALWAYS_ON);
7914
                                else if (content == "MOMENTARY")
7915
                                    bt->setFeedback(Button::FB_MOMENTARY);
7916
                                else if (content == "BLINK")
7917
                                    bt->setFeedback(Button::FB_BLINK);
7918
                                else
7919
                                {
7920
                                    MSG_WARNING("Unknown feedback type " << content);
7921
                                }
335 andreas 7922
#if TESTMODE == 1
7923
                                if (_gTestMode)
7924
                                    _gTestMode->setResult(intToString(bt->getFeedback()));
7925
#endif
150 andreas 7926
                            break;
7927
 
7928
                            default:
7929
                                content = iter->substr(1);
7930
                                // FIXME: Add code to set the feedback type
7931
                        }
7932
                    break;
7933
 
152 andreas 7934
                    case 'P':   // Set picture/bitmap file name
7935
                        content = iter->substr(1);
165 andreas 7936
 
7937
                        if (content.find(".") == string::npos)  // If the image has no extension ...
7938
                        {                                       // we must find the image in the map
7939
                            string iname = findImage(content);
7940
 
7941
                            if (!iname.empty())
7942
                                content = iname;
7943
                        }
7944
 
152 andreas 7945
                        bt->setBitmap(content, btState);
7946
                    break;
7947
 
7948
                    case 'R':   // Set rectangle
7949
                    {
7950
                        content = iter->substr(1);
7951
                        vector<string> corners = StrSplit(content, ",");
7952
 
7953
                        if (corners.size() > 0)
7954
                        {
7955
                            vector<string>::iterator itcorn;
7956
                            int pos = 0;
7957
                            int left, top, right, bottom;
7958
                            left = top = right = bottom = 0;
7959
 
7960
                            for (itcorn = corners.begin(); itcorn != corners.end(); ++itcorn)
7961
                            {
7962
                                switch(pos)
7963
                                {
7964
                                    case 0: left   = atoi(itcorn->c_str()); break;
7965
                                    case 1: top    = atoi(itcorn->c_str()); break;
7966
                                    case 2: right  = atoi(itcorn->c_str()); break;
7967
                                    case 3: bottom = atoi(itcorn->c_str()); break;
7968
                                }
7969
 
7970
                                pos++;
7971
                            }
7972
 
7973
                            if (pos >= 4)
334 andreas 7974
                            {
152 andreas 7975
                                bt->setRectangle(left, top, right, bottom);
334 andreas 7976
                                bt->refresh();
7977
                            }
152 andreas 7978
                        }
334 andreas 7979
#if TESTMODE == 1
7980
                        if (_gTestMode)
7981
                        {
7982
                            int left, top, width, height;
7983
                            bt->getRectangle(&left, &top, &height, &width);
7984
                            string res(intToString(left) + "," + intToString(top) + "," + intToString(width) + "," + intToString(height));
7985
                            _gTestMode->setResult(res);
7986
                        }
7987
#endif
152 andreas 7988
                    }
7989
                    break;
7990
 
150 andreas 7991
                    case 'S':   // show/hide, style, sound
7992
                        cmd2 = iter->at(1);
7993
                        content = iter->substr(2);
7994
 
7995
                        switch(cmd2)
7996
                        {
7997
                            case 'F':   // Set focus of text area button
7998
                                // FIXME: Add code to set the focus of text area button
7999
                            break;
8000
 
8001
                            case 'M':   // Submit text
169 andreas 8002
                                if (content.find("|"))  // To be replaced by LF (0x0a)?
8003
                                {
8004
                                    size_t pos = 0;
8005
 
8006
                                    while ((pos = content.find("|")) != string::npos)
8007
                                        content = content.replace(pos, 1, "\n");
8008
                                }
8009
 
150 andreas 8010
                                bt->setText(content, btState);
8011
                            break;
8012
 
8013
                            case 'O':   // Sound
8014
                                bt->setSound(content, btState);
335 andreas 8015
#if TESTMODE == 1
8016
                                if (_gTestMode)
8017
                                    _gTestMode->setResult(bt->getSound(btState < 0 ? 0 : btState));
8018
#endif
150 andreas 8019
                            break;
8020
 
8021
                            case 'T':   // Button style
8022
                                // FIXME: Add code to set the button style
8023
                            break;
8024
 
8025
                            case 'W':   // Show / hide button
8026
                                if (content[0] == '0')
334 andreas 8027
                                    bt->hide(true);
150 andreas 8028
                                else
8029
                                    bt->show();
334 andreas 8030
#if TESTMODE == 1
8031
                                if (_gTestMode)
8032
                                    _gTestMode->setResult(bt->isVisible() ? "TRUE" : "FALSE");
8033
#endif
150 andreas 8034
                            break;
8035
                        }
8036
                    break;
8037
 
152 andreas 8038
                    case 'T':   // Set text
8039
                        content = iter->substr(1);
169 andreas 8040
 
8041
                        if (content.find("|"))  // To be replaced by LF (0x0a)?
8042
                        {
8043
                            size_t pos = 0;
8044
 
8045
                            while ((pos = content.find("|")) != string::npos)
8046
                                content = content.replace(pos, 1, "\n");
8047
                        }
8048
 
152 andreas 8049
                        bt->setText(content, btState);
334 andreas 8050
#if TESTMODE == 1
8051
                        if (_gTestMode)
8052
                            _gTestMode->setResult(bt->getText(btState < 0 ? 0 : btState));
8053
#endif
152 andreas 8054
                    break;
8055
 
150 andreas 8056
                    case 'U':   // Set the unicode text
8057
                        if (iter->at(1) == 'N')
8058
                        {
8059
                            content = iter->substr(2);
152 andreas 8060
                            string byte, text;
8061
                            size_t pos = 0;
8062
 
8063
                            while (pos < content.length())
8064
                            {
8065
                                byte = content.substr(pos, 2);
8066
                                char ch = (char)strtol(byte.c_str(), NULL, 16);
8067
                                text += ch;
8068
                                pos += 2;
8069
                            }
8070
 
169 andreas 8071
                            if (text.find("|"))  // To be replaced by LF (0x0a)?
8072
                            {
8073
                                size_t pos = 0;
8074
 
8075
                                while ((pos = text.find("|")) != string::npos)
8076
                                    text = text.replace(pos, 1, "\n");
8077
                            }
8078
 
152 andreas 8079
                            bt->setText(text, btState);
150 andreas 8080
                        }
8081
                    break;
8082
 
8083
                    case 'V':   // Video on / off
8084
                        cmd2 = iter->at(1);
8085
                        // Controlling a computer remotely is not supported.
8086
                        if (cmd2 != 'L' && cmd2 != 'N' && cmd2 != 'P')
8087
                        {
8088
                            content = iter->substr(2);
8089
                            // FIXME: Add code to switch video on or off
8090
                        }
8091
                    break;
8092
 
8093
                    case 'W':   // Word wrap
152 andreas 8094
                        if (iter->at(1) == 'W')
8095
                        {
8096
                            content = iter->substr(2);
8097
                            bt->setTextWordWrap(content[0] == '1' ? true : false, btState);
8098
                        }
149 andreas 8099
                    break;
8100
                }
8101
            }
8102
        }
8103
    }
332 andreas 8104
#if TESTMODE == 1
334 andreas 8105
    setDone();
332 andreas 8106
#endif
149 andreas 8107
}
8108
 
14 andreas 8109
/**
110 andreas 8110
 * Set the maximum length of the text area button. If this value is set to
8111
 * zero (0), the text area has no max length. The maximum length available is
8112
 * 2000. This is only for a Text area input button and not for a Text area input
8113
 * masking button.
8114
 */
8115
void TPageManager::doBML(int port, vector<int>& channels, vector<string>& pars)
8116
{
8117
    DECL_TRACER("TPageManager::doBML(int port, vector<int>& channels, vector<string>& pars)");
8118
 
8119
    if (pars.size() < 1)
8120
    {
8121
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
8122
        return;
8123
    }
8124
 
8125
    TError::clear();
8126
    int maxLen = atoi(pars[0].c_str());
8127
 
8128
    if (maxLen < 0 || maxLen > 2000)
8129
    {
8130
        MSG_WARNING("Got illegal length of text area! [" << maxLen << "]");
8131
        return;
8132
    }
8133
 
193 andreas 8134
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 8135
 
8136
    if (TError::isError() || map.empty())
8137
        return;
8138
 
8139
    vector<Button::TButton *> buttons = collectButtons(map);
8140
 
8141
    if (buttons.size() > 0)
8142
    {
8143
        vector<Button::TButton *>::iterator mapIter;
8144
 
8145
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8146
        {
8147
            Button::TButton *bt = *mapIter;
8148
            bt->setTextMaxChars(maxLen);
8149
        }
8150
    }
8151
}
8152
 
8153
/**
60 andreas 8154
 * Assign a picture to those buttons with a defined address range.
8155
 */
8156
void TPageManager::doBMP(int port, vector<int>& channels, vector<string>& pars)
8157
{
8158
    DECL_TRACER("TPageManager::doBMP(int port, vector<int>& channels, vector<string>& pars)");
8159
 
8160
    if (pars.size() < 2)
8161
    {
8162
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
8163
        return;
8164
    }
8165
 
8166
    TError::clear();
8167
    int btState = atoi(pars[0].c_str());
8168
    string bitmap = pars[1];
104 andreas 8169
    // If this is a G5 command, we may have up to 2 additional parameters.
8170
    int slot = -1, justify = -1, jx = 0, jy = 0;
60 andreas 8171
 
104 andreas 8172
    if (pars.size() > 2)
8173
    {
8174
        slot = atoi(pars[2].c_str());
8175
 
8176
        if (pars.size() >= 4)
8177
        {
8178
            justify = atoi(pars[4].c_str());
8179
 
8180
            if (justify == 0)
8181
            {
8182
                if (pars.size() >= 5)
8183
                    jx = atoi(pars[5].c_str());
8184
 
8185
                if (pars.size() >= 6)
8186
                    jy = atoi(pars[6].c_str());
8187
            }
8188
        }
8189
    }
8190
 
193 andreas 8191
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 8192
 
8193
    if (TError::isError() || map.empty())
8194
        return;
8195
 
8196
    vector<Button::TButton *> buttons = collectButtons(map);
8197
 
83 andreas 8198
    if (buttons.size() > 0)
60 andreas 8199
    {
83 andreas 8200
        vector<Button::TButton *>::iterator mapIter;
60 andreas 8201
 
83 andreas 8202
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 8203
        {
83 andreas 8204
            Button::TButton *bt = *mapIter;
252 andreas 8205
//            setButtonCallbacks(bt);
60 andreas 8206
 
83 andreas 8207
            if (btState == 0)       // All instances?
8208
            {
8209
                int bst = bt->getNumberInstances();
96 andreas 8210
                MSG_DEBUG("Setting bitmap " << bitmap << " on all " << bst << " instances...");
83 andreas 8211
 
8212
                for (int i = 0; i < bst; i++)
104 andreas 8213
                {
8214
                    if (justify >= 0)
8215
                    {
8216
                        if (slot == 2)
8217
                            bt->setIconJustification(justify, jx, jy, i);
8218
                        else
106 andreas 8219
                            bt->setBitmapJustification(justify, jx, jy, i);
104 andreas 8220
                    }
8221
 
8222
                    if (slot >= 0)
8223
                    {
8224
                        switch(slot)
8225
                        {
8226
                            case 0: bt->setCameleon(bitmap, i); break;
8227
                            case 2: bt->setIcon(bitmap, i); break;  // On G4 we have no bitmap layer. Therefor we use layer 2 as icon layer.
8228
                            default:
8229
                                bt->setBitmap(bitmap, i);
8230
                        }
8231
                    }
8232
                    else
8233
                        bt->setBitmap(bitmap, i);
8234
                }
83 andreas 8235
            }
8236
            else
104 andreas 8237
            {
8238
                if (justify >= 0)
8239
                {
8240
                    if (slot == 2)
8241
                        bt->setIconJustification(justify, jx, jy, btState);
8242
                    else
106 andreas 8243
                        bt->setBitmapJustification(justify, jx, jy, btState);
104 andreas 8244
                }
8245
 
8246
                if (slot >= 0)
8247
                {
8248
                    switch(slot)
8249
                    {
8250
                        case 0: bt->setCameleon(bitmap, btState); break;
8251
                        case 2: bt->setIcon(bitmap, btState); break;      // On G4 we have no bitmap layer. Therefor we use layer 2 as icon layer.
8252
                        default:
8253
                            bt->setBitmap(bitmap, btState);
8254
                    }
8255
                }
8256
                else
8257
                    bt->setBitmap(bitmap, btState);
8258
            }
60 andreas 8259
        }
8260
    }
8261
}
8262
 
82 andreas 8263
void TPageManager::getBMP(int port, vector<int> &channels, vector<string> &pars)
8264
{
8265
    DECL_TRACER("TPageManager::getBMP(int port, vector<int> &channels, vector<string> &pars)");
8266
 
8267
    if (pars.size() < 1)
8268
    {
8269
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
8270
        return;
8271
    }
8272
 
8273
    TError::clear();
8274
    int btState = atoi(pars[0].c_str());
8275
    string bmp;
8276
 
193 andreas 8277
    vector<TMap::MAP_T> map = findButtons(port, channels);
82 andreas 8278
 
8279
    if (TError::isError() || map.empty())
8280
        return;
8281
 
8282
    vector<Button::TButton *> buttons = collectButtons(map);
8283
 
83 andreas 8284
    if (buttons.size() > 0)
82 andreas 8285
    {
110 andreas 8286
        Button::TButton *bt = buttons[0];
82 andreas 8287
 
110 andreas 8288
        if (btState == 0)       // All instances?
82 andreas 8289
        {
110 andreas 8290
            int bst = bt->getNumberInstances();
82 andreas 8291
 
110 andreas 8292
            for (int i = 0; i < bst; i++)
82 andreas 8293
            {
110 andreas 8294
                bmp = bt->getBitmapName(i);
82 andreas 8295
 
110 andreas 8296
                if (bmp.empty())
8297
                    continue;
82 andreas 8298
 
300 andreas 8299
                sendCustomEvent(i + 1, (int)bmp.length(), 0, bmp, 1002, bt->getChannelPort(), bt->getChannelNumber());
83 andreas 8300
            }
82 andreas 8301
        }
110 andreas 8302
        else
8303
        {
8304
            bmp = bt->getTextColor(btState-1);
300 andreas 8305
            sendCustomEvent(btState, (int)bmp.length(), 0, bmp, 1002, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 8306
        }
82 andreas 8307
    }
8308
}
8309
 
60 andreas 8310
/**
16 andreas 8311
 * Set the button opacity. The button opacity can be specified as a decimal
8312
 * between 0 - 255, where zero (0) is invisible and 255 is opaque, or as a
8313
 * HEX code, as used in the color commands by preceding the HEX code with
8314
 * the # sign. In this case, #00 becomes invisible and #FF becomes opaque.
8315
 * If the opacity is set to zero (0), this does not make the button inactive,
8316
 * only invisible.
8317
 */
8318
void TPageManager::doBOP(int port, vector<int>& channels, vector<string>& pars)
8319
{
8320
    DECL_TRACER("TPageManager::doBOP(int port, vector<int>& channels, vector<string>& pars)");
8321
 
8322
    if (pars.size() < 2)
8323
    {
8324
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
335 andreas 8325
#if TESTMODE == 1
8326
        setAllDone();
8327
#endif
16 andreas 8328
        return;
8329
    }
8330
 
8331
    TError::clear();
335 andreas 8332
    int btState = atoi(pars[0].c_str()) - 1;
16 andreas 8333
    int btOpacity = 0;
8334
 
8335
    if (pars[1].at(0) == '#')
8336
        btOpacity = (int)strtol(pars[1].substr(1).c_str(), NULL, 16);
8337
    else
8338
        btOpacity = atoi(pars[1].c_str());
8339
 
193 andreas 8340
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8341
 
8342
    if (TError::isError() || map.empty())
335 andreas 8343
    {
8344
#if TESTMODE == 1
8345
        setAllDone();
8346
#endif
16 andreas 8347
        return;
335 andreas 8348
    }
16 andreas 8349
 
8350
    vector<Button::TButton *> buttons = collectButtons(map);
8351
 
83 andreas 8352
    if (buttons.size() > 0)
16 andreas 8353
    {
83 andreas 8354
        vector<Button::TButton *>::iterator mapIter;
16 andreas 8355
 
83 andreas 8356
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
16 andreas 8357
        {
83 andreas 8358
            Button::TButton *bt = *mapIter;
335 andreas 8359
            bt->setOpacity(btOpacity, btState);
8360
#if TESTMODE == 1
8361
            if (_gTestMode)
8362
                _gTestMode->setResult(intToString(bt->getOpacity(btState < 0 ? 0 : btState)));
342 andreas 8363
#endif
16 andreas 8364
        }
8365
    }
335 andreas 8366
#if TESTMODE == 1
8367
    setDone();
8368
#endif
16 andreas 8369
}
8370
 
106 andreas 8371
void TPageManager::getBOP(int port, vector<int>& channels, vector<string>& pars)
8372
{
8373
    DECL_TRACER("TPageManager::getBOP(int port, vector<int>& channels, vector<string>& pars)");
8374
 
8375
    if (pars.size() < 1)
8376
    {
8377
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
8378
        return;
8379
    }
8380
 
8381
    TError::clear();
8382
    int btState = atoi(pars[0].c_str());
8383
 
193 andreas 8384
    vector<TMap::MAP_T> map = findButtons(port, channels);
106 andreas 8385
 
8386
    if (TError::isError() || map.empty())
8387
        return;
8388
 
8389
    vector<Button::TButton *> buttons = collectButtons(map);
8390
 
8391
    if (buttons.size() > 0)
8392
    {
110 andreas 8393
        Button::TButton *bt = buttons[0];
106 andreas 8394
 
110 andreas 8395
        if (btState == 0)       // All instances?
106 andreas 8396
        {
110 andreas 8397
            int bst = bt->getNumberInstances();
106 andreas 8398
 
110 andreas 8399
            for (int i = 0; i < bst; i++)
106 andreas 8400
            {
110 andreas 8401
                int oo = bt->getOpacity(i);
8402
                sendCustomEvent(i + 1, oo, 0, "", 1015, bt->getChannelPort(), bt->getChannelNumber());
106 andreas 8403
            }
8404
        }
110 andreas 8405
        else
8406
        {
8407
            int oo = bt->getOpacity(btState-1);
8408
            sendCustomEvent(btState, oo, 0, "", 1015, bt->getChannelPort(), bt->getChannelNumber());
8409
        }
106 andreas 8410
    }
8411
}
8412
 
60 andreas 8413
void TPageManager::doBOR(int port, vector<int>& channels, vector<string>& pars)
8414
{
8415
    DECL_TRACER("TPageManager::doBOR(int port, vector<int>& channels, vector<string>& pars)");
8416
 
8417
    if (pars.size() < 1)
8418
    {
8419
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
335 andreas 8420
#if TESTMODE == 1
8421
        setAllDone();
8422
#endif
60 andreas 8423
        return;
8424
    }
8425
 
8426
    TError::clear();
8427
    // Numbers of styles from 0 to 41
8428
    string bor = pars[0];
8429
    string border = "None";
8430
    int ibor = -1;
336 andreas 8431
    Border::TIntBorder borders;
60 andreas 8432
 
8433
    if (bor.at(0) >= '0' && bor.at(0) <= '9')
336 andreas 8434
    {
60 andreas 8435
        ibor = atoi(bor.c_str());
8436
 
336 andreas 8437
        if (ibor >= 0 && ibor <= 41)
8438
            border = borders.getTP4BorderName(ibor);
8439
        else
60 andreas 8440
        {
336 andreas 8441
            MSG_WARNING("Invalid border style ID " << ibor);
8442
#if TESTMODE == 1
8443
            setAllDone();
8444
#endif
8445
            return;
8446
        }
60 andreas 8447
 
336 andreas 8448
        MSG_DEBUG("Id " << ibor << " is border " << border);
60 andreas 8449
    }
336 andreas 8450
    else
60 andreas 8451
    {
336 andreas 8452
        if (!borders.isTP4BorderValid(bor))
8453
        {
8454
            MSG_WARNING("Unknown border style " << bor);
335 andreas 8455
#if TESTMODE == 1
336 andreas 8456
            setAllDone();
335 andreas 8457
#endif
336 andreas 8458
            return;
8459
        }
60 andreas 8460
 
336 andreas 8461
        border = bor;
60 andreas 8462
    }
8463
 
193 andreas 8464
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 8465
 
8466
    if (TError::isError() || map.empty())
335 andreas 8467
    {
8468
#if TESTMODE == 1
8469
        setAllDone();
8470
#endif
60 andreas 8471
        return;
335 andreas 8472
    }
60 andreas 8473
 
8474
    vector<Button::TButton *> buttons = collectButtons(map);
8475
 
83 andreas 8476
    if (buttons.size() > 0)
60 andreas 8477
    {
83 andreas 8478
        vector<Button::TButton *>::iterator mapIter;
8479
 
8480
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8481
        {
8482
            Button::TButton *bt = *mapIter;
8483
            bt->setBorderStyle(border);
335 andreas 8484
#if TESTMODE == 1
8485
            if (_gTestMode)
8486
                _gTestMode->setResult(bt->getBorderStyle(0));
8487
#endif
83 andreas 8488
        }
60 andreas 8489
    }
335 andreas 8490
#if TESTMODE == 1
8491
    setDone();
8492
#endif
60 andreas 8493
}
8494
 
107 andreas 8495
void TPageManager::doBOS(int port, vector<int>& channels, vector<string>& pars)
8496
{
8497
    DECL_TRACER("TPageManager::doBOS(int port, vector<int>& channels, vector<string>& pars)");
8498
 
8499
    if (pars.size() < 2)
8500
    {
8501
        MSG_ERROR("Expecting at least 2 parameters but got " << pars.size() << "! Ignoring command.");
8502
        return;
8503
    }
8504
 
8505
    TError::clear();
8506
    int btState = atoi(pars[0].c_str());
8507
    int videoState = atoi(pars[1].c_str());
8508
 
193 andreas 8509
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 8510
 
8511
    if (TError::isError() || map.empty())
8512
        return;
8513
 
8514
    vector<Button::TButton *> buttons = collectButtons(map);
8515
 
8516
    if (buttons.size() > 0)
8517
    {
8518
        vector<Button::TButton *>::iterator mapIter;
8519
 
8520
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8521
        {
8522
            Button::TButton *bt = *mapIter;
8523
 
8524
            if (btState == 0)       // All instances?
8525
                bt->setDynamic(videoState);
8526
            else
8527
                bt->setDynamic(videoState, btState-1);
8528
        }
8529
    }
8530
}
8531
 
16 andreas 8532
/**
60 andreas 8533
 * Set the border of a button state/states.
8534
 * The border names are available through the TPDesign4 border-name drop-down
8535
 * list.
8536
 */
8537
void TPageManager::doBRD(int port, vector<int>& channels, vector<string>& pars)
8538
{
8539
    DECL_TRACER("TPageManager::doBRD(int port, vector<int>& channels, vector<string>& pars)");
8540
 
8541
    if (pars.size() < 1)
8542
    {
8543
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8544
        return;
8545
    }
8546
 
8547
    TError::clear();
8548
    int btState = atoi(pars[0].c_str());
8549
    string border = "None";
8550
 
8551
    if (pars.size() > 1)
8552
        border = pars[1];
8553
 
193 andreas 8554
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 8555
 
8556
    if (TError::isError() || map.empty())
8557
        return;
8558
 
8559
    vector<Button::TButton *> buttons = collectButtons(map);
8560
 
83 andreas 8561
    if (buttons.size() > 0)
60 andreas 8562
    {
83 andreas 8563
        vector<Button::TButton *>::iterator mapIter;
60 andreas 8564
 
83 andreas 8565
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
60 andreas 8566
        {
83 andreas 8567
            Button::TButton *bt = *mapIter;
252 andreas 8568
//            setButtonCallbacks(bt);
60 andreas 8569
 
83 andreas 8570
            if (btState == 0)       // All instances?
8571
            {
8572
                int bst = bt->getNumberInstances();
8573
 
8574
                for (int i = 0; i < bst; i++)
106 andreas 8575
                    bt->setBorderStyle(border, i+1);
83 andreas 8576
            }
8577
            else
106 andreas 8578
                bt->setBorderStyle(border, btState);
60 andreas 8579
        }
8580
    }
8581
}
8582
 
107 andreas 8583
void TPageManager::getBRD(int port, vector<int>& channels, vector<string>& pars)
8584
{
8585
    DECL_TRACER("TPageManager::getBRD(int port, vector<int>& channels, vector<string>& pars)");
8586
 
8587
    if (pars.size() < 1)
8588
    {
8589
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8590
        return;
8591
    }
8592
 
8593
    TError::clear();
8594
    int btState = atoi(pars[0].c_str());
8595
 
193 andreas 8596
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 8597
 
8598
    if (TError::isError() || map.empty())
8599
        return;
8600
 
8601
    vector<Button::TButton *> buttons = collectButtons(map);
8602
 
8603
    if (buttons.size() > 0)
8604
    {
110 andreas 8605
        Button::TButton *bt = buttons[0];
107 andreas 8606
 
110 andreas 8607
        if (btState == 0)       // All instances?
107 andreas 8608
        {
110 andreas 8609
            int bst = bt->getNumberInstances();
107 andreas 8610
 
110 andreas 8611
            for (int i = 0; i < bst; i++)
107 andreas 8612
            {
110 andreas 8613
                string bname = bt->getBorderStyle(i);
300 andreas 8614
                sendCustomEvent(i + 1, (int)bname.length(), 0, bname, 1014, bt->getChannelPort(), bt->getChannelNumber());
107 andreas 8615
            }
8616
        }
110 andreas 8617
        else
8618
        {
8619
            string bname = bt->getBorderStyle(btState-1);
300 andreas 8620
            sendCustomEvent(btState, (int)bname.length(), 0, bname, 1014, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 8621
        }
107 andreas 8622
    }
8623
}
8624
 
60 andreas 8625
/**
16 andreas 8626
 * Set the button size and its position on the page.
8627
 */
8628
void TPageManager::doBSP(int port, vector<int>& channels, vector<string>& pars)
8629
{
8630
    DECL_TRACER("TPageManager::doBSP(int port, vector<int>& channels, vector<string>& pars)");
8631
 
8632
    if (pars.size() < 1)
8633
    {
8634
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
341 andreas 8635
#if TESTMODE == 1
8636
        setAllDone();
8637
#endif
16 andreas 8638
        return;
8639
    }
8640
 
8641
    TError::clear();
8642
    bool bLeft = false, bTop = false, bRight = false, bBottom = false;
8643
    int x, y;
8644
 
83 andreas 8645
    if (pars.size() > 0)
16 andreas 8646
    {
83 andreas 8647
        vector<string>::iterator iter;
8648
 
8649
        for (iter = pars.begin(); iter != pars.end(); iter++)
8650
        {
8651
            if (iter->compare("left") == 0)
8652
                bLeft = true;
8653
            else if (iter->compare("top") == 0)
8654
                bTop = true;
8655
            else if (iter->compare("right") == 0)
8656
                bRight = true;
8657
            else if (iter->compare("bottom") == 0)
8658
                bBottom = true;
8659
        }
16 andreas 8660
    }
8661
 
193 andreas 8662
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8663
 
8664
    if (TError::isError() || map.empty())
8665
        return;
8666
 
8667
    vector<Button::TButton *> buttons = collectButtons(map);
8668
 
83 andreas 8669
    if (buttons.size() > 0)
16 andreas 8670
    {
83 andreas 8671
        vector<Button::TButton *>::iterator mapIter;
16 andreas 8672
 
83 andreas 8673
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8674
        {
8675
            Button::TButton *bt = *mapIter;
341 andreas 8676
//            setButtonCallbacks(bt);
16 andreas 8677
 
83 andreas 8678
            if (bLeft)
8679
                x = 0;
16 andreas 8680
 
83 andreas 8681
            if (bTop)
8682
                y = 0;
16 andreas 8683
 
341 andreas 8684
            if (bRight || bBottom)
16 andreas 8685
            {
83 andreas 8686
                ulong handle = bt->getHandle();
8687
                int parentID = (handle >> 16) & 0x0000ffff;
8688
                int pwidth = 0;
341 andreas 8689
                int pheight = 0;
16 andreas 8690
 
83 andreas 8691
                if (parentID < 500)
16 andreas 8692
                {
83 andreas 8693
                    TPage *pg = getPage(parentID);
8694
 
8695
                    if (!pg)
8696
                    {
8697
                        MSG_ERROR("Internal error: Page " << parentID << " not found!");
8698
                        return;
8699
                    }
8700
 
8701
                    pwidth = pg->getWidth();
341 andreas 8702
                    pheight = pg->getHeight();
16 andreas 8703
                }
83 andreas 8704
                else
8705
                {
8706
                    TSubPage *spg = getSubPage(parentID);
16 andreas 8707
 
83 andreas 8708
                    if (!spg)
8709
                    {
8710
                        MSG_ERROR("Internal error: Subpage " << parentID << " not found!");
8711
                        return;
8712
                    }
16 andreas 8713
 
83 andreas 8714
                    pwidth = spg->getWidth();
341 andreas 8715
                    pheight = spg->getHeight();
16 andreas 8716
                }
8717
 
341 andreas 8718
                if (bRight)
8719
                    x = pwidth - bt->getWidth();
8720
 
8721
                if (bBottom)
8722
                    y = pheight - bt->getHeight();
16 andreas 8723
            }
8724
 
341 andreas 8725
            bt->setLeftTop(x, y);
8726
#if TESTMODE == 1
8727
            if (_gTestMode)
83 andreas 8728
            {
341 andreas 8729
                int left = bt->getLeftPosition();
8730
                int top = bt->getTopPosition();
8731
                string res = intToString(left) + "," + intToString(top);
8732
                _gTestMode->setResult(res);
16 andreas 8733
            }
341 andreas 8734
#endif
16 andreas 8735
        }
8736
    }
341 andreas 8737
#if TESTMODE == 1
8738
    setDone();
8739
#endif
16 andreas 8740
}
8741
 
8742
/**
107 andreas 8743
 * Submit text for text area buttons. This command causes the text areas to
8744
 * send their text as strings to the NetLinx Master.
8745
 */
8746
void TPageManager::doBSM(int port, vector<int>& channels, vector<string>&)
8747
{
8748
    DECL_TRACER("TPageManager::doBSM(int port, vector<int>& channels, vector<string>& pars)");
8749
 
8750
    TError::clear();
193 andreas 8751
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 8752
 
8753
    if (TError::isError() || map.empty())
341 andreas 8754
    {
8755
#if TESTMODE == 1
8756
        setAllDone();
8757
#endif
107 andreas 8758
        return;
341 andreas 8759
    }
107 andreas 8760
 
8761
    vector<Button::TButton *> buttons = collectButtons(map);
8762
 
8763
    if (buttons.size() > 0)
8764
    {
8765
        vector<Button::TButton *>::iterator mapIter;
8766
 
8767
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8768
        {
8769
            Button::TButton *bt = *mapIter;
8770
 
195 andreas 8771
            if (bt->getButtonType() != TEXT_INPUT && bt->getButtonType() != GENERAL)
341 andreas 8772
            {
8773
#if TESTMODE == 1
8774
                setAllDone();
8775
#endif
107 andreas 8776
                return;
341 andreas 8777
            }
107 andreas 8778
 
8779
            amx::ANET_SEND scmd;
8780
            scmd.port = bt->getChannelPort();
8781
            scmd.channel = bt->getChannelNumber();
8782
            scmd.ID = scmd.channel;
8783
            scmd.msg = bt->getText(0);
8784
            scmd.MC = 0x008b;       // string value
8785
 
8786
            if (gAmxNet)
8787
                gAmxNet->sendCommand(scmd);
8788
            else
8789
                MSG_WARNING("Missing global class TAmxNet. Can't send message!");
8790
 
8791
        }
8792
    }
8793
}
8794
 
8795
/**
8796
 * Set the sound played when a button is pressed. If the sound name is blank
8797
 * the sound is then cleared. If the sound name is not matched, the button
8798
 * sound is not changed.
8799
 */
8800
void TPageManager::doBSO(int port, vector<int>& channels, vector<string>& pars)
8801
{
8802
    DECL_TRACER("TPageManager::doBSO(int port, vector<int>& channels, vector<string>& pars)");
8803
 
8804
    if (pars.size() < 2)
8805
    {
8806
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
8807
        return;
8808
    }
8809
 
8810
    if (!gPrjResources)
8811
        return;
8812
 
8813
    TError::clear();
8814
    int btState = atoi(pars[0].c_str());
8815
    string sound = pars[1];
8816
 
8817
    if (!soundExist(sound))
8818
        return;
8819
 
193 andreas 8820
    vector<TMap::MAP_T> map = findButtons(port, channels);
107 andreas 8821
 
8822
    if (TError::isError() || map.empty())
8823
        return;
8824
 
8825
    vector<Button::TButton *> buttons = collectButtons(map);
8826
 
8827
    if (buttons.size() > 0)
8828
    {
8829
        vector<Button::TButton *>::iterator mapIter;
8830
 
8831
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8832
        {
8833
            Button::TButton *bt = *mapIter;
8834
 
8835
            if (btState == 0)
8836
            {
8837
                int bst = bt->getNumberInstances();
8838
 
8839
                for (int i = 0; i < bst; i++)
8840
                    bt->setSound(sound, i);
8841
            }
8842
            else
8843
                bt->setSound(sound, btState-1);
8844
        }
8845
    }
8846
}
8847
 
8848
/**
16 andreas 8849
 * Set the button word wrap feature to those buttons with a defined address
8850
 * range. By default, word-wrap is Off.
8851
 */
8852
void TPageManager::doBWW(int port, vector<int>& channels, vector<string>& pars)
8853
{
8854
    DECL_TRACER("TPageManager::doBWW(int port, vector<int>& channels, vector<string>& pars)");
8855
 
8856
    if (pars.size() < 1)
8857
    {
8858
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
8859
        return;
8860
    }
8861
 
8862
    TError::clear();
8863
    int btState = atoi(pars[0].c_str());
8864
 
193 andreas 8865
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8866
 
8867
    if (TError::isError() || map.empty())
8868
        return;
8869
 
8870
    vector<Button::TButton *> buttons = collectButtons(map);
8871
 
83 andreas 8872
    if (buttons.size() > 0)
16 andreas 8873
    {
83 andreas 8874
        vector<Button::TButton *>::iterator mapIter;
16 andreas 8875
 
83 andreas 8876
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
16 andreas 8877
        {
83 andreas 8878
            Button::TButton *bt = *mapIter;
252 andreas 8879
//            setButtonCallbacks(bt);
16 andreas 8880
 
83 andreas 8881
            if (btState == 0)       // All instances?
8882
            {
8883
                int bst = bt->getNumberInstances();
8884
                MSG_DEBUG("Setting word wrap on all " << bst << " instances...");
8885
 
8886
                for (int i = 0; i < bst; i++)
110 andreas 8887
                    bt->setTextWordWrap(true, i);
83 andreas 8888
            }
8889
            else
110 andreas 8890
                bt->setTextWordWrap(true, btState - 1);
16 andreas 8891
        }
8892
    }
8893
}
8894
 
108 andreas 8895
void TPageManager::getBWW(int port, vector<int>& channels, vector<string>& pars)
8896
{
8897
    DECL_TRACER("TPageManager::getBWW(int port, vector<int>& channels, vector<string>& pars)");
8898
 
8899
    if (pars.size() < 1)
8900
    {
8901
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8902
        return;
8903
    }
8904
 
8905
    TError::clear();
8906
    int btState = atoi(pars[0].c_str());
8907
 
193 andreas 8908
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 8909
 
8910
    if (TError::isError() || map.empty())
8911
        return;
8912
 
8913
    vector<Button::TButton *> buttons = collectButtons(map);
8914
 
8915
    if (buttons.size() > 0)
8916
    {
110 andreas 8917
        Button::TButton *bt = buttons[0];
108 andreas 8918
 
110 andreas 8919
        if (btState == 0)       // All instances?
108 andreas 8920
        {
110 andreas 8921
            int bst = bt->getNumberInstances();
108 andreas 8922
 
110 andreas 8923
            for (int i = 0; i < bst; i++)
8924
                sendCustomEvent(i + 1, bt->getTextWordWrap(i), 0, "", 1010, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 8925
        }
110 andreas 8926
        else
8927
            sendCustomEvent(btState, bt->getTextWordWrap(btState-1), 0, "", 1010, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 8928
    }
8929
}
8930
 
16 andreas 8931
/**
8932
 * Clear all page flips from a button.
8933
 */
22 andreas 8934
void TPageManager::doCPF(int port, vector<int>& channels, vector<string>&)
16 andreas 8935
{
8936
    DECL_TRACER("TPageManager::doCPF(int port, vector<int>& channels, vector<string>& pars)");
8937
 
8938
    TError::clear();
193 andreas 8939
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 8940
 
8941
    if (TError::isError() || map.empty())
8942
        return;
8943
 
8944
    vector<Button::TButton *> buttons = collectButtons(map);
8945
 
83 andreas 8946
    if (buttons.size() > 0)
16 andreas 8947
    {
83 andreas 8948
        vector<Button::TButton *>::iterator mapIter;
8949
 
8950
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
8951
        {
8952
            Button::TButton *bt = *mapIter;
252 andreas 8953
//            setButtonCallbacks(bt);
83 andreas 8954
            bt->clearPushFunctions();
8955
        }
16 andreas 8956
    }
8957
}
8958
 
8959
/**
8960
 * Delete page flips from button if it already exists.
8961
 */
8962
void TPageManager::doDPF(int port, vector<int>& channels, vector<string>& pars)
8963
{
8964
    DECL_TRACER("TPageManager::doDPF(int port, vector<int>& channels, vector<string>& pars)");
8965
 
8966
    if (pars.size() < 1)
8967
    {
8968
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
8969
        return;
8970
    }
8971
 
8972
    TError::clear();
8973
    string action = pars[0];
8974
    string pname;
8975
 
8976
    if (pars.size() >= 2)
8977
    {
8978
        pname = pars[1];
8979
        vector<Button::TButton *> list;
8980
        // First we search for a subpage because this is more likely
8981
        TSubPage *spg = getSubPage(pname);
8982
 
8983
        if (spg)
8984
            list = spg->getButtons(port, channels[0]);
8985
        else    // Then for a page
8986
        {
8987
            TPage *pg = getPage(pname);
8988
 
8989
            if (pg)
8990
                list = pg->getButtons(port, channels[0]);
8991
            else
8992
            {
8993
                MSG_WARNING("The name " << pname << " doesn't name either a page or a subpage!");
8994
                return;
8995
            }
8996
        }
8997
 
8998
        if (list.empty())
8999
            return;
9000
 
9001
        vector<Button::TButton *>::iterator it;
9002
 
9003
        for (it = list.begin(); it != list.end(); it++)
9004
        {
9005
            Button::TButton *bt = *it;
252 andreas 9006
//            setButtonCallbacks(bt);
16 andreas 9007
            bt->clearPushFunction(action);
9008
        }
9009
 
9010
        return;
9011
    }
9012
 
9013
    // Here we don't have a page name
193 andreas 9014
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 9015
 
9016
    if (TError::isError() || map.empty())
9017
        return;
9018
 
9019
    vector<Button::TButton *> buttons = collectButtons(map);
9020
 
83 andreas 9021
    if (buttons.size() > 0)
16 andreas 9022
    {
83 andreas 9023
        vector<Button::TButton *>::iterator mapIter;
9024
 
9025
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9026
        {
9027
            Button::TButton *bt = *mapIter;
252 andreas 9028
//            setButtonCallbacks(bt);
83 andreas 9029
            bt->clearPushFunction(action);
9030
        }
16 andreas 9031
    }
9032
}
9033
 
9034
/**
9035
 * Enable or disable buttons with a set variable text range.
9036
 */
9037
void TPageManager::doENA(int port, vector<int>& channels, vector<string>& pars)
9038
{
9039
    DECL_TRACER("TPageManager::doENA(int port, vector<int>& channels, vector<string>& pars)");
9040
 
9041
    if (pars.empty())
9042
    {
9043
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
341 andreas 9044
#if TESTMODE == 1
9045
        setAllDone();
9046
#endif
16 andreas 9047
        return;
9048
    }
9049
 
9050
    TError::clear();
9051
    int cvalue = atoi(pars[0].c_str());
9052
 
193 andreas 9053
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 9054
 
9055
    if (TError::isError() || map.empty())
341 andreas 9056
    {
9057
#if TESTMODE == 1
9058
        setAllDone();
9059
#endif
16 andreas 9060
        return;
341 andreas 9061
    }
16 andreas 9062
 
9063
    vector<Button::TButton *> buttons = collectButtons(map);
9064
 
83 andreas 9065
    if (buttons.size() > 0)
16 andreas 9066
    {
83 andreas 9067
        vector<Button::TButton *>::iterator mapIter;
9068
 
9069
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9070
        {
9071
            Button::TButton *bt = *mapIter;
9072
            bt->setEnable(((cvalue)?true:false));
341 andreas 9073
#if TESTMODE == 1
9074
            __success = true;
9075
 
9076
            if (_gTestMode)
9077
                _gTestMode->setResult(intToString(cvalue));
9078
#endif
83 andreas 9079
        }
16 andreas 9080
    }
341 andreas 9081
#if TESTMODE == 1
9082
    setAllDone();
9083
#endif
16 andreas 9084
}
9085
 
9086
/**
9087
 * Set a font to a specific Font ID value for those buttons with a defined
9088
 * address range. Font ID numbers are generated by the TPDesign4 programmers
9089
 * report.
9090
 */
9091
void TPageManager::doFON(int port, vector<int>& channels, vector<string>& pars)
9092
{
9093
    DECL_TRACER("TPageManager::doFON(int port, vector<int>& channels, vector<string>& pars)");
9094
 
9095
    if (pars.size() < 2)
9096
    {
9097
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
342 andreas 9098
#if TESTMODE == 1
9099
        setAllDone();
9100
#endif
16 andreas 9101
        return;
9102
    }
9103
 
9104
    TError::clear();
342 andreas 9105
    int btState = atoi(pars[0].c_str()) - 1;
16 andreas 9106
    int fvalue = atoi(pars[1].c_str());
9107
 
193 andreas 9108
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 9109
 
9110
    if (TError::isError() || map.empty())
9111
        return;
9112
 
9113
    vector<Button::TButton *> buttons = collectButtons(map);
9114
 
83 andreas 9115
    if (buttons.size() > 0)
16 andreas 9116
    {
83 andreas 9117
        vector<Button::TButton *>::iterator mapIter;
16 andreas 9118
 
83 andreas 9119
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
16 andreas 9120
        {
83 andreas 9121
            Button::TButton *bt = *mapIter;
342 andreas 9122
            bt->setFont(fvalue, btState);
9123
#if TESTMODE == 1
9124
            if (_gTestMode)
9125
                _gTestMode->setResult(intToString(bt->getFontIndex(btState < 0 ? 0 : btState)));
9126
#endif
16 andreas 9127
        }
9128
    }
342 andreas 9129
#if TESTMODE == 1
9130
    setDone();
9131
#endif
16 andreas 9132
}
9133
 
108 andreas 9134
void TPageManager::getFON(int port, vector<int>& channels, vector<string>& pars)
9135
{
9136
    DECL_TRACER("TPageManager::getFON(int port, vector<int>& channels, vector<string>& pars)");
9137
 
9138
    if (pars.size() < 1)
9139
    {
9140
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
342 andreas 9141
#if TESTMODE == 1
9142
        setAllDone();
9143
#endif
108 andreas 9144
        return;
9145
    }
9146
 
9147
    TError::clear();
9148
    int btState = atoi(pars[0].c_str());
9149
 
193 andreas 9150
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9151
 
9152
    if (TError::isError() || map.empty())
342 andreas 9153
    {
9154
#if TESTMODE == 1
9155
        setAllDone();
9156
#endif
108 andreas 9157
        return;
342 andreas 9158
    }
108 andreas 9159
 
9160
    vector<Button::TButton *> buttons = collectButtons(map);
9161
 
9162
    if (buttons.size() > 0)
9163
    {
110 andreas 9164
        Button::TButton *bt = buttons[0];
108 andreas 9165
 
110 andreas 9166
        if (btState == 0)       // All instances?
108 andreas 9167
        {
110 andreas 9168
            int bst = bt->getNumberInstances();
108 andreas 9169
 
110 andreas 9170
            for (int i = 0; i < bst; i++)
9171
                sendCustomEvent(i + 1, bt->getFontIndex(i), 0, "", 1007, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9172
        }
110 andreas 9173
        else
9174
            sendCustomEvent(btState, bt->getFontIndex(btState - 1), 0, "", 1007, bt->getChannelPort(), bt->getChannelNumber());
342 andreas 9175
#if TESTMODE == 1
9176
        if (_gTestMode)
9177
            _gTestMode->setResult(intToString(bt->getFontIndex(btState < 0 ? 0 : btState)));
9178
#endif
108 andreas 9179
    }
342 andreas 9180
#if TESTMODE == 1
9181
    __success = true;
9182
    setAllDone();
9183
#endif
108 andreas 9184
}
9185
 
388 andreas 9186
void TPageManager::doGDI(int port, vector<int>& channels, vector<std::string>& pars)
9187
{
9188
    DECL_TRACER("TPageManager::doGDI(int port, vector<int>& channels, vector<std::string>& pars)");
9189
 
9190
    if (pars.size() < 1)
9191
    {
9192
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9193
        return;
9194
    }
9195
 
9196
    TError::clear();
9197
    int inc = atoi(pars[0].c_str());
9198
 
9199
    if (inc < 0)
9200
    {
9201
        MSG_ERROR("Invalid drag increment of " << inc << "!");
9202
        return;
9203
    }
9204
 
9205
    vector<TMap::MAP_T> map = findButtons(port, channels);
9206
 
9207
    if (TError::isError() || map.empty())
9208
        return;
9209
 
9210
    vector<Button::TButton *> buttons = collectButtons(map);
9211
 
9212
    if (buttons.size() > 0)
9213
    {
9214
        vector<Button::TButton *>::iterator mapIter;
9215
 
9216
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9217
        {
9218
            Button::TButton *bt = *mapIter;
9219
            bt->setBargraphDragIncrement(inc);
9220
        }
9221
    }
9222
}
9223
/* Currently not implemented
9224
void TPageManager::doGDV(int port, vector<int>& channels, vector<std::string>& pars)
9225
{
9226
    DECL_TRACER("TPageManager::doGDV(int port, vector<int>& channels, vector<std::string>& pars)");
9227
}
9228
*/
16 andreas 9229
/**
60 andreas 9230
 * Change the bargraph upper limit.
9231
 */
9232
void TPageManager::doGLH(int port, vector<int>& channels, vector<std::string>& pars)
9233
{
9234
    DECL_TRACER("TPageManager::doGLH(int port, vector<int>& channels, vector<std::string>& pars)");
9235
 
9236
    if (pars.size() < 1)
9237
    {
9238
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9239
        return;
9240
    }
9241
 
9242
    TError::clear();
9243
    int limit = atoi(pars[0].c_str());
9244
 
9245
    if (limit < 1)
9246
    {
9247
        MSG_ERROR("Invalid upper limit " << limit << "!");
9248
        return;
9249
    }
9250
 
193 andreas 9251
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 9252
 
9253
    if (TError::isError() || map.empty())
9254
        return;
9255
 
9256
    vector<Button::TButton *> buttons = collectButtons(map);
9257
 
83 andreas 9258
    if (buttons.size() > 0)
60 andreas 9259
    {
83 andreas 9260
        vector<Button::TButton *>::iterator mapIter;
9261
 
9262
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9263
        {
9264
            Button::TButton *bt = *mapIter;
252 andreas 9265
//            setButtonCallbacks(bt);
83 andreas 9266
            bt->setBargraphUpperLimit(limit);
9267
        }
60 andreas 9268
    }
9269
}
9270
 
9271
/**
9272
 * Change the bargraph lower limit.
9273
 */
9274
void TPageManager::doGLL(int port, vector<int>& channels, vector<std::string>& pars)
9275
{
9276
    DECL_TRACER("TPageManager::doGLL(int port, vector<int>& channels, vector<std::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 limit = atoi(pars[0].c_str());
9286
 
9287
    if (limit < 1)
9288
    {
9289
        MSG_ERROR("Invalid lower limit " << limit << "!");
9290
        return;
9291
    }
9292
 
193 andreas 9293
    vector<TMap::MAP_T> map = findButtons(port, channels);
60 andreas 9294
 
9295
    if (TError::isError() || map.empty())
9296
        return;
9297
 
9298
    vector<Button::TButton *> buttons = collectButtons(map);
9299
 
83 andreas 9300
    if (buttons.size() > 0)
60 andreas 9301
    {
83 andreas 9302
        vector<Button::TButton *>::iterator mapIter;
9303
 
9304
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9305
        {
9306
            Button::TButton *bt = *mapIter;
252 andreas 9307
//            setButtonCallbacks(bt);
83 andreas 9308
            bt->setBargraphLowerLimit(limit);
9309
        }
60 andreas 9310
    }
9311
}
9312
 
108 andreas 9313
void TPageManager::doGSC(int port, vector<int>& channels, vector<string>& pars)
9314
{
9315
    DECL_TRACER("TPageManager::doGSC(int port, vector<int>& channels, vector<string>& pars)");
9316
 
9317
    if (pars.size() < 1)
9318
    {
9319
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9320
        return;
9321
    }
9322
 
9323
    TError::clear();
9324
    string color = pars[0];
193 andreas 9325
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9326
 
9327
    if (TError::isError() || map.empty())
9328
        return;
9329
 
9330
    vector<Button::TButton *> buttons = collectButtons(map);
9331
 
9332
    if (buttons.size() > 0)
9333
    {
9334
        vector<Button::TButton *>::iterator mapIter;
9335
 
9336
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9337
        {
9338
            Button::TButton *bt = *mapIter;
9339
            bt->setBargraphSliderColor(color);
9340
        }
9341
    }
9342
}
9343
 
361 andreas 9344
/*
388 andreas 9345
 * Set bargraph ramp down time in 1/10 seconds.
9346
 */
9347
void TPageManager::doGRD(int port, vector<int>& channels, vector<string>& pars)
9348
{
9349
    DECL_TRACER("TPageManager::doGRD(int port, vector<int>& channels, vector<string>& pars)");
9350
 
9351
    if (pars.size() < 1)
9352
    {
9353
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9354
        return;
9355
    }
9356
 
9357
    TError::clear();
9358
    int t = atoi(pars[0].c_str());
9359
 
9360
    if (t < 0)
9361
    {
9362
        MSG_ERROR("Invalid ramp down time limit " << t << "!");
9363
        return;
9364
    }
9365
 
9366
    vector<TMap::MAP_T> map = findButtons(port, channels);
9367
 
9368
    if (TError::isError() || map.empty())
9369
        return;
9370
 
9371
    vector<Button::TButton *> buttons = collectButtons(map);
9372
 
9373
    if (buttons.size() > 0)
9374
    {
9375
        vector<Button::TButton *>::iterator mapIter;
9376
 
9377
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9378
        {
9379
            Button::TButton *bt = *mapIter;
9380
            bt->setBargraphRampDownTime(t);
9381
        }
9382
    }
9383
}
9384
 
9385
/*
9386
 * Set bargraph ramp up time in 1/10 seconds.
9387
 */
9388
void TPageManager::doGRU(int port, vector<int>& channels, vector<string>& pars)
9389
{
9390
    DECL_TRACER("TPageManager::doGRU(int port, vector<int>& channels, vector<string>& pars)");
9391
 
9392
    if (pars.size() < 1)
9393
    {
9394
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9395
        return;
9396
    }
9397
 
9398
    TError::clear();
9399
    int t = atoi(pars[0].c_str());
9400
 
9401
    if (t < 0)
9402
    {
9403
        MSG_ERROR("Invalid ramp up time limit " << t << "!");
9404
        return;
9405
    }
9406
 
9407
    vector<TMap::MAP_T> map = findButtons(port, channels);
9408
 
9409
    if (TError::isError() || map.empty())
9410
        return;
9411
 
9412
    vector<Button::TButton *> buttons = collectButtons(map);
9413
 
9414
    if (buttons.size() > 0)
9415
    {
9416
        vector<Button::TButton *>::iterator mapIter;
9417
 
9418
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9419
        {
9420
            Button::TButton *bt = *mapIter;
9421
            bt->setBargraphRampUpTime(t);
9422
        }
9423
    }
9424
}
9425
 
9426
/*
361 andreas 9427
 * Change the bargraph slider name or joystick cursor name.
9428
 */
9429
void TPageManager::doGSN(int port, vector<int>& channels, vector<string>& pars)
9430
{
9431
    DECL_TRACER("TPageManager::doGSN(int port, vector<int>& channels, vector<string>& pars)");
9432
 
9433
    if (pars.size() < 1)
9434
    {
9435
        MSG_ERROR("Expecting 1 parameter but got " << pars.size() << "! Ignoring command.");
9436
        return;
9437
    }
9438
 
9439
    TError::clear();
9440
    string name = pars[0];
9441
    vector<TMap::MAP_T> map = findButtons(port, channels);
9442
 
9443
    if (TError::isError() || map.empty())
9444
        return;
9445
 
9446
    vector<Button::TButton *> buttons = collectButtons(map);
9447
 
9448
    if (buttons.size() > 0)
9449
    {
9450
        vector<Button::TButton *>::iterator mapIter;
9451
 
9452
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9453
        {
9454
            Button::TButton *bt = *mapIter;
9455
            bt->setBargraphSliderName(name);
9456
        }
9457
    }
9458
}
9459
 
60 andreas 9460
/**
14 andreas 9461
 * Set the icon to a button.
9462
 */
9463
void TPageManager::doICO(int port, vector<int>& channels, vector<string>& pars)
9464
{
9465
    DECL_TRACER("TPageManager::doICO(int port, vector<int>& channels, vector<string>& pars)");
9466
 
9467
    if (pars.size() < 2)
9468
    {
9469
        MSG_ERROR("Expecting 2 parameters but got " << pars.size() << "! Ignoring command.");
9470
        return;
9471
    }
9472
 
16 andreas 9473
    TError::clear();
14 andreas 9474
    int btState = atoi(pars[0].c_str());
9475
    int iconIdx = atoi(pars[1].c_str());
9476
 
193 andreas 9477
    vector<TMap::MAP_T> map = findButtons(port, channels);
14 andreas 9478
 
9479
    if (TError::isError() || map.empty())
9480
        return;
9481
 
9482
    vector<Button::TButton *> buttons = collectButtons(map);
9483
 
83 andreas 9484
    if (buttons.size() > 0)
14 andreas 9485
    {
83 andreas 9486
        vector<Button::TButton *>::iterator mapIter;
14 andreas 9487
 
83 andreas 9488
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
14 andreas 9489
        {
83 andreas 9490
            Button::TButton *bt = *mapIter;
14 andreas 9491
 
83 andreas 9492
            if (btState == 0)       // All instances?
14 andreas 9493
            {
316 andreas 9494
                if (iconIdx > 0)
9495
                    bt->setIcon(iconIdx, -1);
9496
                else
9497
                    bt->revokeIcon(-1);
14 andreas 9498
            }
83 andreas 9499
            else if (iconIdx > 0)
9500
                bt->setIcon(iconIdx, btState - 1);
9501
            else
9502
                bt->revokeIcon(btState - 1);
14 andreas 9503
        }
9504
    }
9505
}
9506
 
108 andreas 9507
void TPageManager::getICO(int port, vector<int>& channels, vector<string>& pars)
9508
{
9509
    DECL_TRACER("TPageManager::getICO(int port, vector<int>& channels, vector<string>& pars)");
9510
 
9511
    if (pars.size() < 1)
9512
    {
9513
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9514
        return;
9515
    }
9516
 
9517
    TError::clear();
9518
    int btState = atoi(pars[0].c_str());
9519
 
193 andreas 9520
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9521
 
9522
    if (TError::isError() || map.empty())
9523
        return;
9524
 
9525
    vector<Button::TButton *> buttons = collectButtons(map);
9526
 
9527
    if (buttons.size() > 0)
9528
    {
110 andreas 9529
        Button::TButton *bt = buttons[0];
108 andreas 9530
 
110 andreas 9531
        if (btState == 0)       // All instances?
108 andreas 9532
        {
110 andreas 9533
            int bst = bt->getNumberInstances();
108 andreas 9534
 
110 andreas 9535
            for (int i = 0; i < bst; i++)
9536
                sendCustomEvent(i + 1, bt->getIconIndex(i), 0, "", 1003, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9537
        }
110 andreas 9538
        else
9539
            sendCustomEvent(btState, bt->getIconIndex(btState - 1), 0, "", 1003, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9540
    }
9541
}
9542
 
14 andreas 9543
/**
108 andreas 9544
 * Set bitmap/picture alignment using a numeric keypad layout for those buttons
9545
 * with a defined address range. The alignment of 0 is followed by
9546
 * ',<left>,<top>'. The left and top coordinates are relative to the upper left
9547
 * corner of the button.
9548
 */
9549
void TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)
9550
{
9551
    DECL_TRACER("TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)");
9552
 
9553
    if (pars.size() < 2)
9554
    {
9555
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
9556
        return;
9557
    }
9558
 
9559
    TError::clear();
9560
    int btState = atoi(pars[0].c_str());
9561
    int align = atoi(pars[1].c_str());
9562
    int x = 0, y = 0;
9563
 
9564
    if (!align && pars.size() >= 3)
9565
    {
9566
        x = atoi(pars[2].c_str());
9567
 
9568
        if (pars.size() >= 4)
9569
            y = atoi(pars[3].c_str());
9570
    }
9571
 
193 andreas 9572
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9573
 
9574
    if (TError::isError() || map.empty())
9575
        return;
9576
 
9577
    vector<Button::TButton *> buttons = collectButtons(map);
9578
 
9579
    if (buttons.size() > 0)
9580
    {
9581
        vector<Button::TButton *>::iterator mapIter;
9582
 
9583
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9584
        {
9585
            Button::TButton *bt = *mapIter;
9586
 
9587
            if (btState == 0)
9588
                bt->setBitmapJustification(align, x, y, -1);
9589
            else
9590
                bt->setBitmapJustification(align, x, y, btState-1);
9591
        }
9592
    }
9593
}
9594
 
9595
void TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)
9596
{
9597
    DECL_TRACER("TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)");
9598
 
9599
    if (pars.size() < 1)
9600
    {
9601
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9602
        return;
9603
    }
9604
 
9605
    TError::clear();
9606
    int btState = atoi(pars[0].c_str());
9607
    int j, x, y;
9608
 
193 andreas 9609
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9610
 
9611
    if (TError::isError() || map.empty())
9612
        return;
9613
 
9614
    vector<Button::TButton *> buttons = collectButtons(map);
9615
 
9616
    if (buttons.size() > 0)
9617
    {
110 andreas 9618
        Button::TButton *bt = buttons[0];
108 andreas 9619
 
110 andreas 9620
        if (btState == 0)       // All instances?
108 andreas 9621
        {
110 andreas 9622
            int bst = bt->getNumberInstances();
108 andreas 9623
 
110 andreas 9624
            for (int i = 0; i < bst; i++)
108 andreas 9625
            {
110 andreas 9626
                j = bt->getBitmapJustification(&x, &y, i);
9627
                sendCustomEvent(i + 1, j, 0, "", 1005, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9628
            }
9629
        }
110 andreas 9630
        else
9631
        {
9632
            j = bt->getBitmapJustification(&x, &y, btState-1);
9633
            sendCustomEvent(btState, j, 0, "", 1005, bt->getChannelPort(), bt->getChannelNumber());
9634
        }
108 andreas 9635
    }
9636
}
9637
 
9638
/**
9639
 * Set icon alignment using a numeric keypad layout for those buttons with a
9640
 * defined address range. The alignment of 0 is followed by ',<left>,<top>'.
9641
 * The left and top coordinates are relative to the upper left corner of the
9642
 * button.
9643
 */
9644
void TPageManager::doJSI(int port, vector<int>& channels, vector<string>& pars)
9645
{
9646
    DECL_TRACER("TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)");
9647
 
9648
    if (pars.size() < 2)
9649
    {
9650
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
9651
        return;
9652
    }
9653
 
9654
    TError::clear();
9655
    int btState = atoi(pars[0].c_str());
9656
    int align = atoi(pars[1].c_str());
9657
    int x = 0, y = 0;
9658
 
9659
    if (!align && pars.size() >= 3)
9660
    {
9661
        x = atoi(pars[2].c_str());
9662
 
9663
        if (pars.size() >= 4)
9664
            y = atoi(pars[3].c_str());
9665
    }
9666
 
193 andreas 9667
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9668
 
9669
    if (TError::isError() || map.empty())
9670
        return;
9671
 
9672
    vector<Button::TButton *> buttons = collectButtons(map);
9673
 
9674
    if (buttons.size() > 0)
9675
    {
9676
        vector<Button::TButton *>::iterator mapIter;
9677
 
9678
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9679
        {
9680
            Button::TButton *bt = *mapIter;
9681
 
9682
            if (btState == 0)
9683
                bt->setIconJustification(align, x, y, -1);
9684
            else
9685
                bt->setIconJustification(align, x, y, btState-1);
9686
        }
9687
    }
9688
}
9689
 
9690
void TPageManager::getJSI(int port, vector<int>& channels, vector<string>& pars)
9691
{
9692
    DECL_TRACER("TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)");
9693
 
9694
    if (pars.size() < 1)
9695
    {
9696
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9697
        return;
9698
    }
9699
 
9700
    TError::clear();
9701
    int btState = atoi(pars[0].c_str());
9702
    int j, x, y;
9703
 
193 andreas 9704
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9705
 
9706
    if (TError::isError() || map.empty())
9707
        return;
9708
 
9709
    vector<Button::TButton *> buttons = collectButtons(map);
9710
 
9711
    if (buttons.size() > 0)
9712
    {
110 andreas 9713
        Button::TButton *bt = buttons[0];
108 andreas 9714
 
110 andreas 9715
        if (btState == 0)       // All instances?
108 andreas 9716
        {
110 andreas 9717
            int bst = bt->getNumberInstances();
108 andreas 9718
 
110 andreas 9719
            for (int i = 0; i < bst; i++)
108 andreas 9720
            {
110 andreas 9721
                j = bt->getIconJustification(&x, &y, i);
9722
                sendCustomEvent(i + 1, j, 0, "", 1006, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9723
            }
9724
        }
110 andreas 9725
        else
9726
        {
9727
            j = bt->getIconJustification(&x, &y, btState-1);
9728
            sendCustomEvent(btState, j, 0, "", 1006, bt->getChannelPort(), bt->getChannelNumber());
9729
        }
108 andreas 9730
    }
9731
}
9732
 
9733
void TPageManager::doJST(int port, vector<int>& channels, vector<string>& pars)
9734
{
9735
    DECL_TRACER("TPageManager::doJSB(int port, vector<int>& channels, vector<string>& pars)");
9736
 
9737
    if (pars.size() < 2)
9738
    {
9739
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
9740
        return;
9741
    }
9742
 
9743
    TError::clear();
9744
    int btState = atoi(pars[0].c_str());
9745
    int align = atoi(pars[1].c_str());
9746
    int x = 0, y = 0;
9747
 
9748
    if (!align && pars.size() >= 3)
9749
    {
9750
        x = atoi(pars[2].c_str());
9751
 
9752
        if (pars.size() >= 4)
9753
            y = atoi(pars[3].c_str());
9754
    }
9755
 
193 andreas 9756
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9757
 
9758
    if (TError::isError() || map.empty())
9759
        return;
9760
 
9761
    vector<Button::TButton *> buttons = collectButtons(map);
9762
 
9763
    if (buttons.size() > 0)
9764
    {
9765
        vector<Button::TButton *>::iterator mapIter;
9766
 
9767
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9768
        {
9769
            Button::TButton *bt = *mapIter;
9770
 
9771
            if (btState == 0)
9772
                bt->setTextJustification(align, x, y, -1);
9773
            else
9774
                bt->setTextJustification(align, x, y, btState-1);
9775
        }
9776
    }
9777
}
9778
 
9779
void TPageManager::getJST(int port, vector<int>& channels, vector<string>& pars)
9780
{
9781
    DECL_TRACER("TPageManager::getJSB(int port, vector<int>& channels, vector<string>& pars)");
9782
 
9783
    if (pars.size() < 1)
9784
    {
9785
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9786
        return;
9787
    }
9788
 
9789
    TError::clear();
9790
    int btState = atoi(pars[0].c_str());
9791
    int j, x, y;
9792
 
193 andreas 9793
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9794
 
9795
    if (TError::isError() || map.empty())
9796
        return;
9797
 
9798
    vector<Button::TButton *> buttons = collectButtons(map);
9799
 
9800
    if (buttons.size() > 0)
9801
    {
110 andreas 9802
        Button::TButton *bt = buttons[0];
108 andreas 9803
 
110 andreas 9804
        if (btState == 0)       // All instances?
108 andreas 9805
        {
110 andreas 9806
            int bst = bt->getNumberInstances();
108 andreas 9807
 
110 andreas 9808
            for (int i = 0; i < bst; i++)
108 andreas 9809
            {
110 andreas 9810
                j = bt->getTextJustification(&x, &y, i);
9811
                sendCustomEvent(i + 1, j, 0, "", 1004, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 9812
            }
9813
        }
110 andreas 9814
        else
9815
        {
9816
            j = bt->getTextJustification(&x, &y, btState-1);
9817
            sendCustomEvent(btState, j, 0, "", 1004, bt->getChannelPort(), bt->getChannelNumber());
9818
        }
108 andreas 9819
    }
9820
}
9821
 
9822
/**
395 andreas 9823
 * @brief TPageManager::getMSP
9824
 * Sets the speed of a marquee line. Allowed range is from 1 to 10, where 10 is
9825
 * the fastest speed.
9826
 *
9827
 * @param port      The port number
9828
 * @param channels  The channels
9829
 * @param pars      Parameters
9830
 */
9831
void TPageManager::doMSP(int port, vector<int>& channels, vector<string>& pars)
9832
{
9833
    DECL_TRACER("TPageManager::getMSP(int port, vector<int>& channels, vector<string>& pars)");
9834
 
9835
    if (pars.size() < 2)
9836
    {
9837
        MSG_ERROR("Expecting at least 2 parameter but got less! Command ignored.");
9838
        return;
9839
    }
9840
 
9841
    TError::clear();
9842
    int btState = atoi(pars[0].c_str()) - 1;
9843
    int speed = atoi(pars[1].c_str());
9844
 
9845
    if (speed < 1 || speed > 10)
9846
    {
9847
        MSG_ERROR("Speed for marquee line is out of range!");
9848
        return;
9849
    }
9850
 
9851
    vector<TMap::MAP_T> map = findButtons(port, channels);
9852
 
9853
    if (TError::isError() || map.empty())
9854
        return;
9855
 
9856
    vector<Button::TButton *> buttons = collectButtons(map);
9857
 
9858
    if (buttons.size() > 0)
9859
    {
9860
        vector<Button::TButton *>::iterator iter;
9861
 
9862
        for (iter = buttons.begin(); iter != buttons.end(); ++iter)
9863
        {
9864
            Button::TButton *bt = buttons[0];
9865
            bt->setMarqueeSpeed(speed, btState);
9866
        }
9867
    }
9868
}
9869
 
9870
/**
16 andreas 9871
 * Show or hide a button with a set variable text range.
9872
 */
9873
void TPageManager::doSHO(int port, vector<int>& channels, vector<string>& pars)
9874
{
9875
    DECL_TRACER("TPageManager::doSHO(int port, vector<int>& channels, vector<string>& pars)");
9876
 
9877
    if (pars.empty())
9878
    {
9879
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
9880
        return;
9881
    }
9882
 
9883
    TError::clear();
9884
    int cvalue = atoi(pars[0].c_str());
9885
 
193 andreas 9886
    vector<TMap::MAP_T> map = findButtons(port, channels);
16 andreas 9887
 
9888
    if (TError::isError() || map.empty())
9889
        return;
9890
 
9891
    vector<Button::TButton *> buttons = collectButtons(map);
9892
 
83 andreas 9893
    if (buttons.size() > 0)
16 andreas 9894
    {
83 andreas 9895
        vector<Button::TButton *>::iterator mapIter;
9896
 
9897
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9898
        {
9899
            Button::TButton *bt = *mapIter;
318 andreas 9900
 
100 andreas 9901
            int pgID = (bt->getParent() >> 16) & 0x0000ffff;
9902
            bool pVisible = false;
9903
 
9904
            if (pgID < 500)
9905
            {
9906
                TPage *pg = getPage(pgID);
9907
 
9908
                if (pg && pg->isVisilble())
9909
                    pVisible = true;
9910
            }
9911
            else
9912
            {
9913
                TSubPage *pg = getSubPage(pgID);
9914
 
9915
                if (pg && pg->isVisible())
9916
                    pVisible = true;
9917
            }
9918
 
151 andreas 9919
            bool oldV = bt->isVisible();
9920
            bool visible = cvalue ? true : false;
9921
            MSG_DEBUG("Button " << bt->getButtonIndex() << ", \"" << bt->getButtonName() << "\" set " << (visible ? "VISIBLE" : "HIDDEN") << " (Previous: " << (oldV ? "VISIBLE" : "HIDDEN") << ")");
98 andreas 9922
 
151 andreas 9923
            if (visible != oldV)
100 andreas 9924
            {
151 andreas 9925
                bt->setVisible(visible);
100 andreas 9926
 
151 andreas 9927
                if (pVisible)
9928
                {
9929
                    setButtonCallbacks(bt);
9930
 
9931
                    if (_setVisible)
9932
                        _setVisible(bt->getHandle(), visible);
9933
                    else
9934
                        bt->refresh();
9935
                }
100 andreas 9936
            }
83 andreas 9937
        }
16 andreas 9938
    }
9939
}
9940
 
108 andreas 9941
void TPageManager::doTEC(int port, vector<int>& channels, vector<string>& pars)
9942
{
9943
    DECL_TRACER("TPageManager::doTEC(int port, vector<int>& channels, vector<string>& pars)");
9944
 
9945
    if (pars.size() < 2)
9946
    {
9947
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
9948
        return;
9949
    }
9950
 
9951
    TError::clear();
9952
    int btState = atoi(pars[0].c_str());
9953
    string color = pars[1];
9954
 
193 andreas 9955
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9956
 
9957
    if (TError::isError() || map.empty())
9958
        return;
9959
 
9960
    vector<Button::TButton *> buttons = collectButtons(map);
9961
 
9962
    if (buttons.size() > 0)
9963
    {
9964
        vector<Button::TButton *>::iterator mapIter;
9965
 
9966
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
9967
        {
9968
            Button::TButton *bt = *mapIter;
9969
 
9970
            if (btState == 0)
9971
                bt->setTextEffectColor(color);
9972
            else
9973
                bt->setTextEffectColor(color, btState-1);
9974
        }
9975
    }
9976
}
9977
 
9978
void TPageManager::getTEC(int port, vector<int>& channels, vector<string>& pars)
9979
{
9980
    DECL_TRACER("TPageManager::getTEC(int port, vector<int>& channels, vector<string>& pars)");
9981
 
9982
    if (pars.size() < 1)
9983
    {
9984
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
9985
        return;
9986
    }
9987
 
9988
    TError::clear();
9989
    int btState = atoi(pars[0].c_str());
9990
 
193 andreas 9991
    vector<TMap::MAP_T> map = findButtons(port, channels);
108 andreas 9992
 
9993
    if (TError::isError() || map.empty())
9994
        return;
9995
 
9996
    vector<Button::TButton *> buttons = collectButtons(map);
9997
 
9998
    if (buttons.size() > 0)
9999
    {
110 andreas 10000
        Button::TButton *bt = buttons[0];
10001
 
10002
        if (btState == 0)       // All instances?
10003
        {
10004
            int bst = bt->getNumberInstances();
10005
 
10006
            for (int i = 0; i < bst; i++)
10007
            {
10008
                string c = bt->getTextEffectColor(i);
300 andreas 10009
                sendCustomEvent(i + 1, (int)c.length(), 0, c, 1009, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 10010
            }
10011
        }
10012
        else
10013
        {
10014
            string c = bt->getTextEffectColor(btState-1);
300 andreas 10015
            sendCustomEvent(btState, (int)c.length(), 0, c, 1009, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 10016
        }
10017
    }
10018
}
10019
 
10020
void TPageManager::doTEF(int port, vector<int>& channels, vector<string>& pars)
10021
{
10022
    DECL_TRACER("TPageManager::doTEF(int port, vector<int>& channels, vector<string>& pars)");
10023
 
10024
    if (pars.size() < 2)
10025
    {
10026
        MSG_ERROR("Expecting at least 2 parameters but got less! Ignoring command.");
10027
        return;
10028
    }
10029
 
10030
    TError::clear();
10031
    int btState = atoi(pars[0].c_str());
10032
    string tef = pars[1];
10033
 
193 andreas 10034
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 10035
 
10036
    if (TError::isError() || map.empty())
10037
        return;
10038
 
10039
    vector<Button::TButton *> buttons = collectButtons(map);
10040
 
10041
    if (buttons.size() > 0)
10042
    {
108 andreas 10043
        vector<Button::TButton *>::iterator mapIter;
10044
 
10045
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10046
        {
10047
            Button::TButton *bt = *mapIter;
10048
 
110 andreas 10049
            if (btState == 0)
10050
                bt->setTextEffectName(tef);
10051
            else
10052
                bt->setTextEffectName(tef, btState-1);
10053
        }
10054
    }
10055
}
108 andreas 10056
 
110 andreas 10057
void TPageManager::getTEF(int port, vector<int>& channels, vector<string>& pars)
10058
{
10059
    DECL_TRACER("TPageManager::getTEF(int port, vector<int>& channels, vector<string>& pars)");
108 andreas 10060
 
110 andreas 10061
    if (pars.size() < 1)
10062
    {
10063
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
10064
        return;
10065
    }
108 andreas 10066
 
110 andreas 10067
    TError::clear();
10068
    int btState = atoi(pars[0].c_str());
10069
 
193 andreas 10070
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 10071
 
10072
    if (TError::isError() || map.empty())
10073
        return;
10074
 
10075
    vector<Button::TButton *> buttons = collectButtons(map);
10076
 
10077
    if (buttons.size() > 0)
10078
    {
10079
        Button::TButton *bt = buttons[0];
10080
 
10081
        if (btState == 0)       // All instances?
10082
        {
10083
            int bst = bt->getNumberInstances();
10084
 
10085
            for (int i = 0; i < bst; i++)
108 andreas 10086
            {
110 andreas 10087
                string c = bt->getTextEffectName(i);
300 andreas 10088
                sendCustomEvent(i + 1, (int)c.length(), 0, c, 1008, bt->getChannelPort(), bt->getChannelNumber());
108 andreas 10089
            }
10090
        }
110 andreas 10091
        else
10092
        {
10093
            string c = bt->getTextEffectName(btState-1);
300 andreas 10094
            sendCustomEvent(btState, (int)c.length(), 0, c, 1008, bt->getChannelPort(), bt->getChannelNumber());
110 andreas 10095
        }
108 andreas 10096
    }
10097
}
10098
 
16 andreas 10099
/**
14 andreas 10100
 * Assign a text string to those buttons with a defined address range.
10101
 * Sets Non-Unicode text.
10102
 */
10103
void TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)
10104
{
10105
    DECL_TRACER("TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)");
10106
 
10107
    if (pars.size() < 1)
10108
    {
10109
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
331 andreas 10110
#if TESTMODE == 1
334 andreas 10111
        setAllDone();
331 andreas 10112
#endif
14 andreas 10113
        return;
10114
    }
10115
 
16 andreas 10116
    TError::clear();
333 andreas 10117
    int btState = atoi(pars[0].c_str()) - 1;
14 andreas 10118
    string text;
10119
 
333 andreas 10120
    // Every comma (,) in the text produces a new parameter. Therefor we must
10121
    // concatenate this parameters together and insert the comma.
14 andreas 10122
    if (pars.size() > 1)
150 andreas 10123
    {
10124
        for (size_t i = 1; i < pars.size(); ++i)
10125
        {
10126
            if (i > 1)
10127
                text += ",";
14 andreas 10128
 
150 andreas 10129
            text += pars[i];
10130
        }
10131
    }
10132
 
193 andreas 10133
    vector<TMap::MAP_T> map = findButtons(port, channels);
14 andreas 10134
 
10135
    if (TError::isError() || map.empty())
331 andreas 10136
    {
10137
#if TESTMODE == 1
334 andreas 10138
        setAllDone();
331 andreas 10139
#endif
14 andreas 10140
        return;
331 andreas 10141
    }
14 andreas 10142
 
10143
    vector<Button::TButton *> buttons = collectButtons(map);
10144
 
83 andreas 10145
    if (buttons.size() > 0)
14 andreas 10146
    {
83 andreas 10147
        vector<Button::TButton *>::iterator mapIter;
14 andreas 10148
 
333 andreas 10149
        for (mapIter = buttons.begin(); mapIter != buttons.end(); ++mapIter)
14 andreas 10150
        {
83 andreas 10151
            Button::TButton *bt = *mapIter;
14 andreas 10152
 
252 andreas 10153
            if (!bt)
333 andreas 10154
                continue;
252 andreas 10155
 
333 andreas 10156
            bt->setText(text, btState);
331 andreas 10157
#if TESTMODE == 1
333 andreas 10158
            if (_gTestMode)
10159
                _gTestMode->setResult(bt->getText(btState < 0 ? 0 : btState));
331 andreas 10160
 
333 andreas 10161
            __success = true;
331 andreas 10162
#endif
14 andreas 10163
        }
10164
    }
331 andreas 10165
#if TESTMODE == 1
334 andreas 10166
    setDone();
331 andreas 10167
#endif
14 andreas 10168
}
21 andreas 10169
 
110 andreas 10170
void TPageManager::getTXT(int port, vector<int>& channels, vector<string>& pars)
10171
{
10172
    DECL_TRACER("TPageManager::getTXT(int port, vector<int>& channels, vector<string>& pars)");
10173
 
10174
    if (pars.size() < 1)
10175
    {
10176
        MSG_ERROR("Expecting at least 1 parameter but got " << pars.size() << "! Ignoring command.");
10177
        return;
10178
    }
10179
 
10180
    TError::clear();
10181
    int btState = atoi(pars[0].c_str());
10182
 
193 andreas 10183
    vector<TMap::MAP_T> map = findButtons(port, channels);
110 andreas 10184
 
10185
    if (TError::isError() || map.empty())
10186
        return;
10187
 
10188
    vector<Button::TButton *> buttons = collectButtons(map);
10189
 
10190
    if (buttons.size() > 0)
10191
    {
10192
        Button::TButton *bt = buttons[0];
10193
 
10194
        if (btState == 0)       // All instances?
10195
        {
10196
            int bst = bt->getNumberInstances();
10197
 
10198
            for (int i = 0; i < bst; i++)
10199
            {
10200
                string c = bt->getText(i);
300 andreas 10201
                sendCustomEvent(i + 1, (int)c.length(), 0, c, 1001, bt->getChannelPort(), bt->getChannelNumber());
333 andreas 10202
#if TESTMODE == 1
10203
                if (_gTestMode)
10204
                    _gTestMode->setResult(c);
10205
#endif
110 andreas 10206
            }
10207
        }
10208
        else
10209
        {
10210
            string c = bt->getText(btState-1);
300 andreas 10211
            sendCustomEvent(btState, (int)c.length(), 0, c, 1001, bt->getChannelPort(), bt->getChannelNumber());
333 andreas 10212
#if TESTMODE == 1
10213
            if (_gTestMode)
10214
                _gTestMode->setResult(c);
10215
#endif
110 andreas 10216
        }
10217
    }
334 andreas 10218
#if TESTMODE == 1
10219
    setAllDone();
10220
#endif
110 andreas 10221
}
10222
 
97 andreas 10223
/*
104 andreas 10224
 * Set button state legacy unicode text command.
10225
 *
10226
 * Set Unicode text in the legacy G4 format. For the ^UNI command, the Unicode
10227
 * text is sent as ASCII-HEX nibbles.
10228
 */
10229
void TPageManager::doUNI(int port, vector<int>& channels, vector<string>& pars)
10230
{
10231
    DECL_TRACER("TPageManager::doUNI(int port, vector<int>& channels, vector<string>& pars)");
10232
 
10233
    if (pars.size() < 1)
10234
    {
10235
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
331 andreas 10236
#if TESTMODE == 1
334 andreas 10237
        setAllDone();
331 andreas 10238
#endif
104 andreas 10239
        return;
10240
    }
10241
 
10242
    TError::clear();
333 andreas 10243
    int btState = atoi(pars[0].c_str()) - 1;
104 andreas 10244
    string text;
10245
 
361 andreas 10246
    // Unicode is the stadard character set used by Windows internally. It
10247
    // consists of 16 bit unsiged numbers. This can't be transported into a
10248
    // standard character string because a NULL byte means end of string.
10249
    // Therefor we must convert it to UFT-8.
104 andreas 10250
    if (pars.size() > 1)
10251
    {
10252
        string byte;
361 andreas 10253
        std::wstring uni;
104 andreas 10254
        size_t pos = 0;
10255
 
10256
        while (pos < pars[1].length())
10257
        {
361 andreas 10258
            byte = pars[1].substr(pos, 4);
10259
            wchar_t ch = (char)strtol(byte.c_str(), NULL, 16);
10260
            uni += ch;
10261
            pos += 4;
104 andreas 10262
        }
361 andreas 10263
 
10264
        text = UnicodeToUTF8(uni);
104 andreas 10265
    }
10266
 
193 andreas 10267
    vector<TMap::MAP_T> map = findButtons(port, channels);
104 andreas 10268
 
10269
    if (TError::isError() || map.empty())
331 andreas 10270
    {
10271
#if TESTMODE == 1
334 andreas 10272
        setAllDone();
331 andreas 10273
#endif
104 andreas 10274
        return;
331 andreas 10275
    }
104 andreas 10276
 
10277
    vector<Button::TButton *> buttons = collectButtons(map);
10278
 
10279
    if (buttons.size() > 0)
10280
    {
10281
        vector<Button::TButton *>::iterator mapIter;
10282
 
10283
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10284
        {
10285
            Button::TButton *bt = *mapIter;
10286
 
331 andreas 10287
#if TESTMODE == 1
333 andreas 10288
            bool res = bt->setText(text, btState);
104 andreas 10289
 
333 andreas 10290
            if (_gTestMode)
10291
                _gTestMode->setResult(bt->getText(btState < 0 ? 0 : btState));
331 andreas 10292
 
333 andreas 10293
            __success = res;
10294
#else
10295
            bt->setText(text, btState);
331 andreas 10296
#endif
104 andreas 10297
        }
10298
    }
334 andreas 10299
#if TESTMODE == 1
10300
    setDone();
10301
#endif
104 andreas 10302
}
10303
 
10304
void TPageManager::doUTF(int port, vector<int>& channels, vector<string>& pars)
10305
{
10306
    DECL_TRACER("TPageManager::doTXT(int port, vector<int>& channels, vector<string>& pars)");
10307
 
10308
    if (pars.size() < 1)
10309
    {
10310
        MSG_ERROR("Expecting 1 parameters but got none! Ignoring command.");
10311
        return;
10312
    }
10313
 
10314
    TError::clear();
10315
    int btState = atoi(pars[0].c_str());
10316
    string text;
10317
 
10318
    if (pars.size() > 1)
150 andreas 10319
    {
10320
        for (size_t i = 1; i < pars.size(); ++i)
10321
        {
10322
            if (i > 1)
10323
                text += ",";
104 andreas 10324
 
150 andreas 10325
            text += pars[i];
10326
        }
10327
    }
10328
 
193 andreas 10329
    vector<TMap::MAP_T> map = findButtons(port, channels);
104 andreas 10330
 
10331
    if (TError::isError() || map.empty())
10332
        return;
10333
 
10334
    vector<Button::TButton *> buttons = collectButtons(map);
10335
 
10336
    if (buttons.size() > 0)
10337
    {
10338
        vector<Button::TButton *>::iterator mapIter;
10339
 
10340
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10341
        {
10342
            Button::TButton *bt = *mapIter;
10343
 
10344
            if (btState == 0)       // All instances?
10345
            {
10346
                int bst = bt->getNumberInstances();
10347
 
10348
                for (int i = 0; i < bst; i++)
10349
                    bt->setText(text, i);
10350
            }
10351
            else
10352
                bt->setText(text, btState - 1);
10353
        }
10354
    }
10355
}
111 andreas 10356
 
361 andreas 10357
/**
10358
 * Simulates a touch/release/pulse at the given coordinate. If the push event
10359
 * is less then 0 or grater than 2 the command is ignored. It is also ignored
10360
 * if the x and y coordinate is out of range. The range must be between 0 and
10361
 * the maximum with and height.
10362
 */
148 andreas 10363
void TPageManager::doVTP (int, vector<int>&, vector<string>& pars)
10364
{
10365
    DECL_TRACER("TPageManager::doVTP (int, vector<int>&, vector<string>& pars)");
10366
 
10367
    if (pars.size() < 3)
10368
    {
10369
        MSG_ERROR("Expected 3 parameters but got only " << pars.size() << " parameters!");
10370
        return;
10371
    }
10372
 
10373
    int pushType = atoi(pars[0].c_str());
10374
    int x = atoi(pars[1].c_str());
10375
    int y = atoi(pars[2].c_str());
10376
 
10377
    if (pushType < 0 || pushType > 2)
10378
    {
10379
        MSG_ERROR("Invalid push type " << pushType << ". Ignoring command!");
10380
        return;
10381
    }
10382
 
217 andreas 10383
    if (x < 0 || x > mTSettings->getWidth() || y < 0 || y > mTSettings->getHeight())
148 andreas 10384
    {
10385
        MSG_ERROR("Illegal coordinates " << x << " x " << y << ". Ignoring command!");
10386
        return;
10387
    }
10388
 
10389
    if (pushType == 0 || pushType == 2)
10390
        mouseEvent(x, y, true);
10391
 
10392
    if (pushType == 1 || pushType == 2)
10393
        mouseEvent(x, y, false);
10394
}
10395
 
400 andreas 10396
 
111 andreas 10397
/**
10398
 * Set the keyboard passthru.
10399
 */
10400
void TPageManager::doKPS(int, vector<int>&, vector<string>& pars)
10401
{
10402
    DECL_TRACER("TPageManager::doKPS(int, vector<int>&, vector<string>& pars)");
10403
 
10404
    if (pars.size() < 1)
10405
    {
10406
        MSG_ERROR("Got no parameter. Ignoring command!");
10407
        return;
10408
    }
10409
 
10410
    int state = atoi(pars[0].c_str());
10411
 
10412
    if (state == 0)
10413
        mPassThrough = false;
10414
    else if (state == 5)
10415
        mPassThrough = true;
10416
}
10417
 
400 andreas 10418
void TPageManager::doVKS(int, vector<int>&, vector<string>& pars)
111 andreas 10419
{
400 andreas 10420
    DECL_TRACER("TPageManager::doVKS(int, vector<int>&, vector<string>& pars)");
111 andreas 10421
 
10422
    if (pars.size() < 1)
10423
    {
10424
        MSG_ERROR("Got no parameter. Ignoring command!");
10425
        return;
10426
    }
10427
 
10428
    if (_sendVirtualKeys)
10429
        _sendVirtualKeys(pars[0]);
10430
}
10431
 
400 andreas 10432
void TPageManager::doLPB(int port, vector<int>& channels, vector<string>& pars)
10433
{
10434
    DECL_TRACER("TPageManager::doLPB(int port, vector<int>& channels, vector<string>& pars)");
10435
 
10436
    if (pars.size() < 1)
10437
        return;
10438
 
10439
    TError::clear();
10440
    string passwd = pars[0];
10441
    vector<TMap::MAP_T> map = findButtons(port, channels);
10442
 
10443
    if (TError::isError() || map.empty())
10444
        return;
10445
 
10446
    vector<Button::TButton *> buttons = collectButtons(map);
10447
 
10448
    if (buttons.size() > 0)
10449
    {
10450
        vector<Button::TButton *>::iterator mapIter;
10451
 
10452
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10453
        {
10454
            Button::TButton *bt = *mapIter;
10455
            bt->setUserName(passwd);
10456
        }
10457
    }
10458
}
10459
 
401 andreas 10460
void TPageManager::doLPC(int, vector<int>&, vector<string>&)
400 andreas 10461
{
401 andreas 10462
    DECL_TRACER("TPageManager::doLPC(int, vector<int>&, vector<string>&)");
400 andreas 10463
 
10464
    TConfig::clearUserPasswords();
10465
}
10466
 
10467
void TPageManager::doLPR(int, vector<int>&, vector<string>& pars)
10468
{
10469
    DECL_TRACER("TPageManager::doLPR(int, vector<int>&, vector<string>& pars)");
10470
 
10471
    if (pars.size() < 1)
10472
        return;
10473
 
10474
    string user = pars[0];
10475
    TConfig::clearUserPassword(user);
10476
}
10477
 
10478
void TPageManager::doLPS(int, vector<int>&, vector<string>& pars)
10479
{
10480
    DECL_TRACER("TPageManager::doLPS(int, vector<int>&, vector<string>& pars)");
10481
 
10482
    if (pars.size() < 2)
10483
        return;
10484
 
10485
    string user = pars[0];
10486
    string password;
10487
 
10488
    // In case the password contains one or more comma (,), the password is
10489
    // splitted. The following loop concatenates the password into one. Because
10490
    // the comma is lost, we must add it again.
10491
    for (size_t i = 0; i < pars.size(); ++i)
10492
    {
10493
        if (i > 0)
10494
            password += ",";
10495
 
10496
        password += pars[i];
10497
    }
10498
 
10499
    TConfig::setUserPassword(user, password);
10500
}
10501
 
104 andreas 10502
/*
400 andreas 10503
 * Set the page flip password. @PWD sets the level 1 password only.
10504
 */
10505
void TPageManager::doAPWD(int, vector<int>&, vector<string>& pars)
10506
{
10507
    DECL_TRACER("TPageManager::doPWD(int port, vector<int>&, vector<string>& pars)");
10508
 
10509
    if (pars.size() < 1)
10510
    {
10511
        MSG_ERROR("Got less then 1 parameter!");
10512
        return;
10513
    }
10514
 
10515
    string password;
10516
    // In case the password contains one or more comma (,), the password is
10517
    // splitted. The following loop concatenates the password into one. Because
10518
    // the comma is lost, we must add it again.
10519
    for (size_t i = 0; i < pars.size(); ++i)
10520
    {
10521
        if (i > 0)
10522
            password += ",";
10523
 
10524
        password += pars[i];
10525
    }
10526
 
10527
    TConfig::savePassword1(password);
10528
}
10529
 
10530
/*
10531
 * Set the page flip password. Password level is required and must be 1 - 4
10532
 */
10533
void TPageManager::doPWD(int, vector<int>&, vector<string>& pars)
10534
{
10535
    DECL_TRACER("TPageManager::doPWD(int, vector<int>&, vector<string>& pars)");
10536
 
10537
    if (pars.size() < 2)
10538
    {
10539
        MSG_ERROR("Got less then 2 parameters!");
10540
        return;
10541
    }
10542
 
10543
    int pwIdx = atoi(pars[0].c_str());
10544
    string password;
10545
    // In case the password contains one or more comma (,), the password is
10546
    // splitted. The following loop concatenates the password into one. Because
10547
    // the comma is lost, we must add it again.
10548
    for (size_t i = 1; i < pars.size(); ++i)
10549
    {
10550
        if (i > 1)
10551
            password += ",";
10552
 
10553
        password += pars[i];
10554
    }
10555
 
10556
    switch(pwIdx)
10557
    {
10558
        case 1: TConfig::savePassword1(password); break;
10559
        case 2: TConfig::savePassword2(password); break;
10560
        case 3: TConfig::savePassword3(password); break;
10561
        case 4: TConfig::savePassword4(password); break;
10562
    }
10563
}
10564
 
10565
/*
97 andreas 10566
 * Set the bitmap of a button to use a particular resource.
10567
 * Syntax:
10568
 *    "'^BBR-<vt addr range>,<button states range>,<resource name>'"
10569
 * Variable:
10570
 *    variable text address range = 1 - 4000.
10571
 *    button states range = 1 - 256 for multi-state buttons (0 = All states, for General buttons 1 = Off state and 2 = On state).
10572
 *    resource name = 1 - 50 ASCII characters.
10573
 * Example:
10574
 *    SEND_COMMAND Panel,"'^BBR-700,1,Sports_Image'"
10575
 *    Sets the resource name of the button to ’Sports_Image’.
10576
 */
21 andreas 10577
void TPageManager::doBBR(int port, vector<int>& channels, vector<string>& pars)
10578
{
10579
    DECL_TRACER("TPageManager::doBBR(int port, vector<int>& channels, vector<string>& pars)");
10580
 
10581
    if (pars.size() < 2)
10582
    {
10583
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
10584
        return;
10585
    }
10586
 
10587
    TError::clear();
10588
    int btState = atoi(pars[0].c_str());
10589
    string resName = pars[1];
10590
 
193 andreas 10591
    vector<TMap::MAP_T> map = findButtons(port, channels);
21 andreas 10592
 
10593
    if (TError::isError() || map.empty())
10594
        return;
10595
 
10596
    vector<Button::TButton *> buttons = collectButtons(map);
10597
 
83 andreas 10598
    if (buttons.size() > 0)
21 andreas 10599
    {
83 andreas 10600
        vector<Button::TButton *>::iterator mapIter;
21 andreas 10601
 
83 andreas 10602
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
21 andreas 10603
        {
83 andreas 10604
            Button::TButton *bt = *mapIter;
252 andreas 10605
//            setButtonCallbacks(bt);
21 andreas 10606
 
83 andreas 10607
            if (btState == 0)       // All instances?
10608
            {
10609
                int bst = bt->getNumberInstances();
10610
                MSG_DEBUG("Setting BBR on all " << bst << " instances...");
10611
 
10612
                for (int i = 0; i < bst; i++)
10613
                    bt->setResourceName(resName, i);
10614
            }
10615
            else
10616
                bt->setResourceName(resName, btState - 1);
97 andreas 10617
 
10618
            if (bt->isVisible())
10619
                bt->refresh();
99 andreas 10620
            else if (_setVisible)
10621
                _setVisible(bt->getHandle(), false);
21 andreas 10622
        }
10623
    }
10624
}
10625
 
97 andreas 10626
/*
10627
 * Add new resources
10628
 * Adds any and all resource parameters by sending embedded codes and data.
10629
 * Since the embedded codes are preceded by a '%' character, any '%' character
10630
 * contained in* the URL must be escaped with a second '%' character (see
10631
 * example).
10632
 * The file name field (indicated by a %F embedded code) may contain special
10633
 * escape sequences as shown in the ^RAF, ^RMF.
10634
 * Syntax:
10635
 *    "'^RAF-<resource name>,<data>'"
10636
 * Variables:
10637
 *    resource name = 1 - 50 ASCII characters.
10638
 *    data = Refers to the embedded codes, see the ^RAF, ^RMF.
10639
 * Example:
10640
 *    SEND_COMMAND Panel,"'^RAF-New Image,%P0%HAMX.COM%ALab/Test%%5Ffile%Ftest.jpg'"
10641
 *    Adds a new resource.
10642
 *    The resource name is ’New Image’
10643
 *    %P (protocol) is an HTTP
10644
 *    %H (host name) is AMX.COM
10645
 *    %A (file path) is Lab/Test_f ile
10646
 *    %F (file name) is test.jpg.
10647
 *    Note that the %%5F in the file path is actually encoded as %5F.
10648
 */
10649
void TPageManager::doRAF(int, vector<int>&, vector<string>& pars)
10650
{
10651
    DECL_TRACER("TPageManager::doRAF(int port, vector<int>& channels, vector<string>& pars)");
10652
 
10653
    if (pars.size() < 2)
10654
    {
10655
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
10656
        return;
10657
    }
10658
 
10659
    string name = pars[0];
10660
    string data = pars[1];
10661
 
10662
    vector<string> parts = StrSplit(data, "%");
10663
    RESOURCE_T res;
10664
 
10665
    if (parts.size() > 0)
10666
    {
10667
        vector<string>::iterator sIter;
10668
 
10669
        for (sIter = parts.begin(); sIter != parts.end(); sIter++)
10670
        {
10671
            const char *s = sIter->c_str();
10672
            string ss = *sIter;
10673
            MSG_DEBUG("Parsing \"" << ss << "\" with token << " << ss[0]);
10674
 
10675
            switch(*s)
10676
            {
10677
                case 'P':
10678
                    if (*(s+1) == '0')
10679
                        res.protocol = "HTTP";
10680
                    else
10681
                        res.protocol = "FTP";
10682
                    break;
10683
 
10684
                case 'U': res.user = sIter->substr(1); break;
10685
                case 'S': res.password = sIter->substr(1); break;
10686
                case 'H': res.host = sIter->substr(1); break;
10687
                case 'F': res.file = sIter->substr(1); break;
10688
                case 'A': res.path = sIter->substr(1); break;
10689
                case 'R': res.refresh = atoi(sIter->substr(1).c_str()); break;
10690
 
10691
                default:
10692
                    MSG_WARNING("Option " << sIter->at(0) << " is currently not implemented!");
10693
            }
10694
        }
10695
 
10696
        if (gPrjResources)
10697
            gPrjResources->addResource(name, res.protocol, res.host, res.path, res.file, res.user, res.password, res.refresh);
10698
    }
10699
}
10700
 
111 andreas 10701
void TPageManager::doRFR(int, vector<int>&, vector<string>& pars)
97 andreas 10702
{
10703
    DECL_TRACER("TPageManager::doRFR(int port, vector<int>& channels, vector<string>& pars)");
10704
 
10705
    if (pars.size() < 1)
10706
    {
10707
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
10708
        return;
10709
    }
10710
 
10711
    string name = pars[0];
193 andreas 10712
    vector<TMap::MAP_T> map = findButtonByName(name);
97 andreas 10713
 
10714
    if (TError::isError() || map.empty())
10715
        return;
10716
 
10717
    vector<Button::TButton *> buttons = collectButtons(map);
10718
 
10719
    if (buttons.size() > 0)
10720
    {
10721
        vector<Button::TButton *>::iterator mapIter;
10722
 
10723
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
10724
        {
10725
            Button::TButton *bt = *mapIter;
10726
 
10727
            if (bt->isVisible())
10728
            {
252 andreas 10729
//                setButtonCallbacks(bt);
97 andreas 10730
                bt->refresh();
10731
            }
10732
        }
10733
    }
10734
}
10735
 
10736
/*
10737
 * Modify an existing resource
10738
 *
10739
 * Modifies any and all resource parameters by sending embedded codes and data.
10740
 * Since the embedded codes are preceded by a '%' character, any '%' character
10741
 * contained in the URL must be escaped with a second '%' character (see
10742
 * example).
10743
 * The file name field (indicated by a %F embedded code) may contain special
10744
 * escape sequences as shown in the ^RAF.
10745
 *
10746
 * Syntax:
10747
 * "'^RMF-<resource name>,<data>'"
10748
 * Variables:
10749
 *   • resource name = 1 - 50 ASCII characters
10750
 *   • data = Refers to the embedded codes, see the ^RAF, ^RMF.
10751
 * Example:
10752
 *   SEND_COMMAND Panel,"'^RMF-Sports_Image,%ALab%%5FTest/Images%Ftest.jpg'"
10753
 * Changes the resource ’Sports_Image’ file name to ’test.jpg’ and the path to
10754
 * ’Lab_Test/Images’.
10755
 * Note that the %%5F in the file path is actually encoded as %5F.
10756
 */
22 andreas 10757
void TPageManager::doRMF(int, vector<int>&, vector<string>& pars)
21 andreas 10758
{
10759
    DECL_TRACER("TPageManager::doRMF(int port, vector<int>& channels, vector<string>& pars)");
10760
 
10761
    if (pars.size() < 2)
10762
    {
10763
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
10764
        return;
10765
    }
10766
 
10767
    string name = pars[0];
10768
    string data = pars[1];
10769
 
10770
    vector<string> parts = StrSplit(data, "%");
10771
    RESOURCE_T res;
10772
 
83 andreas 10773
    if (parts.size() > 0)
21 andreas 10774
    {
83 andreas 10775
        vector<string>::iterator sIter;
21 andreas 10776
 
83 andreas 10777
        for (sIter = parts.begin(); sIter != parts.end(); sIter++)
21 andreas 10778
        {
83 andreas 10779
            const char *s = sIter->c_str();
10780
            string ss = *sIter;
10781
            MSG_DEBUG("Parsing \"" << ss << "\" with token << " << ss[0]);
21 andreas 10782
 
83 andreas 10783
            switch(*s)
10784
            {
10785
                case 'P':
10786
                    if (*(s+1) == '0')
10787
                        res.protocol = "HTTP";
10788
                    else
10789
                        res.protocol = "FTP";
10790
                break;
21 andreas 10791
 
83 andreas 10792
                case 'U': res.user = sIter->substr(1); break;
10793
                case 'S': res.password = sIter->substr(1); break;
10794
                case 'H': res.host = sIter->substr(1); break;
10795
                case 'F': res.file = sIter->substr(1); break;
10796
                case 'A': res.path = sIter->substr(1); break;
10797
                case 'R': res.refresh = atoi(sIter->substr(1).c_str()); break;
10798
 
10799
                default:
10800
                    MSG_WARNING("Option " << sIter->at(0) << " is currently not implemented!");
10801
            }
21 andreas 10802
        }
83 andreas 10803
 
10804
        if (gPrjResources)
10805
            gPrjResources->setResource(name, res.protocol, res.host, res.path, res.file, res.user, res.password, res.refresh);
21 andreas 10806
    }
10807
}
62 andreas 10808
 
10809
/**
111 andreas 10810
 * Change the refresh rate for a given resource.
10811
 */
10812
void TPageManager::doRSR(int, vector<int>&, vector<string>& pars)
10813
{
10814
    DECL_TRACER("TPageManager::doRSR(int, vector<int>&, vector<string>& pars)");
10815
 
10816
    if (pars.size() < 2)
10817
    {
10818
        MSG_ERROR("Expecting 2 parameters but got none! Ignoring command.");
10819
        return;
10820
    }
10821
 
10822
    string resName = pars[0];
10823
    int resRefresh = atoi(pars[1].c_str());
10824
 
10825
    if (!gPrjResources)
10826
    {
10827
        MSG_ERROR("Missing the resource module. Ignoring command!");
10828
        return;
10829
    }
10830
 
10831
    RESOURCE_T res = gPrjResources->findResource(resName);
10832
 
10833
    if (res.name.empty() || res.refresh == resRefresh)
10834
        return;
10835
 
10836
    gPrjResources->setResource(resName, res.protocol, res.host, res.path, res.file, res.user, res.password, resRefresh);
10837
}
10838
 
10839
/**
62 andreas 10840
 * @brief TPageManager::doAKB - Pop up the keyboard icon
10841
 * Pop up the keyboard icon and initialize the text string to that specified.
10842
 * Keyboard string is set to null on power up and is stored until power is lost.
10843
 * The Prompt Text is optional.
10844
 */
10845
void TPageManager::doAKB(int, vector<int>&, vector<string> &pars)
10846
{
10847
    DECL_TRACER("TPageManager::doAKB(int, vector<int>&, vector<string> &pars)");
10848
 
10849
    if (pars.size() < 1)
10850
    {
10851
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
10852
        return;
10853
    }
10854
 
10855
    string initText = pars[0];
10856
    string promptText;
10857
 
10858
    if (pars.size() > 1)
10859
        promptText = pars[1];
10860
 
63 andreas 10861
    if (initText.empty())
10862
        initText = mAkbText;
10863
    else
10864
        mAkbText = initText;
62 andreas 10865
 
10866
    if (_callKeyboard)
63 andreas 10867
        _callKeyboard(initText, promptText, false);
62 andreas 10868
}
10869
 
63 andreas 10870
/**
10871
 * Pop up the keyboard icon and initialize the text string to that
10872
 * specified.
10873
 */
62 andreas 10874
void TPageManager::doAKEYB(int port, vector<int>& channels, vector<string>& pars)
10875
{
10876
    DECL_TRACER("TPageManager::doAKEYB(int port, vector<int>& channels, vector<string>& pars)");
10877
 
10878
    doAKB(port, channels, pars);
10879
}
10880
 
63 andreas 10881
void TPageManager::doAKEYP(int port, std::vector<int>& channels, std::vector<std::string>& pars)
10882
{
10883
    DECL_TRACER("TPageManager::doAKEYP(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
10884
 
10885
    doAKP(port, channels, pars);
10886
}
10887
 
62 andreas 10888
/**
63 andreas 10889
 * Remove keyboard or keypad that was displayed using 'AKEYB', 'AKEYP', 'PKEYP',
10890
 * @AKB, @AKP, @PKP, @EKP, or @TKP commands.
10891
 */
10892
void TPageManager::doAKEYR(int, vector<int>&, vector<string>&)
10893
{
10894
    DECL_TRACER("TPageManager::doAKEYR(int, vector<int>&, vector<string>&)");
10895
 
10896
    if (_callResetKeyboard)
10897
        _callResetKeyboard();
10898
}
10899
 
10900
/**
62 andreas 10901
 * @brief TPageManager::doAKP - Pop up the keypad icon
10902
 * Pop up the keypad icon and initialize the text string to that specified.
10903
 * Keypad string is set to null on power up and is stored until power is lost.
10904
 * The Prompt Text is optional.
10905
 */
10906
void TPageManager::doAKP(int, std::vector<int>&, std::vector<std::string> &pars)
10907
{
10908
    DECL_TRACER("TPageManager::doAKP(int, vector<int>&, vector<string> &pars)");
10909
 
10910
    if (pars.size() < 1)
10911
    {
10912
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
10913
        return;
10914
    }
10915
 
10916
    string initText = pars[0];
10917
    string promptText;
10918
 
10919
    if (pars.size() > 1)
10920
        promptText = pars[1];
10921
 
63 andreas 10922
    if (initText.empty())
10923
        initText = mAkpText;
10924
    else
10925
        mAkpText = initText;
62 andreas 10926
 
10927
    if (_callKeypad)
63 andreas 10928
        _callKeypad(initText, promptText, false);
62 andreas 10929
}
10930
 
63 andreas 10931
/**
10932
 * Remove keyboard or keypad that was displayed using 'AKEYB', 'AKEYP', 'PKEYP',
10933
 * @AKB, @AKP, @PKP, @EKP, or @TKP commands.
10934
 */
10935
void TPageManager::doAKR(int port, vector<int>& channels, vector<string>& pars)
62 andreas 10936
{
63 andreas 10937
    DECL_TRACER("TPageManager::doAKR(int, vector<int>&, vector<string>&)");
62 andreas 10938
 
63 andreas 10939
    doAKEYR(port, channels, pars);
62 andreas 10940
}
10941
 
108 andreas 10942
void TPageManager::doABEEP(int, std::vector<int>&, vector<string>&)
10943
{
10944
    DECL_TRACER("TPageManager::doBEEP(int, std::vector<int>&, vector<string>&)");
10945
 
10946
    if (!_playSound)
334 andreas 10947
    {
10948
#if TESTMODE == 1
10949
        setAllDone();
10950
#endif
108 andreas 10951
        return;
334 andreas 10952
    }
108 andreas 10953
 
10954
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getSingleBeepSound();
10955
    TValidateFile vf;
10956
 
326 andreas 10957
    if (vf.isValidFile(snd))
108 andreas 10958
        _playSound(snd);
326 andreas 10959
#if TESTMODE == 1
10960
    else
10961
    {
10962
        MSG_PROTOCOL("Sound file invalid!");
334 andreas 10963
        setAllDone();
326 andreas 10964
    }
10965
#endif
108 andreas 10966
}
10967
 
10968
void TPageManager::doADBEEP(int, std::vector<int>&, vector<string>&)
10969
{
10970
    DECL_TRACER("TPageManager::doDBEEP(int, std::vector<int>&, vector<string>&)");
10971
 
10972
    if (!_playSound)
10973
        return;
10974
 
10975
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getDoubleBeepSound();
10976
    TValidateFile vf;
10977
 
326 andreas 10978
    if (vf.isValidFile(snd))
108 andreas 10979
        _playSound(snd);
326 andreas 10980
#if TESTMODE == 1
10981
    else
10982
    {
10983
        MSG_PROTOCOL("Sound file invalid!");
334 andreas 10984
        setAllDone();
326 andreas 10985
    }
10986
#endif
108 andreas 10987
}
10988
 
71 andreas 10989
void TPageManager::doBEEP(int, std::vector<int>&, vector<string>&)
10990
{
10991
    DECL_TRACER("TPageManager::doBEEP(int, std::vector<int>&, vector<string>&)");
10992
 
10993
    if (!_playSound)
326 andreas 10994
    {
10995
#if TESTMODE == 1
10996
        MSG_PROTOCOL("Method \"playSound()\" not initialized!");
334 andreas 10997
        setAllDone();
326 andreas 10998
#endif
71 andreas 10999
        return;
326 andreas 11000
    }
71 andreas 11001
 
11002
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getSingleBeepSound();
11003
    TValidateFile vf;
108 andreas 11004
    TSystemSound sysSound(TConfig::getSystemPath(TConfig::SOUNDS));
71 andreas 11005
 
326 andreas 11006
    if (sysSound.getSystemSoundState() && vf.isValidFile(snd))
71 andreas 11007
        _playSound(snd);
326 andreas 11008
#if TESTMODE == 1
11009
    else
11010
    {
11011
        if (!sysSound.getSystemSoundState())
11012
        {
11013
            MSG_PROTOCOL("Sound state disabled!")
11014
        }
11015
        else
11016
        {
11017
            MSG_PROTOCOL("Sound file invalid!");
11018
        }
11019
 
334 andreas 11020
        setAllDone();
326 andreas 11021
    }
11022
#endif
71 andreas 11023
}
11024
 
11025
void TPageManager::doDBEEP(int, std::vector<int>&, vector<string>&)
11026
{
11027
    DECL_TRACER("TPageManager::doDBEEP(int, std::vector<int>&, vector<string>&)");
11028
 
11029
    if (!_playSound)
11030
        return;
11031
 
11032
    string snd = TConfig::getSystemPath(TConfig::SOUNDS) + "/" + TConfig::getDoubleBeepSound();
11033
    TValidateFile vf;
108 andreas 11034
    TSystemSound sysSound(TConfig::getSystemPath(TConfig::SOUNDS));
71 andreas 11035
 
326 andreas 11036
    if (sysSound.getSystemSoundState() && vf.isValidFile(snd))
71 andreas 11037
        _playSound(snd);
326 andreas 11038
#if TESTMODE == 1
11039
    else
11040
    {
11041
        if (!sysSound.getSystemSoundState())
11042
        {
11043
            MSG_PROTOCOL("Sound state disabled!")
11044
        }
11045
        else
11046
        {
11047
            MSG_PROTOCOL("Sound file invalid!");
11048
        }
11049
 
334 andreas 11050
        setAllDone();
326 andreas 11051
    }
11052
#endif
71 andreas 11053
}
11054
 
63 andreas 11055
/**
11056
 * @brief Pop up the keypad icon and initialize the text string to that specified.
11057
 * Keypad string is set to null on power up and is stored until power is lost.
11058
 * The Prompt Text is optional.
11059
 */
62 andreas 11060
void TPageManager::doEKP(int port, std::vector<int>& channels, std::vector<std::string>& pars)
11061
{
11062
    DECL_TRACER("TPageManager::doEKP(int port, std::vector<int>& channels, std::vector<std::string>& pars)");
11063
 
11064
    doAKP(port, channels, pars);
11065
}
63 andreas 11066
 
11067
/**
11068
 * @brief Present a private keyboard.
11069
 * Pops up the keyboard icon and initializes the text string to that specified.
11070
 * Keyboard displays a '*' instead of the letters typed. The Prompt Text is optional.
11071
 */
11072
void TPageManager::doPKB(int, vector<int>&, vector<string>& pars)
11073
{
11074
    DECL_TRACER("TPageManager::doPKB(int, vector<int>&, vector<string>& pars)");
11075
 
11076
    if (pars.size() < 1)
11077
    {
11078
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
11079
        return;
11080
    }
11081
 
11082
    string initText = pars[0];
11083
    string promptText;
11084
 
11085
    if (pars.size() > 1)
11086
        promptText = pars[1];
11087
 
11088
    if (_callKeyboard)
11089
        _callKeyboard(initText, promptText, true);
11090
}
11091
 
11092
/**
11093
 * @brief Present a private keypad.
11094
 * Pops up the keypad icon and initializes the text string to that specified.
11095
 * Keypad displays a '*' instead of the numbers typed. The Prompt Text is optional.
11096
 */
11097
void TPageManager::doPKP(int, vector<int>&, vector<string>& pars)
11098
{
11099
    DECL_TRACER("TPageManager::doPKP(int, vector<int>&, vector<string>& pars)");
11100
 
11101
    if (pars.size() < 1)
11102
    {
11103
        MSG_ERROR("Expecting 2 parameters but got only " << pars.size() << "! Ignoring command.");
11104
        return;
11105
    }
11106
 
11107
    string initText = pars[0];
11108
    string promptText;
11109
 
11110
    if (pars.size() > 1)
11111
        promptText = pars[1];
11112
 
11113
    if (_callKeypad)
11114
        _callKeypad(initText, promptText, true);
11115
}
11116
 
11117
/**
64 andreas 11118
 * Send panel to SETUP page.
11119
 */
11120
void TPageManager::doSetup(int, vector<int>&, vector<string>&)
11121
{
11122
    DECL_TRACER("TPageManager::doSetup(int, vector<int>&, vector<string>&)");
11123
 
11124
    if (_callShowSetup)
11125
        _callShowSetup();
11126
}
11127
 
11128
/**
11129
 * Shut down the App
11130
 */
11131
void TPageManager::doShutdown(int, vector<int>&, vector<string>&)
11132
{
11133
    DECL_TRACER("TPageManager::doShutdown(int, vector<int>&, vector<string>&)");
11134
 
97 andreas 11135
    MSG_PROTOCOL("Received shutdown ...");
64 andreas 11136
#ifdef __ANDROID__
11137
    stopNetworkState();
11138
#endif
11139
    prg_stopped = true;
11140
    killed = true;
11141
 
11142
    if (_shutdown)
11143
        _shutdown();
11144
}
11145
 
82 andreas 11146
void TPageManager::doSOU(int, vector<int>&, vector<string>& pars)
11147
{
11148
    DECL_TRACER("TPageManager::doSOU(int, vector<int>&, vector<string>& pars)");
11149
 
11150
    if (pars.size() < 1)
11151
    {
11152
        MSG_ERROR("@SOU: Expecting a sound file as parameter! Ignoring command.");
11153
        return;
11154
    }
11155
 
11156
    if (!_playSound)
11157
    {
11158
        MSG_ERROR("@SOU: Missing sound module!");
11159
        return;
11160
    }
11161
 
165 andreas 11162
    if (pars[0].empty() || strCaseCompare(pars[0], "None") == 0)
11163
        return;
11164
 
82 andreas 11165
    _playSound(pars[0]);
11166
}
11167
 
326 andreas 11168
void TPageManager::doMUT(int, vector<int>&, vector<string>& pars)
11169
{
11170
    DECL_TRACER("TPageManager::doMUT(int, vector<int>&, vector<string>& pars)");
11171
 
11172
    if (pars.size() < 1)
11173
    {
11174
        MSG_ERROR("^MUT: Expecting a state parameter! Ignoring command.");
11175
        return;
11176
    }
11177
 
11178
    bool mute = 0;
11179
 
11180
    if (pars[0] == "0")
11181
        mute = false;
11182
    else
11183
        mute = true;
11184
 
11185
    TConfig::setMuteState(mute);
11186
#if TESTMODE == 1
327 andreas 11187
    if (_gTestMode)
11188
    {
11189
        bool st = TConfig::getMuteState();
11190
        _gTestMode->setResult(st ? "1" : "0");
11191
    }
11192
 
326 andreas 11193
    __success = true;
334 andreas 11194
    setAllDone();
326 andreas 11195
#endif
11196
}
11197
 
64 andreas 11198
/**
63 andreas 11199
 * @brief Present a telephone keypad.
11200
 * Pops up the keypad icon and initializes the text string to that specified.
11201
 * The Prompt Text is optional.
11202
 */
11203
void TPageManager::doTKP(int port, vector<int>& channels, vector<string>& pars)
11204
{
11205
    DECL_TRACER("TPageManager::doTKP(int port, vector<int>& channels, vector<string>& pars)");
11206
 
11207
    // TODO: Implement a real telefone keypad.
11208
    doAKP(port, channels, pars);
11209
}
11210
 
11211
/**
11212
 * Popup the virtual keyboard
11213
 */
123 andreas 11214
void TPageManager::doVKB(int port, vector<int>& channels, vector<string>& pars)
63 andreas 11215
{
123 andreas 11216
    DECL_TRACER("TPageManager::doVKB(int port, vector<int>& channels, vector<string>& pars)");
63 andreas 11217
 
11218
    doAKP(port, channels, pars);
11219
}
129 andreas 11220
#ifndef _NOSIP_
123 andreas 11221
void TPageManager::sendPHN(vector<string>& cmds)
11222
{
11223
    DECL_TRACER("TPageManager::sendPHN(const vector<string>& cmds)");
11224
 
11225
    vector<int> channels;
11226
    doPHN(-1, channels, cmds);
11227
}
11228
 
141 andreas 11229
void TPageManager::actPHN(vector<string>& cmds)
11230
{
11231
    DECL_TRACER("TPageManager::actPHN(const vector<string>& cmds)");
11232
 
11233
    vector<int> channels;
11234
    doPHN(1, channels, cmds);
11235
}
11236
 
140 andreas 11237
void TPageManager::phonePickup(int id)
11238
{
11239
    DECL_TRACER("TPageManager::phonePickup(int id)");
11240
 
11241
    if (id < 0 || id >= 4)
11242
        return;
11243
 
11244
    if (mSIPClient)
11245
        mSIPClient->pickup(id);
11246
}
11247
 
11248
void TPageManager::phoneHangup(int id)
11249
{
11250
    DECL_TRACER("TPageManager::phoneHangup(int id)");
11251
 
11252
    if (id < 0 || id >= 4)
11253
        return;
11254
 
11255
    if (mSIPClient)
11256
        mSIPClient->terminate(id);
11257
}
11258
 
123 andreas 11259
/**
11260
 * @brief Phone commands.
11261
 * The phone commands could come from the master or are send to the master.
11262
 * If the parameter \p port is less then 0 (zero) a command is send to the
11263
 * master. In any other case the command came from the mater.
125 andreas 11264
 *
11265
 * @param port  This is used to signal if the command was sent by the master
11266
 *              or generated from the panel. If ths is less then 0, then the
11267
 *              method was called because of an event happen in the panel.
11268
 *              If this is grater or equal 0, then the event is comming from
11269
 *              the master.
11270
 * @param pars  This are parameters. The first parameter defines the action
11271
 *              to be done. According to the command this parameter may have a
11272
 *              different number of arguments.
123 andreas 11273
 */
11274
void TPageManager::doPHN(int port, vector<int>&, vector<string>& pars)
11275
{
11276
    DECL_TRACER("TPageManager::doPHN(int port, vector<int>&, vector<string>& pars)");
11277
 
11278
    if (pars.size() < 1)
11279
    {
11280
        MSG_ERROR("Expecting at least 1 parameter but got none! Ignoring command.");
11281
        return;
11282
    }
11283
 
11284
    string sCommand;
11285
    string cmd = toUpper(pars[0]);
11286
 
11287
    // Master to panel
11288
    if (port >= 0)
11289
    {
11290
        if (!mSIPClient)
11291
        {
11292
            MSG_ERROR("SIP client class was not initialized!")
11293
            return;
11294
        }
11295
 
11296
        if (cmd == "ANSWER")
11297
        {
11298
            if (pars.size() >= 2)
11299
            {
124 andreas 11300
                int id = atoi(pars[1].c_str());
11301
 
11302
                if (mSIPClient->getSIPState(id) == TSIPClient::SIP_HOLD)
11303
                    mSIPClient->resume(id);
11304
                else
135 andreas 11305
                    mSIPClient->pickup(id);
123 andreas 11306
            }
11307
        }
11308
        else if (cmd == "AUTOANSWER")
11309
        {
11310
            if (pars.size() >= 2)
11311
            {
11312
                if (pars[1].at(0) == '0')
11313
                    mPHNautoanswer = false;
11314
                else
11315
                    mPHNautoanswer = true;
127 andreas 11316
 
11317
                vector<string> cmds;
11318
                cmds = { "AUTOANSWER", to_string(mPHNautoanswer ? 1 : 0) };
128 andreas 11319
                sendPHN(cmds);
123 andreas 11320
            }
11321
        }
11322
        else if (cmd == "CALL")     // Initiate a call
11323
        {
11324
            if (pars.size() >= 2)
127 andreas 11325
                mSIPClient->call(pars[1]);
123 andreas 11326
        }
11327
        else if (cmd == "DTMF")     // Send tone modified codes
11328
        {
127 andreas 11329
            if (pars.size() >= 2)
11330
                mSIPClient->sendDTMF(pars[1]);
123 andreas 11331
        }
11332
        else if (cmd == "HANGUP")   // terminate a call
11333
        {
124 andreas 11334
            if (pars.size() >= 2)
11335
            {
11336
                int id = atoi(pars[1].c_str());
11337
                mSIPClient->terminate(id);
11338
            }
123 andreas 11339
        }
11340
        else if (cmd == "HOLD")     // Hold the line
11341
        {
124 andreas 11342
            if (pars.size() >= 2)
11343
            {
11344
                int id = atoi(pars[1].c_str());
11345
                mSIPClient->hold(id);
11346
            }
123 andreas 11347
        }
128 andreas 11348
        else if (cmd == "LINESTATE") // State of all line
127 andreas 11349
        {
128 andreas 11350
            mSIPClient->sendLinestate();
127 andreas 11351
        }
123 andreas 11352
        else if (cmd == "PRIVACY")  // Set/unset "do not disturb"
11353
        {
128 andreas 11354
            if (pars.size() >= 2)
11355
            {
11356
                bool state = (pars[1].at(0) == '1' ? true : false);
11357
                mSIPClient->sendPrivate(state);
11358
            }
123 andreas 11359
        }
11360
        else if (cmd == "REDIAL")   // Redials the last number
11361
        {
128 andreas 11362
            mSIPClient->redial();
123 andreas 11363
        }
11364
        else if (cmd == "TRANSFER") // Transfer call to provided number
11365
        {
128 andreas 11366
            if (pars.size() >= 3)
11367
            {
11368
                int id = atoi(pars[1].c_str());
11369
                string num = pars[2];
11370
 
11371
                if (mSIPClient->transfer(id, num))
11372
                {
11373
                    vector<string> cmds;
11374
                    cmds.push_back("TRANSFERRED");
11375
                    sendPHN(cmds);
11376
                }
11377
            }
123 andreas 11378
        }
144 andreas 11379
        else if (cmd == "IM")
11380
        {
11381
            if (pars.size() < 3)
11382
                return;
11383
 
11384
            string to = pars[1];
11385
            string msg = pars[2];
11386
            string toUri;
11387
 
11388
            if (to.find("sip:") == string::npos)
11389
                toUri = "sip:";
11390
 
11391
            toUri += to;
11392
 
11393
            if (to.find("@") == string::npos)
11394
                toUri += "@" + TConfig::getSIPproxy();
11395
 
11396
            mSIPClient->sendIM(toUri, msg);
11397
        }
123 andreas 11398
        else if (cmd == "SETUP")    // Some temporary settings
11399
        {
11400
            if (pars.size() < 2)
11401
                return;
11402
 
11403
            if (pars[1] == "DOMAIN" && pars.size() >= 3)
11404
                TConfig::setSIPdomain(pars[2]);
11405
            else if (pars[1] == "DTMFDURATION")
11406
            {
138 andreas 11407
                unsigned int ms = atoi(pars[2].c_str());
11408
                mSIPClient->setDTMFduration(ms);
123 andreas 11409
            }
11410
            else if (pars[1] == "ENABLE")   // (re)register user
11411
            {
11412
                TConfig::setSIPstatus(true);
127 andreas 11413
                mSIPClient->cleanUp();
135 andreas 11414
                mSIPClient->init();
123 andreas 11415
            }
127 andreas 11416
            else if (pars[1] == "DOMAIN" && pars.size() >= 3)
11417
                TConfig::setSIPdomain(pars[2]);
123 andreas 11418
            else if (pars[1] == "PASSWORD" && pars.size() >= 3)
11419
                TConfig::setSIPpassword(pars[2]);
11420
            else if (pars[1] == "PORT" && pars.size() != 3)
11421
                TConfig::setSIPport(atoi(pars[2].c_str()));
11422
            else if (pars[1] == "PROXYADDR" && pars.size() >= 3)
11423
                TConfig::setSIPproxy(pars[2]);
11424
            else if (pars[1] == "STUNADDR" && pars.size() >= 3)
11425
                TConfig::setSIPstun(pars[2]);
11426
            else if (pars[1] == "USERNAME" && pars.size() >= 3)
11427
                TConfig::setSIPuser(pars[2]);
11428
        }
11429
        else
11430
        {
11431
            MSG_ERROR("Unknown command ^PHN-" << cmd << " ignored!");
11432
        }
11433
    }
11434
    else   // Panel to master
11435
    {
11436
        vector<string>::iterator iter;
11437
 
11438
        for (iter = pars.begin(); iter != pars.end(); ++iter)
11439
        {
11440
            if (!sCommand.empty())
11441
                sCommand += ",";
11442
 
11443
            sCommand += *iter;
11444
        }
11445
 
11446
        sendPHNcommand(sCommand);
11447
    }
11448
}
127 andreas 11449
 
11450
void TPageManager::getPHN(int, vector<int>&, vector<string>& pars)
11451
{
11452
    DECL_TRACER("TPageManager::getPHN(int, vector<int>&, vector<string>& pars)");
11453
 
11454
    if (pars.size() < 1)
11455
    {
11456
        MSG_ERROR("Invalid number of arguments!");
11457
        return;
11458
    }
11459
 
11460
    string cmd = pars[0];
11461
 
11462
    if (cmd == "AUTOANSWER")
11463
        sendPHNcommand(cmd + "," + (mPHNautoanswer ? "1" : "0"));
11464
    else if (cmd == "LINESTATE")
11465
    {
11466
        if (!mSIPClient)
11467
            return;
11468
 
138 andreas 11469
        mSIPClient->sendLinestate();
127 andreas 11470
    }
11471
    else if (cmd == "MSGWAITING")
11472
    {
144 andreas 11473
        size_t num = mSIPClient->getNumberMessages();
11474
        sendPHNcommand(cmd + "," + (num > 0 ? "1" : "0") + "," + std::to_string(num) + "0,0,0");
127 andreas 11475
    }
11476
    else if (cmd == "PRIVACY")
11477
    {
138 andreas 11478
        if (mSIPClient->getPrivate())
11479
            sendPHNcommand(cmd + ",1");
11480
        else
11481
            sendPHNcommand(cmd + ",0");
127 andreas 11482
    }
144 andreas 11483
    else if (cmd == "REDIAL")
11484
    {
11485
        if (pars.size() < 2)
11486
            return;
11487
 
11488
        sendPHNcommand(cmd + "," + pars[1]);
11489
    }
127 andreas 11490
    else
11491
    {
11492
        MSG_WARNING("Unknown command " << cmd << " found!");
11493
    }
11494
}
129 andreas 11495
#endif  // _NOSIP_
134 andreas 11496
 
300 andreas 11497
/*
318 andreas 11498
 *  Hide all subpages in a subpage viewer button.
11499
 */
11500
void TPageManager::doSHA(int port, vector<int> &channels, vector<string> &pars)
11501
{
11502
    DECL_TRACER("TPageManager::doSHA(int port, vector<int> &channels, vector<string> &pars)");
11503
 
343 andreas 11504
    Q_UNUSED(pars);
318 andreas 11505
    vector<TMap::MAP_T> map = findButtons(port, channels);
11506
 
11507
    if (TError::isError() || map.empty())
11508
        return;
11509
 
11510
    vector<Button::TButton *> buttons = collectButtons(map);
11511
 
11512
    if (!buttons.empty())
11513
    {
11514
        vector<Button::TButton *>::iterator mapIter;
11515
 
11516
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11517
        {
11518
            Button::TButton *bt = *mapIter;
11519
 
11520
            if (_hideAllSubViewItems)
11521
                _hideAllSubViewItems(bt->getHandle());
11522
        }
11523
    }
11524
}
11525
 
11526
void TPageManager::doSHD(int port, vector<int>& channels, vector<string>& pars)
11527
{
11528
    DECL_TRACER("TPageManager::doSHD(int port, vector<int>& channels, vector<string>& pars)");
11529
 
11530
    if (pars.size() < 1)
11531
        return;
11532
 
11533
    string name = pars[0];
11534
 
11535
    vector<TMap::MAP_T> map = findButtons(port, channels);
11536
 
11537
    if (TError::isError() || map.empty())
11538
        return;
11539
 
11540
    vector<Button::TButton *> buttons = collectButtons(map);
11541
 
11542
    if (!buttons.empty())
11543
    {
11544
        vector<Button::TButton *>::iterator mapIter;
11545
 
11546
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11547
        {
11548
            Button::TButton *bt = *mapIter;
11549
 
11550
            vector<TSubPage *> subviews = createSubViewList(bt->getSubViewID());
11551
 
11552
            if (subviews.empty())
11553
                continue;
11554
 
11555
            vector<TSubPage *>::iterator itSub;
11556
 
11557
            for (itSub = subviews.begin(); itSub != subviews.end(); ++itSub)
11558
            {
11559
                TSubPage *sub = *itSub;
11560
 
11561
                if (sub && sub->getName() == name)
11562
                {
11563
                    if (_hideSubViewItem)
11564
                        _hideSubViewItem(bt->getHandle(), sub->getHandle());
11565
 
11566
                    break;
11567
                }
11568
            }
11569
        }
11570
    }
11571
}
11572
 
11573
void TPageManager::doSPD(int port, vector<int>& channels, vector<string>& pars)
11574
{
11575
    DECL_TRACER("TPageManager::doSPD(int port, vector<int>& channel, vector<string>& pars)");
11576
 
11577
    if (pars.size() < 1)
11578
        return;
11579
 
11580
    TError::clear();
11581
    int padding = atoi(pars[0].c_str());
11582
 
11583
    if (padding < 0 || padding > 100)
11584
        return;
11585
 
11586
    vector<TMap::MAP_T> map = findButtons(port, channels);
11587
 
11588
    if (TError::isError() || map.empty())
11589
        return;
11590
 
11591
    vector<Button::TButton *> buttons = collectButtons(map);
11592
 
11593
    if (!buttons.empty())
11594
    {
11595
        vector<Button::TButton *>::iterator mapIter;
11596
 
11597
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11598
        {
11599
            Button::TButton *bt = *mapIter;
11600
 
11601
            if (_setSubViewPadding)
11602
                _setSubViewPadding(bt->getHandle(), padding);
11603
        }
11604
    }
11605
}
11606
 
11607
/*
300 andreas 11608
 * This command will perform one of three different operations based on the following conditions:
11609
 * 1. If the named subpage is hidden in the set associated with the viewer button it will be shown in the anchor position.
11610
 * 2. If the named subpage is not present in the set it will be added to the set and shown in the anchor position.
11611
 * 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
11612
 * position. The anchor position is the location on the subpage viewer button specified by its weighting. This will either be
11613
 * left, center or right for horizontal subpage viewer buttons or top, center or bottom for vertical subpage viewer buttons.
11614
 * Surrounding subpages are relocated on the viewer button as needed to accommodate the described operations
11615
 */
11616
void TPageManager::doSSH(int port, vector<int> &channels, vector<string> &pars)
11617
{
11618
    DECL_TRACER("TPageManager::doSSH(int port, vector<int> &channels, vector<string> &pars)");
11619
 
11620
    if (pars.size() < 1)
11621
    {
11622
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
11623
        return;
11624
    }
11625
 
11626
    TError::clear();
11627
    string name = pars[0];
11628
    int position = 0;   // optional
11629
    int time = 0;       // optional
11630
 
11631
    if (pars.size() > 1)
11632
        position = atoi(pars[1].c_str());
11633
 
11634
    if (pars.size() > 2)
11635
        time = atoi(pars[2].c_str());
11636
 
11637
    vector<TMap::MAP_T> map = findButtons(port, channels);
11638
 
11639
    if (TError::isError() || map.empty())
11640
        return;
11641
 
11642
    vector<Button::TButton *> buttons = collectButtons(map);
11643
 
11644
    if (!buttons.empty())
11645
    {
11646
        vector<Button::TButton *>::iterator mapIter;
11647
 
11648
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11649
        {
11650
            Button::TButton *bt = *mapIter;
11651
            vector<TSubPage *> subviews = createSubViewList(bt->getSubViewID());
11652
 
11653
            if (subviews.empty() || !bt)
11654
                continue;
11655
 
11656
            vector<TSubPage *>::iterator itSub;
11657
 
11658
            for (itSub = subviews.begin(); itSub != subviews.end(); ++itSub)
11659
            {
11660
                TSubPage *sub = *itSub;
11661
 
11662
                if (sub && sub->getName() == name)
11663
                {
11664
                    if (_showSubViewItem)
11665
                        _showSubViewItem(sub->getHandle(), bt->getHandle(), position, time);
11666
 
11667
                    break;
11668
                }
11669
            }
11670
        }
11671
    }
11672
}
11673
 
318 andreas 11674
void TPageManager::doSTG(int port, vector<int>& channels, vector<string>& pars)
11675
{
11676
    DECL_TRACER("TPageManager::doSTG(int port, vector<int>& channels, vector<string>& pars)");
11677
 
11678
    if (pars.empty())
11679
    {
11680
        MSG_ERROR("Expecting 1 parameter but got none! Ignoring command.");
11681
        return;
11682
    }
11683
 
11684
    TError::clear();
11685
    string name = pars[0];
11686
    int position = 0;   // optional
11687
    int time = 0;       // optional
11688
 
11689
    if (pars.size() > 1)
11690
        position = atoi(pars[1].c_str());
11691
 
11692
    if (pars.size() > 2)
11693
        time = atoi(pars[2].c_str());
11694
 
11695
    vector<TMap::MAP_T> map = findButtons(port, channels);
11696
 
11697
    if (TError::isError() || map.empty())
11698
        return;
11699
 
11700
    vector<Button::TButton *> buttons = collectButtons(map);
11701
 
11702
    if (!buttons.empty())
11703
    {
11704
        vector<Button::TButton *>::iterator mapIter;
11705
 
11706
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11707
        {
11708
            Button::TButton *bt = *mapIter;
11709
            vector<TSubPage *> subviews = createSubViewList(bt->getSubViewID());
11710
 
11711
            if (subviews.empty() || !bt)
11712
                continue;
11713
 
11714
            vector<TSubPage *>::iterator itSub;
11715
 
11716
            for (itSub = subviews.begin(); itSub != subviews.end(); ++itSub)
11717
            {
11718
                TSubPage *sub = *itSub;
11719
 
11720
                if (sub && sub->getName() == name)
11721
                {
11722
                    if (_toggleSubViewItem)
11723
                        _toggleSubViewItem(sub->getHandle(), bt->getHandle(), position, time);
11724
 
11725
                    break;
11726
                }
11727
            }
11728
        }
11729
    }
11730
}
11731
 
227 andreas 11732
void TPageManager::doLVD(int port, vector<int> &channels, vector<string> &pars)
225 andreas 11733
{
227 andreas 11734
    DECL_TRACER("TPageManager::doLVD(int port, vector<int> &channels, vector<string> &pars)");
225 andreas 11735
 
11736
    if (pars.size() < 1)
11737
    {
11738
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
11739
        return;
11740
    }
11741
 
11742
    TError::clear();
11743
    string source = pars[0];
11744
    vector<string> configs;
11745
 
11746
    if (pars.size() > 1)
11747
    {
11748
        for (size_t i = 1; i < pars.size(); ++i)
227 andreas 11749
        {
11750
            string low = toLower(pars[i]);
11751
 
11752
            if (low.find_first_of("user=") != string::npos ||
11753
                low.find_first_of("pass=") != string::npos ||
11754
                low.find_first_of("csv=")  != string::npos ||
11755
                low.find_first_of("has_headers=") != string::npos)
11756
            {
11757
                configs.push_back(pars[i]);
11758
            }
11759
        }
225 andreas 11760
    }
11761
 
11762
    vector<TMap::MAP_T> map = findButtons(port, channels);
11763
 
11764
    if (TError::isError() || map.empty())
11765
        return;
11766
 
11767
    vector<Button::TButton *> buttons = collectButtons(map);
11768
 
11769
    if (buttons.size() > 0)
11770
    {
11771
        vector<Button::TButton *>::iterator mapIter;
11772
 
11773
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11774
        {
11775
            Button::TButton *bt = *mapIter;
11776
            bt->setListSource(source, configs);
11777
        }
11778
    }
11779
 
11780
}
11781
 
230 andreas 11782
void TPageManager::doLVE(int port, vector<int> &channels, vector<string> &pars)
11783
{
11784
    DECL_TRACER("TPageManager::doLVE(int port, vector<int> &channels, vector<string> &pars)");
11785
 
11786
    if (pars.size() < 1)
11787
    {
11788
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
11789
        return;
11790
    }
11791
 
11792
    TError::clear();
11793
    int num = atoi(pars[0].c_str());
11794
 
11795
    vector<TMap::MAP_T> map = findButtons(port, channels);
11796
 
11797
    if (TError::isError() || map.empty())
11798
        return;
11799
 
11800
    vector<Button::TButton *> buttons = collectButtons(map);
11801
 
11802
    if (buttons.size() > 0)
11803
    {
11804
        vector<Button::TButton *>::iterator mapIter;
11805
 
11806
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11807
        {
11808
            Button::TButton *bt = *mapIter;
11809
            bt->setListViewEventNumber(num);
11810
        }
11811
    }
11812
 
11813
}
11814
 
227 andreas 11815
void TPageManager::doLVF(int port, vector<int> &channels, vector<string> &pars)
11816
{
11817
    DECL_TRACER("TPageManager::doLVF(int port, vector<int> &channels, vector<string> &pars)");
11818
 
11819
    if (pars.size() < 1)
11820
    {
11821
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
11822
        return;
11823
    }
11824
 
11825
    TError::clear();
11826
    string filter;
11827
 
11828
    vector<string>::iterator iter;
11829
 
11830
    for (iter = pars.begin(); iter != pars.end(); ++iter)
11831
    {
11832
        if (filter.length() > 0)
11833
            filter += ",";
11834
 
11835
        filter += *iter;
11836
    }
11837
 
11838
    vector<TMap::MAP_T> map = findButtons(port, channels);
11839
 
11840
    if (TError::isError() || map.empty())
11841
        return;
11842
 
11843
    vector<Button::TButton *> buttons = collectButtons(map);
11844
 
11845
    if (buttons.size() > 0)
11846
    {
11847
        vector<Button::TButton *>::iterator mapIter;
11848
 
11849
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11850
        {
11851
            Button::TButton *bt = *mapIter;
11852
            bt->setListSourceFilter(filter);
11853
        }
11854
    }
11855
}
11856
 
230 andreas 11857
void TPageManager::doLVL(int port, vector<int> &channels, vector<string> &pars)
11858
{
11859
    DECL_TRACER("TPageManager::doLVL(int port, vector<int> &channels, vector<string> &pars)");
11860
 
11861
    if (pars.size() < 1)
11862
    {
11863
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
11864
        return;
11865
    }
11866
 
11867
    TError::clear();
233 andreas 11868
    bool hasColumns = false;
230 andreas 11869
    int columns = 0;
233 andreas 11870
    bool hasLayout = false;
230 andreas 11871
    int layout = 0;
233 andreas 11872
    bool hasComponent = false;
11873
    int component = 0;
11874
    bool hasCellHeight = false;
11875
    bool cellHeightPercent = false;
11876
    int cellheight = 0;
11877
    bool hasP1 = false;
11878
    int p1 = 0;
11879
    bool hasP2 = false;
11880
    int p2 = 0;
11881
    bool hasFilter = false;
11882
    bool filter = false;
11883
    bool hasFilterHeight = false;
11884
    bool filterHeightPercent = false;
11885
    int filterheight = 0;
11886
    bool hasAlphaScroll = false;
11887
    bool alphascroll = false;
230 andreas 11888
 
11889
    vector<string>::iterator iter;
11890
 
11891
    for (iter = pars.begin(); iter != pars.end(); ++iter)
11892
    {
11893
        string low = toLower(*iter);
11894
 
11895
        if (low.find("columns=") != string::npos ||
11896
            low.find("nc=") != string::npos ||
11897
            low.find("numcol=") != string::npos)
11898
        {
11899
            size_t pos = low.find("=");
11900
            string sCols = low.substr(pos + 1);
11901
            columns = atoi(sCols.c_str());
233 andreas 11902
            hasColumns = true;
11903
        }
11904
        else if (low.find("c=") != string::npos || low.find("comp=") != string::npos)
11905
        {
11906
            size_t pos = low.find("=");
11907
            string sComp = low.substr(pos + 1);
11908
            component |= atoi(sComp.c_str());
11909
            hasComponent = true;
11910
        }
11911
        else if (low.find("l=") != string::npos || low.find("layout=") != string::npos)
11912
        {
11913
            size_t pos = low.find("=");
11914
            string sLay = low.substr(pos + 1);
11915
            layout = atoi(sLay.c_str());
11916
            hasLayout = true;
11917
        }
11918
        else if (low.find("ch=") != string::npos || low.find("cellheight=") != string::npos)
11919
        {
11920
            size_t pos = low.find("=");
11921
            string sCh = low.substr(pos + 1);
11922
            cellheight = atoi(sCh.c_str());
230 andreas 11923
 
233 andreas 11924
            if (low.find("%") != string::npos)
11925
                cellHeightPercent = true;
11926
 
11927
            hasCellHeight = true;
230 andreas 11928
        }
233 andreas 11929
        else if (low.find("p1=") != string::npos)
11930
        {
11931
            size_t pos = low.find("=");
11932
            string sP1 = low.substr(pos + 1);
11933
            p1 = atoi(sP1.c_str());
11934
            hasP1 = true;
11935
        }
11936
        else if (low.find("p2=") != string::npos)
11937
        {
11938
            size_t pos = low.find("=");
11939
            string sP2 = low.substr(pos + 1);
11940
            p2 = atoi(sP2.c_str());
11941
            hasP2 = true;
11942
        }
11943
        else if (low.find("f=") != string::npos || low.find("filter=") != string::npos)
11944
        {
11945
            size_t pos = low.find("=");
11946
            string sFilter = low.substr(pos + 1);
11947
            filter = isTrue(sFilter);
11948
            hasFilter = true;
11949
        }
11950
        else if (low.find("fh=") != string::npos || low.find("filterheight=") != string::npos)
11951
        {
11952
            size_t pos = low.find("=");
11953
            string sFilter = low.substr(pos + 1);
11954
            filterheight = atoi(sFilter.c_str());
11955
 
11956
            if (low.find("%") != string::npos)
11957
                filterHeightPercent = true;
11958
 
11959
            hasFilterHeight = true;
11960
        }
11961
        else if (low.find("as=") != string::npos || low.find("alphascroll=") != string::npos)
11962
        {
11963
            size_t pos = low.find("=");
11964
            string sAlpha = low.substr(pos + 1);
11965
            alphascroll = isTrue(sAlpha);
11966
            hasAlphaScroll = true;
11967
        }
230 andreas 11968
    }
11969
 
11970
    vector<TMap::MAP_T> map = findButtons(port, channels);
11971
 
11972
    if (TError::isError() || map.empty())
11973
        return;
11974
 
11975
    vector<Button::TButton *> buttons = collectButtons(map);
11976
 
11977
    if (buttons.size() > 0)
11978
    {
11979
        vector<Button::TButton *>::iterator mapIter;
11980
 
11981
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
11982
        {
11983
            Button::TButton *bt = *mapIter;
233 andreas 11984
 
11985
            if (hasColumns)         bt->setListViewColumns(columns);
11986
            if (hasComponent)       bt->setListViewComponent(component);
11987
            if (hasLayout)          bt->setListViewLayout(layout);
11988
            if (hasCellHeight)      bt->setListViewCellheight(cellheight, cellHeightPercent);
11989
            if (hasP1)              bt->setListViewP1(p1);
11990
            if (hasP2)              bt->setListViewP2(p2);
11991
            if (hasFilter)          bt->setListViewColumnFilter(filter);
11992
            if (hasFilterHeight)    bt->setListViewFilterHeight(filterheight, filterHeightPercent);
11993
            if (hasAlphaScroll)     bt->setListViewAlphaScroll(alphascroll);
230 andreas 11994
        }
11995
    }
11996
}
11997
 
233 andreas 11998
void TPageManager::doLVM(int port, vector<int> &channels, vector<string> &pars)
11999
{
12000
    DECL_TRACER("TPageManager::doLVM(int port, vector<int> &channels, vector<string> &pars)");
12001
 
12002
    if (pars.size() < 1)
12003
    {
12004
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
12005
        return;
12006
    }
12007
 
12008
    TError::clear();
12009
    map<string,string> mapField;
12010
 
12011
    vector<string>::iterator iter;
12012
 
12013
    for (iter = pars.begin(); iter != pars.end(); ++iter)
12014
    {
12015
        string left, right;
12016
        size_t pos = 0;
12017
 
12018
        if ((pos = iter->find("=")) != string::npos)
12019
        {
12020
            string left = iter->substr(0, pos);
12021
            left = toLower(left);
12022
            string right = iter->substr(pos + 1);
12023
 
12024
            if (left == "t1" || left == "t2" || left == "i1")
12025
                mapField.insert(pair<string,string>(left, right));
12026
        }
12027
    }
12028
 
12029
    vector<TMap::MAP_T> map = findButtons(port, channels);
12030
 
12031
    if (TError::isError() || map.empty())
12032
        return;
12033
 
12034
    vector<Button::TButton *> buttons = collectButtons(map);
12035
 
12036
    if (buttons.size() > 0)
12037
    {
12038
        vector<Button::TButton *>::iterator mapIter;
12039
 
12040
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
12041
        {
12042
            Button::TButton *bt = *mapIter;
12043
            bt->setListViewFieldMap(mapField);
12044
        }
12045
    }
12046
}
12047
 
12048
void TPageManager::doLVN(int port, vector<int> &channels, vector<string> &pars)
12049
{
12050
    DECL_TRACER("TPageManager::doLVN(int port, vector<int> &channels, vector<string> &pars)");
12051
 
12052
    if (pars.size() < 1)
12053
    {
12054
        MSG_ERROR("Expecting one parameter but got none! Ignoring command.");
12055
        return;
12056
    }
12057
 
12058
    TError::clear();
12059
    string command = pars[0];
12060
    bool select = false;
12061
 
12062
    if (pars.size() > 1)
12063
    {
12064
        if (isTrue(pars[1]))
12065
            select = true;
12066
    }
12067
 
12068
    vector<TMap::MAP_T> map = findButtons(port, channels);
12069
 
12070
    if (TError::isError() || map.empty())
12071
        return;
12072
 
12073
    vector<Button::TButton *> buttons = collectButtons(map);
12074
 
12075
    if (buttons.size() > 0)
12076
    {
12077
        vector<Button::TButton *>::iterator mapIter;
12078
 
12079
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
12080
        {
12081
            Button::TButton *bt = *mapIter;
12082
            bt->listViewNavigate(command, select);
12083
        }
12084
    }
12085
}
12086
 
12087
void TPageManager::doLVR(int port, vector<int> &channels, vector<string> &pars)
12088
{
12089
    DECL_TRACER("TPageManager::doLVR(int port, vector<int> &channels, vector<string> &pars)");
12090
 
12091
    TError::clear();
12092
    int interval = -1;
12093
    bool force = false;
12094
 
12095
    if (pars.size() > 0)
12096
        interval = atoi(pars[0].c_str());
12097
 
12098
    if (pars.size() > 1)
12099
        force = isTrue(pars[1]);
12100
 
12101
    vector<TMap::MAP_T> map = findButtons(port, channels);
12102
 
12103
    if (TError::isError() || map.empty())
12104
        return;
12105
 
12106
    vector<Button::TButton *> buttons = collectButtons(map);
12107
 
12108
    if (buttons.size() > 0)
12109
    {
12110
        vector<Button::TButton *>::iterator mapIter;
12111
 
12112
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
12113
        {
12114
            Button::TButton *bt = *mapIter;
12115
            bt->listViewRefresh(interval, force);
12116
        }
12117
    }
12118
}
12119
 
12120
void TPageManager::doLVS(int port, vector<int> &channels, vector<string> &pars)
12121
{
12122
    DECL_TRACER("TPageManager::doLVS(int port, vector<int> &channels, vector<string> &pars)");
12123
 
12124
    TError::clear();
12125
    vector<string> sortColumns;
12126
    Button::LIST_SORT sort = Button::LIST_SORT_NONE;
12127
    string override;
12128
 
12129
    if (pars.size() > 0)
12130
    {
12131
        vector<string>::iterator iter;
12132
 
12133
        for (iter = pars.begin(); iter != pars.end(); ++iter)
12134
        {
12135
            if (iter->find(";") == string::npos)
12136
                sortColumns.push_back(*iter);
12137
            else
12138
            {
12139
                vector<string> parts = StrSplit(*iter, ";");
12140
                sortColumns.push_back(parts[0]);
12141
 
12142
                if (parts[1].find("a") != string::npos || parts[1].find("A") != string::npos)
12143
                    sort = Button::LIST_SORT_ASC;
12144
                else if (parts[1].find("d") != string::npos || parts[1].find("D") != string::npos)
12145
                    sort = Button::LIST_SORT_DESC;
12146
                else if (parts[1].find("*") != string::npos)
12147
                {
12148
                    if (parts.size() > 2 && !parts[2].empty())
12149
                    {
12150
                        override = parts[2];
12151
                        sort = Button::LIST_SORT_OVERRIDE;
12152
                    }
12153
                }
12154
                else if (parts[1].find("n") != string::npos || parts[1].find("N") != string::npos)
12155
                    sort = Button::LIST_SORT_NONE;
12156
            }
12157
        }
12158
    }
12159
 
12160
    vector<TMap::MAP_T> map = findButtons(port, channels);
12161
 
12162
    if (TError::isError() || map.empty())
12163
        return;
12164
 
12165
    vector<Button::TButton *> buttons = collectButtons(map);
12166
 
12167
    if (buttons.size() > 0)
12168
    {
12169
        vector<Button::TButton *>::iterator mapIter;
12170
 
12171
        for (mapIter = buttons.begin(); mapIter != buttons.end(); mapIter++)
12172
        {
12173
            Button::TButton *bt = *mapIter;
12174
            bt->listViewSortData(sortColumns, sort, override);
12175
        }
12176
    }
12177
}
12178
 
134 andreas 12179
void TPageManager::doTPCCMD(int, vector<int>&, vector<string>& pars)
12180
{
12181
    DECL_TRACER("TPageManager::doTPCCMD(int, vector<int>&, vector<string>& pars)");
12182
 
12183
    if (pars.size() < 1)
12184
    {
12185
        MSG_ERROR("Too few arguments for TPCCMD!");
12186
        return;
12187
    }
12188
 
12189
    string cmd = pars[0];
12190
 
12191
    if (strCaseCompare(cmd, "LocalHost") == 0)
12192
    {
12193
        if (pars.size() < 2 || pars[1].empty())
12194
        {
12195
            MSG_ERROR("The command \"LocalHost\" requires an additional parameter!");
12196
            return;
12197
        }
12198
 
12199
        TConfig::saveController(pars[1]);
12200
    }
12201
    else if (strCaseCompare(cmd, "LocalPort") == 0)
12202
    {
12203
        if (pars.size() < 2 || pars[1].empty())
12204
        {
12205
            MSG_ERROR("The command \"LocalPort\" requires an additional parameter!");
12206
            return;
12207
        }
12208
 
12209
        int port = atoi(pars[1].c_str());
12210
 
12211
        if (port > 0 && port < 65536)
12212
            TConfig::savePort(port);
12213
        else
12214
        {
12215
            MSG_ERROR("Invalid network port " << port);
12216
        }
12217
    }
12218
    else if (strCaseCompare(cmd, "DeviceID") == 0)
12219
    {
12220
        if (pars.size() < 2 || pars[1].empty())
12221
        {
12222
            MSG_ERROR("The command \"DeviceID\" requires an additional parameter!");
12223
            return;
12224
        }
12225
 
12226
        int id = atoi(pars[1].c_str());
12227
 
12228
        if (id >= 10000 && id < 30000)
12229
            TConfig::setSystemChannel(id);
12230
    }
12231
    else if (strCaseCompare(cmd, "ApplyProfile") == 0)
12232
    {
12233
        // We restart the network connection only
12234
        if (gAmxNet)
12235
            gAmxNet->reconnect();
12236
    }
12237
    else if (strCaseCompare(cmd, "QueryDeviceInfo") == 0)
12238
    {
12239
        string info = "DEVICEINFO-TPANELID," + TConfig::getPanelType();
12240
        info += ";HOSTNAME,";
12241
        char hostname[HOST_NAME_MAX];
12242
 
12243
        if (gethostname(hostname, HOST_NAME_MAX) != 0)
12244
        {
12245
            MSG_ERROR("Can't get host name: " << strerror(errno));
12246
            return;
12247
        }
12248
 
12249
        info.append(hostname);
12250
        info += ";UUID," + TConfig::getUUID();
12251
        sendGlobalString(info);
12252
    }
12253
    else if (strCaseCompare(cmd, "LockRotation") == 0)
12254
    {
12255
        if (pars.size() < 2 || pars[1].empty())
12256
        {
12257
            MSG_ERROR("The command \"LockRotation\" requires an additional parameter!");
12258
            return;
12259
        }
12260
 
12261
        if (strCaseCompare(pars[1], "true") == 0)
12262
            TConfig::setRotationFixed(true);
12263
        else
12264
            TConfig::setRotationFixed(false);
12265
    }
12266
    else if (strCaseCompare(cmd, "ButtonHit") == 0)
12267
    {
12268
        if (pars.size() < 2 || pars[1].empty())
12269
        {
12270
            MSG_ERROR("The command \"ButtonHit\" requires an additional parameter!");
12271
            return;
12272
        }
12273
 
12274
        if (strCaseCompare(pars[1], "true") == 0)
12275
            TConfig::saveSystemSoundState(true);
12276
        else
12277
            TConfig::saveSystemSoundState(false);
12278
    }
12279
    else if (strCaseCompare(cmd, "ReprocessTP4") == 0)
12280
    {
12281
        if (_resetSurface)
12282
            _resetSurface();
12283
    }
12284
}
12285
 
12286
void TPageManager::doTPCACC(int, vector<int>&, vector<string>& pars)
12287
{
12288
    DECL_TRACER("TPageManager::doTPCACC(int, vector<int>&, vector<string>& pars)");
12289
 
12290
    if (pars.size() < 1)
12291
    {
12292
        MSG_ERROR("Too few arguments for TPCACC!");
12293
        return;
12294
    }
12295
 
12296
    string cmd = pars[0];
12297
 
12298
    if (strCaseCompare(cmd, "ENABLE") == 0)
12299
    {
12300
        mInformOrientation = true;
12301
        sendOrientation();
12302
    }
12303
    else if (strCaseCompare(cmd, "DISABLE") == 0)
12304
    {
12305
        mInformOrientation = false;
12306
    }
12307
    else if (strCaseCompare(cmd, "QUERY") == 0)
12308
    {
12309
        sendOrientation();
12310
    }
12311
}
153 andreas 12312
 
279 andreas 12313
#ifndef _NOSIP_
153 andreas 12314
void TPageManager::doTPCSIP(int, vector<int>&, vector<string>& pars)
12315
{
12316
    DECL_TRACER("TPageManager::doTPCSIP(int port, vector<int>& channels, vector<string>& pars)");
12317
 
12318
    if (pars.empty())
12319
        return;
12320
 
12321
    string cmd = toUpper(pars[0]);
12322
 
12323
    if (cmd == "SHOW" && _showPhoneDialog)
12324
        _showPhoneDialog(true);
12325
    else if (!_showPhoneDialog)
12326
    {
12327
        MSG_ERROR("There is no phone dialog registered!");
12328
    }
12329
}
279 andreas 12330
#endif