Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

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