view.cpp 35 KB
Newer Older
DreamSourceLab's avatar
DreamSourceLab committed
1
/*
DreamSourceLab's avatar
DreamSourceLab committed
2 3
 * This file is part of the DSView project.
 * DSView is based on PulseView.
DreamSourceLab's avatar
DreamSourceLab committed
4 5
 *
 * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
6
 * Copyright (C) 2013 DreamSourceLab <support@dreamsourcelab.com>
DreamSourceLab's avatar
DreamSourceLab committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 */

#include <assert.h>
#include <limits.h>
#include <math.h>

#include <boost/foreach.hpp>

Diego F. Asanza's avatar
Diego F. Asanza committed
29
#include <QApplication>
DreamSourceLab's avatar
DreamSourceLab committed
30 31 32 33
#include <QEvent>
#include <QMouseEvent>
#include <QScrollBar>

DreamSourceLab's avatar
DreamSourceLab committed
34
#include "groupsignal.h"
DreamSourceLab's avatar
DreamSourceLab committed
35
#include "decodetrace.h"
DreamSourceLab's avatar
DreamSourceLab committed
36
#include "header.h"
DreamSourceLab's avatar
DreamSourceLab committed
37
#include "devmode.h"
DreamSourceLab's avatar
DreamSourceLab committed
38 39
#include "ruler.h"
#include "signal.h"
DreamSourceLab's avatar
DreamSourceLab committed
40
#include "dsosignal.h"
DreamSourceLab's avatar
DreamSourceLab committed
41 42
#include "view.h"
#include "viewport.h"
Andy Dneg's avatar
Andy Dneg committed
43 44 45
#include "spectrumtrace.h"
#include "lissajoustrace.h"
#include "analogsignal.h"
DreamSourceLab's avatar
DreamSourceLab committed
46

DreamSourceLab's avatar
DreamSourceLab committed
47
#include "../device/devinst.h"
DreamSourceLab's avatar
DreamSourceLab committed
48 49 50
#include "pv/sigsession.h"
#include "pv/data/logic.h"
#include "pv/data/logicsnapshot.h"
51
#include "pv/dialogs/calibration.h"
Andy Dneg's avatar
Andy Dneg committed
52
#include "pv/dialogs/lissajousoptions.h"
DreamSourceLab's avatar
DreamSourceLab committed
53 54 55 56 57 58 59 60 61 62 63

using namespace boost;
using namespace std;

namespace pv {
namespace view {

const int View::LabelMarginWidth = 70;
const int View::RulerHeight = 50;

const int View::MaxScrollValue = INT_MAX / 2;
64
const int View::MaxHeightUnit = 20;
DreamSourceLab's avatar
DreamSourceLab committed
65 66

//const int View::SignalHeight = 30;s
Andy Dneg's avatar
Andy Dneg committed
67
const int View::SignalMargin = 7;
DreamSourceLab's avatar
DreamSourceLab committed
68 69 70 71 72 73
const int View::SignalSnapGridSize = 10;

const QColor View::CursorAreaColour(220, 231, 243);

const QSizeF View::LabelPadding(4, 4);

Andy Dneg's avatar
Andy Dneg committed
74 75 76 77 78 79
const QColor View::Red = QColor(213, 15, 37, 255);
const QColor View::Orange = QColor(238, 178, 17, 255);
const QColor View::Blue = QColor(17, 133, 209,  255);
const QColor View::Green = QColor(0, 153, 37, 255);
const QColor View::Purple = QColor(109, 50, 156, 255);
const QColor View::LightBlue = QColor(17, 133, 209, 200);
DreamSourceLab's avatar
DreamSourceLab committed
80
const QColor View::LightRed = QColor(213, 15, 37, 200);
Andy Dneg's avatar
Andy Dneg committed
81 82


DreamSourceLab's avatar
DreamSourceLab committed
83
View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget *parent) :
DreamSourceLab's avatar
DreamSourceLab committed
84
    QScrollArea(parent),
DreamSourceLab's avatar
DreamSourceLab committed
85
	_session(session),
DreamSourceLab's avatar
DreamSourceLab committed
86
    _sampling_bar(sampling_bar),
87
    _scale(10),
DreamSourceLab's avatar
DreamSourceLab committed
88 89 90 91 92 93
    _preScale(1e-6),
    _maxscale(1e9),
    _minscale(1e-15),
	_offset(0),
    _preOffset(0),
	_updating_scroll(false),
94
    _trig_hoff(0),
DreamSourceLab's avatar
DreamSourceLab committed
95
	_show_cursors(false),
96
    _search_hit(false),
Andy Dneg's avatar
Andy Dneg committed
97
    _show_xcursors(false),
DreamSourceLab's avatar
DreamSourceLab committed
98
    _hover_point(-1, -1),
Andy Dneg's avatar
Andy Dneg committed
99 100 101
    _dso_auto(true),
    _show_lissajous(false),
    _back_ready(false)
DreamSourceLab's avatar
DreamSourceLab committed
102 103 104 105 106 107 108 109
{
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);

	connect(horizontalScrollBar(), SIGNAL(valueChanged(int)),
		this, SLOT(h_scroll_value_changed(int)));
	connect(verticalScrollBar(), SIGNAL(valueChanged(int)),
		this, SLOT(v_scroll_value_changed(int)));

DreamSourceLab's avatar
DreamSourceLab committed
110 111 112 113 114 115 116
    // trace viewport map
    _trace_view_map[SR_CHANNEL_LOGIC] = TIME_VIEW;
    _trace_view_map[SR_CHANNEL_GROUP] = TIME_VIEW;
    _trace_view_map[SR_CHANNEL_DECODER] = TIME_VIEW;
    _trace_view_map[SR_CHANNEL_ANALOG] = TIME_VIEW;
    _trace_view_map[SR_CHANNEL_DSO] = TIME_VIEW;
    _trace_view_map[SR_CHANNEL_FFT] = FFT_VIEW;
Andy Dneg's avatar
Andy Dneg committed
117 118
    _trace_view_map[SR_CHANNEL_LISSAJOUS] = TIME_VIEW;
    _trace_view_map[SR_CHANNEL_MATH] = TIME_VIEW;
DreamSourceLab's avatar
DreamSourceLab committed
119 120 121 122 123 124

    _active_viewport = NULL;
    _ruler = new Ruler(*this);
    _header = new Header(*this);
    _devmode = new DevMode(this, session);

DreamSourceLab's avatar
DreamSourceLab committed
125
    setViewportMargins(headerWidth(), RulerHeight, 0, 0);
DreamSourceLab's avatar
DreamSourceLab committed
126 127 128 129 130 131 132 133
    //setViewport(_viewport);

