commit 8d451794032b5eb0a4e4579a4d794511878ee783
Author: Juergen Spitzmueller <[email protected]>
Date:   Wed Aug 1 09:28:03 2018 +0200

    More GuiInfo usability work
---
 src/LyXRC.cpp                  |    9 +++
 src/LyXRC.h                    |    2 +
 src/frontends/qt4/GuiInfo.cpp  |   80 ++++++++++++++++++++++++------
 src/frontends/qt4/GuiInfo.h    |    4 ++
 src/frontends/qt4/ui/InfoUi.ui |   33 +++++++++----
 src/insets/InsetInfo.cpp       |  107 ++++++++++++++++++++++++++++++++++++++--
 src/insets/InsetInfo.h         |    2 +
 7 files changed, 207 insertions(+), 30 deletions(-)

diff --git a/src/LyXRC.cpp b/src/LyXRC.cpp
index 8a1910e..5e8d38c 100644
--- a/src/LyXRC.cpp
+++ b/src/LyXRC.cpp
@@ -3049,6 +3049,15 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC 
const & lyxrc_new)
 }
 
 
+set<string> LyXRC::getRCs()
+{
+       set<string> res;
+       for (int i = 0; i != lyxrcCount; ++i)
+               res.insert(ltrim(lyxrcTags[i].tag, "\\"));
+       return res;
+}
+
+
 #if 0
 string const LyXRC::getDescription(LyXRCTags tag)
 {
diff --git a/src/LyXRC.h b/src/LyXRC.h
index c56c581..b499c7a 100644
--- a/src/LyXRC.h
+++ b/src/LyXRC.h
@@ -217,6 +217,8 @@ public:
                   std::string const & tag = std::string()) const;
        ///
        void print() const;
+       ///
+       std::set<std::string> getRCs();
        // FIXME unused (was used for xforms. Do we still need this?)
        //static docstring const getDescription(LyXRCTags);
        ///
diff --git a/src/frontends/qt4/GuiInfo.cpp b/src/frontends/qt4/GuiInfo.cpp
index cafcca8..84bd4f2 100644
--- a/src/frontends/qt4/GuiInfo.cpp
+++ b/src/frontends/qt4/GuiInfo.cpp
@@ -4,6 +4,7 @@
  * Licence details can be found in the file COPYING.
  *
  * \author Abdelrazak Younes
+ * \author Jürgen Spitzmüller
  *
  * Full author contact details are available in file CREDITS.
  */
