view.cpp 31 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"
DreamSourceLab's avatar
DreamSourceLab committed
43
#include "mathtrace.h"
DreamSourceLab's avatar
DreamSourceLab committed
44

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

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

//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
71
View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget *parent) :
DreamSourceLab's avatar
DreamSourceLab committed
72
    QScrollArea(parent),
DreamSourceLab's avatar
DreamSourceLab committed
73
	_session(session),
DreamSourceLab's avatar
DreamSourceLab committed
74
    _sampling_bar(sampling_bar),
75
    _scale(10),
DreamSourceLab's avatar
DreamSourceLab committed
76 77 78 79 80 81 82
    _preScale(1e-6),
    _maxscale(1e9),
    _minscale(1e-15),
	_offset(0),
    _preOffset(0),
	_updating_scroll(false),
	_show_cursors(false),
83
    _search_hit(false),
DreamSourceLab's avatar
DreamSourceLab committed
84
    _hover_point(-1, -1),
85
    _dso_auto(true)
DreamSourceLab's avatar
DreamSourceLab committed
86 87 88 89 90 91 92 93
{
    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
94 95 96 97 98 99 100 101 102 103 104 105 106
    // 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
107
    setViewportMargins(headerWidth(), RulerHeight, 0, 0);
DreamSourceLab's avatar
DreamSourceLab committed
108 109 110 111 112 113 114 115
    //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()));
116
    connect(_time_viewport, SIGNAL(prgRate(int)), this, SIGNAL(prgRate(int)));
DreamSourceLab's avatar
DreamSourceLab committed
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
    _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);
140
    layout->setSpacing(0);
DreamSourceLab's avatar
DreamSourceLab committed
141 142 143
    layout->setContentsMargins(0,0,0,0);
    _viewcenter->setLayout(layout);
    layout->addWidget(_vsplitter, 0, 0);
144
    _viewbottom = new widgets::ViewStatus(_session, this);
145 146
    _viewbottom->setFixedHeight(StatusHeight);
    layout->addWidget(_viewbottom, 1, 0);
DreamSourceLab's avatar
DreamSourceLab committed
147 148 149
    setViewport(_viewcenter);
    connect(_vsplitter, SIGNAL(splitterMoved(int,int)),
        this, SLOT(splitterMoved(int, int)));
DreamSourceLab's avatar
DreamSourceLab committed
150

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

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

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

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

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

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

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

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

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

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

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

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

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

    _maxscale = _session.cur_sampletime() / (get_view_width() * MaxViewRate);
231 232
    if (_session.get_device()->dev_inst()->mode == ANALOG)
        set_scale_offset(_maxscale, 0);
233 234 235
    status_clear();
}

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

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

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

252 253 254 255 256
double View::get_hori_res()
{
    return _sampling_bar->get_hori_res();
}

257
void View::update_hori_res()
DreamSourceLab's avatar
DreamSourceLab committed
258
{
259
    if (_session.get_device()->dev_inst()->mode == DSO) {
260
        _sampling_bar->hori_knob(0);
261
    }
DreamSourceLab's avatar
DreamSourceLab committed
262 263
}

DreamSourceLab's avatar
DreamSourceLab committed
264 265 266 267 268 269
void View::zoom(double steps, int offset)
{
    //if (_session.get_capture_state() == SigSession::Stopped) {
        _preScale = _scale;
        _preOffset = _offset;

DreamSourceLab's avatar
DreamSourceLab committed
270
        if (_session.get_device()->dev_inst()->mode != DSO) {
271
            _scale *= std::pow(3.0/2.0, -steps);
DreamSourceLab's avatar
v0.3  
DreamSourceLab committed
272
            _scale = max(min(_scale, _maxscale), _minscale);
273 274 275 276 277
        } else {
            if (_session.get_capture_state() == SigSession::Running &&
                _session.get_instant())
                return;

278
            double hori_res = -1;
279
            if(steps > 0.5)
280
                hori_res = _sampling_bar->hori_knob(-1);
281
            else if (steps < -0.5)
282 283 284 285 286 287
                hori_res = _sampling_bar->hori_knob(1);

            if (hori_res > 0) {
                const double scale = hori_res * DS_CONF_DSO_HDIVS / SR_SEC(1) / get_view_width();
                _scale = max(min(scale, _maxscale), _minscale);
            }
DreamSourceLab's avatar
v0.3  
DreamSourceLab committed
288
        }
289

290
        _offset = floor((_offset + offset) * (_preScale / _scale) - offset);
DreamSourceLab's avatar
DreamSourceLab committed
291
        _offset = max(min(_offset, get_max_offset()), get_min_offset());
DreamSourceLab's avatar
DreamSourceLab committed
292 293

        if (_scale != _preScale || _offset != _preOffset) {
DreamSourceLab's avatar
v0.3  
DreamSourceLab committed
294
            _header->update();
DreamSourceLab's avatar
DreamSourceLab committed
295
            _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
296
            viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
297 298 299 300 301
            update_scroll();
        }
    //}
}