    // windows splitter
    _time_viewport = new Viewport(*this, TIME_VIEW);
    _time_viewport->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
    _time_viewport->setMinimumHeight(100);
    connect(_time_viewport, SIGNAL(measure_updated()),
            this, SLOT(on_measure_updated()));
134
    connect(_time_viewport, SIGNAL(prgRate(int)), this, SIGNAL(prgRate(int)));
DreamSourceLab's avatar
DreamSourceLab committed
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
    _fft_viewport = new Viewport(*this, FFT_VIEW);
    _fft_viewport->setVisible(false);
    _fft_viewport->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
    _fft_viewport->setMinimumHeight(100);
    connect(_fft_viewport, SIGNAL(measure_updated()),
            this, SLOT(on_measure_updated()));

    _vsplitter = new QSplitter(this);
    _vsplitter->setOrientation(Qt::Vertical);
    _vsplitter->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);

    _viewport_list.push_back(_time_viewport);
    _vsplitter->addWidget(_time_viewport);
    _vsplitter->setCollapsible(0, false);
    _vsplitter->setStretchFactor(0, 2);
    _viewport_list.push_back(_fft_viewport);
    _vsplitter->addWidget(_fft_viewport);
    _vsplitter->setCollapsible(1, false);
    _vsplitter->setStretchFactor(1, 1);

    _viewcenter = new QWidget(this);
    _viewcenter->setContentsMargins(0,0,0,0);
    QGridLayout* layout = new QGridLayout(_viewcenter);
158
    layout->setSpacing(0);
DreamSourceLab's avatar
DreamSourceLab committed
159 160 161
    layout->setContentsMargins(0,0,0,0);
    _viewcenter->setLayout(layout);
    layout->addWidget(_vsplitter, 0, 0);
Andy Dneg's avatar
Andy Dneg committed
162
    _viewbottom = new ViewStatus(_session, *this);
163 164
    _viewbottom->setFixedHeight(StatusHeight);
    layout->addWidget(_viewbottom, 1, 0);
DreamSourceLab's avatar
DreamSourceLab committed
165 166 167
    setViewport(_viewcenter);
    connect(_vsplitter, SIGNAL(splitterMoved(int,int)),
        this, SLOT(splitterMoved(int, int)));
DreamSourceLab's avatar
DreamSourceLab committed
168

169 170
    connect(&_session, SIGNAL(device_setted()),
            _devmode, SLOT(set_device()));
171
    connect(&_session, SIGNAL(signals_changed()),
172
        this, SLOT(signals_changed()), Qt::DirectConnection);
173 174
    connect(&_session, SIGNAL(data_updated()),
        this, SLOT(data_updated()));
DreamSourceLab's avatar
DreamSourceLab committed
175
    connect(&_session, SIGNAL(receive_trigger(quint64)),
176
            this, SLOT(receive_trigger(quint64)));
177 178 179 180
    connect(&_session, SIGNAL(frame_ended()),
            this, SLOT(receive_end()));
    connect(&_session, SIGNAL(frame_began()),
            this, SLOT(frame_began()));
181 182
    connect(&_session, SIGNAL(show_region(uint64_t, uint64_t, bool)),
            this, SLOT(show_region(uint64_t, uint64_t, bool)));
183 184
    connect(&_session, SIGNAL(show_wait_trigger()),
            _time_viewport, SLOT(show_wait_trigger()));
185 186
    connect(&_session, SIGNAL(repeat_hold(int)),
            this, SLOT(repeat_show()));
DreamSourceLab's avatar
DreamSourceLab committed
187

Andy Dneg's avatar
Andy Dneg committed
188 189
    connect(_devmode, SIGNAL(dev_changed(bool)),
            this, SLOT(dev_changed(bool)), Qt::DirectConnection);
DreamSourceLab's avatar
DreamSourceLab committed
190 191 192

    connect(_header, SIGNAL(traces_moved()),
        this, SLOT(on_traces_moved()));
DreamSourceLab's avatar
DreamSourceLab committed
193 194 195
    connect(_header, SIGNAL(header_updated()),
        this, SLOT(header_updated()));

DreamSourceLab's avatar
DreamSourceLab committed
196 197
    _time_viewport->installEventFilter(this);
    _fft_viewport->installEventFilter(this);
DreamSourceLab's avatar
DreamSourceLab committed
198 199
	_ruler->installEventFilter(this);
	_header->installEventFilter(this);
DreamSourceLab's avatar
DreamSourceLab committed
200
    _devmode->installEventFilter(this);
DreamSourceLab's avatar
DreamSourceLab committed
201

DreamSourceLab's avatar
DreamSourceLab committed
202
    _viewcenter->setObjectName(tr("ViewArea_center"));
DreamSourceLab's avatar
DreamSourceLab committed
203 204 205
    _ruler->setObjectName(tr("ViewArea_ruler"));
    _header->setObjectName(tr("ViewArea_header"));

Andy Dneg's avatar
Andy Dneg committed
206 207 208
    QColor fore(QWidget::palette().color(QWidget::foregroundRole()));
    fore.setAlpha(View::BackAlpha);

DreamSourceLab's avatar
DreamSourceLab committed
209
    _show_trig_cursor = false;
DreamSourceLab's avatar
DreamSourceLab committed
210
    _trig_cursor = new Cursor(*this, View::LightRed, 0);
DreamSourceLab's avatar
DreamSourceLab committed
211 212
    _show_search_cursor = false;
    _search_pos = 0;
Andy Dneg's avatar
Andy Dneg committed
213
    _search_cursor = new Cursor(*this, fore, _search_pos);
214 215 216

    _cali = new pv::dialogs::Calibration(this);
    _cali->hide();
DreamSourceLab's avatar
DreamSourceLab committed
217 218 219 220 221 222 223 224 225 226 227 228
}

SigSession& View::session()
{
	return _session;
}

double View::scale() const
{
	return _scale;
}

229
int64_t View::offset() const
DreamSourceLab's avatar
DreamSourceLab committed
230 231 232 233
{
	return _offset;
}

234 235 236 237 238 239 240 241 242 243
double View::trig_hoff() const
{
    return _trig_hoff;
}

void View::set_trig_hoff(double hoff)
{
    _trig_hoff = hoff;
}

DreamSourceLab's avatar
DreamSourceLab committed
244 245 246 247 248 249 250 251 252 253
double View::get_minscale() const
{
    return _minscale;
}

double View::get_maxscale() const
{
    return _maxscale;
}

254
void View::capture_init()
255 256 257 258 259
{
    if (_session.get_device()->dev_inst()->mode == DSO)
        show_trig_cursor(true);
    else if (!_session.isRepeating())
        show_trig_cursor(false);
260 261

    _maxscale = _session.cur_sampletime() / (get_view_width() * MaxViewRate);
262 263
    if (_session.get_device()->dev_inst()->mode == ANALOG)
        set_scale_offset(_maxscale, 0);
264
    status_clear();
Andy Dneg's avatar
Andy Dneg committed
265
    _trig_time_setted = false;
266
    _trig_hoff = 0;
267 268
}

