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