]> git.lyx.org Git - features.git/commitdiff
Introduce splitindex support. File format change.
authorJürgen Spitzmüller <spitz@lyx.org>
Thu, 16 Apr 2009 07:29:01 +0000 (07:29 +0000)
committerJürgen Spitzmüller <spitz@lyx.org>
Thu, 16 Apr 2009 07:29:01 +0000 (07:29 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@29255 a592a061-630c-0410-9148-cb99ea01b6c8

34 files changed:
development/FORMAT
development/scons/scons_manifest.py
lib/chkconfig.ltx
lib/configure.py
lib/doc/LaTeXConfig.lyx
lib/lyx2lyx/lyx_2_0.py
lib/ui/stdcontext.inc
lib/ui/stdmenus.inc
src/Buffer.cpp
src/BufferParams.cpp
src/BufferParams.h
src/Converter.cpp
src/IndicesList.cpp [new file with mode: 0644]
src/IndicesList.h [new file with mode: 0644]
src/LaTeX.cpp
src/LaTeXFeatures.cpp
src/LyXAction.cpp
src/LyXFunc.cpp
src/LyXRC.cpp
src/LyXRC.h
src/Makefile.am
src/OutputParams.cpp
src/OutputParams.h
src/Text3.cpp
src/factory.cpp
src/frontends/qt4/GuiDocument.cpp
src/frontends/qt4/GuiDocument.h
src/frontends/qt4/GuiIndices.cpp [new file with mode: 0644]
src/frontends/qt4/GuiIndices.h [new file with mode: 0644]
src/frontends/qt4/Makefile.am
src/frontends/qt4/Menus.cpp
src/frontends/qt4/ui/IndicesUi.ui [new file with mode: 0644]
src/insets/InsetIndex.cpp
src/insets/InsetIndex.h

index a038fab6bebf85e23a9500eaa762dfd49f16e427..541522062afa30059c2dc80ae666ef98567b547e 100644 (file)
@@ -1,6 +1,9 @@
 LyX file-format changes
 -----------------------
 
+2009-04-15 Jürgen Spitzmüller <spitz@lyx.org>
+       * Format incremented to 352: splitindex support.
+
 2009-04-11 Uwe Stöhr <uwestoehr@web.de>
        * Format incremented to 351: support to set a page background color.
 
index a1d44edc4eafa0d55a391acfa5209ab6ee0bfa2c..5e62aa234078c47a25253dc45e4db31996441306 100644 (file)
@@ -72,6 +72,7 @@ src_header_files = Split('''
     FuncRequest.h
     FuncStatus.h
     Graph.h
+    IndicesList.h
     InsetIterator.h
     InsetList.h
     Intl.h
@@ -172,6 +173,7 @@ src_pre_files = Split('''
     FuncRequest.cpp
     FuncStatus.cpp
     Graph.cpp
+    IndicesList.cpp
     InsetIterator.cpp
     InsetList.cpp
     Intl.cpp
@@ -725,6 +727,7 @@ src_frontends_qt4_header_files = Split('''
     GuiIdListModel.h
     GuiImage.h
     GuiInclude.h
+    GuiIndices.h
     GuiInfo.h
     GuiKeySymbol.h
     GuiLabel.h
@@ -817,6 +820,7 @@ src_frontends_qt4_files = Split('''
     GuiIdListModel.cpp 
     GuiImage.cpp
     GuiInclude.cpp
+    GuiIndices.cpp
     GuiInfo.cpp
     GuiKeySymbol.cpp
     GuiLabel.cpp
@@ -900,6 +904,7 @@ src_frontends_qt4_ui_files = Split('''
     HSpaceUi.ui
     HyperlinkUi.ui
     IncludeUi.ui
+    IndicesUi.ui
     InfoUi.ui
     LabelUi.ui
     LaTeXUi.ui
index 8d7960c0cde4f7572dda848863b92275f513ddb6..2a91d5e11faec615425944a5108642ab0476e71a 100644 (file)
 \TestPackage{setspace}
 \TestPackage{slashed}
 \TestPackage{soul}
+\TestPackage{splitidx}
 \TestPackage{subfig}
 \TestPackage{textcomp}
 \TestPackage{ulem}
index e369b68e14fa9eabcf8c564c1a3468aae88c4c54..05f4c3b22616618aab02d1afec3cf9aea9b44a5a 100644 (file)
@@ -599,6 +599,8 @@ def checkOtherEntries():
         rc_entry = [ r'\index_command "%%"' ])
     checkProg('an index processor appropriate to Japanese', ['mendex -c -q', 'makeindex -c -q'],
         rc_entry = [ r'\jindex_command "%%"' ])
+    checkProg('the splitindex processor', ['splitindex.pl', 'java splitindex', 'splitindex'],
+        rc_entry = [ r'\splitindex_command "%%"' ])
     checkProg('a nomenclature processor', ['makeindex'],
         rc_entry = [ r'\nomencl_command "makeindex -s nomencl.ist"' ])
     ## FIXME: OCTAVE is not used anywhere
index 2c7b866e9a963df589b937c82e7037602d8ad80a..0f494e0c56e202eaf83ba432d682b17293fa510f 100644 (file)
@@ -1,5 +1,5 @@
 #LyX 2.0.0svn created this file. For more info see http://www.lyx.org/
-\lyxformat 347
+\lyxformat 352
 \begin_document
 \begin_header
 \textclass article
 \font_sans default
 \font_typewriter default
 \font_default_family default
+\use_xetex false
 \font_sc false
 \font_osf false
 \font_sf_scale 100
 \font_tt_scale 100
 
 \graphics default
+\default_output_format default
 \paperfontsize default
 \spacing single
 \use_hyperref false
@@ -25,7 +27,9 @@
 \use_esint 0
 \cite_engine basic
 \use_bibtopic false
+\use_indices false
 \paperorientation portrait
+\backgroundcolor #ffffff
 \secnumdepth 3
 \tocdepth 3
 \paragraph_separation indent
@@ -4583,6 +4587,39 @@ slashed
  is needed by LyX to correctly typeset unicode symbols with slashes in math.
 \end_layout
 
+\begin_layout Subsection
+splitidx
+\end_layout
+
+\begin_layout Description
+Found: 
+\begin_inset Info
+type  "package"
+arg   "splitidx"
+\end_inset
+
+
+\end_layout
+
+\begin_layout Description
+CTAN: 
+\family typewriter
+macros/latex/contrib/splitindex/
+\end_layout
+
+\begin_layout Description
+Notes: The package 
+\family sans
+splitidx
+\family default
+ is needed by LyX to generate multiple and subdivided indices.
+ Note that you also need to install one of the included 
+\family sans
+splitindex
+\family default
+ converter programs.
+\end_layout
+
 \begin_layout Subsection
 subfig
 \end_layout
index 646a7c519ace617bccdba4f78ee88887c72655c2..b1f5cd5d25381b0a401e95a33daf5b8f6f6cedf9 100644 (file)
@@ -19,6 +19,8 @@
 """ Convert files to the file format generated by lyx 2.0"""
 
 import re, string
+import unicodedata
+import sys, os
 
 from parser_tools import find_token, find_end_of, find_tokens, get_value, get_value_string
 
@@ -46,6 +48,133 @@ def insert_to_preamble(index, document, text):
     document.preamble.insert(index, text)
 
 
+def read_unicodesymbols():
+    " Read the unicodesymbols list of unicode characters and corresponding commands."
+    pathname = os.path.abspath(os.path.dirname(sys.argv[0]))
+    fp = open(os.path.join(pathname.strip('lyx2lyx'), 'unicodesymbols'))
+    spec_chars = []
+    # Two backslashes, followed by some non-word character, and then a character
+    # in brackets. The idea is to check for constructs like: \"{u}, which is how
+    # they are written in the unicodesymbols file; but they can also be written
+    # as: \"u or even \" u.
+    r = re.compile(r'\\\\(\W)\{(\w)\}')
+    for line in fp.readlines():
+        if line[0] != '#' and line.strip() != "":
+            line=line.replace(' "',' ') # remove all quotation marks with spaces before
+            line=line.replace('" ',' ') # remove all quotation marks with spaces after
+            line=line.replace(r'\"','"') # replace \" by " (for characters with diaeresis)
+            try:
+                [ucs4,command,dead] = line.split(None,2)
+                if command[0:1] != "\\":
+                    continue
+                spec_chars.append([command, unichr(eval(ucs4))])
+            except:
+                continue
+            m = r.match(command)
+            if m != None:
+                command = "\\\\"
+                # If the character is a double-quote, then we need to escape it, too,
+                # since it is done that way in the LyX file.
+                if m.group(1) == "\"":
+                    command += "\\"
+                commandbl = command
+                command += m.group(1) + m.group(2)
+                commandbl += m.group(1) + ' ' + m.group(2)
+                spec_chars.append([command, unichr(eval(ucs4))])
+                spec_chars.append([commandbl, unichr(eval(ucs4))])
+    fp.close()
+    return spec_chars
+
+
+unicode_reps = read_unicodesymbols()
+
+
+def put_cmd_in_ert(string):
+    for rep in unicode_reps:
+        string = string.replace(rep[1], rep[0].replace('\\\\', '\\'))
+    string = string.replace('\\', "\\backslash\n")
+    string = "\\begin_inset ERT\nstatus collapsed\n\\begin_layout Standard\n" \
+      + string + "\n\\end_layout\n\\end_inset"
+    return string
+
+
+def lyx2latex(document, lines):
+    'Convert some LyX stuff into corresponding LaTeX stuff, as best we can.'
+    # clean up multiline stuff
+    content = ""
+    ert_end = 0
+
+    for curline in range(len(lines)):
+      line = lines[curline]
+      if line.startswith("\\begin_inset ERT"):
+          # We don't want to replace things inside ERT, so figure out
+          # where the end of the inset is.
+          ert_end = find_end_of_inset(lines, curline + 1)
+          continue
+      elif line.startswith("\\begin_inset Formula"):
+          line = line[20:]
+      elif line.startswith("\\begin_inset Quotes"):
+          # For now, we do a very basic reversion. Someone who understands
+          # quotes is welcome to fix it up.
+          qtype = line[20:].strip()
+          # lang = qtype[0]
+          side = qtype[1]
+          dbls = qtype[2]
+          if side == "l":
+              if dbls == "d":
+                  line = "``"
+              else:
+                  line = "`"
+          else:
+              if dbls == "d":
+                  line = "''"
+              else:
+                  line = "'"
+      elif line.isspace() or \
+            line.startswith("\\begin_layout") or \
+            line.startswith("\\end_layout") or \
+            line.startswith("\\begin_inset") or \
+            line.startswith("\\end_inset") or \
+            line.startswith("\\lang") or \
+            line.strip() == "status collapsed" or \
+            line.strip() == "status open":
+          #skip all that stuff
+          continue
+
+      # this needs to be added to the preamble because of cases like
+      # \textmu, \textbackslash, etc.
+      add_to_preamble(document, ['% added by lyx2lyx for converted index entries',
+                                 '\\@ifundefined{textmu}',
+                                 ' {\\usepackage{textcomp}}{}'])
+      # a lossless reversion is not possible
+      # try at least to handle some common insets and settings
+      if ert_end >= curline:
+          line = line.replace(r'\backslash', r'\\')
+      else:
+          line = line.replace('&', '\\&{}')
+          line = line.replace('#', '\\#{}')
+          line = line.replace('^', '\\^{}')
+          line = line.replace('%', '\\%{}')
+          line = line.replace('_', '\\_{}')
+          line = line.replace('$', '\\${}')
+
+          # Do the LyX text --> LaTeX conversion
+          for rep in unicode_reps:
+            line = line.replace(rep[1], rep[0] + "{}")
+          line = line.replace(r'\backslash', r'\textbackslash{}')
+          line = line.replace(r'\series bold', r'\bfseries{}').replace(r'\series default', r'\mdseries{}')
+          line = line.replace(r'\shape italic', r'\itshape{}').replace(r'\shape smallcaps', r'\scshape{}')
+          line = line.replace(r'\shape slanted', r'\slshape{}').replace(r'\shape default', r'\upshape{}')
+          line = line.replace(r'\emph on', r'\em{}').replace(r'\emph default', r'\em{}')
+          line = line.replace(r'\noun on', r'\scshape{}').replace(r'\noun default', r'\upshape{}')
+          line = line.replace(r'\bar under', r'\underbar{').replace(r'\bar default', r'}')
+          line = line.replace(r'\family sans', r'\sffamily{}').replace(r'\family default', r'\normalfont{}')
+          line = line.replace(r'\family typewriter', r'\ttfamily{}').replace(r'\family roman', r'\rmfamily{}')
+          line = line.replace(r'\InsetSpace ', r'').replace(r'\SpecialChar ', r'')
+      content += line
+    return content
+
+
 ####################################################################
 
 
@@ -297,7 +426,7 @@ def revert_outputformat(document):
 
 
 def revert_backgroundcolor(document):
-    " Reverts backgrund color to preamble code "
+    " Reverts background color to preamble code "
     i = 0
     colorcode = ""
     while True:
@@ -331,6 +460,100 @@ def revert_backgroundcolor(document):
                            + '\\pagecolor{page_backgroundcolor}\n')
 
 
+def revert_splitindex(document):
+    " Reverts splitindex-aware documents "
+    i = find_token(document.header, '\\use_indices', 0)
+    if i == -1:
+        document.warning("Malformed LyX document: Missing \\use_indices.")
+        return
+    indices = get_value(document.header, "\\use_indices", i)
+    preamble = ""
+    if indices == "true":
+         preamble += "\\usepackage{splitidx}\n"
+    del document.header[i]
+    i = 0
+    while True:
+        i = find_token(document.header, "\\index", i)
+        if i == -1:
+            break
+        k = find_token(document.header, "\\end_index", i)
+        if k == -1:
+            document.warning("Malformed LyX document: Missing \\end_index.")
+            return
+        line = document.header[i]
+        l = re.compile(r'\\index (.*)$')
+        m = l.match(line)
+        iname = m.group(1)
+        ishortcut = get_value(document.header, '\\shortcut', i, k)
+        if ishortcut != "" and indices == "true":
+            preamble += "\\newindex[" + iname + "]{" + ishortcut + "}\n"
+        del document.header[i:k+1]
+        i = 0
+    if preamble != "":
+        insert_to_preamble(0, document, preamble)
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_inset Index", i)
+        if i == -1:
+            break
+        line = document.body[i]
+        l = re.compile(r'\\begin_inset Index (.*)$')
+        m = l.match(line)
+        itype = m.group(1)
+        if itype == "idx" or indices == "false":
+            document.body[i] = "\\begin_inset Index"
+        else:
+            k = find_end_of_inset(document.body, i)
+            if k == -1:
+                 return
+            content = lyx2latex(document, document.body[i:k])
+            # escape quotes
+            content = content.replace('"', r'\"')
+            subst = [put_cmd_in_ert("\\sindex[" + itype + "]{" + content + "}")]
+            document.body[i:k+1] = subst
+        i = i + 1
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_inset CommandInset index_print", i)
+        if i == -1:
+            return
+        k = find_end_of_inset(document.body, i)
+        ptype = get_value(document.body, 'type', i, k).strip('"')
+        if ptype == "idx":
+            j = find_token(document.body, "type", i, k)
+            del document.body[j]
+        elif indices == "false":
+            del document.body[i:k+1]
+        else:
+            subst = [put_cmd_in_ert("\\printindex[" + ptype + "]{}")]
+            document.body[i:k+1] = subst
+        i = i + 1
+
+
+def convert_splitindex(document):
+    " Converts index and printindex insets to splitindex-aware format "
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_inset Index", i)
+        if i == -1:
+            break
+        document.body[i] = document.body[i].replace("\\begin_inset Index",
+            "\\begin_inset Index idx")
+        i = i + 1
+    i = 0
+    while True:
+        i = find_token(document.body, "\\begin_inset CommandInset index_print", i)
+        if i == -1:
+            return
+        if document.body[i + 1].find('LatexCommand printindex') == -1:
+            document.warning("Malformed LyX document: Incomplete printindex inset.")
+            return
+        subst = ["LatexCommand printindex", 
+            "type \"idx\""]
+        document.body[i + 1:i + 2] = subst
+        i = i + 1
+
+
 ##
 # Conversion hub
 #
@@ -341,10 +564,12 @@ convert = [[346, []],
            [348, []],
            [349, []],
            [350, []],
-           [351, []]
+           [351, []],
+           [352, [convert_splitindex]]
           ]
 
-revert =  [[350, [revert_backgroundcolor]],
+revert =  [[351, [revert_splitindex]],
+           [350, [revert_backgroundcolor]],
            [349, [revert_outputformat]],
            [348, [revert_xetex]],
            [347, [revert_phantom, revert_hphantom, revert_vphantom]],
index 84122b20d2ef667d7ab1d4f7fb3001c22e211019..e0db52cb4b6915d339ae90b4205b104491e2af1b 100644 (file)
@@ -469,4 +469,25 @@ Menuset
                Item "Settings...|S" "inset-settings"
        End
 
+#
+# Index context menu
+#
+
+       Menu "context-index"
+               IndicesContext
+               Separator
+               OptItem "Open Inset|O" "inset-toggle open"
+               OptItem "Close Inset|C" "inset-toggle close"
+               Separator
+               Item "Dissolve Inset|D" "inset-dissolve"
+       End
+
+#
+# Index Lists context menu
+#
+
+       Menu "context-indexprint"
+               IndicesListsContext
+       End
+
 End
index 3188b6fd92ee7552e658dda52e622331c787a78a..85ecdf445c735ecac6ab4694c3a4777091b31b41 100644 (file)
@@ -346,7 +346,7 @@ Menuset
                Item "Cross-Reference...|R" "dialog-show-new-inset ref"
                Item "Label...|L" "label-insert"
                Item "Caption" "caption-insert"
-               Item "Index Entry|d" "index-insert"
+               Indices
                Item "Nomenclature Entry...|y" "nomencl-insert"
                Separator
                Item "Table...|T" "tabular-insert"
@@ -430,7 +430,7 @@ Menuset
        Menu "insert_toc"
                Item "Table of Contents|C" "toc-insert"
                FloatListInsert
-               Item "Index List|I" "index-print"
+               IndicesLists
                Item "Nomenclature|N" "nomencl-print"
                Item "BibTeX Bibliography...|B" "dialog-show-new-inset bibtex"
        End
index eb03f06bf670a77020335b1aeb196b5a6f7e87db..d277d96c063d0d3b92a8bde97ab23fddb667d237 100644 (file)
@@ -32,6 +32,7 @@
 #include "Format.h"
 #include "FuncRequest.h"
 #include "FuncStatus.h"
+#include "IndicesList.h"
 #include "InsetIterator.h"
 #include "InsetList.h"
 #include "Language.h"
@@ -124,7 +125,7 @@ namespace {
 
 // Do not remove the comment below, so we get merge conflict in
 // independent branches. Instead add your own.
-int const LYX_FORMAT = 351;  // uwestoehr: support for page background color
+int const LYX_FORMAT = 352;  // jspitzm: splitindex support
 
 typedef map<string, bool> DepClean;
 typedef map<docstring, pair<InsetLabel const *, Buffer::References> > RefCache;
@@ -523,6 +524,7 @@ int Buffer::readHeader(Lexer & lex)
        params().clearLayoutModules();
        params().clearRemovedModules();
        params().pdfoptions().clear();
+       params().indiceslist().clear();
 
        for (int i = 0; i < 4; ++i) {
                params().user_defined_bullet(i) = ITEMIZE_DEFAULTS[i];
index 9492f00f1503851cd50ecad0146b461b54d7b61b..31a24469e95d58aee0d308776df30a4fd4894995 100644 (file)
@@ -25,6 +25,7 @@
 #include "Color.h"
 #include "ColorSet.h"
 #include "Encoding.h"
+#include "IndicesList.h"
 #include "Language.h"
 #include "LaTeXFeatures.h"
 #include "ModuleList.h"
@@ -283,6 +284,7 @@ public:
        BranchList branchlist;
        Bullet temp_bullets[4];
        Bullet user_defined_bullets[4];
+       IndicesList indiceslist;
        Spacing spacing;
        /** This is the amount of space used for paragraph_separation "skip",
         * and for detached paragraphs in "indented" documents.
@@ -334,6 +336,7 @@ BufferParams::BufferParams()
        use_esint = package_auto;
        cite_engine_ = ENGINE_BASIC;
        use_bibtopic = false;
+       use_indices = false;
        trackChanges = false;
        outputChanges = false;
        use_default_options = true;
@@ -363,6 +366,8 @@ BufferParams::BufferParams()
                user_defined_bullet(iter) = ITEMIZE_DEFAULTS[iter];
                temp_bullet(iter) = ITEMIZE_DEFAULTS[iter];
        }
+       // default index
+       indiceslist().addDefault(B_("Index"));
 }
 
 
@@ -397,6 +402,18 @@ BranchList const & BufferParams::branchlist() const
 }
 
 
+IndicesList & BufferParams::indiceslist()
+{
+       return pimpl_->indiceslist;
+}
+
+
+IndicesList const & BufferParams::indiceslist() const
+{
+       return pimpl_->indiceslist;
+}
+
+
 Bullet & BufferParams::temp_bullet(lyx::size_type const index)
 {
        LASSERT(index < 4, /**/);
@@ -572,6 +589,8 @@ string BufferParams::readToken(Lexer & lex, string const & token,
                cite_engine_ = citeenginetranslator().find(engine);
        } else if (token == "\\use_bibtopic") {
                lex >> use_bibtopic;
+       } else if (token == "\\use_indices") {
+               lex >> use_indices;
        } else if (token == "\\tracking_changes") {
                lex >> trackChanges;
        } else if (token == "\\output_changes") {
@@ -604,6 +623,34 @@ string BufferParams::readToken(Lexer & lex, string const & token,
                                lcolor.setColor(to_utf8(branch), color);
                        }
                }
+       } else if (token == "\\index") {
+               lex.eatLine();
+               docstring index = lex.getDocString();
+               indiceslist().add(index);
+               while (true) {
+                       lex.next();
+                       string const tok = lex.getString();
+                       if (tok == "\\end_index")
+                               break;
+                       Index * index_ptr = indiceslist().find(index);
+                       if (tok == "\\shortcut") {
+                               lex.next();
+                               if (index_ptr)
+                                       index_ptr->setShortcut(lex.getDocString());
+                       }
+                       // not yet operational
+                       if (tok == "\\color") {
+                               lex.eatLine();
+                               string color = lex.getString();
+                               if (index_ptr)
+                                       index_ptr->setColor(color);
+                               // Update also the Color table:
+                               if (color == "none")
+                                       color = lcolor.getX11Name(Color_background);
+                               // FIXME UNICODE
+                               lcolor.setColor(to_utf8(index), color);
+                       }
+               }
        } else if (token == "\\author") {
                lex.eatLine();
                istringstream ss(lex.getString());
@@ -781,6 +828,7 @@ void BufferParams::writeFile(ostream & os) const
           << "\n\\use_esint " << use_esint
           << "\n\\cite_engine " << citeenginetranslator().find(cite_engine_)
           << "\n\\use_bibtopic " << convert<string>(use_bibtopic)
+          << "\n\\use_indices " << convert<string>(use_indices)
           << "\n\\paperorientation " << string_orientation[orientation]
           << "\n\\backgroundcolor " << lyx::X11hexname(backgroundcolor)
           << '\n';
@@ -795,6 +843,16 @@ void BufferParams::writeFile(ostream & os) const
                   << "\n";
        }
 
+       IndicesList::const_iterator iit = indiceslist().begin();
+       IndicesList::const_iterator iend = indiceslist().end();
+       for (; iit != iend; ++iit) {
+               os << "\\index " << to_utf8(iit->index())
+                  << "\n\\shortcut " << to_utf8(iit->shortcut())
+                  << "\n\\color " << lyx::X11hexname(iit->color())
+                  << "\n\\end_index"
+                  << "\n";
+       }
+
        if (!paperwidth.empty())
                os << "\\paperwidth "
                   << VSpace(paperwidth).asLyXCommand() << '\n';
@@ -1345,6 +1403,19 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
        // The optional packages;
        lyxpreamble += from_ascii(features.getPackages());
 
+       // Additional Indices
+       if (features.isRequired("splitidx")) {
+               IndicesList::const_iterator iit = indiceslist().begin();
+               IndicesList::const_iterator iend = indiceslist().end();
+               for (; iit != iend; ++iit) {
+                       lyxpreamble += "\\newindex[";
+                       lyxpreamble += iit->index();
+                       lyxpreamble += "]{";
+                       lyxpreamble += iit->shortcut();
+                       lyxpreamble += "}\n";
+               }
+       }
+
        // Line spacing
        lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace")));
 
index 40fee96f6090d3f6e6d686d845f3a988456bf10d..43beea44d4d04aa94e443fb84da7f8356c6dd3a8 100644 (file)
@@ -36,6 +36,7 @@ class BranchList;
 class Bullet;
 class DocumentClass;
 class Encoding;
+class IndicesList;
 class Language;
 class LatexFeatures;
 class LayoutFile;
@@ -215,6 +216,9 @@ public:
        /// BranchList:
        BranchList & branchlist();
        BranchList const & branchlist() const;
+       /// IndicesList:
+       IndicesList & indiceslist();
+       IndicesList const & indiceslist() const;
        /**
         * The input encoding for LaTeX. This can be one of
         * - \c auto: find out the input encoding from the used languages
@@ -278,8 +282,10 @@ public:
        Package use_amsmath;
        /// Whether and how to load esint
        Package use_esint;
-       ///
+       /// Split bibliography?
        bool use_bibtopic;
+       /// Split the index?
+       bool use_indices;
        /// revision tracking for this buffer ?
        bool trackChanges;
        /** This param decides whether change tracking marks should be used
index a970faf38de2587cb7fb8f7a038ff2454b2ba75c..7c71cff525b188dd0ebe882c1975cd1513c1e7ef 100644 (file)
@@ -325,6 +325,8 @@ bool Converters::convert(Buffer const * buffer,
        // used anyway.
        OutputParams runparams(buffer ? &buffer->params().encoding() : 0);
        runparams.flavor = getFlavor(edgepath);
+       
+       runparams.use_indices = buffer->params().use_indices;
 
        if (buffer)
                runparams.use_japanese = buffer->bufferFormat() == "platex";
diff --git a/src/IndicesList.cpp b/src/IndicesList.cpp
new file mode 100644 (file)
index 0000000..a73dbb9
--- /dev/null
@@ -0,0 +1,235 @@
+/**
+ * \file IndicesList.cpp
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Jürgen Spitzmüller
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "IndicesList.h"
+#include "Color.h"
+
+#include "frontends/Application.h"
+
+#include "support/convert.h"
+#include "support/lstrings.h"
+
+#include <algorithm>
+
+using namespace std;
+using namespace lyx::support;
+
+namespace lyx {
+
+namespace {
+
+class IndexNamesEqual : public std::unary_function<Index, bool>
+{
+public:
+       IndexNamesEqual(docstring const & name) : name_(name) {}
+
+       bool operator()(Index const & index) const
+       {
+               return index.index() == name_;
+       }
+private:
+       docstring name_;
+};
+
+
+class IndexHasShortcut : public std::unary_function<Index, bool>
+{
+public:
+       IndexHasShortcut(docstring const & shortcut) : shortc_(shortcut) {}
+
+       bool operator()(Index const & index) const
+       {
+               return index.shortcut() == shortc_;
+       }
+private:
+       docstring shortc_;
+};
+
+}
+
+
+/////////////////////////////////////////////////////////////////////
+//
+// Index
+//
+/////////////////////////////////////////////////////////////////////
+
+
+Index::Index()
+{
+       // no theApp() with command line export
+       if (theApp())
+               theApp()->getRgbColor(Color_indexlabel, color_);
+}
+
+
+docstring const & Index::index() const
+{
+       return index_;
+}
+
+
+void Index::setIndex(docstring const & s)
+{
+       index_ = s;
+}
+
+
+docstring const & Index::shortcut() const
+{
+       return shortcut_;
+}
+
+
+void Index::setShortcut(docstring const & s)
+{
+       shortcut_ = s;
+}
+
+
+RGBColor const & Index::color() const
+{
+       return color_;
+}
+
+
+void Index::setColor(RGBColor const & c)
+{
+       color_ = c;
+}
+
+
+void Index::setColor(string const & str)
+{
+       if (str.size() == 7 && str[0] == '#')
+               color_ = rgbFromHexName(str);
+       else
+               // no color set or invalid color -- use predefined color
+               theApp()->getRgbColor(Color_indexlabel, color_);
+}
+
+
+/////////////////////////////////////////////////////////////////////
+//
+// IndicesList
+//
+/////////////////////////////////////////////////////////////////////
+
+
+Index * IndicesList::find(docstring const & name)
+{
+       List::iterator it =
+               find_if(list.begin(), list.end(), IndexNamesEqual(name));
+       return it == list.end() ? 0 : &*it;
+}
+
+
+Index const * IndicesList::find(docstring const & name) const
+{
+       List::const_iterator it =
+               find_if(list.begin(), list.end(), IndexNamesEqual(name));
+       return it == list.end() ? 0 : &*it;
+}
+
+
+Index * IndicesList::findShortcut(docstring const & shortcut)
+{
+       List::iterator it =
+               find_if(list.begin(), list.end(), IndexHasShortcut(shortcut));
+       return it == list.end() ? 0 : &*it;
+}
+
+
+Index const * IndicesList::findShortcut(docstring const & shortcut) const
+{
+       List::const_iterator it =
+               find_if(list.begin(), list.end(), IndexHasShortcut(shortcut));
+       return it == list.end() ? 0 : &*it;
+}
+
+
+bool IndicesList::add(docstring const & n, docstring const & s)
+{
+       bool added = false;
+       size_t i = 0;
+       while (true) {
+               size_t const j = n.find_first_of(separator_, i);
+               docstring name;
+               if (j == docstring::npos)
+                       name = n.substr(i);
+               else
+                       name = n.substr(i, j - i);
+               // Is this name already in the list?
+               bool const already =
+                       find_if(list.begin(), list.end(),
+                                    IndexNamesEqual(name)) != list.end();
+               if (!already) {
+                       added = true;
+                       Index in;
+                       in.setIndex(name);
+                       docstring sc = s.empty() ?
+                               trim(lowercase(name.substr(0, 3))) : s;
+                       if (findShortcut(sc) != 0) {
+                               int i = 1;
+                               docstring scn = sc + convert<docstring>(i);
+                               while (findShortcut(scn) != 0) {
+                                       ++i;
+                                       scn = sc + convert<docstring>(i);
+                               }
+                               in.setShortcut(scn);
+                       } else
+                               in.setShortcut(sc);
+                       list.push_back(in);
+               }
+               if (j == docstring::npos)
+                       break;
+               i = j + 1;
+       }
+       return added;
+}
+
+
+bool IndicesList::addDefault(docstring const & n)
+{
+       if (findShortcut(from_ascii("idx")) != 0)
+               // we already have a default
+               return false;
+       return add(n, from_ascii("idx"));
+}
+
+bool IndicesList::remove(docstring const & s)
+{
+       size_t const size = list.size();
+       list.remove_if(IndexNamesEqual(s));
+       return size != list.size();
+}
+
+
+bool IndicesList::rename(docstring const & oldname,
+       docstring const & newname)
+{
+       if (newname.empty())
+               return false;
+       if (find_if(list.begin(), list.end(),
+                   IndexNamesEqual(newname)) != list.end())
+               // new name already taken
+               return false;
+
+       Index * index = find(oldname);
+       if (!index)
+               return false;
+       index->setIndex(newname);
+       return true;
+}
+
+
+} // namespace lyx
diff --git a/src/IndicesList.h b/src/IndicesList.h
new file mode 100644 (file)
index 0000000..019c548
--- /dev/null
@@ -0,0 +1,128 @@
+// -*- C++ -*-
+/**
+ * \file IndicesList.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ * \author Jürgen Spitzmüller
+ *
+ * Full author contact details are available in file CREDITS.
+ *
+ *
+ * \class Index
+ *
+ * A class describing an Index type, such as "Index of Names".
+ * Different Index types are used in splitted Indices
+ *
+ * An Index has a name and a shortcut notation. It uses a
+ * user-specifyable GUI colour. All these can be set and
+ * queried.
+ *
+ * \class IndicesList
+ *
+ * A class containing a vector of all defined indices within a
+ * document. Has methods for outputting a '|'-separated string 
+ * of all elements, and for adding, removing and renaming elements.
+ */
+
+
+#ifndef INDICESLIST_H
+#define INDICESLIST_H
+
+#include "ColorCode.h"
+
+#include "support/docstring.h"
+
+#include <list>
+
+
+namespace lyx {
+
+class Index {
+public:
+       ///
+       Index();
+       ///
+       docstring const & index() const;
+       ///
+       void setIndex(docstring const &);
+       ///
+       docstring const & shortcut() const;
+       ///
+       void setShortcut(docstring const &);
+       ///
+       RGBColor const & color() const;
+       ///
+       void setColor(RGBColor const &);
+       /**
+        * Set color from a string "#rrggbb".
+        * Use Color:background if the string is no valid color.
+        * This ensures compatibility with LyX 1.4.0 that had the symbolic
+        * color "none" that was displayed as Color:background.
+        */
+       void setColor(std::string const &);
+
+private:
+       ///
+       docstring index_;
+       ///
+       docstring shortcut_;
+       ///
+       RGBColor color_;
+};
+
+
+class IndicesList {
+       ///
+       typedef std::list<Index> List;
+public:
+       typedef List::const_iterator const_iterator;
+
+       ///
+       IndicesList() : separator_(from_ascii("|")) {}
+
+       ///
+       bool empty() const { return list.empty(); }
+       ///
+       void clear() { list.clear(); }
+       ///
+       const_iterator begin() const { return list.begin(); }
+       const_iterator end() const { return list.end(); }
+
+       /** \returns the Index with \c name. If not found, returns 0.
+        */
+       Index * find(docstring const & name);
+       Index const * find(docstring const & name) const;
+
+       /** \returns the Index with the shortcut \c shortcut. 
+        *  If not found, returns 0.
+        */
+       Index * findShortcut(docstring const & shortcut);
+       Index const * findShortcut(docstring const & shortcut) const;
+
+       /** Add (possibly multiple (separated by separator())) indices to list
+        *  \returns true if an index is added.
+        */
+       bool add(docstring const & n, docstring const & s = docstring());
+       /** Add the default index (if not already there)
+        *  \returns true if an index is added.
+        */
+       bool addDefault(docstring const & n);
+       /** remove an index from list by name
+        *  \returns true if an index is removed.
+        */
+       bool remove(docstring const &);
+       /** rename an index in list
+        *  \returns true if renaming succeeded.
+        */
+       bool rename(docstring const &, docstring const &);
+
+private:
+       ///
+       List list;
+       ///
+       docstring separator_;
+};
+
+} // namespace lyx
+
+#endif // INDICESLIST_H
index d7fe03f770a8833156eb5956de7d3950785752b2..6bd55e8216af6127564548b8812c52ccc9188117 100644 (file)
@@ -416,9 +416,11 @@ bool LaTeX::runMakeIndex(string const & f, OutputParams const & runparams,
                "idx file has been made, running makeindex on file " << f);
        string tmp = runparams.use_japanese ?
                lyxrc.jindex_command : lyxrc.index_command;
-       tmp += ' ';
 
        tmp = subst(tmp, "$$lang", runparams.document_language);
+       if (runparams.use_indices)
+               tmp = lyxrc.splitindex_command + " -m " + quoteName(tmp);
+       tmp += ' ';
        tmp += quoteName(f);
        tmp += params;
        Systemcall one;
index 79ef3e45204cfe44888c802c9f1ff76145bad930..efc3fc6a3be58fd75c0941e40c39064a310a3e51 100644 (file)
@@ -619,9 +619,11 @@ string const LaTeXFeatures::getPackages() const
        // [x]color and pdfcolmk are handled in getColorOptions() above
        
        // makeidx.sty
-       if (isRequired("makeidx")) {
-               if (!tclass.provides("makeidx"))
+       if (isRequired("makeidx") || isRequired("splitidx")) {
+               if (!tclass.provides("makeidx") && !isRequired("splitidx"))
                        packages << "\\usepackage{makeidx}\n";
+               if (!tclass.provides("splitidx") && isRequired("splitidx"))
+                       packages << "\\usepackage{splitidx}\n";
                packages << "\\makeindex\n";
        }
 
index 36a79cc5c9751c37f72c9598b128b537838fdd77..5f0bdae95507b20a9a020cd2ca1acf9605d2cce9 100644 (file)
@@ -515,7 +515,9 @@ void LyXAction::init()
  * \var lyx::FuncCode lyx::LFUN_INDEX_INSERT
  * \li Action: Inserts Index entry.
  * \li Notion: It automatically takes the word on the cursor position.
- * \li Syntax: index-insert
+ * \li Syntax: index-insert [<TYPE:Name>]
+ * \li Params: <TYPE:Name>: name of the index, if multiple indices are defined.
+               with an empty argument, the default index is selected.
  * \li Origin: leeming, 3 Aug 2000
  * \endvar
  */
@@ -523,7 +525,9 @@ void LyXAction::init()
 /*!
  * \var lyx::FuncCode lyx::LFUN_INDEX_PRINT
  * \li Action: Inserts list of Index entries on a new page.
- * \li Syntax: index-print
+ * \li Syntax: index-print [<TYPE:Name>]
+ * \li Params: <TYPE:Name>: name of the index, if multiple indices are defined.
+               with an empty argument, the default index is selected.
  * \li Origin: Lgb, 27 Feb 1997
  * \endvar
  */
index 59d62159897fbf015bc91666d52108362c5e3d3c..4c1d579c42dc46e6687f896caf44fe1059a41f74 100644 (file)
@@ -1977,6 +1977,7 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new)
        case LyXRC::RC_OPEN_BUFFERS_IN_TABS:
        case LyXRC::RC_SPELL_COMMAND:
        case LyXRC::RC_SPELLCHECK_CONTINUOUSLY:
+       case LyXRC::RC_SPLITINDEX_COMMAND:
        case LyXRC::RC_TEMPDIRPATH:
        case LyXRC::RC_TEMPLATEPATH:
        case LyXRC::RC_TEX_ALLOWS_SPACES:
index b1240cd0696f781124956f17a1369611dd37c4e9..121b9f896e460ce37ecf9226b18ca3a6fed8bbf1 100644 (file)
@@ -165,6 +165,7 @@ LexerKeyword lyxrcTags[] = {
        { "\\sort_layouts", LyXRC::RC_SORT_LAYOUTS },
        { "\\spell_command", LyXRC::RC_SPELL_COMMAND },
        { "\\spellcheck_continuously", LyXRC::RC_SPELLCHECK_CONTINUOUSLY },
+       { "\\splitindex_command", LyXRC::RC_SPLITINDEX_COMMAND },
        { "\\tempdir_path", LyXRC::RC_TEMPDIRPATH },
        { "\\template_path", LyXRC::RC_TEMPLATEPATH },
        { "\\tex_allows_spaces", LyXRC::RC_TEX_ALLOWS_SPACES },
@@ -615,6 +616,12 @@ int LyXRC::read(Lexer & lexrc)
                        }
                        break;
 
+               case RC_SPLITINDEX_COMMAND:
+                       if (lexrc.next(true)) {
+                               splitindex_command = lexrc.getString();
+                       }
+                       break;
+
                case RC_NOMENCL_COMMAND:
                        if (lexrc.next(true)) {
                                nomencl_command = lexrc.getString();
@@ -1372,6 +1379,13 @@ void LyXRC::write(ostream & os, bool ignore_system_lyxrc, string const & name) c
                }
                if (tag != RC_LAST)
                        break;
+       case RC_SPLITINDEX_COMMAND:
+               if (ignore_system_lyxrc ||
+                   splitindex_command != system_lyxrc.splitindex_command) {
+                       os << "\\splitindex_command \"" << escapeCommand(splitindex_command) << "\"\n";
+               }
+               if (tag != RC_LAST)
+                       break;
        case RC_NOMENCL_COMMAND:
                if (ignore_system_lyxrc ||
                    nomencl_command != system_lyxrc.nomencl_command) {
index d8fee9d082dd6aafbc736be2e589f22372549fca..a51d63fffc21390fe2c3bdc2d4938c60712351e7 100644 (file)
@@ -149,6 +149,7 @@ public:
                RC_SORT_LAYOUTS,
                RC_SPELL_COMMAND,
                RC_SPELLCHECK_CONTINUOUSLY,
+               RC_SPLITINDEX_COMMAND,
                RC_TEMPDIRPATH,
                RC_TEMPLATEPATH,
                RC_TEX_ALLOWS_SPACES,
@@ -252,6 +253,8 @@ public:
        std::string index_command;
        /// command to run japanese index program incl. options
        std::string jindex_command;
+       /// command to generate multiple indices
+       std::string splitindex_command;
        /// command to run makeindex incl. options for nomencl
        std::string nomencl_command;
        ///
index d4f233b5f95d93a59f87ab40f99794edd1d7b52f..f0263553d44ac7e547241de5dbafa2539b4531e5 100644 (file)
@@ -111,6 +111,7 @@ SOURCEFILESCORE = \
        FuncRequest.cpp \
        FuncStatus.cpp \
        Graph.cpp \
+       IndicesList.cpp \
        InsetIterator.cpp \
        InsetList.cpp \
        Intl.cpp \
@@ -209,6 +210,7 @@ HEADERFILESCORE = \
        FuncRequest.h \
        FuncStatus.h \
        Graph.h \
+       IndicesList.h \
        InsetIterator.h \
        InsetList.h \
        Intl.h \
index 498c65148c7f46f75f0bf4013e8f6117de4a41f8..564232b4baa638adfa1d66ebbb3bd51765e76fef 100644 (file)
@@ -21,7 +21,7 @@ namespace lyx {
 OutputParams::OutputParams(Encoding const * enc)
        : flavor(LATEX), nice(false), moving_arg(false),
          local_font(0), encoding(enc), free_spacing(false), use_babel(false),
-         use_japanese(false), linelen(0), depth(0),
+         use_indices(false), use_japanese(false), linelen(0), depth(0),
          exportdata(new ExportData),
          inComment(false), inTableCell(NO), inFloat(NONFLOAT),
          inDeletedInset(0), changeOfDeletedInset(Change::UNCHANGED),
index cc0f01548eb6da3848f7bc760a650f461674c36f..f0c06dc846461194837bc65f1b4f02e6eeb85381 100644 (file)
@@ -111,6 +111,10 @@ public:
        */
        bool use_babel;
 
+       /** Are we generating multiple indices?
+       */
+       bool use_indices;
+
        /** Are we using japanese (pLaTeX)?
        */
        bool use_japanese;
index 3ac094d033c994f3ad2cfa5fe0cb121626ac14e3..1b9b40aa00f04f1ea2420302c0de90af4ec1fda4 100644 (file)
@@ -1537,7 +1537,18 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
                break;
        }
 
-       case LFUN_INDEX_PRINT:
+       case LFUN_INDEX_PRINT: {
+               InsetCommandParams p(INDEX_PRINT_CODE);
+               if (cmd.argument().empty())
+                       p["type"] = from_ascii("idx");
+               else
+                       p["type"] = cmd.argument();
+               string const data = InsetCommand::params2string("index_print", p);
+               FuncRequest fr(LFUN_INSET_INSERT, data);
+               dispatch(cur, fr);
+               break;
+       }
+
        case LFUN_NOMENCL_PRINT:
        case LFUN_TOC_INSERT:
        case LFUN_LINE_INSERT:
index e390b228c81e6f1e2d2a612983b1481dd53e45e7..641d96cfb6f4b992160d361619861ab63ab09dce 100644 (file)
@@ -177,8 +177,10 @@ Inset * createInsetHelper(Buffer & buf, FuncRequest const & cmd)
                        return 0;
                }
 
-               case LFUN_INDEX_INSERT:
-                       return new InsetIndex(buf);
+               case LFUN_INDEX_INSERT: {
+                       docstring arg = cmd.argument();
+                       return new InsetIndex(buf, InsetIndexParams(arg));
+               }
 
                case LFUN_NOMENCL_INSERT: {
                        InsetCommandParams icp(NOMENCL_CODE);
@@ -202,8 +204,11 @@ Inset * createInsetHelper(Buffer & buf, FuncRequest const & cmd)
                case LFUN_CAPTION_INSERT:
                        return new InsetCaption(buf);
 
-               case LFUN_INDEX_PRINT:
-                       return new InsetPrintIndex(InsetCommandParams(INDEX_PRINT_CODE));
+               case LFUN_INDEX_PRINT:  {
+                       InsetCommandParams icp(INDEX_PRINT_CODE);
+                       icp["type"] = cmd.argument();
+                       return new InsetPrintIndex(icp);
+               }
 
                case LFUN_NOMENCL_PRINT:
                        return new InsetPrintNomencl(InsetCommandParams(NOMENCL_PRINT_CODE));
@@ -283,8 +288,16 @@ Inset * createInsetHelper(Buffer & buf, FuncRequest const & cmd)
                                return new InsetInclude(icp);
                        }
                        
-                       case INDEX_CODE:
-                               return new InsetIndex(buf);
+                       case INDEX_CODE: {
+                               docstring arg = cmd.argument();
+                               return new InsetIndex(buf, InsetIndexParams(arg));
+                       }
+                       
+                       case INDEX_PRINT_CODE:  {
+                               InsetCommandParams icp(code);
+                               InsetCommand::string2params(name, to_utf8(cmd.argument()), icp);
+                               return new InsetPrintIndex(icp);
+                       }
                        
                        case NOMENCL_CODE: {
                                InsetCommandParams icp(code);
@@ -566,7 +579,7 @@ Inset * readInset(Lexer & lex, Buffer const & buf)
                } else if (tmptok == "Caption") {
                        inset.reset(new InsetCaption(buf));
                } else if (tmptok == "Index") {
-                       inset.reset(new InsetIndex(buf));
+                       inset.reset(new InsetIndex(buf, InsetIndexParams()));
                } else if (tmptok == "FloatList") {
                        inset.reset(new InsetFloatList);
                } else if (tmptok == "Info") {
index b74e6536f058b3165254a5f30e2fcb87d51d2db6..c5a63ce661ec72afa823eaecdc97ae943deb8ff0 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "GuiApplication.h"
 #include "GuiBranches.h"
+#include "GuiIndices.h"
 #include "GuiSelectionManager.h"
 #include "LaTeXHighlighter.h"
 #include "LengthCombo.h"
@@ -33,6 +34,7 @@
 #include "FloatPlacement.h"
 #include "Format.h"
 #include "FuncRequest.h"
+#include "IndicesList.h"
 #include "Language.h"
 #include "LaTeXFeatures.h"
 #include "Layout.h"
@@ -862,6 +864,11 @@ GuiDocument::GuiDocument(GuiView & lv)
        biblioModule->citeStyleCO->addItem(qt_("Numerical"));
        biblioModule->citeStyleCO->setCurrentIndex(0);
 
+       // indices
+       indicesModule = new GuiIndices;
+       connect(indicesModule, SIGNAL(changed()),
+               this, SLOT(change_adaptor()));
+
 
        mathsModule = new UiWidget<Ui::MathsUi>;
        connect(mathsModule->amsautoCB, SIGNAL(toggled(bool)),
@@ -1006,6 +1013,7 @@ GuiDocument::GuiDocument(GuiView & lv)
        docPS->addPanel(langModule, qt_("Language"));
        docPS->addPanel(numberingModule, qt_("Numbering & TOC"));
        docPS->addPanel(biblioModule, qt_("Bibliography"));
+       docPS->addPanel(indicesModule, qt_("Indices"));
        docPS->addPanel(pdfSupportModule, qt_("PDF Properties"));
        docPS->addPanel(mathsModule, qt_("Math Options"));
        docPS->addPanel(floatModule, qt_("Float Placement"));
@@ -1713,6 +1721,9 @@ void GuiDocument::applyView()
        bp_.use_bibtopic =
                biblioModule->bibtopicCB->isChecked();
 
+       // Indices
+       indicesModule->apply(bp_);
+
        // language & quotes
        if (langModule->defaultencodingRB->isChecked()) {
                bp_.inputenc = "auto";
@@ -2047,6 +2058,9 @@ void GuiDocument::paramsToDialog()
        biblioModule->bibtopicCB->setChecked(
                bp_.use_bibtopic);
 
+       // indices
+       indicesModule->update(bp_);
+
        // language & quotes
        int const pos = langModule->languageCO->findData(toqstr(
                bp_.language->lang()));
@@ -2618,6 +2632,20 @@ void GuiDocument::dispatchParams()
                dispatch(FuncRequest(LFUN_ALL_INSETS_TOGGLE,
                        "assign branch"));
        }
+       // Generate the colours requested by indices.
+       IndicesList & indiceslist = params().indiceslist();
+       if (!indiceslist.empty()) {
+               IndicesList::const_iterator it = indiceslist.begin();
+               IndicesList::const_iterator const end = indiceslist.end();
+               for (; it != end; ++it) {
+                       docstring const & current_index = it->index();
+                       Index const * index = indiceslist.find(current_index);
+                       string const x11hexname = X11hexname(index->color());
+                       // display the new color
+                       docstring const str = current_index + ' ' + from_ascii(x11hexname);
+                       dispatch(FuncRequest(LFUN_SET_COLOR, str));
+               }
+       }
        // FIXME: If we used an LFUN, we would not need those two lines:
        BufferView * bv = const_cast<BufferView *>(bufferview());
        bv->processUpdateFlags(Update::Force | Update::FitCursor);
index 43cb9a265ba28b1ab850824f6bfa37089d287a50..e2075759c52b21ad22a0ce44a92c3e66355b0ff5 100644 (file)
@@ -48,6 +48,7 @@ class TextClass;
 namespace frontend {
 
 class GuiBranches;
+class GuiIndices;
 class ModuleSelectionManager;
 class PreambleModule;
 
@@ -119,9 +120,10 @@ private:
        UiWidget<Ui::PDFSupportUi> *pdfSupportModule;
        UiWidget<Ui::ModulesUi> *modulesModule;
        UiWidget<Ui::OutputUi> *outputModule;
-       PreambleModule *preambleModule;
+       PreambleModule * preambleModule;
        
-       GuiBranches *branchesModule;
+       GuiBranches * branchesModule;
+       GuiIndices * indicesModule;
 
        BulletsModule * bulletsModule;
        FloatPlacement * floatModule;
diff --git a/src/frontends/qt4/GuiIndices.cpp b/src/frontends/qt4/GuiIndices.cpp
new file mode 100644 (file)
index 0000000..ef76321
--- /dev/null
@@ -0,0 +1,217 @@
+/**
+ * \file GuiIndices.cpp
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Edwin Leuven
+ * \author Jürgen Spitzmüller
+ * \author Abdelrazak Younes
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "GuiIndices.h"
+
+#include "ColorCache.h"
+#include "GuiApplication.h"
+#include "Validator.h"
+#include "qt_helpers.h"
+
+#include "frontends/alert.h"
+
+#include "BufferParams.h"
+
+#include "support/gettext.h"
+#include "support/lstrings.h"
+
+#include <QTreeWidget>
+#include <QTreeWidgetItem>
+#include <QPixmap>
+#include <QIcon>
+#include <QColor>
+#include <QColorDialog>
+
+
+namespace lyx {
+namespace frontend {
+
+
+GuiIndices::GuiIndices(QWidget * parent)
+       : QWidget(parent)
+{
+       setupUi(this);
+       indicesTW->setColumnCount(2);
+       indicesTW->headerItem()->setText(0, qt_("Name"));
+       indicesTW->headerItem()->setText(1, qt_("Label Color"));
+       indicesTW->setSortingEnabled(true);
+}
+
+void GuiIndices::update(BufferParams const & params)
+{
+       indiceslist_ = params.indiceslist();
+       multipleIndicesCB->setChecked(
+               params.use_indices);
+       bool const state = params.use_indices;
+       indicesTW->setEnabled(state);
+       newIndexLE->setEnabled(state);
+       newIndexLA->setEnabled(state);
+       addIndexPB->setEnabled(state);
+       availableLA->setEnabled(state);
+       removePB->setEnabled(state);
+       colorPB->setEnabled(state);
+       updateView();
+}
+
+
+void GuiIndices::updateView()
+{
+       // store the selected index
+       QTreeWidgetItem * item = indicesTW->currentItem();
+       QString sel_index;
+       if (item != 0)
+               sel_index = item->text(0);
+
+       indicesTW->clear();
+
+       IndicesList::const_iterator it = indiceslist_.begin();
+       IndicesList::const_iterator const end = indiceslist_.end();
+       for (; it != end; ++it) {
+               QTreeWidgetItem * newItem = new QTreeWidgetItem(indicesTW);
+
+               QString const iname = toqstr(it->index());
+               newItem->setText(0, iname);
+
+               QColor const itemcolor = rgb2qcolor(it->color());
+               if (itemcolor.isValid()) {
+                       QPixmap coloritem(30, 10);
+                       coloritem.fill(itemcolor);
+                       newItem->setIcon(1, QIcon(coloritem));
+               }
+               // restore selected index
+               if (iname == sel_index) {
+                       indicesTW->setCurrentItem(newItem);
+                       indicesTW->setItemSelected(newItem, true);
+               }
+       }
+       // emit signal
+       changed();
+}
+
+
+void GuiIndices::apply(BufferParams & params) const
+{
+       params.use_indices = multipleIndicesCB->isChecked();
+       params.indiceslist() = indiceslist_;
+}
+
+
+void GuiIndices::on_addIndexPB_pressed()
+{
+       QString const new_index = newIndexLE->text();
+       if (!new_index.isEmpty()) {
+               indiceslist_.add(qstring_to_ucs4(new_index));
+               newIndexLE->clear();
+               updateView();
+       }
+}
+
+
+void GuiIndices::on_removePB_pressed()
+{
+       QTreeWidgetItem * selItem = indicesTW->currentItem();
+       QString sel_index;
+       if (selItem != 0)
+               sel_index = selItem->text(0);
+       if (!sel_index.isEmpty()) {
+               if (indiceslist_.find(qstring_to_ucs4(sel_index)) == 
+                   indiceslist_.findShortcut(from_ascii("idx"))) {
+                       Alert::error(_("Cannot remove standard index"), 
+                             _("The default index cannot be removed."));
+                             return;
+               }
+               indiceslist_.remove(qstring_to_ucs4(sel_index));
+               newIndexLE->clear();
+               updateView();
+       }
+}
+
+
+void GuiIndices::on_renamePB_clicked()
+{
+       QTreeWidgetItem * selItem = indicesTW->currentItem();
+       QString sel_index;
+       if (selItem != 0)
+               sel_index = selItem->text(0);
+       if (!sel_index.isEmpty()) {
+               docstring newname;
+               bool success = false;
+               if (Alert::askForText(newname, _("Enter new index name"))) {
+                       success = indiceslist_.rename(qstring_to_ucs4(sel_index), newname);
+                       newIndexLE->clear();
+                       updateView();
+               }
+               if (!success)
+                       Alert::error(_("Renaming failed"), 
+                             _("The index could not be renamed. "
+                               "Check if the new name already exists."));
+       }
+}
+
+
+void GuiIndices::on_indicesTW_itemDoubleClicked(QTreeWidgetItem * item, int /*col*/)
+{
+       toggleColor(item);
+}
+
+
+void GuiIndices::on_colorPB_clicked()
+{
+       toggleColor(indicesTW->currentItem());
+}
+
+
+void GuiIndices::on_multipleIndicesCB_toggled(bool const state)
+{
+       indicesTW->setEnabled(state);
+       newIndexLE->setEnabled(state);
+       newIndexLA->setEnabled(state);
+       addIndexPB->setEnabled(state);
+       availableLA->setEnabled(state);
+       removePB->setEnabled(state);
+       colorPB->setEnabled(state);
+       // emit signal
+       changed();
+}
+
+
+void GuiIndices::toggleColor(QTreeWidgetItem * item)
+{
+       if (item == 0)
+               return;
+
+       QString sel_index = item->text(0);
+       if (sel_index.isEmpty())
+               return;
+
+       docstring current_index = qstring_to_ucs4(sel_index);
+       Index * index = indiceslist_.find(current_index);
+       if (!index)
+               return;
+
+       QColor const initial = rgb2qcolor(index->color());
+       QColor ncol = QColorDialog::getColor(initial, qApp->focusWidget());
+       if (!ncol.isValid())
+               return;
+
+       // add the color to the indiceslist
+       index->setColor(fromqstr(ncol.name()));
+       newIndexLE->clear();
+       updateView();
+}
+
+} // namespace frontend
+} // namespace lyx
+
+#include "moc_GuiIndices.cpp"
diff --git a/src/frontends/qt4/GuiIndices.h b/src/frontends/qt4/GuiIndices.h
new file mode 100644 (file)
index 0000000..87d946f
--- /dev/null
@@ -0,0 +1,62 @@
+// -*- C++ -*-
+/**
+ * \file GuiIndices.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Edwin Leuven
+ * \author Jürgen Spitzmüller
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef GUIINDICES_H
+#define GUIINDICES_H
+
+#include "GuiDocument.h"
+#include "ui_IndicesUi.h"
+#include "IndicesList.h"
+
+#include <QWidget>
+
+class QTreeWidgetItem;
+
+namespace lyx {
+
+class BufferParams;
+
+namespace frontend {
+
+class GuiIndices : public QWidget, public Ui::IndicesUi
+{
+       Q_OBJECT
+public:
+       GuiIndices(QWidget * parent = 0);
+
+       void update(BufferParams const & params);
+       void apply(BufferParams & params) const;
+
+Q_SIGNALS:
+       void changed();
+
+protected:
+       void toggleColor(QTreeWidgetItem *);
+       void updateView();
+
+protected Q_SLOTS:
+       void on_addIndexPB_pressed();
+       void on_renamePB_clicked();
+       void on_removePB_pressed();
+       void on_indicesTW_itemDoubleClicked(QTreeWidgetItem *, int);
+       void on_colorPB_clicked();
+       void on_multipleIndicesCB_toggled(bool);
+
+private:
+       /// Contains all legal indices for this doc
+       IndicesList indiceslist_;
+};
+
+} // namespace frontend
+} // namespace lyx
+
+#endif // GUIINDICES_H
index d44cfe45792053c578bc81ab421ec49a1bb087da..084cf8f2eb730991f25e0b5366c55bcfa2e41a34 100644 (file)
@@ -90,6 +90,7 @@ SOURCEFILES = \
        GuiIdListModel.cpp \
        GuiImage.cpp \
        GuiInclude.cpp \
+       GuiIndices.cpp \
        GuiInfo.cpp \
        GuiKeySymbol.cpp \
        GuiLabel.cpp \
@@ -186,6 +187,7 @@ MOCHEADER = \
        GuiHSpace.h \
        GuiHyperlink.h \
        GuiInclude.h \
+       GuiIndices.h \
        GuiInfo.h \
        GuiLabel.h \
        GuiListings.h \
@@ -254,6 +256,7 @@ UIFILES = \
        HSpaceUi.ui \
        HyperlinkUi.ui \
        IncludeUi.ui \
+       IndicesUi.ui \
        InfoUi.ui \
        LabelUi.ui \
        LanguageUi.ui \
index 3aae083995a4c41a11f5bed5db0b0d75cd8c614b..5df6e4e8c4cf54dd5d244f7a1725f0932aeb8eb0 100644 (file)
@@ -36,6 +36,7 @@
 #include "Format.h"
 #include "FuncRequest.h"
 #include "FuncStatus.h"
+#include "IndicesList.h"
 #include "KeyMap.h"
 #include "Lexer.h"
 #include "LyXAction.h"
@@ -148,6 +149,14 @@ public:
                Toolbars,
                /** Available branches in document */
                Branches,
+               /** Available indices in document */
+               Indices,
+               /** Context menu for indices in document */
+               IndicesContext,
+               /** Available index lists in document */
+               IndicesLists,
+               /** Context menu for available indices lists in document */
+               IndicesListsContext,
                /** Available citation styles for a given citation */
                CiteStyles,
                /** Available graphics groups */
@@ -304,6 +313,8 @@ public:
        void expandPasteRecent(Buffer const * buf);
        void expandToolbars();
        void expandBranches(Buffer const * buf);
+       void expandIndices(Buffer const * buf, bool listof = false);
+       void expandIndicesContext(Buffer const * buf, bool listof = false);
        void expandCiteStyles(BufferView const *);
        void expandGraphicsGroups(BufferView const *);
        ///
@@ -395,6 +406,10 @@ void MenuDefinition::read(Lexer & lex)
                md_endmenu,
                md_exportformats,
                md_importformats,
+               md_indices,
+               md_indicescontext,
+               md_indiceslists,
+               md_indiceslistscontext,
                md_lastfiles,
                md_optitem,
                md_optsubmenu,
@@ -424,6 +439,10 @@ void MenuDefinition::read(Lexer & lex)
                { "floatlistinsert", md_floatlistinsert },
                { "graphicsgroups", md_graphicsgroups },
                { "importformats", md_importformats },
+               { "indices", md_indices },
+               { "indicescontext", md_indicescontext },
+               { "indiceslists", md_indiceslists },
+               { "indiceslistscontext", md_indiceslistscontext },
                { "item", md_item },
                { "lastfiles", md_lastfiles },
                { "optitem", md_optitem },
@@ -538,6 +557,22 @@ void MenuDefinition::read(Lexer & lex)
                        add(MenuItem(MenuItem::GraphicsGroups));
                        break;
 
+               case md_indices:
+                       add(MenuItem(MenuItem::Indices));
+                       break;
+
+               case md_indicescontext:
+                       add(MenuItem(MenuItem::IndicesContext));
+                       break;
+
+               case md_indiceslists:
+                       add(MenuItem(MenuItem::IndicesLists));
+                       break;
+
+               case md_indiceslistscontext:
+                       add(MenuItem(MenuItem::IndicesListsContext));
+                       break;
+
                case md_optsubmenu:
                        optional = true;
                        // fallback to md_submenu
@@ -1099,6 +1134,78 @@ void MenuDefinition::expandBranches(Buffer const * buf)
 }
 
 
+void MenuDefinition::expandIndices(Buffer const * buf, bool listof)
+{
+       if (!buf)
+               return;
+
+       BufferParams const & params = buf->masterBuffer()->params();
+       if (!params.use_indices) {
+               if (listof)
+                       addWithStatusCheck(MenuItem(MenuItem::Command,
+                                          qt_("Index List|I"),
+                                          FuncRequest(LFUN_INDEX_PRINT,
+                                                 from_ascii("idx"))));
+               else
+                       addWithStatusCheck(MenuItem(MenuItem::Command,
+                                          qt_("Index Entry|d"),
+                                          FuncRequest(LFUN_INDEX_INSERT,
+                                                 from_ascii("idx"))));
+               return;
+       }
+
+       if (params.indiceslist().empty())
+               return;
+
+       IndicesList::const_iterator cit = params.indiceslist().begin();
+       IndicesList::const_iterator end = params.indiceslist().end();
+
+       for (int ii = 1; cit != end; ++cit, ++ii) {
+               if (listof)
+                       addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(cit->index()),
+                                          FuncRequest(LFUN_INDEX_PRINT,
+                                                 cit->shortcut())));
+               else {
+                       docstring label = _("Index Entry");
+                       label += " (" + cit->index() + ")";
+                       addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(label),
+                                          FuncRequest(LFUN_INDEX_INSERT,
+                                                 cit->shortcut())));
+               }
+       }
+}
+
+
+void MenuDefinition::expandIndicesContext(Buffer const * buf, bool listof)
+{
+       if (!buf)
+               return;
+
+       BufferParams const & params = buf->masterBuffer()->params();
+       if (!params.use_indices || params.indiceslist().empty())
+               return;
+
+       IndicesList::const_iterator cit = params.indiceslist().begin();
+       IndicesList::const_iterator end = params.indiceslist().end();
+
+       for (int ii = 1; cit != end; ++cit, ++ii) {
+               if (listof) {
+                       InsetCommandParams p(INDEX_PRINT_CODE);
+                       p["type"] = cit->shortcut();
+                       string const data = InsetCommand::params2string("index_print", p);
+                       addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(cit->index()),
+                                          FuncRequest(LFUN_NEXT_INSET_MODIFY, data)));
+               } else {
+                       docstring label = _("Index Entry");
+                       label += " (" + cit->index() + ")";
+                       addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(label),
+                                          FuncRequest(LFUN_NEXT_INSET_MODIFY,
+                                                 from_ascii("changetype ") + cit->shortcut())));
+               }
+       }
+}
+
+
 void MenuDefinition::expandCiteStyles(BufferView const * bv)
 {
        if (!bv)
@@ -1251,7 +1358,7 @@ struct Menus::Impl {
        /// Expands some special entries of the menu
        /** The entries with the following kind are expanded to a
            sequence of Command MenuItems: Lastfiles, Documents,
-           ViewFormats, ExportFormats, UpdateFormats, Branches
+           ViewFormats, ExportFormats, UpdateFormats, Branches, Indices
        */
        void expand(MenuDefinition const & frommenu, MenuDefinition & tomenu,
                BufferView const *) const;
@@ -1426,6 +1533,22 @@ void Menus::Impl::expand(MenuDefinition const & frommenu,
                        tomenu.expandBranches(buf);
                        break;
 
+               case MenuItem::Indices:
+                       tomenu.expandIndices(buf);
+                       break;
+
+               case MenuItem::IndicesContext:
+                       tomenu.expandIndicesContext(buf);
+                       break;
+
+               case MenuItem::IndicesLists:
+                       tomenu.expandIndices(buf, true);
+                       break;
+
+               case MenuItem::IndicesListsContext:
+                       tomenu.expandIndicesContext(buf, true);
+                       break;
+
                case MenuItem::CiteStyles:
                        tomenu.expandCiteStyles(bv);
                        break;
diff --git a/src/frontends/qt4/ui/IndicesUi.ui b/src/frontends/qt4/ui/IndicesUi.ui
new file mode 100644 (file)
index 0000000..c9407d7
--- /dev/null
@@ -0,0 +1,142 @@
+<ui version="4.0" >
+ <class>IndicesUi</class>
+ <widget class="QWidget" name="IndicesUi" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>401</width>
+    <height>340</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string/>
+  </property>
+  <layout class="QGridLayout" >
+   <property name="margin" >
+    <number>9</number>
+   </property>
+   <property name="spacing" >
+    <number>6</number>
+   </property>
+   <item row="2" column="0" colspan="2" >
+    <layout class="QHBoxLayout" >
+     <property name="margin" >
+      <number>0</number>
+     </property>
+     <property name="spacing" >
+      <number>6</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="newIndexLA" >
+       <property name="text" >
+        <string>&amp;New:</string>
+       </property>
+       <property name="buddy" >
+        <cstring>newIndexLE</cstring>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="newIndexLE" >
+       <property name="toolTip" >
+        <string>Enter the name of the desired index (e.g. "Index of Names") and hit "Add"</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="addIndexPB" >
+       <property name="toolTip" >
+        <string>Add a new branch to the list</string>
+       </property>
+       <property name="text" >
+        <string>&amp;Add</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="4" column="1" >
+    <widget class="QPushButton" name="removePB" >
+     <property name="toolTip" >
+      <string>Remove the selected index</string>
+     </property>
+     <property name="text" >
+      <string>&amp;Remove</string>
+     </property>
+    </widget>
+   </item>
+   <item row="7" column="1" >
+    <spacer>
+     <property name="orientation" >
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeType" >
+      <enum>QSizePolicy::Expanding</enum>
+     </property>
+     <property name="sizeHint" >
+      <size>
+       <width>20</width>
+       <height>121</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item row="3" column="0" >
+    <widget class="QLabel" name="availableLA" >
+     <property name="text" >
+      <string>A&amp;vailable Indices:</string>
+     </property>
+     <property name="buddy" >
+      <cstring>indicesTW</cstring>
+     </property>
+    </widget>
+   </item>
+   <item rowspan="4" row="4" column="0" >
+    <widget class="QTreeWidget" name="indicesTW" />
+   </item>
+   <item row="0" column="0" >
+    <widget class="QCheckBox" name="multipleIndicesCB" >
+     <property name="toolTip" >
+      <string>Check if you need multiple indices (e.g., an Index of Names)</string>
+     </property>
+     <property name="text" >
+      <string>&amp;Use multiple indices</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0" colspan="2" >
+    <widget class="Line" name="line" >
+     <property name="orientation" >
+      <enum>Qt::Horizontal</enum>
+     </property>
+    </widget>
+   </item>
+   <item row="6" column="1" >
+    <widget class="QPushButton" name="colorPB" >
+     <property name="toolTip" >
+      <string>Define or change button color</string>
+     </property>
+     <property name="text" >
+      <string>Alter Co&amp;lor...</string>
+     </property>
+    </widget>
+   </item>
+   <item row="5" column="1" >
+    <widget class="QPushButton" name="renamePB" >
+     <property name="toolTip" >
+      <string>Rename the selected index</string>
+     </property>
+     <property name="text" >
+      <string>R&amp;ename...</string>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <includes>
+  <include location="local" >qt_i18n.h</include>
+ </includes>
+ <resources/>
+ <connections/>
+</ui>
index 998089be3a3876d08c6dc4889d2b2e856b4d3da4..495b612e9ff1533a760d8cc970ac67eb36328f87 100644 (file)
@@ -4,6 +4,7 @@
  * Licence details can be found in the file COPYING.
  *
  * \author Lars Gullik Bjønnes
+ * \author Jürgen Spitzmüller
  *
  * Full author contact details are available in file CREDITS.
  */
 #include "InsetIndex.h"
 
 #include "Buffer.h"
+#include "BufferParams.h"
+#include "ColorSet.h"
 #include "DispatchResult.h"
 #include "Encoding.h"
 #include "FuncRequest.h"
 #include "FuncStatus.h"
+#include "IndicesList.h"
 #include "LaTeXFeatures.h"
+#include "Lexer.h"
 #include "MetricsInfo.h"
 #include "sgml.h"
 #include "TocBackend.h"
@@ -42,16 +47,23 @@ namespace lyx {
 ///////////////////////////////////////////////////////////////////////
 
 
-InsetIndex::InsetIndex(Buffer const & buf)
-       : InsetCollapsable(buf)
+InsetIndex::InsetIndex(Buffer const & buf, InsetIndexParams const & params)
+       : InsetCollapsable(buf), params_(params)
 {}
 
 
 int InsetIndex::latex(odocstream & os,
                      OutputParams const & runparams) const
 {
-       os << "\\index";
-       os << '{';
+       if (buffer().masterBuffer()->params().use_indices && !params_.index.empty()
+           && params_.index != "idx") {
+               os << "\\sindex[";
+               os << params_.index;
+               os << "]{";
+       } else {
+               os << "\\index";
+               os << '{';
+       }
        int i = 0;
 
        // get contents of InsetText as LaTeX and plaintext
@@ -158,13 +170,99 @@ int InsetIndex::docbook(odocstream & os, OutputParams const & runparams) const
 }
 
 
+void InsetIndex::doDispatch(Cursor & cur, FuncRequest & cmd)
+{
+       switch (cmd.action) {
+
+       case LFUN_INSET_MODIFY: {
+               if (cmd.getArg(0) == "changetype") {
+                       params_.index = from_utf8(cmd.getArg(1));
+                       setLayout(cur.buffer()->params());
+                       break;
+               }
+       }
+
+       default:
+               InsetCollapsable::doDispatch(cur, cmd);
+               break;
+       }
+}
+
+
+bool InsetIndex::getStatus(Cursor & cur, FuncRequest const & cmd,
+               FuncStatus & flag) const
+{
+       switch (cmd.action) {
+
+       case LFUN_INSET_MODIFY:
+               if (cmd.getArg(0) == "changetype") {
+                       docstring const newtype = from_utf8(cmd.getArg(1));
+                       Buffer const & realbuffer = *buffer().masterBuffer();
+                       IndicesList const & indiceslist = realbuffer.params().indiceslist();
+                       Index const * index = indiceslist.findShortcut(newtype);
+                       flag.setEnabled(index != 0);
+                       flag.setOnOff(
+                               from_utf8(cmd.getArg(1)) == params_.index);
+                       return true;
+               }
+
+       default:
+               return InsetCollapsable::getStatus(cur, cmd, flag);
+       }
+}
+
+
+docstring const InsetIndex::buttonLabel(BufferView const & bv) const
+{
+       docstring s = _("Idx");
+       if (decoration() == InsetLayout::CLASSIC)
+               return isOpen(bv) ? s : getNewLabel(s);
+       else
+               return getNewLabel(s);
+}
+
+
+docstring InsetIndex::toolTip(BufferView const &, int, int) const
+{
+       docstring tip = _("Index Entry");
+       if (buffer().params().use_indices && !params_.index.empty()) {
+               Buffer const & realbuffer = *buffer().masterBuffer();
+               IndicesList const & indiceslist = realbuffer.params().indiceslist();
+               tip += " (";
+               Index const * index = indiceslist.findShortcut(params_.index);
+               if (!index)
+                       tip += _("unknown type!");
+               else
+                       tip += index->index();
+               tip += ")";
+       }
+       tip += ": ";
+       OutputParams rp(&buffer().params().encoding());
+       odocstringstream ods;
+       InsetText::plaintext(ods, rp);
+       tip += ods.str();
+       // shorten it if necessary
+       if (tip.size() > 200)
+               tip = tip.substr(0, 200) + "...";
+       return tip;
+}
+
+
 void InsetIndex::write(ostream & os) const
 {
-       os << to_utf8(name()) << "\n";
+       os << to_utf8(name());
+       params_.write(os);
        InsetCollapsable::write(os);
 }
 
 
+void InsetIndex::read(Lexer & lex)
+{
+       params_.read(lex);
+       InsetCollapsable::read(lex);
+}
+
+
 void InsetIndex::addToToc(DocIterator const & cpit)
 {
        DocIterator pit = cpit;
@@ -176,6 +274,41 @@ void InsetIndex::addToToc(DocIterator const & cpit)
 }
 
 
+void InsetIndex::validate(LaTeXFeatures & features) const
+{
+       if (buffer().masterBuffer()->params().use_indices
+           && !params_.index.empty()
+           && params_.index != "idx")
+               features.require("splitidx");
+}
+
+
+docstring InsetIndex::contextMenu(BufferView const &, int, int) const
+{
+       return from_ascii("context-index");
+}
+
+
+void InsetIndexParams::write(ostream & os) const
+{
+       os << ' ';
+       if (!index.empty())
+               os << to_utf8(index);
+       else
+               os << "idx";
+       os << '\n';
+}
+
+
+void InsetIndexParams::read(Lexer & lex)
+{
+       if (lex.eatLine())
+               index = lex.getDocString();
+       else
+               index = from_ascii("idx");
+}
+
+
 /////////////////////////////////////////////////////////////////////
 //
 // InsetPrintIndex
@@ -183,34 +316,85 @@ void InsetIndex::addToToc(DocIterator const & cpit)
 ///////////////////////////////////////////////////////////////////////
 
 InsetPrintIndex::InsetPrintIndex(InsetCommandParams const & p)
-       : InsetCommand(p, string())
+       : InsetCommand(p, "index_print")
 {}
 
 
 ParamInfo const & InsetPrintIndex::findInfo(string const & /* cmdName */)
 {
        static ParamInfo param_info_;
-       if (param_info_.empty())
+       if (param_info_.empty()) {
+               param_info_.add("type", ParamInfo::LATEX_OPTIONAL);
                param_info_.add("name", ParamInfo::LATEX_REQUIRED);
+       }
        return param_info_;
 }
 
 
 docstring InsetPrintIndex::screenLabel() const
 {
-       return _("Index");
+       if ((!buffer().masterBuffer()->params().use_indices
+            && getParam("type") == from_ascii("idx"))
+           || getParam("type").empty())
+               return _("Index");
+       Buffer const & realbuffer = *buffer().masterBuffer();
+       IndicesList const & indiceslist = realbuffer.params().indiceslist();
+       Index const * index = indiceslist.findShortcut(getParam("type"));
+       if (!index)
+               return _("Unknown index type!");
+       docstring res = index->index();
+       if (!buffer().masterBuffer()->params().use_indices)
+               res += " (" + _("non-active") + ")";
+       return res;
+}
+
+
+bool InsetPrintIndex::getStatus(Cursor & cur, FuncRequest const & cmd,
+       FuncStatus & status) const
+{
+       switch (cmd.action) {
+
+       case LFUN_INSET_MODIFY: {
+               InsetCommandParams p(INDEX_PRINT_CODE);
+               InsetCommand::string2params("index_print", to_utf8(cmd.argument()), p);
+               Buffer const & realbuffer = *buffer().masterBuffer();
+               IndicesList const & indiceslist = realbuffer.params().indiceslist();
+               Index const * index = indiceslist.findShortcut(p["type"]);
+               status.setEnabled(index != 0);
+               status.setOnOff(p["type"] == getParam("type"));
+               return true;
+       } 
+
+       default:
+               return InsetCommand::getStatus(cur, cmd, status);
+       }
+}
+
+
+int InsetPrintIndex::latex(odocstream & os, OutputParams const &) const
+{
+       if (!buffer().masterBuffer()->params().use_indices) {
+               if (getParam("type") == from_ascii("idx"))
+                       os << "\\printindex{}";
+               return 0;
+       }
+       os << getCommand();
+       return 0;
 }
 
 
 void InsetPrintIndex::validate(LaTeXFeatures & features) const
 {
        features.require("makeidx");
+       if (buffer().masterBuffer()->params().use_indices)
+               features.require("splitidx");
 }
 
 
-InsetCode InsetPrintIndex::lyxCode() const
+docstring InsetPrintIndex::contextMenu(BufferView const &, int, int) const
 {
-       return INDEX_PRINT_CODE;
+       return buffer().masterBuffer()->params().use_indices ?
+               from_ascii("context-indexprint") : docstring();
 }
 
 } // namespace lyx
index 19f61a49fcc925b1ebc035c72320f6454fd92733..15c5e7e3fdcb60fff340913b1c7a3f9bb8bcde42 100644 (file)
 
 namespace lyx {
 
+class InsetIndexParams {
+public:
+       ///
+       explicit InsetIndexParams(docstring const & b = docstring())
+               : index(b) {}
+       ///
+       void write(std::ostream & os) const;
+       ///
+       void read(Lexer & lex);
+       ///
+       docstring index;
+};
+
+
 /** Used to insert index labels
   */
 class InsetIndex : public InsetCollapsable {
 public:
        ///
-       InsetIndex(Buffer const &);
+       InsetIndex(Buffer const &, InsetIndexParams const &);
 private:
        ///
        EDITABLE editable() const { return HIGHLY_EDITABLE; }
@@ -35,15 +49,34 @@ private:
        ///
        void write(std::ostream & os) const;
        ///
+       void read(Lexer & lex);
+       ///
        int docbook(odocstream &, OutputParams const &) const;
        ///
        int latex(odocstream &, OutputParams const &) const;
+       ///
+       bool getStatus(Cursor &, FuncRequest const &, FuncStatus &) const;
+       ///
+       void doDispatch(Cursor & cur, FuncRequest & cmd);
        /// should paragraph indendation be omitted in any case?
        bool neverIndent() const { return true; }
        ///
        void addToToc(DocIterator const &);
        ///
+       docstring const buttonLabel(BufferView const & bv) const;
+       ///
+       docstring toolTip(BufferView const & bv, int x, int y) const;
+       /// Updates needed features for this inset.
+       void validate(LaTeXFeatures & features) const;
+       ///
+       docstring contextMenu(BufferView const & bv, int x, int y) const;
+       ///
        Inset * clone() const { return new InsetIndex(*this); }
+
+       ///
+       friend class InsetIndexParams;
+       ///
+       InsetIndexParams params_;
 };
 
 
@@ -51,6 +84,8 @@ class InsetPrintIndex : public InsetCommand {
 public:
        ///
        InsetPrintIndex(InsetCommandParams const &);
+       ///
+       InsetCode lyxCode() const { return INDEX_PRINT_CODE; }
 
        ///
        static ParamInfo const & findInfo(std::string const &);
@@ -59,14 +94,18 @@ public:
        ///
        static bool isCompatibleCommand(std::string const & s) 
                { return s == "printindex"; }
+       ///
+       int latex(odocstream &, OutputParams const &) const;
+       ///
+       bool getStatus(Cursor &, FuncRequest const &, FuncStatus &) const;
+       ///
+       virtual docstring contextMenu(BufferView const & bv, int x, int y) const;
 private:
        /// Updates needed features for this inset.
        void validate(LaTeXFeatures & features) const;
        ///
        EDITABLE editable() const { return NOT_EDITABLE; }
        ///
-       InsetCode lyxCode() const;
-       ///
        DisplayType display() const { return AlignCenter; }
        ///
        docstring screenLabel() const;