DreamSourceLab's avatar
DreamSourceLab committed
269 270
void View::zoom(double steps)
{
DreamSourceLab's avatar
DreamSourceLab committed
271
    zoom(steps, get_view_width() / 2);
DreamSourceLab's avatar
DreamSourceLab committed
272 273
}

DreamSourceLab's avatar
DreamSourceLab committed
274
void View::set_update(Viewport *viewport, bool need_update)
DreamSourceLab's avatar
DreamSourceLab committed
275
{
DreamSourceLab's avatar
DreamSourceLab committed
276
    viewport->set_need_update(need_update);
DreamSourceLab's avatar
DreamSourceLab committed
277 278
}

DreamSourceLab's avatar
DreamSourceLab committed
279
void View::set_all_update(bool need_update)
DreamSourceLab's avatar
DreamSourceLab committed
280
{
Andy Dneg's avatar
Andy Dneg committed
281 282
   _time_viewport->set_need_update(need_update);
   _fft_viewport->set_need_update(need_update);
DreamSourceLab's avatar
DreamSourceLab committed
283 284
}

285 286 287 288 289
double View::get_hori_res()
{
    return _sampling_bar->get_hori_res();
}

290
void View::update_hori_res()
DreamSourceLab's avatar
DreamSourceLab committed
291
{
292
    if (_session.get_device()->dev_inst()->mode == DSO) {
293
        _sampling_bar->hori_knob(0);
294
    }
DreamSourceLab's avatar
DreamSourceLab committed
295 296
}

297
bool View::zoom(double steps, int offset)
DreamSourceLab's avatar
DreamSourceLab committed
298
{
299
    bool ret = true;
300 301
    _preScale = _scale;
    _preOffset = _offset;
DreamSourceLab's avatar
DreamSourceLab committed
302

303 304 305 306 307 308
    if (_session.get_device()->dev_inst()->mode != DSO) {
        _scale *= std::pow(3.0/2.0, -steps);
        _scale = max(min(_scale, _maxscale), _minscale);
    } else {
        if (_session.get_capture_state() == SigSession::Running &&
            _session.get_instant())
309
            return ret;
310 311 312 313 314 315 316 317 318 319

        double hori_res = -1;
        if(steps > 0.5)
            hori_res = _sampling_bar->hori_knob(-1);
        else if (steps < -0.5)
            hori_res = _sampling_bar->hori_knob(1);

        if (hori_res > 0) {
            const double scale = _session.cur_view_time() / get_view_width();
            _scale = max(min(scale, _maxscale), _minscale);
320 321
        } else {
            ret = false;
DreamSourceLab's avatar
v0.3  
DreamSourceLab committed
322
        }
323
    }
324

325 326
    _offset = floor((_offset + offset) * (_preScale / _scale) - offset);
    _offset = max(min(_offset, get_max_offset()), get_min_offset());
DreamSourceLab's avatar
DreamSourceLab committed
327

328 329 330 331 332 333
    if (_scale != _preScale || _offset != _preOffset) {
        _header->update();
        _ruler->update();
        viewport_update();
        update_scroll();
    }
334 335

    return ret;
DreamSourceLab's avatar
DreamSourceLab committed
336 337
}

338 339 340 341 342 343 344 345
void View::timebase_changed()
{
    if (_session.get_device()->dev_inst()->mode != DSO)
        return;

    double scale = this->scale();
    double hori_res = _sampling_bar->get_hori_res();
    if (hori_res > 0)
346
        scale = _session.cur_view_time() / get_view_width();
347 348 349
    set_scale_offset(scale, this->offset());
}

350
void View::set_scale_offset(double scale, int64_t offset)
DreamSourceLab's avatar
DreamSourceLab committed
351 352 353 354 355
{
    //if (_session.get_capture_state() == SigSession::Stopped) {
        _preScale = _scale;
        _preOffset = _offset;

DreamSourceLab's avatar
DreamSourceLab committed
356
        _scale = max(min(scale, _maxscale), _minscale);
357
        _offset = floor(max(min(offset, get_max_offset()), get_min_offset()));
DreamSourceLab's avatar
DreamSourceLab committed
358 359 360

        if (_scale != _preScale || _offset != _preOffset) {
            update_scroll();
DreamSourceLab's avatar
DreamSourceLab committed
361
            _header->update();
DreamSourceLab's avatar
DreamSourceLab committed
362
            _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
363
            viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
364 365 366 367 368 369 370 371 372 373 374 375 376
        }
    //}
}

void View::set_preScale_preOffset()
{
    //assert(_preScale <= _maxscale);
    //assert(_preScale >= _minscale);
    //assert(_preOffset >= 0);

    set_scale_offset(_preScale, _preOffset);
}

DreamSourceLab's avatar
DreamSourceLab committed
377
vector< boost::shared_ptr<Trace> > View::get_traces(int type)
DreamSourceLab's avatar
DreamSourceLab committed
378
{
379
    const vector< boost::shared_ptr<Signal> > sigs(_session.get_signals());
DreamSourceLab's avatar
DreamSourceLab committed
380
    const vector< boost::shared_ptr<GroupSignal> > groups(_session.get_group_signals());
DreamSourceLab's avatar
DreamSourceLab committed
381
#ifdef ENABLE_DECODE
382
    const vector< boost::shared_ptr<DecodeTrace> > decode_sigs(
DreamSourceLab's avatar
DreamSourceLab committed
383 384
        _session.get_decode_signals());
#endif
Andy Dneg's avatar
Andy Dneg committed
385
    const vector< boost::shared_ptr<SpectrumTrace> > spectrums(_session.get_spectrum_traces());
DreamSourceLab's avatar
DreamSourceLab committed
386

DreamSourceLab's avatar
DreamSourceLab committed
387 388 389 390 391
    vector< boost::shared_ptr<Trace> > traces;
    BOOST_FOREACH(boost::shared_ptr<Trace> t, sigs) {
        if (type == ALL_VIEW || _trace_view_map[t->get_type()] == type)
            traces.push_back(t);
    }
DreamSourceLab's avatar
DreamSourceLab committed
392
#ifdef ENABLE_DECODE
DreamSourceLab's avatar
DreamSourceLab committed
393 394 395 396
    BOOST_FOREACH(boost::shared_ptr<Trace> t, decode_sigs) {
        if (type == ALL_VIEW || _trace_view_map[t->get_type()] == type)
            traces.push_back(t);
    }
DreamSourceLab's avatar
DreamSourceLab committed
397
#endif
DreamSourceLab's avatar
DreamSourceLab committed
398 399 400 401 402
    BOOST_FOREACH(boost::shared_ptr<Trace> t, groups) {
        if (type == ALL_VIEW || _trace_view_map[t->get_type()] == type)
            traces.push_back(t);
    }

Andy Dneg's avatar
Andy Dneg committed
403
    BOOST_FOREACH(boost::shared_ptr<Trace> t, spectrums) {
DreamSourceLab's avatar
DreamSourceLab committed
404 405 406
        if (type == ALL_VIEW || _trace_view_map[t->get_type()] == type)
            traces.push_back(t);
    }
DreamSourceLab's avatar
DreamSourceLab committed
407

Andy Dneg's avatar
Andy Dneg committed
408 409 410 411 412 413 414 415 416 417
    boost::shared_ptr<LissajousTrace> lissajous = _session.get_lissajous_trace();
    if (lissajous && lissajous->enabled() &&
        (type == ALL_VIEW || _trace_view_map[lissajous->get_type()] == type))
        traces.push_back(lissajous);

    boost::shared_ptr<MathTrace> math = _session.get_math_trace();
    if (math && math->enabled() &&
        (type == ALL_VIEW || _trace_view_map[math->get_type()] == type))
        traces.push_back(math);

DreamSourceLab's avatar
DreamSourceLab committed
418 419 420 421
    stable_sort(traces.begin(), traces.end(), compare_trace_v_offsets);
    return traces;
}

