System* MolecularFileDialog::openFile_(String type) { QStringList files = QFileDialog::getOpenFileNames( 0, tr("Choose a molecular file to open"), getWorkingDir().c_str(), "*.*"); System* system = 0; for (QStringList::Iterator it = files.begin(); it != files.end(); ++it) { vector<String> fields; String seperators(FileSystem::PATH_SEPARATOR); // workaround on windows: QT returns the filename in linux style // but I am not sure, if this will stay this way. #ifdef BALL_OS_WINDOWS seperators += "/"; #endif String file = ascii(*it); Position p = file.split(fields, seperators.c_str()) -1; String filename = fields[p]; setWorkingDirFromFilename_(file); // construct a name for the system(the filename without the dir path) system = openMolecularFile(file, type, filename); } return system; }
// by default the confReader will look for a number like "cylinder5" and see the corresponding number. //The number may be in decimals. static double getCylinderSize(int num, std::string propertiesPath = "properties.conf") { std::ifstream stream; // input stream std::string buffer; std::string temp; std::string number; int cylinderNum; double cylinderSize; stream.open(propertiesPath.c_str()); // open the file size_t location(0); while (std::getline(stream, buffer)) // while there is still stuff in the file, get a line from it and put it in buffer { removeCarrageReturn(buffer); // find and kill any '\r' boost::char_separator<char> seperators(",\t()| &^%!@$="); // all of these chars will be ignored and used a tokenizers tokenizer tokens(buffer, seperators); // tokenize tokenizer::iterator tok = tokens.begin(); // there is a list of tokens made, it is accessible via iterator if (tok == tokens.end()) // if there is nothing in the line continue; // skip the line temp = *tok; // string temp = dereference to tok (tok was pointing to a string) if (temp[0] == '#') // this is a comment mark, if found, then ignore the line, continue; // skip the line // ++tok; // go to next token temp = *tok; // string temp = dereference to token (toLower(temp)); // turn to all lower case if ((location = (temp).find("cylinder"))== std::string::npos){ // if that doesnt exist return DEFAULT_CYLINDER_VAL; } number = (temp).substr(location+8); // everything after cylinder if (number.find_first_not_of("1234567890") != std::string::npos) // if anything that isnt those exists { return DEFAULT_CYLINDER_VAL; } cylinderNum = boost::lexical_cast<int>(number); if (num != cylinderNum) continue; ++tok; number = *tok; if (number.find_first_not_of("1234567890.") != std::string::npos) // if anything that isnt those exists { return DEFAULT_CYLINDER_VAL; } cylinderSize = boost::lexical_cast<double>(number); // convert string to double return cylinderSize; } // if all else fails, return the default val return 15.0; };
System* MolecularFileDialog::openMolecularFile(const String& file) { vector<String> fields; String seperators(FileSystem::PATH_SEPARATOR); // workaround on windows: QT returns the filename in linux style // but I am not sure, if this will stay this way. #ifdef BALL_OS_WINDOWS seperators += "/"; #endif Position p = file.split(fields, seperators.c_str()) -1; String filename = fields[p]; setWorkingDirFromFilename_(file); String extension = fields[filename.split(fields, ".") -1]; filename = filename.getSubstring(0, filename.size() - (extension.size() + 1)); return openMolecularFile(file, extension, filename); }
paint::paint(const std::string& s) : color_attrib_(ColorAttrib::VALUE), backup_color_attrib_(ColorAttrib::NONE), opacity_(1.0) { if(s == "none") { color_attrib_ = ColorAttrib::NONE; } else if(s == "currentColor") { color_attrib_ = ColorAttrib::CURRENT_COLOR; } else if(s.length() > 1 && s[0] == '#') { ASSERT_LOG(s.length() == 4 || s.length() == 7, "Expected length of color definition to be 3 or 6 characters long, found: " << s.substr(1)); if(s.length() == 4) { int r_hex = convert_hex_digit(s[1]); int g_hex = convert_hex_digit(s[2]); int b_hex = convert_hex_digit(s[3]); color_value_ = color((r_hex << 4) | r_hex, (g_hex << 4) | g_hex, (b_hex << 4) | b_hex); } else { color_value_ = color((convert_hex_digit(s[1]) << 4) | convert_hex_digit(s[2]), (convert_hex_digit(s[3]) << 4) | convert_hex_digit(s[4]), (convert_hex_digit(s[5]) << 4) | convert_hex_digit(s[6])); } } else if(s.length() > 3 && s.substr(0,3) == "rgb") { boost::char_separator<char> seperators(" \n\t\r,()"); boost::tokenizer<boost::char_separator<char>> tok(s.substr(3), seperators); int count = 0; int cv[3]; for(auto it = tok.begin(); it != tok.end(); ++it) { char* end = NULL; long value = strtol(it->c_str(), &end, 10); uint8_t col_val = 0; if(value == 0 && end == it->c_str()) { ASSERT_LOG(false, "Unable to parse string as an integer: " << *it); } if(end != NULL && *end == '%') { ASSERT_LOG(value >= 0 && value <= 100, "Percentage values range from 0-100: " << value); col_val = uint8_t(value / 100.0 * 255); } else { ASSERT_LOG(value >= 0 && value <= 255, "Percentage values range from 0-255: " << value); col_val = uint8_t(value); } ASSERT_LOG(count < 3, "Too many numbers in color value"); cv[count] = col_val; } color_value_ = color(cv[0],cv[1],cv[2]); } else if(s.length() > 4 && s.substr(0, 4) == "url(") { auto st_it = std::find(s.begin(), s.end(), '('); auto ed_it = std::find(s.begin(), s.end(), '0'); color_ref_ = uri::uri::parse(std::string(st_it, ed_it)); color_attrib_ = ColorAttrib::FUNC_IRI; std::string backup(ed_it, s.end()); if(!backup.empty()) { // XXX parse stuff } } else if(s.length() > 9 && s.substr(0,9) == "icc-color") { boost::char_separator<char> seperators(" \n\t\r,()"); boost::tokenizer<boost::char_separator<char>> tok(s.substr(9), seperators); auto it = tok.begin(); icc_color_name_ = *it; for(; it != tok.end(); ++it) { try { double value = boost::lexical_cast<double>(*it); icc_color_values_.emplace_back(value); } catch(boost::bad_lexical_cast&) { ASSERT_LOG(false, "Unable to convert icc-color value from string to numeric: " << *it << " : " << s); } } color_attrib_ = ColorAttrib::ICC_COLOR; } else { color_value_ = color::from_name(s); } }
std::vector<transform_ptr> transform::factory(const std::string& s) { std::vector<transform_ptr> results; enum { STATE_TYPE, STATE_NUMBER, } state = STATE_TYPE; std::vector<double> parameters; TransformType type = TransformType::ERROR; boost::char_separator<char> seperators(" \n\t\r,", "()"); boost::tokenizer<boost::char_separator<char>> tok(s, seperators); for(auto it = tok.begin(); it != tok.end(); ++it) { if(state == STATE_TYPE) { if(*it == "matrix") { type = TransformType::MATRIX; } else if(*it == "translate") { type = TransformType::TRANSLATE; } else if(*it == "scale") { type = TransformType::SCALE; } else if(*it == "rotate") { type = TransformType::ROTATE; } else if(*it == "skewX") { type = TransformType::SKEW_X; } else if(*it == "skewY") { type = TransformType::SKEW_Y; } else if(*it == "(") { parameters.clear(); state = STATE_NUMBER; } else { ASSERT_LOG(false, "Unexpected token while looking for a type: " << *it << " : " << s); } } else if(state == STATE_NUMBER) { if(*it == ")") { ASSERT_LOG(type != TransformType::ERROR, "svg transform type was not initialized"); switch(type) { case TransformType::MATRIX: { matrix_transform* mtrf = new matrix_transform(parameters); results.emplace_back(mtrf); break; } case TransformType::TRANSLATE: { ASSERT_LOG(parameters.size() == 1 || parameters.size() == 2, "Parsing transform:translate found " << parameters.size() << " parameter(s), expected 1 or 2"); double tx = parameters[0]; double ty = parameters.size() == 2 ? parameters[1] : 0.0f; translate_transform * ttrf = new translate_transform(tx, ty); results.emplace_back(ttrf); break; } case TransformType::SCALE: { ASSERT_LOG(parameters.size() == 1 || parameters.size() == 2, "Parsing transform:scale found " << parameters.size() << " parameter(s), expected 1 or 2"); double sx = parameters[0]; double sy = parameters.size() == 2 ? parameters[1] : sx; scale_transform * strf = new scale_transform(sx, sy); results.emplace_back(strf); break; } case TransformType::ROTATE: { ASSERT_LOG(parameters.size() == 1 || parameters.size() == 3, "Parsing transform:rotate found " << parameters.size() << " parameter(s), expected 1 or 3"); double angle = parameters[0] / 180.0 * M_PI; double cx = parameters.size() == 3 ? parameters[1] : 0; double cy = parameters.size() == 3 ? parameters[2] : 0; rotation_transform* rtrf = new rotation_transform(angle, cx, cy); results.emplace_back(rtrf); break; } case TransformType::SKEW_X: { ASSERT_LOG(parameters.size() == 1, "Parsing transform:skewX found " << parameters.size() << " parameter(s), expected 1"); double sa = tan(parameters[0]); skew_x_transform* sxtrf = new skew_x_transform(sa); results.emplace_back(sxtrf); break; } case TransformType::SKEW_Y: { ASSERT_LOG(parameters.size() == 1, "Parsing transform:skewY found " << parameters.size() << " parameter(s), expected 1"); double sa = tan(parameters[0]); skew_y_transform* sxtrf = new skew_y_transform(sa); results.emplace_back(sxtrf); break; } case TransformType::ERROR: assert(false); break; } state = STATE_TYPE; } else { char* end = nullptr; double value = strtod(it->c_str(), &end); if(value == 0 && it->c_str() == end) { ASSERT_LOG(false, "Invalid number value: " << *it); } ASSERT_LOG(errno != ERANGE, "parsed numeric value out-of-range: " << *it); parameters.push_back(value); } } } return results; }