--- /dev/null
+#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
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());
-
- 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);
-
- 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();
+ // 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_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);
+
+ 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());
-
- // 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);
+
+ 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());
+
+ // 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;
-
- VSpace space_top, 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 (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"));
+ if (!lv_->view()->available() || !dialog_.get())
+ return;
+
+ 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 (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"));
}
void FormParagraph::update()
{
- if (!dialog_.get())
- return;
-
- // Do this first; some objects may be de/activated subsequently.
- bc_.readOnly(lv_->buffer()->isReadonly());
-
- Buffer * buf = lv_->view()->buffer();
-
- /// 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_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;
-
- 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;
- }
-
- LyXAlignment alignpos = tclass[par_->layout()].alignpossible;
-
- 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());
-
- 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());
-
- int linespacing;
- Spacing const space = par_->params().spacing();
-
- 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_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());
+ if (!dialog_.get())
+ return;
+
+ // Do this first; some objects may be de/activated subsequently.
+ bc_.readOnly(lv_->buffer()->isReadonly());
+
+ Buffer * buf = lv_->view()->buffer();
+
+ /// 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_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;
+
+ 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;
+ }
+
+ LyXAlignment alignpos = tclass[par_->layout()].alignpossible;
+
+ 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());
+
+ 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());
+
+ int linespacing;
+ Spacing const space = par_->params().spacing();
+
+ 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_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;
-
- 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.
-
- 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 (fl_get_choice(dialog_->choice_space_above)==7)
- invalid = !input.empty() && !isValidGlueLength(input) && !isStrDbl(input);
-
- input = fl_get_input (dialog_->input_space_below);
-
- if (fl_get_choice(dialog_->choice_space_below)==7)
- invalid = invalid
- || (!input.empty() && !isValidGlueLength(input) && !isStrDbl(input));
-
- 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_linespacing) == 5)
- setEnabled (dialog_->input_linespacing, true);
- else {
- setEnabled (dialog_->input_linespacing, false);
- fl_set_input (dialog_->input_linespacing, "");
- }
-
- double spacing(strToDbl(fl_get_input(dialog_->input_linespacing)));
-
- if (fl_get_choice (dialog_->choice_linespacing) == 5
- && int(spacing) == 0)
- valid = false;
-
- return valid;
+ bool valid = true;
+
+ 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.
+
+ 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 (fl_get_choice(dialog_->choice_space_above) == 7)
+ invalid = !input.empty() &&
+ !isValidGlueLength(input) &&
+ !isStrDbl(input);
+
+ input = fl_get_input(dialog_->input_space_below);
+
+ if (fl_get_choice(dialog_->choice_space_below) == 7)
+ invalid = invalid ||
+ (!input.empty() && !isValidGlueLength(input) && !isStrDbl(input));
+
+ 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_linespacing) == 5)
+ setEnabled(dialog_->input_linespacing, true);
+ else {
+ setEnabled(dialog_->input_linespacing, false);
+ fl_set_input (dialog_->input_linespacing, "");
+ }
+
+ double spacing(strToDbl(fl_get_input(dialog_->input_linespacing)));
+
+ if (fl_get_choice(dialog_->choice_linespacing) == 5 && int(spacing) == 0)
+ valid = false;
+
+ return valid;
}