422 423
bool View::compare_trace_v_offsets(const boost::shared_ptr<Trace> &a,
    const boost::shared_ptr<Trace> &b)
DreamSourceLab's avatar
DreamSourceLab committed
424 425 426
{
    assert(a);
    assert(b);
427
    if (a->get_type() != b->get_type())
Andy Dneg's avatar
Andy Dneg committed
428 429 430
        return a->get_type() < b->get_type();
    else if (a->get_type() == SR_CHANNEL_DSO || a->get_type() == SR_CHANNEL_ANALOG)
        return a->get_index() < b->get_index();
431 432
    else
        return a->get_v_offset() < b->get_v_offset();
DreamSourceLab's avatar
DreamSourceLab committed
433 434
}

DreamSourceLab's avatar
DreamSourceLab committed
435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453
bool View::cursors_shown() const
{
	return _show_cursors;
}

bool View::trig_cursor_shown() const
{
    return _show_trig_cursor;
}

bool View::search_cursor_shown() const
{
    return _show_search_cursor;
}

void View::show_cursors(bool show)
{
	_show_cursors = show;
	_ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
454
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
455 456 457 458 459 460
}

void View::show_trig_cursor(bool show)
{
    _show_trig_cursor = show;
    _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
461
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
462 463 464 465 466 467
}

void View::show_search_cursor(bool show)
{
    _show_search_cursor = show;
    _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
468
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
469 470
}

471 472
void View::status_clear()
{
473 474
    _time_viewport->clear_dso_xm();
    _time_viewport->clear_measure();
475 476 477
    _viewbottom->clear();
}

478
void View::repeat_unshow()
479
{
480
    _viewbottom->repeat_unshow();
481 482 483 484
}

void View::frame_began()
{
Andy Dneg's avatar
Andy Dneg committed
485
//    if (_session.get_device()->dev_inst()->mode == LOGIC)
486
//        _viewbottom->set_trig_time(_session.get_session_time());
487 488 489
    _search_hit = false;
    _search_pos = 0;
    set_search_pos(_search_pos, _search_hit);
490 491
}

Andy Dneg's avatar
Andy Dneg committed
492 493 494
void View::set_trig_time()
{
    if (!_trig_time_setted && _session.get_device()->dev_inst()->mode == LOGIC) {
495 496
        _session.set_session_time(QDateTime::currentDateTime());
        _viewbottom->set_trig_time(_session.get_session_time());
Andy Dneg's avatar
Andy Dneg committed
497 498 499 500 501 502 503 504 505
    }
    _trig_time_setted = true;
}

bool View::trig_time_setted()
{
    return _trig_time_setted;
}

506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524
void View::receive_end()
{
    if (_session.get_device()->dev_inst()->mode == LOGIC) {
        GVariant *gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_RLE);
        if (gvar != NULL) {
            bool rle = g_variant_get_boolean(gvar);
            g_variant_unref(gvar);
            if (rle) {
                gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_ACTUAL_SAMPLES);
                if (gvar != NULL) {
                    uint64_t actual_samples = g_variant_get_uint64(gvar);
                    g_variant_unref(gvar);
                    if (actual_samples != _session.cur_samplelimits()) {
                        _viewbottom->set_rle_depth(actual_samples);
                    }
                }
            }
        }
    }
525
    _time_viewport->unshow_wait_trigger();
526 527
}

528
void View::receive_trigger(quint64 trig_pos)
DreamSourceLab's avatar
DreamSourceLab committed
529
{
530
    const double time = trig_pos * 1.0 / _session.cur_snap_samplerate();
531
    _trig_cursor->set_index(trig_pos);
532 533 534
    if (ds_trigger_get_en() ||
        _session.get_device()->name() == "virtual-session" ||
        _session.get_device()->dev_inst()->mode == DSO) {
535
        _show_trig_cursor = true;
536
        set_scale_offset(_scale,  (time / _scale) - (get_view_width() / 2));
537
    }
538

DreamSourceLab's avatar
DreamSourceLab committed
539
    _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
540
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
541 542
}

543 544 545 546 547 548
void View::set_trig_pos(int percent)
{
    uint64_t index = _session.cur_samplelimits() * percent / 100;
    receive_trigger(index);
}

549
void View::set_search_pos(uint64_t search_pos, bool hit)
DreamSourceLab's avatar
DreamSourceLab committed
550 551
{
    //assert(search_pos >= 0);
Andy Dneg's avatar
Andy Dneg committed
552 553
    QColor fore(QWidget::palette().color(QWidget::foregroundRole()));
    fore.setAlpha(View::BackAlpha);
DreamSourceLab's avatar
DreamSourceLab committed
554

555
    const double time = search_pos * 1.0 / _session.cur_snap_samplerate();
DreamSourceLab's avatar
DreamSourceLab committed
556
    _search_pos = search_pos;
557
    _search_hit = hit;
558
    _search_cursor->set_index(search_pos);
Andy Dneg's avatar
Andy Dneg committed
559
    _search_cursor->set_colour(hit ? View::Blue : fore);
560 561 562 563 564 565

    if (hit) {
        set_scale_offset(_scale,  (time / _scale) - (get_view_width() / 2));
        _ruler->update();
        viewport_update();
    }
DreamSourceLab's avatar
DreamSourceLab committed
566 567 568 569 570 571 572
}

uint64_t View::get_search_pos()
{
    return _search_pos;
}

573 574 575 576 577
bool View::get_search_hit()
{
    return _search_hit;
}

578
const QPoint& View::hover_point() const
DreamSourceLab's avatar
DreamSourceLab committed
579 580 581 582 583 584
{
	return _hover_point;
}