302 303 304 305 306 307 308 309 310 311 312 313
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)
        scale = hori_res * DS_CONF_DSO_HDIVS / SR_SEC(1) / get_view_width();
    set_scale_offset(scale, this->offset());
}

314
void View::set_scale_offset(double scale, int64_t offset)
DreamSourceLab's avatar
DreamSourceLab committed
315 316 317 318 319
{
    //if (_session.get_capture_state() == SigSession::Stopped) {
        _preScale = _scale;
        _preOffset = _offset;

DreamSourceLab's avatar
DreamSourceLab committed
320
        _scale = max(min(scale, _maxscale), _minscale);
321
        _offset = floor(max(min(offset, get_max_offset()), get_min_offset()));
DreamSourceLab's avatar
DreamSourceLab committed
322 323 324

        if (_scale != _preScale || _offset != _preOffset) {
            update_scroll();
DreamSourceLab's avatar
DreamSourceLab committed
325
            _header->update();
DreamSourceLab's avatar
DreamSourceLab committed
326
            _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
327
            viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
328 329 330 331 332 333 334 335 336 337 338 339 340
        }
    //}
}

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

    set_scale_offset(_preScale, _preOffset);
}

DreamSourceLab's avatar
DreamSourceLab committed
341
vector< boost::shared_ptr<Trace> > View::get_traces(int type)
DreamSourceLab's avatar
DreamSourceLab committed
342
{
343
    const vector< boost::shared_ptr<Signal> > sigs(_session.get_signals());
DreamSourceLab's avatar
DreamSourceLab committed
344
    const vector< boost::shared_ptr<GroupSignal> > groups(_session.get_group_signals());
DreamSourceLab's avatar
DreamSourceLab committed
345
#ifdef ENABLE_DECODE
346
    const vector< boost::shared_ptr<DecodeTrace> > decode_sigs(
DreamSourceLab's avatar
DreamSourceLab committed
347 348
        _session.get_decode_signals());
#endif
DreamSourceLab's avatar
DreamSourceLab committed
349
    const vector< boost::shared_ptr<MathTrace> > maths(_session.get_math_signals());
DreamSourceLab's avatar
DreamSourceLab committed
350

DreamSourceLab's avatar
DreamSourceLab committed
351 352 353 354 355
    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
356
#ifdef ENABLE_DECODE
DreamSourceLab's avatar
DreamSourceLab committed
357 358 359 360
    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
361
#endif
DreamSourceLab's avatar
DreamSourceLab committed
362 363 364 365 366 367 368 369 370
    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
371 372 373 374 375

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

376 377
bool View::compare_trace_v_offsets(const boost::shared_ptr<Trace> &a,
    const boost::shared_ptr<Trace> &b)
DreamSourceLab's avatar
DreamSourceLab committed
378 379 380
{
    assert(a);
    assert(b);
381 382 383 384
    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
385 386
}

DreamSourceLab's avatar
DreamSourceLab committed
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
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
406
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
407 408 409 410 411 412
}

void View::show_trig_cursor(bool show)
{
    _show_trig_cursor = show;
    _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
413
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
414 415 416 417 418 419
}

void View::show_search_cursor(bool show)
{
    _show_search_cursor = show;
    _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
420
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
421 422
}

423 424
void View::status_clear()
{
425 426
    _time_viewport->clear_dso_xm();
    _time_viewport->clear_measure();
427 428 429
    _viewbottom->clear();
}

430
void View::repeat_unshow()
431
{
432
    _viewbottom->repeat_unshow();
433 434 435 436 437 438
}

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

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);
                    }
                }
            }
        }
    }
463
    _time_viewport->unshow_wait_trigger();
464 465
}

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

DreamSourceLab's avatar
DreamSourceLab committed
477
    _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
478
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
479 480
}

481 482 483 484 485 486
void View::set_trig_pos(int percent)
{
    uint64_t index = _session.cur_samplelimits() * percent / 100;
    receive_trigger(index);
}

