view.cpp 32.5 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 29
 *
 * 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
30
#include <QApplication>
DreamSourceLab's avatar
DreamSourceLab committed
31 32 33 34
#include <QEvent>
#include <QMouseEvent>
#include <QScrollBar>

DreamSourceLab's avatar
DreamSourceLab committed
35
#include "groupsignal.h"
DreamSourceLab's avatar
DreamSourceLab committed
36
#include "decodetrace.h"
DreamSourceLab's avatar
DreamSourceLab committed
37
#include "header.h"
DreamSourceLab's avatar
DreamSourceLab committed
38
#include "devmode.h"
DreamSourceLab's avatar
DreamSourceLab committed
39 40
#include "ruler.h"
#include "signal.h"
DreamSourceLab's avatar
DreamSourceLab committed
41
#include "dsosignal.h"
DreamSourceLab's avatar
DreamSourceLab committed
42 43
#include "view.h"
#include "viewport.h"
DreamSourceLab's avatar
DreamSourceLab committed
44
#include "mathtrace.h"
DreamSourceLab's avatar
DreamSourceLab committed
45

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

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;
62
const int View::MaxHeightUnit = 20;
DreamSourceLab's avatar
DreamSourceLab committed
63 64 65 66 67 68 69 70 71

//const int View::SignalHeight = 30;s
const int View::SignalMargin = 10;
const int View::SignalSnapGridSize = 10;

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

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

DreamSourceLab's avatar
DreamSourceLab committed
72
View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget *parent) :
DreamSourceLab's avatar
DreamSourceLab committed
73
    QScrollArea(parent),
DreamSourceLab's avatar
DreamSourceLab committed
74
	_session(session),
DreamSourceLab's avatar
DreamSourceLab committed
75
    _sampling_bar(sampling_bar),
76
    _scale(10),
DreamSourceLab's avatar
DreamSourceLab committed
77 78 79 80 81 82 83
    _preScale(1e-6),
    _maxscale(1e9),
    _minscale(1e-15),
	_offset(0),
    _preOffset(0),
	_updating_scroll(false),
	_show_cursors(false),
84
    _hover_point(-1, -1),
85
    _search_hit(false),
86
    _dso_auto(true)
DreamSourceLab's avatar
DreamSourceLab committed
87 88 89 90 91 92 93 94
{
    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
95 96 97 98 99 100 101 102 103 104 105 106 107
    // 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;

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

DreamSourceLab's avatar
DreamSourceLab committed
108
    setViewportMargins(headerWidth(), RulerHeight, 0, 0);
DreamSourceLab's avatar
DreamSourceLab committed
109 110 111 112 113 114 115 116
    //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()));
117
    connect(_time_viewport, SIGNAL(prgRate(int)), this, SIGNAL(prgRate(int)));
DreamSourceLab's avatar
DreamSourceLab committed
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
    _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);
141
    layout->setSpacing(0);
DreamSourceLab's avatar
DreamSourceLab committed
142 143 144
    layout->setContentsMargins(0,0,0,0);
    _viewcenter->setLayout(layout);
    layout->addWidget(_vsplitter, 0, 0);
145
    _viewbottom = new widgets::ViewStatus(_session, this);
146 147
    _viewbottom->setFixedHeight(StatusHeight);
    layout->addWidget(_viewbottom, 1, 0);
DreamSourceLab's avatar
DreamSourceLab committed
148 149 150
    setViewport(_viewcenter);
    connect(_vsplitter, SIGNAL(splitterMoved(int,int)),
        this, SLOT(splitterMoved(int, int)));
DreamSourceLab's avatar
DreamSourceLab committed
151

152 153
    connect(&_session, SIGNAL(device_setted()),
            _devmode, SLOT(set_device()));
154
    connect(&_session, SIGNAL(signals_changed()),
155
        this, SLOT(signals_changed()), Qt::DirectConnection);
156 157
    connect(&_session, SIGNAL(data_updated()),
        this, SLOT(data_updated()));
DreamSourceLab's avatar
DreamSourceLab committed
158
    connect(&_session, SIGNAL(receive_trigger(quint64)),
159
            this, SLOT(receive_trigger(quint64)));
160 161 162 163
    connect(&_session, SIGNAL(frame_ended()),
            this, SLOT(receive_end()));
    connect(&_session, SIGNAL(frame_began()),
            this, SLOT(frame_began()));
164 165
    connect(&_session, SIGNAL(show_region(uint64_t, uint64_t, bool)),
            this, SLOT(show_region(uint64_t, uint64_t, bool)));
166 167
    connect(&_session, SIGNAL(show_wait_trigger()),
            _time_viewport, SLOT(show_wait_trigger()));
168 169
    connect(&_session, SIGNAL(repeat_hold(int)),
            this, SLOT(repeat_show()));
DreamSourceLab's avatar
DreamSourceLab committed
170

DreamSourceLab's avatar
DreamSourceLab committed
171
    connect(_devmode, SIGNAL(mode_changed()),
172
            this, SLOT(mode_changed()), Qt::DirectConnection);
