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.isEmpty()) // 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 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
162  QStringList parts = sName.split('/', QString::SkipEmptyParts);
163 #else
164  QStringList parts = sName.split('/', Qt::SkipEmptyParts);
165 #endif
166 
167  return FindNode( parts, m_rootNode, bCreate );
168 
169 }
170 
172 //
174 
175 QDomNode XmlConfiguration::FindNode( QStringList &sParts, QDomNode &curNode, bool bCreate )
176 {
177  if (sParts.empty())
178  return curNode;
179 
180  QString sName = sParts.front();
181  sParts.pop_front();
182 
183  QDomNode child = curNode.namedItem( sName );
184 
185  if (child.isNull() )
186  {
187  if (bCreate)
188  {
189  QDomNode newNode = m_config.createElement( sName );
190  if (!curNode.isNull())
191  child = curNode.appendChild( newNode );
192  }
193  else
194  sParts.clear();
195  }
196 
197  return FindNode( sParts, child, bCreate );
198 }
199 
201 //
203 
204 int XmlConfiguration::GetValue( const QString &sSetting, int nDefault )
205 {
206  QDomNode node = FindNode( sSetting );
207 
208  if (!node.isNull())
209  {
210  // -=>TODO: This Always assumes firstChild is a Text Node... should change
211  QDomText oText = node.firstChild().toText();
212 
213  if (!oText.isNull())
214  return oText.nodeValue().toInt();
215  }
216 
217  return nDefault;
218 }
219 
221 //
223 
224 QString XmlConfiguration::GetValue( const QString &sSetting, QString sDefault )
225 {
226  QDomNode node = FindNode( sSetting );
227 
228  if (!node.isNull())
229  {
230  // -=>TODO: This Always assumes firstChild is a Text Node... should change
231  QDomText oText = node.firstChild().toText();
232 
233  if (!oText.isNull())
234  return oText.nodeValue();
235  }
236 
237  return sDefault;
238 }
239 
241 //
243 
244 void XmlConfiguration::SetValue( const QString &sSetting, int nValue )
245 {
246  QString sValue = QString::number( nValue );
247  QDomNode node = FindNode( sSetting, true );
248 
249  if (!node.isNull())
250  {
251  QDomText textNode;
252 
253  if (node.hasChildNodes())
254  {
255  // -=>TODO: This Always assumes only child is a Text Node... should change
256  textNode = node.firstChild().toText();
257  textNode.setNodeValue( sValue );
258  }
259  else
260  {
261  textNode = m_config.createTextNode( sValue );
262  node.appendChild( textNode );
263  }
264  }
265 }
266 
268 //
270 
271 void XmlConfiguration::SetValue( const QString &sSetting, QString sValue )
272 {
273  QDomNode node = FindNode( sSetting, true );
274 
275  if (!node.isNull())
276  {
277  QDomText textNode;
278 
279  if (node.hasChildNodes())
280  {
281  // -=>TODO: This Always assumes only child is a Text Node... should change
282  textNode = node.firstChild().toText();
283  textNode.setNodeValue( sValue );
284  }
285  else
286  {
287  textNode = m_config.createTextNode( sValue );
288  node.appendChild( textNode );
289  }
290  }
291 }
292 
294 //
296 
297 void XmlConfiguration::ClearValue( const QString &sSetting )
298 {
299  QDomNode node = FindNode(sSetting);
300  if (!node.isNull())
301  {
302  QDomNode parent = node.parentNode();
303  parent.removeChild(node);
304  while (parent.childNodes().count() == 0)
305  {
306  QDomNode next_parent = parent.parentNode();
307  next_parent.removeChild(parent);
308  parent = next_parent;
309  }
310  }
311 }
312 
315 //
316 // Uses MythContext to access settings in Database
317 //
320 
322 {
323  return true;
324 }
325 
327 //
329 
331 {
332  return true;
333 }
334 
336 //
338 
339 int DBConfiguration::GetValue( const QString &sSetting, int nDefault )
340 {
341  return GetMythDB()->GetNumSetting( sSetting, nDefault );
342 }
343 
345 //
347 
348 QString DBConfiguration::GetValue( const QString &sSetting, QString sDefault )
349 {
350  return GetMythDB()->GetSetting( sSetting, sDefault );
351 }
352 
354 //
356 
357 void DBConfiguration::SetValue( const QString &sSetting, int nValue )
358 {
359  GetMythDB()->SaveSetting( sSetting, nValue );
360 
361 }
362 
364 //
366 
367 void DBConfiguration::SetValue( const QString &sSetting, QString sValue )
368 {
369  GetMythDB()->SaveSetting( sSetting, sValue );
370 }
371 
373 //
375 
376 void DBConfiguration::ClearValue( const QString &sSetting )
377 {
378  GetMythDB()->ClearSetting( sSetting );
379 }
XmlConfiguration::Save
bool Save(void) override
Definition: configuration.cpp:88
XmlConfiguration::m_sFileName
QString m_sFileName
Definition: configuration.h:56
mythdb.h
XmlConfiguration::GetValue
int GetValue(const QString &sSetting, int Default) override
Definition: configuration.cpp:204
arg
arg(title).arg(filename).arg(doDelete))
DBConfiguration::SetValue
void SetValue(const QString &sSetting, int value) override
Definition: configuration.cpp:357
DBConfiguration::GetValue
int GetValue(const QString &sSetting, int Default) override
Definition: configuration.cpp:339
DBConfiguration::Save
bool Save(void) override
Definition: configuration.cpp:330
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
XmlConfiguration::m_rootNode
QDomNode m_rootNode
Definition: configuration.h:59
GetMythDB
MythDB * GetMythDB(void)
Definition: mythdb.cpp:45
build_compdb.file
file
Definition: build_compdb.py:55
mythdirs.h
MythDB::ClearSetting
bool ClearSetting(const QString &key)
Definition: mythdb.cpp:359
XmlConfiguration::m_config
QDomDocument m_config
Definition: configuration.h:58
mythlogging.h
GetConfDir
QString GetConfDir(void)
Definition: mythdirs.cpp:224
XmlConfiguration::SetValue
void SetValue(const QString &sSetting, int value) override
Definition: configuration.cpp:244
MythDB::GetNumSetting
int GetNumSetting(const QString &key, int defaultval)
Definition: mythdb.cpp:570
compat.h
DBConfiguration::ClearValue
void ClearValue(const QString &sSetting) override
Definition: configuration.cpp:376
DBConfiguration::Load
bool Load(void) override
Definition: configuration.cpp:321
XmlConfiguration::XmlConfiguration
XmlConfiguration(const QString &sFileName)
Definition: configuration.cpp:31
MythDB::GetSetting
QString GetSetting(const QString &_key, const QString &defaultval)
Definition: mythdb.cpp:369
XmlConfiguration::FindNode
QDomNode FindNode(const QString &sName, bool bCreate=false)
Definition: configuration.cpp:159
XmlConfiguration::Load
bool Load(void) override
Definition: configuration.cpp:43
configuration.h
MythDB::SaveSetting
void SaveSetting(const QString &key, int newValue)
Definition: mythdb.cpp:242
XmlConfiguration::ClearValue
void ClearValue(const QString &sSetting) override
Definition: configuration.cpp:297
fsync
#define fsync(FD)
Definition: compat.h:136
XmlConfiguration::m_sPath
QString m_sPath
Definition: configuration.h:55