487
void View::set_search_pos(uint64_t search_pos, bool hit)
DreamSourceLab's avatar
DreamSourceLab committed
488 489 490
{
    //assert(search_pos >= 0);

491
    const double time = search_pos * 1.0 / _session.cur_samplerate();
DreamSourceLab's avatar
DreamSourceLab committed
492
    _search_pos = search_pos;
493
    _search_hit = hit;
494
    _search_cursor->set_index(search_pos);
495 496 497 498 499 500 501
    _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
502 503 504 505 506 507 508
}

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

509 510 511 512 513
bool View::get_search_hit()
{
    return _search_hit;
}

514
const QPoint& View::hover_point() const
DreamSourceLab's avatar
DreamSourceLab committed
515 516 517 518 519 520
{
	return _hover_point;
}

void View::normalize_layout()
{
DreamSourceLab's avatar
DreamSourceLab committed
521
    const vector< boost::shared_ptr<Trace> > traces(get_traces(ALL_VIEW));
DreamSourceLab's avatar
DreamSourceLab committed
522 523

	int v_min = INT_MAX;
524
    BOOST_FOREACH(const boost::shared_ptr<Trace> t, traces)
DreamSourceLab's avatar
DreamSourceLab committed
525
        v_min = min(t->get_v_offset(), v_min);
DreamSourceLab's avatar
DreamSourceLab committed
526 527

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

DreamSourceLab's avatar
DreamSourceLab committed
531
    verticalScrollBar()->setSliderPosition(delta);
DreamSourceLab's avatar
DreamSourceLab committed
532 533 534 535 536 537 538 539 540 541 542
	v_scroll_value_changed(verticalScrollBar()->sliderPosition());
}


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

int View::get_signalHeight()
{
DreamSourceLab's avatar
DreamSourceLab committed
543
    return _signalHeight;
DreamSourceLab's avatar
DreamSourceLab committed
544 545
}

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

552 553
    length = ceil(_session.cur_sampletime() / _scale);
    offset = _offset;
DreamSourceLab's avatar
DreamSourceLab committed
554 555 556 557
}

void View::update_scroll()
{
DreamSourceLab's avatar
DreamSourceLab committed
558
    assert(_viewcenter);
DreamSourceLab's avatar
DreamSourceLab committed
559

DreamSourceLab's avatar
DreamSourceLab committed
560
    const QSize areaSize = _viewcenter->size();
DreamSourceLab's avatar
DreamSourceLab committed
561 562

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

	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
578
            _offset * 1.0  / length * MaxScrollValue);
DreamSourceLab's avatar
DreamSourceLab committed
579 580 581 582 583 584
	}

	_updating_scroll = false;

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

588
void View::update_scale_offset()
DreamSourceLab's avatar
DreamSourceLab committed
589
{
590
    const uint64_t sample_rate = _session.cur_samplerate();
DreamSourceLab's avatar
DreamSourceLab committed
591 592 593
    assert(sample_rate > 0);

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

602 603 604
    _scale = max(min(_scale, _maxscale), _minscale);
    _offset = max(min(_offset, get_max_offset()), get_min_offset());

DreamSourceLab's avatar
DreamSourceLab committed
605
    _preScale = _scale;
606
    _preOffset = _offset;
DreamSourceLab's avatar
DreamSourceLab committed
607

608
    //_trig_cursor->set_index(_session.get_trigger_pos());
DreamSourceLab's avatar
DreamSourceLab committed
609 610

    _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
611
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
612 613
}

614 615 616 617 618 619 620 621 622 623 624 625
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
626 627 628
void View::signals_changed()
{
    int total_rows = 0;
629
    uint8_t max_height = MaxHeightUnit;
DreamSourceLab's avatar
DreamSourceLab committed
630 631
    vector< boost::shared_ptr<Trace> > time_traces;
    vector< boost::shared_ptr<Trace> > fft_traces;
632

DreamSourceLab's avatar
DreamSourceLab committed
633 634 635 636 637 638
    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
639
    }
DreamSourceLab's avatar
DreamSourceLab committed
640

DreamSourceLab's avatar
DreamSourceLab committed
641 642 643 644 645 646 647 648 649 650 651 652
    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());
653 654
        }
    } else {
DreamSourceLab's avatar
DreamSourceLab committed
655 656 657
        _fft_viewport->setVisible(false);
        _vsplitter->refresh();

658
        // Find the _fft_viewport in the stack
DreamSourceLab's avatar
DreamSourceLab committed
659
        std::list< Viewport *>::iterator iter = _viewport_list.begin();
660
        for(unsigned int i = 0; i < _viewport_list.size(); i++, iter++)
DreamSourceLab's avatar
DreamSourceLab committed
661 662 663 664 665 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
            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;
704
            if ((dsoSig = dynamic_pointer_cast<view::DsoSignal>(t))) {
705
                dsoSig->set_scale(dsoSig->get_view_rect().height());
706
            }
DreamSourceLab's avatar
DreamSourceLab committed
707 708
        }
        _time_viewport->clear_measure();
