// checkbox.cpp - GUICheckbox object #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern "C" { #include "../twcommon.h" #include "../minuitwrp/minui.h" #include "../variables.h" } #include "rapidxml.hpp" #include "objects.hpp" #include "../data.hpp" GUIObject::GUIObject(xml_node<>* node) { mConditionsResult = true; // Break out early, it's too hard to check if valid every step if (!node) return; // First, get the action xml_node<>* condition = node->first_node("conditions"); if (condition) condition = condition->first_node("condition"); else condition = node->first_node("condition"); if (!condition) return; while (condition) { Condition cond; cond.mCompareOp = "="; xml_attribute<>* attr; attr = condition->first_attribute("var1"); if (attr) cond.mVar1 = attr->value(); attr = condition->first_attribute("op"); if (attr) cond.mCompareOp = attr->value(); attr = condition->first_attribute("var2"); if (attr) cond.mVar2 = attr->value(); mConditions.push_back(cond); condition = condition->next_sibling("condition"); } } GUIObject::~GUIObject() { } bool GUIObject::IsConditionVariable(std::string var) { std::vector::iterator iter; for (iter = mConditions.begin(); iter != mConditions.end(); iter++) { if (iter->mVar1 == var) return true; } return false; } bool GUIObject::isConditionTrue() { return mConditionsResult; } bool GUIObject::isConditionTrue(Condition* condition) { // This is used to hold the proper value of "true" based on the '!' NOT flag bool bTrue = true; if (condition->mVar1.empty()) return bTrue; if (!condition->mCompareOp.empty() && condition->mCompareOp[0] == '!') bTrue = false; if (condition->mVar2.empty() && condition->mCompareOp != "modified") { if (!DataManager::GetStrValue(condition->mVar1).empty()) return bTrue; return !bTrue; } string var1, var2; if (DataManager::GetValue(condition->mVar1, var1)) var1 = condition->mVar1; if (DataManager::GetValue(condition->mVar2, var2)) var2 = condition->mVar2; // This is a special case, we stat the file and that determines our result if (var1 == "fileexists") { struct stat st; if (stat(var2.c_str(), &st) == 0) var2 = var1; else var2 = "FAILED"; } if (var1 == "mounted") { if (isMounted(condition->mVar2)) var2 = var1; else var2 = "FAILED"; } if (condition->mCompareOp.find('=') != string::npos && var1 == var2) return bTrue; if (condition->mCompareOp.find('>') != string::npos && (atof(var1.c_str()) > atof(var2.c_str()))) return bTrue; if (condition->mCompareOp.find('<') != string::npos && (atof(var1.c_str()) < atof(var2.c_str()))) return bTrue; if (condition->mCompareOp == "modified") { // This is a hack to allow areas to reset the default value if (var1.empty()) { condition->mLastVal = var1; return !bTrue; } if (var1 != condition->mLastVal) return bTrue; } return !bTrue; } bool GUIObject::isConditionValid() { return !mConditions.empty(); } int GUIObject::NotifyVarChange(const std::string& varName, const std::string& value) { mConditionsResult = true; const bool varNameEmpty = varName.empty(); std::vector::iterator iter; for (iter = mConditions.begin(); iter != mConditions.end(); ++iter) { if(varNameEmpty && iter->mCompareOp == "modified") { string val; // If this fails, val will not be set, which is perfect if (DataManager::GetValue(iter->mVar1, val)) { DataManager::SetValue(iter->mVar1, ""); DataManager::GetValue(iter->mVar1, val); } iter->mLastVal = val; } if(varNameEmpty || iter->mVar1 == varName || iter->mVar2 == varName) iter->mLastResult = isConditionTrue(&(*iter)); if(!iter->mLastResult) mConditionsResult = false; } return 0; } bool GUIObject::isMounted(string vol) { FILE *fp; char tmpOutput[255]; fp = fopen("/proc/mounts", "rt"); while (fgets(tmpOutput,255,fp) != NULL) { char* mnt = tmpOutput; while (*mnt > 32) mnt++; while (*mnt > 0 && *mnt <= 32) mnt++; char* pos = mnt; while (*pos > 32) pos++; *pos = 0; if (vol == mnt) { fclose(fp); return true; } } fclose(fp); return false; }