view.cpp 31.8 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 224
void View::capture_init(bool instant)
{
225 226
    _maxscale = _session.cur_sampletime() / (get_view_width() * MaxViewRate);

227 228 229 230
    if (_session.get_device()->dev_inst()->mode == DSO)
        show_trig_cursor(true);
    else if (!_session.isRepeating())
        show_trig_cursor(false);
231 232
    if (_session.get_device()->dev_inst()->mode == ANALOG)
        set_scale_offset(_maxscale, 0);
233 234 235 236 237

    update_sample(instant);
    status_clear();
}

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

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

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

DreamSourceLab's avatar
DreamSourceLab committed
254 255 256 257 258 259
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)) {
260
            dsoSig->update_capture(instant);
DreamSourceLab's avatar
DreamSourceLab committed
261 262 263 264 265 266 267
            break;
        }
    }
}

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

void View::set_sample_limit(uint64_t sample_limit, bool force)
{
276
    if (_session.get_capture_state() != pv::SigSession::Stopped || force) {
DreamSourceLab's avatar
DreamSourceLab committed
277
        _sampling_bar->set_sample_limit(sample_limit);
278 279 280 281
        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
282 283
}

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

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

311
        _offset = floor((_offset + offset) * (_preScale / _scale) - offset);
DreamSourceLab's avatar
DreamSourceLab committed
312
        _offset = max(min(_offset, get_max_offset()), get_min_offset());
DreamSourceLab's avatar
DreamSourceLab committed
313 314

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


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

DreamSourceLab's avatar
DreamSourceLab committed
330
        _scale = max(min(scale, _maxscale), _minscale);
331
        _offset = floor(max(min(offset, get_max_offset()), get_min_offset()));
DreamSourceLab's avatar
DreamSourceLab committed
332 333 334

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

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

    set_scale_offset(_preScale, _preOffset);
}

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

DreamSourceLab's avatar
DreamSourceLab committed
361 362 363 364 365
    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
366
#ifdef ENABLE_DECODE
DreamSourceLab's avatar
DreamSourceLab committed
367 368 369 370
    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
371
#endif
DreamSourceLab's avatar
DreamSourceLab committed
372 373 374 375 376 377 378 379 380
    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
381 382 383 384 385

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

386 387
bool View::compare_trace_v_offsets(const boost::shared_ptr<Trace> &a,
    const boost::shared_ptr<Trace> &b)
DreamSourceLab's avatar
DreamSourceLab committed
388 389 390
{
    assert(a);
    assert(b);
391 392 393 394
    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
395 396
}

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

void View::show_trig_cursor(bool show)
{
    _show_trig_cursor = show;
    _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
423
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
424 425 426 427 428 429
}

void View::show_search_cursor(bool show)
{
    _show_search_cursor = show;
    _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
430
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
431 432
}

433 434 435 436 437
void View::status_clear()
{
    _viewbottom->clear();
}

438
void View::repeat_unshow()
439
{
440
    _viewbottom->repeat_unshow();
441 442 443 444 445 446
}

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

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);
                    }
                }
            }
        }
    }
471
    _time_viewport->unshow_wait_trigger();
472 473
}

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

DreamSourceLab's avatar
DreamSourceLab committed
485
    _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
486
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
487 488
}

489 490 491 492 493 494
void View::set_trig_pos(int percent)
{
    uint64_t index = _session.cur_samplelimits() * percent / 100;
    receive_trigger(index);
}

495
void View::set_search_pos(uint64_t search_pos, bool hit)
DreamSourceLab's avatar
DreamSourceLab committed
496 497 498
{
    //assert(search_pos >= 0);

499
    const double time = search_pos * 1.0 / _session.cur_samplerate();
DreamSourceLab's avatar
DreamSourceLab committed
500
    _search_pos = search_pos;
501
    _search_hit = hit;
502
    _search_cursor->set_index(search_pos);
503 504 505 506 507 508 509
    _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
510 511 512 513 514 515 516
}

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

517 518 519 520 521
bool View::get_search_hit()
{
    return _search_hit;
}