709
    }
DreamSourceLab's avatar
DreamSourceLab committed
710 711 712

    header_updated();
    normalize_layout();
713
    update_scale_offset();
714
    data_updated();
DreamSourceLab's avatar
DreamSourceLab committed
715 716 717 718 719 720 721
}

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
722
        if (object == _ruler || object == _time_viewport || object == _fft_viewport) {
DreamSourceLab's avatar
DreamSourceLab committed
723
            //_hover_point = QPoint(mouse_event->x(), 0);
724 725
            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
726
            double cur_deviate_x = qAbs(mouse_event->pos().x() - integer_x);
727 728
            if (_session.get_device()->dev_inst()->mode == LOGIC &&
                cur_deviate_x < 10)
729
                _hover_point = QPoint(integer_x, mouse_event->pos().y());
DreamSourceLab's avatar
DreamSourceLab committed
730 731 732 733 734 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
            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()
{
764
    int headerWidth = _header->get_nameEditWidth();
DreamSourceLab's avatar
v0.21  
DreamSourceLab committed
765

DreamSourceLab's avatar
DreamSourceLab committed
766
    const vector< boost::shared_ptr<Trace> > traces(get_traces(ALL_VIEW));
767 768 769 770
    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
771 772 773 774 775 776 777 778 779
    }

    setViewportMargins(headerWidth, RulerHeight, 0, 0);

    return headerWidth;
}

void View::resizeEvent(QResizeEvent*)
{
DreamSourceLab's avatar
DreamSourceLab committed
780
    setViewportMargins(headerWidth(), RulerHeight, 0, 0);
DreamSourceLab's avatar
DreamSourceLab committed
781 782
    update_margins();
    update_scroll();
DreamSourceLab's avatar
DreamSourceLab committed
783
    signals_changed();
DreamSourceLab's avatar
DreamSourceLab committed
784
    if (_session.get_device()->dev_inst()->mode == DSO)
DreamSourceLab's avatar
DreamSourceLab committed
785
        _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
786

787
    if (_session.get_device()->dev_inst()->mode != DSO)
788
        _maxscale = _session.cur_sampletime() / (get_view_width() * MaxViewRate);
789 790 791
    else
        _maxscale = 1e9;

DreamSourceLab's avatar
DreamSourceLab committed
792 793 794
    _scale = min(_scale, _maxscale);

    _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
795
    _header->header_resize();
DreamSourceLab's avatar
DreamSourceLab committed
796 797
    set_update(_time_viewport, true);
    set_update(_fft_viewport, true);
798
    resize();
DreamSourceLab's avatar
DreamSourceLab committed
799 800 801 802 803 804 805 806 807 808 809
}

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

    _preOffset = _offset;

	const int range = horizontalScrollBar()->maximum();
	if (range < MaxScrollValue)
810
        _offset = value;
DreamSourceLab's avatar
DreamSourceLab committed
811
	else {
812 813
        int64_t length = 0;
        int64_t offset = 0;
DreamSourceLab's avatar
DreamSourceLab committed
814
		get_scroll_layout(length, offset);
DreamSourceLab's avatar
DreamSourceLab committed
815
        _offset = floor(value * 1.0 / MaxScrollValue * length);
DreamSourceLab's avatar
DreamSourceLab committed
816 817
	}

818
    _offset = max(min(_offset, get_max_offset()), get_min_offset());
DreamSourceLab's avatar
DreamSourceLab committed
819 820 821

    if (_offset != _preOffset) {
        _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
822
        viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
823 824 825 826 827
    }
}

void View::v_scroll_value_changed(int value)
{
828
    (void)value;
DreamSourceLab's avatar
DreamSourceLab committed
829
	_header->update();
DreamSourceLab's avatar
DreamSourceLab committed
830
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
831 832 833 834 835 836 837 838 839 840 841
}

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

	// Update the scroll bars
	update_scroll();

	// Repaint the view
842
    _time_viewport->unshow_wait_trigger();
DreamSourceLab's avatar
DreamSourceLab committed
843 844 845
    set_update(_time_viewport, true);
    set_update(_fft_viewport, true);
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
846 847 848 849
}

