diff --git a/src/App/Range.cpp b/src/App/Range.cpp index e019131b3b..fba197b0eb 100644 --- a/src/App/Range.cpp +++ b/src/App/Range.cpp @@ -26,6 +26,8 @@ #include #include #include +#include +#include #endif #include @@ -136,22 +138,33 @@ int App::decodeRow(const std::string &rowstr, bool silent) } /** - * @brief Decode a column specification into a 0-based integer. + * Assumes well-formed input. A through ZZZ. 0-based output + */ +int columnStringToNum(const std::string &colstr){ + double out {0}; + int pos {0}; + for(auto chr = colstr.crbegin(); chr != colstr.crend(); chr++){ + out += (*chr - 'A' + 1) * std::pow(26, pos++); + } + return static_cast(out - 1); +} + +/** + * @brief Decode a column name string into a 0-based integer. * - * @param colstr Column specified as a string, with "A" begin the first column. + * @param colstr input string. * * @returns The column. * */ -int App::decodeColumn(const std::string &colstr, bool silent) +int App::decodeColumn( const std::string &colstr, bool silent ) { - int col = validColumn(colstr); - - if (silent || col >= 0) - return col; - else - throw Base::IndexError("Invalid column specification"); + if(validColumn( colstr ) ) + return columnStringToNum( colstr ); + if( silent ) + return -1; + throw Base::IndexError("Invalid column specification"); } /** @@ -174,39 +187,17 @@ int App::validRow(const std::string &rowstr) } /** - * @brief Determine whether a column specification is valid or not. + * @brief Determine if a string is a valid column specification. * - * @param colstr Column specified as a string, with "A" begin the first column. + * @param colstr input string. * - * @returns 0 or positive on success, -1 on error. + * @returns true if valid, false if not. * */ -int App::validColumn(const std::string &colstr) +bool App::validColumn( const std::string &colstr ) { - int col = 0; - - if (colstr.length() == 1) { - if ((colstr[0] >= 'A' && colstr[0] <= 'Z')) - col = colstr[0] - 'A'; - else - return -1; - } - else { - col = 0; - for (std::string::const_iterator i = colstr.begin(); i != colstr.end(); ++i) { - int v; - - if ((*i >= 'A' && *i <= 'Z')) - v = *i - 'A'; - else - return -1; - - col = col * 26 + v; - } - col += 26; - } - return col; + return std::regex_match(colstr, std::regex("[A-Z]{1,3}" )); } /** diff --git a/src/App/Range.h b/src/App/Range.h index 17f0bb4e33..f40e69557c 100644 --- a/src/App/Range.h +++ b/src/App/Range.h @@ -36,7 +36,7 @@ struct CellAddress; AppExport CellAddress stringToAddress(const char *strAddress, bool silent=false); AppExport int decodeColumn(const std::string &colstr, bool silent=false); AppExport int decodeRow(const std::string &rowstr, bool silent=false); -AppExport int validColumn(const std::string &colstr); +AppExport bool validColumn(const std::string &colstr); AppExport int validRow(const std::string &rowstr); struct AppExport CellAddress { diff --git a/src/Mod/Spreadsheet/App/PropertySheet.cpp b/src/Mod/Spreadsheet/App/PropertySheet.cpp index 56d291549b..319cb20807 100644 --- a/src/Mod/Spreadsheet/App/PropertySheet.cpp +++ b/src/Mod/Spreadsheet/App/PropertySheet.cpp @@ -142,7 +142,7 @@ bool PropertySheet::isValidAlias(const std::string &candidate) const boost::sub_match rowstr = cm[2]; // A valid cell address? - if (App::validRow(rowstr.str()) >= 0 && App::validColumn(colstr.str()) >= 0) + if (App::validRow(rowstr.str()) >= 0 && App::validColumn(colstr.str())) return false; } return true;