#include "FileDialog.h"
#include "FontLoader.h"
#include "GuiApplication.h"
+#include "GuiClickableLabel.h"
#include "GuiCommandBuffer.h"
#include "GuiCompleter.h"
#include "GuiKeySymbol.h"
#include "FuncStatus.h"
#include "FuncRequest.h"
#include "Intl.h"
+#include "Language.h"
#include "Layout.h"
+#include "LayoutFile.h"
#include "Lexer.h"
#include "LyXAction.h"
#include "LyX.h"
#include <QMovie>
#include <QPainter>
#include <QPixmap>
-#include <QPixmapCache>
#include <QPoint>
#include <QPushButton>
#include <QScrollBar>
if (!lyxrc.show_banner)
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]]");
+ /// The text to be written on top of the pixmap
QString const text = lyx_version ?
qt_("version ") + lyx_version : qt_("unknown version");
#if QT_VERSION >= 0x050000
QPainter pain(&splash_);
pain.setPen(QColor(0, 0, 0));
qreal const fsize = fontSize();
- QPointF const position = textPosition();
+ bool ok;
+ int hfsize = 20;
+ qreal locscale = htextsize.toFloat(&ok);
+ if (!ok)
+ locscale = 1.0;
+ QPointF const position = textPosition(false);
+ QPointF const hposition = textPosition(true);
+ QRectF const hrect(hposition, splashSize());
LYXERR(Debug::GUI,
"widget pixel ratio: " << pixelRatio() <<
" splash pixel ratio: " << splashPixelRatio() <<
font.setPointSizeF(fsize);
pain.setFont(font);
pain.drawText(position, text);
+ // The font used to display the version info
+ font.setStyleHint(QFont::SansSerif);
+ font.setWeight(QFont::Normal);
+ font.setPointSizeF(hfsize);
+ // 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);
+ // 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);
+ }
+ // The longest line in the reference font (for English)
+ // is 180. Calculate scale factor from that.
+ double const wscale = wline > 0 ? (180.0 / wline) : 1;
+ // Now do the same for the height (necessary for condensed fonts)
+ double const hscale = (34.0 / hline);
+ // take the lower of the two scale factors.
+ double const scale = min(wscale, hscale);
+ // Now rescale. Also consider l7n's offset factor.
+ font.setPointSizeF(hfsize * scale * locscale);
+
+ pain.setFont(font);
+ pain.drawText(hrect, Qt::AlignLeft, htext);
setFocusPolicy(Qt::StrongFocus);
}
/// Current ratio between physical pixels and device-independent pixels
double pixelRatio() const {
#if QT_VERSION >= 0x050000
- return devicePixelRatio();
+ return qt_scale_factor * devicePixelRatio();
#else
return 1.0;
#endif
}
qreal fontSize() const {
- return toqstr(lyxrc.font_sizes[FONT_SIZE_NORMAL]).toDouble();
+ return toqstr(lyxrc.font_sizes[NORMAL_SIZE]).toDouble();
}
- QPointF textPosition() const {
- return QPointF(width_/2 - 18, height_/2 + 45);
+ QPointF textPosition(bool const heading) const {
+ return heading ? QPointF(width_/2 - 18, height_/2 - 45)
+ : QPointF(width_/2 - 18, height_/2 + 45);
}
QSize splashSize() const {
typedef shared_ptr<Dialog> DialogPtr;
-} // namespace anon
+} // namespace
class GuiView::GuiViewPrivate
QSize iconSize(docstring const & icon_size)
{
- int size;
+ unsigned int size;
if (icon_size == "small")
size = smallIconSize;
else if (icon_size == "normal")
static string icon_size;
- int size = qsize.width();
+ unsigned int size = qsize.width();
if (size < smallIconSize)
size = smallIconSize;
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 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);
+ 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,
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);
+ Buffer::ExportStatus (Buffer::*previewFunc)(string const &) const,
+ bool allow_async);
QVector<GuiWorkArea*> guiWorkAreas();
};
GuiView::GuiView(int id)
: d(*new GuiViewPrivate(this)), id_(id), closing_(false), busy_(0),
- command_execute_(false), minibuffer_focus_(false)
+ command_execute_(false), minibuffer_focus_(false), toolbarsMovable_(true),
+ devel_mode_(false)
{
connect(this, SIGNAL(bufferViewChanged()),
this, SLOT(onBufferViewChanged()));
// Start autosave timer
if (lyxrc.autosave) {
- d.autosave_timeout_.timeout.connect(bind(&GuiView::autoSave, this));
+ // The connection is closed when this is destroyed.
+ d.autosave_timeout_.timeout.connect([this](){ autoSave();});
d.autosave_timeout_.setTimeout(lyxrc.autosave * 1000);
d.autosave_timeout_.start();
}
setAcceptDrops(true);
// add busy indicator to statusbar
- QLabel * busylabel = new QLabel(statusBar());
+ GuiClickableLabel * busylabel = new GuiClickableLabel(statusBar());
statusBar()->addPermanentWidget(busylabel);
search_mode mode = theGuiApp()->imageSearchMode();
QString fn = toqstr(lyx::libFileSearch("images", "busy", "gif", mode).absFileName());
busyanim->start();
busylabel->hide();
- connect(&d.processing_thread_watcher_, SIGNAL(started()),
+ connect(&d.processing_thread_watcher_, SIGNAL(started()),
busylabel, SLOT(show()));
- connect(&d.processing_thread_watcher_, SIGNAL(finished()),
+ connect(&d.processing_thread_watcher_, SIGNAL(finished()),
busylabel, SLOT(hide()));
+ connect(busylabel, SIGNAL(clicked()), this, SLOT(checkCancelBackground()));
QFontMetrics const fm(statusBar()->fontMetrics());
- int const roheight = max(int(d.normalIconSize), fm.height());
- QSize const rosize(roheight, roheight);
- QPixmap readonly = QIcon(getPixmap("images/", "emblem-readonly", "svgz,png")).pixmap(rosize);
+ 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 "
+ "external commands for this document. "
+ "Right click to change."));
+ SEMenu * menu = new SEMenu(this);
+ connect(shell_escape_, SIGNAL(customContextMenuRequested(QPoint)),
+ menu, SLOT(showMenu(QPoint)));
+ shell_escape_->hide();
+ statusBar()->addPermanentWidget(shell_escape_);
+
+ QPixmap readonly = QIcon(getPixmap("images/", "emblem-readonly", "svgz,png")).pixmap(iconsize);
read_only_ = new QLabel(statusBar());
read_only_->setPixmap(readonly);
read_only_->setScaledContents(true);
}
+void GuiView::disableShellEscape()
+{
+ BufferView * bv = documentBufferView();
+ if (!bv)
+ return;
+ theSession().shellescapeFiles().remove(bv->buffer().absFileName());
+ bv->buffer().params().shell_escape = false;
+ bv->processUpdateFlags(Update::Force);
+}
+
+
+void GuiView::checkCancelBackground()
+{
+ docstring const ttl = _("Cancel Export?");
+ docstring const msg = _("Do you want to cancel the background export process?");
+ int const ret =
+ Alert::prompt(ttl, msg, 1, 1,
+ _("&Cancel export"), _("Co&ntinue"));
+ if (ret == 0)
+ Systemcall::killscript();
+}
+
+
QVector<GuiWorkArea*> GuiView::GuiViewPrivate::guiWorkAreas()
{
QVector<GuiWorkArea*> areas;
static void handleExportStatus(GuiView * view, Buffer::ExportStatus status,
string const & format)
{
- docstring const fmt = formats.prettyName(format);
+ docstring const fmt = theFormats().prettyName(format);
docstring msg;
switch (status) {
case Buffer::ExportSuccess:
case Buffer::PreviewError:
msg = bformat(_("Error while previewing format: %1$s"), fmt);
break;
+ case Buffer::ExportKilled:
+ msg = bformat(_("Conversion cancelled while previewing format: %1$s"), fmt);
+ break;
}
view->message(msg);
}
Buffer::ExportStatus const status = watcher->result();
handleExportStatus(this, status, d.processing_format);
-
+
updateToolbars();
BufferView const * const bv = currentBufferView();
if (bv && !bv->buffer().errorList("Export").empty()) {
errors("Export");
return;
}
- errors(d.last_export_format);
+
+ bool const error = (status != Buffer::ExportSuccess &&
+ status != Buffer::PreviewSuccess &&
+ status != Buffer::ExportCancel);
+ if (error && bv) {
+ ErrorList & el = bv->buffer().errorList(d.last_export_format);
+ // at this point, we do not know if buffer-view or
+ // master-buffer-view was called. If there was an export error,
+ // and the current buffer's error log is empty, we guess that
+ // it must be master-buffer-view that was called so we set
+ // from_master=true.
+ errors(d.last_export_format, el.empty());
+ }
}
void GuiView::saveLayout() const
{
QSettings settings;
+ settings.setValue("zoom_ratio", zoom_ratio_);
+ settings.setValue("devel_mode", devel_mode_);
settings.beginGroup("views");
settings.beginGroup(QString::number(id_));
#if defined(Q_WS_X11) || defined(QPA_XCB)
void GuiView::saveUISettings() const
{
+ 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();
+ it->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();
+ it->second->saveSession(settings);
}
bool GuiView::restoreLayout()
{
QSettings settings;
+ zoom_ratio_ = settings.value("zoom_ratio", 1.0).toDouble();
+ // Actual zoom value: default zoom + fractional offset
+ int zoom = lyxrc.defaultZoom * zoom_ratio_;
+ if (zoom < static_cast<int>(zoom_min_))
+ zoom = zoom_min_;
+ lyxrc.currentZoom = zoom;
+ devel_mode_ = settings.value("devel_mode", devel_mode_).toBool();
settings.beginGroup("views");
settings.beginGroup(QString::number(id_));
QString const icon_key = "icon_size";
if (!restoreState(settings.value("layout").toByteArray(), 0))
initToolbars();
-
+
// init the toolbars that have not been restored
Toolbars::Infos::iterator cit = guiApp->toolbars().begin();
Toolbars::Infos::iterator end = guiApp->toolbars().end();
initToolbar(cit->name);
}
+ // update lock (all) toolbars positions
+ updateLockToolbars();
+
updateDialogs();
return true;
}
}
+void GuiView::updateLockToolbars()
+{
+ toolbarsMovable_ = false;
+ for (ToolbarInfo const & info : guiApp->toolbars()) {
+ GuiToolbar * tb = toolbar(info.name);
+ if (tb && tb->isMovable())
+ toolbarsMovable_ = true;
+ }
+}
+
+
void GuiView::constructToolbars()
{
ToolbarMap::iterator it = d.toolbars_.begin();
if (visibility & Toolbars::ON)
tb->setVisible(true);
+
+ tb->setMovable(true);
}
LYXERR(Debug::DEBUG, "GuiView::closeEvent()");
if (!GuiViewPrivate::busyBuffers.isEmpty()) {
- Alert::warning(_("Exit LyX"),
+ Alert::warning(_("Exit LyX"),
_("LyX could not be closed because documents are being processed by LyX."));
close_event->setAccepted(false);
return;
Buffer const & buf = wa->bufferView().buffer();
// Set the windows title
docstring title = buf.fileName().displayName(130) + from_ascii("[*]");
+ if (buf.notifiesExternalModification()) {
+ title = bformat(_("%1$s (modified externally)"), title);
+ // If the external modification status has changed, then maybe the status of
+ // buffer-save has changed too.
+ updateToolbars();
+ }
#ifndef Q_WS_MAC
title += from_ascii(" - LyX");
#endif
// Tell Qt whether the current document is changed
setWindowModified(!buf.isClean());
- if (buf.isReadonly())
+ if (buf.params().shell_escape)
+ shell_escape_->show();
+ else
+ shell_escape_->hide();
+
+ if (buf.hasReadonlyFlag())
read_only_->show();
else
read_only_->hide();
if (msg.isEmpty()) {
BufferView const * bv = currentBufferView();
if (bv)
- msg = toqstr(bv->cursor().currentState());
+ msg = toqstr(bv->cursor().currentState(devel_mode_));
else
msg = qt_("Welcome to LyX!");
}
return;
}
QApplication::restoreOverrideCursor();
- updateLayoutList();
+ updateLayoutList();
}
double GuiView::pixelRatio() const
{
#if QT_VERSION >= 0x050000
- return devicePixelRatio();
+ return qt_scale_factor * devicePixelRatio();
#else
return 1.0;
#endif
}
-
-
+
+
GuiWorkArea * GuiView::workArea(int index)
{
if (TabWorkArea * twa = d.currentTabWorkArea())
if (index < twa->count())
- return dynamic_cast<GuiWorkArea *>(twa->widget(index));
+ return twa->workArea(index);
return 0;
}
theGuiApp()->setCurrentView(this);
d.current_work_area_ = wa;
-
+
// We need to reset this now, because it will need to be
// right if the tabWorkArea gets reset in the for loop. We
// will change it back if we aren't in that case.
for (int i = 0; i != d.splitter_->count(); ++i) {
if (d.tabWorkArea(i)->setCurrentWorkArea(wa)) {
- LYXERR(Debug::DEBUG, "Current wa: " << currentWorkArea()
+ LYXERR(Debug::DEBUG, "Current wa: " << currentWorkArea()
<< ", Current main wa: " << currentMainWorkArea());
return;
}
}
-
+
d.current_main_work_area_ = old_cmwa;
-
+
LYXERR(Debug::DEBUG, "This is not a tabbed wa");
on_currentWorkAreaChanged(wa);
BufferView & bv = wa->bufferView();
}
-void GuiView::setBuffer(Buffer * newBuffer)
+void GuiView::setBuffer(Buffer * newBuffer, bool switch_to)
{
LYXERR(Debug::DEBUG, "Setting buffer: " << newBuffer << endl);
LASSERT(newBuffer, return);
-
+
GuiWorkArea * wa = workArea(*newBuffer);
if (wa == 0) {
setBusy(true);
}
connectBuffer(*newBuffer);
connectBufferView(wa->bufferView());
- setCurrentWorkArea(wa);
+ if (switch_to)
+ setCurrentWorkArea(wa);
}
if (!bv)
return;
-#if EXPORT_in_THREAD
- // We are called with from_master == false by default, so we
- // have to figure out whether that is the case or not.
- ErrorList & el = bv->buffer().errorList(error_type);
- if (el.empty()) {
- el = bv->buffer().masterBuffer()->errorList(error_type);
- from_master = true;
- }
-#else
ErrorList const & el = from_master ?
bv->buffer().masterBuffer()->errorList(error_type) :
bv->buffer().errorList(error_type);
-#endif
if (el.empty())
return;
- string data = error_type;
+ string err = error_type;
if (from_master)
- data = "from_master|" + error_type;
- showDialog("errorlist", data);
+ err = "from_master|" + error_type;
+ showDialog("errorlist", err);
}
void GuiView::structureChanged()
{
+ // This is called from the Buffer, which has no way to ensure that cursors
+ // in BufferView remain valid.
+ if (documentBufferView())
+ documentBufferView()->cursor().sanitize();
// FIXME: This is slightly expensive, though less than the tocBackend update
// (#9880). This also resets the view in the Toc Widget (#6675).
d.toc_models_.reset(documentBufferView());
}
-void GuiView::updateDialog(string const & name, string const & data)
+void GuiView::updateDialog(string const & name, string const & sdata)
{
if (!isDialogVisible(name))
return;
Dialog * const dialog = it->second.get();
if (dialog->isVisibleView())
- dialog->initialiseParams(data);
+ dialog->initialiseParams(sdata);
}
case LFUN_BUFFER_IMPORT:
break;
+ case LFUN_MASTER_BUFFER_EXPORT:
+ enable = doc_buffer
+ && (doc_buffer->parent() != 0
+ || doc_buffer->hasChildren())
+ && !d.processing_thread_watcher_.isRunning()
+ // this launches a dialog, which would be in the wrong Buffer
+ && !(::lyx::operator==(cmd.argument(), "custom"));
+ break;
+
case LFUN_MASTER_BUFFER_UPDATE:
case LFUN_MASTER_BUFFER_VIEW:
enable = doc_buffer
case LFUN_BUFFER_RELOAD:
enable = doc_buffer && !doc_buffer->isUnnamed()
&& doc_buffer->fileName().exists()
- && (!doc_buffer->isClean()
- || doc_buffer->isExternallyModified(Buffer::timestamp_method));
+ && (!doc_buffer->isClean() || doc_buffer->notifiesExternalModification());
break;
case LFUN_BUFFER_CHILD_OPEN:
break;
}
- case LFUN_BUFFER_WRITE_AS:
+ case LFUN_BUFFER_EXTERNAL_MODIFICATION_CLEAR:
+ enable = doc_buffer && doc_buffer->notifiesExternalModification();
+ break;
+
+ case LFUN_BUFFER_EXPORT: {
+ if (!doc_buffer || d.processing_thread_watcher_.isRunning()) {
+ enable = false;
+ break;
+ }
+ return doc_buffer->getStatus(cmd, flag);
+ break;
+ }
+
case LFUN_BUFFER_EXPORT_AS:
+ if (!doc_buffer || d.processing_thread_watcher_.isRunning()) {
+ enable = false;
+ break;
+ }
+ // fall through
+ case LFUN_BUFFER_WRITE_AS:
+ case LFUN_BUFFER_WRITE_AS_TEMPLATE:
enable = doc_buffer != 0;
break;
+ case LFUN_EXPORT_CANCEL:
+ enable = d.processing_thread_watcher_.isRunning();
+ break;
+
case LFUN_BUFFER_CLOSE:
case LFUN_VIEW_CLOSE:
enable = doc_buffer != 0;
enable = theBufferList().last() != theBufferList().first();
break;
+ case LFUN_BUFFER_CHKTEX: {
+ // hide if we have no checktex command
+ if (lyxrc.chktex_command.empty()) {
+ flag.setUnknown(true);
+ enable = false;
+ break;
+ }
+ if (!doc_buffer || !doc_buffer->params().isLatex()
+ || d.processing_thread_watcher_.isRunning()) {
+ // grey out, don't hide
+ enable = false;
+ break;
+ }
+ enable = true;
+ break;
+ }
+
case LFUN_VIEW_SPLIT:
if (cmd.getArg(0) == "vertical")
enable = doc_buffer && (d.splitter_->count() == 1 ||
enable = d.tabWorkAreaCount() > 1;
break;
+ case LFUN_DEVEL_MODE_TOGGLE:
+ flag.setOnOff(devel_mode_);
+ break;
+
case LFUN_TOOLBAR_TOGGLE: {
string const name = cmd.getArg(0);
if (GuiToolbar * t = toolbar(name))
break;
}
+ case LFUN_TOOLBAR_MOVABLE: {
+ string const name = cmd.getArg(0);
+ // use negation since locked == !movable
+ if (name == "*")
+ // toolbar name * locks all toolbars
+ flag.setOnOff(!toolbarsMovable_);
+ else if (GuiToolbar * t = toolbar(name))
+ flag.setOnOff(!(t->isMovable()));
+ else {
+ enable = false;
+ docstring const msg =
+ bformat(_("Unknown toolbar \"%1$s\""), from_utf8(name));
+ flag.message(msg);
+ }
+ break;
+ }
+
case LFUN_ICON_SIZE:
flag.setOnOff(d.iconSize(cmd.argument()) == iconSize());
break;
case LFUN_DIALOG_TOGGLE:
flag.setOnOff(isDialogVisible(cmd.getArg(0)));
- // fall through to set "enable"
+ // to set "enable"
+ // fall through
case LFUN_DIALOG_SHOW: {
string const name = cmd.getArg(0);
if (!doc_buffer)
enable = name == "aboutlyx"
|| name == "file" //FIXME: should be removed.
+ || name == "lyxfiles"
|| name == "prefs"
|| name == "texinfo"
|| name == "progress"
else if (name == "latexlog")
enable = FileName(doc_buffer->logName()).isReadableFile();
else if (name == "spellchecker")
- enable = theSpellChecker()
+ enable = theSpellChecker()
&& !doc_buffer->isReadonly()
&& !doc_buffer->text().empty();
else if (name == "vclog")
bool const neg_zoom =
convert<int>(cmd.argument()) < 0 ||
(cmd.action() == LFUN_BUFFER_ZOOM_OUT && cmd.argument().empty());
- if (lyxrc.zoom <= zoom_min_ && neg_zoom) {
+ if (lyxrc.currentZoom <= zoom_min_ && neg_zoom) {
docstring const msg =
bformat(_("Zoom level cannot be less than %1$d%."), zoom_min_);
flag.message(msg);
enable = doc_buffer;
break;
}
+
+ case LFUN_BUFFER_ZOOM: {
+ bool const less_than_min_zoom =
+ !cmd.argument().empty() && convert<int>(cmd.argument()) < zoom_min_;
+ if (lyxrc.currentZoom <= zoom_min_ && less_than_min_zoom) {
+ docstring const msg =
+ bformat(_("Zoom level cannot be less than %1$d%."), zoom_min_);
+ flag.message(msg);
+ enable = false;
+ }
+ else
+ enable = doc_buffer;
+ break;
+ }
+
case LFUN_BUFFER_MOVE_NEXT:
case LFUN_BUFFER_MOVE_PREVIOUS:
// we do not cycle when moving
enable = doc_buffer && doc_buffer->lyxvc().checkOutEnabled();
break;
case LFUN_VC_LOCKING_TOGGLE:
- enable = doc_buffer && !doc_buffer->isReadonly()
+ enable = doc_buffer && !doc_buffer->hasReadonlyFlag()
&& doc_buffer->lyxvc().lockingToggleEnabled();
flag.setOnOff(enable && doc_buffer->lyxvc().locking());
break;
case LFUN_VC_REVERT:
- enable = doc_buffer && doc_buffer->lyxvc().inUse() && !doc_buffer->isReadonly();
+ enable = doc_buffer && doc_buffer->lyxvc().inUse()
+ && !doc_buffer->hasReadonlyFlag();
break;
case LFUN_VC_UNDO_LAST:
enable = doc_buffer && doc_buffer->lyxvc().undoLastEnabled();
static FileName selectTemplateFile()
{
FileDialog dlg(qt_("Select template file"));
- dlg.setButton1(qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
- dlg.setButton2(qt_("Templates|#T#t"), toqstr(lyxrc.template_path));
+ dlg.setButton1(qt_("D&ocuments"), toqstr(lyxrc.document_path));
+ dlg.setButton2(qt_("&Templates"), toqstr(lyxrc.template_path));
FileDialog::Result result = dlg.open(toqstr(lyxrc.template_path),
QStringList(qt_("LyX Documents (*.lyx)")));
setBuffer(newBuffer);
newBuffer->errors("Parse");
- if (tolastfiles)
+ if (tolastfiles) {
theSession().lastFiles().add(filename);
+ theSession().writeFile();
+ }
return newBuffer;
}
if (fname.empty()) {
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")));
+ dlg.setButton1(qt_("D&ocuments"), toqstr(lyxrc.document_path));
+ dlg.setButton2(qt_("&Examples"), toqstr(lyxrc.example_path));
QStringList const filter(qt_("LyX Documents (*.lyx)"));
FileDialog::Result result =
string const tofile =
support::changeExtension(filename.absFileName(),
- formats.extension(*it));
- if (!theConverters().convert(0, filename, FileName(tofile),
- filename, format, *it, errorList))
+ theFormats().extension(*it));
+ if (theConverters().convert(0, filename, FileName(tofile),
+ filename, format, *it, errorList) != Converters::SUCCESS)
return false;
loader_format = *it;
break;
if (loader_format.empty()) {
frontend::Alert::error(_("Couldn't import file"),
bformat(_("No information for importing the format %1$s."),
- formats.prettyName(format)));
+ theFormats().prettyName(format)));
return false;
}
} else
bool as_paragraphs = loader_format == "textparagraph";
string filename2 = (loader_format == format) ? filename.absFileName()
: support::changeExtension(filename.absFileName(),
- formats.extension(loader_format));
+ theFormats().extension(loader_format));
lv->currentBufferView()->insertPlaintextFile(FileName(filename2),
as_paragraphs);
guiApp->setCurrentView(lv);
}
docstring const text = bformat(_("Select %1$s file to import"),
- formats.prettyName(format));
+ theFormats().prettyName(format));
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")));
+ dlg.setButton1(qt_("D&ocuments"), toqstr(lyxrc.document_path));
+ dlg.setButton2(qt_("&Examples"), toqstr(lyxrc.example_path));
- docstring filter = formats.prettyName(format);
+ docstring filter = theFormats().prettyName(format);
filter += " (*.{";
// FIXME UNICODE
- filter += from_utf8(formats.extensions(format));
+ filter += from_utf8(theFormats().extensions(format));
filter += "})";
FileDialog::Result result =
}
-void GuiView::newDocument(string const & filename, bool from_template)
+void GuiView::newDocument(string const & filename, string templatefile,
+ bool from_template)
{
FileName initpath(lyxrc.document_path);
if (documentBufferView()) {
initpath = trypath;
}
- string templatefile;
if (from_template) {
- templatefile = selectTemplateFile().absFileName();
+ if (templatefile.empty())
+ templatefile = selectTemplateFile().absFileName();
if (templatefile.empty())
return;
}
}
-void GuiView::insertLyXFile(docstring const & fname)
+void GuiView::insertLyXFile(docstring const & fname, bool ignorelang)
{
BufferView * bv = documentBufferView();
if (!bv)
// FIXME UNICODE
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(),
- "examples")));
+ dlg.setButton1(qt_("D&ocuments"), toqstr(lyxrc.document_path));
+ dlg.setButton2(qt_("&Examples"), toqstr(lyxrc.example_path));
FileDialog::Result result = dlg.open(toqstr(initpath),
QStringList(qt_("LyX Documents (*.lyx)")));
}
}
- bv->insertLyXFile(filename);
+ bv->insertLyXFile(filename, ignorelang);
bv->buffer().errors("Parse");
}
+string const GuiView::getTemplatesPath(Buffer & b)
+{
+ // We start off with the user's templates path
+ string result = addPath(package().user_support().absFileName(), "templates");
+ // Check for the document language
+ string const langcode = b.params().language->code();
+ string const shortcode = langcode.substr(0, 2);
+ if (!langcode.empty() && shortcode != "en") {
+ string subpath = addPath(result, shortcode);
+ string subpath_long = addPath(result, langcode);
+ // If we have a subdirectory for the language already,
+ // navigate there
+ FileName sp = FileName(subpath);
+ if (sp.isDirectory())
+ result = subpath;
+ else if (FileName(subpath_long).isDirectory())
+ result = subpath_long;
+ else {
+ // Ask whether we should create such a subdirectory
+ docstring const text =
+ bformat(_("It is suggested to save the template in a subdirectory\n"
+ "appropriate to the document language (%1$s).\n"
+ "This subdirectory does not exists yet.\n"
+ "Do you want to create it?"),
+ _(b.params().language->display()));
+ if (Alert::prompt(_("Create Language Directory?"),
+ text, 0, 1, _("&Yes, Create"), _("&No, Save Template in Parent Directory")) == 0) {
+ // If the user agreed, we try to create it and report if this failed.
+ if (!sp.createDirectory(0777))
+ Alert::error(_("Subdirectory creation failed!"),
+ _("Could not create subdirectory.\n"
+ "The template will be saved in the parent directory."));
+ else
+ result = subpath;
+ }
+ }
+ }
+ // Do we have a layout category?
+ string const cat = b.params().baseClass() ?
+ b.params().baseClass()->category()
+ : string();
+ if (!cat.empty()) {
+ string subpath = addPath(result, cat);
+ // If we have a subdirectory for the category already,
+ // navigate there
+ FileName sp = FileName(subpath);
+ if (sp.isDirectory())
+ result = subpath;
+ else {
+ // Ask whether we should create such a subdirectory
+ docstring const text =
+ bformat(_("It is suggested to save the template in a subdirectory\n"
+ "appropriate to the layout category (%1$s).\n"
+ "This subdirectory does not exists yet.\n"
+ "Do you want to create it?"),
+ _(cat));
+ if (Alert::prompt(_("Create Category Directory?"),
+ text, 0, 1, _("&Yes, Create"), _("&No, Save Template in Parent Directory")) == 0) {
+ // If the user agreed, we try to create it and report if this failed.
+ if (!sp.createDirectory(0777))
+ Alert::error(_("Subdirectory creation failed!"),
+ _("Could not create subdirectory.\n"
+ "The template will be saved in the parent directory."));
+ else
+ result = subpath;
+ }
+ }
+ }
+ return result;
+}
+
+
bool GuiView::renameBuffer(Buffer & b, docstring const & newname, RenameKind kind)
{
FileName fname = b.fileName();
FileName const oldname = fname;
+ bool const as_template = (kind == LV_WRITE_AS_TEMPLATE);
if (!newname.empty()) {
// FIXME UNICODE
- fname = support::makeAbsPath(to_utf8(newname), oldname.onlyPath().absFileName());
+ if (as_template)
+ fname = support::makeAbsPath(to_utf8(newname), getTemplatesPath(b));
+ else
+ fname = support::makeAbsPath(to_utf8(newname),
+ oldname.onlyPath().absFileName());
} else {
// Switch to this Buffer.
setBuffer(&b);
// No argument? Ask user through dialog.
// FIXME UNICODE
- 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));
+ QString const title = as_template ? qt_("Choose a filename to save template as")
+ : qt_("Choose a filename to save document as");
+ FileDialog dlg(title);
+ dlg.setButton1(qt_("D&ocuments"), toqstr(lyxrc.document_path));
+ dlg.setButton2(qt_("&Templates"), toqstr(lyxrc.template_path));
if (!isLyXFileName(fname.absFileName()))
fname.changeExtension(".lyx");
+ string const path = as_template ?
+ getTemplatesPath(b)
+ : fname.onlyPath().absFileName();
FileDialog::Result result =
- dlg.save(toqstr(fname.onlyPath().absFileName()),
+ dlg.save(toqstr(path),
QStringList(qt_("LyX Documents (*.lyx)")),
toqstr(fname.onlyFileName()));
break;
}
case LV_WRITE_AS:
+ case LV_WRITE_AS_TEMPLATE:
break;
}
// LyXVC created the file already in case of LV_VC_RENAME or
FileName fname = b.fileName();
FileDialog dlg(qt_("Choose a filename to export the document as"));
- dlg.setButton1(qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
+ dlg.setButton1(qt_("D&ocuments"), toqstr(lyxrc.document_path));
QStringList types;
QString const anyformat = qt_("Guess from extension (*.*)");
types << anyformat;
vector<Format const *> export_formats;
- for (Format const & f : formats)
+ for (Format const & f : theFormats())
if (f.documentFormat())
export_formats.push_back(&f);
sort(export_formats.begin(), export_formats.end(), Format::formatSorter);
string fmt_name;
fname.set(fromqstr(result.second));
if (filter == anyformat)
- fmt_name = formats.getFormatFromExtension(fname.extension());
+ fmt_name = theFormats().getFormatFromExtension(fname.extension());
else
fmt_name = fmap[filter];
LYXERR(Debug::FILES, "filter=" << fromqstr(filter)
bool const success = (fn.empty() ? b.save() : b.saveAs(fn));
if (success) {
theSession().lastFiles().add(b.fileName());
+ theSession().writeFile();
return true;
}
for (int i = 0; i < d.splitter_->count(); ++i) {
TabWorkArea * twa = d.tabWorkArea(i);
for (int j = 0; j < twa->count(); ++j) {
- GuiWorkArea * wa = static_cast<GuiWorkArea *>(twa->widget(j));
+ GuiWorkArea * wa = twa->workArea(j);
Buffer & buf = wa->bufferView().buffer();
theSession().lastOpened().add(buf.fileName(), wa == active_wa);
}
Buffer & buf = wa->bufferView().buffer();
if (GuiViewPrivate::busyBuffers.contains(&buf)) {
- Alert::warning(_("Close document"),
+ Alert::warning(_("Close document"),
_("Document could not be closed because it is being processed by LyX."));
return false;
}
bool GuiView::closeBuffer(Buffer & buf)
{
- // 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.
bool success = true;
- if (!closing_) {
- 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;
- if (theBufferList().isOthersChild(&buf, child_buf)) {
- child_buf->setParent(0);
- continue;
- }
+ 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;
+ if (theBufferList().isOthersChild(&buf, child_buf)) {
+ child_buf->setParent(0);
+ continue;
+ }
- // FIXME: should we look in other tabworkareas?
- // ANSWER: I don't think so. I've tested, and if the child is
- // open in some other window, it closes without a problem.
- GuiWorkArea * child_wa = workArea(*child_buf);
- if (child_wa) {
- success = closeWorkArea(child_wa, true);
- if (!success)
- break;
- } else {
- // In this case the child buffer is open but hidden.
- // It therefore should not (MUST NOT) be dirty!
- LATTEST(child_buf->isClean());
+ // FIXME: should we look in other tabworkareas?
+ // ANSWER: I don't think so. I've tested, and if the child is
+ // open in some other window, it closes without a problem.
+ GuiWorkArea * child_wa = workArea(*child_buf);
+ if (child_wa) {
+ if (closing_)
+ // 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;
+ success = closeWorkArea(child_wa, true);
+ if (!success)
+ break;
+ } else {
+ // In this case the child buffer is open but hidden.
+ // 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 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();
theBufferList().release(child_buf);
+ } else {
+ // Saving of dirty children has been cancelled.
+ // Cancel the whole process.
+ success = false;
+ break;
}
}
}
setBuffer(&buf);
docstring file;
+ bool exists;
// FIXME: Unicode?
- if (buf.isUnnamed())
+ if (buf.isUnnamed()) {
file = from_utf8(buf.fileName().onlyFileName());
- else
- file = buf.fileName().displayName(30);
+ exists = false;
+ } else {
+ FileName filename = buf.fileName();
+ filename.refresh();
+ file = filename.displayName(30);
+ exists = filename.exists();
+ }
// Bring this window to top before asking questions.
raise();
if (ret == 1)
++ret;
} else {
- docstring const text = bformat(_("The document %1$s has unsaved changes."
- "\n\nDo you want to save the document or discard the changes?"), file);
- ret = Alert::prompt(_("Save changed document?"),
- text, 0, 2, _("&Save"), _("&Discard"), _("&Cancel"));
+ docstring const text = exists ?
+ bformat(_("The document %1$s has unsaved changes."
+ "\n\nDo you want to save the document or "
+ "discard the changes?"), file) :
+ bformat(_("The document %1$s has not been saved yet."
+ "\n\nDo you want to save the document or "
+ "discard it entirely?"), file);
+ docstring const title = exists ?
+ _("Save changed document?") : _("Save document?");
+ ret = Alert::prompt(title, text, 0, 2,
+ _("&Save"), _("&Discard"), _("&Cancel"));
}
switch (ret) {
{
if (!documentBufferView())
return;
-
+
if (TabWorkArea * twa = d.currentTabWorkArea()) {
Buffer * const curbuf = &documentBufferView()->buffer();
int nwa = twa->count();
bool GuiView::reloadBuffer(Buffer & buf)
{
+ currentBufferView()->cursor().reset();
Buffer::ReadStatus status = buf.reload();
return status == Buffer::ReadSuccess;
}
BufferList::iterator const bend = theBufferList().end();
for (; bit != bend; ++bit) {
Buffer * buf = *bit;
- if (buf->fileName().exists()
- && buf->isExternallyModified(Buffer::checksum_method)) {
+ 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."),
from_utf8(buf->absFileName()));
case LFUN_VC_COPY: {
if (!buffer || !ensureBufferClean(buffer))
break;
- if (buffer->lyxvc().inUse() && !buffer->isReadonly()) {
+ if (buffer->lyxvc().inUse() && !buffer->hasReadonlyFlag()) {
if (buffer->lyxvc().isCheckInWithConfirmation()) {
// Some changes are not yet committed.
// We test here and not in getStatus(), since
case LFUN_VC_CHECK_IN:
if (!buffer || !ensureBufferClean(buffer))
break;
- if (buffer->lyxvc().inUse() && !buffer->isReadonly()) {
+ if (buffer->lyxvc().inUse() && !buffer->hasReadonlyFlag()) {
string log;
LyXVC::CommandResult ret = buffer->lyxvc().checkIn(log);
dr.setMessage(log);
case LFUN_VC_LOCKING_TOGGLE:
LASSERT(buffer, return);
- if (!ensureBufferClean(buffer) || buffer->isReadonly())
+ if (!ensureBufferClean(buffer) || buffer->hasReadonlyFlag())
break;
if (buffer->lyxvc().inUse()) {
string res = buffer->lyxvc().lockingToggle();
string rev1 = cmd.getArg(0);
string f1, f2;
+ LATTEST(buffer)
// f1
- // it seems safe to assume we have a buffer
- // coverity[FORWARD_NULL]
if (!buffer->lyxvc().prepareFileRevision(rev1, f1))
break;
bool GuiView::goToFileRow(string const & argument)
{
string file_name;
- int row;
+ int row = -1;
size_t i = argument.find_last_of(' ');
if (i != string::npos) {
file_name = os::internal_path(trim(argument.substr(0, i)));
}
-void GuiView::toolBarPopup(const QPoint & pos)
+void GuiView::toolBarPopup(const QPoint & /*pos*/)
{
- QMenu * menu = new QMenu;
- menu = guiApp->menus().menu(toqstr("context-toolbars"), * this);
+ QMenu * menu = guiApp->menus().menu(toqstr("context-toolbars"), * this);
menu->exec(QCursor::pos());
}
template<class T>
-Buffer::ExportStatus GuiView::GuiViewPrivate::runAndDestroy(const T& func, Buffer const * orig, Buffer * clone, string const & format)
+Buffer::ExportStatus GuiView::GuiViewPrivate::runAndDestroy(const T& func,
+ Buffer const * orig, Buffer * clone, string const & format)
{
Buffer::ExportStatus const status = func(format);
}
-Buffer::ExportStatus GuiView::GuiViewPrivate::compileAndDestroy(Buffer const * orig, Buffer * clone, string const & format)
+Buffer::ExportStatus GuiView::GuiViewPrivate::compileAndDestroy(
+ Buffer const * orig, Buffer * clone, string const & format)
{
- Buffer::ExportStatus (Buffer::* mem_func)(std::string const &, bool) const = &Buffer::doExport;
+ Buffer::ExportStatus (Buffer::* mem_func)(std::string const &, bool) const =
+ &Buffer::doExport;
return runAndDestroy(lyx::bind(mem_func, clone, _1, true), orig, clone, format);
}
-Buffer::ExportStatus GuiView::GuiViewPrivate::exportAndDestroy(Buffer const * orig, Buffer * clone, string const & format)
+Buffer::ExportStatus GuiView::GuiViewPrivate::exportAndDestroy(
+ Buffer const * orig, Buffer * clone, string const & format)
{
- Buffer::ExportStatus (Buffer::* mem_func)(std::string const &, bool) const = &Buffer::doExport;
+ Buffer::ExportStatus (Buffer::* mem_func)(std::string const &, bool) const =
+ &Buffer::doExport;
return runAndDestroy(lyx::bind(mem_func, clone, _1, false), orig, clone, format);
}
-Buffer::ExportStatus GuiView::GuiViewPrivate::previewAndDestroy(Buffer const * orig, Buffer * clone, string const & format)
+Buffer::ExportStatus GuiView::GuiViewPrivate::previewAndDestroy(
+ Buffer const * orig, Buffer * clone, string const & format)
{
- Buffer::ExportStatus (Buffer::* mem_func)(std::string const &) const = &Buffer::preview;
+ Buffer::ExportStatus (Buffer::* mem_func)(std::string const &) const =
+ &Buffer::preview;
return runAndDestroy(lyx::bind(mem_func, clone, _1), orig, clone, format);
}
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)
+ Buffer::ExportStatus (Buffer::*previewFunc)(string const &) const,
+ bool allow_async)
{
if (!used_buffer)
return false;
gv_->message(msg);
}
#if EXPORT_in_THREAD
- GuiViewPrivate::busyBuffers.insert(used_buffer);
- Buffer * cloned_buffer = used_buffer->cloneFromMaster();
- if (!cloned_buffer) {
- Alert::error(_("Export Error"),
- _("Error cloning the Buffer."));
- return false;
+ if (allow_async) {
+ GuiViewPrivate::busyBuffers.insert(used_buffer);
+ Buffer * cloned_buffer = used_buffer->cloneWithChildren();
+ if (!cloned_buffer) {
+ Alert::error(_("Export Error"),
+ _("Error cloning the Buffer."));
+ return false;
+ }
+ QFuture<Buffer::ExportStatus> f = QtConcurrent::run(
+ asyncFunc,
+ used_buffer,
+ cloned_buffer,
+ format);
+ setPreviewFuture(f);
+ last_export_format = used_buffer->params().bufferFormat();
+ (void) syncFunc;
+ (void) previewFunc;
+ // We are asynchronous, so we don't know here anything about the success
+ return true;
+ } else {
+ Buffer::ExportStatus status;
+ if (syncFunc) {
+ status = (used_buffer->*syncFunc)(format, false);
+ } else if (previewFunc) {
+ status = (used_buffer->*previewFunc)(format);
+ } else
+ return false;
+ handleExportStatus(gv_, status, format);
+ (void) asyncFunc;
+ return (status == Buffer::ExportSuccess
+ || status == Buffer::PreviewSuccess);
}
- QFuture<Buffer::ExportStatus> f = QtConcurrent::run(
- asyncFunc,
- used_buffer,
- cloned_buffer,
- format);
- setPreviewFuture(f);
- last_export_format = used_buffer->params().bufferFormat();
- (void) syncFunc;
- (void) previewFunc;
- // We are asynchronous, so we don't know here anything about the success
- return true;
#else
+ (void) allow_async;
Buffer::ExportStatus status;
if (syncFunc) {
status = (used_buffer->*syncFunc)(format, true);
} else if (previewFunc) {
- status = (used_buffer->*previewFunc)(format);
+ status = (used_buffer->*previewFunc)(format);
} else
return false;
handleExportStatus(gv_, status, format);
(void) asyncFunc;
- return (status == Buffer::ExportSuccess
+ return (status == Buffer::ExportSuccess
|| status == Buffer::PreviewSuccess);
#endif
}
// Let the current BufferView dispatch its own actions.
bv->dispatch(cmd, dr);
- if (dr.dispatched())
+ if (dr.dispatched()) {
+ if (cmd.action() == LFUN_REDO || cmd.action() == LFUN_UNDO)
+ updateDialog("document", "");
return;
+ }
// Try with the document BufferView dispatch if any.
BufferView * doc_bv = documentBufferView();
if (doc_bv && doc_bv != bv) {
doc_bv->dispatch(cmd, dr);
- if (dr.dispatched())
+ if (dr.dispatched()) {
+ if (cmd.action() == LFUN_REDO || cmd.action() == LFUN_UNDO)
+ updateDialog("document", "");
return;
+ }
}
// Then let the current Cursor dispatch its own actions.
importDocument(to_utf8(cmd.argument()));
break;
+ case LFUN_MASTER_BUFFER_EXPORT:
+ if (doc_buffer)
+ doc_buffer = const_cast<Buffer *>(doc_buffer->masterBuffer());
+ // fall through
case LFUN_BUFFER_EXPORT: {
if (!doc_buffer)
break;
// GCC only sees strfwd.h when building merged
if (::lyx::operator==(cmd.argument(), "custom")) {
+ // LFUN_MASTER_BUFFER_EXPORT is not enabled for this case,
+ // so the following test should not be needed.
+ // In principle, we could try to switch to such a view...
+ // if (cmd.action() == LFUN_BUFFER_EXPORT)
dispatch(FuncRequest(LFUN_DIALOG_SHOW, "sendto"), dr);
break;
}
else
target_dir = doc_buffer->fileName().onlyPath();
+ string const format = (argument.empty() || argument == "default") ?
+ doc_buffer->params().getDefaultOutputFormat() : argument;
+
if ((dest.empty() && doc_buffer->isUnnamed())
|| !target_dir.isDirWritable()) {
- exportBufferAs(*doc_buffer, cmd.argument());
+ exportBufferAs(*doc_buffer, from_utf8(format));
break;
}
/* TODO/Review: Is it a problem to also export the children?
See the update_unincluded flag */
- d.asyncBufferProcessing(argument,
+ d.asyncBufferProcessing(format,
doc_buffer,
_("Exporting ..."),
&GuiViewPrivate::exportAndDestroy,
&Buffer::doExport,
- 0);
+ 0, cmd.allowAsync());
// TODO Inform user about success
break;
}
_("Exporting ..."),
&GuiViewPrivate::compileAndDestroy,
&Buffer::doExport,
- 0);
+ 0, cmd.allowAsync());
break;
}
case LFUN_BUFFER_VIEW: {
_("Previewing ..."),
&GuiViewPrivate::previewAndDestroy,
0,
- &Buffer::preview);
+ &Buffer::preview, cmd.allowAsync());
break;
}
case LFUN_MASTER_BUFFER_UPDATE: {
docstring(),
&GuiViewPrivate::compileAndDestroy,
&Buffer::doExport,
- 0);
+ 0, cmd.allowAsync());
break;
}
case LFUN_MASTER_BUFFER_VIEW: {
(doc_buffer ? doc_buffer->masterBuffer() : 0),
docstring(),
&GuiViewPrivate::previewAndDestroy,
- 0, &Buffer::preview);
+ 0, &Buffer::preview, cmd.allowAsync());
+ break;
+ }
+ case LFUN_EXPORT_CANCEL: {
+ Systemcall::killscript();
break;
}
case LFUN_BUFFER_SWITCH: {
gotoNextOrPreviousBuffer(PREVBUFFER, true);
break;
+ case LFUN_BUFFER_CHKTEX:
+ LASSERT(doc_buffer, break);
+ doc_buffer->runChktex();
+ break;
+
case LFUN_COMMAND_EXECUTE: {
command_execute_ = true;
minibuffer_focus_ = true;
menu->exec(QCursor::pos());
break;
- case LFUN_FILE_INSERT:
- insertLyXFile(cmd.argument());
+ case LFUN_FILE_INSERT: {
+ if (cmd.getArg(1) == "ignorelang")
+ insertLyXFile(from_utf8(cmd.getArg(0)), true);
+ else
+ insertLyXFile(cmd.argument());
break;
+ }
case LFUN_FILE_INSERT_PLAINTEXT:
case LFUN_FILE_INSERT_PLAINTEXT_PARA: {
dr.setMessage(_("Absolute filename expected."));
break;
}
-
+
FileName filename(fname);
if (fname.empty()) {
FileDialog dlg(qt_("Select file to insert"));
FileDialog::Result result = dlg.open(toqstr(bv->buffer().filePath()),
QStringList(qt_("All Files (*)")));
-
+
if (result.first == FileDialog::Later || result.second.isEmpty()) {
dr.setMessage(_("Canceled."));
break;
case LFUN_BUFFER_RELOAD: {
LASSERT(doc_buffer, break);
+ // drop changes?
+ bool drop = (cmd.argument() == "dump");
+
int ret = 0;
- if (!doc_buffer->isClean()) {
+ if (!drop && !doc_buffer->isClean()) {
docstring const file =
makeDisplayPath(doc_buffer->absFileName(), 20);
- docstring text = bformat(_("Any changes will be lost. "
- "Are you sure you want to revert to the saved version "
- "of the document %1$s?"), file);
- ret = Alert::prompt(_("Revert to saved document?"),
- text, 1, 1, _("&Revert"), _("&Cancel"));
+ if (doc_buffer->notifiesExternalModification()) {
+ docstring text = _("The current version will be lost. "
+ "Are you sure you want to load the version on disk "
+ "of the document %1$s?");
+ ret = Alert::prompt(_("Reload saved document?"),
+ bformat(text, file), 1, 1,
+ _("&Reload"), _("&Cancel"));
+ } else {
+ docstring text = _("Any changes will be lost. "
+ "Are you sure you want to revert to the saved version "
+ "of the document %1$s?");
+ ret = Alert::prompt(_("Revert to saved document?"),
+ bformat(text, file), 1, 1,
+ _("&Revert"), _("&Cancel"));
+ }
}
if (ret == 0) {
renameBuffer(*doc_buffer, cmd.argument());
break;
+ case LFUN_BUFFER_WRITE_AS_TEMPLATE:
+ LASSERT(doc_buffer, break);
+ renameBuffer(*doc_buffer, cmd.argument(),
+ LV_WRITE_AS_TEMPLATE);
+ break;
+
case LFUN_BUFFER_WRITE_ALL: {
Buffer * first = theBufferList().first();
if (!first)
break;
}
+ case LFUN_BUFFER_EXTERNAL_MODIFICATION_CLEAR:
+ LASSERT(doc_buffer, break);
+ doc_buffer->clearExternalModification();
+ break;
+
case LFUN_BUFFER_CLOSE:
closeBuffer();
break;
closeBufferAll();
break;
+ case LFUN_DEVEL_MODE_TOGGLE:
+ devel_mode_ = !devel_mode_;
+ if (devel_mode_)
+ dr.setMessage(_("Developer mode is now enabled."));
+ else
+ dr.setMessage(_("Developer mode is now disabled."));
+ break;
+
case LFUN_TOOLBAR_TOGGLE: {
string const name = cmd.getArg(0);
if (GuiToolbar * t = toolbar(name))
break;
}
+ case LFUN_TOOLBAR_MOVABLE: {
+ string const name = cmd.getArg(0);
+ if (name == "*") {
+ // toggle (all) toolbars movablility
+ toolbarsMovable_ = !toolbarsMovable_;
+ for (ToolbarInfo const & ti : guiApp->toolbars()) {
+ GuiToolbar * tb = toolbar(ti.name);
+ if (tb && tb->isMovable() != toolbarsMovable_)
+ // toggle toolbar movablity if it does not fit lock
+ // (all) toolbars positions state silent = true, since
+ // status bar notifications are slow
+ tb->movable(true);
+ }
+ if (toolbarsMovable_)
+ dr.setMessage(_("Toolbars unlocked."));
+ else
+ dr.setMessage(_("Toolbars locked."));
+ } else if (GuiToolbar * t = toolbar(name)) {
+ // toggle current toolbar movablity
+ t->movable();
+ // update lock (all) toolbars positions
+ updateLockToolbars();
+ }
+ break;
+ }
+
case LFUN_ICON_SIZE: {
QSize size = d.iconSize(cmd.argument());
setIconSize(size);
case LFUN_DIALOG_SHOW: {
string const name = cmd.getArg(0);
- string data = trim(to_utf8(cmd.argument()).substr(name.size()));
+ string sdata = trim(to_utf8(cmd.argument()).substr(name.size()));
- if (name == "character") {
- data = freefont2string();
- if (!data.empty())
- showDialog("character", data);
- } else if (name == "latexlog") {
+ if (name == "latexlog") {
+ // gettatus checks that
+ LATTEST(doc_buffer);
Buffer::LogType type;
string const logfile = doc_buffer->logName(&type);
switch (type) {
case Buffer::latexlog:
- data = "latex ";
+ sdata = "latex ";
break;
case Buffer::buildlog:
- data = "literate ";
+ sdata = "literate ";
break;
}
- data += Lexer::quoteString(logfile);
- showDialog("log", data);
+ sdata += Lexer::quoteString(logfile);
+ showDialog("log", sdata);
} else if (name == "vclog") {
- string const data = "vc " +
+ // getStatus checks that
+ LATTEST(doc_buffer);
+ string const sdata2 = "vc " +
Lexer::quoteString(doc_buffer->lyxvc().getLogFile());
- showDialog("log", data);
+ showDialog("log", sdata2);
} else if (name == "symbols") {
- data = bv->cursor().getEncoding()->name();
- if (!data.empty())
- showDialog("symbols", data);
+ sdata = bv->cursor().getEncoding()->name();
+ if (!sdata.empty())
+ showDialog("symbols", sdata);
// bug 5274
} else if (name == "prefs" && isFullScreen()) {
lfunUiToggle("fullscreen");
- showDialog("prefs", data);
+ showDialog("prefs", sdata);
} else
- showDialog(name, data);
+ showDialog(name, sdata);
break;
}
break;
case LFUN_BUFFER_ZOOM_IN:
- case LFUN_BUFFER_ZOOM_OUT: {
- // use a signed temp to avoid overflow
- int zoom = lyxrc.zoom;
+ case LFUN_BUFFER_ZOOM_OUT:
+ case LFUN_BUFFER_ZOOM: {
if (cmd.argument().empty()) {
- if (cmd.action() == LFUN_BUFFER_ZOOM_IN)
- zoom += 20;
+ if (cmd.action() == LFUN_BUFFER_ZOOM)
+ zoom_ratio_ = 1.0;
+ else if (cmd.action() == LFUN_BUFFER_ZOOM_IN)
+ zoom_ratio_ += 0.1;
else
- zoom -= 20;
- } else
- zoom += convert<int>(cmd.argument());
+ zoom_ratio_ -= 0.1;
+ } else {
+ if (cmd.action() == LFUN_BUFFER_ZOOM)
+ zoom_ratio_ = convert<int>(cmd.argument()) / double(lyxrc.defaultZoom);
+ else if (cmd.action() == LFUN_BUFFER_ZOOM_IN)
+ zoom_ratio_ += convert<int>(cmd.argument()) / 100.0;
+ else
+ zoom_ratio_ -= convert<int>(cmd.argument()) / 100.0;
+ }
+ // Actual zoom value: default zoom + fractional extra value
+ int zoom = lyxrc.defaultZoom * zoom_ratio_;
if (zoom < static_cast<int>(zoom_min_))
zoom = zoom_min_;
- lyxrc.zoom = zoom;
- dr.setMessage(bformat(_("Zoom level is now %1$d%"), lyxrc.zoom));
+ lyxrc.currentZoom = zoom;
+
+ dr.setMessage(bformat(_("Zoom level is now %1$d% (default value: %2$d%)"),
+ lyxrc.currentZoom, lyxrc.defaultZoom));
- // The global QPixmapCache is used in GuiPainter to cache text
- // painting so we must reset it.
- QPixmapCache::clear();
guiApp->fontLoader().update();
- lyx::dispatch(FuncRequest(LFUN_SCREEN_FONT_UPDATE));
+ dr.screenUpdate(Update::Force | Update::FitCursor);
break;
}
break;
case LFUN_FORWARD_SEARCH: {
- // it seems safe to assume we have a document buffer, since
- // getStatus wants one.
- // coverity[FORWARD_NULL]
+ // it seems safe to assume we have a document buffer, since
+ // getStatus wants one.
+ LATTEST(doc_buffer);
Buffer const * doc_master = doc_buffer->masterBuffer();
FileName const path(doc_master->temppath());
string const texname = doc_master->isChild(doc_buffer)
doc_buffer->absFileName(),
"tex")).mangledFileName()
: doc_buffer->latexName();
- string const fulltexname =
+ string const fulltexname =
support::makeAbsPath(texname, doc_master->temppath()).absFileName();
string const mastername =
removeExtension(doc_master->latexName());
continue;
Buffer const * buffer = &(wa->bufferView().buffer());
if (inset_buffer == buffer)
- wa->scheduleRedraw();
+ wa->scheduleRedraw(true);
}
return inset_buffer;
}
-void GuiView::restartCursor()
+void GuiView::restartCaret()
{
/* When we move around, or type, it's nice to be able to see
- * the cursor immediately after the keypress.
+ * the caret immediately after the keypress.
*/
if (d.current_work_area_)
- d.current_work_area_->startBlinkingCursor();
+ d.current_work_area_->startBlinkingCaret();
// Take this occasion to update the other GUI elements.
updateDialogs();
"citation", "compare", "comparehistory", "document", "errorlist", "ert",
"external", "file", "findreplace", "findreplaceadv", "float", "graphics",
"href", "include", "index", "index_print", "info", "listings", "label", "line",
-"log", "mathdelimiter", "mathmatrix", "mathspace", "nomenclature",
+"log", "lyxfiles", "mathdelimiter", "mathmatrix", "mathspace", "nomenclature",
"nomencl_print", "note", "paragraph", "phantom", "prefs", "ref",
"sendto", "space", "spellchecker", "symbols", "tabular", "tabularcreate",
"thesaurus", "texinfo", "toc", "view-source", "vspace", "wrap", "progress"};
cmpCStr(name.c_str())) != end_dialognames;
}
-} // namespace anon
+} // namespace
void GuiView::resetDialogs()
// Now update controls with current buffer.
guiApp->setCurrentView(this);
restoreLayout();
- restartCursor();
+ restartCaret();
}
}
-void GuiView::showDialog(string const & name, string const & data,
+void GuiView::showDialog(string const & name, string const & sdata,
Inset * inset)
{
- triggerShowDialog(toqstr(name), toqstr(data), inset);
+ triggerShowDialog(toqstr(name), toqstr(sdata), inset);
}
return;
const string name = fromqstr(qname);
- const string data = fromqstr(qdata);
+ const string sdata = fromqstr(qdata);
d.in_show_ = true;
try {
Dialog * dialog = findOrBuild(name, false);
if (dialog) {
bool const visible = dialog->isVisibleView();
- dialog->showData(data);
- if (inset && currentBufferView())
+ dialog->showData(sdata);
+ if (currentBufferView())
currentBufferView()->editInset(name, inset);
// We only set the focus to the new dialog if it was not yet
// visible in order not to change the existing previous behaviour
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);
return createGuiListings(*this);
if (name == "log")
return createGuiLog(*this);
+ if (name == "lyxfiles")
+ return createGuiLyXFiles(*this);
if (name == "mathdelimiter")
return createGuiDelimiter(*this);
if (name == "mathmatrix")
}
+SEMenu::SEMenu(QWidget * parent)
+{
+ QAction * action = addAction(qt_("Disable Shell Escape"));
+ connect(action, SIGNAL(triggered()),
+ parent, SLOT(disableShellEscape()));
+}
+
} // namespace frontend
} // namespace lyx