commit 26d4b5bb473155b44cfdf6aca14b38c2ce2d8469
Author: Richard Heck <[email protected]>
Date: Sun Apr 1 22:40:00 2018 -0400
Fix bug #7404.
This allows for external editing of ERT insets. Original patch
by Georg Baum. Updated to 2.4dev by Riki Heck.
(cherry picked from commit f17f5617e05ea8a7f179586cc16c5bb05a0e9e2d)
---
lib/ui/stdcontext.inc | 3 ++
src/FuncCode.h | 3 ++
src/LyXAction.cpp | 16 ++++++++
src/insets/InsetCollapsible.cpp | 1 +
src/insets/InsetERT.cpp | 76 +++++++++++++++++++++++++++++++++++++++
src/insets/InsetERT.h | 15 +++++++-
6 files changed, 113 insertions(+), 1 deletions(-)
diff --git a/lib/ui/stdcontext.inc b/lib/ui/stdcontext.inc
index 47cf349..de3b48c 100644
--- a/lib/ui/stdcontext.inc
+++ b/lib/ui/stdcontext.inc
@@ -664,6 +664,9 @@ Menuset
Menu "context-ert"
# repeat 1 is added as a work-around to not indicate this
action as toggable
Item "Wrap by Preview|y" "command-sequence repeat
1;inset-toggle;char-forward;char-backward;char-forward-select;preview-insert;char-backward;char-backward;inset-toggle"
+ Separator
+ Item "Edit Externally...|x" "inset-edit"
+ Item "End Editing Externally...|e" "inset-end-edit"
End
#
diff --git a/src/FuncCode.h b/src/FuncCode.h
index b4ac25e..3565cec 100644
--- a/src/FuncCode.h
+++ b/src/FuncCode.h
@@ -479,6 +479,9 @@ enum FuncCode
LFUN_BUFFER_ANONYMIZE, // sanda, 20180201
LFUN_GRAPHICS_UNIFY, // sanda, 20180207
LFUN_MASTER_BUFFER_EXPORT, // rkh, 20180417
+ LFUN_LAYOUT_TOGGLE, // lasgouttes 20180514
+ // 375
+ LFUN_INSET_END_EDIT, // gb/rkh, 20180605
LFUN_LASTACTION // end of the table
};
diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp
index 35ae6aa..a9307c3 100644
--- a/src/LyXAction.cpp
+++ b/src/LyXAction.cpp
@@ -2014,6 +2014,11 @@ void LyXAction::init()
* \var lyx::FuncCode lyx::LFUN_INSET_EDIT
* \li Action: Edit the inset at cursor with an external application,
if one is attributed.
+ If the inset is file based, the referenced file is edited.
+ Otherwise, the inset contents is written to a temporary file,
+ the inset is locked, and the temporary file is edited.
+ In this case, #LFUN_INSET_END_EDIT must be called to overtake
+ the changes and unlock the inset after editing is finished.
* \li Syntax: inset-edit [<INSET_PARAMS>]
* \li Params: <INSET_PARAMS>: Parameters for the inset. \n
Currently only the filename will be considered.
@@ -2023,6 +2028,17 @@ void LyXAction::init()
{ LFUN_INSET_EDIT, "inset-edit", ReadOnly | AtPoint, Edit },
+ /*!
+ * \var lyx::FuncCode lyx::LFUN_INSET_END_EDIT
+ * \li Action: End editing the inset at cursor with an external application.
+ * This replaces the inset contents with the contents of the
+ * temporary file, deletes the file and unlocks the inset.
+ * \li Syntax: inset-end-edit
+ * \li Origin: gb, 11 Oct 2015
+ * \endvar
+ */
+ { LFUN_INSET_END_EDIT, "inset-end-edit", ReadOnly | AtPoint,
Edit },
+
/*!
* \var lyx::FuncCode lyx::LFUN_INSET_END
* \li Action: Move the cursor to the end of the current inset if it
diff --git a/src/insets/InsetCollapsible.cpp b/src/insets/InsetCollapsible.cpp
index c429c51..c20e9ce 100644
--- a/src/insets/InsetCollapsible.cpp
+++ b/src/insets/InsetCollapsible.cpp
@@ -453,6 +453,7 @@ Inset * InsetCollapsible::editXY(Cursor & cur, int x, int y)
{
//lyxerr << "InsetCollapsible: edit xy" << endl;
if (geometry(cur.bv()) == ButtonOnly
+ || !editable()
|| (view_[&cur.bv()].button_dim_.contains(x, y)
&& geometry(cur.bv()) != NoButton))
return this;
diff --git a/src/insets/InsetERT.cpp b/src/insets/InsetERT.cpp
index 2d96f95..2566547 100644
--- a/src/insets/InsetERT.cpp
+++ b/src/insets/InsetERT.cpp
@@ -17,7 +17,9 @@
#include "BufferParams.h"
#include "BufferView.h"
#include "Cursor.h"
+#include "CutAndPaste.h"
#include "DispatchResult.h"
+#include "Format.h"
#include "FuncRequest.h"
#include "FuncStatus.h"
#include "Language.h"
@@ -29,8 +31,11 @@
#include "Paragraph.h"
#include "TextClass.h"
+#include "support/docstream.h"
+#include "support/FileName.h"
#include "support/gettext.h"
#include "support/lstrings.h"
+#include "support/TempFile.h"
#include <sstream>
@@ -46,6 +51,21 @@ InsetERT::InsetERT(Buffer * buf, CollapseStatus status)
}
+// Do not copy the temp file on purpose: If a copy of an inset which is
+// currently being edited is made, then we simply copy the current contents.
+InsetERT::InsetERT(InsetERT const & that) : InsetCollapsible(that)
+{}
+
+
+InsetERT & InsetERT::operator=(InsetERT const & that)
+{
+ if (&that == this)
+ return *this;
+ tempfile_.reset();
+ return *this;
+}
+
+
void InsetERT::write(ostream & os) const
{
os << "ERT" << "\n";
@@ -109,6 +129,40 @@ int InsetERT::docbook(odocstream & os, OutputParams const
&) const
void InsetERT::doDispatch(Cursor & cur, FuncRequest & cmd)
{
switch (cmd.action()) {
+ case LFUN_INSET_EDIT: {
+ cur.push(*this);
+ text().selectAll(cur);
+ string const format =
+ cur.buffer()->params().documentClass().outputFormat();
+ string const ext = theFormats().extension(format);
+ tempfile_.reset(new TempFile("ert_editXXXXXX." + ext));
+ FileName const tempfilename = tempfile_->name();
+ string const name = tempfilename.toFilesystemEncoding();
+ ofdocstream os(name.c_str());
+ os << cur.selectionAsString(false);
+ os.close();
+ // Since we lock the inset while the external file is edited,
+ // we need to move the cursor outside and clear any selection
inside
+ cur.clearSelection();
+ cur.pop();
+ cur.leaveInset(*this);
+ theFormats().edit(buffer(), tempfilename, format);
+ break;
+ }
+ case LFUN_INSET_END_EDIT: {
+ FileName const tempfilename = tempfile_->name();
+ docstring const s = tempfilename.fileContents("UTF-8");
+ cur.recordUndoInset(this);
+ cur.push(*this);
+ text().selectAll(cur);
+ cap::replaceSelection(cur);
+ cur.text()->insertStringAsLines(cur, s, cur.current_font);
+ // FIXME it crashes without this
+ cur.fixIfBroken();
+ tempfile_.reset();
+ cur.pop();
+ break;
+ }
case LFUN_INSET_MODIFY:
if (cmd.getArg(0) == "ert") {
cur.recordUndoInset(this);
@@ -128,6 +182,12 @@ bool InsetERT::getStatus(Cursor & cur, FuncRequest const &
cmd,
FuncStatus & status) const
{
switch (cmd.action()) {
+ case LFUN_INSET_EDIT:
+ status.setEnabled(tempfile_ == 0);
+ return true;
+ case LFUN_INSET_END_EDIT:
+ status.setEnabled(tempfile_ != 0);
+ return true;
case LFUN_INSET_MODIFY:
if (cmd.getArg(0) == "ert") {
status.setEnabled(true);
@@ -141,6 +201,22 @@ bool InsetERT::getStatus(Cursor & cur, FuncRequest const &
cmd,
}
+bool InsetERT::editable() const
+{
+ if (tempfile_)
+ return false;
+ return InsetCollapsible::editable();
+}
+
+
+bool InsetERT::descendable(BufferView const & bv) const
+{
+ if (tempfile_)
+ return false;
+ return InsetCollapsible::descendable(bv);
+}
+
+
docstring const InsetERT::buttonLabel(BufferView const & bv) const
{
if (decoration() == InsetLayout::CLASSIC)
diff --git a/src/insets/InsetERT.h b/src/insets/InsetERT.h
index 87ed116..bfe1512 100644
--- a/src/insets/InsetERT.h
+++ b/src/insets/InsetERT.h
@@ -15,7 +15,6 @@
#include "InsetCollapsible.h"
-
namespace lyx {
/** A collapsible text inset for LaTeX insertions.
@@ -29,10 +28,18 @@ namespace lyx {
class Language;
+namespace support {
+ class TempFile;
+}
+
class InsetERT : public InsetCollapsible {
public:
///
InsetERT(Buffer *, CollapseStatus status = Open);
+ ///
+ InsetERT(InsetERT const &);
+ ///
+ InsetERT & operator=(InsetERT const &);
///
static CollapseStatus string2params(std::string const &);
///
@@ -62,12 +69,18 @@ private:
void doDispatch(Cursor & cur, FuncRequest & cmd);
///
bool getStatus(Cursor & cur, FuncRequest const & cmd, FuncStatus &)
const;
+ ///
+ bool editable() const;
+ ///
+ bool descendable(BufferView const &) const;
///
Inset * clone() const { return new InsetERT(*this); }
///
docstring const buttonLabel(BufferView const & bv) const;
///
bool allowSpellCheck() const { return false; }
+ ///
+ unique_ptr<support::TempFile> tempfile_;
};