commit ebc409264980a2e582d4d7ac6f23678d4f7b55ae
Author: Juergen Spitzmueller <sp...@lyx.org>
Date:   Sat Mar 23 10:17:33 2019 +0100

    Add LFUN_BUFFER_WRITE_AS_TEMPLATE
    
    Convenience function to easier save a file as template in the appropriate
    templates folder.
---
 lib/ui/stdmenus.inc                  |    1 +
 src/FuncCode.h                       |    1 +
 src/LyXAction.cpp                    |   11 ++++++
 src/frontends/qt4/GuiApplication.cpp |    3 +-
 src/frontends/qt4/GuiView.cpp        |   64 ++++++++++++++++++++++++++++++++--
 src/frontends/qt4/GuiView.h          |    9 ++++-
 6 files changed, 84 insertions(+), 5 deletions(-)

diff --git a/lib/ui/stdmenus.inc b/lib/ui/stdmenus.inc
index 9f6515d..afe883a 100644
--- a/lib/ui/stdmenus.inc
+++ b/lib/ui/stdmenus.inc
@@ -52,6 +52,7 @@ Menuset
                Item "Close All" "buffer-close-all"
                Item "Save|S" "buffer-write"
                Item "Save As...|A" "buffer-write-as"
+               Item "Save As Template..." "buffer-write-as-template"
                Item "Save All|l" "buffer-write-all"
                Item "Revert to Saved|R" "buffer-reload"
                Submenu "Version Control|V" "file_vc"
diff --git a/src/FuncCode.h b/src/FuncCode.h
index 14b9ba1..b9aed5d 100644
--- a/src/FuncCode.h
+++ b/src/FuncCode.h
@@ -482,6 +482,7 @@ enum FuncCode
        LFUN_INSET_END_EDIT,            // gb/rkh, 20180605
        // 375
        LFUN_SEARCH_IGNORE,             // kornel, 20181115
+       LFUN_BUFFER_WRITE_AS_TEMPLATE,  // spitz, 20190323
        LFUN_LASTACTION                 // end of the table
 };
 
diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp
index 082d608..92734a2 100644
--- a/src/LyXAction.cpp
+++ b/src/LyXAction.cpp
@@ -894,6 +894,17 @@ void LyXAction::init()
                { LFUN_BUFFER_WRITE_AS, "buffer-write-as", ReadOnly, Buffer },
 
 /*!
+ * \var lyx::FuncCode lyx::LFUN_BUFFER_WRITE_AS_TEMPLATE
+ * \li Action: Rename and save current buffer in the local templates directory.
+ * \li Syntax: buffer-write-as-template <FILENAME>
+ * \li Params: <FILENAME>: New name of the buffer/file. A relative path
+              is with respect to the original location of the buffer/file.
+ * \endvar
+ */
+               { LFUN_BUFFER_WRITE_AS_TEMPLATE, "buffer-write-as-template", 
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
diff --git a/src/frontends/qt4/GuiApplication.cpp 
b/src/frontends/qt4/GuiApplication.cpp
index fdaccee..666b961 100644
--- a/src/frontends/qt4/GuiApplication.cpp
+++ b/src/frontends/qt4/GuiApplication.cpp
@@ -1222,7 +1222,8 @@ bool GuiApplication::getStatus(FuncRequest const & cmd, 
FuncStatus & flag) const
        // GuiView::getStatus(). See above.
        /*
        case LFUN_BUFFER_WRITE:
-       case LFUN_BUFFER_WRITE_AS: {
+       case LFUN_BUFFER_WRITE_AS:
+       case LFUN_BUFFER_WRITE_AS_TEMPLATE: {
                Buffer * b = theBufferList().getBuffer(FileName(cmd.getArg(0)));
                enable = b && (b->isUnnamed() || !b->isClean());
                break;
diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp
index 6624d81..2f59145 100644
--- a/src/frontends/qt4/GuiView.cpp
+++ b/src/frontends/qt4/GuiView.cpp
@@ -52,6 +52,7 @@
 #include "FuncRequest.h"
 #include "Intl.h"
 #include "Layout.h"
+#include "LayoutFile.h"
 #include "Lexer.h"
 #include "LyXAction.h"
 #include "LyX.h"
@@ -1990,6 +1991,7 @@ bool GuiView::getStatus(FuncRequest const & cmd, 
FuncStatus & flag)
                }
                // fall through
        case LFUN_BUFFER_WRITE_AS:
+       case LFUN_BUFFER_WRITE_AS_TEMPLATE:
                enable = doc_buffer != 0;
                break;
 
@@ -2646,29 +2648,78 @@ void GuiView::insertLyXFile(docstring const & fname)
 }
 
 
+string const GuiView::getTemplatesPath(Buffer & b)
+{
+       // We start off with the user's templates path
+       string result = addPath(package().user_support().absFileName(), 
"templates");
+       // 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?"),
+                                       from_utf8(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"));
+               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()));
 
@@ -2760,6 +2811,7 @@ bool GuiView::renameBuffer(Buffer & b, docstring const & 
newname, RenameKind kin
                break;
        }
        case LV_WRITE_AS:
+       case LV_WRITE_AS_TEMPLATE:
                break;
        }
        // LyXVC created the file already in case of LV_VC_RENAME or
@@ -4042,6 +4094,12 @@ void GuiView::dispatch(FuncRequest const & cmd, 
DispatchResult & dr)
                        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)
diff --git a/src/frontends/qt4/GuiView.h b/src/frontends/qt4/GuiView.h
index 3c50416..493b070 100644
--- a/src/frontends/qt4/GuiView.h
+++ b/src/frontends/qt4/GuiView.h
@@ -380,7 +380,14 @@ private:
        bool exportBufferAs(Buffer & b, docstring const & iformat);
 
        ///
-       enum RenameKind { LV_WRITE_AS, LV_VC_RENAME, LV_VC_COPY };
+       enum RenameKind {
+               LV_WRITE_AS,
+               LV_WRITE_AS_TEMPLATE,
+               LV_VC_RENAME,
+               LV_VC_COPY,
+       };
+       /// Get a path for LFUN_BUFFER_WRITE_AS_TEMPLATE
+       std::string const getTemplatesPath(Buffer & buf);
        /// Save a buffer as a new file.
        /**
        Write a buffer to a new file name and rename the buffer

Reply via email to