DreamSourceLab's avatar
DreamSourceLab committed
173 174 175

    connect(_header, SIGNAL(traces_moved()),
        this, SLOT(on_traces_moved()));
DreamSourceLab's avatar
DreamSourceLab committed
176 177 178
    connect(_header, SIGNAL(header_updated()),
        this, SLOT(header_updated()));

DreamSourceLab's avatar
DreamSourceLab committed
179 180
    _time_viewport->installEventFilter(this);
    _fft_viewport->installEventFilter(this);
DreamSourceLab's avatar
DreamSourceLab committed
181 182
	_ruler->installEventFilter(this);
	_header->installEventFilter(this);
DreamSourceLab's avatar
DreamSourceLab committed
183
    _devmode->installEventFilter(this);
DreamSourceLab's avatar
DreamSourceLab committed
184

DreamSourceLab's avatar
DreamSourceLab committed
185
    _viewcenter->setObjectName(tr("ViewArea_center"));
DreamSourceLab's avatar
DreamSourceLab committed
186 187 188 189
    _ruler->setObjectName(tr("ViewArea_ruler"));
    _header->setObjectName(tr("ViewArea_header"));

    _show_trig_cursor = false;
190
    _trig_cursor = new Cursor(*this, Trace::dsLightRed, 0);
DreamSourceLab's avatar
DreamSourceLab committed
191 192
    _show_search_cursor = false;
    _search_pos = 0;
193
    _search_cursor = new Cursor(*this, Trace::dsGray, _search_pos);
194 195 196

    _cali = new pv::dialogs::Calibration(this);
    _cali->hide();
DreamSourceLab's avatar
DreamSourceLab committed
197 198 199 200 201 202 203 204 205 206 207 208
}

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

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

209
int64_t View::offset() const
DreamSourceLab's avatar
DreamSourceLab committed
210 211 212 213 214 215 216 217 218 219 220 221 222 223
{
	return _offset;
}

double View::get_minscale() const
{
    return _minscale;
}

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

224 225 226 227 228 229 230 231 232 233 234
void View::capture_init(bool instant)
{
    if (_session.get_device()->dev_inst()->mode == DSO)
        show_trig_cursor(true);
    else if (!_session.isRepeating())
        show_trig_cursor(false);

    update_sample(instant);
    status_clear();
}

DreamSourceLab's avatar
DreamSourceLab committed
235 236
void View::zoom(double steps)
{
DreamSourceLab's avatar
DreamSourceLab committed
237
    zoom(steps, get_view_width() / 2);
DreamSourceLab's avatar
DreamSourceLab committed
238 239
}

DreamSourceLab's avatar
DreamSourceLab committed
240
void View::set_update(Viewport *viewport, bool need_update)
DreamSourceLab's avatar
DreamSourceLab committed
241
{
DreamSourceLab's avatar
DreamSourceLab committed
242
    viewport->set_need_update(need_update);
DreamSourceLab's avatar
DreamSourceLab committed
243 244
}

DreamSourceLab's avatar
DreamSourceLab committed
245
void View::set_all_update(bool need_update)
DreamSourceLab's avatar
DreamSourceLab committed
246
{
DreamSourceLab's avatar
DreamSourceLab committed
247 248
    BOOST_FOREACH(Viewport *viewport, _viewport_list)
        viewport->set_need_update(need_update);
DreamSourceLab's avatar
DreamSourceLab committed
249 250
}

DreamSourceLab's avatar
DreamSourceLab committed
251 252 253 254 255 256
void View::update_sample(bool instant)
{
    _session.get_device()->set_config(NULL, NULL, SR_CONF_INSTANT, g_variant_new_boolean(instant));
    BOOST_FOREACH(const boost::shared_ptr<pv::view::Signal> s, _session.get_signals()) {
        boost::shared_ptr<pv::view::DsoSignal> dsoSig;
        if (dsoSig = dynamic_pointer_cast<pv::view::DsoSignal>(s)) {
257
            dsoSig->update_capture();
DreamSourceLab's avatar
DreamSourceLab committed
258 259 260 261 262 263 264
            break;
        }
    }
}

void View::set_sample_rate(uint64_t sample_rate, bool force)
{
265
    if (_session.get_capture_state() != pv::SigSession::Stopped || force) {
DreamSourceLab's avatar
DreamSourceLab committed
266
        _sampling_bar->set_sample_rate(sample_rate);
267 268
        _session.set_cur_samplerate(_session.get_device()->get_sample_rate());
    }
DreamSourceLab's avatar
DreamSourceLab committed
269 270 271 272
}

void View::set_sample_limit(uint64_t sample_limit, bool force)
{
273
    if (_session.get_capture_state() != pv::SigSession::Stopped || force) {
DreamSourceLab's avatar
DreamSourceLab committed
274
        _sampling_bar->set_sample_limit(sample_limit);
275 276 277 278
        const uint64_t final_limit = _session.get_device()->get_sample_limit();
        _trig_cursor->set_index(_trig_cursor->index() * 1.0 / _session.cur_samplelimits() * final_limit);
        _session.set_cur_samplelimits(final_limit);
    }
DreamSourceLab's avatar
DreamSourceLab committed
279 280
}