void View::update_margins()
{
DreamSourceLab's avatar
DreamSourceLab committed
850 851 852 853
    _ruler->setGeometry(_viewcenter->x(), 0,
        get_view_width(), _viewcenter->y());
    _header->setGeometry(0, _viewcenter->y(),
        _viewcenter->x(), _viewcenter->height());
DreamSourceLab's avatar
DreamSourceLab committed
854
    _devmode->setGeometry(0, 0,
DreamSourceLab's avatar
DreamSourceLab committed
855
        _viewcenter->x(), _viewcenter->y());
DreamSourceLab's avatar
DreamSourceLab committed
856 857 858 859 860 861 862 863 864 865
}

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

    // Update the scroll bars
    update_scroll();

DreamSourceLab's avatar
DreamSourceLab committed
866
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
867 868 869 870 871 872
    _header->update();
}

void View::marker_time_changed()
{
	_ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
873
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
874 875
}

DreamSourceLab's avatar
DreamSourceLab committed
876
void View::on_traces_moved()
DreamSourceLab's avatar
DreamSourceLab committed
877 878
{
	update_scroll();
DreamSourceLab's avatar
DreamSourceLab committed
879 880
    set_update(_time_viewport, true);
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905
}

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

906
void View::add_cursor(QColor color, uint64_t index)
DreamSourceLab's avatar
DreamSourceLab committed
907
{
908
    Cursor *newCursor = new Cursor(*this, color, index);
DreamSourceLab's avatar
DreamSourceLab committed
909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928
    _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++;
929
    set_scale_offset(_scale, (*i)->index() / (_session.cur_samplerate() * _scale) - (get_view_width() / 2));
DreamSourceLab's avatar
DreamSourceLab committed
930 931
}

DreamSourceLab's avatar
DreamSourceLab committed
932 933 934 935 936 937 938
void View::on_measure_updated()
{
    _active_viewport = dynamic_cast<Viewport *>(sender());
    measure_updated();
}

QString View::get_measure(QString option)
DreamSourceLab's avatar
DreamSourceLab committed
939
{
DreamSourceLab's avatar
DreamSourceLab committed
940 941 942 943
    if (_active_viewport) {
        return _active_viewport->get_measure(option);
    }
    return "#####";
DreamSourceLab's avatar
DreamSourceLab committed
944 945 946 947
}

QString View::get_cm_time(int index)
{
948
    return _ruler->format_real_time(get_cursor_samples(index), _session.cur_samplerate());
DreamSourceLab's avatar
DreamSourceLab committed
949 950 951 952 953 954 955
}

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

956 957 958
    uint64_t samples1 = get_cursor_samples(index1);
    uint64_t samples2 = get_cursor_samples(index2);
    uint64_t delta_sample = (samples1 > samples2) ? samples1 - samples2 : samples2 - samples1;
959
    return _ruler->format_real_time(delta_sample, _session.cur_samplerate());
DreamSourceLab's avatar
DreamSourceLab committed
960 961
}

962 963 964 965 966 967 968 969 970
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;
    return _ruler->format_real_time(delta_sample, _session.cur_samplerate());
}

DreamSourceLab's avatar
DreamSourceLab committed
971 972
uint64_t View::get_cursor_samples(int index)
{
973
    assert(index < (int)_cursorList.size());
DreamSourceLab's avatar
DreamSourceLab committed
974

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

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

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

1002 1003 1004 1005 1006 1007 1008 1009
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
1010 1011

    return _viewcenter->rect();
1012 1013
}

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

DreamSourceLab's avatar
DreamSourceLab committed
1026
    return view_width;
DreamSourceLab's avatar
v0.3  
DreamSourceLab committed
1027 1028
}

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

    return view_height;
}

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

1052
int64_t View::get_max_offset()
1053
{
1054 1055
    return ceil((_session.cur_sampletime() / _scale) -
                (get_view_width() * MaxViewRate));
1056 1057
}

1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076
// -- 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());
    }
}

1077
void View::show_region(uint64_t start, uint64_t end, bool keep)
1078 1079
{
    assert(start <= end);
1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092
    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);
    }
1093 1094
}

DreamSourceLab's avatar
DreamSourceLab committed
1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108
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();
}

1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120
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);
1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135
}

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

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

1138 1139 1140 1141 1142
bool View::get_dso_trig_moved() const
{
    return _time_viewport->get_dso_trig_moved();
}

DreamSourceLab's avatar
DreamSourceLab committed
1143 1144
} // namespace view
} // namespace pv