00001 #include "cfgfile.h"
00002
00003
00004 #include <opie2/odebug.h>
00005 using namespace Opie::Core;
00006
00007
00008 #include <qmessagebox.h>
00009
00010
00011 CfgEntry::CfgEntry() {
00012 }
00013
00014 CfgEntry::CfgEntry(const QString& f, const QString& l):
00015 file(f), label(l) {
00016 }
00017
00018 const QString& CfgEntry::getFile() const {
00019 return file;
00020 }
00021
00022 void CfgEntry::setFile(const QString& f) {
00023 file = f;
00024 }
00025
00026 const QString& CfgEntry::getLabel() const {
00027 return label;
00028 }
00029
00030 void CfgEntry::setLabel(const QString& f) {
00031 label = f;
00032 }
00033
00034
00035 CfgFile::CfgFile():ardelay(400), arperiod(80) {
00036 }
00037
00038 CfgFile::~CfgFile() {
00039 }
00040
00041 QList<CfgEntry>& CfgFile::getEntries() {
00042 return entries;
00043 }
00044
00045 bool CfgFile::replaceEntry(const QString& file, const QString& label, int index) {
00046 deleteEntry(file);
00047
00048 CfgEntry* entry = new CfgEntry(file, label);
00049 if (index >= 0) {
00050 entries.insert(index, entry);
00051 } else {
00052 entries.append(entry);
00053 }
00054
00055 return true;
00056 }
00057
00058 bool CfgFile::deleteEntry(const QString& file) {
00059 for(int i = 0; i < (int) entries.count(); i++) {
00060 CfgEntry* entry = entries.at(i);
00061 if (entry->getFile() == file) {
00062 entries.remove(i);
00063 return true;
00064 }
00065 }
00066 return false;
00067 }
00068
00069 int CfgFile::getAutorepeatDelay() const {
00070 return ardelay;
00071 }
00072
00073 void CfgFile::setAutorepeatDelay(int n) {
00074 ardelay = n;
00075 }
00076
00077 int CfgFile::getAutorepeatPeriod() const {
00078 return arperiod;
00079 }
00080
00081 void CfgFile::setAutorepeatPeriod(int n) {
00082 arperiod = n;
00083 }
00084
00085
00086 CfgParser::CfgParser() {
00087 }
00088
00089 bool CfgParser::load(QString file, CfgFile& cfg) {
00090 QFile f(file);
00091 QXmlInputSource is(f);
00092 QXmlSimpleReader reader;
00093 CfgHandler p(*this);
00094
00095 reader.setErrorHandler(this);
00096 reader.setContentHandler(&p);
00097
00098 err = "";
00099 ardelay = -1;
00100 arperiod = -1;
00101 reader.parse(is);
00102
00103 if (!err.isEmpty()) {
00104 odebug << err << oendl;
00105 return false;
00106 }
00107
00108 QMap<QString, QString>::Iterator fit, lit;
00109 for(uint i = 0; i < includeList.count(); i++) {
00110 QString file = *includeList.at(i);
00111 fit = includes.find(file);
00112 QString prefix = fit.data();
00113 QString label = "";
00114
00115 odebug << "include: file=" + fit.key() + ", prefix=" + fit.data() << oendl;
00116 lit = labels.find(prefix+":*");
00117 if (lit != labels.end()) {
00118 label = lit.data();
00119 }
00120
00121 cfg.replaceEntry(file, label);
00122 }
00123
00124 if (ardelay != -1) {
00125 cfg.setAutorepeatDelay(ardelay);
00126 }
00127
00128 if (arperiod != -1) {
00129 cfg.setAutorepeatPeriod(arperiod);
00130 }
00131
00132 return true;
00133 }
00134
00135 bool CfgParser::save(QString file, CfgFile& cfg) {
00136 FILE* f = fopen((const char*) file.local8Bit(), "w");
00137 if (!f) {
00138 oerr << "Could not write config file!" << oendl;
00139 return false;
00140 }
00141
00142 fprintf(f, "<keymap autorepeat-delay=\"%d\" autorepeat-period=\"%d\" "
00143 "author=\"keyzcfg\">\n", cfg.getAutorepeatDelay(),
00144 cfg.getAutorepeatPeriod());
00145
00146 QList<CfgEntry>& entries = cfg.getEntries();
00147 int n;
00148
00149 for(n=0; n < (int) entries.count(); n++) {
00150 CfgEntry* entry = entries.at(n);
00151 QString l = entry->getLabel();
00152 if (l.isEmpty()) {
00153 l = entry->getFile();
00154 }
00155 fprintf(f, "\t<label name=\"%s\" state=\"km%d:*\"/>\n",
00156 (const char*) l.utf8(), n);
00157 }
00158
00159 for(n=0; n < (int) entries.count(); n++) {
00160 CfgEntry* entry = entries.at(n);
00161 fprintf(f, "\t<include file=\"%s\" prefix=\"km%d\"/>\n",
00162 (const char*) entry->getFile().utf8(), n);
00163 }
00164
00165 int k = n-1;
00166 char* states[] = { "LShift", "LShift-Caps", "LShift-Num",
00167 "LShift-Num-Caps", 0};
00168
00169 for(n=0; n < (int) entries.count(); n++) {
00170 QString nstate = "km" + QString::number(n+1);
00171 if (n == k) {
00172 nstate = "km" + QString::number(0);
00173 }
00174
00175 for(int i = 0; states[i] != 0; i++) {
00176 fprintf(f, "\t<state name=\"km%d:%s\">\n",
00177 n, states[i]);
00178 fprintf(f, "\t\t<map keycode=\"Middle\" pressed=\"true\">\n");
00179 fprintf(f, "\t\t\t<next-state name=\"%s:%s\"/>\n",
00180 (const char*) nstate.utf8(), states[i]);
00181 fprintf(f, "\t\t</map>\n\t</state>\n\n");
00182 }
00183 }
00184
00185 fprintf(f, "\t<state name=\"km0:Normal\" default=\"true\"/>\n");
00186
00187 fprintf(f, "</keymap>");
00188 fclose(f);
00189 return true;
00190 }
00191
00192 CfgParser::~CfgParser() {
00193 }
00194
00195 int CfgParser::getAutorepeatDelay() const {
00196 return ardelay;
00197 }
00198
00199 void CfgParser::setAutorepeatDelay(int n) {
00200 ardelay = n;
00201 }
00202
00203 int CfgParser::getAutorepeatPeriod() const {
00204 return arperiod;
00205 }
00206
00207 void CfgParser::setAutorepeatPeriod(int n) {
00208 arperiod = n;
00209 }
00210
00211 void CfgParser::addLabel(const QString& name, const QString& state) {
00212 labels.insert(state, name);
00213 labelList.append(&labels.find(state).data());
00214 }
00215
00216 void CfgParser::addFile(const QString& file, const QString& prefix) {
00217 includes.insert(file, prefix);
00218 includeList.append(&includes.find(file).key());
00219 }
00220
00221 QString CfgParser::errorString() {
00222 return err;
00223 }
00224
00225 bool CfgParser::warning(const QXmlParseException& e) {
00226 QString tmp;
00227
00228 tmp.sprintf("%d: warning: %s\n", e.lineNumber(),
00229 (const char*) e.message().utf8());
00230
00231 err += tmp;
00232
00233 return true;
00234 }
00235
00236 bool CfgParser::error(const QXmlParseException& e) {
00237 QString tmp;
00238
00239 tmp.sprintf("%d: error: %s\n", e.lineNumber(),
00240 (const char*) e.message().utf8());
00241
00242 err += tmp;
00243
00244 return true;
00245 }
00246
00247 bool CfgParser::fatalError(const QXmlParseException& e) {
00248 QString tmp;
00249
00250 tmp.sprintf("%d: fatal error: %s\n", e.lineNumber(),
00251 (const char*) e.message().utf8());
00252
00253 err += tmp;
00254
00255 return false;
00256 }
00257
00258
00259 CfgHandler::CfgHandler(CfgParser& c):cfg(c) {
00260 }
00261
00262 CfgHandler::~CfgHandler() {
00263 }
00264
00265 bool CfgHandler::startKeymapElement(int ard, int arp, const QString& author) {
00266 if (author != "keyzcfg") {
00267 bool ret;
00268 ret = QMessageBox::warning(0, "keyz configurator",
00269 "Your zkb.xml doesn't seem created by keyz configurator.\n"
00270 "By using keyz configurator you may loose your current "
00271 "configuration\n Do you want to continue\n\n",
00272 "Yes", "No", 0, 0, 1);
00273
00274 if (ret != 0) {
00275 err = "cancelled by user";
00276 return false;
00277 }
00278 }
00279
00280 if (ard != -1) {
00281 cfg.setAutorepeatDelay(ard);
00282 }
00283
00284 if (arp != -1) {
00285 cfg.setAutorepeatPeriod(arp);
00286 }
00287
00288 return true;
00289 }
00290
00291 bool CfgHandler::startIncludeElement(const QString& file,
00292 const QString& pref) {
00293
00294 cfg.addFile(file, pref);
00295 return true;
00296 }
00297
00298 bool CfgHandler::startLabelElement(const QString& label,
00299 const QString& state) {
00300
00301 cfg.addLabel(label, state);
00302 return true;
00303 }
00304
00305 bool CfgHandler::startStateElement(const QString&, const QString&, bool) {
00306
00307 return true;
00308 }
00309
00310 bool CfgHandler::startMapElement(int, bool) {
00311 return true;
00312 }
00313
00314 bool CfgHandler::startEventElement(int, int, int, bool, bool) {
00315 return true;
00316 }
00317
00318 bool CfgHandler::startNextStateElement(const QString&) {
00319 return true;
00320 }
00321
00322
00323 bool CfgHandler::endKeymapElement() {
00324 return true;
00325 }
00326
00327 bool CfgHandler::endIncludeElement() {
00328 return true;
00329 }
00330
00331 bool CfgHandler::endLabelElement() {
00332 return true;
00333 }
00334
00335 bool CfgHandler::endStateElement() {
00336 return true;
00337 }
00338
00339 bool CfgHandler::endMapElement() {
00340 return true;
00341 }
00342
00343 bool CfgHandler::endEventElement() {
00344 return true;
00345 }
00346
00347 bool CfgHandler::endNextStateElement() {
00348 return true;
00349 }