DreamSourceLab's avatar
DreamSourceLab committed
281 282 283 284 285 286
void View::zoom(double steps, int offset)
{
    //if (_session.get_capture_state() == SigSession::Stopped) {
        _preScale = _scale;
        _preOffset = _offset;

DreamSourceLab's avatar
DreamSourceLab committed
287
        if (_session.get_device()->dev_inst()->mode != DSO) {
DreamSourceLab's avatar
DreamSourceLab committed
288
            _scale *= std::pow(3.0/2.0, -steps);
DreamSourceLab's avatar
v0.3  
DreamSourceLab committed
289
            _scale = max(min(_scale, _maxscale), _minscale);
DreamSourceLab's avatar
DreamSourceLab committed
290
        }else {
291
            const vector< boost::shared_ptr<Signal> > sigs(_session.get_signals());
DreamSourceLab's avatar
DreamSourceLab committed
292
            bool setted = false;
293 294
            BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
                boost::shared_ptr<DsoSignal> dsoSig;
DreamSourceLab's avatar
DreamSourceLab committed
295 296
                if (dsoSig = dynamic_pointer_cast<DsoSignal>(s)) {
                    if(steps > 0.5)
DreamSourceLab's avatar
DreamSourceLab committed
297
                        dsoSig->go_hDialPre(setted);
DreamSourceLab's avatar
DreamSourceLab committed
298
                    else if (steps < -0.5)
DreamSourceLab's avatar
DreamSourceLab committed
299 300 301 302
                        dsoSig->go_hDialNext(setted);
                    else
                        break;
                    setted = true;
DreamSourceLab's avatar
DreamSourceLab committed
303
                }
DreamSourceLab's avatar
v0.3  
DreamSourceLab committed
304 305
            }
        }
306

307
        _offset = floor((_offset + offset) * (_preScale / _scale) - offset);
DreamSourceLab's avatar
DreamSourceLab committed
308
        _offset = max(min(_offset, get_max_offset()), get_min_offset());
DreamSourceLab's avatar
DreamSourceLab committed
309 310

        if (_scale != _preScale || _offset != _preOffset) {
DreamSourceLab's avatar
v0.3  
DreamSourceLab committed
311
            _header->update();
DreamSourceLab's avatar
DreamSourceLab committed
312
            _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
313
            viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
314 315 316 317 318 319
            update_scroll();
        }
    //}
}


320
void View::set_scale_offset(double scale, int64_t offset)
DreamSourceLab's avatar
DreamSourceLab committed
321 322 323 324 325
{
    //if (_session.get_capture_state() == SigSession::Stopped) {
        _preScale = _scale;
        _preOffset = _offset;

DreamSourceLab's avatar
DreamSourceLab committed
326
        _scale = max(min(scale, _maxscale), _minscale);
327
        _offset = floor(max(min(offset, get_max_offset()), get_min_offset()));
DreamSourceLab's avatar
DreamSourceLab committed
328 329 330

        if (_scale != _preScale || _offset != _preOffset) {
            update_scroll();
DreamSourceLab's avatar
DreamSourceLab committed
331
            _header->update();
DreamSourceLab's avatar
DreamSourceLab committed
332
            _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
333
            viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
334 335 336 337 338 339 340 341 342 343 344 345 346
        }
    //}
}

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

    set_scale_offset(_preScale, _preOffset);
}

DreamSourceLab's avatar
DreamSourceLab committed
347
vector< boost::shared_ptr<Trace> > View::get_traces(int type)
DreamSourceLab's avatar
DreamSourceLab committed
348
{
349
    const vector< boost::shared_ptr<Signal> > sigs(_session.get_signals());
DreamSourceLab's avatar
DreamSourceLab committed
350
    const vector< boost::shared_ptr<GroupSignal> > groups(_session.get_group_signals());
DreamSourceLab's avatar
DreamSourceLab committed
351
#ifdef ENABLE_DECODE
352
    const vector< boost::shared_ptr<DecodeTrace> > decode_sigs(
DreamSourceLab's avatar
DreamSourceLab committed
353 354
        _session.get_decode_signals());
#endif
DreamSourceLab's avatar
DreamSourceLab committed
355
    const vector< boost::shared_ptr<MathTrace> > maths(_session.get_math_signals());
DreamSourceLab's avatar
DreamSourceLab committed
356

DreamSourceLab's avatar
DreamSourceLab committed
357 358 359 360 361
    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
362
#ifdef ENABLE_DECODE
DreamSourceLab's avatar
DreamSourceLab committed
363 364 365 366
    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
367
#endif
DreamSourceLab's avatar
DreamSourceLab committed
368 369 370 371 372 373 374 375 376
    BOOST_FOREACH(boost::shared_ptr<Trace> t, groups) {
        if (type == ALL_VIEW || _trace_view_map[t->get_type()] == type)
            traces.push_back(t);
    }

    BOOST_FOREACH(boost::shared_ptr<Trace> t, maths) {
        if (type == ALL_VIEW || _trace_view_map[t->get_type()] == type)
            traces.push_back(t);
    }
DreamSourceLab's avatar
DreamSourceLab committed
377 378 379 380 381

    stable_sort(traces.begin(), traces.end(), compare_trace_v_offsets);
    return traces;
}

