]> git.zerfleddert.de Git - proxmark3-svn/blame_incremental - client/proxguiqt.cpp
Some more refinements
[proxmark3-svn] / client / proxguiqt.cpp
... / ...
CommitLineData
1//-----------------------------------------------------------------------------
2// Copyright (C) 2009 Michael Gernoth <michael at gernoth.net>
3//
4// This code is licensed to you under the terms of the GNU GPL, version 2 or,
5// at your option, any later version. See the LICENSE.txt file for the text of
6// the license.
7//-----------------------------------------------------------------------------
8// GUI (QT)
9//-----------------------------------------------------------------------------
10
11#include <iostream>
12#include <QPainterPath>
13#include <QBrush>
14#include <QPen>
15#include <QTimer>
16#include <QCloseEvent>
17#include <QMouseEvent>
18#include <QKeyEvent>
19#include <math.h>
20#include <limits.h>
21#include <stdio.h>
22#include <QSlider>
23#include <QHBoxLayout>
24#include <string.h>
25#include "proxguiqt.h"
26#include "proxgui.h"
27#include <QtGui>
28//#include "data_operations.h"
29#include <ctime>
30
31int GridOffset= 0;
32bool GridLocked= 0;
33int startMax;
34int PageWidth;
35
36void ProxGuiQT::ShowGraphWindow(void)
37{
38 emit ShowGraphWindowSignal();
39}
40
41void ProxGuiQT::RepaintGraphWindow(void)
42{
43 emit RepaintGraphWindowSignal();
44}
45
46void ProxGuiQT::HideGraphWindow(void)
47{
48 emit HideGraphWindowSignal();
49}
50
51void ProxGuiQT::_ShowGraphWindow(void)
52{
53 if(!plotapp)
54 return;
55
56 if (!plotwidget)
57 plotwidget = new ProxWidget();
58
59 plotwidget->show();
60}
61
62void ProxGuiQT::_RepaintGraphWindow(void)
63{
64 if (!plotapp || !plotwidget)
65 return;
66
67 plotwidget->update();
68}
69
70void ProxGuiQT::_HideGraphWindow(void)
71{
72 if (!plotapp || !plotwidget)
73 return;
74
75 plotwidget->hide();
76}
77
78void ProxGuiQT::MainLoop()
79{
80 plotapp = new QApplication(argc, argv);
81
82 connect(this, SIGNAL(ShowGraphWindowSignal()), this, SLOT(_ShowGraphWindow()));
83 connect(this, SIGNAL(RepaintGraphWindowSignal()), this, SLOT(_RepaintGraphWindow()));
84 connect(this, SIGNAL(HideGraphWindowSignal()), this, SLOT(_HideGraphWindow()));
85
86 plotapp->exec();
87}
88
89ProxGuiQT::ProxGuiQT(int argc, char **argv) : plotapp(NULL), plotwidget(NULL),
90 argc(argc), argv(argv)
91{
92
93}
94
95ProxGuiQT::~ProxGuiQT(void)
96{
97 if (plotwidget) {
98 delete plotwidget;
99 plotwidget = NULL;
100 }
101
102 if (plotapp) {
103 plotapp->quit();
104 delete plotapp;
105 plotapp = NULL;
106 }
107}
108
109//--------------------
110
111void ProxWidget::applyOperation()
112{
113 printf("ApplyOperation()");
114 memcpy(GraphBuffer,s_Buff, sizeof(int) * GraphTraceLen);
115 RepaintGraphWindow();
116
117}
118void ProxWidget::stickOperation()
119{
120 printf("stickOperation()");
121}
122void ProxWidget::vchange_autocorr(int v)
123{
124 autoCorr(GraphBuffer,s_Buff, GraphTraceLen, v);
125 printf("vchange_autocorr(%d)\n", v);
126 RepaintGraphWindow();
127}
128void ProxWidget::vchange_dthr_up(int v)
129{
130 int down = opsController->horizontalSlider_dirthr_down->value();
131 directionalThreshold(GraphBuffer,s_Buff, GraphTraceLen, v, down);
132 printf("vchange_dthr_up(%d)", v);
133 RepaintGraphWindow();
134
135}
136void ProxWidget::vchange_dthr_down(int v)
137{
138 printf("vchange_dthr_down(%d)", v);
139 int up = opsController->horizontalSlider_dirthr_up->value();
140 directionalThreshold(GraphBuffer,s_Buff, GraphTraceLen, v, up);
141 RepaintGraphWindow();
142
143}
144ProxWidget::ProxWidget(QWidget *parent, ProxGuiQT *master) : QWidget(parent)
145{
146 this->master = master;
147 resize(800,500);
148
149 /** Setup the controller widget **/
150
151 QWidget* controlWidget = new QWidget();
152 opsController = new Ui::Form();
153 opsController->setupUi(controlWidget);
154 //Due to quirks in QT Designer, we need to fiddle a bit
155 opsController->horizontalSlider_dirthr_down->setMinimum(-128);
156 opsController->horizontalSlider_dirthr_down->setMaximum(0);
157 opsController->horizontalSlider_dirthr_down->setValue(-20);
158
159
160 QObject::connect(opsController->pushButton_apply, SIGNAL(clicked()), this, SLOT(applyOperation()));
161 QObject::connect(opsController->pushButton_sticky, SIGNAL(clicked()), this, SLOT(stickOperation()));
162 QObject::connect(opsController->horizontalSlider_window, SIGNAL(valueChanged(int)), this, SLOT(vchange_autocorr(int)));
163 QObject::connect(opsController->horizontalSlider_dirthr_up, SIGNAL(valueChanged(int)), this, SLOT(vchange_dthr_up(int)));
164 QObject::connect(opsController->horizontalSlider_dirthr_down, SIGNAL(valueChanged(int)), this, SLOT(vchange_dthr_down(int)));
165
166 controlWidget->show();
167
168 // Set up the plot widget, which does the actual plotting
169
170 plot = new Plot(this);
171 /*
172 QSlider* slider = new QSlider(Qt::Horizontal);
173 slider->setFocusPolicy(Qt::StrongFocus);
174 slider->setTickPosition(QSlider::TicksBothSides);
175 slider->setTickInterval(10);
176 slider->setSingleStep(1);
177 */
178 QVBoxLayout *layout = new QVBoxLayout;
179 //layout->addWidget(slider);
180 layout->addWidget(plot);
181 setLayout(layout);
182 printf("Proxwidget Constructor just set layout\r\n");
183}
184
185//----------- Plotting
186
187int Plot::xCoordOf(int i, QRect r )
188{
189 return r.left() + (int)((i - GraphStart)*GraphPixelsPerPoint);
190}
191
192int Plot::yCoordOf(int v, QRect r, int maxVal)
193{
194 int z = (r.bottom() - r.top())/2;
195 return -(z * v) / maxVal + z;
196}
197
198int Plot::valueOf_yCoord(int y, QRect r, int maxVal)
199{
200 int z = (r.bottom() - r.top())/2;
201 return (y-z) * maxVal / z;
202}
203static const QColor GREEN = QColor(100, 255, 100);
204static const QColor RED = QColor(255, 100, 100);
205static const QColor BLUE = QColor(100,100,255);
206static const QColor GREY = QColor(240,240,240);
207
208QColor Plot::getColor(int graphNum)
209{
210 switch (graphNum){
211 case 0: return GREEN;//Green
212 case 1: return RED;//Red
213 case 2: return BLUE;//Blue
214 default: return GREY;
215 }
216}
217
218void Plot::PlotGraph(int *buffer, int len, QRect plotRect, QRect annotationRect,QPainter *painter, int graphNum)
219{
220 clock_t begin = clock();
221 QPainterPath penPath;
222
223 startMax = (len - (int)((plotRect.right() - plotRect.left() - 40) / GraphPixelsPerPoint));
224 if(startMax < 0) {
225 startMax = 0;
226 }
227 if(GraphStart > startMax) {
228 GraphStart = startMax;
229 }
230
231 int vMin = INT_MAX, vMax = INT_MIN,vMean = 0, v = 0,absVMax = 0;
232 int sample_index =GraphStart ;
233 for( ; sample_index < len && xCoordOf(sample_index,plotRect) < plotRect.right() ; sample_index++) {
234
235 v = buffer[sample_index];
236 if(v < vMin) vMin = v;
237 if(v > vMax) vMax = v;
238 vMean += v;
239 }
240
241 vMean /= (sample_index - GraphStart);
242
243 if(fabs( (double) vMin) > absVMax) absVMax = (int)fabs( (double) vMin);
244 if(fabs( (double) vMax) > absVMax) absVMax = (int)fabs( (double) vMax);
245 absVMax = (int)(absVMax*1.2 + 1);
246 // number of points that will be plotted
247 int span = (int)((plotRect.right() - plotRect.left()) / GraphPixelsPerPoint);
248 // one label every 100 pixels, let us say
249 int labels = (plotRect.right() - plotRect.left() - 40) / 100;
250 if(labels <= 0) labels = 1;
251 int pointsPerLabel = span / labels;
252 if(pointsPerLabel <= 0) pointsPerLabel = 1;
253
254 int x = xCoordOf(0, plotRect);
255 int y = yCoordOf(buffer[0],plotRect,absVMax);
256 penPath.moveTo(x, y);
257 //int zeroY = yCoordOf( 0 , plotRect , absVMax);
258 for(int i = GraphStart; i < len && xCoordOf(i, plotRect) < plotRect.right(); i++) {
259
260 x = xCoordOf(i, plotRect);
261 v = buffer[i];
262
263 y = yCoordOf( v, plotRect, absVMax);//(y * (r.top() - r.bottom()) / (2*absYMax)) + zeroHeight;
264
265 penPath.lineTo(x, y);
266
267 if(GraphPixelsPerPoint > 10) {
268 QRect f(QPoint(x - 3, y - 3),QPoint(x + 3, y + 3));
269 painter->fillRect(f, QColor(100, 255, 100));
270 }
271
272/* if(((i - GraphStart) % pointsPerLabel == 0) && i != GraphStart) {
273 char str[100];
274 sprintf(str, "+%d", (i - GraphStart));
275
276 painter->setPen(QColor(255, 255, 255));
277 QRect size;
278 QFontMetrics metrics(painter->font());
279 size = metrics.boundingRect(str);
280 painter->drawText(x - (size.right() - size.left()), zeroY + 9, str);
281 }
282*/
283 }
284
285 painter->setPen(getColor(graphNum));
286
287 //Draw y-axis
288 int xo = 5+(graphNum*40);
289 painter->drawLine(xo, plotRect.top(),xo, plotRect.bottom());
290
291 int vMarkers = (absVMax - (absVMax % 10)) / 5;
292 int minYDist = 40; //Minimum pixel-distance between markers
293
294 char yLbl[20];
295
296 int n = 0;
297 int lasty0 = 65535;
298
299 for(int v = vMarkers; yCoordOf(v,plotRect,absVMax) > plotRect.top() && n < 20; v+= vMarkers ,n++)
300 {
301 int y0 = yCoordOf(v,plotRect,absVMax);
302 int y1 = yCoordOf(-v,plotRect,absVMax);
303
304 if(lasty0 - y0 < minYDist) continue;
305
306 painter->drawLine(xo-5,y0, xo+5, y0);
307
308 sprintf(yLbl, "%d", v);
309 painter->drawText(xo+5,y0-2,yLbl);
310
311 painter->drawLine(xo-5, y1, xo+5, y1);
312 sprintf(yLbl, "%d",-v);
313 painter->drawText(xo+5, y1-2 , yLbl);
314 lasty0 = y0;
315 }
316
317
318 //Graph annotations
319 painter->drawPath(penPath);
320 char str[200];
321 sprintf(str, "max=%5d min=%5d mean=%5d n=%5d/%5d CursorA=[%5d] CursorB=[%5d]",
322 vMax, vMin, vMean, sample_index, len, buffer[CursorAPos], buffer[CursorBPos]);
323 painter->drawText(20, annotationRect.bottom() - 25 - 15 * graphNum, str);
324
325 clock_t end = clock();
326 double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
327 printf("Plot time %f\n", elapsed_secs);
328}
329void Plot::plotGridLines(QPainter* painter,QRect r)
330{
331 int zeroHeight = r.top() + (r.bottom() - r.top()) / 2;
332
333 int i;
334 int grid_delta_x = (int) (PlotGridX * GraphPixelsPerPoint);
335 int grid_delta_y = (int) (PlotGridY * GraphPixelsPerPoint);
336
337 if (PlotGridX > 0 && grid_delta_x > 1) {
338 for(i = 40 + (GridOffset * GraphPixelsPerPoint); i < r.right(); i += grid_delta_x)
339 painter->drawLine(r.left()+i, r.top(), r.left()+i, r.bottom());
340 }
341 if (PlotGridY > 0 && grid_delta_y > 1){
342 for(i = 0; i < ((r.top() + r.bottom())>>1); i += grid_delta_y) {
343 painter->drawLine(r.left() + 40,zeroHeight + i,r.right(),zeroHeight + i);
344 painter->drawLine(r.left() + 40,zeroHeight - i,r.right(),zeroHeight - i);
345
346 }
347 }
348
349}
350#define HEIGHT_INFO 60
351#define WIDTH_AXES 80
352
353void Plot::paintEvent(QPaintEvent *event)
354{
355
356 QPainter painter(this);
357
358 QBrush brush(QColor(100, 255, 100));
359 QPen pen(QColor(100, 255, 100));
360
361 painter.setFont(QFont("Courier New", 10));
362
363 if(GraphStart < 0) {
364 GraphStart = 0;
365 }
366
367 if (CursorAPos > GraphTraceLen)
368 CursorAPos= 0;
369 if(CursorBPos > GraphTraceLen)
370 CursorBPos= 0;
371
372
373 QRect plotRect(WIDTH_AXES, 0, width()-WIDTH_AXES, height()-HEIGHT_INFO);
374 QRect infoRect(0, height()-HEIGHT_INFO, width(), HEIGHT_INFO);
375
376 //Grey background
377 painter.fillRect(rect(), QColor(60, 60, 60));
378 //Black foreground
379 painter.fillRect(plotRect, QColor(0, 0, 0));
380
381// painter.fillRect(infoRect, QColor(60, 60, 60));
382
383 int zeroHeight = plotRect.top() + (plotRect.bottom() - plotRect.top()) / 2;
384 // Draw 0-line
385 painter.setPen(QColor(100, 100, 100));
386 painter.drawLine(plotRect.left(), zeroHeight, plotRect.right(), zeroHeight);
387 // plot X and Y grid lines
388 plotGridLines(&painter, plotRect);
389
390 //Start painting graph
391 PlotGraph(s_Buff, GraphTraceLen,plotRect,infoRect,&painter,1);
392 PlotGraph(GraphBuffer, GraphTraceLen,plotRect,infoRect,&painter,0);
393 // End graph drawing
394
395 //Draw the two cursors
396 if(CursorAPos > GraphStart && xCoordOf(CursorAPos, plotRect) < plotRect.right())
397 {
398 painter.setPen(QColor(255, 255, 0));
399 painter.drawLine(xCoordOf(CursorAPos, plotRect),plotRect.top(),xCoordOf(CursorAPos, plotRect),plotRect.bottom());
400 }
401 if(CursorBPos > GraphStart && xCoordOf(CursorBPos, plotRect) < plotRect.right())
402 {
403 painter.setPen(QColor(255, 0, 255));
404 painter.drawLine(xCoordOf(CursorBPos, plotRect),plotRect.top(),xCoordOf(CursorBPos, plotRect),plotRect.bottom());
405 }
406
407 //Draw annotations
408 char str[200];
409 sprintf(str, "@%5d dt=%5d [%2.2f] zoom=%2.2f CursorA= %5d CursorB= %5d GridX=%5d GridY=%5d (%s)",
410 GraphStart, CursorBPos - CursorAPos, (CursorBPos - CursorAPos)/CursorScaleFactor,
411 GraphPixelsPerPoint,CursorAPos,CursorBPos,PlotGridXdefault,PlotGridYdefault,GridLocked?"Locked":"Unlocked");
412 painter.setPen(QColor(255, 255, 255));
413 painter.drawText(20, infoRect.bottom() - 10, str);
414
415}
416
417
418Plot::Plot(QWidget *parent) : QWidget(parent), GraphStart(0), GraphPixelsPerPoint(1)
419{
420 //Need to set this, otherwise we don't receive keypress events
421 setFocusPolicy( Qt::StrongFocus);
422 resize(600, 300);
423
424 QPalette palette(QColor(0,0,0,0));
425 palette.setColor(QPalette::WindowText, QColor(255,255,255));
426 palette.setColor(QPalette::Text, QColor(255,255,255));
427 palette.setColor(QPalette::Button, QColor(100, 100, 100));
428 setPalette(palette);
429 setAutoFillBackground(true);
430 CursorAPos = 0;
431 CursorBPos = 0;
432
433 setWindowTitle(tr("Sliders"));
434
435
436}
437
438void Plot::closeEvent(QCloseEvent *event)
439{
440 event->ignore();
441 this->hide();
442}
443
444void Plot::mouseMoveEvent(QMouseEvent *event)
445{
446 int x = event->x();
447 x -= WIDTH_AXES;
448 x = (int)(x / GraphPixelsPerPoint);
449 x += GraphStart;
450 if((event->buttons() & Qt::LeftButton)) {
451 CursorAPos = x;
452 } else if (event->buttons() & Qt::RightButton) {
453 CursorBPos = x;
454 }
455
456
457 this->update();
458}
459
460void Plot::keyPressEvent(QKeyEvent *event)
461{
462 int offset;
463 int gridchanged;
464
465 gridchanged= 0;
466 if(event->modifiers() & Qt::ShiftModifier) {
467 if (PlotGridX)
468 offset= PageWidth - (PageWidth % PlotGridX);
469 else
470 offset= PageWidth;
471 } else
472 if(event->modifiers() & Qt::ControlModifier)
473 offset= 1;
474 else
475 offset= (int)(20 / GraphPixelsPerPoint);
476
477 switch(event->key()) {
478 case Qt::Key_Down:
479 if(GraphPixelsPerPoint <= 50) {
480 GraphPixelsPerPoint *= 2;
481 }
482 break;
483
484 case Qt::Key_Up:
485 if(GraphPixelsPerPoint >= 0.02) {
486 GraphPixelsPerPoint /= 2;
487 }
488 break;
489
490 case Qt::Key_Right:
491 if(GraphPixelsPerPoint < 20) {
492 if (PlotGridX && GridLocked && GraphStart < startMax){
493 GridOffset -= offset;
494 GridOffset %= PlotGridX;
495 gridchanged= 1;
496 }
497 GraphStart += offset;
498 } else {
499 if (PlotGridX && GridLocked && GraphStart < startMax){
500 GridOffset--;
501 GridOffset %= PlotGridX;
502 gridchanged= 1;
503 }
504 GraphStart++;
505 }
506 if(GridOffset < 0) {
507 GridOffset += PlotGridX;
508 }
509 if (gridchanged)
510 if (GraphStart > startMax) {
511 GridOffset += (GraphStart - startMax);
512 GridOffset %= PlotGridX;
513 }
514 break;
515
516 case Qt::Key_Left:
517 if(GraphPixelsPerPoint < 20) {
518 if (PlotGridX && GridLocked && GraphStart > 0){
519 GridOffset += offset;
520 GridOffset %= PlotGridX;
521 gridchanged= 1;
522 }
523 GraphStart -= offset;
524 } else {
525 if (PlotGridX && GridLocked && GraphStart > 0){
526 GridOffset++;
527 GridOffset %= PlotGridX;
528 gridchanged= 1;
529 }
530 GraphStart--;
531 }
532 if (gridchanged){
533 if (GraphStart < 0)
534 GridOffset += GraphStart;
535 if(GridOffset < 0)
536 GridOffset += PlotGridX;
537 GridOffset %= PlotGridX;
538 }
539 break;
540
541 case Qt::Key_G:
542 if(PlotGridX || PlotGridY) {
543 PlotGridX= 0;
544 PlotGridY= 0;
545 } else {
546 PlotGridX= PlotGridXdefault;
547 PlotGridY= PlotGridYdefault;
548 }
549 break;
550
551 case Qt::Key_H:
552 puts("Plot Window Keystrokes:\n");
553 puts(" Key Action\n");
554 puts(" DOWN Zoom in");
555 puts(" G Toggle grid display");
556 puts(" H Show help");
557 puts(" L Toggle lock grid relative to samples");
558 puts(" LEFT Move left");
559 puts(" <CTL>LEFT Move left 1 sample");
560 puts(" <SHIFT>LEFT Page left");
561 puts(" LEFT-MOUSE-CLICK Set yellow cursor");
562 puts(" Q Hide window");
563 puts(" RIGHT Move right");
564 puts(" <CTL>RIGHT Move right 1 sample");
565 puts(" <SHIFT>RIGHT Page right");
566 puts(" RIGHT-MOUSE-CLICK Set purple cursor");
567 puts(" UP Zoom out");
568 puts("");
569 puts("Use client window 'data help' for more plot commands\n");
570 break;
571
572 case Qt::Key_L:
573 GridLocked= !GridLocked;
574 break;
575
576 case Qt::Key_Q:
577 this->hide();
578 break;
579
580 default:
581 QWidget::keyPressEvent(event);
582 return;
583 break;
584 }
585
586 this->update();
587}
Impressum, Datenschutz