Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions doc/pulseview.1
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,20 @@ Ungroup the traces in the currently selected trace group.
.B "CTRL+up/down arrow keys"
Scroll down/up.
.TP
.B "CTRL+m/CTRL+n"
Scroll forward or backward (right or left) in time (horizontally) for the
entire width of the capture, currently shown in the PulseView window viewport,
according to current zoom settings (could be called a "full-page" scroll, by
analogy with printable document viewers)
.TP
.B "CTRL+b"
Save a bitmap screen capture (screenshot) of only the ruler and the viewport,
currently shown in the PulseView window; which allows these screenshots to be
stitched together horizontally afterwards, if they are obtained through a
"full-page" scroll (note: not pixel-perfect). Screenshots are saved with a
filename of 'pulseview_yyyyMMdd_hhmmss.png' (UTC timestamp), in the
temporary directory of the OS.
.TP
.B "CTRL+q"
Quit, i.e. shutdown PulseView (closing all session tabs).
.TP
Expand Down
98 changes: 98 additions & 0 deletions pv/views/trace/view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
#include <QMouseEvent>
#include <QScrollBar>
#include <QVBoxLayout>
#include <QDir>
#include <QDateTime>
#include <QSvgGenerator>

#include <libsigrokcxx/libsigrokcxx.hpp>

Expand Down Expand Up @@ -236,6 +239,22 @@ View::View(Session &session, bool is_main_view, QMainWindow *parent) :
SLOT(on_scroll_to_end_shortcut_triggered()), nullptr, Qt::WidgetWithChildrenShortcut);
end_shortcut_->setAutoRepeat(false);

scroll_view_left_ = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_N), this,
SLOT(on_h_scroll_view_left_triggered()), nullptr, Qt::WidgetWithChildrenShortcut);
scroll_view_left_->setAutoRepeat(false);

scroll_view_right_ = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_M), this,
SLOT(on_h_scroll_view_right_triggered()), nullptr, Qt::WidgetWithChildrenShortcut);
scroll_view_right_->setAutoRepeat(false);

bitmap_screenshot_ = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_B), this,
SLOT(on_bitmap_screenshot_triggered()), nullptr, Qt::WidgetWithChildrenShortcut);
bitmap_screenshot_->setAutoRepeat(false);

svg_screenshot_ = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_G), this,
SLOT(on_svg_screenshot_triggered()), nullptr, Qt::WidgetWithChildrenShortcut);
svg_screenshot_->setAutoRepeat(false);

grab_ruler_left_shortcut_ = new QShortcut(QKeySequence(Qt::Key_1), this,
nullptr, nullptr, Qt::WidgetWithChildrenShortcut);
connect(grab_ruler_left_shortcut_, &QShortcut::activated,
Expand Down Expand Up @@ -1397,6 +1416,27 @@ void View::set_scroll_default()
set_v_offset(extents.first);
}

void View::h_scroll_view_fullpage(int direction)
{
if (updating_scroll_)
return;

// Disable sticky scrolling when user moves the horizontal scroll bar
// during a running acquisition
if (sticky_scrolling_ && (session_.get_capture_state() == Session::Running)) {
sticky_scrolling_ = false;
sticky_scrolling_changed(false);
}

const QSize areaSize = viewport_->size();
double length = scale_ * areaSize.width();
Timestamp new_offset = offset_ + direction*length;
set_offset(new_offset);

ruler_->update();
viewport_->update();
}

void View::determine_if_header_was_shrunk()
{
const int header_pane_width =
Expand Down Expand Up @@ -1738,6 +1778,64 @@ void View::on_scroll_to_end_shortcut_triggered()
set_h_offset(get_h_scrollbar_maximum());
}

void View::on_h_scroll_view_left_triggered()
{
h_scroll_view_fullpage(-1);
}

void View::on_h_scroll_view_right_triggered()
{
h_scroll_view_fullpage(1);
}

void View::on_bitmap_screenshot_triggered()
{
//note: viewport_ does not contain track name markings at left, nor ruler
//scrollarea_ is the same, except with added scrollbars
//here we will get only viewport_ and ruler_, so as to assist in stitching/appending images
QSize vpSize = viewport_->size();
QSize rlSize = ruler_->size();
QSize imgsize(vpSize.width(), vpSize.height()+rlSize.height());
QImage img(imgsize, QImage::Format::Format_ARGB32);
QPainter painter(&img);
ruler_->render(&painter, QPoint(0, 0));
scrollarea_->render(&painter, QPoint(0, rlSize.height()));
QString fileStamp = QDateTime::currentDateTimeUtc().toString("yyyyMMdd_hhmmss");
QString fileName = QString("pulseview_%1.png").arg(fileStamp);
QString filePath = QDir( QDir::tempPath() ).filePath(fileName);
bool issaved = img.save(filePath);
qDebug() << "Screenshot grabbed (" << issaved << "): " << filePath;
}

void View::on_svg_screenshot_triggered()
{
//note: viewport_ does not contain track name markings at left, nor ruler
//scrollarea_ is the same, except with added scrollbars
//here we will get only viewport_ and ruler_, so as to assist in stitching/appending images
QSize vpSize = viewport_->size();
QSize rlSize = ruler_->size();
QSize imgsize(vpSize.width(), vpSize.height()+rlSize.height());
QString fileStamp = QDateTime::currentDateTimeUtc().toString("yyyyMMdd_hhmmss");
QString fileName = QString("pulseview_%1.svg").arg(fileStamp);
QString filePath = QDir( QDir::tempPath() ).filePath(fileName);

// note that there is no explicit .save command for SVG generator
QSvgGenerator generator;
generator.setFileName(filePath);
generator.setSize(imgsize);
generator.setViewBox(QRect(0, 0, imgsize.width(), imgsize.height()));
generator.setTitle(fileName);
generator.setTitle(tr("An SVG drawing created by the Qt5 SVG Generator from PulseView"));

QPainter painter;
painter.begin(&generator);
ruler_->render(&painter, QPoint(0, 0));
scrollarea_->render(&painter, QPoint(0, rlSize.height()));
painter.end();

qDebug() << "Screenshot grabbed: " << filePath;
}

void View::h_scroll_value_changed(int value)
{
if (updating_scroll_)
Expand Down
10 changes: 10 additions & 0 deletions pv/views/trace/view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,8 @@ public Q_SLOTS:
void update_view_range_metaobject() const;
void update_hover_point();

void h_scroll_view_fullpage(int direction);

public:
void row_item_appearance_changed(bool label, bool content);
void time_item_appearance_changed(bool label, bool content);
Expand All @@ -437,6 +439,10 @@ private Q_SLOTS:
void on_zoom_out_shortcut_triggered();
void on_scroll_to_start_shortcut_triggered();
void on_scroll_to_end_shortcut_triggered();
void on_h_scroll_view_left_triggered();
void on_h_scroll_view_right_triggered();
void on_bitmap_screenshot_triggered();
void on_svg_screenshot_triggered();

void h_scroll_value_changed(int value);
void v_scroll_value_changed();
Expand Down Expand Up @@ -509,6 +515,10 @@ private Q_SLOTS:
QShortcut *home_shortcut_, *end_shortcut_;
QShortcut *grab_ruler_left_shortcut_, *grab_ruler_right_shortcut_;
QShortcut *cancel_grab_shortcut_;
QShortcut *scroll_view_left_;
QShortcut *scroll_view_right_;
QShortcut *bitmap_screenshot_;
QShortcut *svg_screenshot_;

mutable mutex signal_mutex_;
vector< shared_ptr<Signal> > signals_;
Expand Down