bool MythUITextEdit::ParseElement( const QString &filename, QDomElement &element, bool showWarnings) { bool parsed = true; if (element.tagName() == "area") { SetArea(parseRect(element)); } else if (element.tagName() == "keyboardposition") { QString pos = getFirstText(element); if (pos == "aboveedit") m_keyboardPosition = VK_POSABOVEEDIT; else if (pos == "belowedit") m_keyboardPosition = VK_POSBELOWEDIT; else if (pos == "screentop") m_keyboardPosition = VK_POSTOPDIALOG; else if (pos == "screenbottom") m_keyboardPosition = VK_POSBOTTOMDIALOG; else if (pos == "screencenter") m_keyboardPosition = VK_POSCENTERDIALOG; else { VERBOSE_XML(VB_GENERAL, LOG_ERR, filename, element, QString("Unknown popup position '%1'").arg(pos)); m_keyboardPosition = VK_POSBELOWEDIT; } } else { return MythUIType::ParseElement(filename, element, showWarnings); } return parsed; }
bool XMLParseBase::doLoad(const QString &windowname, MythUIType *parent, const QString &filename, bool onlywindows, bool showWarnings) { QDomDocument doc; QFile f(filename); if (!f.open(QIODevice::ReadOnly)) return false; QString errorMsg; int errorLine = 0; int errorColumn = 0; if (!doc.setContent(&f, false, &errorMsg, &errorLine, &errorColumn)) { VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Location: '%1' @ %2 column: %3" "\n\t\t\tError: %4") .arg(qPrintable(filename)).arg(errorLine).arg(errorColumn) .arg(qPrintable(errorMsg))); f.close(); return false; } f.close(); QDomElement docElem = doc.documentElement(); QDomNode n = docElem.firstChild(); while (!n.isNull()) { QDomElement e = n.toElement(); if (!e.isNull()) { if (e.tagName() == "include") { QString include = getFirstText(e); if (!include.isEmpty()) LoadBaseTheme(include); } if (onlywindows && e.tagName() == "window") { QString name = e.attribute("name", ""); if (name.isEmpty()) { VERBOSE_XML(VB_IMPORTANT, filename, e, LOC_ERR + "Window needs a name"); return false; } if (name == windowname) { ParseChildren(filename, e, parent, showWarnings); return true; } } if (!onlywindows) { QString type = e.tagName(); if (type == "font" || type == "fontdef") { bool global = (GetGlobalObjectStore() == parent); MythFontProperties *font = MythFontProperties::ParseFromXml( filename, e, parent, global, showWarnings); if (!global && font) { QString name = e.attribute("name"); parent->AddFont(name, font); } delete font; } else if (type == "imagetype" || type == "textarea" || type == "group" || type == "textedit" || type == "button" || type == "buttonlist" || type == "buttonlist2" || type == "buttontree" || type == "spinbox" || type == "checkbox" || type == "statetype" || type == "window" || type == "clock" || type == "progressbar" || type == "webbrowser" || type == "guidegrid" || type == "shape" || type == "editbar" || type == "video") { ParseUIType(filename, e, type, parent, NULL, showWarnings); } else { VERBOSE_XML(VB_IMPORTANT, filename, e, LOC_ERR + "Unknown widget type"); } } } n = n.nextSibling(); } if (onlywindows) return false; return true; }
MythUIType *XMLParseBase::ParseUIType( const QString &filename, QDomElement &element, const QString &type, MythUIType *parent, MythScreenType *screen, bool showWarnings) { QString name = element.attribute("name", ""); if (name.isEmpty()) { VERBOSE_XML(VB_IMPORTANT, filename, element, LOC_ERR + "This element requires a name"); return NULL; } MythUIType *olduitype = NULL; // check for name in immediate parent as siblings cannot share names if (parent && parent->GetChild(name)) { // if we're the global object store, assume it's just a theme overriding // the defaults.. if (parent == GetGlobalObjectStore()) return NULL; // Reuse the existing child and reparse olduitype = parent->GetChild(name); } MythUIType *uitype = NULL; MythUIType *base = NULL; QString inherits = element.attribute("from", ""); if (!inherits.isEmpty()) { if (parent) base = parent->GetChild(inherits); // might remove this if (screen && !base) base = screen->GetChild(inherits); if (!base) base = GetGlobalObjectStore()->GetChild(inherits); if (!base) { VERBOSE_XML(VB_IMPORTANT, filename, element, LOC_ERR + QString( "Couldn't find object '%1' to inherit '%2' from") .arg(inherits).arg(name)); return NULL; } } if (type == "imagetype") uitype = new MythUIImage(parent, name); else if (type == "textarea") uitype = new MythUIText(parent, name); else if (type == "group") uitype = new MythUIGroup(parent, name); else if (type == "textedit") uitype = new MythUITextEdit(parent, name); else if (type == "button") uitype = new MythUIButton(parent, name); else if (type == "buttonlist2" || type == "buttonlist") uitype = new MythUIButtonList(parent, name); else if (type == "buttontree") uitype = new MythUIButtonTree(parent, name); else if (type == "spinbox") uitype = new MythUISpinBox(parent, name); else if (type == "checkbox") uitype = new MythUICheckBox(parent, name); else if (type == "statetype") uitype = new MythUIStateType(parent, name); else if (type == "clock") uitype = new MythUIClock(parent, name); else if (type == "progressbar") uitype = new MythUIProgressBar(parent, name); else if (type == "webbrowser") uitype = new MythUIWebBrowser(parent, name); else if (type == "guidegrid") uitype = new MythUIGuideGrid(parent, name); else if (type == "shape") uitype = new MythUIShape(parent, name); else if (type == "editbar") uitype = new MythUIEditBar(parent, name); else if (type == "video") uitype = new MythUIVideo(parent, name); else if (type == "window" && parent == GetGlobalObjectStore()) uitype = new MythScreenType(parent, name); else { VERBOSE_XML(VB_IMPORTANT, filename, element, LOC_ERR + "Unknown widget type."); return NULL; } if (!uitype) { VERBOSE_XML(VB_IMPORTANT, filename, element, LOC_ERR + "Failed to instantiate widget type."); return NULL; } if (olduitype) { if (typeid(*olduitype) != typeid(*uitype)) { VERBOSE_XML(VB_IMPORTANT, filename, element, LOC_ERR + QString("Duplicate name: '%1' in parent '%2'") .arg(name).arg(parent->objectName())); parent->DeleteChild(olduitype); } else { parent->DeleteChild(uitype); uitype = olduitype; } } if (base) { if (typeid(*base) != typeid(*uitype)) { VERBOSE_XML(VB_IMPORTANT, filename, element, LOC_ERR + QString("Type of new widget '%1' doesn't " "match old '%2'") .arg(name).arg(inherits)); parent->DeleteChild(uitype); return NULL; } else uitype->CopyFrom(base); } for (QDomNode child = element.firstChild(); !child.isNull(); child = child.nextSibling()) { QDomElement info = child.toElement(); if (!info.isNull()) { if (uitype->ParseElement(filename, info, showWarnings)) { } else if (info.tagName() == "font" || info.tagName() == "fontdef") { bool global = (GetGlobalObjectStore() == parent); MythFontProperties *font = MythFontProperties::ParseFromXml( filename, info, parent, global, showWarnings); if (!global && font) { QString name = info.attribute("name"); uitype->AddFont(name, font); } delete font; } else if (info.tagName() == "imagetype" || info.tagName() == "textarea" || info.tagName() == "group" || info.tagName() == "textedit" || info.tagName() == "button" || info.tagName() == "buttonlist" || info.tagName() == "buttonlist2" || info.tagName() == "buttontree" || info.tagName() == "spinbox" || info.tagName() == "checkbox" || info.tagName() == "statetype" || info.tagName() == "clock" || info.tagName() == "progressbar" || info.tagName() == "webbrowser" || info.tagName() == "guidegrid" || info.tagName() == "shape" || info.tagName() == "editbar" || info.tagName() == "video") { ParseUIType(filename, info, info.tagName(), uitype, screen, showWarnings); } else { VERBOSE_XML(VB_IMPORTANT, filename, info, LOC_ERR + "Unknown widget type."); } } } uitype->Finalize(); return uitype; }
void XMLParseBase::ParseChildren(const QString &filename, QDomElement &element, MythUIType *parent, bool showWarnings) { if (!parent) { VERBOSE(VB_IMPORTANT, "Parent is NULL"); return; } for (QDomNode child = element.firstChild(); !child.isNull(); child = child.nextSibling()) { QDomElement info = child.toElement(); if (!info.isNull()) { QString type = info.tagName(); if (parent->ParseElement(filename, info, showWarnings)) { } else if (type == "font" || type == "fontdef") { bool global = (GetGlobalObjectStore() == parent); MythFontProperties *font = MythFontProperties::ParseFromXml( filename, info, parent, global, showWarnings); if (!global && font) { QString name = info.attribute("name"); parent->AddFont(name, font); } delete font; } else if (type == "imagetype" || type == "textarea" || type == "group" || type == "textedit" || type == "button" || type == "buttonlist" || type == "buttonlist2" || type == "buttontree" || type == "spinbox" || type == "checkbox" || type == "statetype" || type == "clock" || type == "progressbar" || type == "webbrowser" || type == "guidegrid" || type == "shape" || type == "editbar" || type == "video") { ParseUIType(filename, info, type, parent, NULL, showWarnings); } else { VERBOSE_XML(VB_IMPORTANT, filename, info, LOC_ERR + "Unknown widget type"); } } } }
MythFontProperties *MythFontProperties::ParseFromXml( const QString &filename, const QDomElement &element, MythUIType *parent, bool addToGlobal, bool showWarnings) { // Crappy, but cached. Move to GlobalFontMap? static bool show_available = true; bool fromBase = false; MythFontProperties *newFont = new MythFontProperties(); newFont->Freeze(); if (element.tagName() == "font") LOG(VB_GENERAL, LOG_WARNING, LOC + QString("File %1: Use of 'font' is deprecated in favour of " "'fontdef'") .arg(filename)); QString name = element.attribute("name", ""); if (name.isEmpty()) { VERBOSE_XML(VB_GENERAL, LOG_ERR, filename, element, "Font requires a name"); delete newFont; return NULL; } QString base = element.attribute("from", ""); if (!base.isEmpty()) { MythFontProperties *tmp = NULL; if (parent) tmp = parent->GetFont(base); if (!tmp) tmp = GetGlobalFontMap()->GetFont(base); if (!tmp) { VERBOSE_XML(VB_GENERAL, LOG_ERR, filename, element, QString("Specified base font '%1' does not exist.").arg(base)); delete newFont; return NULL; } *newFont = *tmp; fromBase = true; } int size, pixelsize; size = pixelsize = -1; QString face = element.attribute("face", ""); if (face.isEmpty()) { if (!fromBase) { VERBOSE_XML(VB_GENERAL, LOG_ERR, filename, element, "Font needs a face"); delete newFont; return NULL; } } else { newFont->m_face.setFamily(face); } if (addToGlobal && GetGlobalFontMap()->Contains(name)) { MythFontProperties *tmp = GetGlobalFontMap()->GetFont(name); if (showWarnings) { VERBOSE_XML(VB_GENERAL, LOG_WARNING, filename, element, QString("Attempting to define '%1'\n\t\t\t" "with face '%2', but it already " "exists with face '%3'") .arg(name).arg(QFontInfo(newFont->m_face).family()) .arg((tmp) ? QFontInfo(tmp->m_face).family() : "ERROR")); } delete newFont; return NULL; } QString hint = element.attribute("stylehint", ""); if (!hint.isEmpty()) { newFont->m_face.setStyleHint((QFont::StyleHint)hint.toInt()); } for (QDomNode child = element.firstChild(); !child.isNull(); child = child.nextSibling()) { QDomElement info = child.toElement(); if (!info.isNull()) { if (info.tagName() == "size") { size = getFirstText(info).toInt(); } else if (info.tagName() == "pixelsize") { pixelsize = getFirstText(info).toInt(); } else if (info.tagName() == "color") { newFont->m_brush = QBrush(QColor(getFirstText(info))); } else if (info.tagName() == "gradient") { newFont->m_brush = parseGradient(info); } else if (info.tagName() == "shadowcolor") { newFont->m_shadowColor = QColor(getFirstText(info)); } else if (info.tagName() == "shadowoffset") { newFont->m_hasShadow = true; newFont->m_shadowOffset = parsePoint(info, false); } else if (info.tagName() == "shadowalpha") { newFont->m_shadowAlpha = getFirstText(info).toInt(); } else if (info.tagName() == "outlinecolor") { newFont->m_outlineColor = QColor(getFirstText(info)); } else if (info.tagName() == "outlinesize") { newFont->m_hasOutline = true; newFont->m_outlineSize = getFirstText(info).toInt(); } else if (info.tagName() == "outlinealpha") { newFont->m_outlineAlpha = getFirstText(info).toInt(); } else if (info.tagName() == "italics") { newFont->m_face.setItalic(parseBool(info)); } else if (info.tagName() == "letterspacing") { newFont->m_face.setLetterSpacing(QFont::AbsoluteSpacing, getFirstText(info).toInt()); } else if (info.tagName() == "wordspacing") { newFont->m_face.setWordSpacing(getFirstText(info).toInt()); } else if (info.tagName() == "decoration") { QString dec = getFirstText(info).toLower(); QStringList values = dec.split(','); QStringList::Iterator it; for ( it = values.begin(); it != values.end(); ++it ) { if (*it == "underline") newFont->m_face.setUnderline(true); else if (*it == "overline") newFont->m_face.setOverline(true); else if (*it == "strikeout") newFont->m_face.setStrikeOut(true); } } else if (info.tagName() == "weight") { QString weight = getFirstText(info).toLower(); if (weight == "ultralight" || weight == "1") newFont->m_face.setWeight(1); else if (weight == "light" || weight == "2") newFont->m_face.setWeight(QFont::Light); else if (weight == "normal" || weight == "3") newFont->m_face.setWeight(QFont::Normal); else if (weight == "demibold" || weight == "4") newFont->m_face.setWeight(QFont::DemiBold); else if (weight == "bold" || weight == "5") newFont->m_face.setWeight(QFont::Bold); else if (weight == "black" || weight == "6") newFont->m_face.setWeight(QFont::Black); else if (weight == "ultrablack" || weight == "7") newFont->m_face.setWeight(99); else newFont->m_face.setWeight(QFont::Normal); } else if (info.tagName() == "stretch") { QString stretch = getFirstText(info).toLower(); if (stretch == "ultracondensed" || stretch == "1") newFont->m_stretch = QFont::UltraCondensed; else if (stretch == "extracondensed" || stretch == "2") newFont->m_stretch = QFont::ExtraCondensed; else if (stretch == "condensed" || stretch == "3") newFont->m_stretch = QFont::Condensed; else if (stretch == "semicondensed" || stretch == "4") newFont->m_stretch = QFont::SemiCondensed; else if (stretch == "unstretched" || stretch == "5") newFont->m_stretch = QFont::Unstretched; else if (stretch == "semiexpanded" || stretch == "6") newFont->m_stretch = QFont::SemiExpanded; else if (stretch == "expanded" || stretch == "7") newFont->m_stretch = QFont::Expanded; else if (stretch == "extraexpanded" || stretch == "8") newFont->m_stretch = QFont::ExtraExpanded; else if (stretch == "ultraexpanded" || stretch == "9") newFont->m_stretch = QFont::UltraExpanded; else newFont->m_stretch = QFont::Unstretched; newFont->m_face.setStretch(newFont->m_stretch); } else { VERBOSE_XML(VB_GENERAL, LOG_ERR, filename, info, QString("Unknown tag in font '%1'").arg(name)); delete newFont; return NULL; } } } if (size <= 0 && pixelsize <= 0 && !fromBase) { VERBOSE_XML(VB_GENERAL, LOG_ERR, filename, element, "Font size must be greater than 0."); delete newFont; return NULL; } else if (pixelsize > 0) { newFont->SetPixelSize(pixelsize); } else if (size > 0) { newFont->SetPointSize(size); } newFont->Unfreeze(); QFontInfo fi(newFont->m_face); if (newFont->m_face.family() != fi.family()) { VERBOSE_XML(VB_GENERAL, LOG_ERR, filename, element, QString("Failed to load '%1', got '%2' instead") .arg(newFont->m_face.family()).arg(fi.family())); if (show_available) { LOG(VB_GUI, LOG_DEBUG, "Available fonts:"); QFontDatabase database; foreach (const QString &family, database.families()) { QStringList family_styles; family_styles << family + "::"; foreach (const QString &style, database.styles(family)) { family_styles << style + ":"; QString sizes; bool tic = false; foreach (int points, database.smoothSizes(family, style)) { if (tic) sizes += ","; tic = true; sizes += QString::number(points); } sizes += "; "; family_styles << sizes.trimmed(); } LOG(VB_GUI, LOG_DEBUG, family_styles.join(" ")); } show_available = false; } }
bool ThemeInfo::parseThemeInfo() { QDomDocument doc; if ((m_themeurl.startsWith("http://")) || (m_themeurl.startsWith("https://")) || (m_themeurl.startsWith("ftp://"))) { QByteArray data; bool ok = GetMythDownloadManager()->download(m_themeurl + "/themeinfo.xml", &data); if (!ok) return false; if (!doc.setContent(data)) { VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Unable to parse themeinfo.xml " "for %1").arg(m_themeurl)); return false; } } else { QFile f(m_themeurl + "/themeinfo.xml"); if (!f.open(QIODevice::ReadOnly)) { VERBOSE(VB_IMPORTANT, LOC_WARN + QString("Unable to open themeinfo.xml " "for %1").arg(f.fileName())); return false; } if (!doc.setContent(&f)) { VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Unable to parse themeinfo.xml " "for %1").arg(f.fileName())); f.close(); return false; } f.close(); } QDomElement docElem = doc.documentElement(); for (QDomNode n = docElem.firstChild(); !n.isNull(); n = n.nextSibling()) { QDomElement e = n.toElement(); if (!e.isNull()) { if (e.tagName() == "name") { m_name = getFirstText(e); } else if (e.tagName() == "aspect") { m_aspect = getFirstText(e); } else if (e.tagName() == "baseres") { QString size = getFirstText(e); m_baseres = QSize(size.section('x', 0, 0).toInt(), size.section('x', 1, 1).toInt()); } else if (e.tagName() == "types") { for (QDomNode child = e.firstChild(); !child.isNull(); child = child.nextSibling()) { QDomElement ce = child.toElement(); if (!ce.isNull()) { if (ce.tagName() == "type") { QString type = getFirstText(ce); if (type == "UI") { m_type |= THEME_UI; } else if (type == "OSD") { m_type |= THEME_OSD; } else if (type == "Menu") { m_type |= THEME_MENU; } else { VERBOSE_XML(VB_IMPORTANT, m_theme.fileName(), ce, LOC_ERR + "Invalid theme type"); } } } } } else if (e.tagName() == "version") { for (QDomNode child = e.firstChild(); !child.isNull(); child = child.nextSibling()) { QDomElement ce = child.toElement(); if (!ce.isNull()) { if (ce.tagName() == "major") { m_majorver = getFirstText(ce).toInt(); } else if (ce.tagName() == "minor") { m_minorver = getFirstText(ce).toInt(); } } } } else if (e.tagName() == "author") { for (QDomNode child = e.firstChild(); !child.isNull(); child = child.nextSibling()) { QDomElement ce = child.toElement(); if (!ce.isNull()) { if (ce.tagName() == "name") { m_authorName = getFirstText(ce); } else if (ce.tagName() == "email") { m_authorEmail = getFirstText(ce); } } } } else if (e.tagName() == "detail") { for (QDomNode child = e.firstChild(); !child.isNull(); child = child.nextSibling()) { QDomElement ce = child.toElement(); if (!ce.isNull()) { if (ce.tagName() == "thumbnail") { if (ce.attribute("name") == "preview") { QString thumbnail = getFirstText(ce); m_previewpath = m_themeurl + '/' + thumbnail; } } else if (ce.tagName() == "description") { m_description = qApp->translate("ThemeUI", parseText(ce).toUtf8(), NULL, QCoreApplication::UnicodeUTF8); } else if (ce.tagName() == "errata") { m_errata = qApp->translate("ThemeUI", parseText(ce).toUtf8(), NULL, QCoreApplication::UnicodeUTF8); } else if (ce.tagName() == "downloadurl") { m_downloadurl = getFirstText(ce); } else if (ce.tagName() == "themesite") { m_themesite = getFirstText(ce); } } } } } } return true; }