MythTV master
mythuispinbox.cpp
Go to the documentation of this file.
1
3
4#include "mythmainwindow.h"
5#include "mythuispinbox.h"
6#include "mythuibutton.h"
7#include "mythuitextedit.h"
8#include "mythuitext.h"
9
10// QT headers
11#include <QCoreApplication>
12#include <QDomDocument>
13#include <utility>
14
26void MythUISpinBox::SetRange(int low, int high, int step, uint pageMultiple)
27{
28 if ((high == low) || step == 0)
29 return;
30
31 m_low = low;
32 m_high = high;
33 m_step = step;
34
35 m_moveAmount = pageMultiple;
36
37 bool reverse = false;
38 int value = low;
39
40 if (low > high)
41 reverse = true;
42
43 Reset();
44
45 while ((reverse && (value >= high)) ||
46 (!reverse && (value <= high)))
47 {
48 QString text;
49
50 if (m_hasTemplate)
51 {
52 QString temp;
53
54 if (value < 0 && !m_negativeTemplate.isEmpty())
55 temp = m_negativeTemplate;
56 else if (value == 0 && !m_zeroTemplate.isEmpty())
57 temp = m_zeroTemplate;
58 else if (!m_positiveTemplate.isEmpty())
59 temp = m_positiveTemplate;
60
61 if (!temp.isEmpty())
62 {
63 if (temp.contains("%n"))
64 {
65 text = QCoreApplication::translate("ThemeUI", temp.toUtf8(), nullptr,
66 qAbs(value));
67 }
68 else
69 {
70 text = QCoreApplication::translate("ThemeUI", temp.toUtf8());
71 }
72 }
73 }
74
75 if (text.isEmpty())
76 text = QString::number(value);
77
78 new MythUIButtonListItem(this, text, QVariant::fromValue(value));
79
80 if (reverse)
81 value = value - step;
82 else
83 value = value + step;
84 }
85
87}
88
89
96void MythUISpinBox::AddSelection(int value, const QString &label)
97{
98 if (!label.isEmpty())
99 {
100 MythUIButtonListItem *item = GetItemByData(value);
101 if (item)
102 {
103 item->SetText(label);
104 return;
105 }
106 }
107
108 int insertPos=-1;
109
110 for (int pos = 0; pos < m_itemList.size(); pos++)
111 {
112 MythUIButtonListItem *item = m_itemList.at(pos);
113 if (item->GetData().toInt() > value)
114 {
115 insertPos = pos;
116 break;
117 }
118 }
119
120 new MythUIButtonListItem(this, label.isEmpty() ? QChar(value) : label,
121 QVariant::fromValue(value), insertPos);
122}
123
128 const QString &filename, QDomElement &element, bool showWarnings)
129{
130 if (element.tagName() == "template")
131 {
132 QString format = parseText(element);
133
134 if (element.attribute("type") == "negative")
135 m_negativeTemplate = format;
136 else if (element.attribute("type") == "zero")
137 m_zeroTemplate = format;
138 else
139 m_positiveTemplate = format;
140
141 m_hasTemplate = true;
142 }
143 else
144 {
145 return MythUIButtonList::ParseElement(filename, element, showWarnings);
146 }
147
148 return true;
149}
150
155{
156 bool handled = false;
157
158 if ((unit == MovePage) && m_moveAmount)
160 else
161 handled = MythUIButtonList::MoveDown(unit, amount);
162
163 return handled;
164}
165
170{
171 bool handled = false;
172
173 if ((unit == MovePage) && m_moveAmount)
175 else
176 handled = MythUIButtonList::MoveUp(unit, amount);
177
178 return handled;
179}
180
185{
186 auto *spinbox = new MythUISpinBox(parent, objectName());
187 spinbox->CopyFrom(this);
188}
189
194{
195 auto *spinbox = dynamic_cast<MythUISpinBox *>(base);
196
197 if (!spinbox)
198 return;
199
200 m_hasTemplate = spinbox->m_hasTemplate;
201 m_negativeTemplate = spinbox->m_negativeTemplate;
202 m_zeroTemplate = spinbox->m_zeroTemplate;
203 m_positiveTemplate = spinbox->m_positiveTemplate;
204
206}
207
208// Open the entry dialog on certain key presses. A select or search action will
209// open the dialog. A number or minus sign will open the entry dialog with the
210// given key as the first digit.
211// If the spinbox uses a template, the entries are not just numbers
212// but can be sentences. The whole sentence is put in the entry field,
213// allowing the user to change the number part of it.
214
215bool MythUISpinBox::keyPressEvent(QKeyEvent *event)
216{
217 QStringList actions;
218 bool handled = false;
219 handled = GetMythMainWindow()->TranslateKeyPress("Global", event, actions);
220 if (handled)
221 return true;
222
224 if (item == nullptr)
226
227 QString initialEntry = item->GetText();
228 bool doEntry = false;
229
230 // Only invoke the entry dialog if the entry is a number
231 bool isNumber = false;
232 (void)initialEntry.toLongLong(&isNumber,10);
233 if (!isNumber)
235
236 for (const QString& action : std::as_const(actions))
237 {
238 if (action >= ACTION_0 && action <= ACTION_9)
239 {
240 if (!m_hasTemplate)
241 initialEntry = action;
242 doEntry=true;
243 break;
244 }
245 if (action == ACTION_SELECT || action == "SEARCH")
246 {
247 doEntry=true;
248 break;
249 }
250 }
251 if (actions.empty() && event->text() == "-")
252 {
253 if (!m_hasTemplate)
254 initialEntry = "-";
255 doEntry=true;
256 }
257
258 if (doEntry)
259 {
260 ShowEntryDialog(initialEntry);
261 handled = true;
262 }
263
264 if (handled)
265 return true;
267}
268
269void MythUISpinBox::ShowEntryDialog(QString initialEntry)
270{
271 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
272
273 auto *dlg = new SpinBoxEntryDialog(popupStack, "SpinBoxEntryDialog",
274 this, std::move(initialEntry), m_low, m_high, m_step);
275
276 if (dlg->Create())
277 popupStack->AddScreen(dlg);
278 else
279 delete dlg;
280}
281
282// Convenience Dialog to allow entry of a Spinbox value
283
285 MythUIButtonList *parentList, QString searchText,
286 int low, int high, int step)
287 : MythScreenType(parent, name, false),
288 m_parentList(parentList),
289 m_searchText(std::move(searchText)),
290 m_selection(parentList->GetCurrentPos()),
291 m_low(low),
292 m_high(high),
293 m_step(step)
294{
295}
296
297
299{
300 if (!CopyWindowFromBase("SpinBoxEntryDialog", this))
301 return false;
302
303 bool err = false;
304 UIUtilE::Assign(this, m_entryEdit, "entry", &err);
305 UIUtilW::Assign(this, m_cancelButton,"cancel", &err);
306 UIUtilW::Assign(this, m_rulesText,"rules", &err);
307 UIUtilE::Assign(this, m_okButton, "ok", &err);
308
309 if (err)
310 {
311 LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'SpinBoxEntryDialog'");
312 return false;
313 }
314
316 entryChanged();
317 if (m_rulesText)
318 {
319 InfoMap infoMap;
320 infoMap["low"] = QString::number(m_low);
321 infoMap["high"] = QString::number(m_high);
322 infoMap["step"] = QString::number(m_step);
323 m_rulesText->SetTextFromMap(infoMap);
324 }
325
327 if (m_cancelButton)
330
332
333 return true;
334}
335
337{
338 int currPos = 0;
339 int count = m_parentList->GetCount();
340 QString searchText = m_entryEdit->GetText();
341 bool found = false;
342 for (currPos = 0; currPos < count; currPos++)
343 {
344 if (searchText.compare(m_parentList->GetItemAt(currPos)->GetText(),
345 Qt::CaseInsensitive) == 0)
346 {
347 found = true;
348 m_selection = currPos;
349 break;
350 }
351 }
352 m_okButton->SetEnabled(found);
353}
354
356{
358 Close();
359}
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
MythScreenStack * GetStack(const QString &Stackname)
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Screen in which all other widgets are contained and rendered.
void BuildFocusList(void)
virtual void Close()
QString GetText(const QString &name="") const
void SetText(const QString &text, const QString &name="", const QString &state="")
List widget, displays list items in a variety of themeable arrangements and can trigger signals when ...
bool ParseElement(const QString &filename, QDomElement &element, bool showWarnings) override
Parse the xml definition of this widget setting the state of the object accordingly.
virtual bool MoveDown(MovementUnit unit=MoveItem, uint amount=0)
MythUIButtonListItem * GetItemCurrent() const
void SetItemCurrent(MythUIButtonListItem *item)
void CalculateArrowStates(void)
void Reset() override
Reset the widget to it's original state, should not reset changes made by the theme.
MythUIButtonListItem * GetItemByData(const QVariant &data)
virtual bool MoveUp(MovementUnit unit=MoveItem, uint amount=0)
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
MythUIButtonListItem * GetItemAt(int pos) const
QList< MythUIButtonListItem * > m_itemList
void CopyFrom(MythUIType *base) override
Copy this widgets state from another.
friend class MythUIButtonListItem
void Clicked()
A widget for offering a range of numerical values where only the the bounding values and interval are...
Definition: mythuispinbox.h:23
QString m_positiveTemplate
Definition: mythuispinbox.h:73
bool ParseElement(const QString &filename, QDomElement &element, bool showWarnings) override
Parse the xml definition of this widget setting the state of the object accordingly.
void SetRange(int low, int high, int step, uint pageMultiple=5)
Set the lower and upper bounds of the spinbox, the interval and page amount.
MythUISpinBox(MythUIType *parent, const QString &name)
Definition: mythuispinbox.h:26
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
void AddSelection(int value, const QString &label="")
Add a special label for a value of the spinbox, it does not need to be in the range.
QString m_negativeTemplate
Definition: mythuispinbox.h:71
bool MoveDown(MovementUnit unit=MoveItem, uint amount=0) override
bool MoveUp(MovementUnit unit=MoveItem, uint amount=0) override
void CreateCopy(MythUIType *parent) override
Copy the state of this widget to the one given, it must be of the same type.
void CopyFrom(MythUIType *base) override
Copy this widgets state from another.
QString m_zeroTemplate
Definition: mythuispinbox.h:72
void ShowEntryDialog(QString initialEntry)
QString GetText(void) const
void SetText(const QString &text, bool moveCursor=true)
void valueChanged()
void SetTextFromMap(const InfoMap &map)
Definition: mythuitext.cpp:138
The base class on which all widgets and screens are based.
Definition: mythuitype.h:86
void SetEnabled(bool enable)
MythUIButtonList * m_parentList
Definition: mythuispinbox.h:99
SpinBoxEntryDialog(MythScreenStack *parent, const char *name, MythUIButtonList *parentList, QString searchText, int low, int high, int step)
bool Create(void) override
MythUIButton * m_cancelButton
MythUIButton * m_okButton
MythUITextEdit * m_entryEdit
MythUIText * m_rulesText
static bool CopyWindowFromBase(const QString &windowname, MythScreenType *win)
static QString parseText(QDomElement &element)
unsigned int uint
Definition: freesurround.h:24
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythMainWindow * GetMythMainWindow(void)
QHash< QString, QString > InfoMap
Definition: mythtypes.h:15
static constexpr const char * ACTION_0
Definition: mythuiactions.h:4
static constexpr const char * ACTION_SELECT
Definition: mythuiactions.h:15
static constexpr const char * ACTION_9
Definition: mythuiactions.h:13
STL namespace.
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27
VERBOSE_PREAMBLE false
Definition: verbosedefs.h:89