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 0
00154 };
00155
00157 static KStaticDeleter< QDict<QCString> > string2Identifier_deleter;
00158 static QDict<QCString>* string2Identifier_dict = 0;
00159
00160 inline QString char2Identifier(const QChar& c)
00161 {
00162 if ((c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') || c=='_')
00163 return QString(c);
00164 else {
00165 if (!string2Identifier_dict) {
00166
00167 string2Identifier_deleter.setObject( string2Identifier_dict, new QDict<QCString>(1009) );
00168 string2Identifier_dict->setAutoDelete(true);
00169 for (const char **p = string2Identifier_table; *p; p+=2) {
00170 string2Identifier_dict->replace(
00171 QString::fromUtf8(*p), new QCString(*(p+1)) );
00172 }
00173 }
00174 const QCString *fixedChar = string2Identifier_dict->find(c);
00175 if (fixedChar)
00176 return *fixedChar;
00177 }
00178 return QString(QChar('_'));
00179 }
00180
00181 QString KexiUtils::string2Identifier(const QString &s)
00182 {
00183 QString r, id = s.simplifyWhiteSpace();
00184 if (id.isEmpty())
00185 return id;
00186 r.reserve(id.length());
00187
00188 id.replace(' ',"_");
00189 QChar c = id[0];
00190
00191 if (c>='0' && c<='9') {
00192 r+='_';
00193 r+=c;
00194 } else
00195 r+=char2Identifier(c);
00196
00197 for (uint i=1; i<id.length(); i++)
00198 r+=char2Identifier(id.at(i));
00199 return r;
00200 }
00201
00202
00203
00204 QString KexiUtils::identifierExpectedMessage(const QString &valueName, const QVariant& v)
00205 {
00206 return "<p>"+i18n("Value of \"%1\" column must be an identifier.").arg(valueName)
00207 +"</p><p>"+i18n("\"%1\" is not a valid identifier.").arg(v.toString())+"</p>";
00208 }
00209
00210
00211
00212 IdentifierValidator::IdentifierValidator(QObject * parent, const char * name)
00213 : Validator(parent,name)
00214 {
00215 }
00216
00217 IdentifierValidator::~IdentifierValidator()
00218 {
00219 }
00220
00221 QValidator::State IdentifierValidator::validate( QString& input, int& pos ) const
00222 {
00223 uint i;
00224 for (i=0; i<input.length() && input.at(i)==' '; i++)
00225 ;
00226 pos -= i;
00227 if (i<input.length() && input.at(i)>='0' && input.at(i)<='9')
00228 pos++;
00229 bool addspace = (input.right(1)==" ");
00230 input = string2Identifier(input);
00231 if (addspace)
00232 input += "_";
00233 if((uint)pos>input.length())
00234 pos=input.length();
00235 return input.isEmpty() ? Valid : Acceptable;
00236 }
00237
00238 Validator::Result IdentifierValidator::internalCheck(
00239 const QString &valueName, const QVariant& v,
00240 QString &message, QString & )
00241 {
00242 if (isIdentifier(v.toString()))
00243 return Validator::Ok;
00244 message = identifierExpectedMessage(valueName, v);
00245 return Validator::Error;
00246 }
00247