MythTV  master
configuration.cpp
Go to the documentation of this file.
1 // Program Name: configuration.cpp
3 // Created : Feb. 12, 2007
4 //
5 // Purpose : Configuration file Class
6 //
7 // Copyright (c) 2007 David Blain <dblain@mythtv.org>
8 //
9 // Licensed under the GPL v2 or later, see COPYING for details
10 //
12 
13 #include <unistd.h> // for fsync
14 
15 #include <iostream>
16 
17 #include <QDir>
18 #include <QFile>
19 #include <QTextStream>
20 
21 #include "configuration.h"
22 #include "mythlogging.h"
23 #include "mythdb.h"
24 #include "mythdirs.h"
25 #include "compat.h"
26 
28 //
30 
31 XmlConfiguration::XmlConfiguration( const QString &sFileName )
32 {
33  m_sPath = GetConfDir();
34  m_sFileName = sFileName;
35 
37 }
38 
40 //
42 
44 {
45  QString sName = m_sPath + '/' + m_sFileName;
46 
47  QFile file( sName );
48 
49  if (file.exists() && m_sFileName.length()) // Ignore empty filenames
50  {
51 
52  if ( !file.open( QIODevice::ReadOnly ) )
53  return false;
54 
55  QString sErrMsg;
56  int nErrLine = 0;
57  int nErrCol = 0;
58  bool bSuccess = m_config.setContent(&file, false, &sErrMsg,
59  &nErrLine, &nErrCol );
60 
61  file.close();
62 
63  if (!bSuccess)
64  {
65  LOG(VB_GENERAL, LOG_ERR,
66  QString("Error parsing: %1 at line: %2 column: %3")
67  .arg( sName ) .arg( nErrLine ) .arg( nErrCol ));
68 
69  LOG(VB_GENERAL, LOG_ERR, QString("Error Msg: %1" ) .arg( sErrMsg ));
70  return false;
71  }
72 
73  m_rootNode = m_config.namedItem( "Configuration" );
74  }
75  else
76  {
77  m_rootNode = m_config.createElement( "Configuration" );
78  m_config.appendChild( m_rootNode );
79  }
80 
81  return true;
82 }
83 
85 //
87 
89 {
90  if (m_sFileName.isEmpty()) // Special case. No file is created
91  return true;
92 
93  QString config_temppath = m_sPath + '/' + m_sFileName + ".new";
94  QString config_filepath = m_sPath + '/' + m_sFileName;
95  QString config_origpath = m_sPath + '/' + m_sFileName + ".orig";
96 
97  QFile file(config_temppath);
98 
99  if (!file.exists())
100  {
101  QDir createDir(m_sPath);
102  if (!createDir.exists())
103  {
104  if (!createDir.mkdir(m_sPath))
105  {
106  LOG(VB_GENERAL, LOG_ERR,
107  QString("Could not create %1").arg(m_sPath));
108  return false;
109  }
110  }
111  }
112 
113  if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
114  {
115  LOG(VB_GENERAL, LOG_ERR,
116  QString("Could not open settings file %1 for writing")
117  .arg(config_temppath));
118 
119  return false;
120  }
121 
122  {
123  QTextStream ts(&file);
124  m_config.save(ts, 2);
125  }
126 
127  file.flush();
128 
129  fsync(file.handle());
130 
131  file.close();
132 
133  bool ok = true;
134  if (QFile::exists(config_filepath))
135  ok = QFile::rename(config_filepath, config_origpath);
136 
137  if (ok)
138  {
139  ok = file.rename(config_filepath);
140  if (ok)
141  QFile::remove(config_origpath);
142  else if (QFile::exists(config_origpath))
143  QFile::rename(config_origpath, config_filepath);
144  }
145 
146  if (!ok)
147  {
148  LOG(VB_GENERAL, LOG_ERR,
149  QString("Could not save settings file %1").arg(config_filepath));
150  }
151 
152  return ok;
153 }
154 
156 //
158 
159 QDomNode XmlConfiguration::FindNode( const QString &sName, bool bCreate )
160 {
161  QStringList parts = sName.split('/', QString::SkipEmptyParts);
162 
163  return FindNode( parts, m_rootNode, bCreate );
164 
165 }
166 
168 //
170 
171 QDomNode XmlConfiguration::FindNode( QStringList &sParts, QDomNode &curNode, bool bCreate )
172 {
173  if (sParts.empty())
174  return curNode;
175 
176  QString sName = sParts.front();
177  sParts.pop_front();
178 
179  QDomNode child = curNode.namedItem( sName );
180 
181  if (child.isNull() )
182  {
183  if (bCreate)
184  {
185  QDomNode newNode = m_config.createElement( sName );
186  if (!curNode.isNull())
187  child = curNode.appendChild( newNode );
188  }
189  else
190  sParts.clear();
191  }
192 
193  return FindNode( sParts, child, bCreate );
194 }
195 
197 //
199 
200 int XmlConfiguration::GetValue( const QString &sSetting, int nDefault )
201 {
202  QDomNode node = FindNode( sSetting );
203 
204  if (!node.isNull())
205  {
206  // -=>TODO: This Always assumes firstChild is a Text Node... should change
207  QDomText oText = node.firstChild().toText();
208 
209  if (!oText.isNull())
210  return oText.nodeValue().toInt();
211  }
212 
213  return nDefault;
214 }
215 
217 //
219 
220 QString XmlConfiguration::GetValue( const QString &sSetting, QString sDefault )
221 {
222  QDomNode node = FindNode( sSetting );
223 
224  if (!node.isNull())
225  {
226  // -=>TODO: This Always assumes firstChild is a Text Node... should change
227  QDomText oText = node.firstChild().toText();
228 
229  if (!oText.isNull())
230  return oText.nodeValue();
231  }
232 
233  return sDefault;
234 }
235 
237 //
239 
240 void XmlConfiguration::SetValue( const QString &sSetting, int nValue )
241 {
242  QString sValue = QString::number( nValue );
243  QDomNode node = FindNode( sSetting, true );
244 
245  if (!node.isNull())
246  {
247  QDomText textNode;
248 
249  if (node.hasChildNodes())
250  {
251  // -=>TODO: This Always assumes only child is a Text Node... should change
252  textNode = node.firstChild().toText();
253  textNode.setNodeValue( sValue );
254  }
255  else
256  {
257  textNode = m_config.createTextNode( sValue );
258  node.appendChild( textNode );
259  }
260  }
261 }
262 
264 //
266 
267 void XmlConfiguration::SetValue( const QString &sSetting, QString sValue )
268 {
269  QDomNode node = FindNode( sSetting, true );
270 
271  if (!node.isNull())
272  {
273  QDomText textNode;
274 
275  if (node.hasChildNodes())
276  {
277  // -=>TODO: This Always assumes only child is a Text Node... should change
278  textNode = node.firstChild().toText();
279  textNode.setNodeValue( sValue );
280  }
281  else
282  {
283  textNode = m_config.createTextNode( sValue );
284  node.appendChild( textNode );
285  }
286  }
287 }
288 
290 //
292 
293 void XmlConfiguration::ClearValue( const QString &sSetting )
294 {
295  QDomNode node = FindNode(sSetting);
296  if (!node.isNull())
297  {
298  QDomNode parent = node.parentNode();
299  parent.removeChild(node);
300  while (parent.childNodes().count() == 0)
301  {
302  QDomNode next_parent = parent.parentNode();
303  next_parent.removeChild(parent);
304  parent = next_parent;
305  }
306  }
307 }
308 
311 //
312 // Uses MythContext to access settings in Database
313 //
316 
318 {
319  return true;
320 }
321 
323 //
325 
327 {
328  return true;
329 }
330 
332 //
334 
335 int DBConfiguration::GetValue( const QString &sSetting, int nDefault )
336 {
337  return GetMythDB()->GetNumSetting( sSetting, nDefault );
338 }
339 
341 //
343 
344 QString DBConfiguration::GetValue( const QString &sSetting, QString sDefault )
345 {
346  return GetMythDB()->GetSetting( sSetting, sDefault );
347 }
348 
350 //
352 
353 void DBConfiguration::SetValue( const QString &sSetting, int nValue )
354 {
355  GetMythDB()->SaveSetting( sSetting, nValue );
356 
357 }
358 
360 //
362 
363 void DBConfiguration::SetValue( const QString &sSetting, QString sValue )
364 {
365  GetMythDB()->SaveSetting( sSetting, sValue );
366 }
367 
369 //
371 
372 void DBConfiguration::ClearValue( const QString &sSetting )
373 {
374  GetMythDB()->ClearSetting( sSetting );
375 }
#define fsync(FD)
Definition: compat.h:136
void SetValue(const QString &sSetting, int value) override
XmlConfiguration(const QString &sFileName)
bool Load(void) override
QDomNode FindNode(const QString &sName, bool bCreate=false)
int GetNumSetting(const QString &key, int defaultval)
Definition: mythdb.cpp:563
QString GetConfDir(void)
Definition: mythdirs.cpp:224
void ClearValue(const QString &sSetting) override
bool Save(void) override
bool Load(void) override
QString GetSetting(const QString &_key, const QString &defaultval)
Definition: mythdb.cpp:362
bool Save(void) override
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
QDomNode m_rootNode
Definition: configuration.h:59
int GetValue(const QString &sSetting, int Default) override
int GetValue(const QString &sSetting, int Default) override
bool ClearSetting(const QString &key)
Definition: mythdb.cpp:352
void ClearValue(const QString &sSetting) override
void SaveSetting(const QString &key, int newValue)
Definition: mythdb.cpp:243
MythDB * GetMythDB(void)
Definition: mythdb.cpp:46
QDomDocument m_config
Definition: configuration.h:58
void SetValue(const QString &sSetting, int value) override