382 383
bool View::compare_trace_v_offsets(const boost::shared_ptr<Trace> &a,
    const boost::shared_ptr<Trace> &b)
DreamSourceLab's avatar
DreamSourceLab committed
384 385 386
{
    assert(a);
    assert(b);
387 388 389 390
    if (a->get_type() != b->get_type())
        return a->get_type() > b->get_type();
    else
        return a->get_v_offset() < b->get_v_offset();
DreamSourceLab's avatar
DreamSourceLab committed
391 392
}

DreamSourceLab's avatar
DreamSourceLab committed
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
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
412
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
413 414 415 416 417 418
}

void View::show_trig_cursor(bool show)
{
    _show_trig_cursor = show;
    _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
419
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
420 421 422 423 424 425
}

void View::show_search_cursor(bool show)
{
    _show_search_cursor = show;
    _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
426
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
427 428
}

429 430 431 432 433
void View::status_clear()
{
    _viewbottom->clear();
}

434
void View::repeat_unshow()
435
{
436
    _viewbottom->repeat_unshow();
437 438 439 440 441 442
}

void View::frame_began()
{
    if (_session.get_device()->dev_inst()->mode == LOGIC)
        _viewbottom->set_trig_time(_session.get_trigger_time());
443 444 445
    _search_hit = false;
    _search_pos = 0;
    set_search_pos(_search_pos, _search_hit);
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466
}

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);
                    }
                }
            }
        }
    }
467
    _time_viewport->unshow_wait_trigger();
468 469
}

470
void View::receive_trigger(quint64 trig_pos)
DreamSourceLab's avatar
DreamSourceLab committed
471
{
472
    const double time = trig_pos * 1.0 / _session.cur_samplerate();
473
    _trig_cursor->set_index(trig_pos);
474 475 476
    if (ds_trigger_get_en() ||
        _session.get_device()->name() == "virtual-session" ||
        _session.get_device()->dev_inst()->mode == DSO) {
477
        _show_trig_cursor = true;
478
        set_scale_offset(_scale,  (time / _scale) - (get_view_width() / 2));
479
    }
480

DreamSourceLab's avatar
DreamSourceLab committed
481
    _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
482
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
483 484
}

485 486 487 488 489 490
void View::set_trig_pos(int percent)
{
    uint64_t index = _session.cur_samplelimits() * percent / 100;
    receive_trigger(index);
}

491
void View::set_search_pos(uint64_t search_pos, bool hit)
DreamSourceLab's avatar
DreamSourceLab committed
492 493 494
{
    //assert(search_pos >= 0);

495
    const double time = search_pos * 1.0 / _session.cur_samplerate();
DreamSourceLab's avatar
DreamSourceLab committed
496
    _search_pos = search_pos;
497
    _search_hit = hit;
498
    _search_cursor->set_index(search_pos);
499 500 501 502 503 504 505
    _search_cursor->set_colour(hit ? Trace::dsLightBlue : Trace::dsGray);

    if (hit) {
        set_scale_offset(_scale,  (time / _scale) - (get_view_width() / 2));
        _ruler->update();
        viewport_update();
    }
DreamSourceLab's avatar
DreamSourceLab committed
506 507 508 509 510 511 512
}

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

513 514 515 516 517
bool View::get_search_hit()
{
    return _search_hit;
}

518
const QPoint& View::hover_point() const
DreamSourceLab's avatar
DreamSourceLab committed
519 520 521 522 523 524
{
	return _hover_point;
}

void View::normalize_layout()
{
DreamSourceLab's avatar
DreamSourceLab committed
525
    const vector< boost::shared_ptr<Trace> > traces(get_traces(ALL_VIEW));
DreamSourceLab's avatar
DreamSourceLab committed
526 527

	int v_min = INT_MAX;
528
    BOOST_FOREACH(const boost::shared_ptr<Trace> t, traces)
DreamSourceLab's avatar
DreamSourceLab committed
529
        v_min = min(t->get_v_offset(), v_min);
DreamSourceLab's avatar
DreamSourceLab committed
530 531

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

DreamSourceLab's avatar
DreamSourceLab committed
535
    verticalScrollBar()->setSliderPosition(delta);
DreamSourceLab's avatar
DreamSourceLab committed
536 537 538 539 540 541 542 543 544 545 546
	v_scroll_value_changed(verticalScrollBar()->sliderPosition());
}


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

int View::get_signalHeight()
{
DreamSourceLab's avatar
DreamSourceLab committed
547
    return _signalHeight;
DreamSourceLab's avatar
DreamSourceLab committed
548 549
}