void View::normalize_layout()
{
DreamSourceLab's avatar
DreamSourceLab committed
585
    const vector< boost::shared_ptr<Trace> > traces(get_traces(ALL_VIEW));
DreamSourceLab's avatar
DreamSourceLab committed
586 587

	int v_min = INT_MAX;
588
    BOOST_FOREACH(const boost::shared_ptr<Trace> t, traces)
DreamSourceLab's avatar
DreamSourceLab committed
589
        v_min = min(t->get_v_offset(), v_min);
DreamSourceLab's avatar
DreamSourceLab committed
590 591

	const int delta = -min(v_min, 0);
592
    BOOST_FOREACH(boost::shared_ptr<Trace> t, traces)
DreamSourceLab's avatar
DreamSourceLab committed
593
        t->set_v_offset(t->get_v_offset() + delta);
DreamSourceLab's avatar
DreamSourceLab committed
594

DreamSourceLab's avatar
DreamSourceLab committed
595
    verticalScrollBar()->setSliderPosition(delta);
DreamSourceLab's avatar
DreamSourceLab committed
596 597 598 599 600 601 602 603 604 605 606
	v_scroll_value_changed(verticalScrollBar()->sliderPosition());
}


int View::get_spanY()
{
    return _spanY;
}

int View::get_signalHeight()
{
DreamSourceLab's avatar
DreamSourceLab committed
607
    return _signalHeight;
DreamSourceLab's avatar
DreamSourceLab committed
608 609
}

610
void View::get_scroll_layout(int64_t &length, int64_t &offset) const
DreamSourceLab's avatar
DreamSourceLab committed
611
{
612
    const set< boost::shared_ptr<data::SignalData> > data_set = _session.get_data();
DreamSourceLab's avatar
DreamSourceLab committed
613
    if (data_set.empty())
DreamSourceLab's avatar
DreamSourceLab committed
614 615
		return;

616
    length = ceil(_session.cur_snap_sampletime() / _scale);
617
    offset = _offset;
DreamSourceLab's avatar
DreamSourceLab committed
618 619 620 621
}

void View::update_scroll()
{
DreamSourceLab's avatar
DreamSourceLab committed
622
    assert(_viewcenter);
DreamSourceLab's avatar
DreamSourceLab committed
623

Andy Dneg's avatar
Andy Dneg committed
624
    const QSize areaSize = QSize(get_view_width(), get_view_height());
DreamSourceLab's avatar
DreamSourceLab committed
625 626

	// Set the horizontal scroll bar
627 628
    int64_t length = 0;
    int64_t offset = 0;
DreamSourceLab's avatar
DreamSourceLab committed
629
	get_scroll_layout(length, offset);
630
    length = max(length - areaSize.width(), (int64_t)0);
DreamSourceLab's avatar
DreamSourceLab committed
631 632 633 634 635 636 637 638 639 640 641

	horizontalScrollBar()->setPageStep(areaSize.width() / 2);

	_updating_scroll = true;

	if (length < MaxScrollValue) {
		horizontalScrollBar()->setRange(0, length);
		horizontalScrollBar()->setSliderPosition(offset);
	} else {
		horizontalScrollBar()->setRange(0, MaxScrollValue);
		horizontalScrollBar()->setSliderPosition(
DreamSourceLab's avatar
DreamSourceLab committed
642
            _offset * 1.0  / length * MaxScrollValue);
DreamSourceLab's avatar
DreamSourceLab committed
643 644 645 646 647 648
	}

	_updating_scroll = false;

	// Set the vertical scrollbar
	verticalScrollBar()->setPageStep(areaSize.height());
DreamSourceLab's avatar
DreamSourceLab committed
649
    verticalScrollBar()->setRange(0,0);
DreamSourceLab's avatar
DreamSourceLab committed
650 651
}

652
void View::update_scale_offset()
DreamSourceLab's avatar
DreamSourceLab committed
653
{
DreamSourceLab's avatar
DreamSourceLab committed
654
    if (_session.get_device()->dev_inst()->mode != DSO) {
655
        _maxscale = _session.cur_sampletime() / (get_view_width() * MaxViewRate);
656
        _minscale = (1.0 / _session.cur_snap_samplerate()) / MaxPixelsPerSample;
DreamSourceLab's avatar
DreamSourceLab committed
657
    } else {
658
        _scale = _session.cur_view_time() / get_view_width();
DreamSourceLab's avatar
DreamSourceLab committed
659
        _maxscale = 1e9;
660
        _minscale = 1e-15;
DreamSourceLab's avatar
DreamSourceLab committed
661
    }
662

663 664 665
    _scale = max(min(_scale, _maxscale), _minscale);
    _offset = max(min(_offset, get_max_offset()), get_min_offset());

DreamSourceLab's avatar
DreamSourceLab committed
666
    _preScale = _scale;
667
    _preOffset = _offset;
DreamSourceLab's avatar
DreamSourceLab committed
668

669
    //_trig_cursor->set_index(_session.get_trigger_pos());
DreamSourceLab's avatar
DreamSourceLab committed
670 671

    _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
672
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
673 674
}

Andy Dneg's avatar
Andy Dneg committed
675
void View::dev_changed(bool close)
676
{
Andy Dneg's avatar
Andy Dneg committed
677 678
    if (!close) {
        if (_session.get_device()->name().contains("virtual"))
679
            _scale = WellSamplesPerPixel * 1.0 / _session.cur_snap_samplerate();
Andy Dneg's avatar
Andy Dneg committed
680 681
        _scale = max(min(_scale, _maxscale), _minscale);
    }
682

Andy Dneg's avatar
Andy Dneg committed
683
    device_changed(close);
684 685
}

