00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "identifier.h"
00022 #include <kstaticdeleter.h>
00023 #include <qdict.h>
00024
00025 using namespace KexiUtils;
00026
00027 bool KexiUtils::isIdentifier(const QString& s)
00028 {
00029 uint i;
00030 for (i=0; i<s.length(); i++) {
00031 QChar c = s.at(i).lower();
00032 if (!(c=='_' || c>='a' && c<='z' || i>0 && c>='0' && c<='9'))
00033 break;
00034 }
00035 return i>0 && i==s.length();
00036 }
00037
00038 QString KexiUtils::string2FileName(const QString &s)
00039 {
00040 QString fn = s.simplifyWhiteSpace();
00041 fn.replace(' ',"_"); fn.replace('$',"_");
00042 fn.replace('\\',"-"); fn.replace('/',"-");
00043 fn.replace(':',"-"); fn.replace('*',"-");
00044 return fn;
00045 }
00046
00047
00048
00049 static const char* string2Identifier_table[] = {
00050
00051 "Ą", "A", "Ć", "C", "Ę", "E",
00052 "Ł", "L", "Ń", "N", "Ó", "O",
00053 "Ś", "S", "Ź", "Z", "Ż", "Z",
00054 "ą", "a", "ć", "c", "ę", "e",
00055 "ł", "l", "ń", "n", "ó", "o",
00056 "ś", "s", "ź", "z", "ż", "z",
00057
00058
00059
00060
00061
00062
00063
00064
00065
00069 "Ä", "Ae",
00070 "Ö", "Oe",
00071 "Ü", "Ue",
00072 "ä", "ae",
00073 "ö", "oe",
00074 "ü", "ue",
00075 "ß", "ss",
00076
00077
00078
00079
00080 "а", "a",
00081 "б", "b",
00082 "в", "v",
00083 "г", "g",
00084 "д", "d",
00085 "е", "e",
00086 "ж", "z",
00087 "з", "z",
00088 "и", "i",
00089 "к", "k",
00090 "л", "l",
00091 "м", "m",
00092 "н", "n",
00093 "о", "o",
00094 "п", "p",
00095 "р", "r",
00096 "с", "s",
00097 "т", "t",
00098 "у", "u",
00099 "ф", "f",
00100 "х", "h",
00101 "ц", "c",
00102 "ч", "c",
00103 "ш", "s",
00104 "А", "A",
00105 "Б", "B",
00106 "В", "V",
00107 "Г", "G",
00108 "Д", "D",
00109 "Е", "E",
00110 "Ж", "Z",
00111 "З", "Z",
00112 "И", "I",
00113 "К", "K",
00114 "Л", "L",
00115 "М", "M",
00116 "Н", "N",
00117 "О", "O",
00118 "П", "P",
00119 "Р", "R",
00120 "С", "S",
00121 "Т", "T",
00122 "У", "U",
00123 "Ф", "F",
00124 "Х", "H",
00125 "Ц", "C",
00126 "Ч", "C",
00127 "Ш", "S",
00128
00129 "ђ", "dj",
00130 "ј", "j",
00131 "љ", "lj",
00132 "њ", "nj",
00133 "ћ", "c",
00134 "џ", "dz",
00135 "Ђ", "Dj",
00136 "Ј", "J",
00137 "Љ", "Lj",
00138 "Њ", "Nj",
00139 "Ћ", "C",
00140 "Џ", "Dz",
00141
00142 "đ", "dj",
00143 "ž", "z",
00144 "ć", "c",
00145 "č", "c",
00146 "š", "s",
00147 "Đ", "Dj",
00148 "Ž", "Z",
00149 "Ć", "C",
00150 "Č", "C",
00151 "Š", "S",
00152
00153 "Á", "A",
00154 "Č", "C",
00155 "Ď", "D",
00156 "É", "E",
00157 "Ě", "E",
00158 "Í", "I",
00159 "Ň", "N",
00160 "Ó", "O",
00161 "Ř", "R",
00162 "Š", "S",
00163 "Ť", "T",
00164 "Ú", "U",
00165 "Ů", "U",
00166 "Ý", "Y",
00167 "Ž", "Z",
00168 "á", "a",
00169 "č", "c",
00170 "ď", "d",
00171 "é", "e",
00172 "ě", "e",
00173 "í", "i",
00174 "ň", "n",
00175 "ó", "o",
00176 "ř", "r",
00177 "š", "s",
00178 "ť", "t",
00179 "ú", "u",
00180 "ů", "u",
00181 "ý", "y",
00182 "ž", "z",
00183
00184 0
00185 };
00186
00188 static KStaticDeleter< QDict<QCString> > string2Identifier_deleter;
00189 static QDict<QCString>* string2Identifier_dict = 0;
00190
00191 inline QString char2Identifier(const QChar& c)
00192 {
00193 if ((c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') || c=='_')
00194 return QString(c);
00195 else {
00196 if (!string2Identifier_dict) {
00197
00198 string2Identifier_deleter.setObject( string2Identifier_dict, new QDict<QCString>(1009) );
00199 string2Identifier_dict->setAutoDelete(true);
00200 for (const char **p = string2Identifier_table; *p; p+=2) {
00201 string2Identifier_dict->replace(
00202 QString::fromUtf8(*p), new QCString(*(p+1)) );
00203 }
00204 }
00205 const QCString *fixedChar = string2Identifier_dict->find(c);
00206 if (fixedChar)
00207 return *fixedChar;
00208 }
00209 return QString(QChar('_'));
00210 }
00211
00212 QString KexiUtils::string2Identifier(const QString &s)
00213 {
00214 QString r, id = s.simplifyWhiteSpace();
00215 if (id.isEmpty())
00216 return id;
00217 r.reserve(id.length());
00218
00219 id.replace(' ',"_");
00220 QChar c = id[0];
00221
00222 if (c>='0' && c<='9') {
00223 r+='_';
00224 r+=c;
00225 } else
00226 r+=char2Identifier(c);
00227
00228 for (uint i=1; i<id.length(); i++)
00229 r+=char2Identifier(id.at(i));
00230 return r;
00231 }
00232
00233
00234
00235 QString KexiUtils::identifierExpectedMessage(const QString &valueName, const QVariant& v)
00236 {
00237 return "<p>"+i18n("Value of \"%1\" column must be an identifier.").arg(valueName)
00238 +"</p><p>"+i18n("\"%1\" is not a valid identifier.").arg(v.toString())+"</p>";
00239 }
00240
00241
00242
00243 IdentifierValidator::IdentifierValidator(QObject * parent, const char * name)
00244 : Validator(parent,name)
00245 {
00246 }
00247
00248 IdentifierValidator::~IdentifierValidator()
00249 {
00250 }
00251
00252 QValidator::State IdentifierValidator::validate( QString& input, int& pos ) const
00253 {
00254 uint i;
00255 for (i=0; i<input.length() && input.at(i)==' '; i++)
00256 ;
00257 pos -= i;
00258 if (i<input.length() && input.at(i)>='0' && input.at(i)<='9')
00259 pos++;
00260 bool addspace = (input.right(1)==" ");
00261 input = string2Identifier(input);
00262 if (addspace)
00263 input += "_";
00264 if((uint)pos>input.length())
00265 pos=input.length();
00266 return input.isEmpty() ? Valid : Acceptable;
00267 }
00268
00269 Validator::Result IdentifierValidator::internalCheck(
00270 const QString &valueName, const QVariant& v,
00271 QString &message, QString & )
00272 {
00273 if (isIdentifier(v.toString()))
00274 return Validator::Ok;
00275 message = identifierExpectedMessage(valueName, v);
00276 return Validator::Error;
00277 }
00278