550
void View::get_scroll_layout(int64_t &length, int64_t &offset) const
DreamSourceLab's avatar
DreamSourceLab committed
551
{
552
    const set< boost::shared_ptr<data::SignalData> > data_set = _session.get_data();
DreamSourceLab's avatar
DreamSourceLab committed
553
    if (data_set.empty())
DreamSourceLab's avatar
DreamSourceLab committed
554 555
		return;

556 557
    length = ceil(_session.cur_sampletime() / _scale);
    offset = _offset;
DreamSourceLab's avatar
DreamSourceLab committed
558 559 560 561
}

void View::update_scroll()
{
DreamSourceLab's avatar
DreamSourceLab committed
562
    assert(_viewcenter);
DreamSourceLab's avatar
DreamSourceLab committed
563

DreamSourceLab's avatar
DreamSourceLab committed
564
    const QSize areaSize = _viewcenter->size();
DreamSourceLab's avatar
DreamSourceLab committed
565 566

	// Set the horizontal scroll bar
567 568
    int64_t length = 0;
    int64_t offset = 0;
DreamSourceLab's avatar
DreamSourceLab committed
569
	get_scroll_layout(length, offset);
570
    length = max(length - areaSize.width(), (int64_t)0);
DreamSourceLab's avatar
DreamSourceLab committed
571 572 573 574 575 576 577 578 579 580 581

	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(
582
            _offset * MaxScrollValue / length);
DreamSourceLab's avatar
DreamSourceLab committed
583 584 585 586 587 588
	}

	_updating_scroll = false;

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

592
void View::update_scale_offset()
DreamSourceLab's avatar
DreamSourceLab committed
593
{
594
    const uint64_t sample_rate = _session.cur_samplerate();
DreamSourceLab's avatar
DreamSourceLab committed
595 596 597
    assert(sample_rate > 0);

    if (_session.get_device()->dev_inst()->mode != DSO) {
598
        _maxscale = _session.cur_sampletime() / (get_view_width() * MaxViewRate);
599
        _minscale = (1.0 / sample_rate) / MaxPixelsPerSample;
DreamSourceLab's avatar
DreamSourceLab committed
600
    } else {
601
        _scale = _session.get_device()->get_time_base() * 10.0 / get_view_width() * std::pow(10.0, -9.0);
DreamSourceLab's avatar
DreamSourceLab committed
602
        _maxscale = 1e9;
603
        _minscale = 1e-15;
DreamSourceLab's avatar
DreamSourceLab committed
604
    }
605

606 607 608
    _scale = max(min(_scale, _maxscale), _minscale);
    _offset = max(min(_offset, get_max_offset()), get_min_offset());

DreamSourceLab's avatar
DreamSourceLab committed
609
    _preScale = _scale;
610
    _preOffset = _offset;
DreamSourceLab's avatar
DreamSourceLab committed
611

612
    //_trig_cursor->set_index(_session.get_trigger_pos());
DreamSourceLab's avatar
DreamSourceLab committed
613 614

    _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
615
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
616 617
}

618 619 620 621 622 623 624 625 626 627 628 629
void View::mode_changed()
{
    const uint64_t sample_rate = _session.cur_samplerate();
    assert(sample_rate > 0);

    if (_session.get_device()->name().contains("virtual"))
        _scale = WellSamplesPerPixel * 1.0 / sample_rate;
    _scale = max(min(_scale, _maxscale), _minscale);

    update_device_list();
}

DreamSourceLab's avatar
DreamSourceLab committed
630 631 632
void View::signals_changed()
{
    int total_rows = 0;
633
    uint8_t max_height = MaxHeightUnit;
DreamSourceLab's avatar
DreamSourceLab committed
634 635
    vector< boost::shared_ptr<Trace> > time_traces;
    vector< boost::shared_ptr<Trace> > fft_traces;
636
    int bits = 8;
637

DreamSourceLab's avatar
DreamSourceLab committed
638 639 640 641 642 643
    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
644
    }
DreamSourceLab's avatar
DreamSourceLab committed
645

DreamSourceLab's avatar
DreamSourceLab committed
646 647 648 649 650 651 652 653 654 655 656 657
    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());
658 659
        }
    } else {
DreamSourceLab's avatar
DreamSourceLab committed
660 661 662
        _fft_viewport->setVisible(false);
        _vsplitter->refresh();

663
        // Find the _fft_viewport in the stack
DreamSourceLab's avatar
DreamSourceLab committed
664
        std::list< Viewport *>::iterator iter = _viewport_list.begin();
665
        for(unsigned int i = 0; i < _viewport_list.size(); i++, iter++)
DreamSourceLab's avatar
DreamSourceLab committed
666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708
            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();
        }

        const double height = (_time_viewport->height()
                               - 2 * SignalMargin * time_traces.size()) * 1.0 / total_rows;

        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()
                             - 2 * SignalMargin * time_traces.size()) * 1.0 / total_rows;
        } 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);
            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;
709
            if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(t)) {
710
                dsoSig->set_scale(dsoSig->get_view_rect().height());
711
            }