DreamSourceLab's avatar
DreamSourceLab committed
686 687 688
void View::signals_changed()
{
    int total_rows = 0;
Andy Dneg's avatar
Andy Dneg committed
689
    int label_size = 0;
690
    uint8_t max_height = MaxHeightUnit;
DreamSourceLab's avatar
DreamSourceLab committed
691 692
    vector< boost::shared_ptr<Trace> > time_traces;
    vector< boost::shared_ptr<Trace> > fft_traces;
693

DreamSourceLab's avatar
DreamSourceLab committed
694 695 696 697 698 699
    BOOST_FOREACH(const boost::shared_ptr<Trace> t, get_traces(ALL_VIEW)) {
        if (_trace_view_map[t->get_type()] == TIME_VIEW)
            time_traces.push_back(t);
        else if (_trace_view_map[t->get_type()] == FFT_VIEW)
            if (t->enabled())
                fft_traces.push_back(t);
DreamSourceLab's avatar
DreamSourceLab committed
700
    }
DreamSourceLab's avatar
DreamSourceLab committed
701

DreamSourceLab's avatar
DreamSourceLab committed
702 703 704 705 706 707 708 709 710 711 712 713
    if (!fft_traces.empty()) {
        if (!_fft_viewport->isVisible()) {
            _fft_viewport->setVisible(true);
            _fft_viewport->clear_measure();
            _viewport_list.push_back(_fft_viewport);
            _vsplitter->refresh();
        }
        BOOST_FOREACH(boost::shared_ptr<Trace> t, fft_traces) {
            t->set_view(this);
            t->set_viewport(_fft_viewport);
            t->set_totalHeight(_fft_viewport->height());
            t->set_v_offset(_fft_viewport->geometry().bottom());
714 715
        }
    } else {
DreamSourceLab's avatar
DreamSourceLab committed
716 717 718
        _fft_viewport->setVisible(false);
        _vsplitter->refresh();

719
        // Find the _fft_viewport in the stack
Andy Dneg's avatar
Andy Dneg committed
720
        std::list< QWidget *>::iterator iter = _viewport_list.begin();
721
        for(unsigned int i = 0; i < _viewport_list.size(); i++, iter++)
DreamSourceLab's avatar
DreamSourceLab committed
722 723 724 725 726 727 728 729 730 731 732 733 734
            if ((*iter) == _fft_viewport)
                break;
        // Delete the element
        if (iter != _viewport_list.end())
            _viewport_list.erase(iter);
    }

    if (!time_traces.empty() && _time_viewport) {
        BOOST_FOREACH(const boost::shared_ptr<Trace> t, time_traces) {
            assert(t);
            if (dynamic_pointer_cast<DsoSignal>(t) ||
                t->enabled())
                total_rows += t->rows_size();
Andy Dneg's avatar
Andy Dneg committed
735 736
            if (t->rows_size() != 0)
                label_size++;
DreamSourceLab's avatar
DreamSourceLab committed
737 738 739
        }

        const double height = (_time_viewport->height()
Andy Dneg's avatar
Andy Dneg committed
740
                               - 2 * SignalMargin * label_size) * 1.0 / total_rows;
DreamSourceLab's avatar
DreamSourceLab committed
741 742 743 744 745 746 747 748 749 750 751

        if (_session.get_device()->dev_inst()->mode == LOGIC) {
            GVariant* gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_MAX_HEIGHT_VALUE);
            if (gvar != NULL) {
                max_height = (g_variant_get_byte(gvar) + 1) * MaxHeightUnit;
                g_variant_unref(gvar);
            }
            _signalHeight = (int)((height <= 0) ? 1 : (height >= max_height) ? max_height : height);
        } else if (_session.get_device()->dev_inst()->mode == DSO) {
            _signalHeight = (_header->height()
                             - horizontalScrollBar()->height()
Andy Dneg's avatar
Andy Dneg committed
752
                             - 2 * SignalMargin * label_size) * 1.0 / total_rows;
DreamSourceLab's avatar
DreamSourceLab committed
753 754 755 756 757 758 759 760
        } else {
            _signalHeight = (int)((height <= 0) ? 1 : height);
        }
        _spanY = _signalHeight + 2 * SignalMargin;
        int next_v_offset = SignalMargin;
        BOOST_FOREACH(boost::shared_ptr<Trace> t, time_traces) {
            t->set_view(this);
            t->set_viewport(_time_viewport);
Andy Dneg's avatar
Andy Dneg committed
761 762
            if (t->rows_size() == 0)
                continue;
DreamSourceLab's avatar
DreamSourceLab committed
763 764 765 766 767 768
            const double traceHeight = _signalHeight*t->rows_size();
            t->set_totalHeight((int)traceHeight);
            t->set_v_offset(next_v_offset + 0.5 * traceHeight + SignalMargin);
            next_v_offset += traceHeight + 2 * SignalMargin;

            boost::shared_ptr<view::DsoSignal> dsoSig;
769
            if ((dsoSig = dynamic_pointer_cast<view::DsoSignal>(t))) {
770
                dsoSig->set_scale(dsoSig->get_view_rect().height());
771
            }
Andy Dneg's avatar
Andy Dneg committed
772 773 774 775 776

            boost::shared_ptr<view::AnalogSignal> analogSig;
            if ((analogSig = dynamic_pointer_cast<view::AnalogSignal>(t))) {
                analogSig->set_scale(analogSig->get_totalHeight());
            }
DreamSourceLab's avatar
DreamSourceLab committed
777 778
        }
        _time_viewport->clear_measure();
779
    }
DreamSourceLab's avatar
DreamSourceLab committed
780 781 782

    header_updated();
    normalize_layout();
783
    update_scale_offset();
784
    data_updated();
DreamSourceLab's avatar
DreamSourceLab committed
785 786 787 788 789 790 791
}

bool View::eventFilter(QObject *object, QEvent *event)
{
	const QEvent::Type type = event->type();
	if (type == QEvent::MouseMove) {
		const QMouseEvent *const mouse_event = (QMouseEvent*)event;
DreamSourceLab's avatar
DreamSourceLab committed
792
        if (object == _ruler || object == _time_viewport || object == _fft_viewport) {
DreamSourceLab's avatar
DreamSourceLab committed
793
            //_hover_point = QPoint(mouse_event->x(), 0);
794 795
            double cur_periods = (mouse_event->pos().x() + _offset) * _scale / _ruler->get_min_period();
            int integer_x = round(cur_periods) * _ruler->get_min_period() / _scale - _offset;
DreamSourceLab's avatar
DreamSourceLab committed
796
            double cur_deviate_x = qAbs(mouse_event->pos().x() - integer_x);
797 798
            if (_session.get_device()->dev_inst()->mode == LOGIC &&
                cur_deviate_x < 10)
799
                _hover_point = QPoint(integer_x, mouse_event->pos().y());
DreamSourceLab's avatar
DreamSourceLab committed
800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824
            else
                _hover_point = mouse_event->pos();
        } else if (object == _header)
			_hover_point = QPoint(0, mouse_event->y());
		else
			_hover_point = QPoint(-1, -1);

		hover_point_changed();
	} else if (type == QEvent::Leave) {
		_hover_point = QPoint(-1, -1);
		hover_point_changed();
	}

	return QObject::eventFilter(object, event);
}

bool View::viewportEvent(QEvent *e)
{
	switch(e->type()) {
	case QEvent::Paint:
	case QEvent::MouseButtonPress:
	case QEvent::MouseButtonRelease:
	case QEvent::MouseButtonDblClick:
	case QEvent::MouseMove:
	case QEvent::Wheel:
825
    case QEvent::Gesture:
DreamSourceLab's avatar
DreamSourceLab committed
826 827 828 829 830 831 832 833 834
		return false;

	default:
		return QAbstractScrollArea::viewportEvent(e);
	}
}

int View::headerWidth()
{
835
    int headerWidth = _header->get_nameEditWidth();
DreamSourceLab's avatar
v0.21  
DreamSourceLab committed
836

DreamSourceLab's avatar
DreamSourceLab committed
837
    const vector< boost::shared_ptr<Trace> > traces(get_traces(ALL_VIEW));
838 839 840 841
    if (!traces.empty()) {
        BOOST_FOREACH(const boost::shared_ptr<Trace> t, traces)
            headerWidth = max(t->get_name_width() + t->get_leftWidth() + t->get_rightWidth(),
                              headerWidth);
DreamSourceLab's avatar
DreamSourceLab committed
842 843 844 845 846 847 848 849 850
    }

    setViewportMargins(headerWidth, RulerHeight, 0, 0);

    return headerWidth;
}

