Set a maximum value to zoom level

The minimal vamue is set to 10%, let's set the max to 1000%. This
avoids crashes when characters are too large.

The code is refactored to be more compact and the tests are more precise.

Fixes bug #12452.
This commit is contained in:
Jean-Marc Lasgouttes 2022-02-08 19:42:17 +01:00
parent 2e07736c17
commit 5259b6ba62
2 changed files with 39 additions and 42 deletions

View File

@ -643,8 +643,7 @@ GuiView::GuiView(int id)
zoom_ratio_ = settings.value("zoom_ratio", 1.0).toDouble(); zoom_ratio_ = settings.value("zoom_ratio", 1.0).toDouble();
// Actual zoom value: default zoom + fractional offset // Actual zoom value: default zoom + fractional offset
int zoom = (int)(lyxrc.defaultZoom * zoom_ratio_); int zoom = (int)(lyxrc.defaultZoom * zoom_ratio_);
if (zoom < static_cast<int>(zoom_min_)) zoom = min(max(zoom, zoom_min_), zoom_max_);
zoom = zoom_min_;
zoom_slider_->setValue(zoom); zoom_slider_->setValue(zoom);
zoom_slider_->setToolTip(qt_("Workarea zoom level. Drag, use Ctrl-+/- or Shift-Mousewheel to adjust.")); zoom_slider_->setToolTip(qt_("Workarea zoom level. Drag, use Ctrl-+/- or Shift-Mousewheel to adjust."));
@ -982,8 +981,7 @@ bool GuiView::restoreLayout()
zoom_ratio_ = settings.value("zoom_ratio", 1.0).toDouble(); zoom_ratio_ = settings.value("zoom_ratio", 1.0).toDouble();
// Actual zoom value: default zoom + fractional offset // Actual zoom value: default zoom + fractional offset
int zoom = (int)(lyxrc.defaultZoom * zoom_ratio_); int zoom = (int)(lyxrc.defaultZoom * zoom_ratio_);
if (zoom < static_cast<int>(zoom_min_)) zoom = min(max(zoom, zoom_min_), zoom_max_);
zoom = zoom_min_;
setCurrentZoom(zoom); setCurrentZoom(zoom);
devel_mode_ = settings.value("devel_mode", devel_mode_).toBool(); devel_mode_ = settings.value("devel_mode", devel_mode_).toBool();
settings.beginGroup("views"); settings.beginGroup("views");
@ -2100,6 +2098,30 @@ void GuiView::resetAutosaveTimers()
} }
namespace {
double zoomRatio(FuncRequest const & cmd, double const zr)
{
if (cmd.argument().empty()) {
if (cmd.action() == LFUN_BUFFER_ZOOM)
return 1.0;
else if (cmd.action() == LFUN_BUFFER_ZOOM_IN)
return zr + 0.1;
else // cmd.action() == LFUN_BUFFER_ZOOM_OUT
return zr - 0.1;
} else {
if (cmd.action() == LFUN_BUFFER_ZOOM)
return convert<int>(cmd.argument()) / double(lyxrc.defaultZoom);
else if (cmd.action() == LFUN_BUFFER_ZOOM_IN)
return zr + convert<int>(cmd.argument()) / 100.0;
else // cmd.action() == LFUN_BUFFER_ZOOM_OUT
return zr - convert<int>(cmd.argument()) / 100.0;
}
}
}
bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
{ {
bool enable = true; bool enable = true;
@ -2479,36 +2501,24 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
break; break;
case LFUN_BUFFER_ZOOM_OUT: case LFUN_BUFFER_ZOOM_OUT:
case LFUN_BUFFER_ZOOM_IN: { case LFUN_BUFFER_ZOOM_IN:
// only diff between these two is that the default for ZOOM_OUT case LFUN_BUFFER_ZOOM: {
// is a neg. number int const zoom = (int)(lyxrc.defaultZoom * zoomRatio(cmd, zoom_ratio_));
bool const neg_zoom = if (zoom < zoom_min_) {
convert<int>(cmd.argument()) < 0 ||
(cmd.action() == LFUN_BUFFER_ZOOM_OUT && cmd.argument().empty());
if (lyxrc.currentZoom <= zoom_min_ && neg_zoom) {
docstring const msg = docstring const msg =
bformat(_("Zoom level cannot be less than %1$d%."), zoom_min_); bformat(_("Zoom level cannot be less than %1$d%."), zoom_min_);
flag.message(msg); flag.message(msg);
enable = false; enable = false;
} else if (zoom > zoom_max_) {
docstring const msg =
bformat(_("Zoom level cannot be more than %1$d%."), zoom_max_);
flag.message(msg);
enable = false;
} else } else
enable = doc_buffer; enable = doc_buffer;
break; break;
} }
case LFUN_BUFFER_ZOOM: {
bool const less_than_min_zoom =
!cmd.argument().empty() && convert<int>(cmd.argument()) < zoom_min_;
if (lyxrc.currentZoom <= zoom_min_ && less_than_min_zoom) {
docstring const msg =
bformat(_("Zoom level cannot be less than %1$d%."), zoom_min_);
flag.message(msg);
enable = false;
} else if (cmd.argument().empty() && lyxrc.currentZoom == lyxrc.defaultZoom)
enable = false;
else
enable = doc_buffer;
break;
}
case LFUN_BUFFER_MOVE_NEXT: case LFUN_BUFFER_MOVE_NEXT:
case LFUN_BUFFER_MOVE_PREVIOUS: case LFUN_BUFFER_MOVE_PREVIOUS:
@ -4725,26 +4735,11 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
case LFUN_BUFFER_ZOOM_IN: case LFUN_BUFFER_ZOOM_IN:
case LFUN_BUFFER_ZOOM_OUT: case LFUN_BUFFER_ZOOM_OUT:
case LFUN_BUFFER_ZOOM: { case LFUN_BUFFER_ZOOM: {
if (cmd.argument().empty()) { zoom_ratio_ = zoomRatio(cmd, zoom_ratio_);
if (cmd.action() == LFUN_BUFFER_ZOOM)
zoom_ratio_ = 1.0;
else if (cmd.action() == LFUN_BUFFER_ZOOM_IN)
zoom_ratio_ += 0.1;
else
zoom_ratio_ -= 0.1;
} else {
if (cmd.action() == LFUN_BUFFER_ZOOM)
zoom_ratio_ = convert<int>(cmd.argument()) / double(lyxrc.defaultZoom);
else if (cmd.action() == LFUN_BUFFER_ZOOM_IN)
zoom_ratio_ += convert<int>(cmd.argument()) / 100.0;
else
zoom_ratio_ -= convert<int>(cmd.argument()) / 100.0;
}
// Actual zoom value: default zoom + fractional extra value // Actual zoom value: default zoom + fractional extra value
int zoom = (int)(lyxrc.defaultZoom * zoom_ratio_); int zoom = (int)(lyxrc.defaultZoom * zoom_ratio_);
if (zoom < static_cast<int>(zoom_min_)) zoom = min(max(zoom, zoom_min_), zoom_max_);
zoom = zoom_min_;
setCurrentZoom(zoom); setCurrentZoom(zoom);

View File

@ -520,6 +520,8 @@ private:
double zoom_ratio_ = 1.0; double zoom_ratio_ = 1.0;
/// Minimum zoom percentage /// Minimum zoom percentage
static int const zoom_min_ = 10; static int const zoom_min_ = 10;
/// Maximum zoom percentage
static int const zoom_max_ = 1000;
// movability flag of all toolbars // movability flag of all toolbars
bool toolbarsMovable_; bool toolbarsMovable_;