#include "TocModel.h"
#include "qt_helpers.h"
+#include "support/filetools.h"
#include "frontends/alert.h"
#include "frontends/KeySymbol.h"
#include <QSplitter>
#include <QStackedWidget>
#include <QStatusBar>
+#if QT_VERSION >= 0x050000
+#include <QSvgRenderer>
+#endif
#include <QtConcurrentRun>
#include <QTime>
#include <QTimer>
+// sync with GuiAlert.cpp
#define EXPORT_in_THREAD 1
class BackgroundWidget : public QWidget
{
public:
- BackgroundWidget()
+ BackgroundWidget(int width, int height)
+ : width_(width), height_(height)
{
LYXERR(Debug::GUI, "show banner: " << lyxrc.show_banner);
if (!lyxrc.show_banner)
/// The text to be written on top of the pixmap
QString const text = lyx_version ?
qt_("version ") + lyx_version : qt_("unknown version");
- splash_ = getPixmap("images/", "banner", "png");
+#if QT_VERSION >= 0x050000
+ QString imagedir = "images/";
+ FileName fname = imageLibFileSearch(imagedir, "banner", "svgz");
+ QSvgRenderer svgRenderer(toqstr(fname.absFileName()));
+ if (svgRenderer.isValid()) {
+ splash_ = QPixmap(splashSize());
+ QPainter painter(&splash_);
+ svgRenderer.render(&painter);
+ splash_.setDevicePixelRatio(pixelRatio());
+ } else {
+ splash_ = getPixmap("images/", "banner", "png");
+ }
+#else
+ splash_ = getPixmap("images/", "banner", "svgz,png");
+#endif
QPainter pain(&splash_);
pain.setPen(QColor(0, 0, 0));
- double const multiplier = splashPixelRatio() / pixelRatio();
- int const size = toqstr(lyxrc.font_sizes[FONT_SIZE_LARGE]).toDouble() * multiplier;
- int const x = 190 * multiplier;
- int const y = 225 * multiplier;
+ qreal const fsize = fontSize();
+ QPointF const position = textPosition();
LYXERR(Debug::GUI,
"widget pixel ratio: " << pixelRatio() <<
" splash pixel ratio: " << splashPixelRatio() <<
- " version text size,position: " << size << "@" << x << "+" << y);
+ " version text size,position: " << fsize << "@" << position.x() << "+" << position.y());
QFont font;
// The font used to display the version info
font.setStyleHint(QFont::SansSerif);
font.setWeight(QFont::Bold);
- font.setPointSize(size);
+ font.setPointSizeF(fsize);
pain.setFont(font);
- pain.drawText(x, y, text);
+ pain.drawText(position, text);
setFocusPolicy(Qt::StrongFocus);
}
void paintEvent(QPaintEvent *)
{
- int const w = splash_.width() / splashPixelRatio();
- int const h = splash_.height() / splashPixelRatio();
+ int const w = width_;
+ int const h = height_;
int const x = (width() - w) / 2;
int const y = (height() - h) / 2;
LYXERR(Debug::GUI,
private:
QPixmap splash_;
+ int const width_;
+ int const height_;
/// Current ratio between physical pixels and device-independent pixels
double pixelRatio() const {
#endif
}
+ qreal fontSize() const {
+ return toqstr(lyxrc.font_sizes[FONT_SIZE_NORMAL]).toDouble();
+ }
+
+ QPointF textPosition() const {
+ return QPointF(width_/2 - 18, height_/2 + 45);
+ }
+
+ QSize splashSize() const {
+ return QSize(
+ static_cast<unsigned int>(width_ * pixelRatio()),
+ static_cast<unsigned int>(height_ * pixelRatio()));
+ }
+
/// Ratio between physical pixels and device-independent pixels of splash image
double splashPixelRatio() const {
#if QT_VERSION >= 0x050000
smallIconSize = 16; // scaling problems
normalIconSize = 20; // ok, default if iconsize.png is missing
bigIconSize = 26; // better for some math icons
+ hugeIconSize = 32; // better for hires displays
+ giantIconSize = 48;
// if it exists, use width of iconsize.png as normal size
QString const dir = toqstr(addPath("images", lyxrc.icon_set));
QImage image(toqstr(fn.absFileName()));
if (image.width() < int(smallIconSize))
normalIconSize = smallIconSize;
- else if (image.width() > int(bigIconSize))
- normalIconSize = bigIconSize;
+ else if (image.width() > int(giantIconSize))
+ normalIconSize = giantIconSize;
else
normalIconSize = image.width();
}
splitter_ = new QSplitter;
- bg_widget_ = new BackgroundWidget;
+ bg_widget_ = new BackgroundWidget(400, 250);
stack_widget_ = new QStackedWidget;
stack_widget_->addWidget(bg_widget_);
stack_widget_->addWidget(splitter_);
parent, SLOT(bigSizedIcons()));
menu->addAction(bigIcons);
+ QAction * hugeIcons = new QAction(iconSizeGroup);
+ hugeIcons->setText(qt_("Huge-sized icons"));
+ hugeIcons->setCheckable(true);
+ QObject::connect(hugeIcons, SIGNAL(triggered()),
+ parent, SLOT(hugeSizedIcons()));
+ menu->addAction(hugeIcons);
+
+ QAction * giantIcons = new QAction(iconSizeGroup);
+ giantIcons->setText(qt_("Giant-sized icons"));
+ giantIcons->setCheckable(true);
+ QObject::connect(giantIcons, SIGNAL(triggered()),
+ parent, SLOT(giantSizedIcons()));
+ menu->addAction(giantIcons);
+
unsigned int cur = parent->iconSize().width();
if ( cur == parent->d.smallIconSize)
smallIcons->setChecked(true);
normalIcons->setChecked(true);
else if (cur == parent->d.bigIconSize)
bigIcons->setChecked(true);
+ else if (cur == parent->d.hugeIconSize)
+ hugeIcons->setChecked(true);
+ else if (cur == parent->d.giantIconSize)
+ giantIcons->setChecked(true);
return menu;
}
unsigned int smallIconSize;
unsigned int normalIconSize;
unsigned int bigIconSize;
+ unsigned int hugeIconSize;
+ unsigned int giantIconSize;
///
QTimer statusbar_timer_;
/// auto-saving of buffers
GuiView::GuiView(int id)
- : d(*new GuiViewPrivate(this)), id_(id), closing_(false), busy_(0)
+ : d(*new GuiViewPrivate(this)), id_(id), closing_(false), busy_(0),
+ command_execute_(false)
{
// GuiToolbars *must* be initialised before the menu bar.
normalSizedIcons(); // at least on Mac the default is 32 otherwise, which is huge
// assign an icon to main form. We do not do it under Qt/Win or Qt/Mac,
// since the icon is provided in the application bundle. We use a themed
// version when available and use the bundled one as fallback.
- setWindowIcon(QIcon::fromTheme("lyx", getPixmap("images/", "lyx", "png")));
+ setWindowIcon(QIcon::fromTheme("lyx", getPixmap("images/", "lyx", "svg,png")));
#else
- setWindowIcon(getPixmap("images/", "lyx", "png"));
+ setWindowIcon(getPixmap("images/", "lyx", "svg,png"));
#endif
#endif
QSettings settings;
settings.beginGroup("views");
settings.beginGroup(QString::number(id_));
-#ifdef Q_WS_X11
+#if defined(Q_WS_X11) || defined(QPA_XCB)
settings.setValue("pos", pos());
settings.setValue("size", size());
#else
// Check whether session size changed.
if (icon_size.width() != int(d.smallIconSize) &&
icon_size.width() != int(d.normalIconSize) &&
- icon_size.width() != int(d.bigIconSize)) {
+ icon_size.width() != int(d.bigIconSize) &&
+ icon_size.width() != int(d.hugeIconSize) &&
+ icon_size.width() != int(d.giantIconSize)) {
icon_size.setWidth(d.normalIconSize);
icon_size.setHeight(d.normalIconSize);
}
setIconSize(icon_size);
-#ifdef Q_WS_X11
+#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);
}
+bool GuiView::hasFocus() const
+{
+ if (currentWorkArea())
+ return currentWorkArea()->hasFocus();
+ if (currentMainWorkArea())
+ return currentMainWorkArea()->hasFocus();
+ return d.bg_widget_->hasFocus();
+}
+
+
void GuiView::focusInEvent(QFocusEvent * e)
{
LYXERR(Debug::DEBUG, "GuiView::focusInEvent()" << this);
}
+bool GuiView::prepareAllBuffersForLogout()
+{
+ Buffer * first = theBufferList().first();
+ if (!first)
+ return true;
+
+ // First, iterate over all buffers and ask the users if unsaved
+ // changes should be saved.
+ // We cannot use a for loop as the buffer list cycles.
+ Buffer * b = first;
+ do {
+ if (!saveBufferIfNeeded(const_cast<Buffer &>(*b), false))
+ return false;
+ b = theBufferList().next(b);
+ } while (b != first);
+
+ // Next, save session state
+ // When a view/window was closed before without quitting LyX, there
+ // are already entries in the lastOpened list.
+ theSession().lastOpened().clear();
+ writeSession();
+
+ return true;
+}
+
+
/** Destroy only all tabbed WorkAreas. Destruction of other WorkAreas
** is responsibility of the container (e.g., dialog)
**/
}
+void GuiView::hugeSizedIcons()
+{
+ setIconSize(QSize(d.hugeIconSize, d.hugeIconSize));
+}
+
+
+void GuiView::giantSizedIcons()
+{
+ setIconSize(QSize(d.giantIconSize, d.giantIconSize));
+}
+
+
void GuiView::clearMessage()
{
// FIXME: This code was introduced in r19643 to fix bug #4123. However,
}
+void GuiView::resetCommandExecute()
+{
+ command_execute_ = false;
+ updateToolbars();
+}
+
+
double GuiView::pixelRatio() const
{
#if QT_VERSION >= 0x050000
{
ToolbarMap::iterator end = d.toolbars_.end();
if (d.current_work_area_) {
- bool const math =
- d.current_work_area_->bufferView().cursor().inMathed()
- && !d.current_work_area_->bufferView().cursor().inRegexped();
- bool const table =
- lyx::getStatus(FuncRequest(LFUN_LAYOUT_TABULAR)).enabled();
- bool const review =
- lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).enabled() &&
- lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).onOff(true);
- bool const mathmacrotemplate =
- lyx::getStatus(FuncRequest(LFUN_IN_MATHMACROTEMPLATE)).enabled();
- bool const ipa =
- lyx::getStatus(FuncRequest(LFUN_IN_IPA)).enabled();
+ int context = 0;
+ if (d.current_work_area_->bufferView().cursor().inMathed()
+ && !d.current_work_area_->bufferView().cursor().inRegexped())
+ context |= Toolbars::MATH;
+ if (lyx::getStatus(FuncRequest(LFUN_LAYOUT_TABULAR)).enabled())
+ context |= Toolbars::TABLE;
+ if (lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).enabled()
+ && lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).onOff(true))
+ context |= Toolbars::REVIEW;
+ if (lyx::getStatus(FuncRequest(LFUN_IN_MATHMACROTEMPLATE)).enabled())
+ context |= Toolbars::MATHMACROTEMPLATE;
+ if (lyx::getStatus(FuncRequest(LFUN_IN_IPA)).enabled())
+ context |= Toolbars::IPA;
+ if (command_execute_)
+ context |= Toolbars::MINIBUFFER;
for (ToolbarMap::iterator it = d.toolbars_.begin(); it != end; ++it)
- it->second->update(math, table, review, mathmacrotemplate, ipa);
+ it->second->update(context);
} else
for (ToolbarMap::iterator it = d.toolbars_.begin(); it != end; ++it)
- it->second->update(false, false, false, false, false);
+ it->second->update();
}
Buffer * doc_buffer = documentBufferView()
? &(documentBufferView()->buffer()) : 0;
+#ifdef Q_OS_MAC
+ /* In LyX/Mac, when a dialog is open, the menus of the
+ application can still be accessed without giving focus to
+ the main window. In this case, we want to disable the menu
+ entries that are buffer-related.
+ This code must not be used on Linux and Windows, since it
+ would disable buffer-related entries when hovering over the
+ menu (see bug #9574).
+ */
+ if (cmd.origin() == FuncRequest::MENU && !hasFocus()) {
+ buf = 0;
+ doc_buffer = 0;
+ }
+#endif
+
// Check whether we need a buffer
if (!lyxaction.funcHasFlag(cmd.action(), LyXAction::NoBuffer) && !buf) {
// no, exit directly
|| name == "texinfo"
|| name == "progress"
|| name == "compare";
- else if (name == "print")
- enable = doc_buffer->params().isExportable("dvi")
- && lyxrc.print_command != "none";
else if (name == "character" || name == "symbols"
|| name == "mathdelimiter" || name == "mathmatrix") {
if (!buf || buf->isReadonly())
enable = doc_buffer;
break;
+ case LFUN_BUFFER_MOVE_NEXT:
+ case LFUN_BUFFER_MOVE_PREVIOUS:
+ // we do not cycle when moving
case LFUN_BUFFER_NEXT:
case LFUN_BUFFER_PREVIOUS:
- // FIXME: should we check is there is an previous or next buffer?
+ // because we cycle, it doesn't matter whether on first or last
+ enable = (d.currentTabWorkArea()->count() > 1);
break;
case LFUN_BUFFER_SWITCH:
// toggle on the current buffer, but do not toggle off
}
-void GuiView::gotoNextOrPreviousBuffer(NextOrPrevious np)
+void GuiView::gotoNextOrPreviousBuffer(NextOrPrevious np, bool const move)
{
if (!documentBufferView())
return;
next_index = (i == nwa - 1 ? 0 : i + 1);
else
next_index = (i == 0 ? nwa - 1 : i - 1);
- setBuffer(&workArea(next_index)->bufferView().buffer());
+ if (move)
+ twa->moveTab(i, next_index);
+ else
+ setBuffer(&workArea(next_index)->bufferView().buffer());
break;
}
}
LyXVC::CommandResult ret = buffer->lyxvc().checkIn(log);
dr.setMessage(log);
// Only skip reloading if the checkin was cancelled or
- // an error occured before the real checkin VCS command
+ // an error occurred before the real checkin VCS command
// was executed, since the VCS might have changed the
// file even if it could not checkin successfully.
if (ret == LyXVC::ErrorCommand || ret == LyXVC::VCSuccess)
if (format.empty())
format = used_buffer->params().getDefaultOutputFormat();
processing_format = format;
-#if EXPORT_in_THREAD
if (!msg.empty()) {
progress_->clearMessages();
gv_->message(msg);
}
+#if EXPORT_in_THREAD
GuiViewPrivate::busyBuffers.insert(used_buffer);
Buffer * cloned_buffer = used_buffer->cloneFromMaster();
if (!cloned_buffer) {
}
case LFUN_BUFFER_NEXT:
- gotoNextOrPreviousBuffer(NEXTBUFFER);
+ gotoNextOrPreviousBuffer(NEXTBUFFER, false);
+ break;
+
+ case LFUN_BUFFER_MOVE_NEXT:
+ gotoNextOrPreviousBuffer(NEXTBUFFER, true);
break;
case LFUN_BUFFER_PREVIOUS:
- gotoNextOrPreviousBuffer(PREVBUFFER);
+ gotoNextOrPreviousBuffer(PREVBUFFER, false);
+ break;
+
+ case LFUN_BUFFER_MOVE_PREVIOUS:
+ gotoNextOrPreviousBuffer(PREVBUFFER, true);
break;
case LFUN_COMMAND_EXECUTE: {
- bool const show_it = cmd.argument() != "off";
- // FIXME: this is a hack, "minibuffer" should not be
- // hardcoded.
- if (GuiToolbar * t = toolbar("minibuffer")) {
- t->setVisible(show_it);
- if (show_it && t->commandBuffer())
- t->commandBuffer()->setFocus();
- }
+ command_execute_ = true;
break;
}
case LFUN_DROP_LAYOUTS_CHOICE:
if (menuBar()->isVisible() && lyxrc.full_screen_menubar)
menuBar()->hide();
}
+
+ // Need to update bv because many LFUNs here might have destroyed it
+ bv = currentBufferView();
+
+ // Clear non-empty selections
+ // (e.g. from a "char-forward-select" followed by "char-backward-select")
+ if (bv) {
+ Cursor & cur = bv->cursor();
+ if ((cur.selection() && cur.selBegin() == cur.selEnd())) {
+ cur.clearSelection();
+ }
+ }
}
return createGuiPhantom(*this);
if (name == "prefs")
return createGuiPreferences(*this);
- if (name == "print")
- return createGuiPrint(*this);
if (name == "ref")
return createGuiRef(*this);
if (name == "sendto")