CAVAPA-GUI  30.5.2014
 All Classes Namespaces Functions Variables Typedefs Enumerations Pages
keyvaluecollection.h
1 /****************************************************************************
2  * Copyright (c) 2014, Joel Kivelä, Erkki Koskenkorva, Oskari Leppäaho,
3  * Mika Lehtinen and Petri Partanen.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * * Neither the name of the copyright holders nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 ****************************************************************************/
30 #ifndef KEYVALUECOLLECTION_H
31 #define KEYVALUECOLLECTION_H
32 
33 #include <algorithm>
34 #include <array>
35 #include <cassert>
36 #include <clocale>
37 #include <map>
38 #include <string>
39 
40 #include <QColor>
41 #include <QDebug>
42 #include <QString>
43 
44 namespace cavapa_gui
45 {
52 {
53 protected:
57  std::map<std::string, std::string> keyValueMap;
58 
59 public:
64  using const_iterator = std::map<std::string, std::string>::const_iterator;
65 
70  const_iterator begin() const;
71 
76  const_iterator end() const;
77 
83  std::string get(const std::string& name) const;
84 
90  bool getBool(const std::string& name) const;
91 
97  QColor getColor(const std::string& name) const;
98 
104  QString getQString(const std::string& name) const;
105 
111  double getDouble(const std::string& name) const;
112 
118  int getInt(const std::string& name) const;
119 
127  template<typename ValueType, int N>
128  std::array<ValueType, N> getValues(const std::string& name) const
129  {
130  static_assert(std::is_same<ValueType, double>::value
131  || std::is_same<ValueType, int>::value,
132  "Invalid template type argument for getValues");
133  static_assert(N > 0, "Invalid template integer argument for getValues");
134 
135  //Make sure the decimal separator is dot and not comma!
136  setlocale(LC_NUMERIC, "C");
137 
138  std::array<ValueType, N> values;
139  QStringList parts = getQString(name).split(';');
140  if (parts.size() != N)
141  {
142  parts = getQString(name).split(',');
143  if (parts.size() != N)
144  {
145  parts.clear();
146  for (int i = 0; i < N; ++i)
147  {
148  parts.append("0");
149  }
150  }
151  }
152  assert(parts.size() == N);
153  for (int i = 0; i < N; i++)
154  {
155  std::string current = parts.at(i).toStdString();
156  try
157  {
158  if (std::is_same<ValueType, int>::value)
159  {
160  values[i] = std::stoi(current);
161  }
162  else if (std::is_same<ValueType, double>::value)
163  {
164  values[i] = std::stod(current);
165  }
166  }
167  catch (const std::invalid_argument&)
168  {
169  qDebug() << "The key"
170  << QString::fromStdString(name)
171  << "was not convertible to numeric value:"
172  << QString::fromStdString(current)
173  << "(setting to 0)";
174  values[i] = 0;
175  }
176  catch (const std::out_of_range&)
177  {
178  qDebug() << "The key"
179  << QString::fromStdString(name)
180  << "was out of range:"
181  << QString::fromStdString(current)
182  << "(setting to 0)";
183  values[i] = 0;
184  }
185  }
186  return values;
187  }
188 
194  void set(const std::string& name, const std::string& value);
195 
201  void setBool(const std::string& name, bool value);
202 
208  void setColor(const std::string& name, const QColor& value);
209 
215  void setInt(const std::string& name, int value);
216 
224  template<typename... T>
225  void setValues(const std::string& name, T... values)
226  {
227  auto vals = {values...};
228  std::string str;
229  std::string separator;
230  for (auto v : vals)
231  {
232  std::string piece = std::to_string(v);
233 
234  //std::to_string uses a comma instead of dot even though
235  //std::stod requires dot, so we convert the comma to dot here.
236  std::replace(piece.begin(), piece.end(), ',', '.');
237 
238  str += separator + piece;
239  separator = ";";
240  }
241  set(name, str);
242  }
243 
249  void setQString(const std::string& name, const QString& value);
250 
257  bool trySet(const std::string& name, const std::string& value);
258 };
259 } //namespace cavapa_gui
260 
261 #endif // KEYVALUECOLLECTION_H
QColor getColor(const std::string &name) const
Gets the value of the specified key as a QColor.
Definition: keyvaluecollection.cpp:78
double getDouble(const std::string &name) const
Gets the value of the specified key as a double.
Definition: keyvaluecollection.cpp:91
void setBool(const std::string &name, bool value)
Sets the value of the specified key as a bool.
Definition: keyvaluecollection.cpp:119
const_iterator begin() const
Returns a const iterator to the beginning of the collection.
Definition: keyvaluecollection.cpp:38
void setColor(const std::string &name, const QColor &value)
Sets the value of the specified key as a QColor.
Definition: keyvaluecollection.cpp:114
Represents a collection of key-value pairs.
Definition: keyvaluecollection.h:51
void setInt(const std::string &name, int value)
Sets the value of the specified key as an int.
Definition: keyvaluecollection.cpp:131
std::map< std::string, std::string > keyValueMap
Contains the key-value mappings in an std::map.
Definition: keyvaluecollection.h:57
std::array< ValueType, N > getValues(const std::string &name) const
Gets an array of values from the specified key.
Definition: keyvaluecollection.h:128
void setQString(const std::string &name, const QString &value)
Sets the value of the specified key as a QString.
Definition: keyvaluecollection.cpp:136
bool trySet(const std::string &name, const std::string &value)
Attempts to set the value of the specified key.
Definition: keyvaluecollection.cpp:142
int getInt(const std::string &name) const
Gets the value of the specified key as an integer.
Definition: keyvaluecollection.cpp:96
bool getBool(const std::string &name) const
Gets the value of the specified key as a bool.
Definition: keyvaluecollection.cpp:61
void set(const std::string &name, const std::string &value)
Sets the value of the specified key.
Definition: keyvaluecollection.cpp:101
void setValues(const std::string &name, T...values)
Sets the value of the specified key as an array.
Definition: keyvaluecollection.h:225
const_iterator end() const
Returns a const iterator to the end of the collection.
Definition: keyvaluecollection.cpp:43
std::map< std::string, std::string >::const_iterator const_iterator
Provides a bidirectional iterator that can read a const element in the collection.
Definition: keyvaluecollection.h:64
QString getQString(const std::string &name) const
Gets the value of the specified key as a QString.
Definition: keyvaluecollection.cpp:86