1 //=========================================================
2 //  MusE
3 //  Linux Music Editor
4 //    $Id: dentry.cpp,v 1.1.1.1.2.3 2008/08/18 00:15:26 terminator356 Exp $
5 //  (C) Copyright 1999 Werner Schweer (ws@seh.de)
6 //
7 //  This program is free software; you can redistribute it and/or
8 //  modify it under the terms of the GNU General Public License
9 //  as published by the Free Software Foundation; version 2 of
10 //  the License, or (at your option) any later version.
11 //
12 //  This program is distributed in the hope that it will be useful,
13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //  GNU General Public License for more details.
16 //
17 //  You should have received a copy of the GNU General Public License
18 //  along with this program; if not, write to the Free Software
19 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 //
21 //=========================================================
22 
23 #include <stdio.h>
24 
25 #include <QWidget>
26 #include <QWheelEvent>
27 #include <QMouseEvent>
28 #include <QContextMenuEvent>
29 #include <QKeyEvent>
30 #include <QString>
31 #include <QTimer>
32 
33 #include "sliderbase.h"
34 #include "dentry.h"
35 #include "globals.h"
36 #include "gconfig.h"
37 
38 #define TIMER1    400
39 #define TIMER2    200
40 #define TIMEC     7
41 #define TIMER3    100
42 #define TIMEC2    20
43 #define TIMER4    50
44 
45 namespace MusEGui {
46 
47 //---------------------------------------------------------
48 //   Dentry
49 //    lineedit double values
50 //---------------------------------------------------------
51 
Dentry(QWidget * parent,const char * name)52 Dentry::Dentry(QWidget* parent, const char* name) : QLineEdit(parent)
53       {
54       setObjectName(name);
55       _slider = 0;
56       _id = -1;
57       //setAutoFillBackground(true);
58       timer = new QTimer(this);
59       connect(timer, SIGNAL(timeout()), SLOT(repeat()));
60       val = 0.01;
61       connect(this, SIGNAL(returnPressed()), SLOT(endEdit()));
62       setCursor(QCursor(Qt::ArrowCursor));
63       evx = 1;
64       }
65 
66 //---------------------------------------------------------
67 //   contextMenuEvent
68 //---------------------------------------------------------
69 
contextMenuEvent(QContextMenuEvent * e)70 void Dentry::contextMenuEvent(QContextMenuEvent * e)
71 {
72   e->accept();
73 }
74 
75 //---------------------------------------------------------
76 //   endEdit
77 //---------------------------------------------------------
78 
endEdit()79 void Dentry::endEdit()
80       {
81       if (isModified()) {
82             if (setSValue(text())) {
83                   setString(val);
84                   return;
85                   }
86             }
87       setString(val);
88       }
89 
90 //---------------------------------------------------------
91 //   mousePressEvent
92 //---------------------------------------------------------
93 
mousePressEvent(QMouseEvent * event)94 void Dentry::mousePressEvent(QMouseEvent* event)
95       {
96       const Qt::MouseButton m_button = event->button();
97       const Qt::MouseButtons m_buttons = event->buttons();
98 
99       event->accept();
100 
101       // Only one mouse button at a time! Otherwise bad things happen.
102       if(m_buttons ^ m_button)
103       {
104         button = Qt::NoButton;
105         timer->stop();
106         return;
107       }
108 
109       if(m_button == Qt::LeftButton)
110         QLineEdit::mousePressEvent(event);
111 
112       button = m_button;
113       starty = event->y();
114       evx    = event->x();
115       timecount = 0;
116       repeat();
117       timer->start(TIMER1);
118       }
119 
120 //---------------------------------------------------------
121 //   wheelEvent
122 //---------------------------------------------------------
123 
wheelEvent(QWheelEvent * event)124 void Dentry::wheelEvent(QWheelEvent* event)
125       {
126       event->accept();
127 
128       const QPoint pixelDelta = event->pixelDelta();
129       const QPoint angleDegrees = event->angleDelta() / 8;
130       int delta = 0;
131       if(!pixelDelta.isNull())
132         delta = pixelDelta.y();
133       else if(!angleDegrees.isNull())
134         delta = angleDegrees.y() / 15;
135       else
136         return;
137 
138       if (delta < 0)
139       {
140         if(_slider)
141           _slider->stepPages(-1);
142         else
143           decValue(1);
144       }
145       else if (delta > 0)
146       {
147         if(_slider)
148           _slider->stepPages(1);
149         else
150           incValue(1);
151       }
152       }
153 
154 //---------------------------------------------------------
155 //   repeat
156 //---------------------------------------------------------
157 
repeat()158 void Dentry::repeat()
159       {
160       if (timecount == 1) {
161            ++timecount;
162             timer->stop();
163             timer->start(TIMER2);
164             return;
165             }
166       ++timecount;
167       if (timecount == TIMEC) {
168             timer->stop();
169             timer->start(TIMER3);
170             }
171       if (timecount == TIMEC2) {
172             timer->stop();
173             timer->start(TIMER4);
174             }
175 
176       switch (button) {
177             case Qt::LeftButton:
178                   if (!MusEGlobal::config.leftMouseButtonCanDecrease)
179                     return;
180                   // else fall through
181             case Qt::MidButton:
182                   if(_slider)
183                     _slider->stepPages(-1);
184                   else
185                     decValue(evx);
186                   break;
187             case Qt::RightButton:
188                   if(_slider)
189                     _slider->stepPages(1);
190                   else
191                     incValue(evx);
192                   break;
193             default:
194                   break;
195             }
196       }
197 
198 //---------------------------------------------------------
199 //   mouseReleaseEvent
200 //---------------------------------------------------------
201 
mouseReleaseEvent(QMouseEvent * ev)202 void Dentry::mouseReleaseEvent(QMouseEvent* ev)
203       {
204       ev->accept();
205       // Don't call ancestor to avoid middle button pasting.
206       //LineEdit::mouseReleaseEvent(ev);
207 
208       button = Qt::NoButton;
209       timer->stop();
210       }
211 
212 //---------------------------------------------------------
213 //   mouseDoubleClickEvent
214 //---------------------------------------------------------
215 
mouseDoubleClickEvent(QMouseEvent * event)216 void Dentry::mouseDoubleClickEvent(QMouseEvent* event)
217       {
218       event->accept();
219       if (event->button() != Qt::LeftButton) {
220             //mousePressEvent(event);
221             button = event->button();
222             starty = event->y();
223             evx    = event->x();
224             timecount = 0;
225             repeat();
226             timer->start(TIMER1);
227             return;
228             }
229       update();
230       emit doubleClicked(_id);
231       if(event->modifiers() & Qt::ControlModifier)
232         emit ctrlDoubleClicked(_id);
233       else
234         QLineEdit::mouseDoubleClickEvent(event);
235       }
236 
keyPressEvent(QKeyEvent * e)237 void Dentry::keyPressEvent(QKeyEvent* e)
238 {
239   bool inc = true;
240   switch (e->key())
241   {
242     case Qt::Key_Escape:
243       if(isModified())
244       {
245         // Restore the displayed current value.
246         blockSignals(true);
247         setString(val);
248         blockSignals(false);
249       }
250       // Let ancestor have it, such as for yielding focus.
251       e->ignore();
252       return;
253     break;
254 
255     case Qt::Key_Up:
256       inc = true;
257     break;
258 
259     case Qt::Key_Down:
260       inc = false;
261     break;
262 
263     default:
264       // Let ancestor handle it.
265       e->ignore();
266       QLineEdit::keyPressEvent(e);
267       return;
268     break;
269   }
270 
271   if(e->modifiers() & (Qt::AltModifier | Qt::MetaModifier | Qt::ControlModifier))
272   {
273     // Let ancestor handle it.
274     e->ignore();
275     QLineEdit::keyPressEvent(e);
276     return;
277   }
278 
279   e->accept();
280   // Do not allow setting value from the external while mouse is pressed.
281   //if(_pressed)
282   //  return;
283 
284   const bool shift = e->modifiers() == Qt::ShiftModifier;
285   int val = 1;
286   if(shift)
287     val *= 10;
288 
289   if(inc)
290   {
291     if(_slider)
292       _slider->stepPages(val);
293     else
294       incValue(val);
295   }
296   else
297   {
298     if(_slider)
299       _slider->stepPages(-val);
300     else
301       decValue(val);
302   }
303 
304   // Show a handy tooltip value box.
305   //if(d_enableValueToolTips)
306   //  showValueToolTip(e->globalPos());
307 }
308 
309 //---------------------------------------------------------
310 //   setValue
311 //---------------------------------------------------------
312 
setValue(double v)313 void Dentry::setValue(double v)
314       {
315       if (v == val)
316            return;
317       setString(v);
318 #if 0
319       if (setString(v)) {
320             clearFocus();
321             if (!drawFrame)
322                   QLineEdit::setFrame(false);
323             setEnabled(false);
324             }
325       else {
326             setEnabled(true);
327             }
328 #endif
329       val = v;
330       }
331 
332 } // namespace MusEGui
333