diff options
Diffstat (limited to 'gui/conditional.cpp')
-rw-r--r-- | gui/conditional.cpp | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/gui/conditional.cpp b/gui/conditional.cpp new file mode 100644 index 000000000..5ea8d176c --- /dev/null +++ b/gui/conditional.cpp @@ -0,0 +1,204 @@ +// checkbox.cpp - GUICheckbox object + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <sys/reboot.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <time.h> +#include <unistd.h> +#include <stdlib.h> + +#include <string> + +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +#include "../variables.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" +#include "../data.hpp" + +Conditional::Conditional(xml_node<>* node) +{ + // 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"); + } +} + +bool Conditional::IsConditionVariable(std::string var) +{ + std::vector<Condition>::iterator iter; + for (iter = mConditions.begin(); iter != mConditions.end(); iter++) + { + if (iter->mVar1 == var) + return true; + } + return false; +} + +bool Conditional::isConditionTrue() +{ + std::vector<Condition>::iterator iter; + for (iter = mConditions.begin(); iter != mConditions.end(); iter++) + { + if (!isConditionTrue(&(*iter))) + return false; + } + return true; +} + +bool Conditional::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 Conditional::isConditionValid() +{ + return !mConditions.empty(); +} + +void Conditional::NotifyPageSet() +{ + std::vector<Condition>::iterator iter; + for (iter = mConditions.begin(); iter != mConditions.end(); iter++) + { + if (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; + } + } +} + +bool Conditional::isMounted(string vol) +{ + FILE *fp; + char tmpOutput[255]; + + if (strcmp(vol.c_str(), "EXTERNAL") == 0) + DataManager::GetValue(TW_EXTERNAL_MOUNT, vol); + else if (strcmp(vol.c_str(), "INTERNAL") == 0) + DataManager::GetValue(TW_INTERNAL_MOUNT, vol); + 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; +} |