void View::resizeEvent(QResizeEvent*)
{
Andy Dneg's avatar
Andy Dneg committed
851
    reconstruct();
DreamSourceLab's avatar
DreamSourceLab committed
852
    setViewportMargins(headerWidth(), RulerHeight, 0, 0);
DreamSourceLab's avatar
DreamSourceLab committed
853 854
    update_margins();
    update_scroll();
DreamSourceLab's avatar
DreamSourceLab committed
855
    signals_changed();
DreamSourceLab's avatar
DreamSourceLab committed
856
    if (_session.get_device()->dev_inst()->mode == DSO)
857
        _scale = _session.cur_view_time() / get_view_width();
DreamSourceLab's avatar
DreamSourceLab committed
858

859
    if (_session.get_device()->dev_inst()->mode != DSO)
860
        _maxscale = _session.cur_sampletime() / (get_view_width() * MaxViewRate);
861 862 863
    else
        _maxscale = 1e9;

DreamSourceLab's avatar
DreamSourceLab committed
864 865 866
    _scale = min(_scale, _maxscale);

    _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
867
    _header->header_resize();
DreamSourceLab's avatar
DreamSourceLab committed
868 869
    set_update(_time_viewport, true);
    set_update(_fft_viewport, true);
870
    resize();
DreamSourceLab's avatar
DreamSourceLab committed
871 872 873 874 875 876 877 878 879 880 881
}

void View::h_scroll_value_changed(int value)
{
	if (_updating_scroll)
		return;

    _preOffset = _offset;

	const int range = horizontalScrollBar()->maximum();
	if (range < MaxScrollValue)
882
        _offset = value;
DreamSourceLab's avatar
DreamSourceLab committed
883
	else {
884 885
        int64_t length = 0;
        int64_t offset = 0;
DreamSourceLab's avatar
DreamSourceLab committed
886
		get_scroll_layout(length, offset);
DreamSourceLab's avatar
DreamSourceLab committed
887
        _offset = floor(value * 1.0 / MaxScrollValue * length);
DreamSourceLab's avatar
DreamSourceLab committed
888 889
	}

890
    _offset = max(min(_offset, get_max_offset()), get_min_offset());
DreamSourceLab's avatar
DreamSourceLab committed
891 892 893

    if (_offset != _preOffset) {
        _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
894
        viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
895 896 897 898 899
    }
}

void View::v_scroll_value_changed(int value)
{
900
    (void)value;
DreamSourceLab's avatar
DreamSourceLab committed
901
	_header->update();
DreamSourceLab's avatar
DreamSourceLab committed
902
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
903 904 905 906 907 908 909 910 911 912
}

void View::data_updated()
{
    setViewportMargins(headerWidth(), RulerHeight, 0, 0);
    update_margins();

	// Update the scroll bars
	update_scroll();

913 914 915
    // update scale & offset
    update_scale_offset();

DreamSourceLab's avatar
DreamSourceLab committed
916
	// Repaint the view
917
    _time_viewport->unshow_wait_trigger();
DreamSourceLab's avatar
DreamSourceLab committed
918 919 920
    set_update(_time_viewport, true);
    set_update(_fft_viewport, true);
    viewport_update();
921
    _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
922 923 924 925
}

void View::update_margins()
{
DreamSourceLab's avatar
DreamSourceLab committed
926 927 928 929
    _ruler->setGeometry(_viewcenter->x(), 0,
        get_view_width(), _viewcenter->y());
    _header->setGeometry(0, _viewcenter->y(),
        _viewcenter->x(), _viewcenter->height());
DreamSourceLab's avatar
DreamSourceLab committed
930
    _devmode->setGeometry(0, 0,
DreamSourceLab's avatar
DreamSourceLab committed
931
        _viewcenter->x(), _viewcenter->y());
DreamSourceLab's avatar
DreamSourceLab committed
932 933 934 935 936 937 938 939 940 941
}

void View::header_updated()
{
    headerWidth();
    update_margins();

    // Update the scroll bars
    update_scroll();

DreamSourceLab's avatar
DreamSourceLab committed
942
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
943 944 945 946 947 948
    _header->update();
}

void View::marker_time_changed()
{
	_ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
949
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
950 951
}

DreamSourceLab's avatar
DreamSourceLab committed
952
void View::on_traces_moved()
DreamSourceLab's avatar
DreamSourceLab committed
953 954
{
	update_scroll();
DreamSourceLab's avatar
DreamSourceLab committed
955 956
    set_update(_time_viewport, true);
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981
}

/*
 * cursorList
 */
std::list<Cursor*>& View::get_cursorList()
{
    return _cursorList;
}

Cursor* View::get_trig_cursor()
{
    return _trig_cursor;
}

Cursor* View::get_search_cursor()
{
    return _search_cursor;
}

Ruler* View::get_ruler()
{
    return _ruler;
}

982
void View::add_cursor(QColor color, uint64_t index)
DreamSourceLab's avatar
DreamSourceLab committed
983
{
984
    Cursor *newCursor = new Cursor(*this, color, index);
DreamSourceLab's avatar
DreamSourceLab committed
985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004
    _cursorList.push_back(newCursor);
    cursor_update();
}

void View::del_cursor(Cursor* cursor)
{
    assert(cursor);

    _cursorList.remove(cursor);
    delete cursor;
    cursor_update();
}

void View::set_cursor_middle(int index)
{
    assert(index < (int)_cursorList.size());

    list<Cursor*>::iterator i = _cursorList.begin();
    while (index-- != 0)
            i++;
1005
    set_scale_offset(_scale, (*i)->index() / (_session.cur_snap_samplerate() * _scale) - (get_view_width() / 2));
DreamSourceLab's avatar
DreamSourceLab committed
1006 1007
}

DreamSourceLab's avatar
DreamSourceLab committed
1008 1009 1010 1011 1012 1013 1014
void View::on_measure_updated()
{
    _active_viewport = dynamic_cast<Viewport *>(sender());
    measure_updated();
}

QString View::get_measure(QString option)
DreamSourceLab's avatar
DreamSourceLab committed
1015
{
DreamSourceLab's avatar
DreamSourceLab committed
1016 1017 1018 1019
    if (_active_viewport) {
        return _active_viewport->get_measure(option);
    }
    return "#####";
DreamSourceLab's avatar
DreamSourceLab committed
1020 1021 1022 1023
}

QString View::get_cm_time(int index)
{
1024
    return _ruler->format_real_time(get_cursor_samples(index), _session.cur_snap_samplerate());
DreamSourceLab's avatar
DreamSourceLab committed
1025 1026 1027 1028 1029 1030 1031
}

QString View::get_cm_delta(int index1, int index2)
{
    if (index1 == index2)
        return "0";

1032 1033 1034
    uint64_t samples1 = get_cursor_samples(index1);
    uint64_t samples2 = get_cursor_samples(index2);
    uint64_t delta_sample = (samples1 > samples2) ? samples1 - samples2 : samples2 - samples1;
1035
    return _ruler->format_real_time(delta_sample, _session.cur_snap_samplerate());
DreamSourceLab's avatar
DreamSourceLab committed
1036 1037
}