DreamSourceLab's avatar
DreamSourceLab committed
712 713
        }
        _time_viewport->clear_measure();
714
    }
DreamSourceLab's avatar
DreamSourceLab committed
715 716 717

    header_updated();
    normalize_layout();
718
    update_scale_offset();
719
    data_updated();
DreamSourceLab's avatar
DreamSourceLab committed
720 721 722 723 724 725 726
}

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
727
        if (object == _ruler || object == _time_viewport || object == _fft_viewport) {
DreamSourceLab's avatar
DreamSourceLab committed
728
            //_hover_point = QPoint(mouse_event->x(), 0);
729 730
            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
731
            double cur_deviate_x = qAbs(mouse_event->pos().x() - integer_x);
732 733
            if (_session.get_device()->dev_inst()->mode == LOGIC &&
                cur_deviate_x < 10)
734
                _hover_point = QPoint(integer_x, mouse_event->pos().y());
DreamSourceLab's avatar
DreamSourceLab committed
735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769
            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:
		return false;

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

int View::headerWidth()
{
    int headerWidth;
770
    int maxNameWidth = 25;
DreamSourceLab's avatar
DreamSourceLab committed
771 772
    int maxLeftWidth = 0;
    int maxRightWidth = 0;
DreamSourceLab's avatar
v0.3  
DreamSourceLab committed
773

DreamSourceLab's avatar
v0.21  
DreamSourceLab committed
774 775 776
    QFont font = QApplication::font();
    QFontMetrics fm(font);

DreamSourceLab's avatar
DreamSourceLab committed
777
    const vector< boost::shared_ptr<Trace> > traces(get_traces(ALL_VIEW));
DreamSourceLab's avatar
DreamSourceLab committed
778
    if (!traces.empty()){
779
        BOOST_FOREACH(const boost::shared_ptr<Trace> t, traces) {
DreamSourceLab's avatar
DreamSourceLab committed
780 781 782
            maxNameWidth = max(fm.boundingRect(t->get_name()).width(), maxNameWidth);
            maxLeftWidth = max(t->get_leftWidth(), maxLeftWidth);
            maxRightWidth = max(t->get_rightWidth(), maxRightWidth);
DreamSourceLab's avatar
DreamSourceLab committed
783 784 785 786 787 788 789 790 791 792 793 794
        }
    }
    maxNameWidth = max(_header->get_nameEditWidth(), maxNameWidth);
    headerWidth = maxLeftWidth + maxNameWidth + maxRightWidth;

    setViewportMargins(headerWidth, RulerHeight, 0, 0);

    return headerWidth;
}

void View::resizeEvent(QResizeEvent*)
{
DreamSourceLab's avatar
DreamSourceLab committed
795
    setViewportMargins(headerWidth(), RulerHeight, 0, 0);
DreamSourceLab's avatar
DreamSourceLab committed
796 797
    update_margins();
    update_scroll();
DreamSourceLab's avatar
DreamSourceLab committed
798
    signals_changed();
DreamSourceLab's avatar
DreamSourceLab committed
799
    if (_session.get_device()->dev_inst()->mode == DSO)
DreamSourceLab's avatar
DreamSourceLab committed
800
        _scale = _session.get_device()->get_time_base() * std::pow(10.0, -9.0) * DS_CONF_DSO_HDIVS / get_view_width();
DreamSourceLab's avatar
DreamSourceLab committed
801

802
    if (_session.get_device()->dev_inst()->mode != DSO)
803
        _maxscale = _session.cur_sampletime() / (get_view_width() * MaxViewRate);
804 805 806
    else
        _maxscale = 1e9;

DreamSourceLab's avatar
DreamSourceLab committed
807 808 809
    _scale = min(_scale, _maxscale);

    _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
810
    _header->header_resize();
DreamSourceLab's avatar
DreamSourceLab committed
811 812
    set_update(_time_viewport, true);
    set_update(_fft_viewport, true);
DreamSourceLab's avatar
DreamSourceLab committed
813 814 815 816 817 818 819 820 821 822 823
}

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

    _preOffset = _offset;

	const int range = horizontalScrollBar()->maximum();
	if (range < MaxScrollValue)
824
        _offset = value;
DreamSourceLab's avatar
DreamSourceLab committed
825
	else {
826 827
        int64_t length = 0;
        int64_t offset = 0;
DreamSourceLab's avatar
DreamSourceLab committed
828
		get_scroll_layout(length, offset);
829
        _offset = floor(length * value / MaxScrollValue);
DreamSourceLab's avatar
DreamSourceLab committed
830 831
	}

832
    _offset = max(min(_offset, get_max_offset()), get_min_offset());
DreamSourceLab's avatar
DreamSourceLab committed
833 834 835

    if (_offset != _preOffset) {
        _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
836
        viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
837 838 839 840 841
    }
}

void View::v_scroll_value_changed(int value)
{
842
    (void)value;
DreamSourceLab's avatar
DreamSourceLab committed
843
	_header->update();
DreamSourceLab's avatar
DreamSourceLab committed
844
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
845 846 847 848 849 850 851 852 853 854 855
}

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

	// Update the scroll bars
	update_scroll();

	// Repaint the view
