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",
66 temp.toUtf8().constData(),
67 nullptr, qAbs(value));
68 }
69 else
70 {
71 text = QCoreApplication::translate("ThemeUI",
72 temp.toUtf8().constData());
73 }
74 }
75 }
76
77 if (text.isEmpty())
78 text = QString::number(value);
79
80 new MythUIButtonListItem(this, text, QVariant::fromValue(value));
81
82 if (reverse)
83 value = value - step;
84 else
85 value = value + step;
86 }
87
89}
90
91
98void MythUISpinBox::AddSelection(int value, const QString &label)
99{
100 if (!label.isEmpty())
101 {
102 MythUIButtonListItem *item = GetItemByData(value);
103 if (item)
104 {
105 item->SetText(label);
106 return;
107 }
108 }
109
110 int insertPos=-1;
111
112 for (int pos = 0; pos < m_itemList.size(); pos++)
113 {
114 MythUIButtonListItem *item = m_itemList.at(pos);
115 if (item->GetData().toInt() > value)
116 {
117 insertPos = pos;
118 break;
119 }
120 }
121
122 new MythUIButtonListItem(this, label.isEmpty() ? QChar(value & 0xFFFF) : label,
123 QVariant::fromValue(value), insertPos);
124}
125
130 const QString &filename, QDomElement &element, bool showWarnings)
131{
132 if (element.tagName() == "template")
133 {
134 QString format = parseText(element);
135
136 if (element.attribute("type") == "negative")
137 m_negativeTemplate = format;
138 else if (element.attribute("type") == "zero")
139 m_zeroTemplate = format;
140 else
141 m_positiveTemplate = format;
142
143 m_hasTemplate = true;
144 }
145 else
146 {
147 return MythUIButtonList::ParseElement(filename, element, showWarnings);
148 }
149
150 return true;
151}
152
157{
158 bool handled = false;
159
160 if ((unit == MovePage) && m_moveAmount)
162 else
163 handled = MythUIButtonList::MoveDown(unit, amount);
164
165 return handled;
166}
167
172{
173 bool handled = false;
174
175 if ((unit == MovePage) && m_moveAmount)
177 else
178 handled = MythUIButtonList::MoveUp(unit, amount);
179
180 return handled;
181}
182
187{
188 auto *spinbox = new MythUISpinBox(parent, objectName());
189 spinbox->CopyFrom(this);
190}
191
196{
197 auto *spinbox = dynamic_cast<MythUISpinBox *>(base);
198
199 if (!spinbox)
200 return;
201
202 m_hasTemplate = spinbox->m_hasTemplate;
203 m_negativeTemplate = spinbox->m_negativeTemplate;
204 m_zeroTemplate = spinbox->m_zeroTemplate;
205 m_positiveTemplate = spinbox->m_positiveTemplate;
206
208}
209
210// Open the entry dialog on certain key presses. A select or search action will
211// open the dialog. A number or minus sign will open the entry dialog with the
212// given key as the first digit.
213// If the spinbox uses a template, the entries are not just numbers
214// but can be sentences. The whole sentence is put in the entry field,
215// allowing the user to change the number part of it.
216
217bool MythUISpinBox::keyPressEvent(QKeyEvent *event)
218{
219 QStringList actions;
220 bool handled = false;
221 handled = GetMythMainWindow()->TranslateKeyPress("Global", event, actions);
222 if (handled)
223 return true;
224
226 if (item == nullptr)
228
229 QString initialEntry = item->GetText();
230 bool doEntry = false;
231
232 // Only invoke the entry dialog if the entry is a number
233 bool isNumber = false;
234 (void)initialEntry.toLongLong(&isNumber,10);
235 if (!isNumber)
237
238 for (const QString& action : std::as_const(actions))
239 {
240 if (action >= ACTION_0 && action <= ACTION_9)
241 {
242 if (!m_hasTemplate)
243 initialEntry = action;
244 doEntry=true;
245 break;
246 }
247 if (action == ACTION_SELECT || action == "SEARCH")
248 {
249 doEntry=true;
250 break;
251 }
252 }
253 if (actions.empty() && event->text() == "-")
254 {
255 if (!m_hasTemplate)
256 initialEntry = "-";
257 doEntry=true;
258 }
259
260 if (doEntry)
261 {
262 ShowEntryDialog(initialEntry);
263 handled = true;
264 }
265
266 if (handled)
267 return true;
269}
270
271void MythUISpinBox::ShowEntryDialog(QString initialEntry)
272{
273 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
274
275 auto *dlg = new SpinBoxEntryDialog(popupStack, "SpinBoxEntryDialog",
276 this, std::move(initialEntry), m_low, m_high, m_step);
277
278 if (dlg->Create())
279 popupStack->AddScreen(dlg);
280 else
281 delete dlg;
282}
283
284// Convenience Dialog to allow entry of a Spinbox value
285
287 MythUIButtonList *parentList, QString searchText,
288 int low, int high, int step)
289 : MythScreenType(parent, name, false),
290 m_parentList(parentList),
291 m_searchText(std::move(searchText)),
292 m_selection(parentList->GetCurrentPos()),
293 m_low(low),
294 m_high(high),
295 m_step(step)
296{
297}
298
299
301{
302 if (!CopyWindowFromBase("SpinBoxEntryDialog", this))
303 return false;
304
305 bool err = false;
306 UIUtilE::Assign(this, m_entryEdit, "entry", &err);
307 UIUtilW::Assign(this, m_cancelButton,"cancel", &err);
308 UIUtilW::Assign(this, m_rulesText,"rules", &err);
309 UIUtilE::Assign(this, m_okButton, "ok", &err);
310
311 if (err)
312 {
313 LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'SpinBoxEntryDialog'");
314 return false;
315 }
316
318 entryChanged();
319 if (m_rulesText)
320 {
321 InfoMap infoMap;
322 infoMap["low"] = QString::number(m_low);
323 infoMap["high"] = QString::number(m_high);
324 infoMap["step"] = QString::number(m_step);
325 m_rulesText->SetTextFromMap(infoMap);
326 }
327
329 if (m_cancelButton)
332
334
335 return true;
336}
337
339{
340 int currPos = 0;
341 int count = m_parentList->GetCount();
342 QString searchText = m_entryEdit->GetText();
343 bool found = false;
344 for (currPos = 0; currPos < count; currPos++)
345 {
346 if (searchText.compare(m_parentList->GetItemAt(currPos)->GetText(),
347 Qt::CaseInsensitive) == 0)
348 {
349 found = true;
350 m_selection = currPos;
351 break;
352 }
353 }
354 m_okButton->SetEnabled(found);
355}
356
358{
360 Close();
361}
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:19
QString m_positiveTemplate
Definition: mythuispinbox.h:70
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:22
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:68
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:69
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:97
void SetEnabled(bool enable)
MythUIButtonList * m_parentList
Definition: mythuispinbox.h:96
SpinBoxEntryDialog(MythScreenStack *parent, const char *name, MythUIButtonList *parentList, QString searchText, int low, int high, int step)
bool Create(void) override
MythUIButton * m_cancelButton
Definition: mythuispinbox.h:99
MythUIButton * m_okButton
MythUITextEdit * m_entryEdit
Definition: mythuispinbox.h:98
MythUIText * m_rulesText
static bool CopyWindowFromBase(const QString &windowname, MythScreenType *win)
static QString parseText(QDomElement &element)
unsigned int uint
Definition: compat.h:60
#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
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27
VERBOSE_PREAMBLE false
Definition: verbosedefs.h:80