@@ -50,8 +51,8 @@ char const * info_types_gui[] =
 
 char const * info_name_gui[] =
 { N_("Not Applicable"), N_("LyX Function"), N_("LyX Function"), 
N_("Preferences Key"),  N_("Package Name"),
-  N_("Class Name"), N_("LyX Function"), N_("LyX Function"), N_("Information"),
-  N_("Information"), N_("Information"), ""};
+  N_("Class Name"), N_("LyX Function"), N_("LyX Function"), N_("Not 
Applicable"), N_("Not Applicable"),
+  N_("Not Applicable"), ""};
 
 char const * info_tooltip[] =
 { N_("Please select a valid type above"),
@@ -59,7 +60,7 @@ char const * info_tooltip[] =
      "The output is the most recently assigned keyboard shortcut for this 
function"),
   N_("Enter a function name such as 'math-insert \\alpha'. Please refer to 
Help > LyX Functions for a comprehensive list of functions. "
      "The output lists all possible keyboard shortcuts for this function"),
-  N_("Enter a LyX preferences key such as 'bind_file'. Please refer to 
src/LyXRC.h for available entries. "
+  N_("Enter a LyX preferences key such as 'bind_file'. See the proposed list 
for available entries. "
      "The output is the current setting of this preference."),
   N_("Enter a LaTeX package name such as 'hyperref' (extension is optional). "
      "The output will be 'Yes' (package available) or 'No' (package 
unavailable)."),
@@ -69,9 +70,9 @@ char const * info_tooltip[] =
      "The output is the path to the function in the menu (using the current 
localization)."),
   N_("Enter a function name such as 'math-insert \\alpha'. Please refer to 
Help > LyX Functions for a comprehensive list of functions. "
      "The output is the toolbar icon for this function (using the active icon 
theme)."),
-  N_("Enter either 'name' (outputs the filename of the current document), 
'path' (outputs the file path), or 'class' (outputs the text class)."),
-  N_("Enter either 'revision', 'tree-revision', 'author', 'time' or 'date'. If 
available, the respective version control information is output."),
-  N_("Currently supported information type: 'version' (outputs the current LyX 
version)."),
+  N_("Please select a valid type above"),
+  N_("Please select a valid type above"),
+  N_("Please select a valid type above"),
   ""};
 
 
@@ -84,24 +85,41 @@ GuiInfo::GuiInfo(QWidget * parent) : 
InsetParamsWidget(parent)
                typeCO->addItem(qt_(info_types_gui[n]), info_types[n]);
        typeCO->blockSignals(false);
 
-       connect(typeCO, SIGNAL(currentIndexChanged(int)), this, 
SIGNAL(changed()));
+       connect(typeCO, SIGNAL(currentIndexChanged(int)), this, 
SLOT(updateArguments(int)));
        connect(nameLE, SIGNAL(textChanged(QString)), this, SIGNAL(changed()));
+       connect(infoLW, SIGNAL(currentTextChanged(QString)), this, 
SIGNAL(changed()));
 }
 
 
 void GuiInfo::paramsToDialog(Inset const * inset)
 {
        InsetInfo const * ii = static_cast<InsetInfo const *>(inset);
+       inset_ = const_cast<Inset*>(inset);
        QString const type = toqstr(ii->infoType());
        QString const name = toqstr(ii->infoName());
        typeCO->blockSignals(true);
        nameLE->blockSignals(true);
+       nameLE->clear();
        int const i = typeCO->findData(type);
        typeCO->setCurrentIndex(i);
-       // Without this test, 'math-insert' (name) will replace 'math-insert '
-       // in nameLE and effectively disallow the input of spaces after a LFUN.
-       if (nameLE->text().trimmed() != name)
-               nameLE->setText(name);
+       updateArguments(i);
+       int argindex = -1;
+       int customindex = 0;
+       for (int i = 0 ; i < infoLW->count() ; ++i) {
+               if (infoLW->item(i)->data(Qt::UserRole).toString() == name)
+                       argindex = i;
+               else if (infoLW->item(i)->data(Qt::UserRole).toString() == 
"custom")
+                       customindex = i;
+       }
+       if (argindex != -1)
+               infoLW->setCurrentRow(argindex);
+       else {
+               // Without this test, 'math-insert' (name) will replace 
'math-insert '
+               // in nameLE and effectively disallow the input of spaces after 
a LFUN.
+               if (nameLE->text().trimmed() != name)
+                       nameLE->setText(name);
+               infoLW->setCurrentRow(customindex);
+       }
        typeCO->blockSignals(false);
        nameLE->blockSignals(false);
 }
@@ -111,28 +129,60 @@ docstring GuiInfo::dialogToParams() const
 {
        QString type =
                typeCO->itemData(typeCO->currentIndex()).toString();
-       QString const name = nameLE->text();
+       QString name = infoLW->currentItem() ?
+                               
infoLW->currentItem()->data(Qt::UserRole).toString()
+                             : QString();
+       if (name == "custom")
+               name = nameLE->text();
        return qstring_to_ucs4(type + ' ' + name);
 }
 
 
+void GuiInfo::updateArguments(int i)
+{
+       infoLW->clear();
+       if (inset_) {
+               InsetInfo const * ii = static_cast<InsetInfo const *>(inset_);
+               vector<pair<string,docstring>> args = 
ii->getArguments(info_types[i]);
+               for (auto const & p : args) {
+                       QListWidgetItem * li = new 
QListWidgetItem(toqstr(p.second));
+                       li->setData(Qt::UserRole, toqstr(p.first));
+                       if (p.first == "invalid")
+                               // non-selectable, disabled item!
+                               li->setFlags(Qt::NoItemFlags);
+                       if (p.first == "custom")
+                               li->setData(Qt::ToolTipRole, qt_("Enter a valid 
value below"));
+                       infoLW->addItem(li);
+               }
+       }
+       if (infoLW->count() > 0)
+               infoLW->setCurrentRow(0);
+       changed();
+}
+
+
 bool GuiInfo::checkWidgets(bool readonly) const
 {
        nameLE->setReadOnly(readonly);
        typeCO->setEnabled(!readonly);
        nameLA->setText(qt_(info_name_gui[typeCO->currentIndex()]) + 
toqstr(":"));
-       bool const type_enabled =
-               typeCO->itemData(typeCO->currentIndex()).toString() != 
"unknown";
+
+       QString const arg = infoLW->currentItem() ?
+                               
infoLW->currentItem()->data(Qt::UserRole).toString()
+                             : QString();
+
+       bool const type_enabled = (arg == "custom");
        nameLA->setEnabled(type_enabled);
        nameLE->setEnabled(type_enabled);
        nameLE->setToolTip(qt_(info_tooltip[typeCO->currentIndex()]));
 
        if (!InsetParamsWidget::checkWidgets())
                return false;
-       return !nameLE->text().isEmpty();
+       return !arg.isEmpty() && (arg != "custom" || !nameLE->text().isEmpty());
 }
 
 
+
 } // namespace frontend
 } // namespace lyx
 
diff --git a/src/frontends/qt4/GuiInfo.h b/src/frontends/qt4/GuiInfo.h
index f0ebfc4..3e4ce76 100644
--- a/src/frontends/qt4/GuiInfo.h
+++ b/src/frontends/qt4/GuiInfo.h
@@ -25,6 +25,9 @@ class GuiInfo : public InsetParamsWidget, public Ui::InfoUi
 {
        Q_OBJECT
 
+protected Q_SLOTS:
+       void updateArguments(int i);
+
 public:
        GuiInfo(QWidget * parent = 0);
 
@@ -38,6 +41,7 @@ private:
        docstring dialogToParams() const;
        bool checkWidgets(bool readonly) const;
        //@}
+       Inset * inset_;
 };
 
 } // namespace frontend