856
    _time_viewport->unshow_wait_trigger();
DreamSourceLab's avatar
DreamSourceLab committed
857 858 859
    set_update(_time_viewport, true);
    set_update(_fft_viewport, true);
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
860 861 862 863
}

void View::update_margins()
{
DreamSourceLab's avatar
DreamSourceLab committed
864 865 866 867
    _ruler->setGeometry(_viewcenter->x(), 0,
        get_view_width(), _viewcenter->y());
    _header->setGeometry(0, _viewcenter->y(),
        _viewcenter->x(), _viewcenter->height());
DreamSourceLab's avatar
DreamSourceLab committed
868
    _devmode->setGeometry(0, 0,
DreamSourceLab's avatar
DreamSourceLab committed
869
        _viewcenter->x(), _viewcenter->y());
DreamSourceLab's avatar
DreamSourceLab committed
870 871 872 873 874 875 876 877 878 879
}

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

    // Update the scroll bars
    update_scroll();

DreamSourceLab's avatar
DreamSourceLab committed
880
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
881 882 883 884 885 886
    _header->update();
}

void View::marker_time_changed()
{
	_ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
887
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
888 889
}

DreamSourceLab's avatar
DreamSourceLab committed
890
void View::on_traces_moved()
DreamSourceLab's avatar
DreamSourceLab committed
891 892
{
	update_scroll();
DreamSourceLab's avatar
DreamSourceLab committed
893 894
    set_update(_time_viewport, true);
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919
}

/*
 * 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;
}

920
void View::add_cursor(QColor color, uint64_t index)
DreamSourceLab's avatar
DreamSourceLab committed
921
{
922
    Cursor *newCursor = new Cursor(*this, color, index);
DreamSourceLab's avatar
DreamSourceLab committed
923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942
    _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++;
943
    set_scale_offset(_scale, (*i)->index() / (_session.cur_samplerate() * _scale) - (get_view_width() / 2));
DreamSourceLab's avatar
DreamSourceLab committed
944 945
}

DreamSourceLab's avatar
DreamSourceLab committed
946 947 948 949 950 951 952
void View::on_measure_updated()
{
    _active_viewport = dynamic_cast<Viewport *>(sender());
    measure_updated();
}

QString View::get_measure(QString option)
DreamSourceLab's avatar
DreamSourceLab committed
953
{
DreamSourceLab's avatar
DreamSourceLab committed
954 955 956 957
    if (_active_viewport) {
        return _active_viewport->get_measure(option);
    }
    return "#####";
DreamSourceLab's avatar
DreamSourceLab committed
958 959 960 961
}

QString View::get_cm_time(int index)
{
962
    return _ruler->format_real_time(get_cursor_samples(index), _session.cur_samplerate());
DreamSourceLab's avatar
DreamSourceLab committed
963 964 965 966 967 968 969
}

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

970 971 972
    uint64_t samples1 = get_cursor_samples(index1);
    uint64_t samples2 = get_cursor_samples(index2);
    uint64_t delta_sample = (samples1 > samples2) ? samples1 - samples2 : samples2 - samples1;
973
    return _ruler->format_real_time(delta_sample, _session.cur_samplerate());
DreamSourceLab's avatar
DreamSourceLab committed
974 975
}

DreamSourceLab's avatar
DreamSourceLab committed
976 977
uint64_t View::get_cursor_samples(int index)
{
978
    assert(index < (int)_cursorList.size());
DreamSourceLab's avatar
DreamSourceLab committed
979

980 981 982 983 984 985 986 987
    int curIndex = 0;
    for (list<Cursor*>::iterator i = _cursorList.begin();
         i != _cursorList.end(); i++) {
        if (index == curIndex) {
            return (*i)->index();
        }
        curIndex++;
    }
DreamSourceLab's avatar
DreamSourceLab committed
988 989
}

DreamSourceLab's avatar
DreamSourceLab committed
990 991
void View::set_measure_en(int enable)
{
DreamSourceLab's avatar
DreamSourceLab committed
992 993
    BOOST_FOREACH(Viewport *viewport, _viewport_list)
            viewport->set_measure_en(enable);
DreamSourceLab's avatar
DreamSourceLab committed
994 995 996 997
}

void View::on_state_changed(bool stop)
{
DreamSourceLab's avatar
DreamSourceLab committed
998 999 1000 1001
    if (stop) {
        BOOST_FOREACH(Viewport *viewport, _viewport_list)
            viewport->stop_trigger_timer();
    }
1002
    update_scale_offset();
DreamSourceLab's avatar
DreamSourceLab committed
1003 1004
}

1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016
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();
        }
    } else {
        return _viewcenter->rect();
    }
}

DreamSourceLab's avatar
DreamSourceLab committed
1017
int View::get_view_width()
DreamSourceLab's avatar
v0.3  
DreamSourceLab committed
1018
{
DreamSourceLab's avatar
DreamSourceLab committed
1019 1020
    int view_width = 0;
    if (_session.get_device()->dev_inst()->mode == DSO) {
1021 1022
        const vector< boost::shared_ptr<Signal> > sigs(_session.get_signals());
        BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
1023
            view_width = max(view_width, s->get_view_rect().width());
DreamSourceLab's avatar
DreamSourceLab committed
1024 1025
        }
    } else {
DreamSourceLab's avatar
DreamSourceLab committed
1026
        view_width = _viewcenter->width();
DreamSourceLab's avatar
DreamSourceLab committed
1027
    }
DreamSourceLab's avatar
v0.3  
DreamSourceLab committed
1028

DreamSourceLab's avatar
DreamSourceLab committed
1029
    return view_width;
DreamSourceLab's avatar
v0.3  
DreamSourceLab committed
1030 1031
}

1032 1033 1034 1035 1036 1037
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) {
1038
            view_height = max(view_height, s->get_view_rect().height());
1039 1040
        }
    } else {
DreamSourceLab's avatar
DreamSourceLab committed
1041
        view_height = _viewcenter->height();
1042 1043 1044 1045 1046
    }

    return view_height;
}

1047
int64_t View::get_min_offset()
1048
{
1049 1050 1051 1052
    if (MaxViewRate > 1)
        return floor(get_view_width() * (1 - MaxViewRate));
    else
        return 0;
1053 1054
}

1055
int64_t View::get_max_offset()
1056
{
1057 1058
    return ceil((_session.cur_sampletime() / _scale) -
                (get_view_width() * MaxViewRate));
1059 1060
}

1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079
// -- calibration dialog
void View::show_calibration()
{
    _cali->set_device(_session.get_device());
    _cali->show();
}

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

void View::update_calibration()
{
    if (_cali->isVisible()) {
        _cali->set_device(_session.get_device());
    }
}

1080
void View::show_region(uint64_t start, uint64_t end, bool keep)
1081 1082
{
    assert(start <= end);
1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095
    if (keep) {
        set_all_update(true);
        update();
    } else if (_session.get_map_zoom() == 0) {
        const double ideal_scale = (end-start) * 2.0 / _session.cur_samplerate() / get_view_width();
        const double new_scale = max(min(ideal_scale, _maxscale), _minscale);
        const double new_off = (start + end)  * 0.5 / (_session.cur_samplerate() * new_scale) - (get_view_width() / 2);
        set_scale_offset(new_scale, new_off);
    } else {
        const double new_scale = scale();
        const double new_off = (start + end)  * 0.5 / (_session.cur_samplerate() * new_scale) - (get_view_width() / 2);
        set_scale_offset(new_scale, new_off);
    }
1096 1097
}

DreamSourceLab's avatar
DreamSourceLab committed
1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111
void View::viewport_update()
{
    _viewcenter->update();
    BOOST_FOREACH(Viewport *viewport, _viewport_list)
        viewport->update();
}

void View::splitterMoved(int pos, int index)
{
    (void)pos;
    (void)index;
    signals_changed();
}

1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123
void View::reload()
{
    show_trig_cursor(false);

    /*
     * if headerwidth not change, viewport height will not be updated
     * lead to a wrong signal height
     */
    if (_session.get_device()->dev_inst()->mode == LOGIC)
        _viewbottom->setFixedHeight(StatusHeight);
    else
        _viewbottom->setFixedHeight(10);
