diff --git a/icons/navigation.svg b/icons/navigation.svg
new file mode 100644
index 00000000..cbafe7b3
--- /dev/null
+++ b/icons/navigation.svg
@@ -0,0 +1,535 @@
+
+
+
+
diff --git a/pulseview.qrc b/pulseview.qrc
index ceda06df..069dd8eb 100644
--- a/pulseview.qrc
+++ b/pulseview.qrc
@@ -16,6 +16,7 @@
 	icons/media-playback-pause.png
 	icons/media-playback-start.png
 	icons/menu.svg
+	icons/navigation.svg
 	icons/preferences-system.png
 	icons/settings-general.png
 	icons/settings-views.svg
diff --git a/pv/dialogs/settings.cpp b/pv/dialogs/settings.cpp
index efe854af..50eedece 100644
--- a/pv/dialogs/settings.cpp
+++ b/pv/dialogs/settings.cpp
@@ -144,6 +144,15 @@ void Settings::create_pages()
 	viewButton->setTextAlignment(Qt::AlignVCenter);
 	viewButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
 
+	// Navigation page
+	pages->addWidget(get_navigation_settings_form(pages));
+
+	QListWidgetItem *navButton = new QListWidgetItem(page_list);
+	navButton->setIcon(QIcon(":/icons/navigation.svg"));
+	navButton->setText(tr("Navigation"));
+	navButton->setTextAlignment(Qt::AlignVCenter);
+	navButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+
 #ifdef ENABLE_DECODE
 	// Decoder page
 	pages->addWidget(get_decoder_settings_form(pages));
@@ -384,6 +393,54 @@ QWidget *Settings::get_view_settings_form(QWidget *parent) const
 	return form;
 }
 
+QWidget *Settings::get_navigation_settings_form(QWidget *parent)
+{
+	GlobalSettings settings;
+
+	QWidget *form = new QWidget(parent);
+	QVBoxLayout *form_layout = new QVBoxLayout(form);
+
+	// Navigation control settings
+	QGroupBox *nav_group = new QGroupBox(tr("Trace Navigation Controls"));
+	form_layout->addWidget(nav_group);
+
+	QGridLayout *nav_layout = new QGridLayout();
+	nav_group->setLayout(nav_layout);
+	
+	int row = 0;
+	
+	// buttons for default settings
+	QPushButton *zoom_but = new QPushButton( tr("Reset to &Zoom as main controls") );
+	connect(zoom_but, SIGNAL(clicked(bool)), this, SLOT(on_nav_resetZoomControls_clicked(bool)));
+	nav_layout->addWidget(zoom_but, row, 0);
+	QPushButton *move_but = new QPushButton( tr("Reset to &Move as main controls") );
+	connect(move_but, SIGNAL(clicked(bool)), this, SLOT(on_nav_resetMoveControls_clicked(bool)));
+	nav_layout->addWidget(move_but, row, 1);
+	row++;
+	
+	// heading
+	QLabel *hdr1_label = new QLabel(tr("Control"));
+	hdr1_label->setAlignment(Qt::AlignLeft);
+	nav_layout->addWidget(hdr1_label, row, 0);
+	QLabel *hdr2_label = new QLabel(tr("Operation"));
+	hdr2_label->setAlignment(Qt::AlignLeft);
+	nav_layout->addWidget(hdr2_label, row, 1);
+	QLabel *hdr3_label = new QLabel(tr("NumPages or NumTimes"));
+	hdr3_label->setAlignment(Qt::AlignLeft);
+	nav_layout->addWidget(hdr3_label, row, 2);
+	row++;
+	// entries
+	NAV_SETTINGS_ROWS(UpDown,	"Up / Down", row); row++;
+	NAV_SETTINGS_ROWS(LeftRight,"Left / Right", row); row++;
+	NAV_SETTINGS_ROWS(PageUpDown,"PageUp / PageDown", row); row++;
+	NAV_SETTINGS_ROWS(WheelHori,"Mouse Wheel Horizontal", row); row++;
+	NAV_SETTINGS_ROWS(WheelVert,"Mouse Wheel Vertical", row); row++;
+	
+	nav_load_gui_from_settings();
+	
+	return form;
+}
+
 QWidget *Settings::get_decoder_settings_form(QWidget *parent)
 {
 #ifdef ENABLE_DECODE
@@ -769,6 +826,38 @@ void Settings::on_view_defaultLogicHeight_changed(int value)
 	settings.setValue(GlobalSettings::Key_View_DefaultLogicHeight, value);
 }
 
