commit a08cbf41cf2b3087029c19db49dfca5aa01a4b2d
Author: Juergen Spitzmueller <sp...@lyx.org>
Date:   Tue Dec 24 14:31:08 2019 +0100

    Provide way to add (optional) user initials
    
    This makes it easier to hook the changes package into LyX's ct markup.
---
 lib/layouts/changebars.module         |   10 ++--
 src/Author.cpp                        |    8 +-
 src/Author.h                          |    7 ++-
 src/BufferParams.cpp                  |    4 +-
 src/Changes.cpp                       |   48 +++++++++++--
 src/LaTeXFeatures.cpp                 |   14 ++--
 src/LyXRC.cpp                         |   10 +++
 src/LyXRC.h                           |    3 +
 src/frontends/qt/GuiPrefs.cpp         |    8 ++-
 src/frontends/qt/ui/PrefIdentityUi.ui |  121 +++++++++++++++++++--------------
 src/tex2lyx/Preamble.cpp              |    6 +-
 src/tex2lyx/Preamble.h                |    2 +-
 src/tex2lyx/text.cpp                  |    6 ++-
 13 files changed, 166 insertions(+), 81 deletions(-)

diff --git a/lib/layouts/changebars.module b/lib/layouts/changebars.module
index b35c03c..f0c27f3 100644
--- a/lib/layouts/changebars.module
+++ b/lib/layouts/changebars.module
@@ -19,12 +19,12 @@ Format 80
 
 AddToPreamble
   \usepackage{changebar}
-  \providecommand{\lyxadded}[3]{}
+  \providecommand{\lyxadded}[4][]{}
   \providecommand{\lyxdeleted}{}