1038 1039 1040 1041 1042 1043
QString View::get_index_delta(uint64_t start, uint64_t end)
{
    if (start == end)
        return "0";

    uint64_t delta_sample = (start > end) ? start - end : end - start;
1044
    return _ruler->format_real_time(delta_sample, _session.cur_snap_samplerate());
1045 1046
}

DreamSourceLab's avatar
DreamSourceLab committed
1047 1048
uint64_t View::get_cursor_samples(int index)
{
1049
    assert(index < (int)_cursorList.size());
DreamSourceLab's avatar
DreamSourceLab committed
1050

DreamSourceLab's avatar
DreamSourceLab committed
1051
    uint64_t ret = 0;
1052 1053 1054 1055
    int curIndex = 0;
    for (list<Cursor*>::iterator i = _cursorList.begin();
         i != _cursorList.end(); i++) {
        if (index == curIndex) {
DreamSourceLab's avatar
DreamSourceLab committed
1056
            ret = (*i)->index();
1057 1058 1059
        }
        curIndex++;
    }
DreamSourceLab's avatar
DreamSourceLab committed
1060
    return ret;
DreamSourceLab's avatar
DreamSourceLab committed
1061 1062
}

DreamSourceLab's avatar
DreamSourceLab committed
1063 1064
void View::set_measure_en(int enable)
{
Andy Dneg's avatar
Andy Dneg committed
1065 1066
    _time_viewport->set_measure_en(enable);
    _fft_viewport->set_measure_en(enable);
DreamSourceLab's avatar
DreamSourceLab committed
1067 1068 1069 1070
}

void View::on_state_changed(bool stop)
{
DreamSourceLab's avatar
DreamSourceLab committed
1071
    if (stop) {
Andy Dneg's avatar
Andy Dneg committed
1072 1073
        _time_viewport->stop_trigger_timer();
        _fft_viewport->stop_trigger_timer();
DreamSourceLab's avatar
DreamSourceLab committed
1074
    }
1075
    update_scale_offset();
DreamSourceLab's avatar
DreamSourceLab committed
1076 1077
}

1078 1079 1080 1081 1082 1083 1084 1085
QRect View::get_view_rect()
{
    if (_session.get_device()->dev_inst()->mode == DSO) {
        const vector< boost::shared_ptr<Signal> > sigs(_session.get_signals());
        BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
            return s->get_view_rect();
        }
    }
DreamSourceLab's avatar
DreamSourceLab committed
1086 1087

    return _viewcenter->rect();
1088 1089
}

DreamSourceLab's avatar
DreamSourceLab committed
1090
int View::get_view_width()
DreamSourceLab's avatar
v0.3  
DreamSourceLab committed
1091
{
DreamSourceLab's avatar
DreamSourceLab committed
1092 1093
    int view_width = 0;
    if (_session.get_device()->dev_inst()->mode == DSO) {
1094 1095
        const vector< boost::shared_ptr<Signal> > sigs(_session.get_signals());
        BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
1096
            view_width = max(view_width, s->get_view_rect().width());
DreamSourceLab's avatar
DreamSourceLab committed
1097 1098
        }
    } else {
DreamSourceLab's avatar
DreamSourceLab committed
1099
        view_width = _viewcenter->width();
DreamSourceLab's avatar
DreamSourceLab committed
1100
    }
DreamSourceLab's avatar
v0.3  
DreamSourceLab committed
1101

DreamSourceLab's avatar
DreamSourceLab committed
1102
    return view_width;
DreamSourceLab's avatar
v0.3  
DreamSourceLab committed
1103 1104
}

1105 1106 1107 1108 1109 1110
int View::get_view_height()
{
    int view_height = 0;
    if (_session.get_device()->dev_inst()->mode == DSO) {
        const vector< boost::shared_ptr<Signal> > sigs(_session.get_signals());
        BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
1111
            view_height = max(view_height, s->get_view_rect().height());
1112 1113
        }
    } else {
DreamSourceLab's avatar
DreamSourceLab committed
1114
        view_height = _viewcenter->height();
1115 1116 1117 1118 1119
    }

    return view_height;
}

1120
int64_t View::get_min_offset()
1121
{
1122 1123 1124 1125
    if (MaxViewRate > 1)
        return floor(get_view_width() * (1 - MaxViewRate));
    else
        return 0;
1126 1127
}

1128
int64_t View::get_max_offset()
1129
{
1130
    return ceil((_session.cur_snap_sampletime() / _scale) -
1131
                (get_view_width() * MaxViewRate));
1132 1133
}

1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145
// -- calibration dialog
void View::show_calibration()
{
    _cali->set_device(_session.get_device());
    _cali->show();
}

void View::hide_calibration()
{
    _cali->hide();
}

Andy Dneg's avatar
Andy Dneg committed
1146
void View::vDial_updated()
1147 1148 1149 1150
{
    if (_cali->isVisible()) {
        _cali->set_device(_session.get_device());
    }
Andy Dneg's avatar
Andy Dneg committed
1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161
    boost::shared_ptr<view::MathTrace> math_trace = _session.get_math_trace();
    if (math_trace && math_trace->enabled()) {
        math_trace->update_vDial();
    }
}

// -- lissajous figure
void View::show_lissajous(bool show)
{
    _show_lissajous = show;
    signals_changed();
1162 1163
}

1164
void View::show_region(uint64_t start, uint64_t end, bool keep)
1165 1166
{
    assert(start <= end);
1167 1168 1169 1170
    if (keep) {
        set_all_update(true);
        update();
    } else if (_session.get_map_zoom() == 0) {
1171
        const double ideal_scale = (end-start) * 2.0 / _session.cur_snap_samplerate() / get_view_width();
1172
        const double new_scale = max(min(ideal_scale, _maxscale), _minscale);
1173
        const double new_off = (start + end)  * 0.5 / (_session.cur_snap_samplerate() * new_scale) - (get_view_width() / 2);
1174 1175 1176
        set_scale_offset(new_scale, new_off);
    } else {
        const double new_scale = scale();
1177
        const double new_off = (start + end)  * 0.5 / (_session.cur_snap_samplerate() * new_scale) - (get_view_width() / 2);
1178 1179
        set_scale_offset(new_scale, new_off);
    }
1180 1181
}

DreamSourceLab's avatar
DreamSourceLab committed
1182 1183 1184
void View::viewport_update()
{
    _viewcenter->update();
Andy Dneg's avatar
Andy Dneg committed
1185
    BOOST_FOREACH(QWidget *viewport, _viewport_list)
DreamSourceLab's avatar
DreamSourceLab committed
1186 1187 1188 1189 1190 1191 1192 1193 1194 1195
        viewport->update();
}

void View::splitterMoved(int pos, int index