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