522
const QPoint& View::hover_point() const
DreamSourceLab's avatar
DreamSourceLab committed
523 524 525 526 527 528
{
	return _hover_point;
}

void View::normalize_layout()
{
DreamSourceLab's avatar
DreamSourceLab committed
529
    const vector< boost::shared_ptr<Trace> > traces(get_traces(ALL_VIEW));
DreamSourceLab's avatar
DreamSourceLab committed
530 531

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

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

DreamSourceLab's avatar
DreamSourceLab committed
539
    verticalScrollBar()->setSliderPosition(delta);
DreamSourceLab's avatar
DreamSourceLab committed
540 541 542 543 544 545 546 547 548 549 550
	v_scroll_value_changed(verticalScrollBar()->sliderPosition());
}


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

int View::get_signalHeight()
{
DreamSourceLab's avatar
DreamSourceLab committed
551
    return _signalHeight;
DreamSourceLab's avatar
DreamSourceLab committed
552 553
}

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

560 561
    length = ceil(_session.cur_sampletime() / _scale);
    offset = _offset;
DreamSourceLab's avatar
DreamSourceLab committed
562 563 564 565
}

void View::update_scroll()
{
DreamSourceLab's avatar
DreamSourceLab committed
566
    assert(_viewcenter);
DreamSourceLab's avatar
DreamSourceLab committed
567

DreamSourceLab's avatar
DreamSourceLab committed
568
    const QSize areaSize = _viewcenter->size();
DreamSourceLab's avatar
DreamSourceLab committed
569 570

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

	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
586
            _offset * 1.0  / length * MaxScrollValue);
DreamSourceLab's avatar
DreamSourceLab committed
587 588 589 590 591 592
	}

	_updating_scroll = false;

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

596
void View::update_scale_offset()
DreamSourceLab's avatar
DreamSourceLab committed
597
{
598
    const uint64_t sample_rate = _session.cur_samplerate();
DreamSourceLab's avatar
DreamSourceLab committed
599 600 601
    assert(sample_rate > 0);

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

610 611 612
    _scale = max(min(_scale, _maxscale), _minscale);
    _offset = max(min(_offset, get_max_offset()), get_min_offset());

DreamSourceLab's avatar
DreamSourceLab committed
613
    _preScale = _scale;
614
    _preOffset = _offset;
DreamSourceLab's avatar
DreamSourceLab committed
615

616
    //_trig_cursor->set_index(_session.get_trigger_pos());
DreamSourceLab's avatar
DreamSourceLab committed
617 618

    _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
619
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
620 621
}

622 623 624 625 626 627 628 629 630 631 632 633
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
634 635 636
void View::signals_changed()
{
    int total_rows = 0;
637
    uint8_t max_height = MaxHeightUnit;
DreamSourceLab's avatar
DreamSourceLab committed
638 639
    vector< boost::shared_ptr<Trace> > time_traces;
    vector< boost::shared_ptr<Trace> > fft_traces;
640

DreamSourceLab's avatar
DreamSourceLab committed
641 642 643 644 645 646
    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
647
    }
DreamSourceLab's avatar
DreamSourceLab committed
648

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

666
        // Find the _fft_viewport in the stack
DreamSourceLab's avatar
DreamSourceLab committed
667
        std::list< Viewport *>::iterator iter = _viewport_list.begin();
668
        for(unsigned int i = 0; i < _viewport_list.size(); i++, iter++)
DreamSourceLab's avatar
DreamSourceLab committed
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 709 710 711
            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;
712
            if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(t)) {
713
                dsoSig->set_scale(dsoSig->get_view_rect().height());
714
            }
DreamSourceLab's avatar
DreamSourceLab committed
715 716
        }
        _time_viewport->clear_measure();
717
    }
DreamSourceLab's avatar
DreamSourceLab committed
718 719 720

    header_updated();
    normalize_layout();
721
    update_scale_offset();
722
    data_updated();
