00001 #include <deque>
00002 using namespace std;
00003
00004 #include <cmath>
00005 #include <cstdlib>
00006
00007 #include <QApplication>
00008 #include <QCoreApplication>
00009 #include <QPixmap>
00010 #include <QList>
00011 #include <QFile>
00012
00013 #include "xmlparse.h"
00014 #include "mythmiscutil.h"
00015 #include "mythcorecontext.h"
00016 #include "mythfontproperties.h"
00017 #include "mythuihelper.h"
00018 #include "x11colors.h"
00019 #include "mythlogging.h"
00020 #include "mythcorecontext.h"
00021
00022 #ifdef USING_MINGW
00023 #undef LoadImage
00024 #endif
00025
00026 #define LOC QString("XMLParse: ")
00027
00028 XMLParse::XMLParse(void) : wmult(0.0), hmult(0.0)
00029 {
00030 allTypes = new vector<LayerSet *>;
00031 ui = GetMythUI();
00032 }
00033
00034 XMLParse::~XMLParse()
00035 {
00036 vector<LayerSet *>::iterator i = allTypes->begin();
00037 for (; i != allTypes->end(); ++i)
00038 {
00039 LayerSet *type = (*i);
00040 if (type)
00041 delete type;
00042 }
00043 delete allTypes;
00044 }
00045
00046 bool XMLParse::LoadTheme(QDomElement &ele, QString winName, QString specialfile)
00047 {
00048 fontSizeType = gCoreContext->GetSetting("ThemeFontSizeType", "default");
00049
00050 QStringList searchpath = ui->GetThemeSearchPath();
00051 for (QStringList::const_iterator ii = searchpath.begin();
00052 ii != searchpath.end(); ++ii)
00053 {
00054 QString themefile = *ii + specialfile + "ui.xml";
00055 if (doLoadTheme(ele, winName, themefile))
00056 {
00057 LOG(VB_GENERAL, LOG_INFO, LOC + QString("LoadTheme using '%1'")
00058 .arg(themefile));
00059 return true;
00060 }
00061 }
00062
00063 return false;
00064 }
00065
00066 bool XMLParse::doLoadTheme(QDomElement &ele, QString winName, QString themeFile)
00067 {
00068 QDomDocument doc;
00069 QFile f(themeFile);
00070
00071 if (!f.open(QIODevice::ReadOnly))
00072 {
00073 #if 0
00074 LOG(VB_GENERAL, LOG_ERR, "XMLParse::LoadTheme(): Can't open: " +
00075 themeFile);
00076 #endif
00077 return false;
00078 }
00079
00080 QString errorMsg;
00081 int errorLine = 0;
00082 int errorColumn = 0;
00083
00084 if (!doc.setContent(&f, false, &errorMsg, &errorLine, &errorColumn))
00085 {
00086 LOG(VB_GENERAL, LOG_ERR, LOC +
00087 QString("Parsing: %1 at line: %2 column: %3")
00088 .arg(themeFile).arg(errorLine).arg(errorColumn) +
00089 QString("\n\t\t\t%1").arg(errorMsg));
00090 f.close();
00091 return false;
00092 }
00093
00094 f.close();
00095
00096 QDomElement docElem = doc.documentElement();
00097 QDomNode n = docElem.firstChild();
00098 while (!n.isNull())
00099 {
00100 QDomElement e = n.toElement();
00101 if (!e.isNull())
00102 {
00103 if (e.tagName() == "window")
00104 {
00105 QString name = e.attribute("name", "");
00106 if (name.isNull() || name.isEmpty())
00107 {
00108 LOG(VB_GENERAL, LOG_WARNING, LOC + "Window needs a name");
00109 return false;
00110 }
00111
00112 if (name == winName)
00113 {
00114 ele = e;
00115 return true;
00116 }
00117 }
00118 else
00119 {
00120 LOG(VB_GENERAL, LOG_WARNING, LOC +
00121 QString("Unknown element: %1").arg(e.tagName()));
00122 return false;
00123 }
00124 }
00125 n = n.nextSibling();
00126 }
00127
00128 return false;
00129 }
00130
00131 QString XMLParse::getFirstText(QDomElement &element)
00132 {
00133 for (QDomNode dname = element.firstChild(); !dname.isNull();
00134 dname = dname.nextSibling())
00135 {
00136 QDomText t = dname.toText();
00137 if (!t.isNull())
00138 return t.data();
00139 }
00140 return "";
00141 }
00142
00143 void XMLParse::parseFont(QDomElement &element)
00144 {
00145 QString name;
00146 QString face;
00147 QString bold;
00148 QString ital;
00149 QString under;
00150
00151 int size = -1;
00152 int sizeSmall = -1;
00153 int sizeBig = -1;
00154 QPoint shadowOffset = QPoint(0, 0);
00155 QString color = "#ffffff";
00156 QString dropcolor = "#000000";
00157 QString hint;
00158 QFont::StyleHint styleHint = QFont::Helvetica;
00159
00160 bool haveSizeSmall = false;
00161 bool haveSizeBig = false;
00162 bool haveSize = false;
00163 bool haveFace = false;
00164 bool haveColor = false;
00165 bool haveDropColor = false;
00166 bool haveBold = false;
00167 bool haveShadow = false;
00168 bool haveItal = false;
00169 bool haveUnder = false;
00170
00171 fontProp *baseFont = NULL;
00172
00173 name = element.attribute("name", "");
00174 if (name.isNull() || name.isEmpty())
00175 {
00176 LOG(VB_GENERAL, LOG_WARNING, LOC + "Font needs a name");
00177 return;
00178 }
00179
00180 QString base = element.attribute("base", "");
00181 if (base.size())
00182 {
00183 baseFont = GetFont(base);
00184 if (!baseFont)
00185 {
00186 LOG(VB_GENERAL, LOG_WARNING, LOC +
00187 QString("Specified base font '%1' does not exist for font '%2'")
00188 .arg(base).arg(face));
00189 return;
00190 }
00191 }
00192
00193 face = element.attribute("face", "");
00194 if (face.isNull() || face.isEmpty())
00195 {
00196 if (!baseFont)
00197 {
00198 LOG(VB_GENERAL, LOG_WARNING, LOC + "Font needs a face");
00199 return;
00200 }
00201 }
00202 else
00203 {
00204 haveFace = true;
00205 }
00206
00207 hint = element.attribute("stylehint", "");
00208 if (hint.size())
00209 {
00210 styleHint = (QFont::StyleHint)hint.toInt();
00211 }
00212
00213 for (QDomNode child = element.firstChild(); !child.isNull();
00214 child = child.nextSibling())
00215 {
00216 QDomElement info = child.toElement();
00217 if (!info.isNull())
00218 {
00219 if (info.tagName() == "size")
00220 {
00221 haveSize = true;
00222 size = getFirstText(info).toInt();
00223 }
00224 else if (info.tagName() == "size:small")
00225 {
00226 haveSizeSmall = true;
00227 sizeSmall = getFirstText(info).toInt();
00228 }
00229 else if (info.tagName() == "size:big")
00230 {
00231 haveSizeBig = true;
00232 sizeBig = getFirstText(info).toInt();
00233 }
00234 else if (info.tagName() == "color")
00235 {
00236 haveColor = true;
00237 color = getFirstText(info);
00238 }
00239 else if (info.tagName() == "dropcolor")
00240 {
00241 haveDropColor = true;
00242 dropcolor = getFirstText(info);
00243 }
00244 else if (info.tagName() == "shadow")
00245 {
00246 haveShadow = true;
00247 shadowOffset = parsePoint(getFirstText(info));
00248 shadowOffset.setX((int)(shadowOffset.x() * wmult));
00249 shadowOffset.setY((int)(shadowOffset.y() * hmult));
00250 }
00251 else if (info.tagName() == "bold")
00252 {
00253 haveBold = true;
00254 bold = getFirstText(info);
00255 }
00256 else if (info.tagName() == "italics")
00257 {
00258 haveItal = true;
00259 ital = getFirstText(info);
00260 }
00261 else if (info.tagName() == "underline")
00262 {
00263 haveUnder = true;
00264 under = getFirstText(info);
00265 }
00266 else
00267 {
00268 LOG(VB_GENERAL, LOG_WARNING, LOC +
00269 QString("Unknown tag '%1' in font") .arg(info.tagName()));
00270 return;
00271 }
00272 }
00273 }
00274
00275 fontProp *testFont = GetFont(name, false);
00276 if (testFont)
00277 {
00278 LOG(VB_GENERAL, LOG_ERR, LOC +
00279 QString("MythTV already has a font called: '%1'").arg(name));
00280 return;
00281 }
00282
00283 fontProp newFont;
00284
00285 if (baseFont)
00286 newFont = *baseFont;
00287
00288 if ( haveSizeSmall && fontSizeType == "small")
00289 {
00290 if (sizeSmall > 0)
00291 size = sizeSmall;
00292 }
00293 else if (haveSizeBig && fontSizeType == "big")
00294 {
00295 if (sizeBig > 0)
00296 size = sizeBig;
00297 }
00298
00299 if (size < 0 && !baseFont)
00300 {
00301 LOG(VB_GENERAL, LOG_ERR, LOC + "Font size must be > 0");
00302 return;
00303 }
00304
00305 if (baseFont && !haveSize)
00306 size = baseFont->face.pointSize();
00307 else
00308 size = GetMythMainWindow()->NormalizeFontSize(size);
00309
00310
00311 if (!haveFace && baseFont)
00312 {
00313 newFont.face = baseFont->face;
00314 if (haveSize)
00315 newFont.face.setPointSize(size);
00316 }
00317 else
00318 {
00319 QFont temp(face, size);
00320 temp.setStyleHint(styleHint, QFont::PreferAntialias);
00321
00322 if (!temp.exactMatch())
00323 temp = QFont(QFontInfo(QApplication::font()).family(), size);
00324
00325 newFont.face = temp;
00326 }
00327
00328 if (baseFont && !haveBold)
00329 newFont.face.setBold(baseFont->face.bold());
00330 else
00331 {
00332 if (bold.toLower() == "yes")
00333 newFont.face.setBold(true);
00334 else
00335 newFont.face.setBold(false);
00336 }
00337
00338 if (baseFont && !haveItal)
00339 newFont.face.setItalic(baseFont->face.italic());
00340 else
00341 {
00342 if (ital.toLower() == "yes")
00343 newFont.face.setItalic(true);
00344 else
00345 newFont.face.setItalic(false);
00346 }
00347
00348 if (baseFont && !haveUnder)
00349 newFont.face.setUnderline(baseFont->face.underline());
00350 else
00351 {
00352 if (under.toLower() == "yes")
00353 newFont.face.setUnderline(true);
00354 else
00355 newFont.face.setUnderline(false);
00356 }
00357
00358 if (haveColor)
00359 {
00360 QColor foreColor(color);
00361 newFont.color = foreColor;
00362 }
00363
00364 if (haveDropColor)
00365 {
00366 QColor dropColor(dropcolor);
00367 newFont.dropColor = dropColor;
00368 }
00369
00370 if (haveShadow)
00371 newFont.shadowOffset = shadowOffset;
00372
00373 fontMap[name] = newFont;
00374 }
00375
00376 fontProp *XMLParse::GetFont(const QString &text, bool checkGlobal)
00377 {
00378 fontProp *ret;
00379 if (fontMap.contains(text))
00380 ret = &fontMap[text];
00381 else if (checkGlobal && globalFontMap.contains(text))
00382 ret = &globalFontMap[text];
00383 else
00384 ret = NULL;
00385 return ret;
00386 }
00387
00388 void XMLParse::normalizeRect(QRect &rect)
00389 {
00390 rect.setWidth((int)(rect.width() * wmult));
00391 rect.setHeight((int)(rect.height() * hmult));
00392 rect.moveTopLeft(QPoint((int)(rect.x() * wmult),
00393 (int)(rect.y() * hmult)));
00394 rect = rect.normalized();
00395 }
00396
00397 QPoint XMLParse::parsePoint(QString text)
00398 {
00399 QPoint retval(0,0);
00400 QStringList tmp = text.split(',', QString::SkipEmptyParts);
00401 bool x_ok = false, y_ok = false;
00402 if (tmp.size() >= 2)
00403 {
00404 retval = QPoint(tmp[0].toInt(&x_ok), tmp[1].toInt(&y_ok));
00405 if (!x_ok || !y_ok)
00406 retval = QPoint(0,0);
00407 }
00408 return retval;
00409 }
00410
00411 QRect XMLParse::parseRect(QString text)
00412 {
00413 bool x_ok = false, y_ok = false;
00414 bool w_ok = false, h_ok = false;
00415 QRect retval(0, 0, 0, 0);
00416 QStringList tmp = text.split(',', QString::SkipEmptyParts);
00417 if (tmp.size() >= 4)
00418 {
00419 retval = QRect(tmp[0].toInt(&x_ok), tmp[1].toInt(&y_ok),
00420 tmp[2].toInt(&w_ok), tmp[3].toInt(&h_ok));
00421 if (!x_ok || !y_ok || !w_ok || !h_ok)
00422 retval = QRect(0,0,0,0);
00423 }
00424 return retval;
00425 }
00426
00427
00428 void XMLParse::parseContainer(QDomElement &element, QString &newname, int &context, QRect &area)
00429 {
00430 context = -1;
00431 QString debug = "";
00432 QString name = element.attribute("name", "");
00433 if (name.isNull() || name.isEmpty())
00434 {
00435 LOG(VB_GENERAL, LOG_WARNING, LOC + "Container needs a name");
00436 return;
00437 }
00438
00439 LayerSet *container = GetSet(name);
00440 if (container)
00441 {
00442 LOG(VB_GENERAL, LOG_WARNING, LOC +
00443 QString("Container: '%1' already exists").arg(name));
00444 return;
00445 }
00446 newname = name;
00447
00448 container = new LayerSet(name);
00449
00450 layerMap[name] = container;
00451
00452 bool ok = true;
00453 for (QDomNode child = element.firstChild(); !child.isNull();
00454 child = child.nextSibling())
00455 {
00456 QDomElement info = child.toElement();
00457 if (!info.isNull())
00458 {
00459 if (info.tagName() == "debug")
00460 {
00461 debug = getFirstText(info);
00462 if (debug.toLower() == "yes")
00463 container->SetDebug(true);
00464 }
00465 else if (info.tagName() == "context")
00466 {
00467 context = getFirstText(info).toInt();
00468 }
00469 else if (info.tagName() == "area")
00470 {
00471 area = parseRect(getFirstText(info));
00472 normalizeRect(area);
00473 container->SetAreaRect(area);
00474 }
00475 else if (info.tagName() == "keyboard")
00476 {
00477 parseKeyboard(container, info);
00478 }
00479 else
00480 {
00481 LOG(VB_GENERAL, LOG_ERR, LOC +
00482 QString("Container '%1' contains unknown child: '%2'")
00483 .arg(name).arg(info.tagName()));
00484 ok = false;
00485 }
00486 }
00487 }
00488 if (!ok)
00489 {
00490 LOG(VB_GENERAL, LOG_ERR, LOC +
00491 QString("Could not parse container '%1'. Ignoring.") .arg(name));
00492 return;
00493 }
00494
00495 if (context != -1)
00496 container->SetContext(context);
00497
00498
00499 allTypes->push_back(container);
00500 }
00501
00502 LayerSet *XMLParse::GetSet(const QString &text)
00503 {
00504 LayerSet *ret = NULL;
00505 if (layerMap.contains(text))
00506 ret = layerMap[text];
00507
00508 return ret;
00509 }
00510
00511
00512 void XMLParse::parseKey(LayerSet *container, QDomElement &element)
00513 {
00514 QPixmap *normalImage = NULL, *focusedImage = NULL;
00515 QPixmap *downImage = NULL, *downFocusedImage = NULL;
00516 QString normalFontName = "", focusedFontName = "";
00517 QString downFontName = "", downFocusedFontName = "";
00518 QString name, order, type;
00519 QString normalChar = "", shiftChar = "";
00520 QString altChar = "", shiftaltChar = "";
00521 QString moveLeft = "", moveRight = "";
00522 QString moveUp = "", moveDown = "";
00523 QPoint pos = QPoint(0, 0);
00524
00525 name = element.attribute("name", "");
00526 if (name.isNull() || name.isEmpty())
00527 {
00528 LOG(VB_GENERAL, LOG_WARNING, LOC + "key needs a name");
00529 return;
00530 }
00531
00532 type = element.attribute("type", "");
00533 if (type.isNull() || type.isEmpty())
00534 {
00535 LOG(VB_GENERAL, LOG_WARNING, LOC + "key needs a type");
00536 return;
00537 }
00538
00539 order = element.attribute("draworder", "");
00540 if (order.isNull() || order.isEmpty())
00541 {
00542 LOG(VB_GENERAL, LOG_WARNING, LOC + "key needs an order");
00543 return;
00544 }
00545
00546 for (QDomNode child = element.firstChild(); !child.isNull();
00547 child = child.nextSibling())
00548 {
00549 QDomElement e = child.toElement();
00550 if (!e.isNull())
00551 {
00552 if (e.tagName() == "position")
00553 {
00554 pos = parsePoint(getFirstText(e));
00555 pos.setX((int)(pos.x() * wmult));
00556 pos.setY((int)(pos.y() * hmult));
00557
00558 }
00559 else if (e.tagName() == "char")
00560 {
00561 normalChar = e.attribute("normal", "");
00562 shiftChar = e.attribute("shift", "");
00563 altChar = e.attribute("alt", "");
00564 shiftaltChar = e.attribute("altshift", "");
00565 }
00566 else if (e.tagName() == "move")
00567 {
00568 moveLeft = e.attribute("left", "");
00569 moveRight = e.attribute("right", "");
00570 moveUp = e.attribute("up", "");
00571 moveDown = e.attribute("down", "");
00572 }
00573 else if (e.tagName() == "image")
00574 {
00575 QString imgname = "";
00576 QString imgfunction = "";
00577
00578 imgfunction = e.attribute("function", "");
00579 if (imgfunction.isNull() || imgfunction.isEmpty())
00580 {
00581 LOG(VB_GENERAL, LOG_WARNING, LOC +
00582 "Image in a key needs a function");
00583 return;
00584 }
00585
00586 imgname = e.attribute("filename", "");
00587 if (imgname.isNull() || imgname.isEmpty())
00588 {
00589 LOG(VB_GENERAL, LOG_WARNING, LOC +
00590 "Image in a key needs a filename");
00591 return;
00592 }
00593
00594 if (imgfunction.toLower() == "normal")
00595 {
00596 normalImage = ui->LoadScalePixmap(imgname);
00597 if (!normalImage)
00598 {
00599 LOG(VB_GENERAL, LOG_WARNING, LOC +
00600 QString("Can't locate 'normal' image '%1'")
00601 .arg(imgname));
00602 }
00603 }
00604 else if (imgfunction.toLower() == "focused")
00605 {
00606 focusedImage = ui->LoadScalePixmap(imgname);
00607 if (!focusedImage)
00608 {
00609 LOG(VB_GENERAL, LOG_WARNING, LOC +
00610 QString("Can't locate 'focused' image '%1'")
00611 .arg(imgname));
00612 }
00613 }
00614 else if (imgfunction.toLower() == "down")
00615 {
00616 downImage = ui->LoadScalePixmap(imgname);
00617
00618 if (!downImage)
00619 {
00620 LOG(VB_GENERAL, LOG_WARNING, LOC +
00621 QString("Can't locate 'down' image '%1'")
00622 .arg(imgname));
00623 }
00624 }
00625 else if (imgfunction.toLower() == "downfocused")
00626 {
00627 downFocusedImage = ui->LoadScalePixmap(imgname);
00628
00629 if (!downFocusedImage)
00630 {
00631 LOG(VB_GENERAL, LOG_WARNING, LOC +
00632 QString("Can't locate 'downfocused' image '%1'")
00633 .arg(imgname));
00634 }
00635 }
00636 else
00637 {
00638 LOG(VB_GENERAL, LOG_WARNING, LOC +
00639 QString("Unknown image function '%1' in key")
00640 .arg(imgfunction));
00641 return;
00642 }
00643 }
00644 else if (e.tagName() == "fcnfont")
00645 {
00646 QString fontName = e.attribute("name", "");
00647 QString fontFcn = e.attribute("function", "");
00648
00649 if (fontFcn.toLower() == "normal")
00650 normalFontName = fontName;
00651 else if (fontFcn.toLower() == "focused")
00652 focusedFontName = fontName;
00653 else if (fontFcn.toLower() == "down")
00654 downFontName = fontName;
00655 else if (fontFcn.toLower() == "downfocused")
00656 downFocusedFontName = fontName;
00657 else
00658 {
00659 LOG(VB_GENERAL, LOG_WARNING, LOC +
00660 QString("Unknown font function '%1' in key")
00661 .arg(fontFcn));
00662 return;
00663 }
00664 }
00665 else
00666 {
00667 LOG(VB_GENERAL, LOG_WARNING, LOC +
00668 QString("Unknown tag '%1' in key").arg(e.tagName()));
00669 return;
00670 }
00671 }
00672 }
00673
00674 fontProp *normalFont = GetFont(normalFontName);
00675 fontProp *focusedFont = GetFont(focusedFontName);
00676 fontProp *downFont = GetFont(downFontName);
00677 fontProp *downFocusedFont = GetFont(downFocusedFontName);
00678
00679 UIKeyType *key = new UIKeyType(name);
00680 key->SetScreen(wmult, hmult);
00681 key->SetParent(container);
00682 key->SetOrder(order.toInt());
00683 key->SetType(type);
00684 key->SetChars(normalChar, shiftChar, altChar, shiftaltChar);
00685 key->SetMoves(moveLeft, moveRight, moveUp, moveDown);
00686 key->SetPosition(pos);
00687 key->SetImages(normalImage, focusedImage, downImage, downFocusedImage);
00688 key->SetFonts(normalFont, focusedFont, downFont, downFocusedFont);
00689
00690 container->AddType(key);
00691 }
00692
00693 void XMLParse::parseKeyboard(LayerSet *container, QDomElement &element)
00694 {
00695 QString normalFontName = "", focusedFontName = "";
00696 QString downFontName = "", downFocusedFontName = "";
00697 int context = -1;
00698 QRect area;
00699 QPixmap *normalImage = NULL, *focusedImage = NULL;
00700 QPixmap *downImage = NULL, *downFocusedImage = NULL;
00701
00702 QString name = element.attribute("name", "");
00703 if (name.isNull() || name.isEmpty())
00704 {
00705 LOG(VB_GENERAL, LOG_WARNING, LOC + "keyboard needs a name");
00706 return;
00707 }
00708
00709 QString order = element.attribute("draworder", "");
00710 if (order.isNull() || order.isEmpty())
00711 {
00712 LOG(VB_GENERAL, LOG_WARNING, LOC + "keyboard needs an order");
00713 return;
00714 }
00715
00716 for (QDomNode child = element.firstChild(); !child.isNull();
00717 child = child.nextSibling())
00718 {
00719 QDomElement e = child.toElement();
00720 if (!e.isNull())
00721 {
00722 if (e.tagName() == "key")
00723 {
00724 parseKey(container, e);
00725 }
00726 else if (e.tagName() == "area")
00727 {
00728 area = parseRect(getFirstText(e));
00729 normalizeRect(area);
00730 }
00731 else if (e.tagName() == "context")
00732 {
00733 context = getFirstText(e).toInt();
00734 }
00735
00736 else if (e.tagName() == "image")
00737 {
00738 QString imgname = "";
00739 QString imgfunction = "";
00740
00741 imgfunction = e.attribute("function", "");
00742 if (imgfunction.isNull() || imgfunction.isEmpty())
00743 {
00744 LOG(VB_GENERAL, LOG_WARNING, LOC +
00745 "Image in a keyboard needs a function");
00746 return;
00747 }
00748
00749 imgname = e.attribute("filename", "");
00750 if (imgname.isNull() || imgname.isEmpty())
00751 {
00752 LOG(VB_GENERAL, LOG_WARNING, LOC +
00753 "Image in a keyboard needs a filename");
00754 return;
00755 }
00756
00757 if (imgfunction.toLower() == "normal")
00758 {
00759 normalImage = ui->LoadScalePixmap(imgname);
00760 if (!normalImage)
00761 {
00762 LOG(VB_GENERAL, LOG_WARNING, LOC +
00763 QString("Can't locate 'normal' image '%1'")
00764 .arg(imgname));
00765 }
00766 }
00767 else if (imgfunction.toLower() == "focused")
00768 {
00769 focusedImage = ui->LoadScalePixmap(imgname);
00770 if (!focusedImage)
00771 {
00772 LOG(VB_GENERAL, LOG_WARNING, LOC +
00773 QString("Can't locate 'focused' image '%1'")
00774 .arg(imgname));
00775 }
00776 }
00777 else if (imgfunction.toLower() == "down")
00778 {
00779 downImage = ui->LoadScalePixmap(imgname);
00780
00781 if (!downImage)
00782 {
00783 LOG(VB_GENERAL, LOG_WARNING, LOC +
00784 QString("Can't locate 'down' image '%1'")
00785 .arg(imgname));
00786 }
00787 }
00788 else if (imgfunction.toLower() == "downfocused")
00789 {
00790 downFocusedImage = ui->LoadScalePixmap(imgname);
00791
00792 if (!downFocusedImage)
00793 {
00794 LOG(VB_GENERAL, LOG_WARNING, LOC +
00795 QString("Can't locate 'downfocused' image '%1'")
00796 .arg(imgname));
00797 }
00798 }
00799 else
00800 {
00801 LOG(VB_GENERAL, LOG_WARNING, LOC +
00802 QString("Unknown image function '%1' in keyboard")
00803 .arg(imgfunction));
00804 return;
00805 }
00806 }
00807 else if (e.tagName() == "fcnfont")
00808 {
00809 QString fontName = e.attribute("name", "");
00810 QString fontFcn = e.attribute("function", "");
00811
00812 if (fontFcn.toLower() == "normal")
00813 normalFontName = fontName;
00814 else if (fontFcn.toLower() == "focused")
00815 focusedFontName = fontName;
00816 else if (fontFcn.toLower() == "down")
00817 downFontName = fontName;
00818 else if (fontFcn.toLower() == "downfocused")
00819 downFocusedFontName = fontName;
00820 else
00821 {
00822 LOG(VB_GENERAL, LOG_WARNING, LOC +
00823 QString("Unknown font function '%1' in keyboard")
00824 .arg(fontFcn));
00825 return;
00826 }
00827 }
00828 else
00829 {
00830 LOG(VB_GENERAL, LOG_WARNING, LOC +
00831 QString("Unknown tag '%1' in keyboard") .arg(e.tagName()));
00832 return;
00833 }
00834 }
00835 }
00836
00837 if (normalFontName.isEmpty())
00838 {
00839 LOG(VB_GENERAL, LOG_WARNING, LOC + "Keyboard need a normal font" );
00840 return;
00841 }
00842
00843 if (focusedFontName.isEmpty())
00844 focusedFontName = normalFontName;
00845
00846 if (downFontName.isEmpty())
00847 downFontName = normalFontName;
00848
00849 if (downFocusedFontName.isEmpty())
00850 downFocusedFontName = normalFontName;
00851
00852 fontProp *normalFont = GetFont(normalFontName);
00853 if (!normalFont)
00854 {
00855 LOG(VB_GENERAL, LOG_WARNING, LOC +
00856 QString("Unknown normal font '%1' in in Keyboard '%2'")
00857 .arg(normalFontName).arg(name));
00858 return;
00859 }
00860
00861 fontProp *focusedFont = GetFont(focusedFontName);
00862 if (!focusedFont)
00863 {
00864 LOG(VB_GENERAL, LOG_WARNING, LOC +
00865 QString("Unknown focused font '%1' in in Keyboard '%2'")
00866 .arg(focusedFontName).arg(name));
00867 return;
00868 }
00869
00870 fontProp *downFont = GetFont(downFontName);
00871 if (!downFont)
00872 {
00873 LOG(VB_GENERAL, LOG_WARNING, LOC +
00874 QString("Unknown down font '%1' in in Keyboard '%2'")
00875 .arg(downFontName).arg(name));
00876 return;
00877 }
00878
00879 fontProp *downFocusedFont = GetFont(downFocusedFontName);
00880 if (!downFocusedFont)
00881 {
00882 LOG(VB_GENERAL, LOG_WARNING, LOC +
00883 QString("Unknown down focus font '%1' in in Keyboard '%2'")
00884 .arg(downFocusedFontName).arg(name));
00885 return;
00886 }
00887
00888 UIKeyboardType *kbd = new UIKeyboardType(name, order.toInt());
00889 kbd->SetScreen(wmult, hmult);
00890 kbd->SetParent(container);
00891 kbd->SetContext(context);
00892 kbd->SetArea(area);
00893 kbd->calculateScreenArea();
00894
00895 container->AddType(kbd);
00896
00897 vector<UIType *>::iterator i = container->getAllTypes()->begin();
00898 for (; i != container->getAllTypes()->end(); ++i)
00899 {
00900 UIType *type = (*i);
00901 if (UIKeyType *keyt = dynamic_cast<UIKeyType*>(type))
00902 {
00903 kbd->AddKey(keyt);
00904 keyt->SetDefaultImages(normalImage, focusedImage, downImage, downFocusedImage);
00905 keyt->SetDefaultFonts(normalFont, focusedFont, downFont, downFocusedFont);
00906 keyt->calculateScreenArea();
00907 }
00908 }
00909 }
00910
00911