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