diff --git a/src/frontends/qt4/ui/InfoUi.ui b/src/frontends/qt4/ui/InfoUi.ui
index 39cb57c..d7e82d6 100644
--- a/src/frontends/qt4/ui/InfoUi.ui
+++ b/src/frontends/qt4/ui/InfoUi.ui
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>320</width>
-    <height>90</height>
+    <height>311</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -16,31 +16,44 @@
   <property name="sizeGripEnabled" stdset="0">
    <bool>true</bool>
   </property>
-  <layout class="QVBoxLayout">
-   <item>
-    <layout class="QGridLayout">
-     <item row="0" column="0">
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="1" column="0">
+    <widget class="QListWidget" name="infoLW"/>
+   </item>
+   <item row="0" column="0">
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
       <widget class="QLabel" name="typeLA">
        <property name="text">
-        <string>Information Type:</string>
+        <string>Infor&amp;mation Type:</string>
+       </property>
+       <property name="buddy">
+        <cstring>typeCO</cstring>
        </property>
       </widget>
      </item>
-     <item row="0" column="1">
+     <item>
       <widget class="QComboBox" name="typeCO">
        <property name="toolTip">
         <string>Select the type of information to be output. Then specify the 
requested information below.</string>
        </property>
       </widget>
      </item>
-     <item row="1" column="0">
+    </layout>
+   </item>
+   <item row="2" column="0">
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
       <widget class="QLabel" name="nameLA">
        <property name="text">
-        <string>Information Name:</string>
+        <string>&amp;Custom:</string>
+       </property>
+       <property name="buddy">
+        <cstring>nameLE</cstring>
        </property>
       </widget>
      </item>
-     <item row="1" column="1">
+     <item>
       <widget class="QLineEdit" name="nameLE"/>
      </item>
     </layout>
diff --git a/src/insets/InsetInfo.cpp b/src/insets/InsetInfo.cpp
index 88dd347..c0e18ea 100644
--- a/src/insets/InsetInfo.cpp
+++ b/src/insets/InsetInfo.cpp
@@ -247,9 +247,8 @@ bool InsetInfo::validateModifyArgument(docstring const & 
arg) const
        }
 
        case LYXRC_INFO: {
-               ostringstream oss;
-               lyxrc.write(oss, true, name);
-               return !oss.str().empty();
+               set<string> rcs = lyxrc.getRCs();
+               return rcs.find(name) != rcs.end();
        }
 
        case PACKAGE_INFO:
@@ -273,6 +272,104 @@ bool InsetInfo::validateModifyArgument(docstring const & 
arg) const
 }
 
 
