MythTV  master
profilegroup.cpp
Go to the documentation of this file.
1 #include "recordingprofile.h"
2 #include "videosource.h"
3 #include "profilegroup.h"
4 #include "mythdb.h"
5 #include "mythuihelper.h"
6 #include "cardutil.h"
7 
9 {
10  QString idTag(":WHEREID");
11  QString query("id = " + idTag);
12 
13  bindings.insert(idTag, m_parent.getProfileNum());
14 
15  return query;
16 }
17 
19 {
20  QString idTag(":SETID");
21  QString colTag(":SET" + GetColumnName().toUpper());
22 
23  QString query("id = " + idTag + ", " +
24  GetColumnName() + " = " + colTag);
25 
26  bindings.insert(idTag, m_parent.getProfileNum());
27  bindings.insert(colTag, m_user->GetDBValue());
28 
29  return query;
30 }
31 
33 {
34  QStringList hostnames;
35  ProfileGroup::getHostNames(&hostnames);
36  foreach (auto & hostname, hostnames)
37  this->addSelection(hostname);
38 }
39 
41 {
42  // This must be first because it is needed to load/save the other settings
43  addChild(m_id = new ID());
44  addChild(m_isDefault = new Is_default(*this));
45 
46  setLabel(tr("Profile Group"));
47  addChild(m_name = new Name(*this));
48  auto *cardInfo = new CardInfo(*this);
49  addChild(cardInfo);
50  CardType::fillSelections(cardInfo);
51  m_host = new HostName(*this);
54 };
55 
56 void ProfileGroup::loadByID(int profileId) {
57  m_id->setValue(profileId);
58  Load();
59 }
60 
62 {
63  // We need separate profiles for different V4L2 card types
64  QStringList existing;
66  query.prepare("SELECT DISTINCT cardtype FROM profilegroups");
67 
68  if (!query.exec())
69  {
70  MythDB::DBError("ProfileGroup::createMissingDynamicProfiles", query);
71  return false;
72  }
73 
74  while (query.next())
75  existing.push_back(query.value(0).toString());
76 
77 
78  const uint num_profiles = 4;
79  const QString profile_names[num_profiles] = { "Default", "Live TV",
80  "High Quality",
81  "Low Quality" };
82 
84 
85  for (auto Itype = cardtypes.begin();
86  Itype != cardtypes.end(); ++Itype)
87  {
88  if (Itype.key().startsWith("V4L2:") && existing.indexOf(Itype.key()) == -1)
89  {
90  // Add dynamic profile group
91  query.prepare("INSERT INTO profilegroups SET name = "
92  ":CARDNAME, cardtype = :CARDTYPE, is_default = 1;");
93  query.bindValue(":CARDTYPE", Itype.key());
94  query.bindValue(":CARDNAME", Itype.value());
95  if (!query.exec())
96  {
97  MythDB::DBError("Unable to insert V4L2 profilegroup.", query);
98  return false;
99  }
100 
101  // get the id of the new profile group
102  int groupid = query.lastInsertId().toInt();
103 
104  for (const auto & name : profile_names)
105  {
106  // insert the recording profiles
107  query.prepare("INSERT INTO recordingprofiles SET name = "
108  ":NAME, profilegroup = :GROUPID;");
109  query.bindValue(":NAME", name);
110  query.bindValue(":GROUPID", groupid);
111  if (!query.exec())
112  {
113  MythDB::DBError("Unable to insert 'Default' "
114  "recordingprofile.", query);
115  return false;
116  }
117  }
118  }
119  }
120 
121  return true;
122 }
123 
125 {
127  QString tid;
128 
129  MSqlQuery result(MSqlQuery::InitCon());
130  result.prepare(
131  "SELECT name, id, hostname, is_default, cardtype "
132  "FROM profilegroups");
133 
134  if (!result.exec())
135  {
136  MythDB::DBError("ProfileGroup::fillSelections", result);
137  return;
138  }
139 
140  while (result.next())
141  {
142  QString name = result.value(0).toString();
143  QString id = result.value(1).toString();
144  QString hostname = result.value(2).toString();
145  bool is_default = (bool) result.value(3).toInt();
146  QString cardtype = result.value(4).toString();
147 
148  // Only show default profiles that match installed cards
149  // Workaround for #12481 in fixes/0.27
150  bool have_cardtype = cardtypes.contains(cardtype);
151  if (is_default && (cardtype == "TRANSCODE") && !have_cardtype)
152  {
153  tid = id;
154  }
155  else if (have_cardtype)
156  {
157  if (!hostname.isEmpty())
158  name += QString(" (%1)").arg(result.value(2).toString());
159 
160  if (is_default)
161  {
162  setting->addChild(new RecordingProfileEditor(id.toInt(), name));
163  }
164  else
165  {
166  auto *profileGroup = new ProfileGroup();
167  profileGroup->loadByID(id.toInt());
168  profileGroup->setLabel(name);
169  profileGroup->addChild(
170  new RecordingProfileEditor(id.toInt(), tr("Profiles")));
171  setting->addChild(profileGroup);
172  }
173  }
174  }
175 
176  if (!tid.isEmpty())
177  {
178  setting->addChild(new RecordingProfileEditor(tid.toInt(),
179  tr("Transcoders")));
180  }
181 }
182 
183 QString ProfileGroup::getName(int group)
184 {
185  MSqlQuery result(MSqlQuery::InitCon());
186  result.prepare("SELECT name from profilegroups WHERE id = :PROFILE_ID;");
187  result.bindValue(":PROFILE_ID", group);
188  if (result.exec() && result.next())
189  {
190  return result.value(0).toString();
191  }
192 
193  return nullptr;
194 }
195 
197 {
198  MSqlQuery result(MSqlQuery::InitCon());
199  QString querystr = QString("SELECT DISTINCT id FROM profilegroups WHERE "
200  "name = '%1' AND hostname = '%2';")
201  .arg(getName()).arg(m_host->getValue());
202  result.prepare(querystr);
203 
204  return !(result.exec() && result.next());
205 }
206 
207 void ProfileGroup::getHostNames(QStringList *hostnames)
208 {
209  hostnames->clear();
210 
211  MSqlQuery result(MSqlQuery::InitCon());
212 
213  result.prepare("SELECT DISTINCT hostname from capturecard");
214 
215  if (result.exec())
216  {
217  while (result.next())
218  hostnames->append(result.value(0).toString());
219  }
220 }
221 
223 {
224  clearSettings();
228 }
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:783
static void getHostNames(QStringList *hostnames)
HostName * m_host
Definition: profilegroup.h:116
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:864
QString GetColumnName(void) const
Definition: mythstorage.h:47
virtual void clearSettings()
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:125
virtual void Load(void)
void addSelection(const QString &label, QString value=QString(), bool select=false)
bool
Definition: pxsup2dast.c:30
QString getName(void) const
Definition: profilegroup.h:106
virtual void loadByID(int id)
bool allowedGroupName(void)
virtual QString GetDBValue(void) const =0
Is_default * m_isDefault
Definition: profilegroup.h:117
QString GetSetClause(MSqlBindings &bindings) const override
QString GetWhereClause(MSqlBindings &bindings) const override
Definition: profilegroup.cpp:8
virtual QString getValue(void) const
QVariant value(int i) const
Definition: mythdbcon.h:198
const ProfileGroup & m_parent
Definition: profilegroup.h:26
static bool addMissingDynamicProfiles(void)
QMap< QString, QVariant > MSqlBindings
typedef for a map of string -> string bindings for generic queries.
Definition: mythdbcon.h:98
QVariant lastInsertId()
Return the id of the last inserted row.
Definition: mythdbcon.cpp:888
static void fillSelections(GroupSetting *setting)
virtual void setLabel(QString str)
StorageUser * m_user
Definition: mythstorage.h:50
string hostname
Definition: caa.py:17
int getProfileNum(void) const
Definition: profilegroup.h:98
unsigned int uint
Definition: compat.h:140
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:535
virtual void addChild(StandardSetting *child)
QMap< QString, QString > InputTypes
Definition: cardutil.h:43
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:808
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:603
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:179
void Load(void) override
static InputTypes GetInputTypes(void)
Definition: cardutil.cpp:334
static void fillSelections(MythUIComboBoxSetting *setting)
virtual void setValue(const QString &newValue)