#include "GuiView.h"
+#include "DialogFactory.h"
#include "DispatchResult.h"
#include "FileDialog.h"
#include "FontLoader.h"
#include "GuiApplication.h"
#include "GuiClickableLabel.h"
-#include "GuiCommandBuffer.h"
#include "GuiCompleter.h"
+#include "GuiFontMetrics.h"
#include "GuiKeySymbol.h"
#include "GuiToc.h"
#include "GuiToolbar.h"
#include "Format.h"
#include "FuncStatus.h"
#include "FuncRequest.h"
-#include "Intl.h"
+#include "KeySymbol.h"
#include "Language.h"
-#include "Layout.h"
#include "LayoutFile.h"
#include "Lexer.h"
#include "LyXAction.h"
#include "SpellChecker.h"
#include "Session.h"
#include "TexRow.h"
-#include "TextClass.h"
#include "Text.h"
#include "Toolbars.h"
#include "version.h"
#include "support/debug.h"
#include "support/ExceptionMessage.h"
#include "support/FileName.h"
-#include "support/filetools.h"
#include "support/gettext.h"
-#include "support/filetools.h"
#include "support/ForkedCalls.h"
#include "support/lassert.h"
#include "support/lstrings.h"
#include <QAction>
#include <QApplication>
#include <QCloseEvent>
-#include <QDebug>
-#include <QDesktopWidget>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QFuture>
#include <QFutureWatcher>
+#include <QGroupBox>
#include <QLabel>
#include <QList>
#include <QMenu>
#include <QMenuBar>
#include <QMimeData>
-#include <QMovie>
#include <QPainter>
#include <QPixmap>
#include <QPoint>
-#include <QPushButton>
-#include <QScrollBar>
#include <QSettings>
#include <QShowEvent>
+#include <QSlider>
#include <QSplitter>
#include <QStackedWidget>
#include <QStatusBar>
#include <QSvgRenderer>
#include <QtConcurrentRun>
-#include <QTime>
#include <QTimer>
-#include <QToolBar>
#include <QUrl>
-
+#include <QWindowStateChangeEvent>
+#include <QGestureEvent>
+#include <QPinchGesture>
// sync with GuiAlert.cpp
// Check how long the logo gets with the current font
// and adapt if the font is running wider than what
// we assume
- QFontMetrics fm(font);
+ GuiFontMetrics fm(font);
// Split the title into lines to measure the longest line
// in the current l7n.
QStringList titlesegs = htext.split('\n');
int wline = 0;
- int hline = fm.height();
- QStringList::const_iterator sit;
- for (sit = titlesegs.constBegin(); sit != titlesegs.constEnd(); ++sit) {
- if (fm.width(*sit) > wline)
- wline = fm.width(*sit);
+ int hline = fm.maxHeight();
+ for (QString const & seg : titlesegs) {
+ if (fm.width(seg) > wline)
+ wline = fm.width(seg);
}
// The longest line in the reference font (for English)
// is 180. Calculate scale factor from that.
setFocusPolicy(Qt::StrongFocus);
}
- void paintEvent(QPaintEvent *)
+ void paintEvent(QPaintEvent *) override
{
int const w = width_;
int const h = height_;
pain.drawPixmap(x, y, w, h, splash_);
}
- void keyPressEvent(QKeyEvent * ev)
+ void keyPressEvent(QKeyEvent * ev) override
{
KeySymbol sym;
setKeySymbol(&sym, ev);
void operator=(GuiViewPrivate const &);
public:
GuiViewPrivate(GuiView * gv)
- : gv_(gv), current_work_area_(0), current_main_work_area_(0),
- layout_(0), autosave_timeout_(5000),
+ : gv_(gv), current_work_area_(nullptr), current_main_work_area_(nullptr),
+ layout_(nullptr), autosave_timeout_(5000),
in_show_(false)
{
// hardcode here the platform specific icon size
return icon_size;
}
+ static Buffer::ExportStatus previewAndDestroy(Buffer const * orig,
+ Buffer * buffer, string const & format);
+ static Buffer::ExportStatus exportAndDestroy(Buffer const * orig,
+ Buffer * buffer, string const & format);
+ static Buffer::ExportStatus compileAndDestroy(Buffer const * orig,
+ Buffer * buffer, string const & format);
+ static docstring autosaveAndDestroy(Buffer const * orig, Buffer * buffer);
+
+ template<class T>
+ static Buffer::ExportStatus runAndDestroy(const T& func,
+ Buffer const * orig, Buffer * buffer, string const & format);
+
+ // TODO syncFunc/previewFunc: use bind
+ bool asyncBufferProcessing(string const & argument,
+ Buffer const * used_buffer,
+ docstring const & msg,
+ Buffer::ExportStatus (*asyncFunc)(Buffer const *, Buffer *, string const &),
+ Buffer::ExportStatus (Buffer::*syncFunc)(string const &, bool) const,
+ Buffer::ExportStatus (Buffer::*previewFunc)(string const &) const,
+ bool allow_async, bool use_tmpdir = false);
+
+ QVector<GuiWorkArea*> guiWorkAreas();
+
public:
GuiView * gv_;
GuiWorkArea * current_work_area_;
///
map<string, DialogPtr> dialogs_;
- unsigned int smallIconSize;
- unsigned int normalIconSize;
- unsigned int bigIconSize;
- unsigned int hugeIconSize;
- unsigned int giantIconSize;
///
QTimer statusbar_timer_;
/// auto-saving of buffers
Timeout autosave_timeout_;
- /// flag against a race condition due to multiclicks, see bug #1119
- bool in_show_;
///
TocModels toc_models_;
string processing_format;
static QSet<Buffer const *> busyBuffers;
- static Buffer::ExportStatus previewAndDestroy(Buffer const * orig,
- Buffer * buffer, string const & format);
- static Buffer::ExportStatus exportAndDestroy(Buffer const * orig,
- Buffer * buffer, string const & format);
- static Buffer::ExportStatus compileAndDestroy(Buffer const * orig,
- Buffer * buffer, string const & format);
- static docstring autosaveAndDestroy(Buffer const * orig, Buffer * buffer);
- template<class T>
- static Buffer::ExportStatus runAndDestroy(const T& func,
- Buffer const * orig, Buffer * buffer, string const & format);
-
- // TODO syncFunc/previewFunc: use bind
- bool asyncBufferProcessing(string const & argument,
- Buffer const * used_buffer,
- docstring const & msg,
- Buffer::ExportStatus (*asyncFunc)(Buffer const *, Buffer *, string const &),
- Buffer::ExportStatus (Buffer::*syncFunc)(string const &, bool) const,
- Buffer::ExportStatus (Buffer::*previewFunc)(string const &) const,
- bool allow_async);
+ unsigned int smallIconSize;
+ unsigned int normalIconSize;
+ unsigned int bigIconSize;
+ unsigned int hugeIconSize;
+ unsigned int giantIconSize;
- QVector<GuiWorkArea*> guiWorkAreas();
+ /// flag against a race condition due to multiclicks, see bug #1119
+ bool in_show_;
};
QSet<Buffer const *> GuiView::GuiViewPrivate::busyBuffers;
// (such as "source" and "messages")
setDockOptions(QMainWindow::ForceTabbedDocks);
+#ifdef Q_OS_MAC
+ // use document mode tabs on docks
+ setDocumentMode(true);
+#endif
+
// For Drag&Drop.
setAcceptDrops(true);
// add busy indicator to statusbar
- GuiClickableLabel * busylabel = new GuiClickableLabel(statusBar());
- statusBar()->addPermanentWidget(busylabel);
search_mode mode = theGuiApp()->imageSearchMode();
- QString fn = toqstr(lyx::libFileSearch("images", "busy", "gif", mode).absFileName());
- QMovie * busyanim = new QMovie(fn, QByteArray(), busylabel);
- busylabel->setMovie(busyanim);
- busyanim->start();
- busylabel->hide();
+ QString fn = toqstr(lyx::libFileSearch("images", "busy", "svgz", mode).absFileName());
+ PressableSvgWidget * busySVG = new PressableSvgWidget(fn);
+ statusBar()->addPermanentWidget(busySVG);
+ // make busy indicator square with 5px margins
+ busySVG->setMaximumSize(busySVG->height() - 5, busySVG->height() - 5);
+ busySVG->hide();
connect(&d.processing_thread_watcher_, SIGNAL(started()),
- busylabel, SLOT(show()));
+ busySVG, SLOT(show()));
connect(&d.processing_thread_watcher_, SIGNAL(finished()),
- busylabel, SLOT(hide()));
- connect(busylabel, SIGNAL(clicked()), this, SLOT(checkCancelBackground()));
+ busySVG, SLOT(hide()));
+ connect(busySVG, SIGNAL(pressed()), this, SLOT(checkCancelBackground()));
QFontMetrics const fm(statusBar()->fontMetrics());
+
+ zoom_slider_ = new QSlider(Qt::Horizontal, statusBar());
+ // Small size slider for macOS to prevent the status bar from enlarging
+ zoom_slider_->setAttribute(Qt::WA_MacSmallSize);
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
+ zoom_slider_->setFixedWidth(fm.horizontalAdvance('x') * 15);
+#else
+ zoom_slider_->setFixedWidth(fm.width('x') * 15);
+#endif
+ // Make the defaultZoom center
+ zoom_slider_->setRange(10, (lyxrc.defaultZoom * 2) - 10);
+ // Initialize proper zoom value
+ QSettings settings;
+ zoom_ratio_ = settings.value("zoom_ratio", 1.0).toDouble();
+ // Actual zoom value: default zoom + fractional offset
+ int zoom = (int)(lyxrc.defaultZoom * zoom_ratio_);
+ if (zoom < static_cast<int>(zoom_min_))
+ zoom = zoom_min_;
+ zoom_slider_->setValue(zoom);
+ zoom_slider_->setToolTip(qt_("Workarea zoom level. Drag, use Ctrl-+/- or Shift-Mousewheel to adjust."));
+
+ // Buttons to change zoom stepwise
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
+ QSize s(fm.horizontalAdvance('+'), fm.height());
+#else
+ QSize s(fm.width('+'), fm.height());
+#endif
+ zoom_in_ = new GuiClickableLabel(statusBar());
+ zoom_in_->setText("+");
+ zoom_in_->setFixedSize(s);
+ zoom_in_->setAlignment(Qt::AlignCenter);
+ zoom_out_ = new GuiClickableLabel(statusBar());
+ zoom_out_->setText(QString(QChar(0x2212)));
+ zoom_out_->setFixedSize(s);
+ zoom_out_->setAlignment(Qt::AlignCenter);
+
+ statusBar()->addPermanentWidget(zoom_out_);
+ zoom_out_->setEnabled(currentBufferView());
+ statusBar()->addPermanentWidget(zoom_slider_);
+ zoom_slider_->setEnabled(currentBufferView());
+ zoom_in_->setEnabled(currentBufferView());
+ statusBar()->addPermanentWidget(zoom_in_);
+
+ connect(zoom_slider_, SIGNAL(sliderMoved(int)), this, SLOT(zoomSliderMoved(int)));
+ connect(zoom_slider_, SIGNAL(valueChanged(int)), this, SLOT(zoomValueChanged(int)));
+ connect(this, SIGNAL(currentZoomChanged(int)), zoom_slider_, SLOT(setValue(int)));
+ connect(zoom_in_, SIGNAL(clicked()), this, SLOT(zoomInPressed()));
+ connect(zoom_out_, SIGNAL(clicked()), this, SLOT(zoomOutPressed()));
+
+ // QPalette palette = statusBar()->palette();
+
+ zoom_value_ = new QLabel(statusBar());
+ // zoom_value_->setPalette(palette);
+ zoom_value_->setForegroundRole(statusBar()->foregroundRole());
+ zoom_value_->setFixedHeight(fm.height());
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
+ zoom_value_->setMinimumWidth(fm.horizontalAdvance("444\%"));
+#else
+ zoom_value_->setMinimumWidth(fm.width("444\%"));
+#endif
+ zoom_value_->setAlignment(Qt::AlignCenter);
+ zoom_value_->setText(toqstr(bformat(_("[[ZOOM]]%1$d%"), zoom)));
+ statusBar()->addPermanentWidget(zoom_value_);
+ zoom_value_->setEnabled(currentBufferView());
+
+ statusBar()->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(statusBar(), SIGNAL(customContextMenuRequested(QPoint)),
+ this, SLOT(showZoomContextMenu()));
+
+ // enable pinch to zoom
+ grabGesture(Qt::PinchGesture);
+
int const iconheight = max(int(d.normalIconSize), fm.height());
QSize const iconsize(iconheight, iconheight);
QPixmap shellescape = QIcon(getPixmap("images/", "emblem-shellescape", "svgz,png")).pixmap(iconsize);
shell_escape_ = new QLabel(statusBar());
shell_escape_->setPixmap(shellescape);
- shell_escape_->setScaledContents(true);
shell_escape_->setAlignment(Qt::AlignCenter);
shell_escape_->setContextMenuPolicy(Qt::CustomContextMenu);
shell_escape_->setToolTip(qt_("WARNING: LaTeX is allowed to execute "
QPixmap readonly = QIcon(getPixmap("images/", "emblem-readonly", "svgz,png")).pixmap(iconsize);
read_only_ = new QLabel(statusBar());
read_only_->setPixmap(readonly);
- read_only_->setScaledContents(true);
read_only_->setAlignment(Qt::AlignCenter);
read_only_->hide();
statusBar()->addPermanentWidget(read_only_);
initToolbars();
// clear session data if any.
- QSettings settings;
settings.remove("views");
}
}
+void GuiView::zoomSliderMoved(int value)
+{
+ DispatchResult dr;
+ dispatch(FuncRequest(LFUN_BUFFER_ZOOM, convert<string>(value)), dr);
+ scheduleRedrawWorkAreas();
+ zoom_value_->setText(toqstr(bformat(_("[[ZOOM]]%1$d%"), value)));
+}
+
+
+void GuiView::zoomValueChanged(int value)
+{
+ if (value != lyxrc.currentZoom)
+ zoomSliderMoved(value);
+}
+
+
+void GuiView::zoomInPressed()
+{
+ DispatchResult dr;
+ dispatch(FuncRequest(LFUN_BUFFER_ZOOM_IN), dr);
+ scheduleRedrawWorkAreas();
+}
+
+
+void GuiView::zoomOutPressed()
+{
+ DispatchResult dr;
+ dispatch(FuncRequest(LFUN_BUFFER_ZOOM_OUT), dr);
+ scheduleRedrawWorkAreas();
+}
+
+
+void GuiView::showZoomContextMenu()
+{
+ QMenu * menu = guiApp->menus().menu(toqstr("context-statusbar"), * this);
+ if (!menu)
+ return;
+ menu->exec(QCursor::pos());
+}
+
+
+void GuiView::scheduleRedrawWorkAreas()
+{
+ for (int i = 0; i < d.tabWorkAreaCount(); i++) {
+ TabWorkArea* ta = d.tabWorkArea(i);
+ for (int u = 0; u < ta->count(); u++) {
+ ta->workArea(u)->scheduleRedraw(true);
+ }
+ }
+}
+
+
QVector<GuiWorkArea*> GuiView::GuiViewPrivate::guiWorkAreas()
{
QVector<GuiWorkArea*> areas;
static void handleExportStatus(GuiView * view, Buffer::ExportStatus status,
string const & format)
{
- docstring const fmt = theFormats().prettyName(format);
+ docstring const fmt = translateIfPossible(theFormats().prettyName(format));
docstring msg;
switch (status) {
case Buffer::ExportSuccess:
settings.setValue("devel_mode", devel_mode_);
settings.beginGroup("views");
settings.beginGroup(QString::number(id_));
-#if defined(Q_WS_X11) || defined(QPA_XCB)
- settings.setValue("pos", pos());
- settings.setValue("size", size());
-#else
- settings.setValue("geometry", saveGeometry());
-#endif
+ if (guiApp->platformName() == "qt4x11" || guiApp->platformName() == "xcb") {
+ settings.setValue("pos", pos());
+ settings.setValue("size", size());
+ } else
+ settings.setValue("geometry", saveGeometry());
settings.setValue("layout", saveState(0));
settings.setValue("icon_size", toqstr(d.iconSize(iconSize())));
+ settings.setValue("zoom_value_visible", zoom_value_->isVisible());
+ settings.setValue("zoom_slider_visible", zoom_slider_->isVisible());
}
QSettings settings;
// Save the toolbar private states
- ToolbarMap::iterator end = d.toolbars_.end();
- for (ToolbarMap::iterator it = d.toolbars_.begin(); it != end; ++it)
- it->second->saveSession(settings);
+ for (auto const & tb_p : d.toolbars_)
+ tb_p.second->saveSession(settings);
// Now take care of all other dialogs
- map<string, DialogPtr>::const_iterator it = d.dialogs_.begin();
- for (; it!= d.dialogs_.end(); ++it)
- it->second->saveSession(settings);
+ for (auto const & dlg_p : d.dialogs_)
+ dlg_p.second->saveSession(settings);
+}
+
+
+void GuiView::setCurrentZoom(const int v)
+{
+ lyxrc.currentZoom = v;
+ zoom_value_->setText(toqstr(bformat(_("[[ZOOM]]%1$d%"), v)));
+ Q_EMIT currentZoomChanged(v);
}
QSettings settings;
zoom_ratio_ = settings.value("zoom_ratio", 1.0).toDouble();
// Actual zoom value: default zoom + fractional offset
- int zoom = lyxrc.defaultZoom * zoom_ratio_;
+ int zoom = (int)(lyxrc.defaultZoom * zoom_ratio_);
if (zoom < static_cast<int>(zoom_min_))
zoom = zoom_min_;
- lyxrc.currentZoom = zoom;
+ setCurrentZoom(zoom);
devel_mode_ = settings.value("devel_mode", devel_mode_).toBool();
settings.beginGroup("views");
settings.beginGroup(QString::number(id_));
//code below is skipped when when ~/.config/LyX is (re)created
setIconSize(d.iconSize(settings.value(icon_key).toString()));
-#if defined(Q_WS_X11) || defined(QPA_XCB)
- QPoint pos = settings.value("pos", QPoint(50, 50)).toPoint();
- QSize size = settings.value("size", QSize(690, 510)).toSize();
- resize(size);
- move(pos);
-#else
- // Work-around for bug #6034: the window ends up in an undetermined
- // state when trying to restore a maximized window when it is
- // already maximized.
- if (!(windowState() & Qt::WindowMaximized))
- if (!restoreGeometry(settings.value("geometry").toByteArray()))
- setGeometry(50, 50, 690, 510);
-#endif
+ zoom_value_->setVisible(settings.value("zoom_value_visible", true).toBool());
+
+ bool const show_zoom_slider = settings.value("zoom_slider_visible", true).toBool();
+ zoom_slider_->setVisible(show_zoom_slider);
+ zoom_in_->setVisible(show_zoom_slider);
+ zoom_out_->setVisible(show_zoom_slider);
+
+ if (guiApp->platformName() == "qt4x11" || guiApp->platformName() == "xcb") {
+ QPoint pos = settings.value("pos", QPoint(50, 50)).toPoint();
+ QSize size = settings.value("size", QSize(690, 510)).toSize();
+ resize(size);
+ move(pos);
+ } else {
+ // Work-around for bug #6034: the window ends up in an undetermined
+ // state when trying to restore a maximized window when it is
+ // already maximized.
+ if (!(windowState() & Qt::WindowMaximized))
+ if (!restoreGeometry(settings.value("geometry").toByteArray()))
+ setGeometry(50, 50, 690, 510);
+ }
+
// Make sure layout is correctly oriented.
setLayoutDirection(qApp->layoutDirection());
initToolbars();
// init the toolbars that have not been restored
- Toolbars::Infos::iterator cit = guiApp->toolbars().begin();
- Toolbars::Infos::iterator end = guiApp->toolbars().end();
- for (; cit != end; ++cit) {
- GuiToolbar * tb = toolbar(cit->name);
+ for (auto const & tb_p : guiApp->toolbars()) {
+ GuiToolbar * tb = toolbar(tb_p.name);
if (tb && !tb->isRestored())
- initToolbar(cit->name);
+ initToolbar(tb_p.name);
}
// update lock (all) toolbars positions
return it->second;
LYXERR(Debug::GUI, "Toolbar::display: no toolbar named " << name);
- return 0;
+ return nullptr;
}
if (tb && tb->isMovable())
toolbarsMovable_ = true;
}
+#if QT_VERSION >= 0x050200
+ // set unified mac toolbars only when not movable as recommended:
+ // https://doc.qt.io/qt-5/qmainwindow.html#unifiedTitleAndToolBarOnMac-prop
+ setUnifiedTitleAndToolBarOnMac(!toolbarsMovable_);
+#endif
}
void GuiView::constructToolbars()
{
- ToolbarMap::iterator it = d.toolbars_.begin();
- for (; it != d.toolbars_.end(); ++it)
- delete it->second;
+ for (auto const & tb_p : d.toolbars_)
+ delete tb_p.second;
d.toolbars_.clear();
// I don't like doing this here, but the standard toolbar
d.layout_->move(0,0);
// extracts the toolbars from the backend
- Toolbars::Infos::iterator cit = guiApp->toolbars().begin();
- Toolbars::Infos::iterator end = guiApp->toolbars().end();
- for (; cit != end; ++cit)
- d.toolbars_[cit->name] = new GuiToolbar(*cit, *this);
+ for (ToolbarInfo const & inf : guiApp->toolbars())
+ d.toolbars_[inf.name] = new GuiToolbar(inf, *this);
+
+ DynamicMenuButton::resetIconCache();
}
void GuiView::initToolbars()
{
// extracts the toolbars from the backend
- Toolbars::Infos::iterator cit = guiApp->toolbars().begin();
- Toolbars::Infos::iterator end = guiApp->toolbars().end();
- for (; cit != end; ++cit)
- initToolbar(cit->name);
+ for (ToolbarInfo const & inf : guiApp->toolbars())
+ initToolbar(inf.name);
}
// We cannot use a for loop as the buffer list cycles.
Buffer * b = first;
do {
- if (!saveBufferIfNeeded(const_cast<Buffer &>(*b), false))
+ if (!saveBufferIfNeeded(*b, false))
return false;
b = theBufferList().next(b);
} while (b != first);
vector<const Format *> found_formats;
// Find all formats that have the correct extension.
- vector<const Format *> const & import_formats
- = theConverters().importableFormats();
- vector<const Format *>::const_iterator it = import_formats.begin();
- for (; it != import_formats.end(); ++it)
- if ((*it)->hasExtension(ext))
- found_formats.push_back(*it);
+ for (const Format * fmt : theConverters().importableFormats())
+ if (fmt->hasExtension(ext))
+ found_formats.push_back(fmt);
FuncRequest cmd;
- if (found_formats.size() >= 1) {
+ if (!found_formats.empty()) {
if (found_formats.size() > 1) {
//FIXME: show a dialog to choose the correct importable format
LYXERR(Debug::FILES,
{
if (d.current_work_area_)
// disconnect the current work area from all slots
- QObject::disconnect(d.current_work_area_, 0, this, 0);
+ QObject::disconnect(d.current_work_area_, nullptr, this, nullptr);
disconnectBuffer();
disconnectBufferView();
connectBufferView(wa->bufferView());
// Buffer-dependent dialogs must be updated. This is done here because
// some dialogs require buffer()->text.
updateDialogs();
+ zoom_slider_->setEnabled(currentBufferView());
+ zoom_value_->setEnabled(currentBufferView());
+ zoom_in_->setEnabled(currentBufferView());
+ zoom_out_->setEnabled(currentBufferView());
}
//case QEvent::Drop:
// break;
+ case QEvent::WindowStateChange: {
+ QWindowStateChangeEvent * ev = (QWindowStateChangeEvent*)e;
+ bool ofstate = (ev->oldState() & Qt::WindowFullScreen);
+ bool result = QMainWindow::event(e);
+ bool nfstate = (windowState() & Qt::WindowFullScreen);
+ if (!ofstate && nfstate) {
+ LYXERR(Debug::DEBUG, "GuiView: WindowStateChange(): full-screen " << nfstate);
+ // switch to full-screen state
+ if (lyxrc.full_screen_statusbar)
+ statusBar()->hide();
+ if (lyxrc.full_screen_menubar)
+ menuBar()->hide();
+ if (lyxrc.full_screen_toolbars) {
+ for (auto const & tb_p : d.toolbars_)
+ if (tb_p.second->isVisibilityOn() && tb_p.second->isVisible())
+ tb_p.second->hide();
+ }
+ for (int i = 0; i != d.splitter_->count(); ++i)
+ d.tabWorkArea(i)->setFullScreen(true);
+#if QT_VERSION > 0x050903
+ //Qt's 5.9.4 ba44cdae38406c safe area measures won't allow us to go negative in margins
+ setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea, false);
+#endif
+ setContentsMargins(-2, -2, -2, -2);
+ // bug 5274
+ hideDialogs("prefs", nullptr);
+ } else if (ofstate && !nfstate) {
+ LYXERR(Debug::DEBUG, "GuiView: WindowStateChange(): full-screen " << nfstate);
+ // switch back from full-screen state
+ if (lyxrc.full_screen_statusbar && !statusBar()->isVisible())
+ statusBar()->show();
+ if (lyxrc.full_screen_menubar && !menuBar()->isVisible())
+ menuBar()->show();
+ if (lyxrc.full_screen_toolbars) {
+ for (auto const & tb_p : d.toolbars_)
+ if (tb_p.second->isVisibilityOn() && !tb_p.second->isVisible())
+ tb_p.second->show();
+ //updateToolbars();
+ }
+ for (int i = 0; i != d.splitter_->count(); ++i)
+ d.tabWorkArea(i)->setFullScreen(false);
+#if QT_VERSION > 0x050903
+ setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea, true);
+#endif
+ setContentsMargins(0, 0, 0, 0);
+ }
+ return result;
+ }
+
case QEvent::WindowActivate: {
GuiView * old_view = guiApp->currentView();
if (this == old_view) {
return QMainWindow::event(e);
}
+ case QEvent::ApplicationPaletteChange: {
+ // runtime switch from/to dark mode
+ refillToolbars();
+ return QMainWindow::event(e);
+ }
+
+ case QEvent::Gesture: {
+ QGestureEvent *ge = static_cast<QGestureEvent*>(e);
+ QGesture *gp = ge->gesture(Qt::PinchGesture);
+ if (gp) {
+ QPinchGesture *pinch = static_cast<QPinchGesture *>(gp);
+ QPinchGesture::ChangeFlags changeFlags = pinch->changeFlags();
+ if (changeFlags & QPinchGesture::ScaleFactorChanged) {
+ qreal factor = lyxrc.currentZoom*pinch->scaleFactor();
+ //factor = ceil(factor/20)*20;
+ zoomValueChanged(factor);
+ }
+ }
+ return QMainWindow::event(e);
+ }
+
default:
return QMainWindow::event(e);
}
if (TabWorkArea * twa = d.currentTabWorkArea())
if (index < twa->count())
return twa->workArea(index);
- return 0;
+ return nullptr;
}
return currentWorkArea();
if (TabWorkArea * twa = d.currentTabWorkArea())
return twa->workArea(buffer);
- return 0;
+ return nullptr;
}
GuiWorkArea const * GuiView::currentMainWorkArea() const
{
if (!d.currentTabWorkArea())
- return 0;
+ return nullptr;
return d.currentTabWorkArea()->currentWorkArea();
}
GuiWorkArea * GuiView::currentMainWorkArea()
{
if (!d.currentTabWorkArea())
- return 0;
+ return nullptr;
return d.currentTabWorkArea()->currentWorkArea();
}
{
LYXERR(Debug::DEBUG, "Setting current wa: " << wa << endl);
if (!wa) {
- d.current_work_area_ = 0;
+ d.current_work_area_ = nullptr;
d.setBackground();
Q_EMIT bufferViewChanged();
return;
if (wa == d.current_work_area_) {
disconnectBuffer();
disconnectBufferView();
- d.current_work_area_ = 0;
- d.current_main_work_area_ = 0;
+ d.current_work_area_ = nullptr;
+ d.current_main_work_area_ = nullptr;
}
bool found_twa = false;
// Found in this tab group, and deleted the GuiWorkArea.
found_twa = true;
if (twa->count() != 0) {
- if (d.current_work_area_ == 0)
+ if (d.current_work_area_ == nullptr)
// This means that we are closing the current GuiWorkArea, so
// switch to the next GuiWorkArea in the found TabWorkArea.
setCurrentWorkArea(twa->currentWorkArea());
// should be deleted by other means.
LASSERT(found_twa, return);
- if (d.current_work_area_ == 0) {
+ if (d.current_work_area_ == nullptr) {
if (d.splitter_->count() != 0) {
TabWorkArea * twa = d.currentTabWorkArea();
setCurrentWorkArea(twa->currentWorkArea());
} else {
// No more work areas, switch to the background widget.
- setCurrentWorkArea(0);
+ setCurrentWorkArea(nullptr);
}
}
}
void GuiView::updateToolbars()
{
- ToolbarMap::iterator end = d.toolbars_.end();
if (d.current_work_area_) {
int context = 0;
if (d.current_work_area_->bufferView().cursor().inMathed()
minibuffer_focus_ = false;
}
- for (ToolbarMap::iterator it = d.toolbars_.begin(); it != end; ++it)
- it->second->update(context);
+ for (auto const & tb_p : d.toolbars_)
+ tb_p.second->update(context);
} else
- for (ToolbarMap::iterator it = d.toolbars_.begin(); it != end; ++it)
- it->second->update();
+ for (auto const & tb_p : d.toolbars_)
+ tb_p.second->update();
+}
+
+
+void GuiView::refillToolbars()
+{
+ DynamicMenuButton::resetIconCache();
+ for (auto const & tb_p : d.toolbars_)
+ tb_p.second->refill();
}
LASSERT(newBuffer, return);
GuiWorkArea * wa = workArea(*newBuffer);
- if (wa == 0) {
+ if (wa == nullptr) {
setBusy(true);
newBuffer->masterBuffer()->updateBuffer();
setBusy(false);
void GuiView::disconnectBuffer()
{
if (d.current_work_area_)
- d.current_work_area_->bufferView().buffer().setGuiDelegate(0);
+ d.current_work_area_->bufferView().buffer().setGuiDelegate(nullptr);
}
void GuiView::disconnectBufferView()
{
if (d.current_work_area_)
- d.current_work_area_->bufferView().setGuiDelegate(0);
+ d.current_work_area_->bufferView().setGuiDelegate(nullptr);
}
{
return currentMainWorkArea()
? ¤tMainWorkArea()->bufferView()
- : 0;
+ : nullptr;
}
{
return currentMainWorkArea()
? ¤tMainWorkArea()->bufferView()
- : 0;
+ : nullptr;
}
BufferView * GuiView::currentBufferView()
{
- return d.current_work_area_ ? &d.current_work_area_->bufferView() : 0;
+ return d.current_work_area_ ? &d.current_work_area_->bufferView() : nullptr;
}
BufferView const * GuiView::currentBufferView() const
{
- return d.current_work_area_ ? &d.current_work_area_->bufferView() : 0;
+ return d.current_work_area_ ? &d.current_work_area_->bufferView() : nullptr;
}
LYXERR(Debug::INFO, "Running autoSave()");
Buffer * buffer = documentBufferView()
- ? &documentBufferView()->buffer() : 0;
+ ? &documentBufferView()->buffer() : nullptr;
if (!buffer) {
resetAutosaveTimers();
return;
{
bool enable = true;
Buffer * buf = currentBufferView()
- ? ¤tBufferView()->buffer() : 0;
+ ? ¤tBufferView()->buffer() : nullptr;
Buffer * doc_buffer = documentBufferView()
- ? &(documentBufferView()->buffer()) : 0;
+ ? &(documentBufferView()->buffer()) : nullptr;
#ifdef Q_OS_MAC
/* In LyX/Mac, when a dialog is open, the menus of the
case LFUN_MASTER_BUFFER_EXPORT:
enable = doc_buffer
- && (doc_buffer->parent() != 0
+ && (doc_buffer->parent() != nullptr
|| doc_buffer->hasChildren())
&& !d.processing_thread_watcher_.isRunning()
// this launches a dialog, which would be in the wrong Buffer
case LFUN_MASTER_BUFFER_UPDATE:
case LFUN_MASTER_BUFFER_VIEW:
enable = doc_buffer
- && (doc_buffer->parent() != 0
+ && (doc_buffer->parent() != nullptr
|| doc_buffer->hasChildren())
&& !d.processing_thread_watcher_.isRunning();
break;
&& (!doc_buffer->isClean() || doc_buffer->notifiesExternalModification());
break;
+ case LFUN_BUFFER_RESET_EXPORT:
+ enable = doc_buffer != nullptr;
+ break;
+
case LFUN_BUFFER_CHILD_OPEN:
- enable = doc_buffer != 0;
+ enable = doc_buffer != nullptr;
+ break;
+
+ case LFUN_MASTER_BUFFER_FORALL: {
+ if (doc_buffer == nullptr) {
+ flag.message(from_utf8(N_("Command not allowed without a buffer open")));
+ enable = false;
+ break;
+ }
+ FuncRequest const cmdToPass = lyxaction.lookupFunc(cmd.getLongArg(0));
+ if (cmdToPass.action() == LFUN_UNKNOWN_ACTION) {
+ flag.message(from_utf8(N_("Invalid argument of master-buffer-forall")));
+ enable = false;
+ break;
+ }
+ enable = false;
+ for (Buffer * buf : doc_buffer->allRelatives()) {
+ GuiWorkArea * wa = workArea(*buf);
+ if (!wa)
+ continue;
+ if (wa->bufferView().getStatus(cmdToPass, flag)) {
+ enable = flag.enabled();
+ break;
+ }
+ }
break;
+ }
case LFUN_BUFFER_WRITE:
- enable = doc_buffer && (doc_buffer->isUnnamed() || !doc_buffer->isClean());
+ enable = doc_buffer && (doc_buffer->isUnnamed()
+ || (!doc_buffer->isClean()
+ || cmd.argument() == "force"));
break;
//FIXME: This LFUN should be moved to GuiApplication.
break;
}
return doc_buffer->getStatus(cmd, flag);
- break;
}
case LFUN_BUFFER_EXPORT_AS:
// fall through
case LFUN_BUFFER_WRITE_AS:
case LFUN_BUFFER_WRITE_AS_TEMPLATE:
- enable = doc_buffer != 0;
+ enable = doc_buffer != nullptr;
break;
case LFUN_EXPORT_CANCEL:
case LFUN_BUFFER_CLOSE:
case LFUN_VIEW_CLOSE:
- enable = doc_buffer != 0;
+ enable = doc_buffer != nullptr;
break;
case LFUN_BUFFER_CLOSE_ALL:
flag.setOnOff(devel_mode_);
break;
+ case LFUN_TOOLBAR_SET: {
+ string const name = cmd.getArg(0);
+ string const state = cmd.getArg(1);
+ if (name.empty() || state.empty()) {
+ enable = false;
+ docstring const msg =
+ _("Function toolbar-set requires two arguments!");
+ flag.message(msg);
+ break;
+ }
+ if (state != "on" && state != "off" && state != "auto") {
+ enable = false;
+ docstring const msg =
+ bformat(_("Invalid argument \"%1$s\" to function toolbar-set!"),
+ from_utf8(state));
+ flag.message(msg);
+ break;
+ }
+ if (GuiToolbar * t = toolbar(name)) {
+ bool const autovis = t->visibility() & Toolbars::AUTO;
+ if (state == "on")
+ flag.setOnOff(t->isVisible() && !autovis);
+ else if (state == "off")
+ flag.setOnOff(!t->isVisible() && !autovis);
+ else if (state == "auto")
+ flag.setOnOff(autovis);
+ } else {
+ enable = false;
+ docstring const msg =
+ bformat(_("Unknown toolbar \"%1$s\""), from_utf8(name));
+ flag.message(msg);
+ }
+ break;
+ }
+
case LFUN_TOOLBAR_TOGGLE: {
string const name = cmd.getArg(0);
if (GuiToolbar * t = toolbar(name))
break;
case LFUN_DROP_LAYOUTS_CHOICE:
- enable = buf != 0;
+ enable = buf != nullptr;
break;
case LFUN_UI_TOGGLE:
- flag.setOnOff(isFullScreen());
+ if (cmd.argument() == "zoom") {
+ flag.setOnOff(zoom_value_ ? zoom_value_->isVisible() : false);
+ } else if (cmd.argument() == "zoomslider") {
+ flag.setOnOff(zoom_slider_ ? zoom_slider_->isVisible() : false);
+ } else
+ flag.setOnOff(isFullScreen());
break;
case LFUN_DIALOG_DISCONNECT_INSET:
enable = FileName(doc_buffer->logName()).isReadableFile();
else if (name == "spellchecker")
enable = theSpellChecker()
- && !doc_buffer->isReadonly()
&& !doc_buffer->text().empty();
else if (name == "vclog")
enable = doc_buffer->lyxvc().inUse();
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_SERVER_GOTO_FILE_ROW:
case LFUN_LYX_ACTIVATE:
+ case LFUN_WINDOW_RAISE:
break;
case LFUN_FORWARD_SEARCH:
enable = !(lyxrc.forward_search_dvi.empty() && lyxrc.forward_search_pdf.empty());
flag.setOnOff(lyxrc.spellcheck_continuously);
break;
+ case LFUN_CITATION_OPEN:
+ enable = true;
+ break;
+
default:
return false;
}
{
setBusy(true);
- Buffer * newBuffer = 0;
+ Buffer * newBuffer = nullptr;
try {
newBuffer = checkAndLoadLyXFile(filename);
- } catch (ExceptionMessage const & e) {
+ } catch (ExceptionMessage const &) {
setBusy(false);
- throw(e);
+ throw;
}
setBusy(false);
if (!newBuffer) {
message(_("Document not loaded."));
- return 0;
+ return nullptr;
}
setBuffer(newBuffer);
dlg.setButton1(qt_("D&ocuments"), toqstr(lyxrc.document_path));
dlg.setButton2(qt_("&Examples"), toqstr(lyxrc.example_path));
- QStringList const filter(qt_("LyX Documents (*.lyx)"));
+ QStringList const filter({
+ qt_("LyX Documents (*.lyx)"),
+ qt_("LyX Document Backups (*.lyx~)"),
+ qt_("All Files (*.*)")
+ });
FileDialog::Result result =
dlg.open(toqstr(initpath), filter);
string loader_format;
vector<string> loaders = theConverters().loaders();
if (find(loaders.begin(), loaders.end(), format) == loaders.end()) {
- vector<string>::const_iterator it = loaders.begin();
- vector<string>::const_iterator en = loaders.end();
- for (; it != en; ++it) {
- if (!theConverters().isReachable(format, *it))
+ for (string const & loader : loaders) {
+ if (!theConverters().isReachable(format, loader))
continue;
string const tofile =
support::changeExtension(filename.absFileName(),
- theFormats().extension(*it));
- if (theConverters().convert(0, filename, FileName(tofile),
- filename, format, *it, errorList) != Converters::SUCCESS)
+ theFormats().extension(loader));
+ if (theConverters().convert(nullptr, filename, FileName(tofile),
+ filename, format, loader, errorList) != Converters::SUCCESS)
return false;
- loader_format = *it;
+ loader_format = loader;
break;
}
if (loader_format.empty()) {
frontend::Alert::error(_("Couldn't import file"),
bformat(_("No information for importing the format %1$s."),
- theFormats().prettyName(format)));
+ translateIfPossible(theFormats().prettyName(format))));
return false;
}
} else
}
docstring const text = bformat(_("Select %1$s file to import"),
- theFormats().prettyName(format));
+ translateIfPossible(theFormats().prettyName(format)));
FileDialog dlg(toqstr(text));
dlg.setButton1(qt_("D&ocuments"), toqstr(lyxrc.document_path));
dlg.setButton2(qt_("&Examples"), toqstr(lyxrc.example_path));
- docstring filter = theFormats().prettyName(format);
+ docstring filter = translateIfPossible(theFormats().prettyName(format));
filter += " (*.{";
// FIXME UNICODE
filter += from_utf8(theFormats().extensions(format));
}
-void GuiView::insertLyXFile(docstring const & fname, bool ignorelang)
+bool GuiView::insertLyXFile(docstring const & fname, bool ignorelang)
{
BufferView * bv = documentBufferView();
if (!bv)
- return;
+ return false;
// FIXME UNICODE
FileName filename(to_utf8(fname));
QStringList(qt_("LyX Documents (*.lyx)")));
if (result.first == FileDialog::Later)
- return;
+ return false;
// FIXME UNICODE
filename.set(fromqstr(result.second));
if (filename.empty()) {
// emit message signal.
message(_("Canceled."));
- return;
+ return false;
}
}
bv->insertLyXFile(filename, ignorelang);
bv->buffer().errors("Parse");
+ return true;
}
return false;
// fname is now the new Buffer location.
- if (FileName(fname).exists()) {
+ if (fname.exists()) {
docstring const file = makeDisplayPath(fname.absFileName(), 30);
docstring text = bformat(_("The document %1$s already "
"exists.\n\nDo you want to "
" Tools->Preferences->Look&Feel->UserInterface\n"
), file);
int ret = Alert::prompt(_("Close or hide document?"),
- text, 0, 1, _("&Close"), _("&Hide"));
+ text, 0, 2, _("&Close"), _("&Hide"), _("&Cancel"));
+ if (ret == 2)
+ return false;
close_buffer = (ret == 0);
}
}
bool GuiView::closeBufferAll()
{
+
+ for (auto & buf : theBufferList()) {
+ if (!saveBufferIfNeeded(*buf, false)) {
+ // Closing has been cancelled, so abort.
+ return false;
+ }
+ }
+
// Close the workareas in all other views
QList<int> const ids = guiApp->viewIds();
for (int i = 0; i != ids.size(); ++i) {
if (!closeWorkAreaAll())
return false;
- // Now close the hidden buffers. We prevent hidden buffers from being
- // dirty, so we can just close them.
- theBufferList().closeAll();
return true;
}
bool GuiView::closeBuffer(Buffer & buf)
{
bool success = true;
- ListOfBuffers clist = buf.getChildren();
- ListOfBuffers::const_iterator it = clist.begin();
- ListOfBuffers::const_iterator const bend = clist.end();
- for (; it != bend; ++it) {
- Buffer * child_buf = *it;
+ for (Buffer * child_buf : buf.getChildren()) {
if (theBufferList().isOthersChild(&buf, child_buf)) {
- child_buf->setParent(0);
+ child_buf->setParent(nullptr);
continue;
}
// Even in this case, children can be dirty (e.g.,
// after a label change in the master, see #11405).
// Therefore, check this
- if (closing_ && (child_buf->isClean() || child_buf->paragraphs().empty()))
+ if (closing_ && (child_buf->isClean() || child_buf->paragraphs().empty())) {
// If we are in a close_event all children will be closed in some time,
// so no need to do it here. This will ensure that the children end up
// in the session file in the correct order. If we close the master
// buffer, we can close or release the child buffers here too.
continue;
+ }
// Save dirty buffers also if closing_!
if (saveBufferIfNeeded(*child_buf, false)) {
child_buf->removeAutosaveFile();
if (success) {
// goto bookmark to update bookmark pit.
// FIXME: we should update only the bookmarks related to this buffer!
+ // FIXME: this is done also in LFUN_WINDOW_CLOSE!
LYXERR(Debug::DEBUG, "GuiView::closeBuffer()");
- for (size_t i = 0; i < theSession().bookmarks().size(); ++i)
- guiApp->gotoBookmark(i+1, false, false);
+ for (unsigned int i = 1; i < theSession().bookmarks().size(); ++i)
+ guiApp->gotoBookmark(i, false, false);
if (saveBufferIfNeeded(buf, false)) {
buf.removeAutosaveFile();
void GuiView::checkExternallyModifiedBuffers()
{
- BufferList::iterator bit = theBufferList().begin();
- BufferList::iterator const bend = theBufferList().end();
- for (; bit != bend; ++bit) {
- Buffer * buf = *bit;
+ for (Buffer * buf : theBufferList()) {
if (buf->fileName().exists() && buf->isChecksumModified()) {
docstring text = bformat(_("Document \n%1$s\n has been externally modified."
" Reload now? Any local changes will be lost."),
void GuiView::dispatchVC(FuncRequest const & cmd, DispatchResult & dr)
{
Buffer * buffer = documentBufferView()
- ? &(documentBufferView()->buffer()) : 0;
+ ? &(documentBufferView()->buffer()) : nullptr;
switch (cmd.action()) {
case LFUN_VC_REGISTER:
break;
case LFUN_VC_LOCKING_TOGGLE:
- LASSERT(buffer, return);
- if (!ensureBufferClean(buffer) || buffer->hasReadonlyFlag())
+ if (!buffer || !ensureBufferClean(buffer) || buffer->hasReadonlyFlag())
break;
if (buffer->lyxvc().inUse()) {
string res = buffer->lyxvc().lockingToggle();
break;
case LFUN_VC_REVERT:
- LASSERT(buffer, return);
+ if (!buffer)
+ break;
if (buffer->lyxvc().revert()) {
reloadBuffer(*buffer);
dr.clearMessageUpdate();
break;
case LFUN_VC_UNDO_LAST:
- LASSERT(buffer, return);
+ if (!buffer)
+ break;
buffer->lyxvc().undoLast();
reloadBuffer(*buffer);
dr.clearMessageUpdate();
break;
case LFUN_VC_REPO_UPDATE:
- LASSERT(buffer, return);
+ if (!buffer)
+ break;
if (ensureBufferClean(buffer)) {
dr.setMessage(buffer->lyxvc().repoUpdate());
checkExternallyModifiedBuffers();
lyx::dispatch(FuncRequest(LFUN_DIALOG_SHOW, "comparehistory"));
break;
}
+ if (!buffer)
+ break;
string rev1 = cmd.getArg(0);
string f1, f2;
- LATTEST(buffer)
// f1
if (!buffer->lyxvc().prepareFileRevision(rev1, f1))
Buffer & buffer = documentBufferView()->buffer();
FileName const filename = support::makeAbsPath(fname, buffer.filePath());
documentBufferView()->saveBookmark(false);
- Buffer * child = 0;
+ Buffer * child = nullptr;
if (theBufferList().exists(filename)) {
child = theBufferList().getBuffer(filename);
setBuffer(child);
int row = -1;
size_t i = argument.find_last_of(' ');
if (i != string::npos) {
- file_name = os::internal_path(trim(argument.substr(0, i)));
+ file_name = os::internal_path(FileName(trim(argument.substr(0, i))).realPath());
istringstream is(argument.substr(i + 1));
is >> row;
if (is.fail())
LYXERR0("Wrong argument: " << argument);
return false;
}
- Buffer * buf = 0;
- string const abstmp = package().temp_dir().absFileName();
+ Buffer * buf = nullptr;
string const realtmp = package().temp_dir().realPath();
// We have to use os::path_prefix_is() here, instead of
// simply prefixIs(), because the file name comes from
// an external application and may need case adjustment.
- if (os::path_prefix_is(file_name, abstmp, os::CASE_ADJUSTED)
- || os::path_prefix_is(file_name, realtmp, os::CASE_ADJUSTED)) {
- // Needed by inverse dvi search. If it is a file
- // in tmpdir, call the apropriated function.
- // If tmpdir is a symlink, we may have the real
- // path passed back, so we correct for that.
- if (!prefixIs(file_name, abstmp))
- file_name = subst(file_name, realtmp, abstmp);
- buf = theBufferList().getBufferFromTmp(file_name);
+ if (os::path_prefix_is(file_name, realtmp, os::CASE_ADJUSTED)) {
+ buf = theBufferList().getBufferFromTmp(file_name, true);
+ LYXERR(Debug::FILES, "goToFileRow: buffer lookup for " << file_name
+ << (buf ? " success" : " failed"));
} else {
// Must replace extension of the file to be .lyx
// and get full path
}
-bool GuiView::GuiViewPrivate::asyncBufferProcessing(
- string const & argument,
+bool GuiView::GuiViewPrivate::asyncBufferProcessing(string const & argument,
Buffer const * used_buffer,
docstring const & msg,
Buffer::ExportStatus (*asyncFunc)(Buffer const *, Buffer *, string const &),
Buffer::ExportStatus (Buffer::*syncFunc)(string const &, bool) const,
Buffer::ExportStatus (Buffer::*previewFunc)(string const &) const,
- bool allow_async)
+ bool allow_async, bool use_tmpdir)
{
if (!used_buffer)
return false;
} else {
Buffer::ExportStatus status;
if (syncFunc) {
- status = (used_buffer->*syncFunc)(format, false);
+ status = (used_buffer->*syncFunc)(format, use_tmpdir);
} else if (previewFunc) {
status = (used_buffer->*previewFunc)(format);
} else
dr.dispatched(true);
Buffer * doc_buffer = documentBufferView()
- ? &(documentBufferView()->buffer()) : 0;
+ ? &(documentBufferView()->buffer()) : nullptr;
if (cmd.origin() == FuncRequest::TOC) {
GuiToc * toc = static_cast<GuiToc*>(findOrBuild("toc", false));
- // FIXME: do we need to pass a DispatchResult object here?
- toc->doDispatch(bv->cursor(), cmd);
+ toc->doDispatch(bv->cursor(), cmd, dr);
return;
}
_("Exporting ..."),
&GuiViewPrivate::exportAndDestroy,
&Buffer::doExport,
- 0, cmd.allowAsync());
+ nullptr, cmd.allowAsync());
// TODO Inform user about success
break;
}
_("Exporting ..."),
&GuiViewPrivate::compileAndDestroy,
&Buffer::doExport,
- 0, cmd.allowAsync());
+ nullptr, cmd.allowAsync(), true);
break;
}
case LFUN_BUFFER_VIEW: {
doc_buffer,
_("Previewing ..."),
&GuiViewPrivate::previewAndDestroy,
- 0,
+ nullptr,
&Buffer::preview, cmd.allowAsync());
break;
}
case LFUN_MASTER_BUFFER_UPDATE: {
d.asyncBufferProcessing(argument,
- (doc_buffer ? doc_buffer->masterBuffer() : 0),
+ (doc_buffer ? doc_buffer->masterBuffer() : nullptr),
docstring(),
&GuiViewPrivate::compileAndDestroy,
&Buffer::doExport,
- 0, cmd.allowAsync());
+ nullptr, cmd.allowAsync(), true);
break;
}
case LFUN_MASTER_BUFFER_VIEW: {
d.asyncBufferProcessing(argument,
- (doc_buffer ? doc_buffer->masterBuffer() : 0),
+ (doc_buffer ? doc_buffer->masterBuffer() : nullptr),
docstring(),
&GuiViewPrivate::previewAndDestroy,
- 0, &Buffer::preview, cmd.allowAsync());
+ nullptr, &Buffer::preview, cmd.allowAsync());
break;
}
case LFUN_EXPORT_CANCEL: {
break;
case LFUN_FILE_INSERT: {
- if (cmd.getArg(1) == "ignorelang")
- insertLyXFile(from_utf8(cmd.getArg(0)), true);
- else
- insertLyXFile(cmd.argument());
+ bool const ignore_lang = cmd.getArg(1) == "ignorelang";
+ if (insertLyXFile(from_utf8(cmd.getArg(0)), ignore_lang)) {
+ dr.forceBufferUpdate();
+ dr.screenUpdate(Update::Force);
+ }
break;
}
break;
}
+ case LFUN_BUFFER_RESET_EXPORT:
+ LASSERT(doc_buffer, break);
+ doc_buffer->requireFreshStart(true);
+ dr.setMessage(_("Buffer export reset."));
+ break;
+
case LFUN_BUFFER_WRITE:
LASSERT(doc_buffer, break);
saveBuffer(*doc_buffer);
break;
}
+ case LFUN_MASTER_BUFFER_FORALL: {
+ if (!doc_buffer)
+ break;
+
+ FuncRequest funcToRun = lyxaction.lookupFunc(cmd.getLongArg(0));
+ funcToRun.allowAsync(false);
+
+ for (Buffer const * buf : doc_buffer->allRelatives()) {
+ // Switch to other buffer view and resend cmd
+ lyx::dispatch(FuncRequest(
+ LFUN_BUFFER_SWITCH, buf->absFileName()));
+ lyx::dispatch(funcToRun);
+ }
+ // switch back
+ lyx::dispatch(FuncRequest(
+ LFUN_BUFFER_SWITCH, doc_buffer->absFileName()));
+ break;
+ }
+
case LFUN_BUFFER_EXTERNAL_MODIFICATION_CLEAR:
LASSERT(doc_buffer, break);
doc_buffer->clearExternalModification();
dr.setMessage(_("Developer mode is now disabled."));
break;
+ case LFUN_TOOLBAR_SET: {
+ string const name = cmd.getArg(0);
+ string const state = cmd.getArg(1);
+ if (GuiToolbar * t = toolbar(name))
+ t->setState(state);
+ break;
+ }
+
case LFUN_TOOLBAR_TOGGLE: {
string const name = cmd.getArg(0);
if (GuiToolbar * t = toolbar(name))
dr.setMessage(_("Toolbars unlocked."));
else
dr.setMessage(_("Toolbars locked."));
- } else if (GuiToolbar * t = toolbar(name)) {
+ } else if (GuiToolbar * tb = toolbar(name))
// toggle current toolbar movablity
- t->movable();
- // update lock (all) toolbars positions
- updateLockToolbars();
- }
+ tb->movable();
+ // update lock (all) toolbars positions
+ updateLockToolbars();
break;
}
break;
case LFUN_DIALOG_HIDE: {
- guiApp->hideDialogs(to_utf8(cmd.argument()), 0);
+ guiApp->hideDialogs(to_utf8(cmd.argument()), nullptr);
break;
}
string sdata = trim(to_utf8(cmd.argument()).substr(name.size()));
if (name == "latexlog") {
- // gettatus checks that
- LATTEST(doc_buffer);
+ // getStatus checks that
+ LASSERT(doc_buffer, break);
Buffer::LogType type;
string const logfile = doc_buffer->logName(&type);
switch (type) {
showDialog("log", sdata);
} else if (name == "vclog") {
// getStatus checks that
- LATTEST(doc_buffer);
+ LASSERT(doc_buffer, break);
string const sdata2 = "vc " +
Lexer::quoteString(doc_buffer->lyxvc().getLogFile());
showDialog("log", sdata2);
sdata = bv->cursor().getEncoding()->name();
if (!sdata.empty())
showDialog("symbols", sdata);
+ } else if (name == "findreplace") {
+ sdata = to_utf8(bv->cursor().selectionAsString(false));
+ showDialog(name, sdata);
// bug 5274
} else if (name == "prefs" && isFullScreen()) {
lfunUiToggle("fullscreen");
case LFUN_TAB_GROUP_CLOSE:
if (TabWorkArea * twa = d.currentTabWorkArea()) {
closeTabWorkArea(twa);
- d.current_work_area_ = 0;
+ d.current_work_area_ = nullptr;
twa = d.currentTabWorkArea();
// Switch to the next GuiWorkArea in the found TabWorkArea.
if (twa) {
// Make sure the work area is up to date.
setCurrentWorkArea(twa->currentWorkArea());
} else {
- setCurrentWorkArea(0);
+ setCurrentWorkArea(nullptr);
}
}
break;
case LFUN_VIEW_CLOSE:
if (TabWorkArea * twa = d.currentTabWorkArea()) {
closeWorkArea(twa->currentWorkArea());
- d.current_work_area_ = 0;
+ d.current_work_area_ = nullptr;
twa = d.currentTabWorkArea();
// Switch to the next GuiWorkArea in the found TabWorkArea.
if (twa) {
// Make sure the work area is up to date.
setCurrentWorkArea(twa->currentWorkArea());
} else {
- setCurrentWorkArea(0);
+ setCurrentWorkArea(nullptr);
}
}
break;
}
// Actual zoom value: default zoom + fractional extra value
- int zoom = lyxrc.defaultZoom * zoom_ratio_;
+ int zoom = (int)(lyxrc.defaultZoom * zoom_ratio_);
if (zoom < static_cast<int>(zoom_min_))
zoom = zoom_min_;
- lyxrc.currentZoom = zoom;
+ setCurrentZoom(zoom);
dr.setMessage(bformat(_("Zoom level is now %1$d% (default value: %2$d%)"),
lyxrc.currentZoom, lyxrc.defaultZoom));
guiApp->fontLoader().update();
- dr.screenUpdate(Update::Force | Update::FitCursor);
+ dr.screenUpdate(Update::ForceAll | Update::FitCursor);
break;
}
activateWindow();
break;
+ case LFUN_WINDOW_RAISE:
+ raise();
+ activateWindow();
+ showNormal();
+ break;
+
case LFUN_FORWARD_SEARCH: {
// it seems safe to assume we have a document buffer, since
// getStatus wants one.
- LATTEST(doc_buffer);
+ LASSERT(doc_buffer, break);
Buffer const * doc_master = doc_buffer->masterBuffer();
FileName const path(doc_master->temppath());
string const texname = doc_master->isChild(doc_buffer)
command = subst(command, "$$t", texname);
command = subst(command, "$$o", outname);
- PathChanger p(path);
+ volatile PathChanger p(path);
Systemcall one;
one.startscript(Systemcall::DontWait, command);
break;
dr.screenUpdate(Update::Force);
break;
+ case LFUN_CITATION_OPEN: {
+ string pdfv, psv;
+ if (theFormats().getFormat("pdf"))
+ pdfv = theFormats().getFormat("pdf")->viewer();
+ if (theFormats().getFormat("ps"))
+ psv = theFormats().getFormat("ps")->viewer();
+ frontend::showTarget(argument, pdfv, psv);
+ break;
+ }
+
default:
// The LFUN must be for one of BufferView, Buffer or Cursor;
// let's try that:
break;
}
- // Part of automatic menu appearance feature.
- if (isFullScreen()) {
- if (menuBar()->isVisible() && lyxrc.full_screen_menubar)
- menuBar()->hide();
- }
-
// Need to update bv because many LFUNs here might have destroyed it
bv = currentBufferView();
statusBar()->setVisible(!statusBar()->isVisible());
} else if (ui_component == "menubar") {
menuBar()->setVisible(!menuBar()->isVisible());
- } else
- if (ui_component == "frame") {
- int l, t, r, b;
- getContentsMargins(&l, &t, &r, &b);
+ } else if (ui_component == "zoom") {
+ zoom_value_->setVisible(!zoom_value_->isVisible());
+ } else if (ui_component == "zoomslider") {
+ zoom_slider_->setVisible(!zoom_slider_->isVisible());
+ zoom_in_->setVisible(zoom_slider_->isVisible());
+ zoom_out_->setVisible(zoom_slider_->isVisible());
+ } else if (ui_component == "frame") {
+ int const l = contentsMargins().left();
+
//are the frames in default state?
d.current_work_area_->setFrameStyle(QFrame::NoFrame);
if (l == 0) {
+#if QT_VERSION > 0x050903
+ setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea, false);
+#endif
setContentsMargins(-2, -2, -2, -2);
} else {
+#if QT_VERSION > 0x050903
+ setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea, true);
+#endif
setContentsMargins(0, 0, 0, 0);
}
} else
void GuiView::toggleFullScreen()
{
- if (isFullScreen()) {
- for (int i = 0; i != d.splitter_->count(); ++i)
- d.tabWorkArea(i)->setFullScreen(false);
- setContentsMargins(0, 0, 0, 0);
- setWindowState(windowState() ^ Qt::WindowFullScreen);
- restoreLayout();
- menuBar()->show();
- statusBar()->show();
- } else {
- // bug 5274
- hideDialogs("prefs", 0);
- for (int i = 0; i != d.splitter_->count(); ++i)
- d.tabWorkArea(i)->setFullScreen(true);
- setContentsMargins(-2, -2, -2, -2);
- saveLayout();
- setWindowState(windowState() ^ Qt::WindowFullScreen);
- if (lyxrc.full_screen_statusbar)
- statusBar()->hide();
- if (lyxrc.full_screen_menubar)
- menuBar()->hide();
- if (lyxrc.full_screen_toolbars) {
- ToolbarMap::iterator end = d.toolbars_.end();
- for (ToolbarMap::iterator it = d.toolbars_.begin(); it != end; ++it)
- it->second->hide();
- }
- }
-
- // give dialogs like the TOC a chance to adapt
- updateDialogs();
+ setWindowState(windowState() ^ Qt::WindowFullScreen);
}
Buffer const * GuiView::updateInset(Inset const * inset)
{
if (!inset)
- return 0;
+ return nullptr;
Buffer const * inset_buffer = &(inset->buffer());
char const * const dialognames[] = {
"aboutlyx", "bibitem", "bibtex", "box", "branch", "changes", "character",
-"citation", "compare", "comparehistory", "document", "errorlist", "ert",
+"citation", "compare", "comparehistory", "counter", "document", "errorlist", "ert",
"external", "file", "findreplace", "findreplaceadv", "float", "graphics",
"href", "include", "index", "index_print", "info", "listings", "label", "line",
"log", "lyxfiles", "mathdelimiter", "mathmatrix", "mathspace", "nomenclature",
bool isValidName(string const & name)
{
return find_if(dialognames, end_dialognames,
- cmpCStr(name.c_str())) != end_dialognames;
+ cmpCStr(name.c_str())) != end_dialognames;
}
} // namespace
void GuiView::resetDialogs()
{
// Make sure that no LFUN uses any GuiView.
- guiApp->setCurrentView(0);
+ guiApp->setCurrentView(nullptr);
saveLayout();
saveUISettings();
menuBar()->clear();
}
+void GuiView::flatGroupBoxes(const QObject * widget, bool flag)
+{
+ for (QObject * child: widget->children()) {
+ if (child->inherits("QGroupBox")) {
+ QGroupBox * box = (QGroupBox*) child;
+ box->setFlat(flag);
+ } else {
+ flatGroupBoxes(child, flag);
+ }
+ }
+}
+
+
Dialog * GuiView::findOrBuild(string const & name, bool hide_it)
{
if (!isValidName(name))
- return 0;
+ return nullptr;
map<string, DialogPtr>::iterator it = d.dialogs_.find(name);
Dialog * dialog = build(name);
d.dialogs_[name].reset(dialog);
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+ // Force a uniform style for group boxes
+ // On Mac non-flat works better, on Linux flat is standard
+ flatGroupBoxes(dialog->asQWidget(), guiApp->platformName() != "cocoa");
+#endif
if (lyxrc.allow_geometry_session)
dialog->restoreSession();
if (hide_it)
// activateWindow is needed for floating dockviews
dialog->asQWidget()->raise();
dialog->asQWidget()->activateWindow();
- dialog->asQWidget()->setFocus();
+ if (dialog->wantInitialFocus())
+ dialog->asQWidget()->setFocus();
}
}
}
- catch (ExceptionMessage const & ex) {
+ catch (ExceptionMessage const &) {
d.in_show_ = false;
- throw ex;
+ throw;
}
d.in_show_ = false;
}
if (dialog->isVisibleView())
dialog->hideView();
if (currentBufferView())
- currentBufferView()->editInset(name, 0);
+ currentBufferView()->editInset(name, nullptr);
}
if (!isValidName(name))
return;
if (currentBufferView())
- currentBufferView()->editInset(name, 0);
+ currentBufferView()->editInset(name, nullptr);
}
void GuiView::hideAll() const
{
- map<string, DialogPtr>::const_iterator it = d.dialogs_.begin();
- map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
-
- for(; it != end; ++it)
- it->second->hideView();
+ for(auto const & dlg_p : d.dialogs_)
+ dlg_p.second->hideView();
}
void GuiView::updateDialogs()
{
- map<string, DialogPtr>::const_iterator it = d.dialogs_.begin();
- map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
-
- for(; it != end; ++it) {
- Dialog * dialog = it->second.get();
+ for(auto const & dlg_p : d.dialogs_) {
+ Dialog * dialog = dlg_p.second.get();
if (dialog) {
if (dialog->needBufferOpen() && !documentBufferView())
- hideDialog(fromqstr(dialog->name()), 0);
+ hideDialog(fromqstr(dialog->name()), nullptr);
else if (dialog->isVisibleView())
dialog->checkStatus();
}
updateLayoutList();
}
-Dialog * createDialog(GuiView & lv, string const & name);
-
-// will be replaced by a proper factory...
-Dialog * createGuiAbout(GuiView & lv);
-Dialog * createGuiBibtex(GuiView & lv);
-Dialog * createGuiChanges(GuiView & lv);
-Dialog * createGuiCharacter(GuiView & lv);
-Dialog * createGuiCitation(GuiView & lv);
-Dialog * createGuiCompare(GuiView & lv);
-Dialog * createGuiCompareHistory(GuiView & lv);
-Dialog * createGuiDelimiter(GuiView & lv);
-Dialog * createGuiDocument(GuiView & lv);
-Dialog * createGuiErrorList(GuiView & lv);
-Dialog * createGuiExternal(GuiView & lv);
-Dialog * createGuiGraphics(GuiView & lv);
-Dialog * createGuiInclude(GuiView & lv);
-Dialog * createGuiIndex(GuiView & lv);
-Dialog * createGuiListings(GuiView & lv);
-Dialog * createGuiLog(GuiView & lv);
-Dialog * createGuiLyXFiles(GuiView & lv);
-Dialog * createGuiMathMatrix(GuiView & lv);
-Dialog * createGuiNote(GuiView & lv);
-Dialog * createGuiParagraph(GuiView & lv);
-Dialog * createGuiPhantom(GuiView & lv);
-Dialog * createGuiPreferences(GuiView & lv);
-Dialog * createGuiPrint(GuiView & lv);
-Dialog * createGuiPrintindex(GuiView & lv);
-Dialog * createGuiRef(GuiView & lv);
-Dialog * createGuiSearch(GuiView & lv);
-Dialog * createGuiSearchAdv(GuiView & lv);
-Dialog * createGuiSendTo(GuiView & lv);
-Dialog * createGuiShowFile(GuiView & lv);
-Dialog * createGuiSpellchecker(GuiView & lv);
-Dialog * createGuiSymbols(GuiView & lv);
-Dialog * createGuiTabularCreate(GuiView & lv);
-Dialog * createGuiTexInfo(GuiView & lv);
-Dialog * createGuiToc(GuiView & lv);
-Dialog * createGuiThesaurus(GuiView & lv);
-Dialog * createGuiViewSource(GuiView & lv);
-Dialog * createGuiWrap(GuiView & lv);
-Dialog * createGuiProgressView(GuiView & lv);
-
-
Dialog * GuiView::build(string const & name)
{
- LASSERT(isValidName(name), return 0);
-
- Dialog * dialog = createDialog(*this, name);
- if (dialog)
- return dialog;
-
- if (name == "aboutlyx")
- return createGuiAbout(*this);
- if (name == "bibtex")
- return createGuiBibtex(*this);
- if (name == "changes")
- return createGuiChanges(*this);
- if (name == "character")
- return createGuiCharacter(*this);
- if (name == "citation")
- return createGuiCitation(*this);
- if (name == "compare")
- return createGuiCompare(*this);
- if (name == "comparehistory")
- return createGuiCompareHistory(*this);
- if (name == "document")
- return createGuiDocument(*this);
- if (name == "errorlist")
- return createGuiErrorList(*this);
- if (name == "external")
- return createGuiExternal(*this);
- if (name == "file")
- return createGuiShowFile(*this);
- if (name == "findreplace")
- return createGuiSearch(*this);
- if (name == "findreplaceadv")
- return createGuiSearchAdv(*this);
- if (name == "graphics")
- return createGuiGraphics(*this);
- if (name == "include")
- return createGuiInclude(*this);
- if (name == "index")
- return createGuiIndex(*this);
- if (name == "index_print")
- return createGuiPrintindex(*this);
- if (name == "listings")
- return createGuiListings(*this);
- if (name == "log")
- return createGuiLog(*this);
- if (name == "lyxfiles")
- return createGuiLyXFiles(*this);
- if (name == "mathdelimiter")
- return createGuiDelimiter(*this);
- if (name == "mathmatrix")
- return createGuiMathMatrix(*this);
- if (name == "note")
- return createGuiNote(*this);
- if (name == "paragraph")
- return createGuiParagraph(*this);
- if (name == "phantom")
- return createGuiPhantom(*this);
- if (name == "prefs")
- return createGuiPreferences(*this);
- if (name == "ref")
- return createGuiRef(*this);
- if (name == "sendto")
- return createGuiSendTo(*this);
- if (name == "spellchecker")
- return createGuiSpellchecker(*this);
- if (name == "symbols")
- return createGuiSymbols(*this);
- if (name == "tabularcreate")
- return createGuiTabularCreate(*this);
- if (name == "texinfo")
- return createGuiTexInfo(*this);
- if (name == "thesaurus")
- return createGuiThesaurus(*this);
- if (name == "toc")
- return createGuiToc(*this);
- if (name == "view-source")
- return createGuiViewSource(*this);
- if (name == "wrap")
- return createGuiWrap(*this);
- if (name == "progress")
- return createGuiProgressView(*this);
-
- return 0;
+ return createDialog(*this, name);
}
parent, SLOT(disableShellEscape()));
}
+
+void PressableSvgWidget::mousePressEvent(QMouseEvent * event)
+{
+ if (event->button() == Qt::LeftButton) {
+ Q_EMIT pressed();
+ }
+}
+
} // namespace frontend
} // namespace lyx