+// sync with GuiAlert.cpp
#define EXPORT_in_THREAD 1
/// 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");
+ splash_ = getPixmap("images/", "banner", "svgz,png");
QPainter pain(&splash_);
pain.setPen(QColor(0, 0, 0));
+ double const multiplier = splashPixelRatio() / pixelRatio();
+ int const size = static_cast<int>(toqstr(lyxrc.font_sizes[FONT_SIZE_LARGE]).toDouble() * multiplier);
+ int const x = static_cast<int>(190 * multiplier);
+ int const y = static_cast<int>(225 * multiplier);
+ LYXERR(Debug::GUI,
+ "widget pixel ratio: " << pixelRatio() <<
+ " splash pixel ratio: " << splashPixelRatio() <<
+ " version text size,position: " << size << "@" << x << "+" << y);
QFont font;
// The font used to display the version info
font.setStyleHint(QFont::SansSerif);
font.setWeight(QFont::Bold);
- font.setPointSize(int(toqstr(lyxrc.font_sizes[FONT_SIZE_LARGE]).toDouble()));
+ font.setPointSize(size);
pain.setFont(font);
- pain.drawText(190, 225, text);
+ pain.drawText(x, y, text);
setFocusPolicy(Qt::StrongFocus);
}
void paintEvent(QPaintEvent *)
{
- int x = (width() - splash_.width()) / 2;
- int y = (height() - splash_.height()) / 2;
+ int const w = static_cast<int>(splash_.width() / splashPixelRatio());
+ int const h = static_cast<int>(splash_.height() / splashPixelRatio());
+ int const x = (width() - w) / 2;
+ int const y = (height() - h) / 2;
+ LYXERR(Debug::GUI,
+ "widget pixel ratio: " << pixelRatio() <<
+ " splash pixel ratio: " << splashPixelRatio() <<
+ " paint pixmap: " << w << "x" << h << "@" << x << "+" << y);
QPainter pain(this);
- pain.drawPixmap(x, y, splash_);
+ pain.drawPixmap(x, y, w, h, splash_);
}
void keyPressEvent(QKeyEvent * ev)
private:
QPixmap splash_;
+
+ /// Current ratio between physical pixels and device-independent pixels
+ double pixelRatio() const {
+#if QT_VERSION >= 0x050000
+ return devicePixelRatio();
+#else
+ return 1.0;
+#endif
+ }
+
+ /// Ratio between physical pixels and device-independent pixels of splash image
+ double splashPixelRatio() const {
+#if QT_VERSION >= 0x050000
+ return splash_.devicePixelRatio();
+#else
+ return 1.0;
+#endif
+ }
};
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();
}
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
// We don't want to keep the window in memory if it is closed.
setAttribute(Qt::WA_DeleteOnClose, true);
-#if (!defined(Q_WS_WIN) && !defined(Q_WS_MACX))
+#if !(defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN)) && !defined(Q_OS_MAC)
// QIcon::fromTheme was introduced in Qt 4.6
#if (QT_VERSION >= 0x040600)
// 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
// add busy indicator to statusbar
QLabel * busylabel = new QLabel(statusBar());
statusBar()->addPermanentWidget(busylabel);
- QString fn = toqstr(lyx::libFileSearch("images", "busy.gif").absFileName());
+ 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();
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,
return;
setWindowTitle(qt_("LyX: ") + wa->windowTitle());
setWindowIconText(wa->windowIconText());
+#if (QT_VERSION >= 0x040400)
+ // Sets the path for the window: this is used by OSX to
+ // allow a context click on the title bar showing a menu
+ // with the path up to the file
+ setWindowFilePath(toqstr(wa->bufferView().buffer().absFileName()));
+#endif
}
return;
}
-#ifdef Q_WS_MACX
+#ifdef Q_OS_MAC
// On Mac we also close the last window because the application stay
// resident in memory. On other platforms we don't close the last
// window because this would quit the application.
}
+double GuiView::pixelRatio() const
+{
+#if QT_VERSION >= 0x050000
+ return devicePixelRatio();
+#else
+ return 1.0;
+#endif
+}
+
+
GuiWorkArea * GuiView::workArea(int index)
{
if (TabWorkArea * twa = d.currentTabWorkArea())
Buffer * doc_buffer = documentBufferView()
? &(documentBufferView()->buffer()) : 0;
+ /* 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.
+ */
+ if (cmd.origin() == FuncRequest::MENU && !hasFocus()) {
+ buf = 0;
+ doc_buffer = 0;
+ }
+
// Check whether we need a buffer
if (!lyxaction.funcHasFlag(cmd.action(), LyXAction::NoBuffer) && !buf) {
// no, exit directly
else if (name == "print")
enable = doc_buffer->params().isExportable("dvi")
&& lyxrc.print_command != "none";
- else if (name == "character" || name == "symbols") {
+ else if (name == "character" || name == "symbols"
+ || name == "mathdelimiter" || name == "mathmatrix") {
if (!buf || buf->isReadonly())
enable = false;
else {
enable = false;
break;
- case LFUN_COMPLETION_COMPLETE:
+ case LFUN_COMPLETE:
if (!d.current_work_area_
|| !d.current_work_area_->completer().inlinePossible(
currentBufferView()->cursor()))
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
string filename;
if (fname.empty()) {
- FileDialog dlg(qt_("Select document to open"), LFUN_FILE_OPEN);
+ FileDialog dlg(qt_("Select document to open"));
dlg.setButton1(qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
dlg.setButton2(qt_("Examples|#E#e"),
toqstr(addPath(package().system_support().absFileName(), "examples")));
- QStringList filter(qt_("LyX Documents (*.lyx)"));
- filter << qt_("LyX-1.3.x Documents (*.lyx13)")
- << qt_("LyX-1.4.x Documents (*.lyx14)")
- << qt_("LyX-1.5.x Documents (*.lyx15)")
- << qt_("LyX-1.6.x Documents (*.lyx16)");
+ QStringList const filter(qt_("LyX Documents (*.lyx)"));
FileDialog::Result result =
dlg.open(toqstr(initpath), filter);
docstring const text = bformat(_("Select %1$s file to import"),
formats.prettyName(format));
- FileDialog dlg(toqstr(text), LFUN_BUFFER_IMPORT);
+ FileDialog dlg(toqstr(text));
dlg.setButton1(qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
dlg.setButton2(qt_("Examples|#E#e"),
toqstr(addPath(package().system_support().absFileName(), "examples")));
// get absolute path of file
FileName const fullname(support::makeAbsPath(filename));
+ // Can happen if the user entered a path into the dialog
+ // (see bug #7437)
+ if (fullname.onlyFileName().empty()) {
+ docstring msg = bformat(_("The file name '%1$s' is invalid!\n"
+ "Aborting import."),
+ from_utf8(fullname.absFileName()));
+ frontend::Alert::error(_("File name error"), msg);
+ message(_("Canceled."));
+ return;
+ }
+
+
FileName const lyxfile(support::changeExtension(fullname.absFileName(), ".lyx"));
// Check if the document already is open
initpath = trypath;
// FIXME UNICODE
- FileDialog dlg(qt_("Select LyX document to insert"), LFUN_FILE_INSERT);
+ FileDialog dlg(qt_("Select LyX document to insert"));
dlg.setButton1(qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
dlg.setButton2(qt_("Examples|#E#e"),
toqstr(addPath(package().system_support().absFileName(),
// No argument? Ask user through dialog.
// FIXME UNICODE
- FileDialog dlg(qt_("Choose a filename to save document as"),
- LFUN_BUFFER_WRITE_AS);
+ FileDialog dlg(qt_("Choose a filename to save document as"));
dlg.setButton1(qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
dlg.setButton2(qt_("Templates|#T#t"), toqstr(lyxrc.template_path));
for (; fit != export_formats.end(); ++fit) {
docstring const loc_prettyname =
translateIfPossible(from_utf8((*fit)->prettyname()));
- QString const loc_filter = toqstr(bformat(_("%1$s (*.%2$s)"),
+ QString const loc_filter = toqstr(bformat(from_ascii("%1$s (*.%2$s)"),
loc_prettyname,
from_ascii((*fit)->extension())));
types << loc_filter;
}
-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;
}
}
if (!buffer->lyxvc().inUse()) {
if (buffer->lyxvc().registrer()) {
reloadBuffer(*buffer);
- dr.suppressMessageUpdate();
+ dr.clearMessageUpdate();
}
}
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)
LASSERT(buffer, return);
if (buffer->lyxvc().revert()) {
reloadBuffer(*buffer);
- dr.suppressMessageUpdate();
+ dr.clearMessageUpdate();
}
break;
LASSERT(buffer, return);
buffer->lyxvc().undoLast();
reloadBuffer(*buffer);
- dr.suppressMessageUpdate();
+ dr.clearMessageUpdate();
break;
case LFUN_VC_REPO_UPDATE:
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: {
case LFUN_FILE_INSERT_PLAINTEXT:
case LFUN_FILE_INSERT_PLAINTEXT_PARA: {
- bool const as_paragraph = (cmd.action() == LFUN_FILE_INSERT_PLAINTEXT_PARA);
string const fname = to_utf8(cmd.argument());
if (!fname.empty() && !FileName::isAbsolute(fname)) {
dr.setMessage(_("Absolute filename expected."));
FileName filename(fname);
if (fname.empty()) {
- FileDialog dlg(qt_("Select file to insert"), (as_paragraph ?
- LFUN_FILE_INSERT_PLAINTEXT_PARA : LFUN_FILE_INSERT_PLAINTEXT));
+ FileDialog dlg(qt_("Select file to insert"));
FileDialog::Result result = dlg.open(toqstr(bv->buffer().filePath()),
QStringList(qt_("All Files (*)")));
break;
- case LFUN_COMPLETION_COMPLETE:
+ case LFUN_COMPLETE:
if (d.current_work_area_)
d.current_work_area_->completer().tab();
break;
if (isFullScreen()) {
if (menuBar()->isVisible() && lyxrc.full_screen_menubar)
menuBar()->hide();
- if (statusBar()->isVisible())
- statusBar()->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();
+ }
}
}
setContentsMargins(-2, -2, -2, -2);
saveLayout();
setWindowState(windowState() ^ Qt::WindowFullScreen);
- statusBar()->hide();
+ if (lyxrc.full_screen_statusbar)
+ statusBar()->hide();
if (lyxrc.full_screen_menubar)
menuBar()->hide();
if (lyxrc.full_screen_toolbars) {