Introduce splitindex support. File format change.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@29255 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Jürgen Spitzmüller 2009-04-16 07:29:01 +00:00
parent a86337e83f
commit c52bd08442
34 changed files with 1632 additions and 38 deletions

View 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.

View 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

View File

@ -268,6 +268,7 @@
\TestPackage{setspace}
\TestPackage{slashed}
\TestPackage{soul}
\TestPackage{splitidx}
\TestPackage{subfig}
\TestPackage{textcomp}
\TestPackage{ulem}

View 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

View 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
@ -10,12 +10,14 @@
\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

View 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]],

View 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

View 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

View 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];

View 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")));

View 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

View 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";

235
src/IndicesList.cpp Normal file
View File

@ -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

128
src/IndicesList.h Normal file
View File

@ -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

View 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;

View 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";
}

View 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
*/

View 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:

View 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) {

View 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;
///

View 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 \

View 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),

View 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;

View 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:

View 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") {

View 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);

View 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;

View File

@ -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"

View File

@ -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

View 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 \

View 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;

View File

@ -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>

View 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.
*/
@ -12,11 +13,15 @@
#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

View File

@ -19,12 +19,26 @@
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;