return;
/// The text to be written on top of the pixmap
QString const htext = qt_("The Document\nProcessor[[welcome banner]]");
- QString const htextsize = qt_("1.0[[possibly scale the welcome banner text size]]");
+ QString const htextsize = qt_("1.0[[translating this to different value scales the welcome banner text size for your language]]");
/// The text to be written on top of the pixmap
QString const text = lyx_version ?
qt_("version ") + lyx_version : qt_("unknown version");
processStop, SLOT(show()));
connect(&d.processing_thread_watcher_, SIGNAL(finished()),
processStop, SLOT(hide()));
- connect(processStop, SIGNAL(pressed()), this, SLOT(checkCancelBackground()));
+ connect(processStop, SIGNAL(clicked()), this, SLOT(checkCancelBackground()));
connect(this, SIGNAL(scriptKilled()), busySVG, SLOT(hide()));
connect(this, SIGNAL(scriptKilled()), processStop, SLOT(hide()));
stat_counts_ = new GuiClickableLabel(statusBar());
stat_counts_->setAlignment(Qt::AlignCenter);
- stat_counts_->setFrameStyle(QFrame::StyledPanel);
stat_counts_->hide();
statusBar()->addPermanentWidget(stat_counts_);
connect(stat_counts_, SIGNAL(clicked()), this, SLOT(statsPressed()));
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_out_->setFixedSize(s);
zoom_out_->setAlignment(Qt::AlignCenter);
- statusBar()->addPermanentWidget(zoom_out_);
- zoom_out_->setEnabled(currentBufferView());
- statusBar()->addPermanentWidget(zoom_slider_);
+
+ zoom_widget_ = new QWidget(statusBar());
+ zoom_widget_->setAttribute(Qt::WA_MacSmallSize);
+ zoom_widget_->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
+ zoom_widget_->setLayout(new QHBoxLayout());
+ zoom_widget_->layout()->setSpacing(5);
+ zoom_widget_->layout()->setContentsMargins(0,0,0,0);
+ zoom_widget_->layout()->addWidget(zoom_out_);
+ zoom_widget_->layout()->addWidget(zoom_slider_);
+ zoom_widget_->layout()->addWidget(zoom_in_);
+ statusBar()->addPermanentWidget(zoom_widget_);
+ zoom_out_->setEnabled(currentBufferView()
+ && zoom_slider_->value() > zoom_slider_->minimum());
zoom_slider_->setEnabled(currentBufferView());
- zoom_in_->setEnabled(currentBufferView());
- statusBar()->addPermanentWidget(zoom_in_);
+ zoom_in_->setEnabled(currentBufferView()
+ && zoom_slider_->value() < zoom_slider_->maximum());
connect(zoom_slider_, SIGNAL(sliderMoved(int)), this, SLOT(zoomSliderMoved(int)));
connect(zoom_slider_, SIGNAL(valueChanged(int)), this, SLOT(zoomValueChanged(int)));
dispatch(FuncRequest(LFUN_BUFFER_ZOOM, convert<string>(value)), dr);
scheduleRedrawWorkAreas();
zoom_value_->setText(toqstr(bformat(_("[[ZOOM]]%1$d%"), value)));
+ zoom_in_->setEnabled(currentBufferView()
+ && value < zoom_slider_->maximum());
+ zoom_out_->setEnabled(currentBufferView()
+ && value > zoom_slider_->minimum());
}
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());
+ settings.setValue("zoom_slider_visible", zoom_widget_->isVisible());
settings.setValue("word_count_enabled", word_count_enabled_);
settings.setValue("char_count_enabled", char_count_enabled_);
settings.setValue("char_nb_count_enabled", char_nb_count_enabled_);
void GuiView::setCurrentZoom(const int v)
{
+ Q_EMIT currentZoomChanged(v);
lyxrc.currentZoom = v;
zoom_value_->setText(toqstr(bformat(_("[[ZOOM]]%1$d%"), v)));
- Q_EMIT currentZoomChanged(v);
+ zoom_in_->setEnabled(currentBufferView() && v < zoom_slider_->maximum());
+ zoom_out_->setEnabled(currentBufferView() && v > zoom_slider_->minimum());
}
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);
+ zoom_widget_->setVisible(show_zoom_slider);
word_count_enabled_ = settings.value("word_count_enabled", true).toBool();
char_count_enabled_ = settings.value("char_count_enabled", true).toBool();
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
}
{
LYXERR(Debug::DEBUG, "GuiView::closeEvent()");
+ // FIXME Bug #12828 bites here. If there is some other View open, then
+ // we really should only refuse to close if one of the Buffers open here
+ // is being processed.
if (!GuiViewPrivate::busyBuffers.isEmpty()) {
Alert::warning(_("Exit LyX"),
_("LyX could not be closed because documents are being processed by LyX."));
updateDialogs();
zoom_slider_->setEnabled(currentBufferView());
zoom_value_->setEnabled(currentBufferView());
- zoom_in_->setEnabled(currentBufferView());
- zoom_out_->setEnabled(currentBufferView());
+ zoom_in_->setEnabled(currentBufferView()
+ && zoom_slider_->value() < zoom_slider_->maximum());
+ zoom_out_->setEnabled(currentBufferView()
+ && zoom_slider_->value() > zoom_slider_->minimum());
}
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);
return QMainWindow::event(e);
}
+ // dark/light mode runtime switch support, OS-dependent.
+ // 1. Mac OS X
+ // Limit to Q_OS_MAC as this unnecessarily would also
+ // trigger on Linux with grave performance issues
+#ifdef Q_OS_MAC
+ case QEvent::ApplicationPaletteChange: {
+ // We need to update metrics here to avoid a crash (#12786)
+ theBufferList().changed(true);
+ refillToolbars();
+ return QMainWindow::event(e);
+ }
+#endif
+ // 2. Linux
+ case QEvent::StyleChange: {
+ // We need to update metrics here to avoid a crash (#12786)
+ theBufferList().changed(true);
+ return QMainWindow::event(e);
+ }
+
default:
return QMainWindow::event(e);
}
QObject::connect(twa, SIGNAL(lastWorkAreaRemoved()),
this, SLOT(on_lastWorkAreaRemoved()));
- d.splitter_->addWidget(twa);
+ d.splitter_->insertWidget(d.splitter_->indexOf(d.currentTabWorkArea()) + 1,
+ twa);
d.stack_widget_->setCurrentWidget(d.splitter_);
return twa;
}
break;
}
+ case LFUN_CHANGES_TRACK: {
+ if (!doc_buffer) {
+ enable = false;
+ break;
+ }
+ return doc_buffer->getStatus(cmd, flag);
+ }
+
case LFUN_VIEW_SPLIT:
if (cmd.getArg(0) == "vertical")
enable = doc_buffer && (d.splitter_->count() == 1 ||
if (cmd.argument() == "zoomlevel") {
flag.setOnOff(zoom_value_ ? zoom_value_->isVisible() : false);
} else if (cmd.argument() == "zoomslider") {
- flag.setOnOff(zoom_slider_ ? zoom_slider_->isVisible() : false);
+ flag.setOnOff(zoom_widget_ ? zoom_widget_->isVisible() : false);
} else if (cmd.argument() == "statistics-w") {
flag.setOnOff(word_count_enabled_);
} else if (cmd.argument() == "statistics-cb") {
}
-void GuiView::openDocument(string const & fname)
+void GuiView::openDocuments(string const & fname, int origin)
{
string initpath = lyxrc.document_path;
initpath = trypath;
}
- string filename;
+ QStringList files;
if (fname.empty()) {
- FileDialog dlg(qt_("Select document to open"));
+ FileDialog dlg(qt_("Select documents to open"));
dlg.setButton1(qt_("D&ocuments"), toqstr(lyxrc.document_path));
dlg.setButton2(qt_("&Examples"), toqstr(lyxrc.example_path));
QStringList const filter({
qt_("LyX Documents (*.lyx)"),
qt_("LyX Document Backups (*.lyx~)"),
- qt_("All Files (*.*)")
+ qt_("All Files") + " " + wildcardAllFiles()
});
- FileDialog::Result result =
- dlg.open(toqstr(initpath), filter);
+ FileDialog::Results results =
+ dlg.openMulti(toqstr(initpath), filter);
- if (result.first == FileDialog::Later)
+ if (results.first == FileDialog::Later)
return;
- filename = fromqstr(result.second);
+ files = results.second;
// check selected filename
- if (filename.empty()) {
+ if (files.isEmpty()) {
message(_("Canceled."));
return;
}
} else
- filename = fname;
-
- // get absolute path of file and add ".lyx" to the filename if
- // necessary.
- FileName const fullname =
- fileSearch(string(), filename, "lyx", support::may_not_exist);
- if (!fullname.empty())
- filename = fullname.absFileName();
-
- if (!fullname.onlyPath().isDirectory()) {
- Alert::warning(_("Invalid filename"),
- bformat(_("The directory in the given path\n%1$s\ndoes not exist."),
- from_utf8(fullname.absFileName())));
- return;
- }
+ files << toqstr(fname);
+
+ // iterate over all selected files
+ for (auto const & file : files) {
+ string filename = fromqstr(file);
+
+ // get absolute path of file and add ".lyx" to the filename if
+ // necessary.
+ FileName const fullname =
+ fileSearch(string(), filename, "lyx", support::may_not_exist);
+ if (!fullname.empty())
+ filename = fullname.absFileName();
+
+ if (!fullname.onlyPath().isDirectory()) {
+ Alert::warning(_("Invalid filename"),
+ bformat(_("The directory in the given path\n%1$s\ndoes not exist."),
+ from_utf8(fullname.absFileName())));
+ continue;
+ }
- // if the file doesn't exist and isn't already open (bug 6645),
- // let the user create one
- if (!fullname.exists() && !theBufferList().exists(fullname) &&
- !LyXVC::file_not_found_hook(fullname)) {
- // the user specifically chose this name. Believe him.
- Buffer * const b = newFile(filename, string(), true);
- if (b)
- setBuffer(b);
- return;
- }
+ // if the file doesn't exist and isn't already open (bug 6645),
+ // let the user create one
+ if (!fullname.exists() && !theBufferList().exists(fullname) &&
+ !LyXVC::file_not_found_hook(fullname)) {
+ // see bug #12609
+ if (origin == FuncRequest::MENU) {
+ docstring const & msg =
+ bformat(_("File\n"
+ "%1$s\n"
+ "does not exist. Create empty file?"),
+ from_utf8(filename));
+ int ret = Alert::prompt(_("File does not exist"),
+ msg, 0, 1,
+ _("Create &File"),
+ _("&Cancel"));
+ if (ret == 1)
+ continue;
+ }
+ Buffer * const b = newFile(filename, string(), true);
+ if (b)
+ setBuffer(b);
+ continue;
+ }
- docstring const disp_fn = makeDisplayPath(filename);
- message(bformat(_("Opening document %1$s..."), disp_fn));
+ docstring const disp_fn = makeDisplayPath(filename);
+ message(bformat(_("Opening document %1$s..."), disp_fn));
- docstring str2;
- Buffer * buf = loadDocument(fullname);
- if (buf) {
- str2 = bformat(_("Document %1$s opened."), disp_fn);
- if (buf->lyxvc().inUse())
- str2 += " " + from_utf8(buf->lyxvc().versionString()) +
- " " + _("Version control detected.");
- } else {
- str2 = bformat(_("Could not open document %1$s"), disp_fn);
+ docstring str2;
+ Buffer * buf = loadDocument(fullname);
+ if (buf) {
+ str2 = bformat(_("Document %1$s opened."), disp_fn);
+ if (buf->lyxvc().inUse())
+ str2 += " " + from_utf8(buf->lyxvc().versionString()) +
+ " " + _("Version control detected.");
+ } else {
+ str2 = bformat(_("Could not open document %1$s"), disp_fn);
+ }
+ message(str2);
}
- message(str2);
}
// FIXME: clean that
doc_buffer->runChktex();
break;
+ case LFUN_CHANGES_TRACK: {
+ // the actual dispatch is done in Buffer
+ dispatchToBufferView(cmd, dr);
+ // but we inform the GUI (document settings) if this is toggled
+ LASSERT(doc_buffer, break);
+ Q_EMIT changeTrackingToggled(doc_buffer->params().track_changes);
+ break;
+ }
+
case LFUN_COMMAND_EXECUTE: {
command_execute_ = true;
minibuffer_focus_ = true;
FileDialog dlg(qt_("Select file to insert"));
FileDialog::Result result = dlg.open(toqstr(bv->buffer().filePath()),
- QStringList(qt_("All Files (*)")));
+ QStringList(qt_("All Files")+ " " + wildcardAllFiles()));
if (result.first == FileDialog::Later || result.second.isEmpty()) {
dr.setMessage(_("Canceled."));
? Qt::Vertical : Qt::Horizontal);
TabWorkArea * twa = addTabWorkArea();
GuiWorkArea * wa = twa->addWorkArea(*doc_buffer, *this);
+
+ wa->bufferView().copySettingsFrom(*bv);
+ dr.screenUpdate(Update::ForceAll);
setCurrentWorkArea(wa);
break;
}
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);
+ LASSERT(doc_buffer, break);
+ frontend::showTarget(argument, *doc_buffer);
break;
}
} else if (ui_component == "zoomlevel") {
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());
+ zoom_widget_->setVisible(!zoom_widget_->isVisible());
} else if (ui_component == "statistics-w") {
word_count_enabled_ = !word_count_enabled_;
if (statsEnabled())
return dialog;
dialog = build(name);
- d.dialogs_[name].reset(dialog);
- // Force a uniform style for group boxes
- // On Mac non-flat works better, on Linux flat is standard
- flatGroupBoxes(dialog->asQWidget(), guiApp->platformName() != "cocoa");
- if (lyxrc.allow_geometry_session)
- dialog->restoreSession();
- if (hide_it)
- dialog->hideView();
+ if (dialog) {
+
+ d.dialogs_[name].reset(dialog);
+ // Force a uniform style for group boxes
+ // On Mac non-flat works better, on Linux flat is standard
+ flatGroupBoxes(dialog->asQWidget(), guiApp->platformName() != "cocoa");
+ if (lyxrc.allow_geometry_session)
+ dialog->restoreSession();
+ if (hide_it)
+ dialog->hideView();
+ }
return dialog;
}