DreamSourceLab's avatar
DreamSourceLab committed
723 724 725 726 727 728 729
}

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
730
        if (object == _ruler || object == _time_viewport || object == _fft_viewport) {
DreamSourceLab's avatar
DreamSourceLab committed
731
            //_hover_point = QPoint(mouse_event->x(), 0);
732 733
            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
734
            double cur_deviate_x = qAbs(mouse_event->pos().x() - integer_x);
735 736
            if (_session.get_device()->dev_inst()->mode == LOGIC &&
                cur_deviate_x < 10)
737
                _hover_point = QPoint(integer_x, mouse_event->pos().y());
DreamSourceLab's avatar
DreamSourceLab committed
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 770 771 772
            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;
773
    int maxNameWidth = 25;
DreamSourceLab's avatar
DreamSourceLab committed
774 775
    int maxLeftWidth = 0;
    int maxRightWidth = 0;
DreamSourceLab's avatar
v0.3  
DreamSourceLab committed
776

DreamSourceLab's avatar
v0.21  
DreamSourceLab committed
777 778 779
    QFont font = QApplication::font();
    QFontMetrics fm(font);

DreamSourceLab's avatar
DreamSourceLab committed
780
    const vector< boost::shared_ptr<Trace> > traces(get_traces(ALL_VIEW));
DreamSourceLab's avatar
DreamSourceLab committed
781
    if (!traces.empty()){
782
        BOOST_FOREACH(const boost::shared_ptr<Trace> t, traces) {
DreamSourceLab's avatar
DreamSourceLab committed
783 784 785
            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
786 787 788 789 790 791 792 793 794 795 796 797
        }
    }
    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
798
    setViewportMargins(headerWidth(), RulerHeight, 0, 0);
DreamSourceLab's avatar
DreamSourceLab committed
799 800
    update_margins();
    update_scroll();
DreamSourceLab's avatar
DreamSourceLab committed
801
    signals_changed();
DreamSourceLab's avatar
DreamSourceLab committed
802
    if (_session.get_device()->dev_inst()->mode == DSO)
DreamSourceLab's avatar
DreamSourceLab committed
803
        _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
804

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

DreamSourceLab's avatar
DreamSourceLab committed
810 811 812
    _scale = min(_scale, _maxscale);

    _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
813
    _header->header_resize();
DreamSourceLab's avatar
DreamSourceLab committed
814 815
    set_update(_time_viewport, true);
    set_update(_fft_viewport, true);
816
    resize();
DreamSourceLab's avatar
DreamSourceLab committed
817 818 819 820 821 822 823 824 825 826 827
}

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

    _preOffset = _offset;

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

836
    _offset = max(min(_offset, get_max_offset()), get_min_offset());
DreamSourceLab's avatar
DreamSourceLab committed
837 838 839

    if (_offset != _preOffset) {
        _ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
840
        viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
841 842 843 844 845
    }
}

void View::v_scroll_value_changed(int value)
{
846
    (void)value;
DreamSourceLab's avatar
DreamSourceLab committed
847
	_header->update();
DreamSourceLab's avatar
DreamSourceLab committed
848
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
849 850 851 852 853 854 855 856 857 858 859
}

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

	// Update the scroll bars
	update_scroll();

	// Repaint the view
860
    _time_viewport->unshow_wait_trigger();
DreamSourceLab's avatar
DreamSourceLab committed
861 862 863
    set_update(_time_viewport, true);
    set_update(_fft_viewport, true);
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
864 865 866 867
}

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

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

    // Update the scroll bars
    update_scroll();

DreamSourceLab's avatar
DreamSourceLab committed
884
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
885 886 887 888 889 890
    _header->update();
}

void View::marker_time_changed()
{
	_ruler->update();
DreamSourceLab's avatar
DreamSourceLab committed
891
    viewport_update();
DreamSourceLab's avatar
DreamSourceLab committed
892 893
}

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

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

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

DreamSourceLab's avatar
DreamSourceLab committed
950 951 952 953 954 955 956
void View::on_measure_updated()
{
    _active_viewport = dynamic_cast<Viewport *>(sender());
    measure_updated();
}

QString View::get_measure(QString option)
DreamSourceLab's avatar
DreamSourceLab committed
957
{
DreamSourceLab's avatar
DreamSourceLab committed
958 959 960 961
    if (_active_viewport) {
        return _active_viewport->get_measure(option);
    }
    return "#####";
DreamSourceLab's avatar
DreamSourceLab committed
962 963 964 965
}

