tentative fix for #190; other small things

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@3782 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Jean-Marc Lasgouttes 2002-03-19 21:42:50 +00:00
parent a575055c84
commit f10227802b
10 changed files with 1448 additions and 414 deletions

View File

@ -1,3 +1,14 @@
2002-03-19 Jean-Marc Lasgouttes <lasgouttes@freesurf.fr>
* layouts/svjour.inc: remove ProvidesAmsMath
2002-03-19 Kayvan A. Sylvan <kayvan@sylvan.com>
* examples/listerrors.lyx:
* scripts/listerrors: new files
* Makefile.am: Removed build-listerrors cruft.
2002-03-19 Jean-Marc Lasgouttes <lasgouttes@freesurf.fr>
* ui/default.ui: small cleanup: move Tex info and childs to View,

View File

@ -1,7 +1,7 @@
AUTOMAKE_OPTIONS = foreign
DISTCLEANFILES = *.orig *.rej *~ *.bak core textclass.lst packages.lst \
lyxrc.defaults doc/LyXConfig.lyx
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in listerrors
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
SUBDIRS = reLyX
M4=m4
@ -35,7 +35,7 @@ LYXLIBDIRS = bind clipart doc examples help images kbd layouts scripts \
templates tex ui
EXTRA_DIST = CREDITS chkconfig.ltx configure.cmd lyxrc.example \
external_templates $(LYXLIBDIRS) build-listerrors \
external_templates $(LYXLIBDIRS) \
encodings languages symbols configure configure.m4
$(srcdir)/configure: $(srcdir)/configure.m4
@ -56,14 +56,11 @@ install-data-local: libinstalldirs
$(INSTALL_DATA) ${srcdir}/$$i $(DESTDIR)$(pkgdatadir)/$$i ; \
done
install-exec-local: libinstalldirs listerrors
install-exec-local: libinstalldirs
files=`cd ${srcdir} ; echo $(LYXSCRIPTS)` ; \
for i in $${files} ; do \
$(INSTALL_SCRIPT) ${srcdir}/$$i $(DESTDIR)$(pkgdatadir)/$$i ; \
done
if [ -s listerrors ]; then \
$(INSTALL_SCRIPT) listerrors $(DESTDIR)$(bindir)/listerrors; \
fi
uninstall-local:
@$(NORMAL_UNINSTALL)
@ -81,6 +78,3 @@ dist-hook:
rm -rf doc/.cvsignore; \
[ -f doc/UserGuide.lyx ] || { cvs -Q export -r HEAD -d doc lyxdoc || \
echo "WARNING: Unable to get LyX Documentation from CVS!" ; true ; }
listerrors: examples/Literate.lyx
${srcdir}/build-listerrors ${srcdir}

859
lib/examples/listerrors.lyx Normal file
View File