1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149
}

void View::repeat_show()
{
    _viewbottom->update();
}

bool View::get_capture_status(bool &triggered, int &progress)
{
    uint64_t sample_limits = _session.cur_samplelimits();
    sr_status status;
    if (sr_status_get(_session.get_device()->dev_inst(), &status, SR_STATUS_TRIG_BEGIN, SR_STATUS_TRIG_END) == SR_OK){
        triggered = status.trig_hit & 0x01;
        const bool  captured_cnt_dec = status.trig_hit & 0x02;
        uint64_t captured_cnt = status.trig_hit >> 2;
        captured_cnt = ((uint64_t)status.captured_cnt0 +
                       ((uint64_t)status.captured_cnt1 << 8) +
                       ((uint64_t)status.captured_cnt2 << 16) +
                       ((uint64_t)status.captured_cnt3 << 24) +
                       (captured_cnt << 32));
        if (_session.get_device()->dev_inst()->mode == DSO)
            captured_cnt = captured_cnt * _session.get_signals().size() / _session.get_ch_num(SR_CHANNEL_DSO);
        if (captured_cnt_dec)
            progress = (sample_limits - captured_cnt) * 100.0 / sample_limits;
        else
            progress = captured_cnt * 100.0 / sample_limits;
1150 1151


1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165
        return true;
    }

    return false;
}

void View::set_capture_status()
{
    bool triggered;
    int progress;
    if (_session.get_capture_status(triggered, progress)) {
        _viewbottom->set_capture_status(triggered, progress);
        _viewbottom->update();
    }
1166 1167
}

DreamSourceLab's avatar
DreamSourceLab committed
1168 1169
} // namespace view
} // namespace pv