[LyX/master] When catching exception, give error on STDERR
commit 3db74fa92d9acd784b271b01c473f69c36311777 Author: Scott Kostyshak Date: Fri Mar 10 17:11:58 2017 -0500 When catching exception, give error on STDERR The error is reported in the GUI, but for the terminal we must write explicitly to STDERR. For a specific example of this type of exception, see the previous commit, 72c3dbd. --- src/Buffer.cpp |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/src/Buffer.cpp b/src/Buffer.cpp index b220ee3..84b5e6c 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -1741,6 +1741,7 @@ bool Buffer::makeLaTeXFile(FileName const & fname, catch (exception const & e) { errorList.push_back(ErrorItem(_("conversion failed"), _(e.what(; + lyxerr << e.what() << endl; failed_export = true; } catch (...) {
[LyX/master] Change a warning to an error if missing include
commit 72c3dbd02ccd0a3b85f1c9b940462ac1e7ed98d6 Author: Scott Kostyshak Date: Fri Mar 10 15:38:27 2017 -0500 Change a warning to an error if missing include If an included file is not found, it seems impossible that the final output would be correct. Before this commit, when exporting on the command line, LyX would create the PDF and exit with a zero error code so unless the user was monitoring the terminal output, they would not know there is a problem. This change is consistent with 1a374a93. --- src/insets/InsetInclude.cpp |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/src/insets/InsetInclude.cpp b/src/insets/InsetInclude.cpp index a5ed017..4820301 100644 --- a/src/insets/InsetInclude.cpp +++ b/src/insets/InsetInclude.cpp @@ -640,7 +640,8 @@ void InsetInclude::latex(otexstream & os, OutputParams const & runparams) const "file\n`%1$s'\n" "Please, check whether it actually exists."), included_file.displayName()); - Alert::warning(_("Missing included file"), text); + throw ExceptionMessage(ErrorException, _("Error: "), + text); } return; }
[LyX/master] Preventive fix inspired from ~
commit 22edb3df96e78cf10aa94e0f2d9f6f6697534786 Author: Guillaume Munch Date: Fri Mar 10 23:20:29 2017 +0100 Preventive fix inspired from ~ --- src/TextMetrics.cpp | 27 --- 1 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp index 5873a28..3dd0520 100644 --- a/src/TextMetrics.cpp +++ b/src/TextMetrics.cpp @@ -1361,18 +1361,23 @@ Inset * TextMetrics::editXY(Cursor & cur, int x, int y, if (edited == inset && cur.pos() == it->pos) { // non-editable inset, set cursor after the inset if x is // nearer to that position (bug 9628) + // TODO: This should be replaced with an improvement of + // Cursor::moveToClosestEdge that handles rtl text. (Which could not + // be tested because of #10569.) CoordCache::Insets const & insetCache = bv_->coordCache().getInsets(); - Dimension const & dim = insetCache.dim(inset); - Point p = insetCache.xy(inset); - bool const is_rtl = text_->isRTL(text_->getPar(pit)); - if (is_rtl) { - // "in front of" == "right of" - if (abs(p.x_ - x) < abs(p.x_ + dim.wid - x)) - cur.posForward(); - } else { - // "in front of" == "left of" - if (abs(p.x_ + dim.wid - x) < abs(p.x_ - x)) - cur.posForward(); + if (insetCache.has(inset)) { + Dimension const & dim = insetCache.dim(inset); + Point p = insetCache.xy(inset); + bool const is_rtl = text_->isRTL(text_->getPar(pit)); + if (is_rtl) { + // "in front of" == "right of" + if (abs(p.x_ - x) < abs(p.x_ + dim.wid - x)) + cur.posForward(); + } else { + // "in front of" == "left of" + if (abs(p.x_ + dim.wid - x) < abs(p.x_ - x)) + cur.posForward(); + } } }
[LyX/master] Replace FileMonitor with FileMonitor2 in RenderPreview
commit a4fae021f23aa38382673d014cea839aaa9cb812 Author: Guillaume Munch Date: Thu Mar 9 22:44:07 2017 +0100 Replace FileMonitor with FileMonitor2 in RenderPreview --- src/insets/InsetExternal.cpp | 10 +++- src/insets/InsetInclude.cpp |8 +++--- src/insets/RenderPreview.cpp | 44 +++-- src/insets/RenderPreview.h | 21 --- 4 files changed, 58 insertions(+), 25 deletions(-) diff --git a/src/insets/InsetExternal.cpp b/src/insets/InsetExternal.cpp index 8ddd756..3b79249 100644 --- a/src/insets/InsetExternal.cpp +++ b/src/insets/InsetExternal.cpp @@ -629,14 +629,12 @@ void InsetExternal::setParams(InsetExternalParams const & p) LASSERT(false, return); break; case PREVIEW_INSTANT: { - renderer_.reset(new RenderMonitoredPreview(this)); + renderer_ = make_unique(this); RenderMonitoredPreview * preview_ptr = renderer_->asMonitoredPreview(); - preview_ptr->fileChanged(bind(&InsetExternal::fileChanged, this)); - if (preview_ptr->monitoring()) - preview_ptr->stopMonitoring(); + preview_ptr->connect([=]() { fileChanged(); }); add_preview_and_start_loading(*preview_ptr, *this, buffer()); break; - } + } case PREVIEW_GRAPHICS: { RenderGraphic * graphic_ptr = renderer_->asGraphic(); if (!graphic_ptr) { @@ -837,7 +835,7 @@ void InsetExternal::validate(LaTeXFeatures & features) const void InsetExternal::addPreview(DocIterator const & /*inset_pos*/, - graphics::PreviewLoader & ploader) const + graphics::PreviewLoader & ploader) const { RenderMonitoredPreview * const ptr = renderer_->asMonitoredPreview(); if (!ptr) diff --git a/src/insets/InsetInclude.cpp b/src/insets/InsetInclude.cpp index 3a8c0b8..a5ed017 100644 --- a/src/insets/InsetInclude.cpp +++ b/src/insets/InsetInclude.cpp @@ -170,10 +170,10 @@ InsetLabel * createLabel(Buffer * buf, docstring const & label_str) InsetInclude::InsetInclude(Buffer * buf, InsetCommandParams const & p) : InsetCommand(buf, p), include_label(uniqueID()), - preview_(new RenderMonitoredPreview(this)), failedtoload_(false), + preview_(make_unique(this)), failedtoload_(false), set_label_(false), label_(0), child_buffer_(0) { - preview_->fileChanged(bind(&InsetInclude::fileChanged, this)); + preview_->connect([=](){ fileChanged(); }); if (isListings(params())) { InsetListingsParams listing_params(to_utf8(p["lstparams"])); @@ -185,10 +185,10 @@ InsetInclude::InsetInclude(Buffer * buf, InsetCommandParams const & p) InsetInclude::InsetInclude(InsetInclude const & other) : InsetCommand(other), include_label(other.include_label), - preview_(new RenderMonitoredPreview(this)), failedtoload_(false), + preview_(make_unique(this)), failedtoload_(false), set_label_(false), label_(0), child_buffer_(0) { - preview_->fileChanged(bind(&InsetInclude::fileChanged, this)); + preview_->connect([=](){ fileChanged(); }); if (other.label_) label_ = new InsetLabel(*other.label_); diff --git a/src/insets/RenderPreview.cpp b/src/insets/RenderPreview.cpp index e985d29..99abca9 100644 --- a/src/insets/RenderPreview.cpp +++ b/src/insets/RenderPreview.cpp @@ -271,28 +271,58 @@ void RenderPreview::imageReady(graphics::PreviewImage const & pimage) RenderMonitoredPreview::RenderMonitoredPreview(Inset const * inset) - : RenderPreview(inset), monitor_(FileName(), 2000) -{} + : RenderPreview(inset) +{ + setAbsFile(FileName()); +} void RenderMonitoredPreview::setAbsFile(FileName const & file) { - monitor_.reset(file); + bool mon = monitoring(); + if (mon) + stopMonitoring(); + filename_ = file; + if (mon) + startMonitoring(); } void RenderMonitoredPreview::draw(PainterInfo & pi, int x, int y) const { RenderPreview::draw(pi, x, y); - if (!monitoring()) - startMonitoring(); + startMonitoring(); } boost::signals2::connection -RenderMonitoredPreview::fileChanged(slot_type const & slot) +RenderMonitoredPreview::connect(ChangedSig::slot_type const & slot) { - return monitor_.connect(slot); + return changed_.connect(slot); } + +bool RenderMonitoredPreview::monitoring() const +{ + return (bool) monitor_; +} + + +void RenderMonitoredPreview::startMonitoring() const +{ + if (!monitoring()) { + monitor_ = FileSystemWatcher::monitor(filename_); + monitor_->connect(changed_); + } +} + + +void RenderMonitoredPreview::stopMonitoring() const +{ + monitor_ = nullptr; +} + + + + } // namespace lyx diff --git a/src/insets/Re
[LyX/master] Display externally modified status
commit 1e57fd12b18f82b4fbc00ee5dbe78d03143b4adb Author: Guillaume Munch Date: Tue Feb 28 22:58:44 2017 +0100 Display externally modified status --- src/frontends/WorkAreaManager.cpp | 13 + src/frontends/WorkAreaManager.h |3 ++- src/frontends/qt4/GuiView.cpp |6 ++ src/frontends/qt4/GuiWorkArea.cpp | 17 + src/frontends/qt4/GuiWorkArea_Private.h |2 ++ src/frontends/qt4/Menus.cpp |4 6 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/frontends/WorkAreaManager.cpp b/src/frontends/WorkAreaManager.cpp index f938db4..a1c244e 100644 --- a/src/frontends/WorkAreaManager.cpp +++ b/src/frontends/WorkAreaManager.cpp @@ -33,10 +33,8 @@ void WorkAreaManager::remove(WorkArea * wa) void WorkAreaManager::redrawAll(bool update_metrics) { - iterator it = work_areas_.begin(); - iterator const en = work_areas_.end(); - for (; it != en; ++it) - (*it)->redraw(update_metrics); + for (WorkArea * wa : work_areas_) + wa->redraw(update_metrics); } @@ -50,12 +48,11 @@ void WorkAreaManager::closeAll() void WorkAreaManager::updateTitles() { - iterator it = work_areas_.begin(); - iterator const en = work_areas_.end(); - for (; it != en; ++it) - (*it)->updateWindowTitle(); + for (WorkArea * wa : work_areas_) + wa->updateWindowTitle(); } + } // namespace frontend } // namespace lyx diff --git a/src/frontends/WorkAreaManager.h b/src/frontends/WorkAreaManager.h index dfef00e..e8952f2 100644 --- a/src/frontends/WorkAreaManager.h +++ b/src/frontends/WorkAreaManager.h @@ -38,7 +38,8 @@ public: void redrawAll(bool update_metrics); /// void closeAll(); - /// Update window titles of all users. + /// Update window titles of all users and the external modifications + /// warning. void updateTitles(); private: diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp index c595632..7ff8e04 100644 --- a/src/frontends/qt4/GuiView.cpp +++ b/src/frontends/qt4/GuiView.cpp @@ -1121,6 +1121,12 @@ void GuiView::updateWindowTitle(GuiWorkArea * wa) 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 diff --git a/src/frontends/qt4/GuiWorkArea.cpp b/src/frontends/qt4/GuiWorkArea.cpp index bb8de83..050eae7 100644 --- a/src/frontends/qt4/GuiWorkArea.cpp +++ b/src/frontends/qt4/GuiWorkArea.cpp @@ -251,7 +251,7 @@ GuiWorkArea::Private::Private(GuiWorkArea * parent) need_resize_(false), schedule_redraw_(false), preedit_lines_(1), pixel_ratio_(1.0), completer_(new GuiCompleter(p, p)), dialog_mode_(false), - read_only_(false), clean_(true) + read_only_(false), clean_(true), externally_modified_(false) { } @@ -1390,12 +1390,16 @@ QVariant GuiWorkArea::inputMethodQuery(Qt::InputMethodQuery query) const void GuiWorkArea::updateWindowTitle() { Buffer const & buf = bufferView().buffer(); - if (buf.fileName() != d->file_name_ || buf.isReadonly() != d->read_only_ - || buf.lyxvc().vcstatus() != d->vc_status_ || buf.isClean() != d->clean_) { + if (buf.fileName() != d->file_name_ + || buf.isReadonly() != d->read_only_ + || buf.lyxvc().vcstatus() != d->vc_status_ + || buf.isClean() != d->clean_ + || buf.notifiesExternalModification() != d->externally_modified_) { d->file_name_ = buf.fileName(); d->read_only_ = buf.isReadonly(); d->vc_status_ = buf.lyxvc().vcstatus(); d->clean_ = buf.isClean(); + d->externally_modified_ = buf.notifiesExternalModification(); Q_EMIT titleChanged(this); } } @@ -2052,9 +2056,14 @@ void TabWorkArea::updateTabTexts() QString tab_tooltip = it->abs(); if (buf.isReadonly()) { setTabIcon(tab_index, QIcon(getPixmap("images/", "emblem-readonly", "svgz,png"))); - tab_tooltip = qt_("%1 (read only)").arg(it->abs()); + tab_tooltip = qt_("%1 (read only)").arg(tab_tooltip); } else setTabIcon(tab_index, QIcon()); + if (buf.notifiesExternalModification()) { + QString const warn = qt_("%1 (modified externally)"); + tab_tooltip = warn.arg(tab_tooltip); + tab_text +
[LyX/master] Notification of external modification inspired by gedit
commit b6b56d85189966dd18223dcc30b3cef1ec6ed39a Author: Guillaume Munch Date: Thu Mar 2 00:41:02 2017 +0100 Notification of external modification inspired by gedit --- src/frontends/qt4/GuiView.cpp |8 ++-- src/frontends/qt4/GuiWorkArea.cpp | 98 +++--- src/frontends/qt4/GuiWorkArea.h| 29 ++ src/frontends/qt4/Makefile.am |1 + src/frontends/qt4/ui/WorkAreaUi.ui | 103 5 files changed, 226 insertions(+), 13 deletions(-) diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp index e2e6555..d990d79 100644 --- a/src/frontends/qt4/GuiView.cpp +++ b/src/frontends/qt4/GuiView.cpp @@ -1352,13 +1352,13 @@ double GuiView::pixelRatio() const return 1.0; #endif } - - + + GuiWorkArea * GuiView::workArea(int index) { if (TabWorkArea * twa = d.currentTabWorkArea()) if (index < twa->count()) - return dynamic_cast(twa->widget(index)); + return twa->workArea(index); return 0; } @@ -2767,7 +2767,7 @@ void GuiView::writeSession() const { 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(twa->widget(j)); + GuiWorkArea * wa = twa->workArea(j); Buffer & buf = wa->bufferView().buffer(); theSession().lastOpened().add(buf.fileName(), wa == active_wa); } diff --git a/src/frontends/qt4/GuiWorkArea.cpp b/src/frontends/qt4/GuiWorkArea.cpp index 050eae7..dc6ee32 100644 --- a/src/frontends/qt4/GuiWorkArea.cpp +++ b/src/frontends/qt4/GuiWorkArea.cpp @@ -1688,15 +1688,24 @@ GuiWorkArea * TabWorkArea::currentWorkArea() if (count() == 0) return 0; - GuiWorkArea * wa = dynamic_cast(currentWidget()); + GuiWorkAreaContainer * wac = + dynamic_cast(currentWidget()); + LATTEST(wac); + GuiWorkArea * wa = wac->workArea(); LATTEST(wa); return wa; } +GuiWorkArea const * TabWorkArea::workArea(int index) const +{ + return (dynamic_cast(widget(index)))->workArea(); +} + + GuiWorkArea * TabWorkArea::workArea(int index) { - return dynamic_cast(widget(index)); + return (dynamic_cast(widget(index)))->workArea(); } @@ -1717,18 +1726,27 @@ GuiWorkArea * TabWorkArea::workArea(Buffer & buffer) void TabWorkArea::closeAll() { while (count()) { - GuiWorkArea * wa = workArea(0); - LASSERT(wa, return); + QWidget * wac = widget(0); + LASSERT(wac, return); removeTab(0); - delete wa; + delete wac; } } +int TabWorkArea::indexOfWorkArea(GuiWorkArea * w) const +{ + for (int index = 0; index < count(); ++index) + if (workArea(index) == w) + return index; + return -1; +} + + bool TabWorkArea::setCurrentWorkArea(GuiWorkArea * work_area) { LASSERT(work_area, return false); - int index = indexOf(work_area); + int index = indexOfWorkArea(work_area); if (index == -1) return false; @@ -1747,12 +1765,13 @@ bool TabWorkArea::setCurrentWorkArea(GuiWorkArea * work_area) GuiWorkArea * TabWorkArea::addWorkArea(Buffer & buffer, GuiView & view) { GuiWorkArea * wa = new GuiWorkArea(buffer, view); + GuiWorkAreaContainer * wac = new GuiWorkAreaContainer(wa); wa->setUpdatesEnabled(false); // Hide tabbar if there's no tab (avoid a resize and a flashing tabbar // when hiding it again below). if (!(currentWorkArea() && currentWorkArea()->isFullScreen())) showBar(count() > 0); - addTab(wa, wa->windowTitle()); + addTab(wac, wa->windowTitle()); QObject::connect(wa, SIGNAL(titleChanged(GuiWorkArea *)), this, SLOT(updateTabTexts())); if (currentWorkArea() && currentWorkArea()->isFullScreen()) @@ -1770,13 +1789,14 @@ GuiWorkArea * TabWorkArea::addWorkArea(Buffer & buffer, GuiView & view) bool TabWorkArea::removeWorkArea(GuiWorkArea * work_area) { LASSERT(work_area, return false); - int index = indexOf(work_area); + int index = indexOfWorkArea(work_area); if (index == -1) return false; work_area->setUpdatesEnabled(false); + QWidget * wac = widget(index); removeTab(index); - delete work_area; + delete wac; if (count()) { // make sure the next work area is enabled. @@ -2180,6 +2200,66 @@ void DragTabBar::dropEvent(QDropEvent * event) } +GuiWorkAreaContainer::GuiWorkAreaContainer(GuiWorkArea * wa, QWidget * parent) + : QWidget(parent), wa_(wa) +{ + LASSERT(wa, ret
[LyX/master] Implement real-time detection of external modifications
commit cf3c035266486b797e4bc3fe1a9e95c87f45f66d Author: Guillaume Munch Date: Sun Mar 5 20:12:07 2017 +0100 Implement real-time detection of external modifications --- src/Buffer.cpp| 69 src/Buffer.h | 29 + src/frontends/qt4/GuiView.cpp |7 +--- 3 files changed, 73 insertions(+), 32 deletions(-) diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 6b41213..2bc454b 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -91,6 +91,7 @@ #include "support/debug.h" #include "support/docstring_list.h" #include "support/ExceptionMessage.h" +#include "support/FileMonitor.h" #include "support/FileName.h" #include "support/FileNameList.h" #include "support/filetools.h" @@ -376,6 +377,18 @@ public: // display the review toolbar, for instance) mutable bool tracked_changes_present_; + // Make sure the file monitor monitors the good file. + void refreshFileMonitor(); + + /// has it been notified of an external modification? + bool isExternallyModified() const { return externally_modified_; } + + /// Notify or clear of external modification + void fileExternallyModified(bool modified) const; + + /// Block notifications of external modifications + FileMonitorBlocker blockFileMonitor() { return file_monitor_->block(10); } + private: /// So we can force access via the accessors. mutable Buffer const * parent_buffer; @@ -384,6 +397,10 @@ private: int char_count_; int blank_count_; + /// has been externally modified? Can be reset by the user. + mutable bool externally_modified_; + + FileMonitorPtr file_monitor_; }; @@ -425,8 +442,10 @@ Buffer::Impl::Impl(Buffer * owner, FileName const & file, bool readonly_, inset(0), preview_loader_(0), cloned_buffer_(cloned_buffer), clone_list_(0), doing_export(false), tracked_changes_present_(0), parent_buffer(0), - word_count_(0), char_count_(0), blank_count_(0) + word_count_(0), char_count_(0), blank_count_(0), + externally_modified_(false) { + refreshFileMonitor(); if (!cloned_buffer_) { temppath = createBufferTmpDir(); lyxvc.setBuffer(owner_); @@ -864,6 +883,7 @@ void Buffer::setFileName(FileName const & fname) { bool const changed = fname != d->filename; d->filename = fname; + d->refreshFileMonitor(); if (changed) lyxvc().file_found_hook(fname); setReadonly(d->filename.isReadOnly()); @@ -1360,6 +1380,7 @@ FileName Buffer::getBackupName() const { // Should probably be moved to somewhere else: BufferView? GuiView? bool Buffer::save() const { + FileMonitorBlocker block = d->blockFileMonitor(); docstring const file = makeDisplayPath(absFileName(), 20); d->filename.refresh(); @@ -1375,7 +1396,7 @@ bool Buffer::save() const } // ask if the disk file has been externally modified (use checksum method) - if (fileName().exists() && isExternallyModified(checksum_method)) { + if (fileName().exists() && isChecksumModified()) { docstring text = bformat(_("Document %1$s has been externally modified. " "Are you sure you want to overwrite this file?"), file); @@ -2995,13 +3016,10 @@ bool Buffer::isClean() const } -bool Buffer::isExternallyModified(CheckMethod method) const +bool Buffer::isChecksumModified() const { LASSERT(d->filename.exists(), return false); - // if method == timestamp, check timestamp before checksum - return (method == checksum_method - || d->timestamp_ != d->filename.lastModified()) - && d->checksum_ != d->filename.checksum(); + return d->checksum_ != d->filename.checksum(); } @@ -3031,6 +3049,7 @@ void Buffer::markClean() const // autosave d->bak_clean = true; d->undo_.markDirty(); + clearExternalModification(); } @@ -5298,5 +5317,41 @@ void Buffer::updateChangesPresent() const } +void Buffer::Impl::refreshFileMonitor() +{ + if (file_monitor_ && file_monitor_->filename() == filename.absFileName()) + return file_monitor_->refresh(); + + // The previous file monitor is invalid + // This also destroys the previous file monitor and all its connections + file_monitor_ = FileSystemWatcher::monitor(filename); + fileExternallyModified(false); + // file_monitor_ will be destroyed with *this, so it is not going to call a + // destroyed object method. + file_monitor_->connect([this](){ fileExternallyModified(true); }); +} + + +void Buffer::Impl::fileExternallyModified(bool modified) const +{ + if (modified) + lyx_clean = bak_clean = false; + externally_modified_ = modified; + if (
[LyX/master] Implement FileMonitor as a wrapper for QFileSystemWatcher
commit caa54e80ee410c0fa3cc9a1eea6588d68a92386b Author: Guillaume Munch Date: Mon Feb 27 23:46:10 2017 +0100 Implement FileMonitor as a wrapper for QFileSystemWatcher The new file monitor supports both boost and qt signals. It is implemented in a ressource-safe way. --- src/support/FileMonitor.h|6 +- src/support/FileMonitor2.cpp | 211 ++ src/support/FileMonitor2.h | 192 ++ src/support/Makefile.am |3 + 4 files changed, 411 insertions(+), 1 deletions(-) diff --git a/src/support/FileMonitor.h b/src/support/FileMonitor.h index d0d3741..efc8102 100644 --- a/src/support/FileMonitor.h +++ b/src/support/FileMonitor.h @@ -15,6 +15,9 @@ #ifndef FILEMONITOR_H #define FILEMONITOR_H +// TODO: Remove FileMonitor +#include "support/FileMonitor2.h" + #include namespace lyx { @@ -28,7 +31,8 @@ public: /** Once monitoring begins, the file will be monitored every * interval ms. * -* FIXME: rewrite and simplify using an encapsulation of QFileSystemWatcher. +* This is now obsoleted by FileMonitor2 based on QFileSystemWatcher. +* FIXME: Remove FileMonitor */ FileMonitor(FileName const & file_with_path, int interval); diff --git a/src/support/FileMonitor2.cpp b/src/support/FileMonitor2.cpp new file mode 100644 index 000..2cf8cb9 --- /dev/null +++ b/src/support/FileMonitor2.cpp @@ -0,0 +1,211 @@ +/** + * \file FileMonitor.cpp + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Guillaume Munch + * + * Full author contact details are available in file CREDITS. + */ + +#include + +#include "support/FileMonitor2.h" + +#include "support/debug.h" +#include "support/FileName.h" +#include "support/qstring_helpers.h" +#include "support/unique_ptr.h" + +#include +#include +#include + +#include + +using namespace std; + +namespace lyx { +namespace support { + + +FileSystemWatcher & FileSystemWatcher::instance() +{ + // This thread-safe because QFileSystemWatcher is thread-safe. + static FileSystemWatcher f; + return f; +} + + +FileSystemWatcher::FileSystemWatcher() + : qwatcher_(make_unique()) +{} + + +//static +FileMonitorPtr FileSystemWatcher::monitor(FileName const & file_with_path) +{ + FileSystemWatcher & f = instance(); + string const filename = file_with_path.absFileName(); + weak_ptr & wptr = f.store_[filename]; + if (shared_ptr mon = wptr.lock()) + return make_unique(mon); + auto mon = make_shared(filename, f.qwatcher_.get()); + wptr = mon; + return make_unique(mon); +} + + +//static +void FileSystemWatcher::debug() +{ + FileSystemWatcher & f = instance(); + QStringList q_files = f.qwatcher_->files(); + for (pair> pair : f.store_) { + string const & name = pair.first; + if (!pair.second.expired()) { + if (!q_files.contains(toqstr(name))) + LYXERR0("Monitored but not QFileSystemWatched (bad): " << name); + else { + //LYXERR0("Monitored and QFileSystemWatched (good): " << name); + } + } + } + for (QString const & qname : q_files) { + string const name = fromqstr(qname); + weak_ptr & wptr = f.store_[name]; + if (wptr.expired()) + LYXERR0("QFileSystemWatched but not monitored (bad): " << name); + } +} + + +FileMonitorGuard::FileMonitorGuard(string const & filename, + QFileSystemWatcher * qwatcher) + : filename_(filename), qwatcher_(qwatcher) +{ + QObject::connect(qwatcher, SIGNAL(fileChanged(QString const &)), +this, SLOT(notifyChange(QString const &))); + if (qwatcher_->files().contains(toqstr(filename))) + LYXERR0("This file is already being QFileSystemWatched: " << filename + << ". This should not happen."); + refresh(); +} + + +FileMonitorGuard::~FileMonitorGuard() +{ + qwatcher_->removePath(toqstr(filename_)); +} + + +void FileMonitorGuard::refresh(bool new_file) +{ + QString const qfilename = toqstr(filename_); + if(!qwatcher_->files().contains(qfilename)) { + bool exists = QFile(qfilename).exists(); + if (!exists || !qwatcher_->addPath(qfilename)) { + if (exists) + LYXERR(Debug::FILES, + "Could not add path to QFileSystemWatcher: " + << filename_); + QTimer::singleShot(1000, this, [=](){ + refresh(new_file || !exists); + }); +
[LyX/master] Nonsense for whoever insists on using gcc4.6 & qt4.8 in 2017
commit 24f68aff8d2ba9139017ca3927eda1f1aaf039af Author: Guillaume Munch Date: Sat Mar 11 00:11:02 2017 +0100 Nonsense for whoever insists on using gcc4.6 & qt4.8 in 2017 --- src/support/FileMonitor.cpp | 21 ++--- src/support/FileMonitor.h | 17 + 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/support/FileMonitor.cpp b/src/support/FileMonitor.cpp index a55fd23..051 100644 --- a/src/support/FileMonitor.cpp +++ b/src/support/FileMonitor.cpp @@ -18,6 +18,7 @@ #include "support/unique_ptr.h" #include +#include #include #include @@ -103,6 +104,7 @@ void FileMonitorGuard::refresh(bool new_file) QString const qfilename = toqstr(filename_); if(!qwatcher_->files().contains(qfilename)) { bool exists = QFile(qfilename).exists(); +#if (QT_VERSION >= 0x05) if (!exists || !qwatcher_->addPath(qfilename)) { if (exists) LYXERR(Debug::FILES, @@ -111,6 +113,21 @@ void FileMonitorGuard::refresh(bool new_file) QTimer::singleShot(1000, this, [=](){ refresh(new_file || !exists); }); +#else + auto add_path = [&]() { + qwatcher_->addPath(qfilename); + return qwatcher_->files().contains(qfilename); + }; + if (!exists || !add_path()) { + if (exists) + LYXERR(Debug::FILES, + "Could not add path to QFileSystemWatcher: " + << filename_); + if (new_file || !exists) + QTimer::singleShot(1000, this, SLOT(refreshTrue())); + else + QTimer::singleShot(1000, this, SLOT(refreshFalse())); +#endif } else if (exists && new_file) Q_EMIT fileChanged(); } @@ -199,9 +216,7 @@ FileMonitorBlockerGuard::~FileMonitorBlockerGuard() // from QFileSystemWatcher that we meant to ignore are not going to be // treated immediately, so we must yield to give us the opportunity to // ignore them. - QTimer::singleShot(delay_, parent, [parent]() { - parent->connectToFileMonitorGuard(); - }); + QTimer::singleShot(delay_, parent, SLOT(connectToFileMonitorGuard())); } } // namespace support diff --git a/src/support/FileMonitor.h b/src/support/FileMonitor.h index 09d85e8..deca740 100644 --- a/src/support/FileMonitor.h +++ b/src/support/FileMonitor.h @@ -34,7 +34,7 @@ class FileName; class FileMonitor; class FileMonitorGuard; -using FileMonitorPtr = std::unique_ptr; +typedef std::unique_ptr FileMonitorPtr; /// /// Watch a file: @@ -115,6 +115,14 @@ private Q_SLOTS: /// Receive notifications from the QFileSystemWatcher void notifyChange(QString const & path); + /// nonsense introduced for when QT_VERSION < 0x05, cannot be placed + /// between #ifdef + void refreshTrue() { refresh(true); } + /// nonsense introduced for when QT_VERSION < 0x05, cannot be placed + /// between #ifdef + void refreshFalse() { refresh(false); } + + private: std::string const filename_; QFileSystemWatcher * qwatcher_; @@ -134,7 +142,7 @@ public: }; -using FileMonitorBlocker = std::shared_ptr; +typedef std::shared_ptr FileMonitorBlocker; /// Main class @@ -146,7 +154,7 @@ class FileMonitor : public QObject public: FileMonitor(std::shared_ptr monitor); - using sig = boost::signals2::signal; + typedef boost::signals2::signal sig; /// Connect and you'll be informed when the file has changed. boost::signals2::connection connect(sig::slot_type const &); /// disconnect all slots connected to the boost signal fileChanged_ or to @@ -173,9 +181,10 @@ Q_SIGNALS: private Q_SLOTS: /// Receive notifications from the FileMonitorGuard void changed(); + /// + void connectToFileMonitorGuard(); private: - void connectToFileMonitorGuard(); // boost signal sig fileChanged_; // the unique watch for our file
[LyX/master] Remove legacy FileMonitor
commit f96d7a8b2cb45e98382e2d88f1156e74e7898f5e Author: Guillaume Munch Date: Fri Mar 10 22:41:48 2017 +0100 Remove legacy FileMonitor --- src/support/FileMonitor.cpp | 233 +++-- src/support/FileMonitor.h| 201 src/support/FileMonitor2.cpp | 211 -- src/support/FileMonitor2.h | 192 -- src/support/Makefile.am |4 +- 5 files changed, 288 insertions(+), 553 deletions(-) diff --git a/src/support/FileMonitor.cpp b/src/support/FileMonitor.cpp index bdd6444..a55fd23 100644 --- a/src/support/FileMonitor.cpp +++ b/src/support/FileMonitor.cpp @@ -3,7 +3,7 @@ * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * - * \author Angus Leeming + * \author Guillaume Munch * * Full author contact details are available in file CREDITS. */ @@ -12,170 +12,199 @@ #include "support/FileMonitor.h" +#include "support/debug.h" #include "support/FileName.h" -#include "support/Timeout.h" +#include "support/qstring_helpers.h" +#include "support/unique_ptr.h" -#include "support/bind.h" -#include +#include +#include + +#include using namespace std; namespace lyx { namespace support { -class FileMonitor::Impl : public boost::signals2::trackable { -public: - - /// - Impl(FileName const & file_with_path, int interval); - - /// - void monitorFile(); - - /// - FileName filename_; - /// - Timeout timer_; - - /// This signal is emitted if the file is modified (has a new checksum). - FileMonitor::FileChangedSig fileChanged_; - - /** We use these to ascertain whether a file (once loaded successfully) -* has changed. -*/ - time_t timestamp_; - /// - unsigned long checksum_; -}; +FileSystemWatcher & FileSystemWatcher::instance() +{ + // This thread-safe because QFileSystemWatcher is thread-safe. + static FileSystemWatcher f; + return f; +} -FileMonitor::FileMonitor(FileName const & file_with_path, int interval) - : pimpl_(new Impl(file_with_path, interval)) +FileSystemWatcher::FileSystemWatcher() + : qwatcher_(make_unique()) {} -FileMonitor::~FileMonitor() +//static +FileMonitorPtr FileSystemWatcher::monitor(FileName const & file_with_path) { - delete pimpl_; + FileSystemWatcher & f = instance(); + string const filename = file_with_path.absFileName(); + weak_ptr & wptr = f.store_[filename]; + if (shared_ptr mon = wptr.lock()) + return make_unique(mon); + auto mon = make_shared(filename, f.qwatcher_.get()); + wptr = mon; + return make_unique(mon); } -void FileMonitor::reset(FileName const & file_with_path) const +//static +void FileSystemWatcher::debug() { - if (pimpl_->filename_ == file_with_path) - return; - - bool const monitor = pimpl_->timer_.running(); - if (monitor) - stop(); + FileSystemWatcher & f = instance(); + QStringList q_files = f.qwatcher_->files(); + for (pair> pair : f.store_) { + string const & name = pair.first; + if (!pair.second.expired()) { + if (!q_files.contains(toqstr(name))) + LYXERR0("Monitored but not QFileSystemWatched (bad): " << name); + else { + //LYXERR0("Monitored and QFileSystemWatched (good): " << name); + } + } + } + for (QString const & qname : q_files) { + string const name = fromqstr(qname); + weak_ptr & wptr = f.store_[name]; + if (wptr.expired()) + LYXERR0("QFileSystemWatched but not monitored (bad): " << name); + } +} - pimpl_->filename_ = file_with_path; - if (monitor) - start(); +FileMonitorGuard::FileMonitorGuard(string const & filename, + QFileSystemWatcher * qwatcher) + : filename_(filename), qwatcher_(qwatcher) +{ + QObject::connect(qwatcher, SIGNAL(fileChanged(QString const &)), +this, SLOT(notifyChange(QString const &))); + if (qwatcher_->files().contains(toqstr(filename))) + LYXERR0("This file is already being QFileSystemWatched: " << filename + << ". This should not happen."); + refresh(); } -FileName const & FileMonitor::filename() const +FileMonitorGuard::~FileMonitorGuard() { - return pimpl_->filename_; + qwatcher_->removePath(toqstr(filename_)); } -void FileMonitor::start() const +void FileMonitorGuard::refresh(bool new_file) { - if (monitoring()) - return; - - if (!pimpl_->filename_.exists()) - return; + Q
[LyX/master] Clean-up
commit 656bc46892c2041437111dfff697957530e75ec2 Author: Guillaume Munch Date: Wed Mar 1 20:32:33 2017 +0100 Clean-up --- src/Buffer.cpp | 18 +- src/Buffer.h |2 +- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/Buffer.cpp b/src/Buffer.cpp index ac01cf4..5c46fb3 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -264,9 +264,8 @@ public: /// Container for all sort of Buffer dependant errors. map errorLists; - /// timestamp and checksum used to test if the file has been externally - /// modified. (Used to properly enable 'File->Revert to saved', bug 4114). - time_t timestamp_; + /// checksum used to test if the file has been externally modified. Used to + /// double check whether the file had been externally modified when saving. unsigned long checksum_; /// @@ -436,7 +435,7 @@ Buffer::Impl::Impl(Buffer * owner, FileName const & file, bool readonly_, : owner_(owner), lyx_clean(true), bak_clean(true), unnamed(false), internal_buffer(false), read_only(readonly_), filename(file), file_fully_loaded(false), file_format(LYX_FORMAT), need_format_backup(false), - ignore_parent(false), toc_backend(owner), macro_lock(false), timestamp_(0), + ignore_parent(false), toc_backend(owner), macro_lock(false), checksum_(0), wa_(0), gui_(0), undo_(*owner), bibinfo_cache_valid_(false), bibfile_cache_valid_(false), cite_labels_valid_(false), preview_error_(false), inset(0), preview_loader_(0), cloned_buffer_(cloned_buffer), @@ -3026,16 +3025,9 @@ bool Buffer::isChecksumModified() const void Buffer::saveCheckSum() const { FileName const & file = d->filename; - file.refresh(); - if (file.exists()) { - d->timestamp_ = file.lastModified(); - d->checksum_ = file.checksum(); - } else { - // in the case of save to a new file. - d->timestamp_ = 0; - d->checksum_ = 0; - } + d->checksum_ = file.exists() ? file.checksum() + : 0; // in the case of save to a new file. } diff --git a/src/Buffer.h b/src/Buffer.h index 957d54c..7327de3 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -231,7 +231,7 @@ private: typedef std::map BufferMap; /// void cloneWithChildren(BufferMap &, CloneList *) const; - /// save timestamp and checksum of the given file. + /// save checksum of the given file. void saveCheckSum() const; /// read a new file ReadStatus readFile(support::FileName const & fn);
[LyX/master] buffer-export default
commit 3dec5826dae76e89a80ea9a0404467f8200fa783 Author: Guillaume Munch Date: Thu Mar 9 23:35:27 2017 +0100 buffer-export default --- src/Buffer.cpp|6 +++--- src/LyX.cpp |2 +- src/LyXAction.cpp |2 +- src/frontends/qt4/GuiView.cpp |2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Buffer.cpp b/src/Buffer.cpp index d01336e..6b41213 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -2534,7 +2534,7 @@ bool Buffer::getStatus(FuncRequest const & cmd, FuncStatus & flag) enable = true; break; } - string format = (arg.empty() || arg == "*") ? + string format = (arg.empty() || arg == "default") ? params().getDefaultOutputFormat() : to_utf8(arg); size_t pos = format.find(' '); if (pos != string::npos) @@ -2643,7 +2643,7 @@ void Buffer::dispatch(FuncRequest const & func, DispatchResult & dr) break; case LFUN_BUFFER_EXPORT: { - string const format = (argument.empty() || argument == "*") ? + string const format = (argument.empty() || argument == "default") ? params().getDefaultOutputFormat() : argument; ExportStatus const status = doExport(format, false); dr.setError(status != ExportSuccess); @@ -4231,7 +4231,7 @@ Buffer::ExportStatus Buffer::doExport(string const & target, bool put_in_tempdir if (pos != string::npos) { dest_filename = target.substr(pos + 1, target.length() - pos - 1); format = target.substr(0, pos); - if (format == "*") + if (format == "default") format = params().getDefaultOutputFormat(); runparams.export_folder = FileName(dest_filename).onlyPath().realPath(); FileName(dest_filename).onlyPath().createPath(); diff --git a/src/LyX.cpp b/src/LyX.cpp index d7f3243..c88e205 100644 --- a/src/LyX.cpp +++ b/src/LyX.cpp @@ -1182,7 +1182,7 @@ int parse_help(string const &, string const &, string &) " Tools->Preferences->File Handling->File Formats->Short Name\n" " to see which parameter (which differs from the format name\n" " in the File->Export menu) should be passed. To export to\n" - " the document's default output format, use '*'.\n" + " the document's default output format, use 'default'.\n" " Note that the order of -e and -x switches matters.\n" "\t-E [--export-to] fmt filename\n" " where fmt is the export format of choice (see --export),\n" diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp index 1ac74db..673cf3b 100644 --- a/src/LyXAction.cpp +++ b/src/LyXAction.cpp @@ -583,7 +583,7 @@ void LyXAction::init() want to start from and for the command that you want to apply to this format. Internally the control is then passed to #LFUN_BUFFER_EXPORT_CUSTOM.\n -If absent or *, then the default output format of the +If absent or "default", then the default output format of the document is used. If present, this argument provides the export destination filename. Its containing folder will also be the destination diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp index 63bd4c6..b4d0810 100644 --- a/src/frontends/qt4/GuiView.cpp +++ b/src/frontends/qt4/GuiView.cpp @@ -3548,7 +3548,7 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) else target_dir = doc_buffer->fileName().onlyPath(); - string const format = (argument.empty() || argument == "*") ? + string const format = (argument.empty() || argument == "default") ? doc_buffer->params().getDefaultOutputFormat() : argument; if ((dest.empty() && doc_buffer->isUnnamed())
[LyX/master] Clarify dialog
commit 22ce6636efc236aff26244180c9a46508b291aa3 Author: Guillaume Munch Date: Sun Mar 5 23:55:59 2017 +0100 Clarify dialog --- src/frontends/qt4/GuiView.cpp | 15 ++- 1 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp index 52a783a..1f1ec61 100644 --- a/src/frontends/qt4/GuiView.cpp +++ b/src/frontends/qt4/GuiView.cpp @@ -3735,11 +3735,16 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) if (!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")); + doc_buffer->notifiesExternalModification(); + docstring text = doc_buffer->notifiesExternalModification() ? + _("Any changes will be lost. " + "Are you sure you want to load the version on disk " + "of the document %1$s?") + : _("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 file on disk?"), + bformat(text, file), 1, 1, _("&Revert"), _("&Cancel")); } if (ret == 0) {
[LyX/master] Add option to ignore a parameter in InsetCommandParams
commit 387ac780883f16ef8edb647c4b556d42f4cd33bf Author: Guillaume Munch Date: Tue Feb 14 21:16:39 2017 +0100 Add option to ignore a parameter in InsetCommandParams It will not be saved to the file and will always be equal to a given default value. --- src/insets/InsetCommandParams.cpp | 26 +- src/insets/InsetCommandParams.h | 17 +++-- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/insets/InsetCommandParams.cpp b/src/insets/InsetCommandParams.cpp index 5ea28ff..1acb72f 100644 --- a/src/insets/InsetCommandParams.cpp +++ b/src/insets/InsetCommandParams.cpp @@ -99,8 +99,10 @@ static ParamInfo const & findInfo(InsetCode code, string const & cmdName) / ParamInfo::ParamData::ParamData(std::string const & s, ParamType t, - ParamHandling h) - : name_(s), type_(t), handling_(h) +ParamHandling h, bool ignore, +docstring default_value) + : name_(s), type_(t), handling_(h), ignore_(ignore), + default_value_(default_value) {} @@ -130,9 +132,10 @@ bool ParamInfo::hasParam(std::string const & name) const void ParamInfo::add(std::string const & name, ParamType type, - ParamHandling handling) -{ - info_.push_back(ParamData(name, type, handling)); +ParamHandling handling, bool ignore, +docstring default_value) +{ + info_.push_back(ParamData(name, type, handling, ignore, default_value)); } @@ -296,6 +299,11 @@ void InsetCommandParams::Read(Lexer & lex, Buffer const * buffer) } info_ = findInfo(insetCode_, cmdName_); + + for (ParamInfo::ParamData const & param : info_) + if (param.ignore()) { + params_[param.name()] = param.defaultValue(); + } string token; while (lex.isOK()) { @@ -361,6 +369,8 @@ void InsetCommandParams::Write(ostream & os, Buffer const * buffer) const ParamInfo::const_iterator it = info_.begin(); ParamInfo::const_iterator end = info_.end(); for (; it != end; ++it) { + if (it->ignore()) + continue; string const & name = it->name(); string data = to_utf8((*this)[name]); if (!data.empty()) { @@ -538,6 +548,9 @@ docstring const & InsetCommandParams::operator[](string const & name) const ParamMap::const_iterator data = params_.find(name); if (data == params_.end() || data->second.empty()) return dummy; + ParamInfo::ParamData const & param = info_[name]; + if (param.ignore()) + return param.defaultValue(); return data->second; } @@ -546,6 +559,9 @@ docstring & InsetCommandParams::operator[](string const & name) { LATTEST(info_.hasParam(name)); // this will add the name in release mode + ParamInfo::ParamData const & param = info_[name]; + if (param.ignore()) + params_[name] = param.defaultValue(); return params_[name]; } diff --git a/src/insets/InsetCommandParams.h b/src/insets/InsetCommandParams.h index 4107378..861565a 100644 --- a/src/insets/InsetCommandParams.h +++ b/src/insets/InsetCommandParams.h @@ -52,7 +52,9 @@ public: // flag for all commands. public: /// - ParamData(std::string const &, ParamType, ParamHandling = HANDLING_NONE); + ParamData(std::string const &, ParamType, ParamHandling = HANDLING_NONE, + bool ignore = false, + docstring default_value = docstring()); /// std::string name() const { return name_; } /// @@ -62,6 +64,10 @@ public: /// whether this is an optional LaTeX argument bool isOptional() const; /// + bool ignore() const { return ignore_; } + /// + docstring const & defaultValue() const { return default_value_; } + /// bool operator==(ParamData const &) const; /// bool operator!=(ParamData const & rhs) const @@ -73,11 +79,18 @@ public: ParamType type_; /// do we need special handling on latex output? ParamHandling handling_; + /// + bool ignore_; + /// + docstring default_value_; }; /// adds a new parameter + /// If ignore is true, then the parameter is never saved, and is always + /// given the default value. void add(std::string const & name, ParamType type, -ParamHandling = HANDLING_NONE); +ParamHandling = HANDLING_NONE, bo
[LyX/master] New LFUN buffer-external-modification-clear
commit 299242bb16e2fdd026ac975e8ac4d81e8dfef890 Author: Guillaume Munch Date: Wed Mar 1 21:16:37 2017 +0100 New LFUN buffer-external-modification-clear --- src/FuncCode.h|1 + src/LyXAction.cpp | 10 ++ src/frontends/qt4/GuiView.cpp |9 + 3 files changed, 20 insertions(+), 0 deletions(-) diff --git a/src/FuncCode.h b/src/FuncCode.h index ad9cb56..4ad5a78 100644 --- a/src/FuncCode.h +++ b/src/FuncCode.h @@ -468,6 +468,7 @@ enum FuncCode LFUN_BRANCH_INVERT, // rgheck, 20160712 LFUN_LYX_ACTIVATE, // skostysh, 20160804 LFUN_ICON_SIZE, // daniel, 20160712 + LFUN_BUFFER_EXTERNAL_MODIFICATION_CLEAR,// gm, 20170302 LFUN_LASTACTION // end of the table }; diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp index 673cf3b..337 100644 --- a/src/LyXAction.cpp +++ b/src/LyXAction.cpp @@ -879,6 +879,16 @@ void LyXAction::init() { LFUN_BUFFER_WRITE_AS, "buffer-write-as", ReadOnly, Buffer }, /*! + * \var lyx::FuncCode lyx::LFUN_BUFFER_EXTERNAL_MODIFICATION_CLEAR + * \li Action: Clear the external modification flag on the current buffer. + * \li Syntax: buffer-external-modification-clear + * \li Origin: gm, 2 March 2017 + * \endvar + */ + { LFUN_BUFFER_EXTERNAL_MODIFICATION_CLEAR, + "buffer-external-modification-clear", ReadOnly, Buffer }, + +/*! * \var lyx::FuncCode lyx::LFUN_BUFFER_ZOOM_IN * \li Action: Increases the zoom of the screen fonts. * \li Syntax: buffer-zoom-in [] diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp index 7ff8e04..e2e6555 100644 --- a/src/frontends/qt4/GuiView.cpp +++ b/src/frontends/qt4/GuiView.cpp @@ -1848,6 +1848,10 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) break; } + case LFUN_BUFFER_EXTERNAL_MODIFICATION_CLEAR: + enable = doc_buffer && doc_buffer->notifiesExternalModification(); + break; + case LFUN_BUFFER_WRITE_AS: case LFUN_BUFFER_EXPORT_AS: enable = doc_buffer != 0; @@ -3773,6 +3777,11 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) break; } + case LFUN_BUFFER_EXTERNAL_MODIFICATION_CLEAR: + LASSERT(doc_buffer, break); + doc_buffer->clearExternalModification(); + break; + case LFUN_BUFFER_CLOSE: closeBuffer(); break;
[LyX/master] Amend 63be456c8
commit b034389e6def020d5201d59f6bab901453c3b5af Author: Guillaume Munch Date: Fri Mar 10 22:55:33 2017 +0100 Amend 63be456c8 Fix crash when clicking on math previews --- src/Cursor.cpp |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/src/Cursor.cpp b/src/Cursor.cpp index 2de42ba..758cef9 100644 --- a/src/Cursor.cpp +++ b/src/Cursor.cpp @@ -2443,6 +2443,8 @@ void Cursor::moveToClosestEdge(int const x, bool const edit) if (edit && (inset->hasSettings() || !inset->contextMenuName().empty())) return; CoordCache::Insets const & insetCache = bv().coordCache().getInsets(); + if (!insetCache.has(inset)) + return; int const wid = insetCache.dim(inset).wid; Point p = insetCache.xy(inset); if (x > p.x_ + (wid + 1) / 2)
[LyX/master] Replace FileMonitor with FileMonitor2 in GraphicsCacheItem
commit e3a13968139a7b9469060e2f10b7807c8e10339b Author: Guillaume Munch Date: Mon Mar 6 23:16:04 2017 +0100 Replace FileMonitor with FileMonitor2 in GraphicsCacheItem Remove dead code --- src/graphics/GraphicsCacheItem.cpp | 25 + src/graphics/GraphicsCacheItem.h |8 +--- src/graphics/GraphicsLoader.cpp|9 - src/graphics/GraphicsLoader.h |5 - 4 files changed, 14 insertions(+), 33 deletions(-) diff --git a/src/graphics/GraphicsCacheItem.cpp b/src/graphics/GraphicsCacheItem.cpp index c698168..9eb449a 100644 --- a/src/graphics/GraphicsCacheItem.cpp +++ b/src/graphics/GraphicsCacheItem.cpp @@ -45,6 +45,8 @@ public: /// Impl(FileName const & file, FileName const & doc_file); + void startMonitor(); + /** * If no file conversion is needed, then tryDisplayFormat() calls * loadImage() directly. @@ -97,7 +99,7 @@ public: /// The document filename this graphic item belongs to FileName const & doc_file_; /// - FileMonitor const monitor_; + FileMonitorPtr monitor_; /// Is the file compressed? bool zipped_; @@ -167,20 +169,13 @@ void CacheItem::startLoading() const void CacheItem::startMonitoring() const { - if (!pimpl_->monitor_.monitoring()) - pimpl_->monitor_.start(); + pimpl_->startMonitor(); } bool CacheItem::monitoring() const { - return pimpl_->monitor_.monitoring(); -} - - -unsigned long CacheItem::checksum() const -{ - return pimpl_->monitor_.checksum(); + return (bool)pimpl_->monitor_; } @@ -209,12 +204,18 @@ boost::signals2::connection CacheItem::connect(slot_type const & slot) const CacheItem::Impl::Impl(FileName const & file, FileName const & doc_file) : filename_(file), doc_file_(doc_file), - monitor_(file, 2000), zipped_(false), remove_loaded_file_(false), status_(WaitingToLoad) +{} + + +void CacheItem::Impl::startMonitor() { - monitor_.connect(bind(&Impl::startLoading, this)); + if (monitor_) + return; + monitor_ = FileSystemWatcher::monitor(filename_); + monitor_->connect([=](){ startLoading(); }); } diff --git a/src/graphics/GraphicsCacheItem.h b/src/graphics/GraphicsCacheItem.h index ee2348d..b6d7d41 100644 --- a/src/graphics/GraphicsCacheItem.h +++ b/src/graphics/GraphicsCacheItem.h @@ -66,11 +66,6 @@ public: void startMonitoring() const; /// bool monitoring() const; - /** Returns the check checksum of filename() so that, for example, you can -* ascertain whether to output a new PostScript version of the file -* for a LaTeX run. -*/ - unsigned long checksum() const; /** Get the image associated with filename(). * If the image is not yet loaded, returns 0. @@ -85,8 +80,7 @@ public: /** Connect and you'll be informed when the loading status of the image * changes. */ - typedef boost::signals2::signal sig_type; - typedef sig_type::slot_type slot_type; + typedef boost::signals2::signal::slot_type slot_type; /// boost::signals2::connection connect(slot_type const &) const; diff --git a/src/graphics/GraphicsLoader.cpp b/src/graphics/GraphicsLoader.cpp index 987a973..617ce24 100644 --- a/src/graphics/GraphicsLoader.cpp +++ b/src/graphics/GraphicsLoader.cpp @@ -328,15 +328,6 @@ bool Loader::monitoring() const } -unsigned long Loader::checksum() const -{ - if (!pimpl_->cached_item_) - return 0; - - return pimpl_->cached_item_->checksum(); -} - - FileName const & Loader::filename() const { static FileName const empty; diff --git a/src/graphics/GraphicsLoader.h b/src/graphics/GraphicsLoader.h index 8b97114..0b58857 100644 --- a/src/graphics/GraphicsLoader.h +++ b/src/graphics/GraphicsLoader.h @@ -81,11 +81,6 @@ public: void startMonitoring() const; /// bool monitoring() const; - /** Returns the check checksum of filename() so that, for example, you can -* ascertain whether to output a new PostScript version of the file -* for a LaTeX run. -*/ - unsigned long checksum() const; /// How far have we got in loading the image? ImageStatus status() const;
[LyX/master] Whitespace
commit 7c123507a4a5a79ef8cec5bb85375ce7ca99ca18 Author: Guillaume Munch Date: Tue Feb 28 22:24:51 2017 +0100 Whitespace --- src/Buffer.cpp | 10 +- 1 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 2bc454b..ac01cf4 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -1411,12 +1411,12 @@ bool Buffer::save() const // if the file does not yet exist, none of the backup activity // that follows is necessary - if (!fileName().exists()) { + if (!fileName().exists()) { if (!writeFile(fileName())) - return false; -markClean(); -return true; - } + return false; + markClean(); + return true; + } // we first write the file to a new name, then move it to its // proper location once that has been done successfully. that
[LyX/master] Disable edition when external modifications are detected
commit 0cb85e920666e8a47cb74ce96711fdcae8168862 Author: Guillaume Munch Date: Wed Mar 1 22:03:44 2017 +0100 Disable edition when external modifications are detected Introduce a distinction between being read-only and having the read-only flag. A buffer is read-only if either it has been externally modified or if it has the read-only flag. --- src/Buffer.cpp| 18 -- src/Buffer.h |6 +- src/BufferView.cpp|5 - src/LyXVC.cpp |4 ++-- src/VCBackend.cpp |4 ++-- src/frontends/qt4/GuiView.cpp | 13 +++-- src/frontends/qt4/GuiWorkArea.cpp |6 +++--- src/frontends/qt4/Menus.cpp |4 ++-- 8 files changed, 37 insertions(+), 23 deletions(-) diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 5c46fb3..b220ee3 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -2535,7 +2535,7 @@ bool Buffer::getStatus(FuncRequest const & cmd, FuncStatus & flag) switch (cmd.action()) { case LFUN_BUFFER_TOGGLE_READ_ONLY: - flag.setOnOff(isReadonly()); + flag.setOnOff(hasReadonlyFlag()); break; // FIXME: There is need for a command-line import. @@ -2659,7 +2659,7 @@ void Buffer::dispatch(FuncRequest const & func, DispatchResult & dr) dr.setMessage(log); } else - setReadonly(!isReadonly()); + setReadonly(!hasReadonlyFlag()); break; case LFUN_BUFFER_EXPORT: { @@ -3262,12 +3262,18 @@ void Buffer::setLayoutPos(string const & path) } -bool Buffer::isReadonly() const +bool Buffer::hasReadonlyFlag() const { return d->read_only; } +bool Buffer::isReadonly() const +{ + return hasReadonlyFlag() || notifiesExternalModification(); +} + + void Buffer::setParent(Buffer const * buffer) { // Avoids recursive include. @@ -4144,7 +4150,7 @@ void Buffer::moveAutosaveFile(support::FileName const & oldauto) const bool Buffer::autoSave() const { Buffer const * buf = d->cloned_buffer_ ? d->cloned_buffer_ : this; - if (buf->d->bak_clean || isReadonly()) + if (buf->d->bak_clean || hasReadonlyFlag()) return true; message(_("Autosaving current document...")); @@ -4541,7 +4547,7 @@ Buffer::ReadStatus Buffer::loadEmergency() ReadStatus const ret_llf = loadThisLyXFile(emergencyFile); bool const success = (ret_llf == ReadSuccess); if (success) { - if (isReadonly()) { + if (hasReadonlyFlag()) { Alert::warning(_("File is read-only"), bformat(_("An emergency file is successfully loaded, " "but the original file %1$s is marked read-only. " @@ -4604,7 +4610,7 @@ Buffer::ReadStatus Buffer::loadAutosave() ReadStatus const ret_llf = loadThisLyXFile(autosaveFile); // the file is not saved if we load the autosave file. if (ret_llf == ReadSuccess) { - if (isReadonly()) { + if (hasReadonlyFlag()) { Alert::warning(_("File is read-only"), bformat(_("A backup file is successfully loaded, " "but the original file %1$s is marked read-only. " diff --git a/src/Buffer.h b/src/Buffer.h index 7327de3..d483de9 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -471,9 +471,13 @@ public: /// thing from whichever Buffer it is called. ListOfBuffers allRelatives() const; - /// Is buffer read-only? + /// Is buffer read-only? True if it has either the read-only flag or the + /// externally modified flag. bool isReadonly() const; + /// Does the buffer have the read-only flag? + bool hasReadonlyFlag() const; + /// Set buffer read-only flag void setReadonly(bool flag = true); diff --git a/src/BufferView.cpp b/src/BufferView.cpp index d017db0..a6ae1d4 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -1028,7 +1028,10 @@ bool BufferView::getStatus(FuncRequest const & cmd, FuncStatus & flag) if (buffer_.isReadonly() && !lyxaction.funcHasFlag(act, LyXAction::ReadOnly) && !lyxaction.funcHasFlag(act, LyXAction::NoBuffer)) { - flag.message(from_utf8(N_("Document is read-only"))); + if (buffer_.hasReadonlyFlag()) + flag.message(from_utf8(N_("Document is read-only"))); + else + flag.message(from_utf8(N_("Document has been modified externally"))); flag.setEnabled(false); return true; } d
[LyX/master] Update fr.po
commit 8e9fb2eabcbd2386b2f3489ccb61e56d8b5c8e01 Author: jpc Date: Fri Mar 10 19:14:09 2017 +0100 Update fr.po --- po/fr.gmo | Bin 526008 -> 526220 bytes po/fr.po | 1096 +++-- 2 files changed, 552 insertions(+), 544 deletions(-) diff --git a/po/fr.gmo b/po/fr.gmo index 5248b28..6635e32 100644 Binary files a/po/fr.gmo and b/po/fr.gmo differ diff --git a/po/fr.po b/po/fr.po index b1e0b90..83c2401 100644 --- a/po/fr.po +++ b/po/fr.po @@ -322,8 +322,8 @@ msgid "" msgstr "" "Project-Id-Version: LyX 2.2\n" "Report-Msgid-Bugs-To: lyx-de...@lists.lyx.org\n" -"POT-Creation-Date: 2017-02-28 15:21+0100\n" -"PO-Revision-Date: 2017-02-28 17:00+0100\n" +"POT-Creation-Date: 2017-03-10 18:37+0100\n" +"PO-Revision-Date: 2017-03-10 18:47+0100\n" "Last-Translator: Jean-Pierre Chrétien \n" "Language-Team: lyxfr\n" "Language: fr\n" @@ -614,7 +614,7 @@ msgstr "A&jouter" #: src/frontends/qt4/ui/BibtexUi.ui:296 src/frontends/qt4/ui/ChangesUi.ui:91 #: src/frontends/qt4/ui/SendtoUi.ui:92 src/frontends/qt4/ui/ShortcutUi.ui:65 #: src/buffer_funcs.cpp:129 src/frontends/qt4/ButtonController.cpp:238 -#: src/frontends/qt4/GuiApplication.cpp:1819 +#: src/frontends/qt4/GuiApplication.cpp:1817 #: src/frontends/qt4/GuiCompare.cpp:192 msgid "Cancel" msgstr "Annuler" @@ -1010,8 +1010,8 @@ msgid "Remove the selected branch" msgstr "Enlever la branche sélectionnée" #: src/frontends/qt4/ui/BranchesUi.ui:136 -#: src/frontends/qt4/ui/IndicesUi.ui:165 src/Buffer.cpp:4547 -#: src/Buffer.cpp:4560 +#: src/frontends/qt4/ui/IndicesUi.ui:165 src/Buffer.cpp:4550 +#: src/Buffer.cpp:4563 msgid "&Remove" msgstr "&Enlever" @@ -1044,8 +1044,8 @@ msgstr "Ajouter &tout" #: src/frontends/qt4/ui/CompareHistoryUi.ui:205 #: src/frontends/qt4/ui/DocumentUi.ui:84 src/frontends/qt4/ui/IndexUi.ui:78 #: src/frontends/qt4/ui/ListingsUi.ui:559 -#: src/frontends/qt4/ui/PrintindexUi.ui:108 src/Buffer.cpp:1382 -#: src/Buffer.cpp:4521 src/Buffer.cpp:4585 src/LyXVC.cpp:114 src/LyXVC.cpp:304 +#: src/frontends/qt4/ui/PrintindexUi.ui:108 src/Buffer.cpp:1383 +#: src/Buffer.cpp:4524 src/Buffer.cpp:4588 src/LyXVC.cpp:114 src/LyXVC.cpp:304 #: src/buffer_funcs.cpp:78 src/frontends/qt4/GuiBranches.cpp:219 #: src/frontends/qt4/GuiClipboard.cpp:247 #: src/frontends/qt4/GuiDocument.cpp:2209 @@ -1233,7 +1233,7 @@ msgstr "Série de police" #: lib/layouts/europasscv.layout:380 lib/layouts/europecv.layout:246 #: lib/layouts/europecv.layout:252 lib/layouts/moderncv.layout:467 #: src/frontends/qt4/GuiDocument.cpp:1451 src/frontends/qt4/GuiPrefs.cpp:2370 -#: src/frontends/qt4/Menus.cpp:893 +#: src/frontends/qt4/Menus.cpp:902 msgid "Language" msgstr "Langue" @@ -6774,8 +6774,8 @@ msgstr "Solution \\thesolution." msgid "Summary" msgstr "Résumé" -#: lib/layouts/AEA.layout:300 src/frontends/qt4/Menus.cpp:1692 -#: src/frontends/qt4/Menus.cpp:1707 +#: lib/layouts/AEA.layout:300 src/frontends/qt4/Menus.cpp:1701 +#: src/frontends/qt4/Menus.cpp:1716 msgid "Caption" msgstr "Légende" @@ -7423,7 +7423,7 @@ msgstr "SousSousSection" #: lib/layouts/scrlettr.layout:165 lib/layouts/scrlttr2.layout:244 #: lib/layouts/siamltex.layout:237 lib/layouts/stdtitle.inc:54 #: lib/layouts/svcommon.inc:369 lib/layouts/tufte-book.layout:43 -#: lib/ui/stdmenus.inc:395 +#: lib/ui/stdmenus.inc:397 msgid "Date" msgstr "Date" @@ -17628,71 +17628,71 @@ msgstr "Unicode (XeTeX) (utf8)" msgid "ASCII" msgstr "ASCII" -#: lib/ui/stdcontext.inc:30 lib/ui/stdmenus.inc:456 +#: lib/ui/stdcontext.inc:30 lib/ui/stdmenus.inc:458 msgid "Array Environment|y" msgstr "Environnement tableau|b" -#: lib/ui/stdcontext.inc:31 lib/ui/stdmenus.inc:457 +#: lib/ui/stdcontext.inc:31 lib/ui/stdmenus.inc:459 msgid "Cases Environment|C" msgstr "Environnement cas|c" -#: lib/ui/stdcontext.inc:32 lib/ui/stdmenus.inc:458 +#: lib/ui/stdcontext.inc:32 lib/ui/stdmenus.inc:460 msgid "Aligned Environment|l" msgstr "Environnement Aligné|v" -#: lib/ui/stdcontext.inc:33 lib/ui/stdmenus.inc:459 +#: lib/ui/stdcontext.inc:33 lib/ui/stdmenus.inc:461 msgid "AlignedAt Environment|v" msgstr "Environnement AlignéSur|é" -#: lib/ui/stdcontext.inc:34 lib/ui/stdmenus.inc:460 +#: lib/ui/stdcontext.inc:34 lib/ui/stdmenus.inc:462 msgid "Gathered Environment|h" msgstr "Environnement Rassemblé|m" -#: lib/ui/stdcontext.inc:35 lib/ui/stdmenus.inc:461 +#: lib/ui/stdcontext.inc:35 lib/ui/stdmenus.inc:463 msgid "Split Environment|S" msgstr "Environnement disjoint|j" -#: lib/ui/stdcontext.inc:37 lib/ui/stdmenus.inc:463 +#: lib/ui/stdcontext.inc:37 lib/ui/stdmenus.inc:465 msgid "Delimiters...|r" msgstr "Délimiteurs...|r" -#: lib/ui/stdcontext.inc:38 lib/ui/stdmenus.inc:464 +#: lib/ui/stdcontext.inc:38 lib/ui/stdmenus.inc:466 msgid "Matrix...|x" msgstr "Matrice...|t" -#: lib/ui/stdcontext.inc:39 lib/ui/stdmenus.inc:465 +#: lib/ui/stdcontext.inc:39 lib/ui/stdmenus.inc:467 msgid "Macro|o" msgstr "Macro|o" -#: lib/ui/stdcontext.inc:43 li
[LyX/master] Class agutex.cls is obsolete: information given in the LyX template
commit ac06a54163d7867c1df8852de51ee411e2dd631f Author: jpc Date: Fri Mar 10 19:11:22 2017 +0100 Class agutex.cls is obsolete: information given in the LyX template --- lib/templates/AGUTeX.lyx | 23 +-- 1 files changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/templates/AGUTeX.lyx b/lib/templates/AGUTeX.lyx index 056fa2f..d648055 100644 --- a/lib/templates/AGUTeX.lyx +++ b/lib/templates/AGUTeX.lyx @@ -1,5 +1,5 @@ -#LyX 2.2 created this file. For more info see http://www.lyx.org/ -\lyxformat 508 +#LyX 2.3 created this file. For more info see http://www.lyx.org/ +\lyxformat 534 \begin_document \begin_header \save_transient_properties true @@ -59,6 +59,7 @@ theorems-std \font_osf false \font_sf_scale 100 100 \font_tt_scale 100 100 +\use_microtype false \graphics default \default_output_format default \output_sync 0 @@ -96,7 +97,8 @@ theorems-std \tocdepth 3 \paragraph_separation indent \paragraph_indentation default -\quotes_language english +\quotes_style english +\dynamic_quotes 0 \papercolumns 1 \papersides 1 \paperpagestyle default @@ -114,9 +116,9 @@ theorems-std status open \begin_layout Plain Layout -This is a template \SpecialChar LyX - file for articles to be submitted to Journals of the - American Geophysical Union (AGU). +This is an OBSOLETE template \SpecialChar LyX + file for articles to be submitted to Journals + of the American Geophysical Union (AGU). How to install the AGU\SpecialChar TeX \SpecialChar LaTeX class to your \SpecialChar LaTeX @@ -131,7 +133,12 @@ http://wiki.lyx.org/Examples/AGUTeX \end_inset +: the new AGU class name is +\family sans +agujournal.cls +\family default . + A template LyX file and the corresponding layout are pending. \end_layout \end_inset @@ -385,6 +392,7 @@ A & = & \prod_{i=1}^{\infty}B\nonumber \\ \begin_inset CommandInset citation LatexCommand citet key "jskilby,inproceedings-minimal" +literal "true" \end_inset @@ -393,6 +401,7 @@ key "jskilby,inproceedings-minimal" \begin_inset CommandInset citation LatexCommand citep key "jskilbye" +literal "true" \end_inset @@ -569,6 +578,7 @@ Or plain bibliography: LatexCommand bibitem label "\\textit{Kilby}(2008)" key "jskilby" +literal "true" \end_inset @@ -591,6 +601,7 @@ IEEE Trans. LatexCommand bibitem label "\\textit{Kilby et al.}(2008)" key "jskilbye" +literal "true" \end_inset
[LyX/master] Experiment: limit size of strings read from lib/symbols
commit 9a013637bbe7c35dc90cb28ff874da99133a1f8b Author: Jean-Marc Lasgouttes Date: Fri Mar 10 16:29:09 2017 +0100 Experiment: limit size of strings read from lib/symbols Coverity complains that we might read strings that are arbitrary large, and that this can be a security issue. This is a problem in particular, when we feed these strings to from_utf8(), which coverity flags as dangerous for some reason. The best solution would be IMO to model from_utf8() properly, but I do not know how to do that. Here I try a different solution, where I cannot read a string larger than 64k from the file. Let's see whether this removes part of coverity warnings. --- src/mathed/MathFactory.cpp |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/src/mathed/MathFactory.cpp b/src/mathed/MathFactory.cpp index 3198f80..2cd045b 100644 --- a/src/mathed/MathFactory.cpp +++ b/src/mathed/MathFactory.cpp @@ -74,6 +74,7 @@ #include "LyX.h" // use_gui #include "OutputParams.h" +#include using namespace std; using namespace lyx::support; @@ -188,7 +189,7 @@ void initSymbols() string extra; string xmlname; bool hidden = false; - is >> macro >> requires; + is >> setw(65536) >> macro >> requires; if ((is >> xmlname)) { extra = requires; if (!(is >> requires))
[LyX/master] Small cleanup to LayoutBox and CategorizedCombo
commit 0f220503ff9f0b571ce3d3f8ee5941cf344edff7 Author: Jean-Marc Lasgouttes Date: Fri Mar 10 15:54:27 2017 +0100 Small cleanup to LayoutBox and CategorizedCombo Coverity does not find it obvious that p is never negative. Normally it is the case (because the items have been filtered), but it is better to play safe. --- src/frontends/qt4/CategorizedCombo.cpp |4 ++-- src/frontends/qt4/LayoutBox.cpp|4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/frontends/qt4/CategorizedCombo.cpp b/src/frontends/qt4/CategorizedCombo.cpp index 8e4fc64..4509e79 100644 --- a/src/frontends/qt4/CategorizedCombo.cpp +++ b/src/frontends/qt4/CategorizedCombo.cpp @@ -271,10 +271,10 @@ QString CCItemDelegate::underlineFilter(QString const & s) const // step through data item and put "(x)" for every matching character QString r; int lastp = -1; - cc_->filter(); for (int i = 0; i < f.length(); ++i) { int p = s.indexOf(f[i], lastp + 1, Qt::CaseInsensitive); - LASSERT(p != -1, /**/); + if (p < 0) + continue; if (lastp == p - 1 && lastp != -1) { // remove ")" and append "x)" r = r.left(r.length() - 4) + s[p] + ""; diff --git a/src/frontends/qt4/LayoutBox.cpp b/src/frontends/qt4/LayoutBox.cpp index 09dd878..8945ed0 100644 --- a/src/frontends/qt4/LayoutBox.cpp +++ b/src/frontends/qt4/LayoutBox.cpp @@ -320,10 +320,10 @@ QString LayoutItemDelegate::underlineFilter(QString const & s) const // step through data item and put "(x)" for every matching character QString r; int lastp = -1; - layout_->filter(); for (int i = 0; i < f.length(); ++i) { int p = s.indexOf(f[i], lastp + 1, Qt::CaseInsensitive); - LASSERT(p != -1, continue); + if (p < 0) + continue; if (lastp == p - 1 && lastp != -1) { // remove ")" and append "x)" r = r.left(r.length() - 4) + s[p] + "";
[LyX/master] Add label 'defaultoutput' to export tests using document default output format
commit c99e2f1fad4f19d7a9f7114850558bcd82f83c98 Author: Kornel Benko Date: Fri Mar 10 14:32:21 2017 +0100 Add label 'defaultoutput' to export tests using document default output format --- development/autotests/ExportTests.cmake | 103 +-- 1 files changed, 56 insertions(+), 47 deletions(-) diff --git a/development/autotests/ExportTests.cmake b/development/autotests/ExportTests.cmake index 3f91b13..ad99163 100644 --- a/development/autotests/ExportTests.cmake +++ b/development/autotests/ExportTests.cmake @@ -48,7 +48,7 @@ macro(initLangVars varname) endforeach() endmacro() -macro(getoutputformats filepath varname) +macro(getoutputformats filepath varname format_set) file(STRINGS "${filepath}" lines) # What should we test, if default_output_format is not defined? # For now we test everything ... @@ -58,18 +58,21 @@ macro(getoutputformats filepath varname) set(_format ${CMAKE_MATCH_1}) if(_format STREQUAL "default") set(out_formats "xhtml" ${DVI_FORMATS} ${PDF_FORMATS}) - elseif(_format STREQUAL "pdf2" AND "${filepath}" MATCHES "/doc/") -set(out_formats "xhtml" ${DVI_FORMATS} ${PDF_FORMATS}) - elseif(_format MATCHES "pdf$") -set(out_formats "xhtml" ${PDF_FORMATS}) - elseif(_format MATCHES "dvi$") -set(out_formats "xhtml" ${DVI_FORMATS}) - elseif(_format MATCHES "xhtml") -set(out_formats "xhtml") else() -# Respect all other output formats -# like "eps3" -set(out_formats "xhtml" ${_format}) +set(${format_set} ${_format}) +if(_format STREQUAL "pdf2" AND "${filepath}" MATCHES "/doc/") + set(out_formats "xhtml" ${DVI_FORMATS} ${PDF_FORMATS}) +elseif(_format MATCHES "pdf$") + set(out_formats "xhtml" ${PDF_FORMATS}) +elseif(_format MATCHES "dvi$") + set(out_formats "xhtml" ${DVI_FORMATS}) +elseif(_format MATCHES "xhtml") + set(out_formats "xhtml") +else() + # Respect all other output formats + # like "eps3" + set(out_formats "xhtml" ${_format}) +endif() endif() break() endif() @@ -161,10 +164,10 @@ macro(maketestname testname inverted listinverted listignored listunreliable lis findexpr(foundsuspended ${testname} ${listsuspendedx} sublabel3) set(${inverted} 1) if (foundsuspended) - set(sublabel "suspended" ${sublabel} ${sublabel2} ${sublabel3}) - list(REMOVE_ITEM sublabel "export" "inverted" ) +set(sublabel "suspended" ${sublabel} ${sublabel2} ${sublabel3}) +list(REMOVE_ITEM sublabel "export" "inverted" ) else() - set(sublabel "inverted" ${sublabel} ${sublabel2} ${sublabel3}) +set(sublabel "inverted" ${sublabel} ${sublabel2} ${sublabel3}) endif() else() set(${inverted} 0) @@ -218,12 +221,12 @@ macro(loadTestList filename resList depth splitlangs) list(REMOVE_DUPLICATES mylabels) set(sublabel ${_newl}) else() - if (${splitlangs} MATCHES "ON") - string(REGEX REPLACE "(\\/|\\||\\(|\\))" " " _vxx ${_newl}) - string(REGEX MATCHALL " ([a-z][a-z](_[A-Z][A-Z])?) " _vx ${_vxx}) - else() - set(_vx OFF) - endif() +if (${splitlangs} MATCHES "ON") + string(REGEX REPLACE "(\\/|\\||\\(|\\))" " " _vxx ${_newl}) + string(REGEX MATCHALL " ([a-z][a-z](_[A-Z][A-Z])?) " _vx ${_vxx}) +else() + set(_vx OFF) +endif() if(_vx) foreach(_v ${_vx}) string(REGEX REPLACE " " "" _v ${_v}) @@ -377,7 +380,8 @@ foreach(libsubfolderx autotests/export lib/doc lib/examples lib/templates autote setmarkedtestlabel(${TestName} ${mytestlabel}) #set_tests_properties(${TestName} PROPERTIES RUN_SERIAL ON) endif() -getoutputformats("${LIBSUB_SRC_DIR}/${f}.lyx" formatlist) +set(default_output_format) +getoutputformats("${LIBSUB_SRC_DIR}/${f}.lyx" formatlist default_output_format) foreach(format ${formatlist}) if(format MATCHES "dvi3|pdf4|pdf5") set(fonttypes "texF" "systemF") @@ -387,24 +391,24 @@ foreach(libsubfolderx autotests/export lib/doc lib/examples lib/templates autote foreach(fonttype ${fonttypes}) if (format MATCHES "pdf2" AND f MATCHES "latex/unicodesymbols") #message(STATUS "Test ${TestName} matches Unicode encodings") - # test_encodings does not include "default", since it should be covered - # by one of the supplied encodings + # test_encodings does not include "default", since it should be covered + # by one of the supplied encodings set(test_encodings "ascii" "utf8x" "armscii8" "applemac" - "cp437" "cp437de" "cp850" "cp852" - "cp855" "cp862" "cp865" - "cp866" "cp1250" "cp1251" "cp1252" - "cp1255" "cp1256" "cp1257" - "koi8-r" "koi8-u" -
[LyX/master] Be careful about unparsable bibtex years
commit e2f2915f8edcc558e7d41b6e9bf8e0a6838ba47d Author: Jean-Marc Lasgouttes Date: Fri Mar 10 10:32:38 2017 +0100 Be careful about unparsable bibtex years Handle gracefully the case where the regex that parses a year fails. This is a fixup to ba171930 (spotted by coverity). --- src/BiblioInfo.cpp |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/src/BiblioInfo.cpp b/src/BiblioInfo.cpp index 5e2c7db..bfde294 100644 --- a/src/BiblioInfo.cpp +++ b/src/BiblioInfo.cpp @@ -417,7 +417,9 @@ docstring const BibTeXInfo::getYear() const static regex const ereg(".*/[-]?([\\d]{4}).*"); smatch sm; string const date = to_utf8(year); - regex_match(date, sm, yreg); + if (!regex_match(date, sm, yreg)) + // cannot parse year. + return docstring(); year = from_ascii(sm[1]); // check for an endyear if (regex_match(date, sm, ereg))