User interface update
[qtmeetings] / src / Domain / Configuration / Configuration.cpp
1 #include "Configuration.h"
2 #include "ConnectionSettings.h"
3 #include "StartupSettings.h"
4 #include "DisplaySettings.h"
5 #include "DateTimeSettings.h"
6 #include "Room.h"
7 #include <QDomDocument>
8 #include <QDomElement>
9 #include <QDomNode>
10 #include <QFile>
11 #include <QCryptographicHash>
12
13 #include <QtDebug>
14 #include <QString>
15 #include <QUrl>
16
17 Configuration * Configuration::sInstance = 0;
18 QString Configuration::sConfigurationPath = "/etc/QtMeetings.conf";
19
20 Configuration::Configuration() :
21         iConnectionSettings(0), iStartupSettings(0), iDisplaySettings(0),
22                         iDateTimeSettings(0) {
23 }
24
25 Configuration::~Configuration() {
26         delete iConnectionSettings;
27         delete iStartupSettings;
28         delete iDisplaySettings;
29         delete iDateTimeSettings;
30         while (!iRooms.isEmpty()) {
31                 delete iRooms.takeFirst();
32         }
33 }
34
35 Configuration* Configuration::instance() {
36         if (sInstance == 0) {
37                 qDebug() << "HERE";
38                 sInstance = new Configuration();
39                 sInstance->readFromXML(sConfigurationPath);
40                 if (!sInstance) {
41                         qDebug() << "FATAL: Configuration cannot be read from:"
42                                         << Configuration::sConfigurationPath;
43                 }
44         }
45         return sInstance;
46 }
47
48 /*ConnectionSettings* Configuration::connectionSettings()
49  {
50  return iConnectionSettings;
51  }*/
52
53 StartupSettings * Configuration::startupSettings() {
54         return iStartupSettings;
55 }
56
57 DisplaySettings * Configuration::displaySettings() {
58         return iDisplaySettings;
59 }
60
61 DateTimeSettings * Configuration::dateTimeSettings() {
62         return iDateTimeSettings;
63 }
64
65 Room* Configuration::defaultRoom() {
66         // default room is stored as the first element of the list
67         return (iRooms.count() == 0) ? 0 : iRooms.at(0);
68 }
69
70 QString Configuration::languageCode() {
71         return iLanguageCode;
72 }
73
74 QList<Room*> Configuration::rooms() {
75         return iRooms;
76 }
77
78 QByteArray Configuration::adminPassword() {
79         return iAdminPassword;
80 }
81 QUrl Configuration::getServerUrl() {
82         return iConnectionSettings->serverUrl();
83 }
84
85 QString Configuration::getUsername() {
86         return iConnectionSettings->username();
87 }
88 QString Configuration::getPassword() {
89         return iConnectionSettings->password();
90 }
91
92 unsigned int Configuration::getRefreshinterval() {
93         return iConnectionSettings->refreshInterval();
94 }
95
96 void Configuration::setServerUrl(QUrl serverUrl) {
97         iConnectionSettings->setServerUrl(serverUrl);
98 }
99 void Configuration::setUsername(QString username) {
100         iConnectionSettings->setUsername(username);
101 }
102 void Configuration::setPassword(QString password) {
103         iConnectionSettings->setPassword(password);
104 }
105 void Configuration::setRefreshinterval(unsigned int refreshinterval) {
106         iConnectionSettings->setRefreshInterval(refreshinterval);
107 }
108
109 void Configuration::save() {
110         QDomDocument doc;
111         QFile file(sConfigurationPath);
112         if (!file.open(QIODevice::ReadWrite)) {
113                 return;
114         }
115
116         if (!doc.setContent(&file)) {
117                 file.close();
118                 return;
119         }
120
121         QDomElement root = doc.documentElement();
122         // Save all attributes to document
123
124         saveAdminPassword(root);
125
126         for (QDomNode node = root.firstChild(); !node.isNull(); node
127                         = node.nextSibling()) {
128                 QDomElement e = node.toElement();
129                 QString tagName = e.tagName().toLower();
130                 if (tagName == QString("connection")) {
131                         saveConnectionSettings(node);
132                 } else if (tagName == QString("rooms")) {
133                         saveRooms(node);
134                 } else if (tagName == QString("language")) {
135                         saveLanguageCode(node);
136                 } else if (tagName == QString("startup")) {
137                         saveStartupSettings(node);
138                 } else if (tagName == QString("display")) {
139                         saveDisplaySettings(node);
140                 } else if (tagName == QString("daylight_saving_time")) {
141                         saveDateTimeSettings(node);
142                 }
143         }
144
145         //! Empty the file from previous content and write again with new one
146         file.resize(0);
147         file.write(doc.toByteArray(4)); //! 4 as intent
148
149         file.close();
150         emit configurationChanged();
151 }
152
153 void Configuration::saveConnectionSettings(const QDomNode &aXML) {
154         QDomElement e = aXML.firstChild().toElement();
155         QString tagName = e.tagName().toLower();
156         qDebug() << tagName;
157         for (QDomNode node = aXML.firstChild(); !node.isNull(); node
158                         = node.nextSibling()) {
159                 QDomElement e = node.toElement();
160                 QString tagName = e.tagName().toLower();
161                 qDebug() << tagName;
162                 if (tagName == QString("serverurl")) {
163                         QDomText t = node.ownerDocument().createTextNode(
164                                         iConnectionSettings->serverUrl().toString());
165                         if (e.hasChildNodes()) {
166
167                                 e.replaceChild(t, e.firstChild());
168                         } else {
169                                 e.appendChild(t);
170                         }
171                 } else if (tagName == QString("username")) {
172                         QDomText t = node.ownerDocument().createTextNode(
173                                         iConnectionSettings->username());
174                         if (e.hasChildNodes()) {
175                                 e.replaceChild(t, e.firstChild());
176                         } else {
177                                 e.appendChild(t);
178                         }
179
180                 } else if (tagName == QString("password")) {
181                         QDomText t = node.ownerDocument().createTextNode(
182                                         iConnectionSettings->password());
183                         if (e.hasChildNodes()) {
184                                 e.replaceChild(t, e.firstChild());
185                         } else {
186                                 e.appendChild(t);
187                         }
188                 } else if (tagName == QString("refreshinterval")) {
189                         QString s = QString("%1").arg(
190                                         iConnectionSettings->refreshInterval());
191                         QDomText t = node.ownerDocument().createTextNode(s);
192                         e.replaceChild(t, e.firstChild());
193                 }
194         }
195 }
196
197 void Configuration::saveRooms(const QDomNode &aXML) {
198         //! List of rooms must be cleared and rewritten again
199         QDomDocument doc = aXML.ownerDocument();
200         QDomNode root = aXML;
201
202         // Remove child nodes...
203         int count = root.childNodes().count();
204         QDomNode node = root.firstChild();
205         QDomNode next;
206         for (int i = 0; i < count; i++) {
207                 qDebug() << "remove " << node.toElement().text();
208                 next = node.nextSibling();
209                 node = root.removeChild(node);
210                 node = next;
211         }
212
213         node = aXML;
214         QList<Room*>::iterator i;
215         for (i = iRooms.begin(); i != iRooms.end(); ++i) {
216                 QDomElement tag = doc.createElement("room");
217                 node.appendChild(tag);
218
219                 // First room in the list is a dafault room
220                 if (i == iRooms.begin()) {
221                         tag.setAttribute("default", "true");
222                 }
223
224                 QDomElement ename = doc.createElement("name");
225                 QDomText tname = node.ownerDocument().createTextNode((*i)->name());
226                 ename.appendChild(tname);
227                 tag.appendChild(ename);
228
229                 QDomElement eaddress = doc.createElement("address");
230                 QDomText taddress =
231                                 node.ownerDocument().createTextNode((*i)->address());
232                 eaddress.appendChild(taddress);
233                 tag.appendChild(eaddress);
234         }
235 }
236
237 void Configuration::saveLanguageCode(const QDomNode &aXML) {
238         QDomElement e = aXML.toElement();
239         e.setAttribute("code", languageCode());
240 }
241
242 void Configuration::saveStartupSettings(const QDomNode &aXML) {
243         QDomElement e = aXML.toElement();
244
245         for (QDomNode node = aXML.firstChild(); !node.isNull(); node
246                         = node.nextSibling()) {
247                 e = node.toElement();
248                 QString tagName = e.tagName().toLower();
249
250                 if (tagName == QString("powersaving")) {
251                         (iStartupSettings->isPowersavingEnabled() ? e.setAttribute(
252                                         "enabled", "true") : e.setAttribute("enabled", "false"));
253
254                         e.setAttribute("on", iStartupSettings->turnOnAt().toString("hh:mm"));
255                         e.setAttribute("off", iStartupSettings->turnOffAt().toString(
256                                         "hh:mm"));
257                 }
258         }
259 }
260
261 void Configuration::saveDisplaySettings(const QDomNode &aXML) {
262         for (QDomNode node = aXML.firstChild(); !node.isNull(); node
263                         = node.nextSibling()) {
264                 QDomElement e = node.toElement();
265                 QString tagName = e.tagName().toLower();
266
267                 if (tagName == QString("schedule")) {
268                         for (QDomNode scheduleNode = node.firstChild(); !scheduleNode.isNull(); scheduleNode
269                                         = scheduleNode.nextSibling()) {
270                                 QDomElement scheduleElem = scheduleNode.toElement();
271                                 tagName = scheduleElem.tagName().toLower();
272
273                                 if (tagName == QString("week")) {
274                                         scheduleElem.setAttribute("days",
275                                                         iDisplaySettings->daysInSchedule());
276                                 } else if (tagName == QString("day")) {
277                                         scheduleElem.setAttribute("startsat",
278                                                         iDisplaySettings->dayStartsAt().toString("hh:mm"));
279                                         scheduleElem.setAttribute("endsat",
280                                                         iDisplaySettings->dayEndsAt().toString("hh:mm"));
281                                 }
282                         } // end of for
283                 } // end of schedule
284                 else if (tagName == QString("dateformat")) {
285                         QDomText t = node.ownerDocument().createTextNode(
286                                         iDisplaySettings->dateFormat());
287                         e.replaceChild(t, e.firstChild());
288                 } else if (tagName == QString("timeformat")) {
289                         QDomText t = node.ownerDocument().createTextNode(
290                                         iDisplaySettings->timeFormat());
291                         e.replaceChild(t, e.firstChild());
292                 } else if (tagName == QString("screensaver")) {
293                         QString s = QString("%1").arg(iDisplaySettings->screensaver());
294                         QDomText t = node.ownerDocument().createTextNode(s);
295                         e.replaceChild(t, e.firstChild());
296                 }
297         }
298 }
299
300 void Configuration::saveDateTimeSettings(const QDomNode &aXML) {
301         for (QDomNode node = aXML.firstChild(); !node.isNull(); node
302                         = node.nextSibling()) {
303                 QDomElement e = node.toElement();
304                 QString tagName = e.tagName().toLower();
305
306                 if (tagName == QString("dayofweek")) {
307                         QDomText t = node.ownerDocument().createTextNode(
308                                         iDateTimeSettings->switchDay());
309                         e.replaceChild(t, e.firstChild());
310                 } else if (tagName == QString("StandardTimeChangeMoment")) {
311                         QDomText t =
312                                         node.ownerDocument().createTextNode(
313                                                         iDateTimeSettings->STDDateTime().toString(
314                                                                         "ddMMyyyyhhmmss"));
315                         e.replaceChild(t, e.firstChild());
316                 } else if (tagName == QString("DaylightSaveTimeChangeMoment")) {
317                         QDomText t =
318                                         node.ownerDocument().createTextNode(
319                                                         iDateTimeSettings->DSTDateTime().toString(
320                                                                         "ddMMyyyyhhmmss"));
321                         e.replaceChild(t, e.firstChild());
322                 }
323         }
324 }
325
326 void Configuration::saveAdminPassword(const QDomNode &aXML) {
327         QDomElement e = aXML.toElement();
328         e.setAttribute("password", QString(adminPassword()));
329 }
330
331 void Configuration::readFromXML(const QString &aPath) {
332         QDomDocument doc;
333         QFile file(aPath);
334
335         if (!file.open(QIODevice::ReadOnly)) {
336                 return;
337         }
338         if (!doc.setContent(&file)) {
339                 file.close();
340                 return;
341         }
342         file.close();
343
344         QDomElement root = doc.documentElement();
345         // check if the file is the one we need
346         if (root.tagName().toLower() != QString("configuration")) {
347                 return;
348         }
349
350         iAdminPassword = /*Configuration::*/readAdminPassword(root);
351
352         for (QDomNode node = root.firstChild(); !node.isNull(); node
353                         = node.nextSibling()) {
354                 QDomElement e = node.toElement();
355                 QString tagName = e.tagName().toLower();
356
357                 if (tagName == QString("connection")) {
358                         iConnectionSettings = readConnectionSettings(node);
359
360                 } else if (tagName == QString("rooms")) {
361                         iRooms = readRooms(node);
362                 } else if (tagName == QString("language")) {
363                         iLanguageCode = readLanguageCode(node);
364                 } else if (tagName == QString("startup")) {
365                         iStartupSettings = readStartupSettings(node);
366                 } else if (tagName == QString("display")) {
367                         iDisplaySettings = readDisplaySettings(node);
368                 } else if (tagName == QString("daylight_saving_time")) {
369                         iDateTimeSettings = /*Configuration::*/readDateTimeSettings(node);
370                 }
371         }
372 }
373
374 ConnectionSettings* Configuration::readConnectionSettings(const QDomNode &aXML) {
375         QString server, username, password;
376         unsigned int interval = Configuration::sDefaultInterval;
377
378         for (QDomNode node = aXML.firstChild(); !node.isNull(); node
379                         = node.nextSibling()) {
380                 QDomElement e = node.toElement();
381                 QString tagName = e.tagName().toLower();
382
383                 if (tagName == QString("serverurl")) {
384                         server = e.text();
385                 } else if (tagName == QString("username")) {
386                         username = e.text();
387                 } else if (tagName == QString("password")) {
388                         password = e.text();
389                 } else if (tagName == QString("refreshinterval")) {
390                         bool success = false;
391                         unsigned int intervalTMP = e.text().toUInt(&success);
392                         if (success) {
393                                 interval = intervalTMP;
394                         }
395                 }
396         }
397
398         return new ConnectionSettings(server, username, password, interval);
399 }
400
401 QList<Room*> Configuration::readRooms(const QDomNode &aXML) {
402         QList<Room*> rooms;
403
404         for (QDomNode node = aXML.firstChild(); !node.isNull(); node
405                         = node.nextSibling()) {
406                 QDomElement e = node.toElement();
407                 QString tagName = e.tagName().toLower();
408
409                 if (tagName == QString("room")) {
410                         QString name, address;
411
412                         for (QDomNode roomNode = node.firstChild(); !roomNode.isNull(); roomNode
413                                         = roomNode.nextSibling()) {
414                                 QDomElement roomElem = roomNode.toElement();
415                                 tagName = roomElem.tagName().toLower();
416                                 if (tagName == QString("name")) {
417                                         name = roomElem.text();
418                                 } else if (tagName == QString("address")) {
419                                         address = roomElem.text();
420                                 }
421                         }
422                         Room* room = new Room(name, address);
423                         QString defaultAttr = e.attribute("default").toLower();
424                         if (defaultAttr == QString("true")) {
425                                 rooms.insert(0, room);
426                         } else {
427                                 rooms.append(room);
428                         }
429                 }
430         }
431
432         return rooms;
433 }
434
435 QString Configuration::readLanguageCode(const QDomNode &aXML) {
436         QDomElement e = aXML.toElement();
437         QString tagName = e.tagName().toLower();
438
439         if (e.hasAttribute("code")) {
440                 return e.attribute("code");
441         } else {
442                 // default language is English
443                 return "EN";
444         }
445 }
446
447 StartupSettings * Configuration::readStartupSettings(const QDomNode &aXML) {
448         QDomElement e = aXML.toElement();
449
450         bool isPowersavingEnabled = false;
451         QTime turnOnAt, turnOffAt;
452
453         for (QDomNode node = aXML.firstChild(); !node.isNull(); node
454                         = node.nextSibling()) {
455                 e = node.toElement();
456                 QString tagName = e.tagName().toLower();
457
458                 if (tagName == QString("powersaving")) {
459                         if (e.hasAttribute("enabled") && e.attribute("enabled") == QString(
460                                         "true")) {
461                                 isPowersavingEnabled = true;
462                         }
463
464                         if (e.hasAttribute("on")) {
465                                 QString on = e.attribute("on");
466                                 turnOnAt = QTime::fromString(on, "hh:mm");
467
468                         }
469
470                         if (e.hasAttribute("off")) {
471                                 QString off = e.attribute("off");
472                                 turnOffAt = QTime::fromString(off, "hh:mm");
473                         }
474                 }
475         }
476
477         return new StartupSettings(isPowersavingEnabled, turnOnAt, turnOffAt);
478 }
479
480 DisplaySettings * Configuration::readDisplaySettings(const QDomNode &aXML) {
481         DisplaySettings::DaysInSchedule daysInSchedule =
482                         DisplaySettings::WeekdaysInSchedule;
483         QTime dayStartsAt, dayEndsAt;
484         DisplaySettings::DateFormat dateformat = DisplaySettings::ShortDateFormat;
485         DisplaySettings::TimeFormat timeformat =
486                         DisplaySettings::TwentyFourHoursTimeFormat;
487         int screensaver = 1; //! Default value for screensaver wait time
488
489         for (QDomNode node = aXML.firstChild(); !node.isNull(); node
490                         = node.nextSibling()) {
491                 QDomElement e = node.toElement();
492                 QString tagName = e.tagName().toLower();
493
494                 if (tagName == QString("schedule")) {
495                         for (QDomNode scheduleNode = node.firstChild(); !scheduleNode.isNull(); scheduleNode
496                                         = scheduleNode.nextSibling()) {
497                                 QDomElement scheduleElem = scheduleNode.toElement();
498                                 tagName = scheduleElem.tagName().toLower();
499
500                                 if (tagName == QString("week")) {
501                                         if (scheduleElem.hasAttribute("days")) {
502                                                 // default value is 5, only other supported possibility is 7
503                                                 bool success = false;
504                                                 unsigned int days =
505                                                                 scheduleElem.attribute("days").toUInt(&success);
506                                                 daysInSchedule
507                                                                 = (success && days == 7) ? DisplaySettings::WholeWeekInSchedule
508                                                                                 : DisplaySettings::WeekdaysInSchedule;
509                                         }
510
511                                 } else if (tagName == QString("day")) {
512                                         if (scheduleElem.hasAttribute("startsat")) {
513                                                 QString time = scheduleElem.attribute("startsat");
514                                                 dayStartsAt = QTime::fromString(time, "hh:mm");
515                                         }
516                                         if (scheduleElem.hasAttribute("endsat")) {
517                                                 QString time = scheduleElem.attribute("endsat");
518                                                 dayEndsAt = QTime::fromString(time, "hh:mm");
519                                         }
520
521                                 }
522                         } // end of for
523                 } // end of schedule
524                 else if (tagName == QString("dateformat")) {
525                         //! Not able to display long format anyway at the moment
526                         /*
527                          if ( e.text() == QObject::tr( "dddd d MMMM yyyy" ) )
528                          dateformat = DisplaySettings::LongDateFormat;
529                          else
530                          dateformat = DisplaySettings::ShortDateFormat;
531                          */
532                         dateformat = DisplaySettings::ShortDateFormat;
533                 } else if (tagName == QString("timeformat")) {
534                         //! Not able to display "TwelveHoursTimeFormat" anyway at the moment
535                         /*
536                          if ( e.text() == QObject::tr( "hh:mm ap" ) )
537                          timeformat = DisplaySettings::TwelveHoursTimeFormat;
538                          else
539                          timeformat = DisplaySettings::TwentyFourHoursTimeFormat;
540                          */
541                         timeformat = DisplaySettings::TwentyFourHoursTimeFormat;
542                 } else if (tagName == QString("screensaver")) {
543                         bool success = false;
544                         unsigned int screensaverTMP = e.text().toUInt(&success);
545                         if (success) {
546                                 screensaver = screensaverTMP;
547                         }
548                 }
549         }
550
551         return new DisplaySettings(dateformat, timeformat, daysInSchedule,
552                         dayStartsAt, dayEndsAt, screensaver);
553 }
554
555 DateTimeSettings * Configuration::readDateTimeSettings(const QDomNode &aXML) {
556         // Set defaults..
557         QDateTime standardTimeChangeMoment = QDateTime::fromString(
558                         "05.10.2009 04:00:00", "dd'.'MM'.'yyyy' 'hh:mm:ss");
559         QDateTime daylightSaveTimeChangeMoment = QDateTime::fromString(
560                         "01.04.2010 03:00:00", "dd'.'MM'.'yyyy' 'hh:mm:ss");
561         DateTimeSettings::weekDay dayOfWeek = DateTimeSettings::Sunday;
562
563         for (QDomNode node = aXML.firstChild(); !node.isNull(); node
564                         = node.nextSibling()) {
565                 QDomElement e = node.toElement();
566                 QString tagName = e.tagName().toLower();
567
568                 if (tagName == QString("dayofweek")) {
569                         qDebug() << "Configuration::readDateTimeSettings: " + e.text();
570
571                         bool success = false;
572                         unsigned int weekDayTmp = e.text().toUInt(&success);
573                         if (success && weekDayTmp < 7) {
574                                 dayOfWeek = (DateTimeSettings::weekDay) weekDayTmp;
575                         }
576                 } else if (tagName == QString("standardtimechangemoment")) {
577                         standardTimeChangeMoment = QDateTime::fromString(e.text(),
578                                         "dd'.'MM'.'yyyy' 'hh:mm:ss");
579                         qDebug() << "Configuration::readDateTimeSettings: "
580                                         + standardTimeChangeMoment.toString("dd.MM.yyyy hh:mm:ss");
581                 } else if (tagName == QString("daylightsavetimechangemoment")) {
582                         daylightSaveTimeChangeMoment = QDateTime::fromString(e.text(),
583                                         "dd'.'MM'.'yyyy' 'hh:mm:ss");
584                         qDebug() << "Configuration::readDateTimeSettings: "
585                                         + daylightSaveTimeChangeMoment.toString(
586                                                         "dd.MM.yyyy hh:mm:ss");
587                 }
588         }
589
590         return new DateTimeSettings(standardTimeChangeMoment,
591                         daylightSaveTimeChangeMoment, dayOfWeek);
592 }
593
594 QByteArray Configuration::readAdminPassword(const QDomNode &aXML) {
595         QDomElement e = aXML.toElement();
596         QString tagName = e.tagName().toLower();
597         if (e.hasAttribute("password")) {
598                 QString pw = e.attribute("password");
599                 // Check if the password is default uncrypted "admin"
600
601                 int x = QString::compare(pw, "admin", Qt::CaseInsensitive);  // x == 0
602
603                 if (x == 0) {
604                         // uncrypted password needs to be encoded
605                         QCryptographicHash *hash = new QCryptographicHash(
606                                         QCryptographicHash::Md5);
607                         hash->addData(pw.toUtf8());
608                         pw = QString(hash->result());
609                         delete hash;
610                         return (pw.toAscii()).toHex();
611                 }
612
613                 return (pw.toAscii());
614
615         } else {
616                 return 0;
617         }
618 }
619
620 void Configuration::setRooms(const QList<Room*> aRooms) {
621         iRooms = aRooms;
622 }
623
624 QString Configuration::hashPassword(const QString aPassword) {
625         QCryptographicHash *hash = new QCryptographicHash(QCryptographicHash::Md5);
626         hash->addData(aPassword.toUtf8());
627         QByteArray password = hash->result();
628         delete hash;
629
630         return QString(password);
631 }