void Value::Read(ods::Ns &ns, ods::Attrs &attrs) { DeleteData(); auto *type_attr = attrs.Get(ns.office(), ods::ns::kValueType); if (type_attr == nullptr) { // shouldn't happen type_ = ods::Type::Fail; return; } type_ = ods::TypeFromString(type_attr->value()); auto *value_attr = attrs.Get(ns.office(), ods::ns::kValue); if (value_attr == nullptr) { type_ = ods::Type::Fail; return; } if (IsDouble() || IsPercentage() || IsCurrency()) { double num; if (!value_attr->ToDouble(num)) { mtl_warn("ToDouble()"); return; } set(new double(num), type_); } else if (IsString()) { set(new QString(value_attr->value()), ods::Type::String); } else if (IsDate()) { auto *custom_attr = attrs.Get(ns.office(), ods::ns::kDateValue); if (custom_attr == nullptr) { mtl_warn("custom_attr == nullptr"); return; } auto dt = QDateTime::fromString(custom_attr->value(), Qt::ISODate); set(new QDateTime(dt), type_); } else if (IsDuration()) { auto *custom_attr = attrs.Get(ns.office(), ods::ns::kTimeValue); if (custom_attr == nullptr) { mtl_warn("custom_attr == nullptr"); return; } auto *t = new ods::Duration(); t->Decode(custom_attr->value()); set(t, type_); } else { type_ = ods::Type::NotSet; } }
Substyle::~Substyle() { if (IsNotSet()) return; if (IsCurrency()) delete AsCurrency(); else if (IsDate()) delete AsDate(); else if (IsDuration()) delete AsDuration(); else if (IsPercent()) delete AsPercent(); }
QString Value::toString() const { if (!Ok()) return ""; if (IsDouble() || IsPercentage()) return QString::number(*AsDouble()); if (IsString()) return *AsString(); if (IsDate()) return AsDate()->toString(Qt::ISODate); if (IsCurrency()) mtl_qline("Currency not supported yet"); if (IsDuration()) return AsDuration()->ToString(); return ""; }
void Value::CopyTo(ods::Value &v) { v.type_set(type_); if (NoValue()) return; if (IsDouble()) v.SetDouble(*AsDouble()); else if (IsString()) v.SetString(*AsString()); else if (IsCurrency()) v.SetCurrency(*AsCurrency()); else if (IsPercentage()) v.SetPercentage(*AsPercentage()); else if (IsDate()) v.SetDate(*AsDate()); else if (IsDuration()) v.SetDuration(*AsDuration()); else mtl_warn("Not implemented"); }
void CScraperPreprocessor::PreprocessMonetaryString(CString *monetary_string) { // 1) Commas in numbers: "$3,45" should be raplaced by "$3.45". // And "$3,456.78" should be replaced by "$3.456.78" // 2) Dot as delimter-symbol in numbers: "$3.456.78". // Dots followed by three (or more) digits should be removed: "$3456.78" // 3) Spaces inside numbers: somebody reported blinds like "$40 000" in MTTs. // They also should be removed. // 4) Foreign-language money-signs like Euro € should be replaced by dollars. int length = monetary_string->GetLength(); CString result; // A small technical trick: append 3 spaces, // so we don't have to check for index errors if we investigate the next 3 characters *monetary_string += " "; // Special handling required for the first character char first_character = monetary_string->GetAt(0); char second_character = monetary_string->GetAt(1); if (!IsCurrency(first_character) || !isdigit(second_character)) { result += first_character; } // Now caring about the rest, starting from 2nd character int second_position = 1; int last_position = length - 1; char ith_character = ' '; char previous_character = ' '; char next_character = ' '; for (int i=second_position; i<=last_position; i++) { ith_character = monetary_string->GetAt(i); next_character = monetary_string->GetAt(i+1); if (IsCurrency(ith_character)) { // Keep them at the moment, but replace foreign currencys by dollars. // The scraper will deal with them later result += '$'; } else if ((ith_character == '.') || (ith_character == ',')) { // Accept commans and dots outside numbers if (!isdigit(previous_character) || !isdigit(next_character)) { result += ith_character; } else { // Comma or dot inside number // If only the following 2 digits are numbers then we have a fractional-dot. // But if the 3rd digit is a number too then it is only a delimiter-dot // (for better readability) that has to be ignored. char third_next_character = monetary_string->GetAt(i+3); if (!isdigit(third_next_character)) { // Append the fractional-dot (implicitly repalcing comma if necessary) result += '.'; } } } else if (ith_character == ' ') { // Spaces inside numbers have to be ignored // Up to now we saw it only for very large blinds of SNGs / MTTs, // for example "$40 000". if (isdigit(previous_character) && next_character == '0' && monetary_string->GetAt(i+2) == '0' && monetary_string->GetAt(i+3) == '0') { // Ignore it } else { result += ' '; } } else { // Everything else // Keep it result += ith_character; } previous_character = ith_character; } *monetary_string = result; write_log(preferences.debug_scraper_preprocessor(), "Monetary string after preprocessing: %s\n", result); }