00001 #include <QNetworkInterface>
00002 #include <QDomDocument>
00003 #include <QFile>
00004
00005 #include "channelsettings.h"
00006 #include "mythsettings.h"
00007 #include "frequencies.h"
00008 #include "mythcontext.h"
00009 #include "mythdb.h"
00010
00011 MythSetting::SettingType parse_setting_type(const QString &str);
00012 MythSetting::DataType parse_data_type(const QString &str);
00013 bool parse_dom(MythSettingList &settings, const QDomElement &element,
00014 const QString &filename, const QString &group,
00015 bool includeAllChildren, bool &foundGroup);
00016
00017 static QString indent(uint level)
00018 {
00019 QString ret;
00020 for (uint i = 0; i < level; i++)
00021 ret += " ";
00022 return ret;
00023 }
00024
00025 static QString extract_query_list(
00026 const MythSettingList &settings, MythSetting::SettingType stype)
00027 {
00028 QString list;
00029
00030 MythSettingList::const_iterator it = settings.begin();
00031 for (; it != settings.end(); ++it)
00032 {
00033 const MythSettingGroup *group =
00034 dynamic_cast<const MythSettingGroup*>(*it);
00035 if (group)
00036 {
00037 list += extract_query_list(group->settings, stype);
00038 continue;
00039 }
00040 const MythSetting *setting = dynamic_cast<const MythSetting*>(*it);
00041 if (setting && (setting->stype == stype))
00042 list += QString(",'%1'").arg(setting->value);
00043 }
00044 if (!list.isEmpty() && (list[0] == QChar(',')))
00045 list = list.mid(1);
00046
00047 return list;
00048 }
00049
00050 static void fill_setting(
00051 MythSettingBase *sb, const QMap<QString,QString> &map,
00052 MythSetting::SettingType stype)
00053 {
00054 const MythSettingGroup *group =
00055 dynamic_cast<const MythSettingGroup*>(sb);
00056 if (group)
00057 {
00058 MythSettingList::const_iterator it = group->settings.begin();
00059 for (; it != group->settings.end(); ++it)
00060 fill_setting(*it, map, stype);
00061 return;
00062 }
00063
00064 MythSetting *setting = dynamic_cast<MythSetting*>(sb);
00065 if (setting && (setting->stype == stype))
00066 {
00067 QMap<QString,QString>::const_iterator it = map.find(setting->value);
00068 if (it != map.end())
00069 setting->data = *it;
00070
00071 bool do_option_check = false;
00072 if (MythSetting::kLocalIPAddress == setting->dtype)
00073 {
00074 setting->data_list = GetSettingValueList("LocalIPAddress");
00075 setting->display_list = setting->data_list;
00076 do_option_check = true;
00077 }
00078 else if (MythSetting::kSelect == setting->dtype)
00079 {
00080 do_option_check = true;
00081 }
00082 else if (MythSetting::kTVFormat == setting->dtype)
00083 {
00084 setting->data_list = setting->display_list =
00085 ChannelTVFormat::GetFormats();
00086 do_option_check = true;
00087 }
00088 else if (MythSetting::kFrequencyTable == setting->dtype)
00089 {
00090 setting->data_list.clear();
00091 for (uint i = 0; chanlists[i].name; i++)
00092 setting->data_list.push_back(chanlists[i].name);
00093 setting->display_list = setting->data_list;
00094 do_option_check = true;
00095 }
00096
00097 if (do_option_check)
00098 {
00099 if (!setting->data_list.empty() &&
00100 !setting->data_list.contains(setting->data.toLower(),
00101 Qt::CaseInsensitive))
00102 {
00103 bool ok;
00104 long long idata = setting->data.toLongLong(&ok);
00105 if (ok)
00106 {
00107 uint sel = 0;
00108 for (int i = setting->data_list.size() - 1; i >= 0; i--)
00109 {
00110 if (idata < setting->data_list[i].toLongLong())
00111 break;
00112 sel = i;
00113 }
00114 setting->data = setting->data_list[sel];
00115 }
00116 else
00117 {
00118 setting->data =
00119 (setting->data_list.contains(
00120 setting->default_data, Qt::CaseInsensitive)) ?
00121 setting->default_data : setting->data_list[0];
00122 }
00123 }
00124 }
00125 }
00126 }
00127
00128 static void fill_settings(
00129 MythSettingList &settings, MSqlQuery &query, MythSetting::SettingType stype)
00130 {
00131 QMap<QString,QString> map;
00132 while (query.next())
00133 map[query.value(0).toString()] = query.value(1).toString();
00134
00135 MythSettingList::const_iterator it = settings.begin();
00136 for (; it != settings.end(); ++it)
00137 fill_setting(*it, map, stype);
00138 }
00139
00140 QString MythSettingGroup::ToHTML(uint depth) const
00141 {
00142 QString ret;
00143
00144 ret = indent(depth) +
00145 QString("<div class=\"group\" id=\"%1\">\r\n").arg(unique_label);
00146 if (!human_label.isEmpty())
00147 {
00148 ret += indent(depth+1) + QString("<h%1 class=\"config\">%2</h%3>\r\n")
00149 .arg(depth+1).arg(human_label).arg(depth+1);
00150 }
00151
00152 MythSettingList::const_iterator it = settings.begin();
00153 for (; it != settings.end(); ++it)
00154 ret += (*it)->ToHTML(depth+1);
00155
00156 ret += indent(depth) +"</div>";
00157
00158 return ret;
00159 }
00160
00161 QString MythSetting::ToHTML(uint level) const
00162 {
00163 QString ret = indent(level) +
00164 QString("<div class=\"setting\" id=\"%1_div\">\r\n").arg(value);
00165
00166 int size = 20;
00167 switch (dtype)
00168 {
00169 case kFloat:
00170 case kInteger:
00171 case kIntegerRange:
00172 case kUnsignedInteger:
00173 size = 20;
00174 break;
00175 case kTimeOfDay:
00176 size = 20;
00177 break;
00178 case kString:
00179 size = 60;
00180 break;
00181 case kIPAddress:
00182 size = 20;
00183 break;
00184 }
00185
00186 switch (dtype)
00187 {
00188 case kInteger:
00189 case kUnsignedInteger:
00190 ret += indent(level) +
00191 QString("<p class=\"setting_paragraph\"><label class=\"setting_label\" "
00192 "for=\"%1\">%2</label>")
00193 .arg(value).arg(label);
00194 ret += indent(level) +
00195 QString("<input class=\"setting_input\" name=\"%1\" id=\"%2\" type=\"number\""
00196 " value='%3' step='1' size='%4'/>\r\n")
00197 .arg(value).arg(value).arg(data).arg(size);
00198 ret += indent(level) +
00199 QString("<a class=\"setting_helplink\" href=\"javascript:showSettingHelp('%1')"
00200 "\">[?]</a></label></p>\r\n").arg(value);
00201 ret += indent(level) +
00202 QString("<div class=\"form_error\""
00203 "id=\"%1_error\"></div><div style=\"display:none;"
00204 "position:absolute;left:-4000px\" "
00205 "id=\"%2_default\">%3</div>\r\n")
00206 .arg(value).arg(value).arg(default_data);
00207 break;
00208 case kIntegerRange:
00209 ret += indent(level) +
00210 QString("<p class=\"setting_paragraph\"><label class=\"setting_label\" "
00211 "for=\"%1\">%2</label>")
00212 .arg(value).arg(label);
00213 ret += indent(level) +
00214 QString("<input class=\"setting_input\" name=\"%1\" id=\"%2\" type=\"number\""
00215 " value='%3' min='%4' max='%5' step='1' size='%6'/>\r\n")
00216 .arg(value).arg(value).arg(data).arg(range_min).arg(range_max).arg(size);
00217 ret += indent(level) +
00218 QString("<a class=\"setting_helplink\" href=\"javascript:showSettingHelp('%1')"
00219 "\">[?]</a></label></p>\r\n").arg(value);
00220 ret += indent(level) +
00221 QString("<div class=\"form_error\""
00222 "id=\"%1_error\"></div><div style=\"display:none;"
00223 "position:absolute;left:-4000px\" "
00224 "id=\"%2_default\">%3</div>\r\n")
00225 .arg(value).arg(value).arg(default_data);
00226 break;
00227 case kFloat:
00228 case kComboBox:
00229 case kIPAddress:
00230 case kString:
00231 case kTimeOfDay:
00232 case kOther:
00233 ret += indent(level) +
00234 QString("<p class=\"setting_paragraph\"><label class=\"setting_label\" "
00235 "for=\"%1\">%2</label>")
00236 .arg(value).arg(label);
00237 ret += indent(level) +
00238 QString("<input class=\"setting_input\" name=\"%1\" id=\"%2\" type=\"text\""
00239 " value=\"%3\" size='%4' placeholder=\"%5\"/>\r\n")
00240 .arg(value).arg(value).arg(data).arg(size).arg(placeholder_text);
00241 ret += indent(level) +
00242 QString("<a class=\"setting_helplink\" href=\"javascript:showSettingHelp('%1')"
00243 "\">[?]</a></label></p>\r\n").arg(value);
00244 ret += indent(level) +
00245 QString("<div class=\"form_error\""
00246 "id=\"%1_error\"></div><div style=\"display:none;"
00247 "position:absolute;left:-4000px\" "
00248 "id=\"%2_default\">%3</div>\r\n")
00249 .arg(value).arg(value).arg(default_data);
00250 break;
00251 case kCheckBox:
00252 ret += indent(level) +
00253 QString("<p class=\"setting_paragraph\">"
00254 "<input class=\"setting_input\" name=\"%1_input\" id=\"%2\" type=\"checkbox\""
00255 " value=\"1\" %3/><label class=\"setting_label_checkbox\" for=\"%5\">%6</label>")
00256 .arg(value).arg(value).arg((data.toUInt()) ? "checked" : "").arg(value).arg(label);
00257 ret += indent(level) +
00258 QString("<a class=\"setting_helplink\" href=\"javascript:showSettingHelp('%1'"
00259 ")\">[?]</a></p><div class=\"form_error\""
00260 " id=\"%2_error\"></div>").arg(value).arg(value);
00261 ret += indent(level) +
00262 QString("<div style=\"display:none;"
00263 "position:absolute;left:-4000px\" "
00264 "id=\"%1_default\">%2</div>")
00265 .arg(value).arg(default_data);
00266 break;
00267 case kLocalIPAddress:
00268 case kTVFormat:
00269 case kFrequencyTable:
00270 case kSelect:
00271 ret += indent(level) +
00272 QString("<p class=\"setting_paragraph\"><label class=\"setting_label\" "
00273 "for=\"%1\">%2</label>")
00274 .arg(value).arg(label);
00275 ret += indent(level) +
00276 QString("<select class=\"setting_select\" name=\"%1_input\" id=\"%2\">\r\n")
00277 .arg(value).arg(value);
00278 for (uint i = 0; (i < (uint)data_list.size()) &&
00279 (i < (uint)display_list.size()); i++)
00280 {
00281 ret += indent(level+1) +
00282 QString("<option value=\"%1\" %2>%3</option>\r\n")
00283 .arg(data_list[i])
00284 .arg((data_list[i].toLower() == data.toLower()) ?
00285 "selected" : "")
00286 .arg(display_list[i]);
00287 }
00288 ret += indent(level) + "</select>" +
00289 QString("<a class=\"setting_helplink\" href=\"javascript:showSettingHelp('%1')"
00290 "\">[?]</a></p>\r\n").arg(value);
00291 ret += indent(level) +
00292 QString("<div class=\"form_error\""
00293 "id=\"%1_error\"></div><div style=\"display:none;"
00294 "position:absolute;left:-4000px\" "
00295 "id=\"%2_default\">%3</div>\r\n")
00296 .arg(value).arg(value).arg(default_data);
00297 break;
00298 }
00299
00300 ret += indent(level) + "</div>\r\n";
00301
00302 return ret;
00303 }
00304
00305 MythSetting::SettingType parse_setting_type(const QString &str)
00306 {
00307 QString s = str.toLower();
00308 if (s=="file")
00309 return MythSetting::kFile;
00310 if (s=="host")
00311 return MythSetting::kHost;
00312 if (s=="global")
00313 return MythSetting::kGlobal;
00314 return MythSetting::kInvalidSettingType;
00315 }
00316
00317 MythSetting::DataType parse_data_type(const QString &str)
00318 {
00319 QString s = str.toLower();
00320 if (s == "integer")
00321 return MythSetting::kInteger;
00322 if (s == "unsigned")
00323 return MythSetting::kUnsignedInteger;
00324 if (s == "integer_range")
00325 return MythSetting::kIntegerRange;
00326 if (s == "checkbox")
00327 return MythSetting::kCheckBox;
00328 if (s == "select")
00329 return MythSetting::kSelect;
00330 if (s == "combobox")
00331 return MythSetting::kComboBox;
00332 if (s == "tvformat")
00333 return MythSetting::kTVFormat;
00334 if (s == "frequency_table")
00335 return MythSetting::kFrequencyTable;
00336 if (s == "float")
00337 return MythSetting::kFloat;
00338 if (s == "ipaddress")
00339 return MythSetting::kIPAddress;
00340 if (s == "localipaddress")
00341 return MythSetting::kLocalIPAddress;
00342 if (s == "string")
00343 return MythSetting::kString;
00344 if (s == "timeofday")
00345 return MythSetting::kTimeOfDay;
00346 if (s == "other")
00347 return MythSetting::kOther;
00348 LOG(VB_GENERAL, LOG_ERR, QString("Unknown type: %1").arg(str));
00349 return MythSetting::kInvalidDataType;
00350 }
00351
00352 QMap<QString,QString> GetSettingsMap(MythSettingList &settings,
00353 const QString &hostname)
00354 {
00355 QMap<QString,QString> result;
00356 MSqlQuery query(MSqlQuery::InitCon());
00357
00358 QString list = extract_query_list(settings, MythSetting::kHost);
00359 QString qstr =
00360 "SELECT value, data "
00361 "FROM settings "
00362 "WHERE hostname = '" + hostname + "' AND "
00363 " value in (" + list + ")";
00364
00365 if (!list.isEmpty())
00366 {
00367 if (!query.exec(qstr))
00368 {
00369 MythDB::DBError("GetSettingsMap() 1", query);
00370 return result;
00371 }
00372
00373 while (query.next())
00374 result[query.value(0).toString()] = query.value(1).toString();
00375 }
00376
00377 list = extract_query_list(settings, MythSetting::kGlobal);
00378 qstr =
00379 "SELECT value, data "
00380 "FROM settings "
00381 "WHERE hostname IS NULL AND "
00382 " value in (" + list + ")";
00383
00384 if (!list.isEmpty())
00385 {
00386 if (!query.exec(qstr))
00387 {
00388 MythDB::DBError("GetSettingsMap() 2", query);
00389 return result;
00390 }
00391
00392 while (query.next())
00393 result[query.value(0).toString()] = query.value(1).toString();
00394 }
00395
00396 return result;
00397 }
00398
00399 QStringList GetSettingValueList(const QString &type)
00400 {
00401 QStringList sList;
00402
00403 if (type == "LocalIPAddress")
00404 {
00405 QList<QHostAddress> list = QNetworkInterface::allAddresses();
00406 for (uint i = 0; i < (uint)list.size(); i++)
00407 {
00408 if (list[i].toString().contains(":"))
00409 continue;
00410 sList << list[i].toString();
00411 }
00412
00413 if (sList.isEmpty())
00414 sList << "127.0.0.1";
00415 }
00416
00417 return sList;
00418 }
00419
00420 QString StringMapToJSON(const QMap<QString,QString> &map)
00421 {
00422 QString result;
00423
00424 QMap<QString,QString>::const_iterator it = map.begin();
00425 for (; it != map.end(); ++it)
00426 {
00427 if (result.isEmpty())
00428 result += "{ ";
00429 else
00430 result += ", ";
00431
00432
00433 result += "\"" + it.key() + "\": \"" + it.value() + "\"";
00434 }
00435
00436 if (!result.isEmpty())
00437 result += " }";
00438 else
00439 result = "{ }";
00440
00441 return result;
00442 }
00443
00444 QString StringListToJSON(const QString &key,
00445 const QStringList &sList)
00446 {
00447 QString result;
00448
00449 QStringList::const_iterator it = sList.begin();
00450 for (; it != sList.end(); ++it)
00451 {
00452 if (result.isEmpty())
00453 result += QString("{ \"%1\" : [ ").arg(key);
00454 else
00455 result += ", ";
00456
00457
00458 result += "\"" + *it + "\"";
00459 }
00460
00461 if (!result.isEmpty())
00462 result += " ] }";
00463 else
00464 result = "{ }";
00465
00466 return result;
00467 }
00468
00469 bool parse_dom(MythSettingList &settings, const QDomElement &element,
00470 const QString &filename, const QString &group,
00471 bool includeAllChildren, bool &foundGroup)
00472 {
00473 #define LOC QString("parse_dom(%1@~%2), error: ") \
00474 .arg(filename).arg(e.lineNumber())
00475
00476 bool mFoundGroup = false;
00477
00478 QDomNode n = element.firstChild();
00479 while (!n.isNull())
00480 {
00481 const QDomElement e = n.toElement();
00482 if (e.isNull())
00483 {
00484 n = n.nextSibling();
00485 continue;
00486 }
00487
00488 if (e.tagName() == "group")
00489 {
00490 QString human_label = e.attribute("human_label");
00491 QString unique_label = e.attribute("unique_label");
00492 QString ecma_script = e.attribute("ecma_script");
00493
00494 bool tmpFoundGroup = false;
00495 bool tmpIncludeAllChildren = false || includeAllChildren;
00496 if (group.isEmpty() || unique_label == group)
00497 {
00498 mFoundGroup = true;
00499 tmpIncludeAllChildren = true;
00500 }
00501
00502 MythSettingGroup *g = new MythSettingGroup(
00503 human_label, unique_label, ecma_script);
00504
00505 if ((e.hasChildNodes()) &&
00506 (!parse_dom(g->settings, e, filename, group, tmpIncludeAllChildren,
00507 tmpFoundGroup)))
00508 return false;
00509
00510 if (tmpFoundGroup || tmpIncludeAllChildren)
00511 {
00512 settings.push_back(g);
00513 mFoundGroup = true;
00514 }
00515 else
00516 delete g;
00517
00518 }
00519 else if (e.tagName() == "setting" && includeAllChildren)
00520 {
00521 QMap<QString,QString> m;
00522 m["value"] = e.attribute("value");
00523 m["setting_type"] = e.attribute("setting_type");
00524 m["label"] = e.attribute("label");
00525 m["help_text"] = e.attribute("help_text");
00526 m["data_type"] = e.attribute("data_type");
00527
00528 MythSetting::DataType dtype = parse_data_type(m["data_type"]);
00529 if (MythSetting::kInvalidDataType == dtype)
00530 {
00531 LOG(VB_GENERAL, LOG_ERR, LOC +
00532 "Setting has invalid or missing data_type attribute.");
00533 return false;
00534 }
00535
00536 QStringList data_list;
00537 QStringList display_list;
00538 if ((MythSetting::kComboBox == dtype) ||
00539 (MythSetting::kSelect == dtype))
00540 {
00541 if (!e.hasChildNodes())
00542 {
00543 LOG(VB_GENERAL, LOG_ERR, LOC +
00544 "Setting missing selection items.");
00545 return false;
00546 }
00547
00548 QDomNode n2 = e.firstChild();
00549 while (!n2.isNull())
00550 {
00551 const QDomElement e2 = n2.toElement();
00552 if (e2.tagName() != "option")
00553 {
00554 LOG(VB_GENERAL, LOG_ERR, LOC +
00555 "Setting selection contains invalid tags.");
00556 return false;
00557 }
00558 QString display = e2.attribute("display");
00559 QString data = e2.attribute("data");
00560 if (data.isEmpty())
00561 {
00562 LOG(VB_GENERAL, LOG_ERR, LOC +
00563 "Setting selection item missing data.");
00564 return false;
00565 }
00566 display = (display.isEmpty()) ? data : display;
00567 data_list.push_back(data);
00568 display_list.push_back(display);
00569
00570 n2 = n2.nextSibling();
00571 }
00572 }
00573
00574 if (MythSetting::kIntegerRange == dtype)
00575 {
00576 m["range_min"] = e.attribute("range_min");
00577 m["range_max"] = e.attribute("range_max");
00578 }
00579
00580 QMap<QString,QString>::const_iterator it = m.begin();
00581 for (; it != m.end(); ++it)
00582 {
00583 if ((*it).isEmpty())
00584 {
00585 LOG(VB_GENERAL, LOG_ERR, LOC +
00586 QString("Setting has invalid or missing %1 attribute")
00587 .arg(it.key()));
00588 return false;
00589 }
00590 }
00591
00592 m["default_data"] = e.attribute("default_data");
00593 m["placeholder_text"] = e.attribute("placeholder_text");
00594
00595 MythSetting::SettingType stype =
00596 parse_setting_type(m["setting_type"]);
00597 if (MythSetting::kInvalidSettingType == stype)
00598 {
00599 LOG(VB_GENERAL, LOG_ERR, LOC +
00600 "Setting has invalid setting_type attribute.");
00601 return false;
00602 }
00603
00604 long long range_min = m["range_min"].toLongLong();
00605 long long range_max = m["range_max"].toLongLong();
00606 if (range_max < range_min)
00607 {
00608 LOG(VB_GENERAL, LOG_ERR, LOC +
00609 "Setting has invalid range attributes");
00610 return false;
00611 }
00612
00613 MythSetting *s = new MythSetting(
00614 m["value"], m["default_data"], stype,
00615 m["label"], m["help_text"], dtype,
00616 data_list, display_list, range_min, range_max,
00617 m["placeholder_text"]);
00618
00619 settings.push_back(s);
00620 }
00621 else if (group.isEmpty())
00622 {
00623 LOG(VB_GENERAL, LOG_ERR, LOC +
00624 QString("Unknown element: %1").arg(e.tagName()));
00625 return false;
00626 }
00627 n = n.nextSibling();
00628 }
00629
00630 if (mFoundGroup)
00631 foundGroup = true;
00632
00633 return true;
00634 #undef LOC
00635 }
00636
00637 bool parse_settings(MythSettingList &settings, const QString &filename,
00638 const QString &group)
00639 {
00640 QDomDocument doc;
00641 QFile f(filename);
00642
00643 if (!f.open(QIODevice::ReadOnly))
00644 {
00645 LOG(VB_GENERAL, LOG_ERR, QString("parse_settings: Can't open: '%1'")
00646 .arg(filename));
00647 return false;
00648 }
00649
00650 QString errorMsg;
00651 int errorLine = 0;
00652 int errorColumn = 0;
00653
00654 if (!doc.setContent(&f, false, &errorMsg, &errorLine, &errorColumn))
00655 {
00656 LOG(VB_GENERAL, LOG_ERR, QString("parse_settings: ") +
00657 QString("Parsing: %1 at line: %2 column: %3")
00658 .arg(filename).arg(errorLine).arg(errorColumn) +
00659 QString("\n\t\t\t%1").arg(errorMsg));
00660 f.close();
00661 return false;
00662 }
00663 f.close();
00664
00665 settings.clear();
00666 bool foundGroup = false;
00667 bool includeAllChildren = group.isEmpty();
00668 return parse_dom(settings, doc.documentElement(), filename, group,
00669 includeAllChildren, foundGroup);
00670 }
00671
00672 bool load_settings(MythSettingList &settings, const QString &hostname)
00673 {
00674 MSqlQuery query(MSqlQuery::InitCon());
00675
00676 QString list = extract_query_list(settings, MythSetting::kHost);
00677 QString qstr =
00678 "SELECT value, data "
00679 "FROM settings "
00680 "WHERE hostname = '" + hostname + "' AND "
00681 " value in (" + list + ")";
00682
00683 if (!list.isEmpty())
00684 {
00685 if (!query.exec(qstr))
00686 {
00687 MythDB::DBError("HttpConfig::LoadMythSettings() 1", query);
00688 return false;
00689 }
00690 fill_settings(settings, query, MythSetting::kHost);
00691 }
00692
00693 list = extract_query_list(settings, MythSetting::kGlobal);
00694 qstr =
00695 "SELECT value, data "
00696 "FROM settings "
00697 "WHERE hostname IS NULL AND "
00698 " value in (" + list + ")";
00699
00700 if (!list.isEmpty())
00701 {
00702 if (!query.exec(qstr))
00703 {
00704 MythDB::DBError("HttpConfig::LoadMythSettings() 2", query);
00705 return false;
00706 }
00707 fill_settings(settings, query, MythSetting::kGlobal);
00708 }
00709
00710 return true;
00711 }
00712
00713 bool check_settings(MythSettingList &database_settings,
00714 const QMap<QString,QString> ¶ms,
00715 QString &result)
00716 {
00717 QMap<QString,QString>::const_iterator it = params.begin();
00718 for (; it != params.end(); ++it)
00719 {
00720 if (it.key().startsWith("__"))
00721 continue;
00722
00723 if (result.isEmpty())
00724 result += "{ ";
00725 else
00726 result += ", ";
00727
00728 result += QString("\"%1\": \"DEBUG: New value for '%2' would be '%3'\"")
00729 .arg(it.key()).arg(it.key()).arg(*it);
00730 }
00731
00732 if (!result.isEmpty())
00733 result += " }";
00734
00735
00736 return result.isEmpty();
00737 }