QString View::get_cm_time(int index)
{
966
    return _ruler->format_real_time(get_cursor_samples(index), _session.cur_samplerate());
DreamSourceLab's avatar
DreamSourceLab committed
967 968 969 970 971 972 973
}

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

974 975 976
    uint64_t samples1 = get_cursor_samples(index1);
    uint64_t samples2 = get_cursor_samples(index2);
    uint64_t delta_sample = (samples1 > samples2) ? samples1 - samples2 : samples2 - samples1;
977
    return _ruler->format_real_time(delta_sample, _session.cur_samplerate());
DreamSourceLab's avatar
DreamSourceLab committed
978 979
}

DreamSourceLab's avatar
DreamSourceLab committed
980 981
uint64_t View::get_cursor_samples(int index)
{
982
    assert(index < (int)_cursorList.size());
DreamSourceLab's avatar
DreamSourceLab committed
983

DreamSourceLab's avatar
DreamSourceLab committed
984
    uint64_t ret = 0;
985 986 987 988
    int curIndex = 0;
    for (list<Cursor*>::iterator i = _cursorList.begin();
         i != _cursorList.end(); i++) {
        if (index == curIndex) {
DreamSourceLab's avatar
DreamSourceLab committed
989
            ret = (*i)->index();
990 991 992
        }
        curIndex++;
    }
DreamSourceLab's avatar
DreamSourceLab committed
993
    return ret;
DreamSourceLab's avatar
DreamSourceLab committed
994 995
}

DreamSourceLab's avatar
DreamSourceLab committed
996 997
void View::set_measure_en(int enable)
{
DreamSourceLab's avatar
DreamSourceLab committed
998 999
    BOOST_FOREACH(Viewport *viewport, _viewport_list)
            viewport->set_measure_en(enable);
DreamSourceLab's avatar
DreamSourceLab committed
1000 1001 1002 1003
}

void View::on_state_changed(bool stop)
{
DreamSourceLab's avatar
DreamSourceLab committed
1004 1005 1006 1007
    if (stop) {
        BOOST_FOREACH(Viewport *viewport, _viewport_list)
            viewport->stop_trigger_timer();
    }
1008
    update_scale_offset();
DreamSourceLab's avatar
DreamSourceLab committed
1009 1010
}

1011 1012 1013 1014 1015 1016 1017 1018
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
1019 1020

    return _viewcenter->rect();
1021 1022
}

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

DreamSourceLab's avatar
DreamSourceLab committed
1035
    return view_width;
DreamSourceLab's avatar
v0.3  
DreamSourceLab committed
1036 1037
}

1038 1039 1040 1041 1042 1043
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) {
1044
            view_height = max(view_height, s->get_view_rect().height());
1045 1046
        }
    } else {
DreamSourceLab's avatar
DreamSourceLab committed
1047
        view_height = _viewcenter->height();
1048 1049 1050 1051 1052
    }

    return view_height;
}

1053
int64_t View::get_min_offset()
1054
{
1055 1056 1057 1058
    if (MaxViewRate > 1)
        return floor(get_view_width() * (1 - MaxViewRate));
    else
        return 0;
1059 1060
}

1061
int64_t View::get_max_offset()
1062
{
1063 1064
    return ceil((_session.cur_sampletime() / _scale) -
                (get_view_width() * MaxViewRate));
1065 1066
}

1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085
// -- 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());
    }
}

1086
void View::show_region(uint64_t start, uint64_t end, bool keep)
1087 1088
{
    assert(start <= end);
1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101
    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);
    }
1102 1103
}

DreamSourceLab's avatar
DreamSourceLab committed
1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117
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();
}

1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129
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);
1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144
}

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();
    }
1145 1146
}

1147 1148 1149 1150 1151
bool View::get_dso_trig_moved() const
{
    return _time_viewport->get_dso_trig_moved();
}

DreamSourceLab's avatar
DreamSourceLab committed
1152 1153
} // namespace view
} // namespace pv