@ -0,0 +1,859 @@
#LyX 1.2 created this file. For more info see http://www.lyx.org/
\lyxformat 220
\textclass literate-article
\begin_preamble
%
% ps2pdf stuff
%
\usepackage[ps2pdf,pdftitle={LyX listerrors re-implemented},urlcolor=blue,linktocpage,letterpaper,colorlinks=true]{hyperref}
\@savsf=1% This is to get around a hyperref+noweb interaction problem
\hyphenpenalty 10000
%
% This (from the noweb FAQ) relaxes the constraint that chunks are never broken across pages.
%
\def\nwendcode{\endtrivlist \endgroup \vfil\penalty10\vfilneg}
\let\nwdocspar=\smallbreak
\end_preamble
\language english
\inputencoding auto
\fontscheme pslatex
\graphics default
\paperfontsize default
\spacing single
\papersize Default
\paperpackage a4
\use_geometry 0
\use_amsmath 0
\use_natbib 0
\use_numerical_citations 0
\paperorientation portrait
\secnumdepth 3
\tocdepth 3
\paragraph_separation indent
\defskip medskip
\quotes_language english
\quotes_times 2
\papercolumns 1
\papersides 1
\paperpagestyle default
\layout Title
LyX listerrors:
\newline
rewritten in Python
\layout Author
Kayvan A.
Sylvan
\newline
\begin_inset LatexCommand \url{mailto:kayvan@sylvan.com}
\end_inset
\layout Date
3/15/2002
\layout Abstract
The listerrors program used to be compiled as a C program and installed
as
\emph on
BINDIR/listerrors
\emph default
along with LyX in order to perform some simple re-formatting of noweb and
GCC error messages.
This document describes and implements the Python version of the same program.
\layout Standard
\begin_inset LatexCommand \tableofcontents{}
\end_inset
\layout Section
Introduction
\layout Standard
The motivation for this program was Bugzilla bug 190
\begin_inset Foot
collapsed true
\layout Standard
Visit
\begin_inset LatexCommand \url{http://bugzilla.lyx.org/show_bug.cgi?id=190}
\end_inset
for the details.
\end_inset
dealing with the
\begin_inset Quotes eld
\end_inset
listerrors
\begin_inset Quotes erd
\end_inset
executable.
\layout Standard
What is
\begin_inset Quotes eld
\end_inset
listerrors
\begin_inset Quotes erd
\end_inset
? Usually, LyX has great support for parsing of error messages.
For each error in the log file, LyX pops up an error box at that location
in the LyX window.
The error scanning routines expect these errors to be in a certain format
(similar to LaTeX errors).
When dealing with Literate Programs, you have
\begin_inset Quotes eld
\end_inset
noweb
\begin_inset Foot
collapsed true
\layout Standard
See
\begin_inset LatexCommand \url{http://www.eecs.harvard.edu/~nr/noweb}
\end_inset
for more information about noweb.
\end_inset
\begin_inset Quotes erd
\end_inset
as well as gcc error messages (and potentially others).
The listerrors program attempts to standardize these error messages to
a format that LyX can parse and react to.
\layout Standard
In a nutshell, the problems with the old implementation of listerrors that
bug 190 refers to were::
\layout Enumerate
It was a C program and it was installed in the user path in the same directory
as LyX.
Having such a generically named binary in, for example,
\emph on
/usr/bin
\emph default
, was potentially confusing.
\layout Enumerate
It required that noweb be installed on the compiling machine (the source
was extracted by noweb from
\emph on
SRCDIR/examples/Literate.lyx
\emph default
, compiled and installed by
\begin_inset Quotes eld
\end_inset
make install
\begin_inset Quotes erd
\end_inset
).
\layout Standard
The new version deals with these problems in the following fashion:
\layout Enumerate
Both the example file (this document) and the program are to be added to
the LyX CVS repository.
\layout Enumerate
The program itself will be installed in
\emph on
SHAREDIR/lyx/scripts
\emph default
, along with other LyX-specific helper scripts.
\layout Standard
In the design and implementation of this new
\begin_inset Quotes eld
\end_inset
listerrors
\begin_inset Quotes erd
\end_inset
, the Python
\begin_inset Foot
collapsed true
\layout Standard
See the Python home page (
\begin_inset LatexCommand \url{http://www.python.org}
\end_inset
) for more information.
\end_inset
language was chosen since it is fully multi-platform and provides a very
uniform and easy to read syntax.
This re-write also simplifies the code for
\begin_inset Quotes eld
\end_inset
listerrors
\begin_inset Quotes erd
\end_inset
greatly.
Python is installed by default on all modern Linux systems and is freely
available for all other platforms.
\layout Scrap
<<listerrors>>=
\newline
#!/usr/bin/python
\newline
"""reformat noweb and compiler errors for LyX.
\newline
\newline
Expects to read from stdin and output to stdout.
\newline
"""
\newline
\newline
__author__ = "Kayvan A.
Sylvan <kayvan@sylvan.com>"
\newline
__date__ = "$Date: 2002/03/19 21:42:48 $"
\newline
__version__ = "$Revision: 1.1 $"
\newline
__credits__ = """Edmar Wienskoski Jr.
<edmar-w-jr@technologist.com>
\newline
original Literate support for LyX.
\newline
Bernard Michael Hurley <berhardh@westherts.ac.uk>
\newline
modifications to original listerrors."""
\newline
__copyright__ = "Copyright 2002 - The LyX team."
\newline
\newline
import sys
\newline
\newline
<<Function Bodies>>
\newline
\newline
if __name__ == "__main__":
\newline
main()
\newline
@
\layout Section
LaTeX style error message
\layout Standard
The following function mimics the TeX error message format.
\layout Scrap
<<Function Bodies>>=
\newline
def write_error(msg, tool = "noweb", line_number = 1):
\newline
"""Write out the given message in TeX error style.
\newline
\newline
called like: write_error(msg, tool, line_number)."""
\newline
print "! Build Error: ==> %s ==>
\backslash
n" % (tool),
\newline
print " ...
\backslash
n
\backslash
nl.%d ...
\backslash
n" % (line_number),
\newline
if type(msg) == type("str"): # simple string
\newline
print msg
\newline
else: # some kind of list (sequence or tuple)
\newline
for m in msg:
\newline
if m != "": print m,
\newline
print
\newline
\newline
@ %def write_error
\layout Section
Filtering errors
\layout Standard
The only complication in our filtering code is that some parsers might need
to push back lines that are read in to be read again later.
We solve this problem by implementing a
\begin_inset Quotes eld
\end_inset
getline
\begin_inset Quotes erd
\end_inset
and
\begin_inset Quotes eld
\end_inset
pushline
\begin_inset Quotes erd
\end_inset
set of functions:
\layout Scrap
<<Function Bodies>>=
\newline
__lines = [] # lines pushed back
\newline
\newline
def getline(file = sys.stdin):
\newline
"""read a line from internal stack or from file.
\newline
\newline
optional file argument defaults to sys.stdin."""
\newline
global __lines
\newline
lines = __lines
\newline
if lines:
\newline
line = lines[-1]
\newline
lines = lines[:-1]
\newline
else:
\newline
line = file.readline()
\newline
return line
\newline
\newline
@ %def getline
\layout Standard
And now for the corresponding pushline function:
\layout Scrap
<<Function Bodies>>=
\newline
def pushline(line):
\newline
"push a line onto the pushback stack."
\newline
global __lines
\newline
lines = __lines
\newline
lines += (line,) # push a list onto the stack, not individual letters
\newline
\newline
@ %def pushline
\layout Standard
The main() entry point function is extremely simple.
Note that this version of
\begin_inset Quotes eld
\end_inset
listerrors
\begin_inset Quotes erd
\end_inset
takes no options and simply filters, attempting simply to match against
the known error message patterns.
The listerrors C program handled a single-character command-line argument
that the current code no longer needs.
\layout Scrap
<<Function Bodies>>=
\newline
def main():
\newline
"""Entry point for listerrors.
Takes no options.
\newline
\newline
Reads stdin and writes to stdout.
Filter errors"""
\newline
\newline
while 1:
\newline
line = getline()
\newline
if line == "": break
\newline
<<Check line against patterns and take action>>
\newline
@ %def main
\layout Standard
For each line read in, we need to find out if it matches any of our tools
(noweb, gcc, etc.) and act accordingly.
\layout Scrap
<<Check line against patterns and take action>>=
\newline
try_patterns_dispatch = [ noweb_try, gcc_try, xlc_try ]
\newline
for predicate in try_patterns_dispatch:
\newline
if predicate(line): break
\newline
@
\layout Section
Different Error Formats
\layout Standard
The following sections handle the various error message formats that we
recognize in this program.
\layout Subsection
noweb errors
\layout Standard
Noweb errors are output on a single line, so examining just the current
line is enough.
\layout Scrap
<<Function Bodies>>=
\newline
def noweb_try(line):
\newline
"""see if line is a noweb error.
\newline
\newline
Returns 1 on success, 0 otherwise.
Outputs on stdout."""
\newline
retval = 0
\newline
<<Look for the unescaped angle-brackets in documentation>>
\newline
<<Look for anything with double angle brackets>>
\newline
<<Last ditch effort scan for specific strings>>
\newline
return retval
\newline
\newline
@ %def noweb_try
\layout Standard
First, we look for the
\begin_inset Quotes eld
\end_inset
unescaped < < in documentation chunk
\begin_inset Quotes erd
\end_inset
message.
This is the only message with an associated line number from noweb.
\layout Scrap
<<Look for the unescaped angle-brackets in documentation>>=
\newline
if line.find(": unescaped << in documentation chunk") != -1:
\newline
line_parts = line.split(':')
\newline
num_str = line_parts[1]
\newline
num_len = len(num_str)
\newline
i = 0
\newline
while i < num_len and num_str[i].isdigit(): i += 1
\newline
if i == num_len:
\newline
write_error(":" + line_parts[2], "noweb", int(num_str))
\newline
retval = 1
\newline
@
\layout Standard
Some noweb messages are simply about undefined scraps.
These can be seen by looking for matching double-angle-brackets.
\layout Scrap
<<Look for anything with double angle brackets>>=
\newline
if (not retval):
\newline
left = line.find("<<")
\newline
if (left != -1) and ((left + 2) < len(line)) and
\backslash
\newline
(line[left+2:].find(">>") != -1):
\newline
write_error(line, "noweb");
\newline
retval = 1;
\newline
@
\layout Standard
Finally, here is an additional list of explicit strings to check for.
\layout Scrap
<<Last ditch effort scan for specific strings>>=
\newline
if (not retval):
\newline
msgs_to_try = ("couldn't open file",
\newline
"couldn't open temporary file",
\newline
"error writing temporary file",
\newline
"ill-formed option",
\newline
"unknown option",
\newline
"Bad format sequence",
\newline
"Can't open output file",
\newline
"Can't open temporary file",
\newline
"Capacity exceeded:",
\newline
"Ignoring unknown option -",
\newline
"This can't happen:",
\newline
"non-numeric line number in")
\newline
for msg in msgs_to_try:
\newline
if line.find(msg) != -1:
\newline
write_error(line, "noweb")
\newline
retval = 1
\newline
break
\newline
@
\layout Subsection
gcc errors
\layout Standard
The gcc errors can be multi-line, with the following format:
\layout LyX-Code
foo.c: In function `main':
\newline
foo.c:3: `bar' undeclared (first use in this function)
\newline
foo.c:3: (Each undeclared identifier is reported only once
\newline
foo.c:3: for each function it appears in.)
\newline
foo.c:3: parse error before `x'
\layout Standard
In order to parse this, the gcc error handler has to look ahead and return
any and all lines that do not match the expected pattern.
\layout Scrap
<<Function Bodies>>=
\newline
def gcc_try(line):
\newline
"""See if line is a gcc error.
Read ahead to handle all the lines.
\newline
\newline
Returns 1 on success, 0 otherwise.
Outputs on stdout."""
\newline
retval = 0
\newline
<<Handle the gcc error message>>
\newline
return retval
\newline
\newline
@ %def gcc_try
\layout Standard
The error message starts with a gcc header (as above) without an associated
line number.
\layout Scrap
<<Handle the gcc error message>>=
\newline
first_space = line.find(' ')
\newline
if first_space > 1: # The smallest would be "X: "
\newline
if line[first_space - 1] == ':':
\newline
header_to_see = line[:first_space - 1]
\newline
next_line = getline()
\newline
if next_line and next_line[:first_space - 1] == header_to_see:
\newline
num_end = first_space
\newline
while next_line[num_end].isdigit(): num_end += 1
\newline
if num_end > first_space: # good!
\newline
<<Accumulate gcc error lines and print it>>
\newline
else: # oops! Not a gcc error.
\newline
pushline(next_line)
\newline
elif next_line:
\newline
pushline(next_line) # return this line to input stream
\newline
@
\layout Standard
At the point in the code that we know that we are in the middle of an error
message, we do the following:
\layout Scrap
<<Accumulate gcc error lines and print it>>=
\newline
num_str = next_line[first_space:num_end]
\newline
msgs = []
\newline
msgs += (line[first_space:],)
\newline
msgs += (next_line[num_end + 1:],)
\newline
header_to_see = next_line[:num_end]
\newline
next_line = getline()
\newline
while next_line and next_line[:num_end] == header_to_see:
\newline
msgs += (next_line[num_end + 1:],)
\newline
next_line = getline()
\newline
if next_line: pushline(next_line)
\newline
write_error(msgs, "gcc", int(num_str))
\newline
retval = 1
\newline
@
\layout Subsection
xlc errors
\layout Standard
A xlc error message is easy to identify.
Every error message starts with a quoted string with no spaces, a comma,
a space, the word
\begin_inset Quotes eld
\end_inset
line
\begin_inset Quotes erd
\end_inset
, a space, and some variable text.
The following routine tests if a given buffer line matches this criteria
(this code would probably be simpler if I used the
\begin_inset Quotes eld
\end_inset
re
\begin_inset Quotes erd
\end_inset
regexp module, but we don't really need the full regular expression engine
here).
\layout Scrap
<<Function Bodies>>=
\newline
def xlc_try(line):
\newline
"""see if line is an xlc error.
\newline
\newline
Returns 1 on success, 0 otherwise.
Outputs on stdout."""
\newline
retval = 0
\newline
if line[0] == '"': # This is the first character of all xlc errors
\newline
next_quote = line.find('"', 1)
\newline
first_space = line.find(' ')
\newline
if (next_quote != -1) and (first_space > next_quote): # no space inisde
quotes
\newline
if line[first_space - 1:first_space + 6] == ", line ":
\newline
num_start = num_end = first_space + 6
\newline
while line[num_end].isdigit(): num_end += 1
\newline
if num_end > num_start:
\newline
write_error(line, "xlc", int(line[num_start : num_end]))
\newline
retval = 1
\newline
return retval
\newline
\newline
@ %def xlc_try
\layout Section
Extracting the code
\layout Standard
This project can be tangled from LyX if you set your
\begin_inset Quotes eld
\end_inset
Program
\begin_inset Quotes erd
\end_inset
convertor to call a generic script that always extracts a scrap named
\family typewriter
build-script
\family default
and executes it.
Here is an example of such a generic script:
\layout LyX-Code
#!/bin/sh
\newline
notangle -Rbuild-script $1 | env NOWEB_SOURCE=$1 sh
\layout Standard
This section defines our build-script, which extracts the code.
\layout Scrap
<<build-script>>=
\newline
#!/bin/sh
\newline
if [ -z "$NOWEB_SOURCE" ]; then NOWEB_SOURCE=listerrors.nw; fi
\newline
notangle -Rlisterrors ${NOWEB_SOURCE} > listerrors
\newline
chmod +x listerrors
\newline
@
\layout Section
Indices
\layout Standard
This section provides cross-references into the rest of the program.
\layout Subsection
Macros
\layout Standard
\begin_inset ERT
status Collapsed
\layout Standard
\backslash
nowebchunks
\end_inset
\layout Subsection
Identifiers
\layout Standard
\begin_inset ERT
status Collapsed
\layout Standard
\backslash
nowebindex
\end_inset
\the_end

View File

@ -21,7 +21,6 @@ Columns 2
Sides 1
PageStyle Plain
MaxCounter Counter_Section
ProvidesAmsmath 1
# Standard style definition
Style Standard

154
lib/scripts/listerrors Executable file
View File

@ -0,0 +1,154 @@
#!/usr/bin/python
"""reformat noweb and compiler errors for LyX.
Expects to read from stdin and output to stdout.
"""
__author__ = "Kayvan A. Sylvan <kayvan@sylvan.com>"
__date__ = "$Date: 2002/03/19 21:42:48 $"
__version__ = "$Revision: 1.1 $"
__credits__ = """Edmar Wienskoski Jr. <edmar-w-jr@technologist.com>
original Literate support for LyX.
Bernard Michael Hurley <berhardh@westherts.ac.uk>
modifications to original listerrors."""
__copyright__ = "Copyright 2002 - The LyX team."
import sys
def write_error(msg, tool = "noweb", line_number = 1):
"""Write out the given message in TeX error style.
called like: write_error(msg, tool, line_number)."""
print "! Build Error: ==> %s ==>\n" % (tool),
print " ...\n\nl.%d ...\n" % (line_number),
if type(msg) == type("str"): # simple string
print msg
else: # some kind of list (sequence or tuple)
for m in msg:
if m != "": print m,
print
__lines = [] # lines pushed back
def getline(file = sys.stdin):
"""read a line from internal stack or from file.
optional file argument defaults to sys.stdin."""
global __lines
lines = __lines
if lines:
line = lines[-1]
lines = lines[:-1]
else:
line = file.readline()
return line
def pushline(line):
"push a line onto the pushback stack."
global __lines
lines = __lines
lines += (line,) # push a list onto the stack, not individual letters
def main():
"""Entry point for listerrors. Takes no options.
Reads stdin and writes to stdout. Filter errors"""
while 1:
line = getline()
if line == "": break
try_patterns_dispatch = [ noweb_try, gcc_try, xlc_try ]
for predicate in try_patterns_dispatch:
if predicate(line): break
def noweb_try(line):
"""see if line is a noweb error.
Returns 1 on success, 0 otherwise. Outputs on stdout."""
retval = 0
if line.find(": unescaped << in documentation chunk") != -1:
line_parts = line.split(':')
num_str = line_parts[1]
num_len = len(num_str)
i = 0
while i < num_len and num_str[i].isdigit(): i += 1
if i == num_len:
write_error(":" + line_parts[2], "noweb", int(num_str))
retval = 1
if (not retval):
left = line.find("<<")
if (left != -1) and ((left + 2) < len(line)) and \
(line[left+2:].find(">>") != -1):
write_error(line, "noweb");
retval = 1;
if (not retval):
msgs_to_try = ("couldn't open file",
"couldn't open temporary file",
"error writing temporary file",
"ill-formed option",
"unknown option",
"Bad format sequence",
"Can't open output file",
"Can't open temporary file",
"Capacity exceeded:",
"Ignoring unknown option -",
"This can't happen:",
"non-numeric line number in")
for msg in msgs_to_try:
if line.find(msg) != -1:
write_error(line, "noweb")
retval = 1
break
return retval
def gcc_try(line):
"""See if line is a gcc error. Read ahead to handle all the lines.
Returns 1 on success, 0 otherwise. Outputs on stdout."""
retval = 0
first_space = line.find(' ')
if first_space > 1: # The smallest would be "X: "
if line[first_space - 1] == ':':
header_to_see = line[:first_space - 1]
next_line = getline()
if next_line and next_line[:first_space - 1] == header_to_see:
num_end = first_space
while next_line[num_end].isdigit(): num_end += 1
if num_end > first_space: # good!
num_str = next_line[first_space:num_end]
msgs = []
msgs += (line[first_space:],)
msgs += (next_line[num_end + 1:],)
header_to_see = next_line[:num_end]
next_line = getline()
while next_line and next_line[:num_end] == header_to_see:
msgs += (next_line[num_end + 1:],)
next_line = getline()
if next_line: pushline(next_line)
write_error(msgs, "gcc", int(num_str))
retval = 1
else: # oops! Not a gcc error.
pushline(next_line)
elif next_line:
pushline(next_line) # return this line to input stream
return retval
def xlc_try(line):
"""see if line is an xlc error.
Returns 1 on success, 0 otherwise. Outputs on stdout."""
retval = 0
if line[0] == '"': # This is the first character of all xlc errors
next_quote = line.find('"', 1)
first_space = line.find(' ')
if (next_quote != -1) and (first_space > next_quote): # no space inisde quotes
if line[first_space - 1:first_space + 6] == ", line ":
num_start = num_end = first_space + 6
while line[num_end].isdigit(): num_end += 1
if num_end > num_start:
write_error(line, "xlc", int(line[num_start : num_end]))
retval = 1
return retval
if __name__ == "__main__":
main()

View File

@ -1,3 +1,7 @@
2002-03-19 Jean-Marc Lasgouttes <lasgouttes@freesurf.fr>
* text2.C (setCursorIntern): put debuging code in INSETS channel
2002-03-19 André Pönitz <poenitz@gmx.net>
* lyxfunc.C: tiny whitespace change

View File

@ -657,7 +657,12 @@ bool Converters::convert(Buffer const * buffer,
if (!conv.parselog.empty()) {
string const logfile = infile2 + ".log";
string const command2 = conv.parselog +
string script =
LibFileSearch("scripts",
conv.parselog);
if (script.empty())
script = conv.parselog;
string const command2 = script +
" < " + QuoteName(infile2 + ".out") +
" > " + QuoteName(logfile);
one.startscript(Systemcall::Wait, command2);

View File

@ -1,3 +1,7 @@
2002-03-19 André Pönitz <poenitz@gmx.net>
* FormParagraph.C: whitespace changes
2002-03-18 Angus Leeming <a.leeming@ic.ac.uk>
* Tooltips.[Ch] (initTooltip): renamed init. In the 0.89 version, no

View File

@ -100,469 +100,471 @@ void FormParagraph::redraw()
FL_FORM * FormParagraph::form() const
{
if (dialog_.get()) return dialog_->form;
return 0;
if (dialog_.get())
return dialog_->form;
return 0;
}
void FormParagraph::build()
{
// the tabbed folder
dialog_.reset(build_paragraph());
// the tabbed folder
dialog_.reset(build_paragraph());
fl_addto_choice(dialog_->choice_space_above,
_(" None | Defskip | Smallskip "
"| Medskip | Bigskip | VFill | Length "));
fl_addto_choice(dialog_->choice_space_below,
_(" None | Defskip | Smallskip "
"| Medskip | Bigskip | VFill | Length "));
fl_addto_choice(dialog_->choice_space_above,
_(" None | Defskip | Smallskip "
"| Medskip | Bigskip | VFill | Length "));
fl_addto_choice(dialog_->choice_space_below,
_(" None | Defskip | Smallskip "
"| Medskip | Bigskip | VFill | Length "));
fl_addto_choice(dialog_->choice_linespacing,
_(" Default | Single | OneHalf | Double | Other "));
fl_set_input_return(dialog_->input_space_above, FL_RETURN_CHANGED);
fl_set_input_return(dialog_->input_space_below, FL_RETURN_CHANGED);
fl_set_input_return(dialog_->input_labelwidth, FL_RETURN_CHANGED);
fl_set_input_return(dialog_->input_linespacing, FL_RETURN_CHANGED);
fl_set_input_filter(dialog_->input_linespacing, fl_unsigned_float_filter);
fl_addto_choice(dialog_->choice_linespacing,
_(" Default | Single | OneHalf | Double | Other "));
setPrehandler(dialog_->input_space_above);
setPrehandler(dialog_->input_space_below);
setPrehandler(dialog_->input_labelwidth);
setPrehandler(dialog_->input_linespacing);
fl_set_input_return(dialog_->input_space_above, FL_RETURN_CHANGED);
fl_set_input_return(dialog_->input_space_below, FL_RETURN_CHANGED);
fl_set_input_return(dialog_->input_labelwidth, FL_RETURN_CHANGED);
fl_set_input_return(dialog_->input_linespacing, FL_RETURN_CHANGED);
fl_set_input_filter(dialog_->input_linespacing, fl_unsigned_float_filter);
// Create the contents of the unit choices
// Don't include the "%" terms...
vector<string> units_vec = getLatexUnits();
setPrehandler(dialog_->input_space_above);
setPrehandler(dialog_->input_space_below);
setPrehandler(dialog_->input_labelwidth);
setPrehandler(dialog_->input_linespacing);
// Create the contents of the unit choices
// Don't include the "%" terms...
vector<string> units_vec = getLatexUnits();
#if 0
for (vector<string>::iterator it = units_vec.begin();
it != units_vec.end(); ++it) {
if (contains(*it, "%"))
it = units_vec.erase(it, it+1) - 1;
}
for (vector<string>::iterator it = units_vec.begin();
it != units_vec.end(); ++it) {
if (contains(*it, "%"))
it = units_vec.erase(it, it+1) - 1;
}
#else
// Something similar to this is a better way to erase
vector<string>::iterator del =
remove_if(units_vec.begin(), units_vec.end(),
bind2nd(contains_functor(), "%"));
units_vec.erase(del, units_vec.end());
// Something similar to this is a better way to erase
vector<string>::iterator del =
remove_if(units_vec.begin(), units_vec.end(),
bind2nd(contains_functor(), "%"));
units_vec.erase(del, units_vec.end());
#endif
string units = getStringFromVector(units_vec, "|");
fl_addto_choice(dialog_->choice_value_space_above, units.c_str());
fl_addto_choice(dialog_->choice_value_space_below, units.c_str());
string units = getStringFromVector(units_vec, "|");
// Manage the ok, apply, restore and cancel/close buttons
bc_.setOK(dialog_->button_ok);
bc_.setApply(dialog_->button_apply);
bc_.setCancel(dialog_->button_close);
bc_.setRestore(dialog_->button_restore);
fl_addto_choice(dialog_->choice_value_space_above, units.c_str());
fl_addto_choice(dialog_->choice_value_space_below, units.c_str());
bc_.addReadOnly (dialog_->radio_align_right);
bc_.addReadOnly (dialog_->radio_align_left);
bc_.addReadOnly (dialog_->radio_align_block);
bc_.addReadOnly (dialog_->radio_align_center);
bc_.addReadOnly (dialog_->check_lines_top);
bc_.addReadOnly (dialog_->check_lines_bottom);
bc_.addReadOnly (dialog_->check_pagebreaks_top);
bc_.addReadOnly (dialog_->check_pagebreaks_bottom);
bc_.addReadOnly (dialog_->choice_space_above);
bc_.addReadOnly (dialog_->input_space_above);
bc_.addReadOnly (dialog_->check_space_above);
bc_.addReadOnly (dialog_->choice_space_below);
bc_.addReadOnly (dialog_->input_space_below);
bc_.addReadOnly (dialog_->check_space_below);
bc_.addReadOnly (dialog_->choice_linespacing);
bc_.addReadOnly (dialog_->input_linespacing);
bc_.addReadOnly (dialog_->check_noindent);
bc_.addReadOnly (dialog_->input_labelwidth);
// Manage the ok, apply, restore and cancel/close buttons
bc_.setOK(dialog_->button_ok);
bc_.setApply(dialog_->button_apply);
bc_.setCancel(dialog_->button_close);
bc_.setRestore(dialog_->button_restore);
bc_.addReadOnly(dialog_->radio_align_right);
bc_.addReadOnly(dialog_->radio_align_left);
bc_.addReadOnly(dialog_->radio_align_block);
bc_.addReadOnly(dialog_->radio_align_center);
bc_.addReadOnly(dialog_->check_lines_top);
bc_.addReadOnly(dialog_->check_lines_bottom);
bc_.addReadOnly(dialog_->check_pagebreaks_top);
bc_.addReadOnly(dialog_->check_pagebreaks_bottom);
bc_.addReadOnly(dialog_->choice_space_above);
bc_.addReadOnly(dialog_->input_space_above);
bc_.addReadOnly(dialog_->check_space_above);
bc_.addReadOnly(dialog_->choice_space_below);
bc_.addReadOnly(dialog_->input_space_below);
bc_.addReadOnly(dialog_->check_space_below);
bc_.addReadOnly(dialog_->choice_linespacing);
bc_.addReadOnly(dialog_->input_linespacing);
bc_.addReadOnly(dialog_->check_noindent);
bc_.addReadOnly(dialog_->input_labelwidth);
}
void FormParagraph::apply()
{
if (!lv_->view()->available() || !dialog_.get())
return;
if (!lv_->view()->available() || !dialog_.get())
return;
VSpace space_top, space_bottom;
LyXAlignment align;
string labelwidthstring;
bool noindent;
VSpace space_top;
VSpace space_bottom;
LyXAlignment align;
string labelwidthstring;
bool noindent;
// If a vspace kind is "Length" but there's no text in
// the input field, reset the kind to "None".
if ((fl_get_choice (dialog_->choice_space_above) == 7) &&
!*(fl_get_input (dialog_->input_space_above)))
{
fl_set_choice (dialog_->choice_space_above, 1);
}
if ((fl_get_choice (dialog_->choice_space_below) == 7) &&
!*(fl_get_input (dialog_->input_space_below)))
{
fl_set_choice (dialog_->choice_space_below, 1);
}
bool line_top = fl_get_button(dialog_->check_lines_top);
bool line_bottom = fl_get_button(dialog_->check_lines_bottom);
bool pagebreak_top = fl_get_button(dialog_->check_pagebreaks_top);
bool pagebreak_bottom = fl_get_button(dialog_->check_pagebreaks_bottom);
switch (fl_get_choice (dialog_->choice_space_above)) {
case 1:
space_top = VSpace(VSpace::NONE);
break;
case 2:
space_top = VSpace(VSpace::DEFSKIP);
break;
case 3:
space_top = VSpace(VSpace::SMALLSKIP);
break;
case 4:
space_top = VSpace(VSpace::MEDSKIP);
break;
case 5:
space_top = VSpace(VSpace::BIGSKIP);
break;
case 6:
space_top = VSpace(VSpace::VFILL);
break;
case 7:
{
string const length =
getLengthFromWidgets(dialog_->input_space_above,
dialog_->choice_value_space_above);
space_top =
VSpace(LyXGlueLength(length));
break;
}
}
// If a vspace kind is "Length" but there's no text in
// the input field, reset the kind to "None".
if ((fl_get_choice(dialog_->choice_space_above) == 7) &&
!*(fl_get_input(dialog_->input_space_above)))
{
fl_set_choice(dialog_->choice_space_above, 1);
}
if (fl_get_button (dialog_->check_space_above))
space_top.setKeep (true);
switch (fl_get_choice (dialog_->choice_space_below)) {
case 1:
space_bottom = VSpace(VSpace::NONE);
break;
case 2:
space_bottom = VSpace(VSpace::DEFSKIP);
break;
case 3:
space_bottom = VSpace(VSpace::SMALLSKIP);
break;
case 4:
space_bottom = VSpace(VSpace::MEDSKIP);
break;
case 5:
space_bottom = VSpace(VSpace::BIGSKIP);
break;
case 6:
space_bottom = VSpace(VSpace::VFILL);
break;
case 7:
string const length =
getLengthFromWidgets(dialog_->input_space_below,
dialog_->choice_value_space_below);
space_bottom = VSpace(LyXGlueLength(length));
break;
}
if (fl_get_button (dialog_->check_space_below))
space_bottom.setKeep (true);
if ((fl_get_choice (dialog_->choice_space_below) == 7) &&
!*(fl_get_input (dialog_->input_space_below)))
{
fl_set_choice(dialog_->choice_space_below, 1);
}
if (fl_get_button(dialog_->radio_align_left))
align = LYX_ALIGN_LEFT;
else if (fl_get_button(dialog_->radio_align_right))
align = LYX_ALIGN_RIGHT;
else if (fl_get_button(dialog_->radio_align_center))
align = LYX_ALIGN_CENTER;
else
align = LYX_ALIGN_BLOCK;
labelwidthstring = fl_get_input(dialog_->input_labelwidth);
noindent = fl_get_button(dialog_->check_noindent);
Spacing::Space linespacing = Spacing::Default;
string other_linespacing;
switch (fl_get_choice(dialog_->choice_linespacing)) {
case 1: linespacing = Spacing::Default; break;
case 2: linespacing = Spacing::Single; break;
case 3: linespacing = Spacing::Onehalf; break;
case 4: linespacing = Spacing::Double; break;
case 5:
linespacing = Spacing::Other;
other_linespacing = fl_get_input(dialog_->input_linespacing);
break;
}
bool line_top = fl_get_button(dialog_->check_lines_top);
bool line_bottom = fl_get_button(dialog_->check_lines_bottom);
bool pagebreak_top = fl_get_button(dialog_->check_pagebreaks_top);
bool pagebreak_bottom = fl_get_button(dialog_->check_pagebreaks_bottom);
Spacing const spacing(linespacing, other_linespacing);
LyXText * text(lv_->view()->getLyXText());
text->setParagraph(lv_->view(), line_top, line_bottom, pagebreak_top,
pagebreak_bottom, space_top, space_bottom, spacing,
align, labelwidthstring, noindent);
switch (fl_get_choice(dialog_->choice_space_above)) {
case 1:
space_top = VSpace(VSpace::NONE);
break;
case 2:
space_top = VSpace(VSpace::DEFSKIP);
break;
case 3:
space_top = VSpace(VSpace::SMALLSKIP);
break;
case 4:
space_top = VSpace(VSpace::MEDSKIP);
break;
case 5:
space_top = VSpace(VSpace::BIGSKIP);
break;
case 6:
space_top = VSpace(VSpace::VFILL);
break;
case 7: {
string const length =
getLengthFromWidgets(dialog_->input_space_above,
dialog_->choice_value_space_above);
space_top = VSpace(LyXGlueLength(length));
break;
}
}
if (fl_get_button(dialog_->check_space_above))
space_top.setKeep(true);
switch (fl_get_choice(dialog_->choice_space_below)) {
case 1:
space_bottom = VSpace(VSpace::NONE);
break;
case 2:
space_bottom = VSpace(VSpace::DEFSKIP);
break;
case 3:
space_bottom = VSpace(VSpace::SMALLSKIP);
break;
case 4:
space_bottom = VSpace(VSpace::MEDSKIP);
break;
case 5:
space_bottom = VSpace(VSpace::BIGSKIP);
break;
case 6:
space_bottom = VSpace(VSpace::VFILL);
break;
case 7:
string const length =
getLengthFromWidgets(dialog_->input_space_below,
dialog_->choice_value_space_below);
space_bottom = VSpace(LyXGlueLength(length));
break;
}
if (fl_get_button (dialog_->check_space_below))
space_bottom.setKeep (true);
if (fl_get_button(dialog_->radio_align_left))
align = LYX_ALIGN_LEFT;
else if (fl_get_button(dialog_->radio_align_right))
align = LYX_ALIGN_RIGHT;
else if (fl_get_button(dialog_->radio_align_center))
align = LYX_ALIGN_CENTER;
else
align = LYX_ALIGN_BLOCK;
labelwidthstring = fl_get_input(dialog_->input_labelwidth);
noindent = fl_get_button(dialog_->check_noindent);
Spacing::Space linespacing = Spacing::Default;
string other_linespacing;
switch (fl_get_choice(dialog_->choice_linespacing)) {
case 1: linespacing = Spacing::Default; break;
case 2: linespacing = Spacing::Single; break;
case 3: linespacing = Spacing::Onehalf; break;
case 4: linespacing = Spacing::Double; break;
case 5:
linespacing = Spacing::Other;
other_linespacing = fl_get_input(dialog_->input_linespacing);
break;
}
Spacing const spacing(linespacing, other_linespacing);
LyXText * text(lv_->view()->getLyXText());
text->setParagraph(lv_->view(), line_top, line_bottom, pagebreak_top,
pagebreak_bottom, space_top, space_bottom, spacing,
align, labelwidthstring, noindent);
// Actually apply these settings
lv_->view()->update(text,
BufferView::SELECT | BufferView::FITCUR | BufferView::CHANGE);
lv_->buffer()->markDirty();
setMinibuffer(lv_, _("Paragraph layout set"));
// Actually apply these settings
lv_->view()->update(text,
BufferView::SELECT | BufferView::FITCUR | BufferView::CHANGE);
lv_->buffer()->markDirty();
setMinibuffer(lv_, _("Paragraph layout set"));
}
void FormParagraph::update()
{
if (!dialog_.get())
return;
if (!dialog_.get())
return;
// Do this first; some objects may be de/activated subsequently.
bc_.readOnly(lv_->buffer()->isReadonly());
// Do this first; some objects may be de/activated subsequently.
bc_.readOnly(lv_->buffer()->isReadonly());
Buffer * buf = lv_->view()->buffer();
Buffer * buf = lv_->view()->buffer();
/// Record the paragraph
par_ = getCurrentParagraph();
/// Record the paragraph
par_ = getCurrentParagraph();
fl_set_input(dialog_->input_labelwidth,
par_->getLabelWidthString().c_str());
setEnabled(dialog_->input_labelwidth,
(par_->getLabelWidthString() != _("Senseless with this layout!")));
fl_set_input(dialog_->input_labelwidth,
par_->getLabelWidthString().c_str());
setEnabled(dialog_->input_labelwidth,
(par_->getLabelWidthString() != _("Senseless with this layout!")));
fl_set_button(dialog_->radio_align_right, 0);
fl_set_button(dialog_->radio_align_left, 0);
fl_set_button(dialog_->radio_align_center, 0);
fl_set_button(dialog_->radio_align_block, 0);
fl_set_button(dialog_->radio_align_right, 0);
fl_set_button(dialog_->radio_align_left, 0);
fl_set_button(dialog_->radio_align_center, 0);
fl_set_button(dialog_->radio_align_block, 0);
LyXTextClass const & tclass = textclasslist[buf->params.textclass];
int align = par_->getAlign();
if (align == LYX_ALIGN_LAYOUT)
align = tclass[par_->layout()].align;
LyXTextClass const & tclass = textclasslist[buf->params.textclass];
switch (align) {
case LYX_ALIGN_RIGHT:
fl_set_button(dialog_->radio_align_right, 1);
break;
case LYX_ALIGN_LEFT:
fl_set_button(dialog_->radio_align_left, 1);
break;
case LYX_ALIGN_CENTER:
fl_set_button(dialog_->radio_align_center, 1);
break;
default:
fl_set_button(dialog_->radio_align_block, 1);
break;
}
int align = par_->getAlign();
if (align == LYX_ALIGN_LAYOUT)
align = tclass[par_->layout()].align;
LyXAlignment alignpos = tclass[par_->layout()].alignpossible;
switch (align) {
case LYX_ALIGN_RIGHT:
fl_set_button(dialog_->radio_align_right, 1);
break;
case LYX_ALIGN_LEFT:
fl_set_button(dialog_->radio_align_left, 1);
break;
case LYX_ALIGN_CENTER:
fl_set_button(dialog_->radio_align_center, 1);
break;
default:
fl_set_button(dialog_->radio_align_block, 1);
break;
}
setEnabled(dialog_->radio_align_block, bool(alignpos & LYX_ALIGN_BLOCK));
setEnabled(dialog_->radio_align_center, bool(alignpos & LYX_ALIGN_CENTER));
setEnabled(dialog_->radio_align_left, bool(alignpos & LYX_ALIGN_LEFT));
setEnabled(dialog_->radio_align_right, bool(alignpos & LYX_ALIGN_RIGHT));
// no inset-text-owned paragraph may have pagebreaks
setEnabled(dialog_->check_pagebreaks_top, !par_->inInset());
setEnabled(dialog_->check_pagebreaks_bottom, !par_->inInset());
LyXAlignment alignpos = tclass[par_->layout()].alignpossible;
fl_set_button(dialog_->check_lines_top,
par_->params().lineTop());
fl_set_button(dialog_->check_lines_bottom,
par_->params().lineBottom());
fl_set_button(dialog_->check_pagebreaks_top,
par_->params().pagebreakTop());
fl_set_button(dialog_->check_pagebreaks_bottom,
par_->params().pagebreakBottom());
fl_set_button(dialog_->check_noindent,
par_->params().noindent());
setEnabled(dialog_->radio_align_block, bool(alignpos & LYX_ALIGN_BLOCK));
setEnabled(dialog_->radio_align_center, bool(alignpos & LYX_ALIGN_CENTER));
setEnabled(dialog_->radio_align_left, bool(alignpos & LYX_ALIGN_LEFT));
setEnabled(dialog_->radio_align_right, bool(alignpos & LYX_ALIGN_RIGHT));
int linespacing;
Spacing const space = par_->params().spacing();
// no inset-text-owned paragraph may have pagebreaks
setEnabled(dialog_->check_pagebreaks_top, !par_->inInset());
setEnabled(dialog_->check_pagebreaks_bottom, !par_->inInset());
switch (space.getSpace()) {
default: linespacing = 1; break;
case Spacing::Single: linespacing = 2; break;
case Spacing::Onehalf: linespacing = 3; break;
case Spacing::Double: linespacing = 4; break;
case Spacing::Other: linespacing = 5; break;
}
fl_set_choice(dialog_->choice_linespacing, linespacing);
if (space.getSpace() == Spacing::Other) {
string const sp = tostr(space.getValue());
fl_set_input(dialog_->input_linespacing, sp.c_str());
setEnabled(dialog_->input_linespacing, true);
} else {
fl_set_input(dialog_->input_linespacing, "");
setEnabled(dialog_->input_linespacing, false);
}
fl_set_button(dialog_->check_lines_top,
par_->params().lineTop());
fl_set_button(dialog_->check_lines_bottom,
par_->params().lineBottom());
fl_set_button(dialog_->check_pagebreaks_top,
par_->params().pagebreakTop());
fl_set_button(dialog_->check_pagebreaks_bottom,
par_->params().pagebreakBottom());
fl_set_button(dialog_->check_noindent,
par_->params().noindent());
fl_set_input (dialog_->input_space_above, "");
int linespacing;
Spacing const space = par_->params().spacing();
setEnabled(dialog_->input_space_above, false);
setEnabled(dialog_->choice_value_space_above, false);
switch (par_->params().spaceTop().kind()) {
case VSpace::NONE:
fl_set_choice (dialog_->choice_space_above, 1);
break;
case VSpace::DEFSKIP:
fl_set_choice (dialog_->choice_space_above, 2);
break;
case VSpace::SMALLSKIP:
fl_set_choice (dialog_->choice_space_above, 3);
break;
case VSpace::MEDSKIP:
fl_set_choice (dialog_->choice_space_above, 4);
break;
case VSpace::BIGSKIP:
fl_set_choice (dialog_->choice_space_above, 5);
break;
case VSpace::VFILL:
fl_set_choice (dialog_->choice_space_above, 6);
break;
case VSpace::LENGTH:
{
fl_set_choice (dialog_->choice_space_above, 7);
setEnabled(dialog_->input_space_above, true);
setEnabled(dialog_->choice_value_space_above, true);
bool const metric = lyxrc.default_papersize > 3;
string const default_unit = metric ? "cm" : "in";
string const length = par_->params().spaceTop().length().asString();
updateWidgetsFromLengthString(dialog_->input_space_above,
dialog_->choice_value_space_above,
length, default_unit);
break;
}
}
fl_set_button (dialog_->check_space_above,
par_->params().spaceTop().keep());
fl_set_input (dialog_->input_space_below, "");
switch (space.getSpace()) {
default: linespacing = 1; break;
case Spacing::Single: linespacing = 2; break;
case Spacing::Onehalf: linespacing = 3; break;
case Spacing::Double: linespacing = 4; break;
case Spacing::Other: linespacing = 5; break;
}
setEnabled(dialog_->input_space_below, false);
setEnabled(dialog_->choice_value_space_below, false);
switch (par_->params().spaceBottom().kind()) {
case VSpace::NONE:
fl_set_choice (dialog_->choice_space_below, 1);
break;
case VSpace::DEFSKIP:
fl_set_choice (dialog_->choice_space_below, 2);
break;
case VSpace::SMALLSKIP:
fl_set_choice (dialog_->choice_space_below, 3);
break;
case VSpace::MEDSKIP:
fl_set_choice (dialog_->choice_space_below, 4);
break;
case VSpace::BIGSKIP:
fl_set_choice (dialog_->choice_space_below, 5);
break;
case VSpace::VFILL:
fl_set_choice (dialog_->choice_space_below, 6);
break;
case VSpace::LENGTH:
{
fl_set_choice (dialog_->choice_space_below, 7);
setEnabled(dialog_->input_space_below, true);
setEnabled(dialog_->choice_value_space_below, true);
bool const metric = lyxrc.default_papersize > 3;
string const default_unit = metric ? "cm" : "in";
string const length =
par_->params().spaceBottom().length().asString();
updateWidgetsFromLengthString(dialog_->input_space_below,
dialog_->choice_value_space_below,
length, default_unit);
break;
}
}
fl_set_choice(dialog_->choice_linespacing, linespacing);
if (space.getSpace() == Spacing::Other) {
string const sp = tostr(space.getValue());
fl_set_input(dialog_->input_linespacing, sp.c_str());
setEnabled(dialog_->input_linespacing, true);
} else {
fl_set_input(dialog_->input_linespacing, "");
setEnabled(dialog_->input_linespacing, false);
}
fl_set_button(dialog_->check_space_below,
par_->params().spaceBottom().keep());
fl_set_button(dialog_->check_noindent,
par_->params().noindent());
fl_set_input (dialog_->input_space_above, "");
setEnabled(dialog_->input_space_above, false);
setEnabled(dialog_->choice_value_space_above, false);
switch (par_->params().spaceTop().kind()) {
case VSpace::NONE:
fl_set_choice (dialog_->choice_space_above, 1);
break;
case VSpace::DEFSKIP:
fl_set_choice (dialog_->choice_space_above, 2);
break;
case VSpace::SMALLSKIP:
fl_set_choice (dialog_->choice_space_above, 3);
break;
case VSpace::MEDSKIP:
fl_set_choice (dialog_->choice_space_above, 4);
break;
case VSpace::BIGSKIP:
fl_set_choice (dialog_->choice_space_above, 5);
break;
case VSpace::VFILL:
fl_set_choice (dialog_->choice_space_above, 6);
break;
case VSpace::LENGTH: {
fl_set_choice (dialog_->choice_space_above, 7);
setEnabled(dialog_->input_space_above, true);
setEnabled(dialog_->choice_value_space_above, true);
bool const metric = lyxrc.default_papersize > 3;
string const default_unit = metric ? "cm" : "in";
string const length = par_->params().spaceTop().length().asString();
updateWidgetsFromLengthString(dialog_->input_space_above,
dialog_->choice_value_space_above,
length, default_unit);
break;
}
}
fl_set_button (dialog_->check_space_above,
par_->params().spaceTop().keep());
fl_set_input (dialog_->input_space_below, "");
setEnabled(dialog_->input_space_below, false);
setEnabled(dialog_->choice_value_space_below, false);
switch (par_->params().spaceBottom().kind()) {
case VSpace::NONE:
fl_set_choice(dialog_->choice_space_below, 1);
break;
case VSpace::DEFSKIP:
fl_set_choice(dialog_->choice_space_below, 2);
break;
case VSpace::SMALLSKIP:
fl_set_choice(dialog_->choice_space_below, 3);
break;
case VSpace::MEDSKIP:
fl_set_choice(dialog_->choice_space_below, 4);
break;
case VSpace::BIGSKIP:
fl_set_choice(dialog_->choice_space_below, 5);
break;
case VSpace::VFILL:
fl_set_choice(dialog_->choice_space_below, 6);
break;
case VSpace::LENGTH: {
fl_set_choice(dialog_->choice_space_below, 7);
setEnabled(dialog_->input_space_below, true);
setEnabled(dialog_->choice_value_space_below, true);
bool const metric = lyxrc.default_papersize > 3;
string const default_unit = metric ? "cm" : "in";
string const length =
par_->params().spaceBottom().length().asString();
updateWidgetsFromLengthString(dialog_->input_space_below,
dialog_->choice_value_space_below,
length, default_unit);
break;
}
}
fl_set_button(dialog_->check_space_below,
par_->params().spaceBottom().keep());
fl_set_button(dialog_->check_noindent,
par_->params().noindent());
}
bool FormParagraph::input(FL_OBJECT * ob, long)
{
bool valid = true;
bool valid = true;
fl_hide_object(dialog_->text_warning);
fl_hide_object(dialog_->text_warning);
// First check the buttons which are exclusive and you have to
// check only the actuall de/activated button.
//
// "Synchronize" the choices and input fields, making it
// impossible to commit senseless data.
// First check the buttons which are exclusive and you have to
// check only the actuall de/activated button.
//
// "Synchronize" the choices and input fields, making it
// impossible to commit senseless data.
if (ob == dialog_->choice_space_above) {
if (fl_get_choice (dialog_->choice_space_above) != 7) {
fl_set_input (dialog_->input_space_above, "");
setEnabled (dialog_->input_space_above, false);
setEnabled (dialog_->choice_value_space_above, false);
} else {
setEnabled (dialog_->input_space_above, !lv_->buffer()->isReadonly());
setEnabled (dialog_->choice_value_space_above, !lv_->buffer()->isReadonly());
bool const metric = lyxrc.default_papersize > 3;
int const default_unit = metric ? 8 : 9;
if (strip(fl_get_input(dialog_->input_space_above)).empty())
fl_set_choice(dialog_->choice_value_space_above,
default_unit);
}
}
if (ob == dialog_->choice_space_below) {
if (fl_get_choice (dialog_->choice_space_below) != 7) {
fl_set_input (dialog_->input_space_below, "");
setEnabled (dialog_->input_space_below, false);
setEnabled (dialog_->choice_value_space_below, false);
} else {
setEnabled (dialog_->input_space_below, !lv_->buffer()->isReadonly());
setEnabled (dialog_->choice_value_space_below, !lv_->buffer()->isReadonly());
bool const metric = lyxrc.default_papersize > 3;
int const default_unit = metric ? 8 : 9;
if (strip(fl_get_input(dialog_->input_space_below)).empty())
fl_set_choice(dialog_->choice_value_space_below,
default_unit);
}
}
//
// warnings if input is senseless
//
string input = fl_get_input (dialog_->input_space_above);
bool invalid = false;
if (ob == dialog_->choice_space_above) {
if (fl_get_choice (dialog_->choice_space_above) != 7) {
fl_set_input(dialog_->input_space_above, "");
setEnabled(dialog_->input_space_above, false);
setEnabled(dialog_->choice_value_space_above, false);
} else {
setEnabled(dialog_->input_space_above,
!lv_->buffer()->isReadonly());
setEnabled(dialog_->choice_value_space_above,
!lv_->buffer()->isReadonly());
bool const metric = lyxrc.default_papersize > 3;
int const default_unit = metric ? 8 : 9;
if (strip(fl_get_input(dialog_->input_space_above)).empty())
fl_set_choice(dialog_->choice_value_space_above, default_unit);
}
}
if (ob == dialog_->choice_space_below) {
if (fl_get_choice (dialog_->choice_space_below) != 7) {
fl_set_input(dialog_->input_space_below, "");
setEnabled(dialog_->input_space_below, false);
setEnabled(dialog_->choice_value_space_below, false);
} else {
setEnabled(dialog_->input_space_below,
!lv_->buffer()->isReadonly());
setEnabled(dialog_->choice_value_space_below,
!lv_->buffer()->isReadonly());
bool const metric = lyxrc.default_papersize > 3;
int const default_unit = metric ? 8 : 9;
if (strip(fl_get_input(dialog_->input_space_below)).empty())
fl_set_choice(dialog_->choice_value_space_below, default_unit);
}
}
if (fl_get_choice(dialog_->choice_space_above)==7)
invalid = !input.empty() && !isValidGlueLength(input) && !isStrDbl(input);
//
// warnings if input is senseless
//
string input = fl_get_input(dialog_->input_space_above);
bool invalid = false;
input = fl_get_input (dialog_->input_space_below);
if (fl_get_choice(dialog_->choice_space_above) == 7)
invalid = !input.empty() &&
!isValidGlueLength(input) &&
!isStrDbl(input);
if (fl_get_choice(dialog_->choice_space_below)==7)
invalid = invalid
|| (!input.empty() && !isValidGlueLength(input) && !isStrDbl(input));
input = fl_get_input(dialog_->input_space_below);
if (ob == dialog_->input_space_above || ob == dialog_->input_space_below) {
if (invalid) {
fl_set_object_label(dialog_->text_warning,
_("Warning: Invalid Length (valid example: 10mm)"));
fl_show_object(dialog_->text_warning);
return false;
} else {
fl_hide_object(dialog_->text_warning);
return true;
}
}
if (fl_get_choice(dialog_->choice_space_below) == 7)
invalid = invalid ||
(!input.empty() && !isValidGlueLength(input) && !isStrDbl(input));
if (fl_get_choice (dialog_->choice_linespacing) == 5)
setEnabled (dialog_->input_linespacing, true);
else {
setEnabled (dialog_->input_linespacing, false);
fl_set_input (dialog_->input_linespacing, "");
}
if (ob == dialog_->input_space_above || ob == dialog_->input_space_below) {
if (invalid) {
fl_set_object_label(dialog_->text_warning,
_("Warning: Invalid Length (valid example: 10mm)"));
fl_show_object(dialog_->text_warning);
return false;
} else {
fl_hide_object(dialog_->text_warning);
return true;
}
}
double spacing(strToDbl(fl_get_input(dialog_->input_linespacing)));
if (fl_get_choice (dialog_->choice_linespacing) == 5)
setEnabled(dialog_->input_linespacing, true);
else {
setEnabled(dialog_->input_linespacing, false);
fl_set_input (dialog_->input_linespacing, "");
}
if (fl_get_choice (dialog_->choice_linespacing) == 5
&& int(spacing) == 0)
valid = false;
double spacing(strToDbl(fl_get_input(dialog_->input_linespacing)));
return valid;
if (fl_get_choice(dialog_->choice_linespacing) == 5 && int(spacing) == 0)
valid = false;
return valid;
}

View File

@ -2156,8 +2156,10 @@ void LyXText::setCursorIntern(BufferView * bview, Paragraph * par,
InsetText * it = static_cast<InsetText *>(par->inInset());
if (it) {
if (it != inset_owner) {
lyxerr << "InsetText is " << it << endl;
lyxerr << "inset_owner is " << inset_owner << endl;
lyxerr[Debug::INSETS] << "InsetText is " << it
<< endl
<< "inset_owner is "
<< inset_owner << endl;
#ifdef WITH_WARNINGS
#warning I believe this code is wrong. (Lgb)
#warning Jürgen, have a look at this. (Lgb)