+void Settings::on_nav_resetZoomControls_clicked(bool checked)
+{
+	printf("on_nav_resetZoomControls_clicked : %d\n", checked?1:0);
+	GlobalSettings settings;
+	settings.set_nav_zoom_defaults(true);
+	nav_load_gui_from_settings();
+}
+
+void Settings::on_nav_resetMoveControls_clicked(bool checked)
+{
+	printf("on_nav_resetMoveControls_clicked : %d\n", checked?1:0);
+	GlobalSettings settings;
+	settings.set_nav_move_defaults(true);
+	nav_load_gui_from_settings();
+}
+
+NAV_SETTINGS_FUNC_DEFINE(UpDown)
+NAV_SETTINGS_FUNC_DEFINE(LeftRight)
+NAV_SETTINGS_FUNC_DEFINE(PageUpDown)
+NAV_SETTINGS_FUNC_DEFINE(WheelHori)
+NAV_SETTINGS_FUNC_DEFINE(WheelVert)
+
+void Settings::nav_load_gui_from_settings()
+{
+	GlobalSettings settings;
+	NAV_SETTINGS_LOAD(UpDown);
+	NAV_SETTINGS_LOAD(LeftRight);
+	NAV_SETTINGS_LOAD(PageUpDown);
+	NAV_SETTINGS_LOAD(WheelHori);
+	NAV_SETTINGS_LOAD(WheelVert);
+}
+
 #ifdef ENABLE_DECODE
 void Settings::on_dec_initialStateConfigurable_changed(int state)
 {
diff --git a/pv/dialogs/settings.hpp b/pv/dialogs/settings.hpp
index 157fa6ba..764a8c99 100644
--- a/pv/dialogs/settings.hpp
+++ b/pv/dialogs/settings.hpp
@@ -27,6 +27,79 @@
 #include 
 #include 
 #include 
+#include 
+
+#define NAV_SETTINGS_FUNC_DECLARE1(name)			\
+	void on_nav_ ## name ## Type_changed(int type);	\
+	void on_nav_ ## name ## Amount_changed(const QString& astr)
+
+#define NAV_SETTINGS_FUNC_DECLARE(name)		\
+	NAV_SETTINGS_FUNC_DECLARE1(name);		\
+	NAV_SETTINGS_FUNC_DECLARE1(name ## Alt);\
+	NAV_SETTINGS_FUNC_DECLARE1(name ## Ctrl);\
+	NAV_SETTINGS_FUNC_DECLARE1(name ## Shift)
+
+#define NAV_SETTINGS_FUNC_DEFINE1(name)				\
+	void Settings::on_nav_ ## name ## Type_changed(int type){	\
+		GlobalSettings settings;	\
+		settings.setValue(GlobalSettings::Key_Nav_ ## name ## Type, type);	\
+	}	\
+	void Settings::on_nav_ ## name ## Amount_changed(const QString& astr) {	\
+		GlobalSettings settings;	\
+		settings.setValue(GlobalSettings::Key_Nav_ ## name ## Amount, astr.toDouble());	\
+	}
+
+#define NAV_SETTINGS_FUNC_DEFINE(name)		\
+	NAV_SETTINGS_FUNC_DEFINE1(name)			\
+	NAV_SETTINGS_FUNC_DEFINE1(name ## Alt)	\
+	NAV_SETTINGS_FUNC_DEFINE1(name ## Ctrl)	\
+	NAV_SETTINGS_FUNC_DEFINE1(name ## Shift)
+
+#define NAV_SETTINGS_ROW(name, text, row)			\
+	QLabel * name ## _label = new QLabel(tr(text));\
+	name ## _label->setAlignment(Qt::AlignLeft);	\
+	nav_layout->addWidget(name ## _label, row, 0);	\
+	\
+	name ## _type_cb_ = new QComboBox();	\
+	name ## _type_cb_->addItem(tr("None"), NAV_TYPE_NONE);	\
+	name ## _type_cb_->addItem(tr("Zoom"), NAV_TYPE_ZOOM);	\
+	name ## _type_cb_->addItem(tr("Move Horizontally"), NAV_TYPE_HORI);	\
+	name ## _type_cb_->addItem(tr("Move Vertically"), NAV_TYPE_VERT);	\
+	name ## _type_cb_->setCurrentIndex( settings.value(GlobalSettings::Key_Nav_ ## name ## Type).toInt() );	\
+	connect(name ## _type_cb_, SIGNAL(currentIndexChanged(int)), this, SLOT(on_nav_ ## name ## Type_changed(int)));	\
+	nav_layout->addWidget(name ## _type_cb_, row, 1);	\
+	\
+	name ## _amount_edit_ = new QLineEdit();	\
+	name ## _amount_edit_->setText( settings.value(GlobalSettings::Key_Nav_ ## name ## Amount).toString() );	\
+	connect(name ## _amount_edit_, SIGNAL(textChanged(const QString&)), this, SLOT(on_nav_ ## name ## Amount_changed(const QString&)));	\
+	nav_layout->addWidget(name ## _amount_edit_, row, 2)
+//	name ## _amount_edit_->setValidator( new QDoubleValidator(name ## _amount_edit_) );
+
+#define NAV_SETTINGS_ROWS(name, text, row)			\
+	NAV_SETTINGS_ROW(name,          text,            row*4 + 0);	\
+	NAV_SETTINGS_ROW(name ## Alt,   text " + Alt",   row*4 + 1);	\
+	NAV_SETTINGS_ROW(name ## Ctrl,  text " + Ctrl",  row*4 + 2);	\
+	NAV_SETTINGS_ROW(name ## Shift, text " + Shift", row*4 + 3)
+
+#define NAV_SETTINGS_VAR_DECLARE1(name)	\
+	QComboBox * name ## _type_cb_;		\
+	QLineEdit* name ## _amount_edit_
+
+#define NAV_SETTINGS_VAR_DECLARE(name)	\
+	NAV_SETTINGS_VAR_DECLARE1(name);	\
+	NAV_SETTINGS_VAR_DECLARE1(name ## Alt);	\
+	NAV_SETTINGS_VAR_DECLARE1(name ## Ctrl);	\
+	NAV_SETTINGS_VAR_DECLARE1(name ## Shift)
+
+#define NAV_SETTINGS_LOAD1(name)			\
+	name ## _type_cb_->setCurrentIndex( settings.value(GlobalSettings::Key_Nav_ ## name ## Type).toInt() );	\
+	name ## _amount_edit_->setText( settings.value(GlobalSettings::Key_Nav_ ## name ## Amount).toString() )
+
+#define NAV_SETTINGS_LOAD(name)			\
+	NAV_SETTINGS_LOAD1(name);			\
+	NAV_SETTINGS_LOAD1(name ## Alt);	\
+	NAV_SETTINGS_LOAD1(name ## Ctrl);	\
+	NAV_SETTINGS_LOAD1(name ## Shift)
 
 namespace pv {
 
@@ -49,6 +122,7 @@ class Settings : public QDialog
 
 	QWidget *get_general_settings_form(QWidget *parent) const;
 	QWidget *get_view_settings_form(QWidget *parent) const;
+	QWidget *get_navigation_settings_form(QWidget *parent);
 	QWidget *get_decoder_settings_form(QWidget *parent);
 	QWidget *get_about_page(QWidget *parent) const;
 	QWidget *get_logging_page(QWidget *parent) const;
@@ -77,7 +151,15 @@ private Q_SLOTS:
 	void on_view_conversionThresholdDispMode_changed(int state);
 	void on_view_defaultDivHeight_changed(int value);
 	void on_view_defaultLogicHeight_changed(int value);
-#ifdef ENABLE_DECODE
+	void on_nav_resetZoomControls_clicked(bool checked);
+	void on_nav_resetMoveControls_clicked(bool checked);
+	NAV_SETTINGS_FUNC_DECLARE(UpDown);
+	NAV_SETTINGS_FUNC_DECLARE(LeftRight);
+	NAV_SETTINGS_FUNC_DECLARE(PageUpDown);
+	NAV_SETTINGS_FUNC_DECLARE(WheelHori);
+	NAV_SETTINGS_FUNC_DECLARE(WheelVert);
+	void nav_load_gui_from_settings();
+	#ifdef ENABLE_DECODE
 	void on_dec_initialStateConfigurable_changed(int state);
 	void on_dec_exportFormat_changed(const QString &text);
 	void on_dec_alwaysshowallrows_changed(int state);
@@ -91,6 +173,11 @@ private Q_SLOTS:
 	DeviceManager &device_manager_;
 	PageListWidget *page_list;
 	QStackedWidget *pages;
+	NAV_SETTINGS_VAR_DECLARE(UpDown);
+	NAV_SETTINGS_VAR_DECLARE(LeftRight);
+	NAV_SETTINGS_VAR_DECLARE(PageUpDown);
+	NAV_SETTINGS_VAR_DECLARE(WheelHori);
+	NAV_SETTINGS_VAR_DECLARE(WheelVert);
 
 #ifdef ENABLE_DECODE
 	QLineEdit *ann_export_format_;
diff --git a/pv/globalsettings.cpp b/pv/globalsettings.cpp
index ca649bef..34ad983b 100644
--- a/pv/globalsettings.cpp
+++ b/pv/globalsettings.cpp
@@ -70,6 +70,11 @@ const QString GlobalSettings::Key_View_CursorFillColor = "View_CursorFillColor";
 const QString GlobalSettings::Key_View_CursorShowFrequency = "View_CursorShowFrequency";
 const QString GlobalSettings::Key_View_CursorShowInterval = "View_CursorShowInterval";
 const QString GlobalSettings::Key_View_CursorShowSamples = "View_CursorShowSamples";
+NAV_GSETTINGS_VAR_SETUP(UpDown);
+NAV_GSETTINGS_VAR_SETUP(LeftRight);
+NAV_GSETTINGS_VAR_SETUP(PageUpDown);
+NAV_GSETTINGS_VAR_SETUP(WheelHori);
+NAV_GSETTINGS_VAR_SETUP(WheelVert);
 const QString GlobalSettings::Key_Dec_InitialStateConfigurable = "Dec_InitialStateConfigurable";
 const QString GlobalSettings::Key_Dec_ExportFormat = "Dec_ExportFormat";
 const QString GlobalSettings::Key_Dec_AlwaysShowAllRows = "Dec_AlwaysShowAllRows";
@@ -98,6 +103,72 @@ void GlobalSettings::save_internal_defaults()
 	default_palette_ = QApplication::palette();
 }
 
+// make controls zoom the traces when not using any key modifiers
+// these controls are similar to the old controls used before customisation was introduced.
+void GlobalSettings::set_nav_zoom_defaults(bool force)
+{
+	// zoom
+	NAV_GSETTINGS_VAR_DEFAULT(UpDown,			NAV_TYPE_ZOOM, 0.25);	// up/down arrow will zoom the traces by 1/4x
+	// small vertical movement
+	NAV_GSETTINGS_VAR_DEFAULT(UpDownCtrl,		NAV_TYPE_VERT, 0.125);	// up/down with any modifier will move traces vertically by 1/8 page
+	NAV_GSETTINGS_VAR_DEFAULT(UpDownAlt,		NAV_TYPE_VERT, 0.125);
+	NAV_GSETTINGS_VAR_DEFAULT(UpDownShift,		NAV_TYPE_VERT, 0.125);
+	// small horizontal movement
+	NAV_GSETTINGS_VAR_DEFAULT(LeftRight,		NAV_TYPE_HORI, 0.125);	// left/right arrow        will move the trace by 1/8 page
+	NAV_GSETTINGS_VAR_DEFAULT(LeftRightShift,	NAV_TYPE_HORI, 0.125);	// left/right arrow + ctrl will move the trace by 1/8 page
+	NAV_GSETTINGS_VAR_DEFAULT(LeftRightCtrl,	NAV_TYPE_HORI, 0.25);	// left/right arrow + ctrl will move the trace by 1/4 page
+	NAV_GSETTINGS_VAR_DEFAULT(LeftRightAlt,		NAV_TYPE_HORI, 0.5);	// left/right arrow + alt  will move the trace by 1/2 page
+	// big vertical movement
+	NAV_GSETTINGS_VAR_DEFAULT(PageUpDown,		NAV_TYPE_VERT, 1.0);	// page up/down         will move traces vertically by 1 page
+	NAV_GSETTINGS_VAR_DEFAULT(PageUpDownShift,	NAV_TYPE_VERT, 1.0);	// page up/down + shift will move traces vertically by 1 page
+	NAV_GSETTINGS_VAR_DEFAULT(PageUpDownCtrl,	NAV_TYPE_VERT, 2.0);	// page up/down + ctrl  will move traces vertically by 2 page
+	NAV_GSETTINGS_VAR_DEFAULT(PageUpDownAlt,	NAV_TYPE_VERT, 4.0);	// page up/down + alt   will move traces vertically by 4 page
+	// vertical mosewheel can zoom and move horizontally and vertically
+	NAV_GSETTINGS_VAR_DEFAULT(WheelVert,		NAV_TYPE_ZOOM, 0.25);	// vertical   mousewheel will zoom the traces by 1/4x
+	NAV_GSETTINGS_VAR_DEFAULT(WheelVertShift,	NAV_TYPE_ZOOM, 0.25);	// vertical   mousewheel + shift will zoom the traces by 1/4x
+	NAV_GSETTINGS_VAR_DEFAULT(WheelVertCtrl,	NAV_TYPE_VERT, 0.5);	// vertical   mousewheel + ctrl will move the traces by 1/2 page
+	NAV_GSETTINGS_VAR_DEFAULT(WheelVertAlt,		NAV_TYPE_HORI, 1.0);	// vertical   mousewheel + alt  will move the traces by 1 page
+	// horizontal mousewheel always moves horizontally
+	NAV_GSETTINGS_VAR_DEFAULT(WheelHori,		NAV_TYPE_HORI, 0.25);	// horizontal mousewheel will move the traces by 1/4 page
+	NAV_GSETTINGS_VAR_DEFAULT(WheelHoriShift,	NAV_TYPE_HORI, 0.25);	// horizontal mousewheel + shift will move the traces by 1/4 page
+	NAV_GSETTINGS_VAR_DEFAULT(WheelHoriCtrl,	NAV_TYPE_HORI, 0.5);	// horizontal mousewheel + ctrl  will move the traces by 1/2 page
+	NAV_GSETTINGS_VAR_DEFAULT(WheelHoriAlt,		NAV_TYPE_HORI, 1.0);	// horizontal mousewheel + alt   will move the traces by 1 page
+}
+
+// make controls move the traces without key modifiers.
+// slow speed move is default
+// ctrl modifier does medium speed move
+// alt  modifier does fast speed move
+// shift key always does zoom
+void GlobalSettings::set_nav_move_defaults(bool force)
+{
+	// vertical movement
+	NAV_GSETTINGS_VAR_DEFAULT(UpDown,			NAV_TYPE_VERT, 0.125);	// up/down arrow will move the traces by 1/8 page
+	// zoom
+	NAV_GSETTINGS_VAR_DEFAULT(WheelHoriShift,	NAV_TYPE_ZOOM, 0.25);	// horizontal mousewheel + shift will zoom in/out by 1/4 x
+	NAV_GSETTINGS_VAR_DEFAULT(WheelVertShift,	NAV_TYPE_ZOOM, 0.25);	// vertical   mousewheel + shift will zoom in/out by 1/4 x
+	NAV_GSETTINGS_VAR_DEFAULT(UpDownShift,		NAV_TYPE_ZOOM, 1.0);	// up/down arrow + shift will zoom in/out  by 1x
+	NAV_GSETTINGS_VAR_DEFAULT(PageUpDownShift,	NAV_TYPE_ZOOM, 2.0);	// page up/down  + shift will zoom in/out  by 2x
+	// horizontal movement
+	NAV_GSETTINGS_VAR_DEFAULT(LeftRight,		NAV_TYPE_HORI, 0.125);	// left/right arrow        will move the trace by 1/8 page
+	NAV_GSETTINGS_VAR_DEFAULT(LeftRightCtrl,	NAV_TYPE_HORI, 0.25);	// left/right arrow + ctrl will move the trace by 1/4 page
+	NAV_GSETTINGS_VAR_DEFAULT(LeftRightAlt,		NAV_TYPE_HORI, 0.5);	// left/right arrow + alt  will move the trace by 1/2 page
+	NAV_GSETTINGS_VAR_DEFAULT(PageUpDown,		NAV_TYPE_HORI, 1.0);	// page up/down        will move the trace by 1 page
+	NAV_GSETTINGS_VAR_DEFAULT(PageUpDownCtrl,	NAV_TYPE_HORI, 2.0);	// page up/down + ctrl will move the trace by 2 pages
+	NAV_GSETTINGS_VAR_DEFAULT(PageUpDownAlt,	NAV_TYPE_HORI, 4.0);	// page up/down + alt  will move the trace by 4 pages
+	// horizontal movement with mousewheel
+	NAV_GSETTINGS_VAR_DEFAULT(WheelHori,		NAV_TYPE_HORI, 0.25);	// horizontal mousewheel will move the traces by 1/4 page
+	NAV_GSETTINGS_VAR_DEFAULT(WheelVert,		NAV_TYPE_HORI, 0.25);	// vertical   mousewheel will move the traces by 1/4 page
+	NAV_GSETTINGS_VAR_DEFAULT(WheelHoriCtrl,	NAV_TYPE_HORI, 0.5);	// horizontal mousewheel + ctrl will move the traces by 1/2 page
+	NAV_GSETTINGS_VAR_DEFAULT(WheelVertCtrl,	NAV_TYPE_HORI, 0.5);	// vertical   mousewheel + ctrl will move the traces by 1/2 page
+	NAV_GSETTINGS_VAR_DEFAULT(WheelHoriAlt,		NAV_TYPE_HORI, 1.0);	// horizontal mousewheel + alt will move the traces by 1 page
+	NAV_GSETTINGS_VAR_DEFAULT(WheelVertAlt,		NAV_TYPE_HORI, 1.0);	// vertical   mousewheel + alt will move the traces by 1 page
+	// not used
+	NAV_GSETTINGS_VAR_DEFAULT(UpDownCtrl,		NAV_TYPE_NONE, 0);
+	NAV_GSETTINGS_VAR_DEFAULT(UpDownAlt,		NAV_TYPE_NONE, 0);
+	NAV_GSETTINGS_VAR_DEFAULT(LeftRightShift,	NAV_TYPE_NONE, 0);
+}
+
 void GlobalSettings::set_defaults_where_needed()
 {
 	if (!contains(Key_General_Language)) {
@@ -154,7 +225,9 @@ void GlobalSettings::set_defaults_where_needed()
 
 	if (!contains(Key_View_CursorShowFrequency))
 		setValue(Key_View_CursorShowFrequency, true);
-
+	
+	set_nav_zoom_defaults(false);
+	
 	// %c was used for the row name in the past so we need to transition such users
 	if (!contains(Key_Dec_ExportFormat) ||
 		value(Key_Dec_ExportFormat).toString() == "%s %d: %c: %1")
diff --git a/pv/globalsettings.hpp b/pv/globalsettings.hpp
index e41c2ea9..151c300e 100644
--- a/pv/globalsettings.hpp
+++ b/pv/globalsettings.hpp
@@ -48,6 +48,39 @@ class GlobalSettingsInterface
 };
 
 
+// type of navigation to perform
+#define NAV_TYPE_NONE		0
+#define NAV_TYPE_ZOOM		1
+#define NAV_TYPE_HORI		2
+#define NAV_TYPE_VERT		3
+
+#define NAV_GSETTINGS_VAR_DECLARE(name)						\
+	static const QString Key_Nav_ ## name ## Type;			\
+	static const QString Key_Nav_ ## name ## Amount;		\
+	static const QString Key_Nav_ ## name ## AltType;		\
+	static const QString Key_Nav_ ## name ## AltAmount;		\
+	static const QString Key_Nav_ ## name ## CtrlType;		\
+	static const QString Key_Nav_ ## name ## CtrlAmount;	\
+	static const QString Key_Nav_ ## name ## ShiftType;		\
+	static const QString Key_Nav_ ## name ## ShiftAmount
+
+#define NAV_GSETTINGS_VAR_SETUP(name)						\
+	const QString GlobalSettings::Key_Nav_ ## name ## Type = "Nav_" #name "Type";				\
+	const QString GlobalSettings::Key_Nav_ ## name ## Amount = "Nav_" #name "Amount";			\
+	const QString GlobalSettings::Key_Nav_ ## name ## AltType = "Nav_" #name "AltType";			\
+	const QString GlobalSettings::Key_Nav_ ## name ## AltAmount = "Nav_" #name "AltAmount";		\
+	const QString GlobalSettings::Key_Nav_ ## name ## CtrlType = "Nav_" #name "CtrlType";		\
+	const QString GlobalSettings::Key_Nav_ ## name ## CtrlAmount = "Nav_" #name "CtrlAmount";	\
+	const QString GlobalSettings::Key_Nav_ ## name ## ShiftType = "Nav_" #name "ShiftType";		\
+	const QString GlobalSettings::Key_Nav_ ## name ## ShiftAmount = "Nav_" #name "ShiftAmount"
+
+#define NAV_GSETTINGS_VAR_DEFAULT(name, type, amount)	\
+	if (!contains(Key_Nav_ ## name ## Type) || force)	\
+		setValue(Key_Nav_ ## name ## Type, type);		\
+	if (!contains(Key_Nav_ ## name ## Amount) || force)	\
+		setValue(Key_Nav_ ## name ## Amount, amount)
+
+
 class GlobalSettings : public QSettings
 {
 	Q_OBJECT
@@ -75,6 +108,11 @@ class GlobalSettings : public QSettings
 	static const QString Key_View_CursorShowInterval;
 	static const QString Key_View_CursorShowFrequency;
 	static const QString Key_View_CursorShowSamples;
+	NAV_GSETTINGS_VAR_DECLARE(UpDown);
+	NAV_GSETTINGS_VAR_DECLARE(LeftRight);
+	NAV_GSETTINGS_VAR_DECLARE(PageUpDown);
+	NAV_GSETTINGS_VAR_DECLARE(WheelHori);
+	NAV_GSETTINGS_VAR_DECLARE(WheelVert);
 	static const QString Key_Dec_InitialStateConfigurable;
 	static const QString Key_Dec_ExportFormat;
 	static const QString Key_Dec_AlwaysShowAllRows;
@@ -92,6 +130,8 @@ class GlobalSettings : public QSettings
 
 	void save_internal_defaults();
 	void set_defaults_where_needed();
+	void set_nav_zoom_defaults(bool force);
+	void set_nav_move_defaults(bool force);
 	void set_bright_theme_default_colors();
 	void set_dark_theme_default_colors();
 
diff --git a/pv/views/trace/view.cpp b/pv/views/trace/view.cpp
index 47cb96b2..dd519b8e 100644
--- a/pv/views/trace/view.cpp
+++ b/pv/views/trace/view.cpp
@@ -223,11 +223,6 @@ View::View(Session &session, bool is_main_view, QMainWindow *parent) :
 		SLOT(on_zoom_out_shortcut_triggered()), nullptr, Qt::WidgetWithChildrenShortcut);
 	zoom_out_shortcut_->setAutoRepeat(false);
 
-	zoom_in_shortcut_2_ = new QShortcut(QKeySequence(Qt::Key_Up), this,
-		SLOT(on_zoom_in_shortcut_triggered()), nullptr, Qt::WidgetWithChildrenShortcut);
-	zoom_out_shortcut_2_ = new QShortcut(QKeySequence(Qt::Key_Down), this,
-		SLOT(on_zoom_out_shortcut_triggered()), nullptr, Qt::WidgetWithChildrenShortcut);
-
 	home_shortcut_ = new QShortcut(QKeySequence(Qt::Key_Home), this,
 		SLOT(on_scroll_to_start_shortcut_triggered()), nullptr, Qt::WidgetWithChildrenShortcut);
 	home_shortcut_->setAutoRepeat(false);
@@ -254,6 +249,26 @@ View::View(Session &session, bool is_main_view, QMainWindow *parent) :
 		this, [=]{grabbed_widget_ = nullptr;});
 	cancel_grab_shortcut_->setAutoRepeat(false);
 
+	// Keyboard navigation
+	// This sets them all up as disabled initially.
+	NAV_KB_VAR_SETUP(up,		Qt::Key_Up);
+	NAV_KB_VAR_SETUP(down,		Qt::Key_Down);
+	NAV_KB_VAR_SETUP(left,		Qt::Key_Left);
+	NAV_KB_VAR_SETUP(right,		Qt::Key_Right);
+	NAV_KB_VAR_SETUP(pageup,	Qt::Key_PageUp);
+	NAV_KB_VAR_SETUP(pagedown,	Qt::Key_PageDown);
+	// Mousewheel navigation
+	// This sets them all up as disabled initially.
+	NAV_MW_VAR_SETUP(hori);
+	NAV_MW_VAR_SETUP(vert);
+	
+	// Load settings for keyboard and mousewheel navigation
+	NAV_KB_SETTING_LOAD(UpDown,		up, down);
+	NAV_KB_SETTING_LOAD(LeftRight,	left, right);
+	NAV_KB_SETTING_LOAD(PageUpDown,	pageup, pagedown);
+	NAV_MW_SETTING_LOAD(WheelHori,	hori);
+	NAV_MW_SETTING_LOAD(WheelVert,	vert);
+	
 	// Trigger the initial event manually. The default device has signals
 	// which were created before this object came into being
 	signals_changed();
@@ -1195,6 +1210,12 @@ void View::on_setting_changed(const QString &key, const QVariant &value)
 
 	if (key == GlobalSettings::Key_View_SnapDistance)
 		snap_distance_ = settings.value(GlobalSettings::Key_View_SnapDistance).toInt();
+
+	NAV_KB_SETTING_CHANGED(UpDown,    up, down)
+	NAV_KB_SETTING_CHANGED(LeftRight, left, right)
+	NAV_KB_SETTING_CHANGED(PageUpDown, pageup, pagedown)
+	NAV_MW_SETTING_CHANGED(WheelHori, hori)
+	NAV_MW_SETTING_CHANGED(WheelVert, vert)
 }
 
 void View::trigger_event(int segment_id, util::Timestamp location)
@@ -1738,6 +1759,91 @@ void View::on_scroll_to_end_shortcut_triggered()
 	set_h_offset(get_h_scrollbar_maximum());
 }
 
+
+void View::nav_zoom(double numTimes)
+{
+	QPoint global_point = QCursor::pos();
+	printf("nav_zoom()  global_point(%d, %d)  %d\n", global_point.x(), global_point.y(), global_point.isNull()?1:0);
+	if( global_point.isNull() )
+	{
+		zoom(-numTimes);
+		return;
+	}
+	
+	QPoint widget_point = viewport_->mapFromGlobal(global_point);
+	printf("nav_zoom()  widget_point(%d, %d)  %d\n", widget_point.x(), widget_point.y(), widget_point.isNull()?1:0);
+	if( widget_point.isNull() ||
+		widget_point.x() < 0 || widget_point.x() > viewport_->width() ||
+		widget_point.y() < 0 || widget_point.y() > viewport_->height())
+	{
+		zoom(-numTimes);
+		return;
+	}
+	
+	printf("zoom t mouse\n");
+	zoom(-numTimes, widget_point.x());
+}
+
+void View::nav_zoom(double numTimes, int offset)
+{
+	zoom(-numTimes, offset);
+}
+
+void View::nav_move_hori(double numPages)
+{
+	double page_width = viewport_->width();
+	double move_amount = numPages * page_width;
+	int curr_pos = scrollarea_->horizontalScrollBar()->sliderPosition();
+	int new_pos = curr_pos + move_amount;
+
+//	printf("nav_move_hori(): page_width=%g move_amount=%g curr_pos=%d new_pos=%d\n",
+//		page_width, move_amount, curr_pos, new_pos);
+	
+	set_h_offset(new_pos);
+}
+
+// amount is double value representing numPages.
+//  1.0 is a full page down
+// -1.0 is a full page up
+void View::nav_move_vert(double numPages)
+{
+	double page_height = viewport_->height();
+	double move_amount = numPages * page_height;
+	int curr_pos = scrollarea_->verticalScrollBar()->sliderPosition();
+	int new_pos = curr_pos + move_amount;
+ 
+//	printf("nav_move_vert(): page_height=%g move_amount=%g curr_pos=%d new_pos=%d\n",
+//		page_height, move_amount, curr_pos, new_pos);
+	
+	set_v_offset(new_pos);
+}
+
+NAV_KB_FUNC_DEFINE(up)
+NAV_KB_FUNC_DEFINE(down)
+NAV_KB_FUNC_DEFINE(left)
+NAV_KB_FUNC_DEFINE(right)
+NAV_KB_FUNC_DEFINE(pageup)
+NAV_KB_FUNC_DEFINE(pagedown)
+
+NAV_MW_FUNC_DEFINE(hori)
+NAV_MW_FUNC_DEFINE(vert)
+
+void View::on_mw_vert_all(QWheelEvent *event)
+{
+	if (event->modifiers() & Qt::AltModifier)			on_mw_vert_alt(event);
+	else if (event->modifiers() & Qt::ControlModifier)	on_mw_vert_ctrl(event);
+	else if (event->modifiers() & Qt::ShiftModifier)	on_mw_vert_shift(event);
+	else												on_mw_vert(event);
+}
+
+void View::on_mw_hori_all(QWheelEvent *event)
+{
+	if (event->modifiers() & Qt::AltModifier)			on_mw_hori_alt(event);
+	else if (event->modifiers() & Qt::ControlModifier)	on_mw_hori_ctrl(event);
+	else if (event->modifiers() & Qt::ShiftModifier)	on_mw_hori_shift(event);
+	else												on_mw_hori(event);
+}
+
 void View::h_scroll_value_changed(int value)
 {
 	if (updating_scroll_)
diff --git a/pv/views/trace/view.hpp b/pv/views/trace/view.hpp
index f8506cf4..d3c02c0d 100644
--- a/pv/views/trace/view.hpp
+++ b/pv/views/trace/view.hpp
@@ -80,6 +80,192 @@ class CustomScrollArea : public QAbstractScrollArea
 	bool viewportEvent(QEvent *event);
 };
 
+// This Navigation code handles customisation of keyboard and mousewheel controls
+// for navigating the traces by moving them and zooming them.
+// 
+// There are 5 sets of keys/mousewheels usable for customisation:
+//   up/down, left/right, pageup/pagedown,
+//   horizontal mousewheel and vertical mousewheel.
+// There are 3 modifier keys that can be used with the above, as well as using
+// no modifier. These are:
+//   none, alt, ctrl, shift.
+// Together the main and modifiers provide 5 * 4 = 20 different navigation controls
+// for customisation.
+// 
+// There are 4 types of navigation that the above can be assigned to do:
+//   none = no operation performed (same as disabling the operation)
+//   zoom = zoom in/out of the trace view
+//   hori = move the trace horizontally to see previous or next sample data
+//   vert = move the trace vertically to see channels above or below
+// 
+// There is an "amount" variable of type "double" to be used with navigation.
+// When moving traces horizontally or vertically the "amount" value is equal to
+// the number of pages to move. So a value of 1.0 would move 1 page forward.
+// A value of -0.5 would move half a page backwards.
+// When zooming into traces the "amount" value is equal to the zoom multiplier.
+// So a value of 1.0 will zoom out by 1x and a value of -2.0 will zoom in by 2x.
+// 
+// A "Navigation" page has been added to the Settings to allow the user to
+// customise the navigation controls to their liking.
+
+// type of navigation to perform
+#define NAV_TYPE_NONE		0
+#define NAV_TYPE_ZOOM		1
+#define NAV_TYPE_HORI		2
+#define NAV_TYPE_VERT		3
+
+// navigation using keyboard
+typedef struct {
+	int type;			// NAV_TYPE_??? value
+	double amount;		// amount to perform nav operation by
+	QShortcut* sc;
+} NavKb_t;
+
+// navigation using mousewheel
+typedef struct {
+	int type;			// NAV_TYPE_??? value
+	double amount;		// amount to perform nav operation by
+} NavMw_t;
+
+// keyboard
+#define NAV_KB_VAR_DECLARE(name)	\
+	NavKb_t name ## _nav_, name ## _alt_nav_, name ## _ctrl_nav_, name ## _shift_nav_
+
+#define NAV_KB_VAR_SETUP(name, keys)			\
+	name ## _nav_.type			= NAV_TYPE_NONE;\
+	name ## _alt_nav_.type		= NAV_TYPE_NONE;\
+	name ## _ctrl_nav_.type		= NAV_TYPE_NONE;\
+	name ## _shift_nav_.type	= NAV_TYPE_NONE;\
+	name ## _nav_.amount		= 0;			\
+	name ## _alt_nav_.amount	= 0;			\
+	name ## _ctrl_nav_.amount	= 0;			\
+	name ## _shift_nav_.amount	= 0;			\
+	name ## _nav_.sc		= new QShortcut(QKeySequence(keys),				this, SLOT(on_kb_ ##name ()),			nullptr, Qt::WidgetWithChildrenShortcut);	\
+	name ## _alt_nav_.sc	= new QShortcut(QKeySequence(keys + Qt::ALT),	this, SLOT(on_kb_ ##name## _alt()),		nullptr, Qt::WidgetWithChildrenShortcut);	\
+	name ## _ctrl_nav_.sc	= new QShortcut(QKeySequence(keys + Qt::CTRL),	this, SLOT(on_kb_ ##name## _ctrl()),	nullptr, Qt::WidgetWithChildrenShortcut);	\
+	name ## _shift_nav_.sc	= new QShortcut(QKeySequence(keys + Qt::SHIFT),	this, SLOT(on_kb_ ##name## _shift()),	nullptr, Qt::WidgetWithChildrenShortcut)
+
+#define NAV_KB_FUNC_DECLARE1(name)	\
+	void on_kb_ ## name ()
+
+#define NAV_KB_FUNC_DECLARE(name)			\
+	NAV_KB_FUNC_DECLARE1(name);				\
+	NAV_KB_FUNC_DECLARE1(name ## _alt);		\
+	NAV_KB_FUNC_DECLARE1(name ## _ctrl);	\
+	NAV_KB_FUNC_DECLARE1(name ## _shift)
+
+#define NAV_KB_FUNC_DEFINE1(name)		\
+	void View::on_kb_ ## name ()	{	\
+		if (     name ## _nav_.type == NAV_TYPE_NONE )return;	\
+		else if (name ## _nav_.type == NAV_TYPE_ZOOM )nav_zoom(name ## _nav_.amount);		\
+		else if (name ## _nav_.type == NAV_TYPE_HORI )nav_move_hori(name ## _nav_.amount);	\
+		else if (name ## _nav_.type == NAV_TYPE_VERT )nav_move_vert(name ## _nav_.amount);	\
+	}
+
+#define NAV_KB_FUNC_DEFINE(name)		\
+	NAV_KB_FUNC_DEFINE1(name)			\
+	NAV_KB_FUNC_DEFINE1(name ## _alt)	\
+	NAV_KB_FUNC_DEFINE1(name ## _ctrl)	\
+	NAV_KB_FUNC_DEFINE1(name ## _shift)
+
+#define NAV_KB_SETTING_CHANGED1(name, k1, k2)	\
+	if (key == GlobalSettings::Key_Nav_ ## name ## Type) {	\
+		k1 ## _nav_.type = settings.value(GlobalSettings::Key_Nav_ ## name ## Type).toInt();	\
+		k2 ## _nav_.type = settings.value(GlobalSettings::Key_Nav_ ## name ## Type).toInt();	\
+	}	\
+	if (key == GlobalSettings::Key_Nav_ ## name ## Amount) {	\
+		k1 ## _nav_.amount = -settings.value(GlobalSettings::Key_Nav_ ## name ## Amount).toDouble();	\
+		k2 ## _nav_.amount =  settings.value(GlobalSettings::Key_Nav_ ## name ## Amount).toDouble();	\
+	}
+	
+#define NAV_KB_SETTING_CHANGED(name, k1, k2)		\
+	NAV_KB_SETTING_CHANGED1(name,			k1, k2)	\
+	NAV_KB_SETTING_CHANGED1(name ## Alt,	k1 ## _alt, k2 ## _alt)		\
+	NAV_KB_SETTING_CHANGED1(name ## Ctrl,	k1 ## _ctrl, k2 ## _ctrl)	\
+	NAV_KB_SETTING_CHANGED1(name ## Shift,	k1 ## _shift, k2 ## _shift)
+
+#define NAV_KB_SETTING_LOAD1(name,	k1, k2)	\
+	if (settings.contains(GlobalSettings::Key_Nav_ ## name ## Type)) {	\
+		k1 ## _nav_.type = settings.value(GlobalSettings::Key_Nav_ ## name ## Type).toInt();	\
+		k2 ## _nav_.type = settings.value(GlobalSettings::Key_Nav_ ## name ## Type).toInt();	\
+	}	\
+	if (settings.contains(GlobalSettings::Key_Nav_ ## name ## Amount)) {	\
+		k1 ## _nav_.amount = -settings.value(GlobalSettings::Key_Nav_ ## name ## Amount).toDouble();	\
+		k2 ## _nav_.amount =  settings.value(GlobalSettings::Key_Nav_ ## name ## Amount).toDouble();	\
+	}
+
+#define NAV_KB_SETTING_LOAD(name,	k1, k2)		\
+	NAV_KB_SETTING_LOAD1(name,			k1, k2)	\
+	NAV_KB_SETTING_LOAD1(name ## Alt,	k1 ## _alt, k2 ## _alt)		\
+	NAV_KB_SETTING_LOAD1(name ## Ctrl,	k1 ## _ctrl, k2 ## _ctrl)	\
+	NAV_KB_SETTING_LOAD1(name ## Shift,	k1 ## _shift, k2 ## _shift)
+
+// mousewheel
+#define NAV_MW_VAR_DECLARE(name)		\
+	NavMw_t name ## _nav_, name ## _alt_nav_, name ## _ctrl_nav_, name ## _shift_nav_
+
+#define NAV_MW_VAR_SETUP(name)			\
+	name ## _nav_.type			= NAV_TYPE_NONE;\
+	name ## _alt_nav_.type		= NAV_TYPE_NONE;\
+	name ## _ctrl_nav_.type		= NAV_TYPE_NONE;\
+	name ## _shift_nav_.type	= NAV_TYPE_NONE;\
+	name ## _nav_.amount		= 0;			\
+	name ## _alt_nav_.amount	= 0;			\
+	name ## _ctrl_nav_.amount	= 0;			\
+	name ## _shift_nav_.amount	= 0
+
+#define NAV_MW_FUNC_DECLARE1(name)	\
+	void on_mw_ ## name (QWheelEvent *event)
+
+#define NAV_MW_FUNC_DECLARE(name)			\
+	NAV_MW_FUNC_DECLARE1(name);				\
+	NAV_MW_FUNC_DECLARE1(name ## _alt);		\
+	NAV_MW_FUNC_DECLARE1(name ## _ctrl);	\
+	NAV_MW_FUNC_DECLARE1(name ## _shift)
+
+#define NAV_MW_FUNC_DEFINE1(name)		\
+	void View::on_mw_ ## name (QWheelEvent *event)	{	\
+		if (     name ## _nav_.type == NAV_TYPE_NONE )return;	\
+		else if (name ## _nav_.type == NAV_TYPE_ZOOM )nav_zoom(     (-event->delta() * name ## _nav_.amount)/120.0, event->x());	\
+		else if (name ## _nav_.type == NAV_TYPE_HORI )nav_move_hori((-event->delta() * name ## _nav_.amount)/120.0);	\
+		else if (name ## _nav_.type == NAV_TYPE_VERT )nav_move_vert((-event->delta() * name ## _nav_.amount)/120.0);	\
+	}
+
+#define NAV_MW_FUNC_DEFINE(name)		\
+	NAV_MW_FUNC_DEFINE1(name)			\
+	NAV_MW_FUNC_DEFINE1(name ## _alt)	\
+	NAV_MW_FUNC_DEFINE1(name ## _ctrl)	\
+	NAV_MW_FUNC_DEFINE1(name ## _shift)
+
+#define NAV_MW_SETTING_CHANGED1(name, mw)	\
+	if (key == GlobalSettings::Key_Nav_ ## name ## Type) {	\
+		mw ## _nav_.type = settings.value(GlobalSettings::Key_Nav_ ## name ## Type).toInt();	\
+	}	\
+	if (key == GlobalSettings::Key_Nav_ ## name ## Amount) {	\
+		mw ## _nav_.amount = settings.value(GlobalSettings::Key_Nav_ ## name ## Amount).toDouble();	\
+	}
+	
+#define NAV_MW_SETTING_CHANGED(name, mw)		\
+	NAV_MW_SETTING_CHANGED1(name,			mw)	\
+	NAV_MW_SETTING_CHANGED1(name ## Alt,	mw ## _alt)		\
+	NAV_MW_SETTING_CHANGED1(name ## Ctrl,	mw ## _ctrl)	\
+	NAV_MW_SETTING_CHANGED1(name ## Shift,	mw ## _shift)
+
+#define NAV_MW_SETTING_LOAD1(name,	mw)		\
+	if (settings.contains(GlobalSettings::Key_Nav_ ## name ## Type)) {	\
+		mw ## _nav_.type = settings.value(GlobalSettings::Key_Nav_ ## name ## Type).toInt();	\
+	}	\
+	if (settings.contains(GlobalSettings::Key_Nav_ ## name ## Amount)) {	\
+		mw ## _nav_.amount = settings.value(GlobalSettings::Key_Nav_ ## name ## Amount).toDouble();	\
+	}
+
+#define NAV_MW_SETTING_LOAD(name,	mw)		\
+	NAV_MW_SETTING_LOAD1(name,			mw)	\
+	NAV_MW_SETTING_LOAD1(name ## Alt,	mw ## _alt)		\
+	NAV_MW_SETTING_LOAD1(name ## Ctrl,	mw ## _ctrl)	\
+	NAV_MW_SETTING_LOAD1(name ## Shift,	mw ## _shift)
+
+
 class View : public ViewBase, public TraceTreeItemOwner, public GlobalSettingsInterface
 {
 	Q_OBJECT
@@ -429,6 +615,14 @@ public Q_SLOTS:
 
 	void extents_changed(bool horz, bool vert);
 
+	void nav_zoom(double amount);
+	void nav_zoom(double amount, int offset);
+	void nav_move_hori(double amount);
+	void nav_move_vert(double amount);
+	
+	void on_mw_vert_all(QWheelEvent *event);
+	void on_mw_hori_all(QWheelEvent *event);
+	
 private Q_SLOTS:
 	void on_signal_name_changed();
 	void on_splitter_moved();
@@ -446,6 +640,16 @@ private Q_SLOTS:
 	void signals_changed();
 	void capture_state_updated(int state);
 
+	// keyboard and mousewheel navigation functions
+	NAV_KB_FUNC_DECLARE(up);
+	NAV_KB_FUNC_DECLARE(down);
+	NAV_KB_FUNC_DECLARE(left);
+	NAV_KB_FUNC_DECLARE(right);
+	NAV_KB_FUNC_DECLARE(pageup);
+	NAV_KB_FUNC_DECLARE(pagedown);
+	NAV_MW_FUNC_DECLARE(hori);
+	NAV_MW_FUNC_DECLARE(vert);
+	
 	void on_new_segment(int new_segment_id);
 	void on_segment_completed(int new_segment_id);
 	void on_segment_changed(int segment);
@@ -504,12 +708,21 @@ private Q_SLOTS:
 	Header *header_;
 	QSplitter *splitter_;
 
-	QShortcut *zoom_in_shortcut_, *zoom_in_shortcut_2_;
-	QShortcut *zoom_out_shortcut_, *zoom_out_shortcut_2_;
+	QShortcut *zoom_in_shortcut_, *zoom_out_shortcut_;
 	QShortcut *home_shortcut_, *end_shortcut_;
 	QShortcut *grab_ruler_left_shortcut_, *grab_ruler_right_shortcut_;
 	QShortcut *cancel_grab_shortcut_;
-
+	
+	// keyboard and mousewheel navigation variables
+	NAV_KB_VAR_DECLARE(up);
+	NAV_KB_VAR_DECLARE(down);
+	NAV_KB_VAR_DECLARE(left);
+	NAV_KB_VAR_DECLARE(right);
+	NAV_KB_VAR_DECLARE(pageup);
+	NAV_KB_VAR_DECLARE(pagedown);
+	NAV_MW_VAR_DECLARE(hori);
+	NAV_MW_VAR_DECLARE(vert);
+	
 	mutable mutex signal_mutex_;
 	vector< shared_ptr > signals_;
 
diff --git a/pv/views/trace/viewport.cpp b/pv/views/trace/viewport.cpp
index 0c73ec49..7753dc60 100644
--- a/pv/views/trace/viewport.cpp
+++ b/pv/views/trace/viewport.cpp
@@ -212,19 +212,9 @@ void Viewport::wheelEvent(QWheelEvent *event)
 	assert(event);
 
 	if (event->orientation() == Qt::Vertical) {
-		if (event->modifiers() & Qt::ControlModifier) {
-			// Vertical scrolling with the control key pressed
-			// is intrepretted as vertical scrolling
-			view_.set_v_offset(-view_.owner_visual_v_offset() -
-				(event->delta() * height()) / (8 * 120));
-		} else {
-			// Vertical scrolling is interpreted as zooming in/out
-			view_.zoom(event->delta() / 120.0, event->x());
-		}
+		view_.on_mw_vert_all(event);
 	} else if (event->orientation() == Qt::Horizontal) {
-		// Horizontal scrolling is interpreted as moving left/right
-		view_.set_scale_offset(view_.scale(),
-			event->delta() * view_.scale() + view_.offset());
+		view_.on_mw_hori_all(event);
 	}
 }