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