-  \renewcommand{\lyxadded}[3]{
-    {\protect\cbstart\color{lyxadded}{}#3\protect\cbend}
+  \renewcommand{\lyxadded}[4][]{
+    {\protect\cbstart\color{lyxadded}{}#4\protect\cbend}
   }
-  \renewcommand{\lyxdeleted}[3]{%
-    {\protect\cbstart\color{lyxdeleted}\sout{#3}\protect\cbend}
+  \renewcommand{\lyxdeleted}[4][]{%
+    {\protect\cbstart\color{lyxdeleted}\sout{#4}\protect\cbend}
   }
 EndPreamble
diff --git a/src/Author.cpp b/src/Author.cpp
index 3d03fe7..b70815c 100644
--- a/src/Author.cpp
+++ b/src/Author.cpp
@@ -37,14 +37,14 @@ static int computeHash(docstring const & name,
 }
 
 
-Author::Author(docstring const & name, docstring const & email)
-       : name_(name), email_(email), used_(true),
+Author::Author(docstring const & name, docstring const & email, docstring 
const & initials)
+       : name_(name), email_(email), initials_(initials), used_(true),
          buffer_id_(computeHash(name, email))
 {}
 
 
 Author::Author(int buffer_id)
-       : name_(convert<docstring>(buffer_id)), email_(docstring()), 
used_(false),
+       : name_(convert<docstring>(buffer_id)), email_(docstring()), 
initials_(docstring()), used_(false),
          buffer_id_(buffer_id)
 {}
 
@@ -67,7 +67,7 @@ bool Author::valid() const
 
 bool operator==(Author const & l, Author const & r)
 {
-       return l.name() == r.name() && l.email() == r.email();
+       return l.name() == r.name() && l.email() == r.email() && l.initials() 
== r.initials();
 }
 
 
diff --git a/src/Author.h b/src/Author.h
index 108a701..b498655 100644
--- a/src/Author.h
+++ b/src/Author.h
@@ -24,7 +24,8 @@ public:
        ///
        Author() : used_(false), buffer_id_(0) {};
        ///
-       Author(docstring const & name, docstring const & email);
+       Author(docstring const & name, docstring const & email,
+              docstring const & initials);
        /// For when the \author line is missing (#9854)
        Author(int buffer_id);
        ///
@@ -32,6 +33,8 @@ public:
        ///
        docstring email() const { return email_; }
        ///
+       docstring initials() const { return initials_; }
+       ///
        docstring nameAndEmail() const;
        ///
        int bufferId() const { return buffer_id_; }
@@ -53,6 +56,8 @@ private:
        docstring name_;
        /// The author's email address
        docstring email_;
+       /// The author's initials
+       docstring initials_;
        ///
        mutable bool used_;
        /// The id of the author in the lyx-file
diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp
index 22793ec..3b0b831 100644
--- a/src/BufferParams.cpp
+++ b/src/BufferParams.cpp
@@ -365,7 +365,9 @@ BufferParams::Impl::Impl()
 {
        // set initial author
        // FIXME UNICODE
-       authorlist.record(Author(from_utf8(lyxrc.user_name), 
from_utf8(lyxrc.user_email)));
+       authorlist.record(Author(from_utf8(lyxrc.user_name),
+                                from_utf8(lyxrc.user_email),
+                                from_utf8(lyxrc.user_initials)));
 }
 
 
diff --git a/src/Changes.cpp b/src/Changes.cpp
index 8c96338..f8f70e1 100644
--- a/src/Changes.cpp
+++ b/src/Changes.cpp
@@ -338,7 +338,7 @@ void Changes::merge()
 
 namespace {
 
-docstring getLaTeXMarkup(docstring const & macro, docstring const & author,
+docstring getLaTeXMarkup(docstring const & macro, Author const & author,
                         docstring const & chgTime,
                         OutputParams const & runparams)
 {
@@ -348,18 +348,52 @@ docstring getLaTeXMarkup(docstring const & macro, 
docstring const & author,
        docstring uncodable_author;
        odocstringstream ods;
 
+       docstring const author_name = author.name();
+       docstring const author_initials = author.initials();
+       
        ods << macro;
+       if (!author_initials.empty()) {
+               docstring uncodable_initials;
+               // convert utf8 author initials to something representable
+               // in the current encoding
+               pair<docstring, docstring> author_initials_latexed =
+                       runparams.encoding->latexString(author_initials, 
runparams.dryrun);
+               if (!author_initials_latexed.second.empty()) {
+                       LYXERR0("Omitting uncodable characters '"
+                               << author_initials_latexed.second
+                               << "' in change author initials!");
+                       uncodable_initials = author_initials;
+               }
+               ods << "[" << author_initials_latexed.first << "]";
+               // warn user (once) if we found uncodable glyphs.
+               if (!uncodable_initials.empty()) {
+                       static std::set<docstring> warned_author_initials;
+                       static Mutex warned_mutex;
+                       Mutex::Locker locker(&warned_mutex);
+                       if (warned_author_initials.find(uncodable_initials) == 
warned_author_initials.end()) {
+                               frontend::Alert::warning(_("Uncodable character 
in author initials"),
+                                       support::bformat(_("The author initials 
'%1$s',\n"
+                                         "used for change tracking, contain 
the following glyphs that\n"
+                                         "cannot be represented in the current 
encoding: %2$s.\n"
+                                         "These glyphs will be omitted in the 
exported LaTeX file.\n\n"
+                                         "Choose an appropriate document 
encoding (such as utf8)\n"
+                                         "or change the author initials."),
+                                       uncodable_initials, 
author_initials_latexed.second));
+                               warned_author_initials.insert(uncodable_author);
+                       }
+               }
+       }
        // convert utf8 author name to something representable
        // in the current encoding
        pair<docstring, docstring> author_latexed =
-               runparams.encoding->latexString(author, runparams.dryrun);
+               runparams.encoding->latexString(author_name, runparams.dryrun);
        if (!author_latexed.second.empty()) {
                LYXERR0("Omitting uncodable characters '"
                        << author_latexed.second
                        << "' in change author name!");
-               uncodable_author = author;
+               uncodable_author = author_name;
        }
-       ods << author_latexed.first << "}{" << chgTime << "}{";
+       ods << "{" << author_latexed.first << "}{" << chgTime << "}{";
 
        // warn user (once) if we found uncodable glyphs.
        if (!uncodable_author.empty()) {
@@ -414,15 +448,15 @@ int Changes::latexMarkChange(otexstream & os, 
BufferParams const & bparams,
 
        docstring macro_beg;
        if (change.type == Change::DELETED) {
-               macro_beg = from_ascii("\\lyxdeleted{");
+               macro_beg = from_ascii("\\lyxdeleted");
                if (!runparams.inDisplayMath && !dvipost)
                        ++runparams.inulemcmd;
        }
        else if (change.type == Change::INSERTED)
-               macro_beg = from_ascii("\\lyxadded{");
+               macro_beg = from_ascii("\\lyxadded");
 
        docstring str = getLaTeXMarkup(macro_beg,
-                                      
bparams.authors().get(change.author).name(),
+                                      bparams.authors().get(change.author),
                                       chgTime, runparams);
 
        // signature needed by \lyxsout to correctly strike out display math
diff --git a/src/LaTeXFeatures.cpp b/src/LaTeXFeatures.cpp
index cd04b4c..533f5ad 100644
--- a/src/LaTeXFeatures.cpp
+++ b/src/LaTeXFeatures.cpp
@@ -242,20 +242,20 @@ static docstring const changetracking_dvipost_def = 
from_ascii(
        "\\dvipost{osend color pop}\n"
        "\\dvipost{cbstart color push Blue}\n"
        "\\dvipost{cbend color pop}\n"
-       "\\DeclareRobustCommand{\\lyxadded}[3]{\\changestart#3\\changeend}\n"
-       "\\DeclareRobustCommand{\\lyxdeleted}[3]{%\n"
-       "\\changestart\\overstrikeon#3\\overstrikeoff\\changeend}\n");
+       "\\DeclareRobustCommand{\\lyxadded}[4][]{\\changestart#4\\changeend}\n"
+       "\\DeclareRobustCommand{\\lyxdeleted}[4][]{%\n"
+       "\\changestart\\overstrikeon#4\\overstrikeoff\\changeend}\n");
 
 static docstring const changetracking_xcolor_ulem_def = from_ascii(
        "%% Change tracking with ulem\n"
-       "\\DeclareRobustCommand{\\lyxadded}[3]{{\\color{lyxadded}{}#3}}\n"
-       
"\\DeclareRobustCommand{\\lyxdeleted}[3]{{\\color{lyxdeleted}\\lyxsout{#3}}}\n"
+       "\\DeclareRobustCommand{\\lyxadded}[4][]{{\\color{lyxadded}{}#4}}\n"
+       
"\\DeclareRobustCommand{\\lyxdeleted}[4][]{{\\color{lyxdeleted}\\lyxsout{#4}}}\n"
        
"\\DeclareRobustCommand{\\lyxsout}[1]{\\ifx\\\\#1\\else\\sout{#1}\\fi}\n");
 
 static docstring const changetracking_xcolor_ulem_hyperref_def = from_ascii(
        "%% Change tracking with ulem\n"
-       
"\\DeclareRobustCommand{\\lyxadded}[3]{{\\texorpdfstring{\\color{lyxadded}{}}{}#3}}\n"
-       
"\\DeclareRobustCommand{\\lyxdeleted}[3]{{\\texorpdfstring{\\color{lyxdeleted}\\lyxsout{#3}}{}}}\n"
+       
"\\DeclareRobustCommand{\\lyxadded}[4][]{{\\texorpdfstring{\\color{lyxadded}{}}{}#4}}\n"
+       
"\\DeclareRobustCommand{\\lyxdeleted}[4][]{{\\texorpdfstring{\\color{lyxdeleted}\\lyxsout{#4}}{}}}\n"
        
"\\DeclareRobustCommand{\\lyxsout}[1]{\\ifx\\\\#1\\else\\sout{#1}\\fi}\n");
 
 static docstring const changetracking_tikz_math_sout_def = from_ascii(
diff --git a/src/LyXRC.cpp b/src/LyXRC.cpp
index 83bf82d..19e28a3 100644
--- a/src/LyXRC.cpp
+++ b/src/LyXRC.cpp
@@ -201,6 +201,7 @@ LexerKeyword lyxrcTags[] = {
        { "\\use_system_theme_icons", LyXRC::RC_USE_SYSTEM_THEME_ICONS },
        { "\\use_tooltip", LyXRC::RC_USE_TOOLTIP },
        { "\\user_email", LyXRC::RC_USER_EMAIL },
+       { "\\user_initials", LyXRC::RC_USER_INITIALS },
        { "\\user_name", LyXRC::RC_USER_NAME },
        { "\\view_dvi_paper_option", LyXRC::RC_VIEWDVI_PAPEROPTION },
        // compatibility with versions older than 1.4.0 only
@@ -971,6 +972,9 @@ LyXRC::ReturnValues LyXRC::read(Lexer & lexrc, bool 
check_format)
                case RC_USER_EMAIL:
                        lexrc >> user_email;
                        break;
+               case RC_USER_INITIALS:
+                       lexrc >> user_initials;
+                       break;
 
                case RC_PATH_PREFIX:
                        lexrc >> path_prefix;
@@ -1446,6 +1450,11 @@ void LyXRC::write(ostream & os, bool 
ignore_system_lyxrc, string const & name) c
                if (tag != RC_LAST)
                        break;
                // fall through
+       case RC_USER_INITIALS:
+               os << "\\user_initials \"" << user_initials << "\"\n";
+               if (tag != RC_LAST)
+                       break;
+               // fall through
        case RC_SHOW_BANNER:
                if (ignore_system_lyxrc ||
                    show_banner != system_lyxrc.show_banner) {
@@ -2869,6 +2878,7 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC 
const & lyxrc_new)
        case LyXRC::RC_THESAURUSDIRPATH:
        case LyXRC::RC_UIFILE:
        case LyXRC::RC_USER_EMAIL:
+       case LyXRC::RC_USER_INITIALS:
        case LyXRC::RC_USER_NAME:
        case LyXRC::RC_USE_CONVERTER_CACHE:
        case LyXRC::RC_USE_CONVERTER_NEEDAUTH_FORBIDDEN:
diff --git a/src/LyXRC.h b/src/LyXRC.h
index 10df636..8e47c49 100644
--- a/src/LyXRC.h
+++ b/src/LyXRC.h
@@ -169,6 +169,7 @@ public:
                RC_UIFILE,
                RC_USELASTFILEPOS,
                RC_USER_EMAIL,
+               RC_USER_INITIALS,
                RC_USER_NAME,
                RC_USE_CONVERTER_CACHE,
                RC_USE_CONVERTER_NEEDAUTH_FORBIDDEN,
@@ -449,6 +450,8 @@ public:
        std::string user_name; // set in constructor
        /// user email
        std::string user_email; // set in constructor (empty for now)
+       /// user initials
+       std::string user_initials;
        /// icon set name
        std::string icon_set;
        /// whether to use the icons from the theme
diff --git a/src/frontends/qt/GuiPrefs.cpp b/src/frontends/qt/GuiPrefs.cpp
index 02c9234..be6204b 100644
--- a/src/frontends/qt/GuiPrefs.cpp
+++ b/src/frontends/qt/GuiPrefs.cpp
@@ -3409,9 +3409,12 @@ PrefIdentity::PrefIdentity(GuiPreferences * form)
                this, SIGNAL(changed()));
        connect(emailED, SIGNAL(textChanged(QString)),
                this, SIGNAL(changed()));
+       connect(initialsED, SIGNAL(textChanged(QString)),
+               this, SIGNAL(changed()));
 
        nameED->setValidator(new NoNewLineValidator(nameED));
        emailED->setValidator(new NoNewLineValidator(emailED));
+       initialsED->setValidator(new NoNewLineValidator(initialsED));
 }
 
 
@@ -3419,6 +3422,7 @@ void PrefIdentity::applyRC(LyXRC & rc) const
 {
        rc.user_name = fromqstr(nameED->text());
        rc.user_email = fromqstr(emailED->text());
+       rc.user_initials = fromqstr(initialsED->text());
 }
 
 
@@ -3426,6 +3430,7 @@ void PrefIdentity::updateRC(LyXRC const & rc)
 {
        nameED->setText(toqstr(rc.user_name));
        emailED->setText(toqstr(rc.user_email));
+       initialsED->setText(toqstr(rc.user_initials));
 }
 
 
@@ -3565,7 +3570,8 @@ void GuiPreferences::dispatchParams()
        // FIXME: these need lfuns
        // FIXME UNICODE
        Author const & author =
-               Author(from_utf8(rc_.user_name), from_utf8(rc_.user_email));
+               Author(from_utf8(rc_.user_name), from_utf8(rc_.user_email),
+                      from_utf8(rc_.user_initials));
        theBufferList().recordCurrentAuthor(author);
 
        theFormats() = formats_;
diff --git a/src/frontends/qt/ui/PrefIdentityUi.ui 
b/src/frontends/qt/ui/PrefIdentityUi.ui
index bd146b3..974bdd0 100644
--- a/src/frontends/qt/ui/PrefIdentityUi.ui
+++ b/src/frontends/qt/ui/PrefIdentityUi.ui
@@ -1,77 +1,99 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
  <class>PrefIdentityUi</class>
- <widget class="QWidget" name="PrefIdentityUi" >
-  <property name="geometry" >
+ <widget class="QWidget" name="PrefIdentityUi">
+  <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>388</width>
-    <height>209</height>
+    <width>433</width>
+    <height>135</height>
    </rect>
   </property>
-  <property name="windowTitle" >
+  <property name="windowTitle">
    <string/>
   </property>
-  <layout class="QVBoxLayout" >
-   <property name="margin" >
-    <number>11</number>
-   </property>
-   <property name="spacing" >
-    <number>6</number>
-   </property>
-   <item>
-    <layout class="QGridLayout" >
-     <property name="margin" >
-      <number>0</number>
-     </property>
-     <property name="spacing" >
-      <number>6</number>
-     </property>
-     <item row="1" column="0" >
-      <widget class="QLabel" name="emailLA" >
-       <property name="text" >
-        <string>&amp;E-mail:</string>
+  <layout class="QGridLayout" name="gridLayout_2">
+   <item row="0" column="0">
+    <layout class="QGridLayout" name="gridLayout">
+     <item row="0" column="0">
+      <widget class="QLabel" name="nameLA">
+       <property name="text">
+        <string>&amp;Name:</string>
        </property>
-       <property name="buddy" >
-        <cstring>emailED</cstring>
+       <property name="buddy">
+        <cstring>nameED</cstring>
        </property>
       </widget>
      </item>
-     <item row="0" column="1" >
-      <widget class="QLineEdit" name="nameED" >
-       <property name="toolTip" >
-        <string>Your name</string>
-       </property>
-      </widget>
+     <item row="0" column="1">
+      <layout class="QHBoxLayout" name="horizontalLayout">
+       <item>
+        <widget class="QLineEdit" name="nameED">
+         <property name="toolTip">
+          <string>Your name</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLabel" name="initialsLA">
+         <property name="text">
+          <string>&amp;Initials:</string>
+         </property>
+         <property name="buddy">
+          <cstring>initialsED</cstring>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLineEdit" name="initialsED">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>50</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="toolTip">
+          <string>Initials of your name</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
      </item>
-     <item row="0" column="0" >
-      <widget class="QLabel" name="nameLA" >
-       <property name="text" >
-        <string>&amp;Name:</string>
+     <item row="1" column="0">
+      <widget class="QLabel" name="emailLA">
+       <property name="text">
+        <string>&amp;E-mail:</string>
        </property>
-       <property name="buddy" >
-        <cstring>nameED</cstring>
+       <property name="buddy">
+        <cstring>emailED</cstring>
        </property>
       </widget>
      </item>
-     <item row="1" column="1" >
-      <widget class="QLineEdit" name="emailED" >
-       <property name="toolTip" >
+     <item row="1" column="1">
+      <widget class="QLineEdit" name="emailED">
+       <property name="toolTip">
         <string>Your E-mail address</string>
        </property>
       </widget>
      </item>
     </layout>
    </item>
-   <item>
+   <item row="1" column="0">
     <spacer>
-     <property name="orientation" >
+     <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
-     <property name="sizeType" >
+     <property name="sizeType">
       <enum>QSizePolicy::Expanding</enum>
      </property>
-     <property name="sizeHint" >
+     <property name="sizeHint" stdset="0">
       <size>
        <width>20</width>
        <height>20</height>
@@ -81,14 +103,13 @@
    </item>
   </layout>
  </widget>
- <pixmapfunction></pixmapfunction>
- <includes>
-  <include location="local" >qt_i18n.h</include>
- </includes>
  <tabstops>
   <tabstop>nameED</tabstop>
   <tabstop>emailED</tabstop>
  </tabstops>
+ <includes>
+  <include location="local">qt_i18n.h</include>
+ </includes>
  <resources/>
  <connections/>
 </ui>
diff --git a/src/tex2lyx/Preamble.cpp b/src/tex2lyx/Preamble.cpp
index 38139b4..b489859 100644
--- a/src/tex2lyx/Preamble.cpp
+++ b/src/tex2lyx/Preamble.cpp
@@ -411,9 +411,9 @@ void Preamble::suppressDate(bool suppress)
 }
 
 
-void Preamble::registerAuthor(std::string const & name)
+void Preamble::registerAuthor(std::string const & name, string const & 
initials)
 {
-       Author author(from_utf8(name), empty_docstring());
+       Author author(from_utf8(name), empty_docstring(), from_utf8(initials));
        author.setUsed(true);
        authors_.record(author);
        h_tracking_changes = "true";
@@ -423,7 +423,7 @@ void Preamble::registerAuthor(std::string const & name)
 
 Author const & Preamble::getAuthor(std::string const & name) const
 {
-       Author author(from_utf8(name), empty_docstring());
+       Author author(from_utf8(name), empty_docstring(), empty_docstring());
        for (AuthorList::Authors::const_iterator it = authors_.begin();
             it != authors_.end(); ++it)
                if (*it == author)
diff --git a/src/tex2lyx/Preamble.h b/src/tex2lyx/Preamble.h
index 6a29c45..de20b5e 100644
--- a/src/tex2lyx/Preamble.h
+++ b/src/tex2lyx/Preamble.h
@@ -92,7 +92,7 @@ public:
        ///
        void titleLayoutFound(bool found) { title_layout_found = found; }
        /// Register an author named \p name in the author list
-       void registerAuthor(std::string const & name);
+       void registerAuthor(std::string const & name, std::string const & 
initials);
        /// Get author named \p name (must be registered first)
        Author const & getAuthor(std::string const & name) const;
        /// Get number of arguments of special table column type \c or -1
diff --git a/src/tex2lyx/text.cpp b/src/tex2lyx/text.cpp
index 9dc589d..626311f 100644
--- a/src/tex2lyx/text.cpp
+++ b/src/tex2lyx/text.cpp
@@ -4053,9 +4053,13 @@ void parse_text(Parser & p, ostream & os, unsigned 
flags, bool outer,
 
                if (t.cs() == "lyxadded" || t.cs() == "lyxdeleted") {
                        context.check_layout(os);
+                       string initials;
+                       if (p.hasOpt()) {
+                               initials = p.getArg('[', ']');
+                       }
                        string name = p.getArg('{', '}');
                        string localtime = p.getArg('{', '}');
-                       preamble.registerAuthor(name);
+                       preamble.registerAuthor(name, initials);
                        Author const & author = preamble.getAuthor(name);
                        // from_asctime_utc() will fail if LyX decides to 
output the
                        // time in the text language.
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to