maxLibQt
TimerEdit.cpp
Go to the documentation of this file.
1 /*
2  TimerEdit
3 
4  COPYRIGHT: (c)2017 Maxim Paperno; All Right Reserved.
5  Contact: http://www.WorldDesign.com/contact
6 
7  LICENSE:
8 
9  Commercial License Usage
10  Licensees holding valid commercial licenses may use this file in
11  accordance with the terms contained in a written agreement between
12  you and the copyright holder.
13 
14  GNU General Public License Usage
15  Alternatively, this file may be used under the terms of the GNU
16  General Public License as published by the Free Software Foundation,
17  either version 3 of the License, or (at your option) any later version.
18 
19  This program is distributed in the hope that it will be useful,
20  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  GNU General Public License for more details.
23 
24  A copy of the GNU General Public License is available at <http://www.gnu.org/licenses/>.
25 */
26 
27 #include "TimerEdit.h"
28 #include <cmath>
29 
31  QLineEdit(parent),
32  m_showSeconds(true),
33  m_minTime(0),
34  m_maxTime(24 * 3600 - 1),
35  m_singleStep(1),
36  m_pageStep(60),
37  m_hourDigits(2),
38  m_validator(new QRegularExpressionValidator(this))
39 {
41  setupFormat();
42  setToolTip(tr("Use mouse scroll or UP/DOWN arrow keys to change time in small steps.\nCTRL + scroll or PAGE UP/DOWN keys to change time in larger steps."));
44 }
45 
47 {
48  int ret = 0;
49 
50  ret += timepart(text(), TimeParts::Hours) * 3600;
51  ret += timepart(text(), TimeParts::Minutes) * 60;
52  ret += timepart(text(), TimeParts::Seconds);
53  ret *= timepart(text(), TimeParts::Polarity);
54 
55  return ret;
56 }
57 
58 int TimerEdit::timepart(const QString &input, TimerEdit::TimeParts part) const
59 {
60  int ret = 0;
62 
63  if (match.hasMatch()) {
64  switch (part) {
65  case Hours:
66  if (!match.captured("hrs").isEmpty())
67  ret = match.captured("hrs").toInt();
68  break;
69 
70  case Minutes:
71  if (!match.captured("mins").isEmpty())
72  ret = match.captured("mins").toInt();
73  break;
74 
75  case Seconds:
76  if (!match.captured("secs").isEmpty())
77  ret = match.captured("secs").toInt();
78  break;
79 
80  case Polarity:
81  if (!match.captured("pol").isEmpty() && !match.captured("pol").compare("-"))
82  ret = -1;
83  else
84  ret = 1;
85  break;
86 
87  default:
88  break;
89  }
90  }
91 
92  return ret;
93 }
94 
95 
97 
98 void TimerEdit::setTime(int seconds)
99 {
100  if (seconds > m_maxTime)
101  seconds = m_maxTime;
102  else if (seconds < m_minTime)
103  seconds = m_minTime;
104 
105  div_t qrM = div(abs(seconds), 60);
106  div_t qrH = div(qrM.quot, 60);
107 
108  QString val = QString("%1").arg(qrH.rem, 2, 10, QChar('0'));
109 
110  if (m_hourDigits)
111  val.prepend(QString("%1:").arg(qrH.quot, m_hourDigits, 10, QChar('0')));
112 
113  if (m_showSeconds)
114  val.append(QString(":%1").arg(qrM.rem, 2, 10, QChar('0')));
115 
116  if (m_minTime < 0) {
117  if (seconds < 0)
118  val.prepend("-");
119  else
120  val.prepend(" ");
121  }
122 
123  if (text().compare(val)) {
124  setText(val);
125  }
126 }
127 
128 void TimerEdit::incrDecr(int seconds)
129 {
130  if (!seconds)
131  return;
132 
133  const int cs = timeInSeconds();
134  int s = seconds + cs;
135  if (s < m_minTime)
136  s = m_minTime;
137  if (s > m_maxTime)
138  s = m_maxTime;
139  if (s != cs) {
140  setTime(s);
142  }
143 }
144 
145 void TimerEdit::setTimeRange(int minSeconds, int maxSeconds)
146 {
147  if (minSeconds <= maxSeconds && (m_minTime != minSeconds || m_maxTime != maxSeconds)) {
148  int digits = 0;
149  if (maxSeconds >= 3600)
150  digits = floorf(logf(round(maxSeconds / 3600)) / logf(10.0f)) + 1;
151 
152  bool mod = (m_hourDigits != digits || std::signbit((float)m_minTime) != std::signbit((float)minSeconds));
153 
154  m_minTime = minSeconds;
155  m_maxTime = maxSeconds;
156  m_hourDigits = digits;
157 
158  if (mod)
159  setupFormat();
160  }
161 }
162 
163 void TimerEdit::setMinimumTime(int minSeconds)
164 {
165  setTimeRange(minSeconds, (m_maxTime > minSeconds ? m_maxTime : minSeconds));
166 }
167 
168 void TimerEdit::setMaximumTime(int maxSeconds)
169 {
170  setTimeRange((m_minTime < maxSeconds ? m_minTime : maxSeconds), maxSeconds);
171 }
172 
173 void TimerEdit::setShowSeconds(bool showSeconds)
174 {
175  if (m_showSeconds != showSeconds) {
177  setupFormat();
178  }
179 }
180 
181 
183 
185 {
186  int sec = timeInSeconds();
187  if (sec < m_minTime)
189  else if (sec > m_maxTime)
191  else
192  return;
193 
195 }
196 
198 {
199  QString inputRe = "(?<mins>[0-5][0-9])";
200  QString inputMsk = "99";
201  QString suffx = "\\" % tr("m") % "\\" % tr("m");
202 
203  if (m_hourDigits) {
204  inputRe.prepend("(?<hrs>[0-9]*[0-9]):");
205  inputMsk.prepend(":");
206  suffx.prepend(":");
207  for (int i=0; i < m_hourDigits; ++i) {
208  inputMsk.prepend("9");
209  suffx.prepend("\\" % tr("h"));
210  }
211  }
212  if (m_showSeconds) {
213  inputRe.append(":(?<secs>[0-5][0-9])");
214  inputMsk.append(":99");
215  suffx.append(":\\" % tr("s") % "\\" % tr("s"));
216  }
217  if (m_minTime < 0) {
218  inputRe.prepend("(?<pol>-|\\+|\\s)?");
219  inputMsk.prepend("#");
220  }
221 
222  inputRe.prepend("^");
223  inputRe.append("\\s?\\[[^\\]]+\\]$");
224  inputMsk.append(" \\[" % suffx % "\\]");
225 
227 
228  setInputMask(inputMsk);
230 }
231 
233 {
234  emit QLineEdit::textEdited(text());
235 }
236 
238 {
239  switch (event->key()) {
240  case Qt::Key_Up:
242  break;
243 
244  case Qt::Key_Down:
245  incrDecr(-(int)m_singleStep);
246  break;
247 
248  case Qt::Key_PageUp:
250  break;
251 
252  case Qt::Key_PageDown:
253  incrDecr(-(int)m_pageStep);
254  break;
255 
256  case Qt::Key_Plus:
257  case Qt::Key_Equal:
258  case Qt::Key_Minus:
259  if (m_minTime < 0) {
262  }
263  break;
264 
265  default:
267  break;
268  }
269 }
270 
272 {
273  if (event->angleDelta().isNull()) {
274  event->ignore();
275  return;
276  }
277  int numSteps = -event->angleDelta().y() / 8 / 15 * -1; // one step per 15deg
278  numSteps *= (event->modifiers() & Qt::ControlModifier) ? m_pageStep : m_singleStep;
279  incrDecr(numSteps);
280  event->accept();
281 }
QString captured(int nth) const const
ControlModifier
QString & append(QChar ch)
unsigned m_singleStep
Definition: TimerEdit.h:97
int timepart(const QString &input, TimeParts part) const
Definition: TimerEdit.cpp:58
void setupFormat()
Definition: TimerEdit.cpp:197
void keyPressEvent(QKeyEvent *event) override
Definition: TimerEdit.cpp:237
QString text() const const
void incrDecr(int seconds)
Definition: TimerEdit.cpp:128
virtual bool event(QEvent *e) override
QString & prepend(QChar ch)
void setShowSeconds(bool showSeconds)
Definition: TimerEdit.cpp:173
int timeInSeconds() const
Definition: TimerEdit.cpp:46
TimerEdit(QWidget *parent=Q_NULLPTR)
Definition: TimerEdit.cpp:30
void setTime(int seconds)
Definition: TimerEdit.cpp:98
virtual void keyPressEvent(QKeyEvent *event) override
void setMaximumTime(int maxSeconds)
Definition: TimerEdit.cpp:168
short m_hourDigits
Definition: TimerEdit.h:99
int toInt(bool *ok, int base) const const
bool showSeconds() const
Definition: TimerEdit.h:70
bool isEmpty() const const
bool hasMatch() const const
void setSizePolicy(QSizePolicy)
unsigned m_pageStep
Definition: TimerEdit.h:98
int m_minTime
Definition: TimerEdit.h:95
void textEdited(const QString &text)
bool m_showSeconds
Definition: TimerEdit.h:94
void setMinimumTime(int minSeconds)
Definition: TimerEdit.cpp:163
void emitValueChanged()
Definition: TimerEdit.cpp:232
QRegularExpressionValidator * m_validator
Definition: TimerEdit.h:100
void textEditedHandler()
Definition: TimerEdit.cpp:184
QString tr(const char *s, const char *c, int n)
int m_maxTime
Definition: TimerEdit.h:96
void setToolTip(const QString &)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
int compare(const QString &other, Qt::CaseSensitivity cs) const const
void wheelEvent(QWheelEvent *event) override
Definition: TimerEdit.cpp:271
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
void setValidator(const QValidator *v)
void setInputMask(const QString &inputMask)
void setTimeRange(int minSeconds, int maxSeconds)
Definition: TimerEdit.cpp:145