]> git.lyx.org Git - features.git/commitdiff
Fix bug #7404.
authorRichard Heck <rgheck@lyx.org>
Mon, 2 Apr 2018 02:40:00 +0000 (22:40 -0400)
committerRichard Kimberly Heck <rikiheck@lyx.org>
Tue, 11 Dec 2018 22:43:17 +0000 (17:43 -0500)
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
src/FuncCode.h
src/LyXAction.cpp
src/insets/InsetCollapsible.cpp
src/insets/InsetERT.cpp
src/insets/InsetERT.h

index 47cf349784e0719ab710500cc192704fc603f7db..de3b48c8ccead19e5d1bead3149fe2cf6a71eec9 100644 (file)
@@ -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
 
 #
index b4ac25ef07d36b75df7da5ce5bda0954477e4be5..3565cecaf9e9f908dc3fa94699f7f753b1b03dc4 100644 (file)
@@ -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
 };
 
index 35ae6aae87b5ea30b3218f85dcb031f84de5178f..a9307c3bc63181ba55bf09a4064d2a64da9b9952 100644 (file)
@@ -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
index c429c51b417c2ed34999f876ff78f1503c1ca1ce..c20e9ce9881fcb0c7c419149d9fdd299d921459a 100644 (file)
@@ -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;
index 2d96f952f636c919df1bce41594089f77231df4f..25665471038b733c7c063e838b72a380136902f4 100644 (file)
@@ -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"
 #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)
index 87ed11616a302e8be87e7d399a4ced83d024c205..bfe15126dab662a39683748392f52a8176f3805e 100644 (file)
@@ -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_;
 };