bug fix: TIVI-1997, TIVI-2161, An action is inaccurate when the menu of HomeScreen...
[profile/ivi/ico-uxf-homescreen.git] / lib / common / CicoAilItems.cpp
1 /*
2  * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
3  *
4  * This program is licensed under the terms and conditions of the
5  * Apache License, version 2.0.  The full text of the Apache License is at
6  * http://www.apache.org/licenses/LICENSE-2.0
7  *
8  */
9
10 #include <iostream>
11 #include <string>
12 #include <sstream>
13 #include <vector>
14 #include <utility>
15 #include <cstdlib>
16
17 #include <ico_log.h>
18 #include "CicoAilItems.h"
19 #include "CicoConf.h"
20 #include "CicoSystemConfig.h"
21 #include "CicoLibString.h"
22
23 using namespace std;
24
25 /**
26  * @brief constructor
27  */
28 CicoAilItems::CicoAilItems()
29 {
30     ICO_TRA("start");
31     init();
32     ICO_TRA("end");
33 }
34
35 /**
36  * @brief constructor
37  * @param pkg package name(appid) by ail information data
38  * @param icon icon path and file name by ail information data
39  * @param nam name by ail information data
40  * @param ctgry category by ail information data
41  * @param exe exec path by ail information data
42  * @param cateforys environ file data
43  */
44 CicoAilItems::CicoAilItems(const char* pkg, const char* icon,
45                                const char* nam, const char* ctgry,
46                                const char* typ, const char* exe,
47                                const std::string categorys, bool ndisp)
48 {
49     ICO_TRA("start");
50     init();
51     setup(pkg, icon, nam, ctgry, typ, exe, categorys, ndisp);
52     ICO_TRA("end");
53 }
54
55 CicoAilItems::CicoAilItems(const CicoAilItems &s)
56 {
57     m_appid = s.m_appid;    // PACKAGE NAME
58     m_icon = s.m_icon;  // ICON
59     m_name = s.m_name;  // NAME
60     m_execPath = s.m_execPath;  // EXEC
61     m_type = s.m_type;  // TYPE
62
63     m_categories = s.m_categories; // CATEGORIES
64
65     m_nodeID = s.m_nodeID;  // "run=xxx" xxx change to id
66     m_kindID = s.m_kindID;  // "kind=xxx" xxx change to id
67     m_categoryID = s.m_categoryID;  // "category=xxx" xxx change to id
68
69     m_display = s.m_display; //
70     m_layer = s.m_layer;
71     m_displayZone = s.m_displayZone; // display zone number
72     m_soundZone = s.m_soundZone;  // sound zone number
73     m_sound = s.m_sound;
74     m_inputDev = s.m_inputDev;   // input device number
75     m_switch = s.m_switch;
76     m_noIcon = s.m_noIcon;
77     m_animation = s.m_animation;
78     m_animationTime = s.m_animationTime;
79     m_invisibleCPU = s.m_invisibleCPU;
80     m_memnuOverlap = s.m_memnuOverlap;
81     m_autoStart = s.m_autoStart; // auto start flag
82
83     m_group = s.m_group;
84     m_location = s.m_location;
85     m_resumeShow = s.m_resumeShow;
86 }
87
88 /**
89  * @brief
90  */
91 CicoAilItems::~CicoAilItems()
92 {
93     ICO_TRA("start");
94     ICO_TRA("end");
95 }
96 /**
97  * @brief init member 
98  */
99 void CicoAilItems::init()
100 {
101     
102     m_appid.clear();      // PACKAGE NAME
103     m_icon.clear();       // ICON
104     m_name.clear();       // NAME
105     m_execPath.clear();   // EXEC
106     m_type.clear();       // TYPE
107
108     m_categories.clear(); // CATEGORIES
109
110     const CicoSCDefaultConf* oCSCDC;
111     oCSCDC = CicoSystemConfig::getInstance()->getDefaultConf();
112     if (NULL != oCSCDC) {
113         ICO_DBG("CicoAilItems::init base CicoSCDefaultConf");
114         m_nodeID      = oCSCDC->node;
115         m_kindID      = oCSCDC->appkind;
116         m_categoryID  = oCSCDC->category;
117
118         m_display     = oCSCDC->display;
119         m_layer       = oCSCDC->layer;
120         m_displayZone = oCSCDC->displayzone;
121
122         m_sound       = oCSCDC->sound;
123         m_soundZone   = oCSCDC->soundzone;
124
125         m_inputDev    = oCSCDC->inputdev;
126         m_switch      = oCSCDC->inputsw;
127     }
128     else {
129         ICO_DBG("CicoAilItems::init base define");
130         m_nodeID      = DINITm_nodeID; // "run=xxx" xxx change to id
131         m_kindID      = DINITm_kindID; // "kind=xxx" xxx change to id
132         m_categoryID  = DINITm_categoryID; // "category=xxx" xxx change to id
133
134         m_display     = DINITm_display; //
135         m_layer       = DINITm_layer;
136         m_displayZone = DINITm_displayZone; // display zone
137
138         m_soundZone   = DINITm_soundZone; // sound zone
139         m_sound       = DINITm_sound;
140
141         m_inputDev    = DINITm_inputDev; // input device
142         m_switch      = DINITm_switch;
143     }
144
145     m_noIcon = false;
146     m_animation.clear();
147     m_animationTime = DINITm_animationTime;
148     m_invisibleCPU = DINITm_invisibleCPU;
149     m_memnuOverlap = false;
150     m_autoStart = false; // auto start flag
151
152     m_group.clear();
153     m_location.clear();
154     m_resumeShow = false;
155 }
156
157 /**
158  * @brief constructor
159  * @param pkg package name(appid) by ail information data
160  * @param icon icon path and file name by ail information data
161  * @param nam name by ail information data
162  * @param ctgry category by ail information data
163  * @param exe exec path by ail information data
164  * @param cateforys environ file data
165  */
166 void CicoAilItems::setup(const char* pkg, const char* icon,
167                            const char* nam, const char* ctgry,
168                            const char* typ, const char* exe,
169                            std::string categorys, bool ndisp)
170 {
171     ICO_TRA("start");
172     m_appid.assign(pkg);
173     ICO_DBG("package name=%s", pkg? pkg: "(NULL)");
174
175     m_noIcon = ndisp;
176     if (NULL != icon) {
177         m_icon.assign(icon);
178         ICO_DBG("icon path=%s", icon? icon: "(NULL)");
179     }
180
181     if (NULL != nam) {
182         m_name.assign(nam);
183         ICO_DBG("name=%s", nam? nam: "(NULL)");
184     }
185
186     if (NULL != exe) {
187         m_execPath.assign(exe);
188         ICO_DBG("exec path=%s", exe? exe: "(NULL)");
189     }
190
191     if (NULL != typ) {
192         m_type.assign(typ);
193         ICO_DBG("type=%s", typ? typ: "(NULL)");
194     }
195
196     categoryParse(categorys);
197     ICO_TRA("end");
198 }
199
200 const string s_run("run");
201 const string s_kind("kind");
202 const string s_category("category");
203 const string s_display("display");
204 const string s_layer("layer");
205 const string s_dispzone("dispzone");
206 const string s_sound("sound");
207 const string s_input("input");
208 const string s_NoDisplay("NoDisplay");
209 const string s_Animation("Animation");
210 const string s_invisiblecpu("invisiblecpu");
211 const string s_noconfigure("noconfigure");
212 const string s_menuoverlap("menuoverlap");
213 const string s_auto("auto");
214 const string s_noauto("noauto");
215
216 const string s_soundzone("soundzone");
217 const string s_Animation_time("Animation_time");
218
219 /**
220  * @brief category string parse
221  * @parm category string data split code ";"
222  */
223 void CicoAilItems::categoryParse(const std::string categorys)
224 {
225     ICO_TRA("start");
226     if (categorys.empty()) {
227         ICO_TRA("end no category");
228         return;
229     }
230     vector<string> x;
231     split(categorys, ';', x);
232     vector<string>::iterator it = x.begin(); // iterator
233     string displayName;
234     string layerName;
235     string dispZoneName;
236     string soundName;
237     string soundZoneName;
238     string inputDevName;
239     string switchName;
240
241     displayName.clear();
242     layerName.clear();
243     dispZoneName.clear();
244     soundName.clear();
245     soundZoneName.clear();
246     inputDevName.clear();
247     switchName.clear();
248
249     CicoSystemConfig* CSCSC = CicoSystemConfig::getInstance();
250
251     ICO_DBG("category def size = %d", x.size());
252     for (it = x.begin(); it != x.end(); it++) {
253
254         // run
255         if (0 == strncasecmp(it->c_str(), s_run.c_str(), s_run.size())) {
256             if (true == categoryParseRun(*it)) {
257                 ICO_DBG("Parse OK %s", it->c_str());
258                 continue;
259             }
260         }
261
262         // kind
263         if (0 == strncasecmp(it->c_str(), s_kind.c_str(), s_kind.size())) {
264             if (true == categoryParseKind(*it)) {
265                 ICO_DBG("Parse OK %s", it->c_str());
266                 continue;
267             }
268         }
269
270         // category
271         if (0 == strncasecmp(it->c_str(), s_category.c_str(),
272                              s_category.size())) {
273             if (true == categoryParseCategory(*it)) {
274                 ICO_DBG("Parse OK %s", it->c_str());
275                 continue;
276             }
277         }
278
279         // display
280         if (0 == strncasecmp(it->c_str(), s_display.c_str(),
281                              s_display.size())) {
282             if (true == categoryParseGetValue(*it, s_display, displayName)) {
283                 ICO_DBG("Parse OK %s", it->c_str());
284                 continue;
285             }
286         }
287
288         // layer
289         if (0 == strncasecmp(it->c_str(), s_layer.c_str(), s_layer.size())) {
290             if (true == categoryParseGetValue(*it, s_layer, layerName)) {
291                 ICO_DBG("Parse OK %s", it->c_str());
292                 continue;
293             }
294         }
295
296         // dispzone
297         if (0 == strncasecmp(it->c_str(), s_dispzone.c_str(),
298                              s_dispzone.size())) {
299             if (true == categoryParseGetValue(*it, s_dispzone, dispZoneName)) {
300                 ICO_DBG("Parse OK %s", it->c_str());
301                 continue;
302             }
303         }
304
305         // sound / soundzone
306         if (0 == strncasecmp(it->c_str(), s_soundzone.c_str(),
307                              s_soundzone.size())) {
308             if (true == categoryParseGetValue(*it, s_soundzone,
309                                               soundZoneName)) {
310                 ICO_DBG("Parse OK %s", it->c_str());
311                 continue;
312             }
313         }
314         if (0 == strncasecmp(it->c_str(), s_sound.c_str(), s_sound.size())) {
315             if (true == categoryParseGetValue(*it, s_sound, soundName)) {
316                 ICO_DBG("Parse OK %s", it->c_str());
317                 continue;
318             }
319         }
320
321         // input
322         if (0 == strncasecmp(it->c_str(), s_input.c_str(), s_input.size())) {
323             if (true == categoryParseGetValue(*it, s_input, inputDevName)) {
324                 ICO_DBG("Parse OK %s", it->c_str());
325                 continue;
326             }
327         }
328 // TODO mk_k not get switchName
329 //     switchName
330 // TODO mk_k not get switchName
331
332         // NoDisplay
333         if (0 == strncasecmp(it->c_str(), s_NoDisplay.c_str(),
334                              s_NoDisplay.size())) {
335             if (true == categoryParseNodisplay(*it)) {
336                 ICO_DBG("Parse OK %s", it->c_str());
337                 continue;
338             }
339         }
340
341         // Animation / Animation_time
342         if (0 == strncasecmp(it->c_str(), s_Animation.c_str(),
343                              s_Animation.size())) {
344             if (true == categoryParseAnimation(*it)) {
345                 ICO_DBG("Parse OK %s", it->c_str());
346                 continue;
347             }
348         }
349
350         // invisiblecpu
351         if (0 == strncasecmp(it->c_str(), s_invisiblecpu.c_str(),
352                              s_invisiblecpu.size())) {
353             if (true == categoryParseInvisiblecpu(*it)) {
354                 ICO_DBG("Parse OK %s", it->c_str());
355                 continue;
356             }
357         }
358
359         // noconfigure
360         if (0 == strncasecmp(it->c_str(), s_noconfigure.c_str(),
361                              s_noconfigure.size())) {
362             if (true == categoryParseNoconfigure(*it)) {
363                 ICO_DBG("Parse OK %s", it->c_str());
364                 continue;
365             }
366         }
367
368         // menuoverlap
369         if (0 == strncasecmp(it->c_str(), s_menuoverlap.c_str(),
370                              s_menuoverlap.size())) {
371             if (true == categoryParseMenuoverlap(*it)) {
372                 ICO_DBG("Parse OK %s", it->c_str());
373                 continue;
374             }
375         }
376
377         // auto
378         if (0 == strncasecmp(it->c_str(), s_auto.c_str(), s_auto.size())) {
379             if (true == categoryParseAuto(*it)) {
380                 ICO_DBG("Parse OK %s", it->c_str());
381                 continue;
382             }
383         }
384
385         // noauto
386         if (0 == strncasecmp(it->c_str(), s_noauto.c_str(),
387                              s_noauto.size())) {
388             if (true == categoryParseNoauto(*it)) {
389                 ICO_DBG("Parse OK %s", it->c_str());
390                 continue;
391             }
392         }
393
394         int categoryID = CSCSC->getCategoryIdbyName(*it);
395         const char* ttt = it->c_str()? it->c_str(): "(NULL)";
396         ICO_DBG("Category %s->%d", ttt, categoryID);
397         if (-1 != categoryID) {
398             ICO_DBG("Category %d -> %d(%s)", m_categoryID, categoryID, ttt);
399             m_categoryID = categoryID;
400             continue;
401         }
402
403         ICO_DBG("Parse UNKOWN %s", it->c_str());
404     }
405     categoryGetDisplay(displayName, layerName, dispZoneName);
406     categoryGetSound(soundName, soundZoneName);
407     categoryGetInput(inputDevName, switchName);
408     ICO_TRA("end");
409 }
410
411 /**
412  * @brief category string parse
413  * @param category string
414  * @retval true parse success
415  * @retval false parse fail
416  */
417 bool CicoAilItems::categoryParseRun(const string& s)
418 {
419     ICO_TRA("start");
420     const char* ps = s.c_str();
421     int c = s_run.size();
422     if ('=' != ps[c]) {
423         ICO_TRA("end");
424         return false;
425     }
426     // "run=xxx"
427 // TODO mk_k START getHostID(..) request order
428     CicoSystemConfig* CSCSC = CicoSystemConfig::getInstance();
429     int nodeID = CSCSC->getNodeIdbyName(&ps[c+1]);
430 // TODO mk_k int nodeID = -1;
431 // TODO mk_k int nodeID = CSCSC->getHostID(&ps[c+1]);
432 // TODO mk_k END getHostID(..) request order
433     if (nodeID==-1) {
434         ICO_TRA("end");
435         return false;
436     }
437     m_nodeID = nodeID;
438     ICO_TRA("end %d", m_nodeID);
439     return true;
440 }
441
442 /**
443  * @brief category string parse
444  * @param category string
445  * @retval true parse success
446  * @retval false parse fail
447  */
448 bool CicoAilItems::categoryParseKind(const string& s)
449 {
450     ICO_TRA("start");
451     const char* ps = s.c_str();
452     int c = s_kind.size();
453     if ('=' != ps[c]) {
454         ICO_TRA("end");
455         return false;
456     }
457     // "kind=xxx" xxx change to id
458     CicoSystemConfig* CSCSC = CicoSystemConfig::getInstance();
459     int kindID = CSCSC->getAppKindIdbyName(&ps[c+1]);
460     if (kindID==-1) {
461         ICO_TRA("end");
462         return false;
463     }
464     m_kindID = kindID;
465     ICO_TRA("end %d", m_kindID);
466     return true;
467 }
468
469 /**
470  * @brief category string parse
471  * @param category string
472  * @retval true parse success
473  * @retval false parse fail
474  */
475 bool CicoAilItems::categoryParseCategory(const string& s)
476 {
477     ICO_TRA("start");
478     const char* ps = s.c_str();
479     int c = s_category.size();
480     if ('=' != ps[c]) {
481         ICO_TRA("end");
482         return false;  // not "category=xxx"
483     }
484     // "category=xxx" xxx change to id
485     CicoSystemConfig* CSCSC = CicoSystemConfig::getInstance();
486     int categoryID = CSCSC->getCategoryIdbyName(&ps[c+1]);
487     if (categoryID==-1) {
488         ICO_TRA("end");
489         return false; // unkown category xxx
490     }
491     m_categoryID = categoryID;
492     ICO_TRA("end %d", m_categoryID);
493     return true;
494 }
495
496 /**
497  * @brief value get
498  * @param s "key=value" string
499  * @param k key string
500  * @param val store value
501  * @retval true get value success
502  * @retval false get not good
503  */
504 bool CicoAilItems::categoryParseGetValue(const std::string& s,
505                                            const std::string& k,
506                                            std::string & val)
507 {
508     ICO_TRA("start, %s, %s", s.c_str(), k.c_str());
509     const char* ps = s.c_str();
510     int c = k.size();
511     int c2;
512 #if 0 // TODO mk_k x!?
513     int x = -1;
514 #endif // TODO mk_k x!?
515     if ('=' == ps[c]) {
516 #if 0 // TODO mk_k x!?
517         x = 0;
518 #endif // TODO mk_k x!?
519         c2 = c+1;
520     }
521 #if 0 // TODO mk_k .[0-9] !?
522     else if (('.' == ps[c]) &&
523              (0 != isdigit((int)ps[c+1])) &&
524              ('=' == ps[c+2])) {
525         x = (int) ps[c+1] - '0';
526         c2 = c+3;
527
528     }
529 #endif // TODO mk_k .[0-9] !?
530     else {
531         ICO_TRA("end NG");
532         return false;
533     }
534     val = s.substr(c2);
535     ICO_TRA("end %s", val.c_str());
536     return true;
537 }
538     
539 /**
540  * @brief get
541  * @param disp display key name
542  * @param layer display layer key name
543  * @param zone display zone key name
544  * @retval true parse success
545  * @retval false parse fail
546  */
547 bool CicoAilItems::categoryGetDisplay(const string& disp,
548                                         const string& layer,
549                                         const string& zone)
550 {
551     ICO_TRA("start");
552     if (true == disp.empty()) {
553         ICO_TRA("end not get display's data");
554         return false;
555     }
556
557     CicoSystemConfig* CSCSC = CicoSystemConfig::getInstance();
558     m_display = CSCSC->getDisplayIdbyName(disp);
559     ICO_DBG("display %s->%d", disp.c_str(), m_display);
560     if (false == layer.empty()) {
561         m_layer = CSCSC->getLayerIdfbyName(disp, layer);
562         ICO_DBG("layer %s, %s->%d", disp.c_str(), layer.c_str(), m_layer);
563     }
564     if (false == zone.empty()) {
565         m_displayZone = CSCSC->getDizplayZoneIdbyName(disp, zone);
566         ICO_DBG("zone %s, %s->%d", disp.c_str(), zone.c_str(), m_displayZone);
567     }
568     ICO_TRA("end d:%d l:%d z:%d", m_display, m_layer, m_displayZone);
569     return true;
570 }
571
572 /**
573  * @brief get sound config data
574  * @param sound name key
575  * @param soundZone name key
576  * @retval true get data
577  * @retval false param fail
578  */
579 bool CicoAilItems::categoryGetSound(const string& sound, const string& zone)
580 {
581     ICO_TRA("start");
582     if (true == sound.empty()) {
583         ICO_TRA("end not get sound's data");
584         return false;
585     }
586
587     CicoSystemConfig* CSCSC = CicoSystemConfig::getInstance();
588     m_sound = CSCSC->getSoundIdbyName(sound);
589     ICO_DBG("sound %s->%d", sound.c_str(), m_sound);
590     if (false == zone.empty()) {
591         m_soundZone = CSCSC->getSoundZoneIdbyName(sound, zone);
592         ICO_DBG("zone %s, %s->%d", sound.c_str(), zone.c_str(), m_soundZone);
593     }
594     ICO_TRA("end s:%d z:%d", m_sound, m_soundZone);
595     return true;
596 }
597
598 bool CicoAilItems::categoryGetInput(const string& inputDev,
599                                       const string& sw)
600 {
601     ICO_TRA("start");
602     if (true == inputDev.empty()) {
603         ICO_TRA("end not get input Device's data");
604         return false;
605     }
606
607     CicoSystemConfig* CSCSC = CicoSystemConfig::getInstance();
608     m_sound = CSCSC->getInputDevIdbyName(inputDev);
609     ICO_DBG("sound %s->%d", inputDev.c_str(), m_sound);
610     if (false == sw.empty()) {
611         m_switch = CSCSC->getSwitchIdbyName(inputDev, sw);
612         ICO_DBG("switch %s, %s->%d", inputDev.c_str(), sw.c_str(), m_switch);
613     }
614     ICO_TRA("end idev:%d i:%d", m_inputDev, m_switch);
615     return true;
616 }
617
618 /**
619  * @brief category string parse
620  * @param category string
621  * @retval true parse success
622  * @retval false parse fail
623  */
624 bool CicoAilItems::categoryParseNodisplay(const string& s)
625 {
626     ICO_TRA("start");
627     const char* ps = s.c_str();
628     int c = s_NoDisplay.size();
629     if ('=' != ps[c]) {
630         ICO_TRA("end");
631         return false;  // not "NoDisplay=true/false"
632     }
633     if (0 == strcasecmp(&ps[c+1], "false")) {
634         m_noIcon = false;
635     }
636     else {
637         m_noIcon = true;
638     }
639     ICO_TRA("end %s", m_noIcon? "true": "false");
640     return true;
641 }
642
643 /**
644  * @brief category string parse
645  * @param category string
646  * @retval true parse success
647  * @retval false parse fail
648  */
649 bool CicoAilItems::categoryParseAnimation(const string& s)
650 {
651     ICO_TRA("start");
652     const char* ps = s.c_str();
653     int c = s_Animation_time.size();
654     bool b_at = false;  // animation time flag off
655     if (0 == strncasecmp(ps, s_Animation_time.c_str(), c)) {
656         b_at = true;    // flag on
657     }
658     else {
659         c = s_Animation.size(); // not Animation_time
660     }
661     if ('=' != ps[c]) {
662         ICO_TRA("end");
663         return false;  // not "Animation=xxx" / "Animation_time=xxx"
664     }
665     if (true == b_at) {
666         // Animation_time
667         m_animationTime = (int)strtol(&ps[c+1], (char **)0, 0);
668     }
669     else {
670         // Animation
671         m_animation = &ps[c+1];
672     }
673     ICO_TRA("end");
674     return true;
675 }
676
677 /**
678  * @brief category string parse
679  * @param category string
680  * @retval true parse success
681  * @retval false parse fail
682  */
683 bool CicoAilItems::categoryParseInvisiblecpu(const string& s)
684 {
685     ICO_TRA("start");
686     const char* ps = s.c_str();
687     int c = s_invisiblecpu.size();
688     if ('=' != ps[c]) {
689         ICO_TRA("end");
690         return false;  // not "invisibluecpu=xxx"
691     }
692     if (0 == strcasecmp(&ps[c+1], "yes")) {
693         m_invisibleCPU = 100;
694     }
695     else if (0 != strcasecmp(&ps[c+1], "no")) {
696         m_invisibleCPU = (int)strtol(&ps[c+1], (char **)0, 0);
697     }
698     else { // "no"
699         m_invisibleCPU = 0;
700     }
701     ICO_TRA("end %s,%d", &ps[c+1], m_invisibleCPU);
702     return true;
703 }
704
705 /**
706  * @brief category string parse
707  * @param category string
708  * @retval true parse success
709  * @retval false parse fail
710  */
711 bool CicoAilItems::categoryParseNoconfigure(const string&)
712 {
713 // TODO mk_k
714     ICO_TRA("start");
715 //    m_noconfigure = true;
716     ICO_TRA("end");
717 //    return true;
718     return false;
719 }
720
721 /**
722  * @brief category string parse
723  * @param category string
724  * @retval true parse success
725  * @retval false parse fail
726  */
727 bool CicoAilItems::categoryParseMenuoverlap(const string&)
728 {
729     ICO_TRA("start");
730     m_memnuOverlap = true;
731     ICO_TRA("end");
732     return true;
733 }
734
735 /**
736  * @brief category string parse
737  * @param category string
738  * @retval true parse success
739  * @retval false parse fail
740  */
741 bool CicoAilItems::categoryParseAuto(const string&)
742 {
743     ICO_TRA("start");
744     m_autoStart = true;
745     ICO_TRA("end");
746     return true;
747 }
748
749 /**
750  * @brief category string parse
751  * @param category string
752  * @retval true parse success
753  * @retval false parse fail
754  */
755 bool CicoAilItems::categoryParseNoauto(const string&)
756 {
757     ICO_TRA("start");
758     m_autoStart = false;
759     ICO_TRA("end");
760     return true;
761 }
762 // vim:set expandtab ts=4 sw=4: