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