+namespace{
+set<string> getTexFileList(string const & filename)
+{
+       set<string> list;
+       FileName const file = libFileSearch(string(), filename);
+       if (file.empty())
+               return list;
+
+       // FIXME Unicode.
+       vector<docstring> doclist =
+               getVectorFromString(file.fileContents("UTF-8"), 
from_ascii("\n"));
+
+       // Normalise paths like /foo//bar ==> /foo/bar
+       for (auto doc : doclist) {
+               subst(doc, from_ascii("\r"), docstring());
+               while (contains(doc, from_ascii("//")))
+                       subst(doc, from_ascii("//"), from_ascii("/"));
+               if (!doc.empty())
+                       
list.insert(removeExtension(onlyFileName(to_utf8(doc))));
+       }
+
+       // remove duplicates
+       return list;
+}
+} // namespace anon
+
+
+vector<pair<string,docstring>> InsetInfo::getArguments(string const & type) 
const
+{
+       vector<pair<string,docstring>> result;
+
+       switch (nameTranslator().find(type)) {
+       case UNKNOWN_INFO:
+               result.push_back(make_pair("invalid", _("Please select a valid 
type!")));
+               break;
+
+       case SHORTCUT_INFO:
+       case SHORTCUTS_INFO:
+       case MENU_INFO:
+       case ICON_INFO: {
+               result.push_back(make_pair("custom", _("Custom")));
+               LyXAction::const_iterator fit = lyxaction.func_begin();
+               LyXAction::const_iterator const fen = lyxaction.func_end();
+               for (; fit != fen; ++fit) {
+                       string const lfun = fit->first;
+                       if (!lfun.empty())
+                               result.push_back(make_pair(lfun, 
from_ascii(lfun)));
+               }
+               break;
+       }
+
+       case LYXRC_INFO: {
+               result.push_back(make_pair("custom", _("Custom")));
+               set<string> rcs = lyxrc.getRCs();
+               for (auto const & rc : rcs)
+                       result.push_back(make_pair(rc, from_ascii(rc)));
+               break;
+       }
+
+       case PACKAGE_INFO:
+       case TEXTCLASS_INFO: {
+               result.push_back(make_pair("custom", _("Custom")));
+               string const filename = (type == "package") ? "styFiles.lst"
+                                                           : "clsFiles.lst";
+               set<string> flist = getTexFileList(filename);
+               for (auto const & f : flist)
+                       result.push_back(make_pair(f, from_utf8(f)));
+               break;
+       }
+
+       case BUFFER_INFO:
+               result.push_back(make_pair("name", _("File name")));
+               result.push_back(make_pair("path", _("File path")));
+               result.push_back(make_pair("class", _("Used text class")));
+               break;
+
+       case VCS_INFO: {
+               if (!buffer().lyxvc().inUse()) {
+                       result.push_back(make_pair("invalid", _("No version 
control!")));
+                       break;
+               }
+               result.push_back(make_pair("revision", _("Revision[[Version 
Control]]")));
+               result.push_back(make_pair("tree-revision", _("Tree 
revision")));
+               result.push_back(make_pair("author", _("Author")));
+               result.push_back(make_pair("date", _("Date")));
+               result.push_back(make_pair("time", _("Time")));
+               break;
+       }
+
+       case LYX_INFO:
+               result.push_back(make_pair("version", _("LyX version")));
+               break;
+       }
+
+       return result;
+}
+
+
 bool InsetInfo::showInsetDialog(BufferView * bv) const
 {
        bv->showDialog("info");
@@ -595,8 +692,8 @@ void InsetInfo::updateBuffer(ParIterator const & it, 
UpdateType utype) {
                // this information could change, in principle, so we will 
                // recalculate each time through
                if (!buffer().lyxvc().inUse()) {
-                       gui = _("No version control");
-                       info(from_ascii("No version control"), lang);
+                       gui = _("No version control!");
+                       info(from_ascii("No version control!"), lang);
                        break;
                }
                LyXVC::RevisionInfo itype = LyXVC::Unknown;
diff --git a/src/insets/InsetInfo.h b/src/insets/InsetInfo.h
index 4a4bf89..e1c42a7 100644
--- a/src/insets/InsetInfo.h
+++ b/src/insets/InsetInfo.h
@@ -124,6 +124,8 @@ public:
        ///
        bool validateModifyArgument(docstring const & argument) const;
        ///
+       std::vector<std::pair<std::string,docstring>> getArguments(std::string 
const &) const;
+       ///
        bool showInsetDialog(BufferView * bv) const;
        ///
        bool getStatus(Cursor &, FuncRequest const &, FuncStatus &) const;

Reply via email to