]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/xforms/FormDocument.C
Bugfixes: checkboxes to radiobuttons (from J�rgen S) and remove a little
[lyx.git] / src / frontends / xforms / FormDocument.C
index c952be85144891f9238c601d281e6d508ed598bb..c18b7d201cbee126888ce90f697cb87f06a612ec 100644 (file)
 #pragma implementation
 #endif
 
-#include "lyx_gui_misc.h"
-
 #include "FormDocument.h"
 #include "form_document.h"
+#include "Alert.h"
 #include "Dialogs.h"
-#include "layout.h"
+#include "lyxtextclasslist.h"
 #include "combox.h"
 #include "tex-strings.h"
 #include "bufferparams.h"
-#include "insets/insetquotes.h"
 #include "vspace.h"
 #include "bmtable.h"
-#include "support/filetools.h"
-#include "support/lstrings.h"
 #include "language.h"
 #include "LyXView.h"
 #include "lyxfunc.h"
 #include "xforms_helpers.h" 
 #include "debug.h"
 #include "input_validators.h" // fl_unsigned_float_filter
+#include "helper_funcs.h" 
+#include "lyx_main.h" // for user_lyxdir
+
+#include "insets/insetquotes.h"
+
+#include "support/filetools.h"
+#include "support/lstrings.h"
 
 using Liason::setMinibuffer;
 using SigC::slot;
@@ -106,46 +109,33 @@ void FormDocument::build()
                          "| Very small Margins "
                          "| Very wide Margins "));
 
-       fl_set_input_return(paper_->input_custom_width, FL_RETURN_CHANGED);
+       fl_set_input_return(paper_->input_custom_width,  FL_RETURN_CHANGED);
        fl_set_input_return(paper_->input_custom_height, FL_RETURN_CHANGED);
-       fl_set_input_return(paper_->input_top_margin, FL_RETURN_CHANGED);
+       fl_set_input_return(paper_->input_top_margin,    FL_RETURN_CHANGED);
        fl_set_input_return(paper_->input_bottom_margin, FL_RETURN_CHANGED);
-       fl_set_input_return(paper_->input_left_margin, FL_RETURN_CHANGED);
-       fl_set_input_return(paper_->input_right_margin, FL_RETURN_CHANGED);
-       fl_set_input_return(paper_->input_head_height, FL_RETURN_CHANGED);
-       fl_set_input_return(paper_->input_head_sep, FL_RETURN_CHANGED);
-       fl_set_input_return(paper_->input_foot_skip, FL_RETURN_CHANGED);
+       fl_set_input_return(paper_->input_inner_margin,  FL_RETURN_CHANGED);
+       fl_set_input_return(paper_->input_outer_margin,  FL_RETURN_CHANGED);
+       fl_set_input_return(paper_->input_head_height,   FL_RETURN_CHANGED);
+       fl_set_input_return(paper_->input_head_sep,      FL_RETURN_CHANGED);
+       fl_set_input_return(paper_->input_foot_skip,     FL_RETURN_CHANGED);
 
-       // Set input filters on width and height to make them accept only
-       // unsigned numbers.
-       fl_set_input_filter(paper_->input_custom_width,
-                           fl_unsigned_float_filter);
-       fl_set_input_filter(paper_->input_custom_height,
-                           fl_unsigned_float_filter);
-       fl_set_input_filter(paper_->input_top_margin,
-                           fl_unsigned_float_filter);
-       fl_set_input_filter(paper_->input_bottom_margin,
-                           fl_unsigned_float_filter);
-       fl_set_input_filter(paper_->input_left_margin,
-                           fl_unsigned_float_filter);
-       fl_set_input_filter(paper_->input_right_margin,
-                           fl_unsigned_float_filter);
-       fl_set_input_filter(paper_->input_head_height,
-                           fl_unsigned_float_filter);
-       fl_set_input_filter(paper_->input_head_sep,
-                           fl_unsigned_float_filter);
-       fl_set_input_filter(paper_->input_foot_skip,
-                           fl_unsigned_float_filter);
 
        // Create the contents of the unit choices
-       string const units = " cm | inch ";
+       // Don't include the "%" terms...
+       std::vector<string> units_vec = getLatexUnits();
+       for (std::vector<string>::iterator it = units_vec.begin();
+               it != units_vec.end(); ++it) {
+               if (contains(*it, "%"))
+                       it = units_vec.erase(it, it+1) - 1;
+       }
+       string units = getStringFromVector(units_vec, "|");
 
        fl_addto_choice(paper_->choice_custom_width_units,  units.c_str());
        fl_addto_choice(paper_->choice_custom_height_units, units.c_str());
        fl_addto_choice(paper_->choice_top_margin_units,    units.c_str());
        fl_addto_choice(paper_->choice_bottom_margin_units, units.c_str());
-       fl_addto_choice(paper_->choice_left_margin_units,   units.c_str());
-       fl_addto_choice(paper_->choice_right_margin_units,  units.c_str());
+       fl_addto_choice(paper_->choice_inner_margin_units,  units.c_str());
+       fl_addto_choice(paper_->choice_outer_margin_units,  units.c_str());
        fl_addto_choice(paper_->choice_head_height_units,   units.c_str());
        fl_addto_choice(paper_->choice_head_sep_units,      units.c_str());
        fl_addto_choice(paper_->choice_foot_skip_units,     units.c_str());
@@ -160,8 +150,8 @@ void FormDocument::build()
        bc().addReadOnly (paper_->input_custom_height);
        bc().addReadOnly (paper_->input_top_margin);
        bc().addReadOnly (paper_->input_bottom_margin);
-       bc().addReadOnly (paper_->input_left_margin);
-       bc().addReadOnly (paper_->input_right_margin);
+       bc().addReadOnly (paper_->input_inner_margin);
+       bc().addReadOnly (paper_->input_outer_margin);
        bc().addReadOnly (paper_->input_head_height);
        bc().addReadOnly (paper_->input_head_sep);
        bc().addReadOnly (paper_->input_foot_skip);
@@ -195,10 +185,15 @@ void FormDocument::build()
                        "default|empty|plain|headings|fancy");
        fl_addto_choice(class_->choice_doc_skip,
                        _(" Smallskip | Medskip | Bigskip | Length "));
+       fl_addto_choice(class_->choice_default_skip_units,  units.c_str());
        fl_set_input_return(class_->input_doc_extra, FL_RETURN_CHANGED);
        fl_set_input_return(class_->input_doc_skip, FL_RETURN_CHANGED);
        fl_set_input_return(class_->input_doc_spacing, FL_RETURN_CHANGED);
 
+       // Set input filters on doc spacing to make it accept only
+       // unsigned numbers.
+       fl_set_input_filter(class_->input_doc_spacing, fl_unsigned_float_filter);
+
        bc().addReadOnly (class_->radio_doc_indent);
        bc().addReadOnly (class_->radio_doc_skip);
 
@@ -345,13 +340,6 @@ void FormDocument::update()
 
        BufferParams const & params = lv_->buffer()->params;
 
-//     fl_set_object_label(dialog_->button_save_defaults,
-//                         _("Save as Defaults"));
-//     fl_set_object_label(dialog_->button_reset_defaults,
-//                         _("Use Class Defaults"));
-       setEnabled(dialog_->button_reset_defaults,
-                  !params.hasClassDefaults());
-
        class_update(params);
        paper_update(params);
        language_update(params);
@@ -360,6 +348,34 @@ void FormDocument::update()
 }
 
 
+namespace {
+// should this go elsewhere? Maybe a ControllerDocument? (JMarc)
+/** Save the buffer's parameters as user default.
+    This function saves a file \c user_lyxdir/templates/defaults.lyx
+    which parameters are those of the current buffer. This file
+    is used as a default template when creating a new
+    file. Returns \c true on success.
+*/
+bool saveParamsAsDefault(BufferParams const &params)
+{
+       if (!Alert::askQuestion(_("Do you want to save the current settings"),
+                        _("for the document layout as default?"),
+                        _("(they will be valid for any new document)")))
+               return false;
+       
+       string const fname = AddName(AddPath(user_lyxdir, "templates/"),
+                                    "defaults.lyx");
+       Buffer defaults = Buffer(fname);
+       defaults.params = params;
+       
+       // add an empty paragraph. Is this enough?
+       defaults.paragraph = new Paragraph;
+               
+       return defaults.writeFile(defaults.fileName(), false);
+}
+
+} //namespace
+
 bool FormDocument::input( FL_OBJECT * ob, long data )
 {
        State cb = static_cast<State>( data );
@@ -395,13 +411,48 @@ bool FormDocument::input( FL_OBJECT * ob, long data )
                break;
        }
 
+       bool const length_input = fl_get_choice(class_->choice_doc_skip) == 4;
+       if (ob == class_->choice_doc_skip) {
+               setEnabled(class_->input_doc_skip, length_input);
+               setEnabled(class_->choice_default_skip_units, length_input);
+       }
+
+       if (ob == class_->choice_doc_spacing)
+               setEnabled(class_->input_doc_spacing,
+                          fl_get_choice(class_->choice_doc_spacing) == 4);
+
+       bool const skip_used = fl_get_button(class_->radio_doc_skip);
+       if (ob == class_->radio_doc_skip ||
+           ob == class_->radio_doc_indent) {
+               setEnabled(class_->choice_doc_skip, skip_used);
+               setEnabled(class_->input_doc_skip,
+                          skip_used && length_input);
+               setEnabled(class_->choice_default_skip_units,
+                          skip_used && length_input);
+               // Default unit choice is cm if metric, inches if US paper.
+               // If papersize is default, check the lyxrc-settings
+               int const paperchoice = fl_get_choice(paper_->choice_papersize);
+               bool const metric = (paperchoice == 1 && lyxrc.default_papersize > 3)
+                       || paperchoice == 2 || paperchoice > 5;
+               int const default_unit = metric ? 8 : 9;
+               if (strip(fl_get_input(class_->input_doc_skip)).empty())
+                       fl_set_choice(class_->choice_default_skip_units,
+                                     default_unit);
+       }
+
        if (ob == options_->check_use_natbib) {
                setEnabled(options_->choice_citation_format,
                           fl_get_button(options_->check_use_natbib));
        }
 
        if (ob == dialog_->button_save_defaults) {
-               lv_->getLyXFunc()->dispatch(LFUN_LAYOUT_SAVE_DEFAULT);
+               BufferParams params;
+               class_apply(params);
+               paper_apply(params);
+               language_apply(params);
+               options_apply(params);
+               bullets_apply(params);
+               saveParamsAsDefault(params);
        }
 
        if (ob == dialog_->button_reset_defaults) {
@@ -416,21 +467,81 @@ bool FormDocument::input( FL_OBJECT * ob, long data )
                BufferParams::PACKAGE_NONE + 1);
 
        if (ob == paper_->choice_papersize) {
-               if (fl_get_choice(paper_->choice_papersize) == 2)
+               int const paperchoice = fl_get_choice(paper_->choice_papersize);
+               bool const defsize = paperchoice == 1;
+               bool const custom = paperchoice == 2;
+               bool const a3size = paperchoice == 6;
+               bool const b3size = paperchoice == 9;
+               bool const b4size = paperchoice == 10;
+
+               if (custom)
                        fl_set_button(paper_->radio_portrait, 1);
-               bool const custom =
-                       fl_get_choice(paper_->choice_papersize) == 2;
+
+               bool const use_geom = (custom || a3size || b3size || b4size);
+
+               fl_set_button(paper_->check_use_geometry, int(use_geom));
+
+               setEnabled(paper_->input_top_margin,    use_geom);
+               setEnabled(paper_->input_bottom_margin, use_geom);
+               setEnabled(paper_->input_inner_margin,  use_geom);
+               setEnabled(paper_->input_outer_margin,  use_geom);
+               setEnabled(paper_->input_head_height,   use_geom);
+               setEnabled(paper_->input_head_sep,      use_geom);
+               setEnabled(paper_->input_foot_skip,     use_geom);
+               setEnabled(paper_->choice_top_margin_units,    use_geom);
+               setEnabled(paper_->choice_bottom_margin_units, use_geom);
+               setEnabled(paper_->choice_inner_margin_units,  use_geom);
+               setEnabled(paper_->choice_outer_margin_units,  use_geom);
+               setEnabled(paper_->choice_head_height_units,   use_geom);
+               setEnabled(paper_->choice_head_sep_units,      use_geom);
+               setEnabled(paper_->choice_foot_skip_units,     use_geom);
+               setEnabled(paper_->choice_custom_width_units,  use_geom);
+               setEnabled(paper_->choice_custom_height_units, use_geom);
+
                setEnabled(paper_->input_custom_width,  custom);
                setEnabled(paper_->input_custom_height, custom);
                setEnabled(paper_->choice_custom_width_units,  custom);
                setEnabled(paper_->choice_custom_height_units, custom);
                setEnabled(paper_->radio_portrait,  !custom);
                setEnabled(paper_->radio_landscape, !custom);
+
+               // Default unit choice is cm if metric, inches if US paper.
+               // If papersize is default, use the lyxrc-settings
+               bool const metric = (defsize && lyxrc.default_papersize > 3)
+                       || paperchoice == 2 || paperchoice > 5;
+               int const default_unit = metric ? 8 : 9;
+               if (strip(fl_get_input(paper_->input_custom_width)).empty())
+               fl_set_choice(paper_->choice_custom_width_units,
+                             default_unit);
+               if (strip(fl_get_input(paper_->input_custom_height)).empty())
+                       fl_set_choice(paper_->choice_custom_height_units,
+                                     default_unit);
+               if (strip(fl_get_input(paper_->input_top_margin)).empty())
+                       fl_set_choice(paper_->choice_top_margin_units,
+                                     default_unit);
+               if (strip(fl_get_input(paper_->input_bottom_margin)).empty())
+                       fl_set_choice(paper_->choice_bottom_margin_units,
+                                     default_unit);
+               if (strip(fl_get_input(paper_->input_inner_margin)).empty())
+                       fl_set_choice(paper_->choice_inner_margin_units,
+                                     default_unit);
+               if (strip(fl_get_input(paper_->input_outer_margin)).empty())
+                       fl_set_choice(paper_->choice_outer_margin_units,
+                                     default_unit);
+               if (strip(fl_get_input(paper_->input_head_height)).empty())
+                       fl_set_choice(paper_->choice_head_height_units,
+                                     default_unit);
+               if (strip(fl_get_input(paper_->input_head_sep)).empty())
+                       fl_set_choice(paper_->choice_head_sep_units,
+                                     default_unit);
+               if (strip(fl_get_input(paper_->input_foot_skip)).empty())
+                       fl_set_choice(paper_->choice_foot_skip_units,
+                                     default_unit);
        }
 
-       if (ob == paper_->choice_papersize
-           || paper_->radio_portrait
-           || paper_->radio_landscape) {
+       if (ob == paper_->choice_papersize ||
+           ob == paper_->radio_portrait ||
+           ob == paper_->radio_landscape) {
 
                setEnabled(paper_->choice_paperpackage,
                           //either default papersize (preferences)
@@ -447,15 +558,15 @@ bool FormDocument::input( FL_OBJECT * ob, long data )
 
                        setEnabled(paper_->input_top_margin,    false);
                        setEnabled(paper_->input_bottom_margin, false);
-                       setEnabled(paper_->input_left_margin,   false);
-                       setEnabled(paper_->input_right_margin,  false);
+                       setEnabled(paper_->input_inner_margin,  false);
+                       setEnabled(paper_->input_outer_margin,  false);
                        setEnabled(paper_->input_head_height,   false);
                        setEnabled(paper_->input_head_sep,      false);
                        setEnabled(paper_->input_foot_skip,     false);
                        setEnabled(paper_->choice_top_margin_units,    false);
                        setEnabled(paper_->choice_bottom_margin_units, false);
-                       setEnabled(paper_->choice_left_margin_units,   false);
-                       setEnabled(paper_->choice_right_margin_units,  false);
+                       setEnabled(paper_->choice_inner_margin_units,  false);
+                       setEnabled(paper_->choice_outer_margin_units,  false);
                        setEnabled(paper_->choice_head_height_units,   false);
                        setEnabled(paper_->choice_head_sep_units,      false);
                        setEnabled(paper_->choice_foot_skip_units,     false);
@@ -464,31 +575,31 @@ bool FormDocument::input( FL_OBJECT * ob, long data )
 
        if (ob == paper_->check_use_geometry) {
                //don't allow switching geometry off in custom papersize mode
-               if (fl_get_choice(paper_->choice_papersize) == 2)
+               //nor in A3, B3, and B4
+               int const choice = fl_get_choice(paper_->choice_papersize);
+               if (choice == 2 || choice == 6 || choice == 9 || choice == 10)
                        fl_set_button(paper_->check_use_geometry, 1);
+
                fl_set_choice(paper_->choice_paperpackage,
                              BufferParams::PACKAGE_NONE + 1);
 
                bool const use_geom = fl_get_button(paper_->check_use_geometry);
                setEnabled(paper_->input_top_margin,    use_geom);
                setEnabled(paper_->input_bottom_margin, use_geom);
-               setEnabled(paper_->input_left_margin,   use_geom);
-               setEnabled(paper_->input_right_margin,  use_geom);
+               setEnabled(paper_->input_inner_margin,  use_geom);
+               setEnabled(paper_->input_outer_margin,  use_geom);
                setEnabled(paper_->input_head_height,   use_geom);
                setEnabled(paper_->input_head_sep,      use_geom);
                setEnabled(paper_->input_foot_skip,     use_geom);
                setEnabled(paper_->choice_top_margin_units,    use_geom);
                setEnabled(paper_->choice_bottom_margin_units, use_geom);
-               setEnabled(paper_->choice_left_margin_units,   use_geom);
-               setEnabled(paper_->choice_right_margin_units,  use_geom);
+               setEnabled(paper_->choice_inner_margin_units,  use_geom);
+               setEnabled(paper_->choice_outer_margin_units,  use_geom);
                setEnabled(paper_->choice_head_height_units,   use_geom);
                setEnabled(paper_->choice_head_sep_units,      use_geom);
                setEnabled(paper_->choice_foot_skip_units,     use_geom);
        }
 
-       setEnabled(dialog_->button_reset_defaults,
-                  lv_->buffer()->params.hasClassDefaults());
-
        switch (data) {
        case INPUT:
        case CHECKCHOICECLASS:
@@ -513,10 +624,9 @@ void FormDocument::ComboInputCB(int, void * v, Combox * combox)
 }
 
 
-bool FormDocument::class_apply()
+bool FormDocument::class_apply(BufferParams &params)
 {
        bool redo = false;
-       BufferParams &params = lv_->buffer()->params;
 
        // If default skip is a "Length" but there's no text in the
        // input field, reset the kind to "Medskip", which is the default.
@@ -528,38 +638,8 @@ bool FormDocument::class_apply()
        params.fontsize = fl_get_choice_text(class_->choice_doc_fontsize);
        params.pagestyle = fl_get_choice_text(class_->choice_doc_pagestyle);
 
-       unsigned int const new_class = combo_doc_class->get() - 1;
+       params.textclass = combo_doc_class->get() - 1;
        
-       if (params.textclass != new_class) {
-               // try to load new_class
-               if (textclasslist.Load(new_class)) {
-                       // successfully loaded
-                       redo = true;
-                       setMinibuffer(lv_, _("Converting document to new document class..."));
-                       int ret = CutAndPaste::SwitchLayoutsBetweenClasses(
-                               params.textclass, new_class,
-                               lv_->buffer()->paragraph);
-                       if (ret) {
-                               string s;
-                               if (ret==1) {
-                                       s = _("One paragraph couldn't be converted");
-                               } else {
-                                       s += tostr(ret);
-                                       s += _(" paragraphs couldn't be converted");
-                               }
-                               WriteAlert(_("Conversion Errors!"),s,
-                                          _("into chosen document class"));
-                       }
-                       
-                       params.textclass = new_class;
-               } else {
-                       // problem changing class -- warn user and retain old style
-                       WriteAlert(_("Conversion Errors!"),
-                                  _("Errors loading new document class."),
-                                  _("Reverting to original document class."));
-                       combo_doc_class->select(int(params.textclass) + 1);
-               }
-       }
        BufferParams::PARSEP tmpsep = params.paragraph_separation;
        if (fl_get_button(class_->radio_doc_indent))
                params.paragraph_separation = BufferParams::PARSEP_INDENT;
@@ -580,11 +660,16 @@ bool FormDocument::class_apply()
            params.setDefSkip(VSpace(VSpace::BIGSKIP));
            break;
        case 4:
-               params.setDefSkip
-                       (VSpace(LyXGlueLength(fl_get_input(class_->input_doc_skip))));
+       {
+               string const length =
+                       getLengthFromWidgets(class_->input_doc_skip,
+                                            class_->choice_default_skip_units);
+
+               params.setDefSkip(VSpace(LyXGlueLength(length)));
                break;
-               // DocumentDefskipCB assures that this never happens
+       }
        default:
+               // DocumentDefskipCB assures that this never happens
                params.setDefSkip(VSpace(VSpace::MEDSKIP));
                break;
        }
@@ -629,17 +714,58 @@ bool FormDocument::class_apply()
 }
 
 
-void FormDocument::paper_apply()
+bool FormDocument::class_apply()
 {
-       BufferParams & params = lv_->buffer()->params;
+       BufferParams &params = lv_->buffer()->params;
+
+       unsigned int const old_class = params.textclass;
+
+       bool redo = class_apply(params);
 
+       if (params.textclass != old_class) {
+               // try to load new_class
+               if (textclasslist.Load(params.textclass)) {
+                       // successfully loaded
+                       redo = true;
+                       setMinibuffer(lv_, _("Converting document to new document class..."));
+                       int ret = CutAndPaste::SwitchLayoutsBetweenClasses(
+                               old_class, params.textclass,
+                               lv_->buffer()->paragraph,
+                               lv_->buffer()->params);
+                       if (ret) {
+                               string s;
+                               if (ret==1) {
+                                       s = _("One paragraph couldn't be converted");
+                               } else {
+                                       s += tostr(ret);
+                                       s += _(" paragraphs couldn't be converted");
+                               }
+                               Alert::alert(_("Conversion Errors!"),s,
+                                          _("into chosen document class"));
+                       }
+                       
+               } else {
+                       // problem changing class -- warn user and retain old style
+                       Alert::alert(_("Conversion Errors!"),
+                                  _("Errors loading new document class."),
+                                  _("Reverting to original document class."));
+                       combo_doc_class->select(int(old_class) + 1);
+               }
+       }
+       
+       return redo;
+}
+
+
+void FormDocument::paper_apply(BufferParams & params)
+{
        params.papersize2 = char(fl_get_choice(paper_->choice_papersize)-1);
 
        params.paperpackage =
                char(fl_get_choice(paper_->choice_paperpackage)-1);
 
        // set params.papersize from params.papersize2 and params.paperpackage
-       lv_->buffer()->setPaperStuff();
+       params.setPaperStuff();
 
        params.use_geometry = fl_get_button(paper_->check_use_geometry);
 
@@ -657,16 +783,16 @@ void FormDocument::paper_apply()
                                     paper_->choice_custom_height_units);
 
        params.leftmargin =
-               getLengthFromWidgets(paper_->input_left_margin,
-                                    paper_->choice_left_margin_units);
+               getLengthFromWidgets(paper_->input_inner_margin,
+                                    paper_->choice_inner_margin_units);
 
        params.topmargin =
                getLengthFromWidgets(paper_->input_top_margin,
                                     paper_->choice_top_margin_units);
 
        params.rightmargin =
-               getLengthFromWidgets(paper_->input_right_margin,
-                                    paper_->choice_right_margin_units);
+               getLengthFromWidgets(paper_->input_outer_margin,
+                                    paper_->choice_outer_margin_units);
 
        params.bottommargin =
                getLengthFromWidgets(paper_->input_bottom_margin,
@@ -686,9 +812,14 @@ void FormDocument::paper_apply()
 }
 
 
-bool FormDocument::language_apply()
+void FormDocument::paper_apply()
+{
+       paper_apply(lv_->buffer()->params);
+}
+
+
+bool FormDocument::language_apply(BufferParams & params)
 {
-       BufferParams & params = lv_->buffer()->params;
        InsetQuotes::quote_language lga = InsetQuotes::EnglishQ;
        bool redo = false;
 
@@ -725,12 +856,14 @@ bool FormDocument::language_apply()
                new_language = default_language;
 
        if (old_language != new_language
-           && old_language->RightToLeft() == new_language->RightToLeft()
+           && old_language->RightToLeft() == params.language->RightToLeft()
            && !lv_->buffer()->isMultiLingual())
-               lv_->buffer()->changeLanguage(old_language, new_language);
+               lv_->buffer()->changeLanguage(old_language, params.language);
+
        if (old_language != new_language) {
                redo = true;
        }
+
        params.language = new_language;
        params.inputenc = fl_get_choice_text(language_->choice_inputenc);
 
@@ -738,9 +871,14 @@ bool FormDocument::language_apply()
 }
 
 
-bool FormDocument::options_apply()
+bool FormDocument::language_apply()
+{
+       return language_apply(lv_->buffer()->params);
+}
+
+
+bool FormDocument::options_apply(BufferParams & params)
 {
-       BufferParams & params = lv_->buffer()->params;
        bool redo = false;
 
        params.graphicsDriver =
@@ -764,16 +902,28 @@ bool FormDocument::options_apply()
 }
 
 
-void FormDocument::bullets_apply()
+bool FormDocument::options_apply()
+{
+       return options_apply(lv_->buffer()->params);
+}
+
+
+void FormDocument::bullets_apply(BufferParams & params)
 {
        /* update the bullet settings */
-       BufferParams & param = lv_->buffer()->params;
+       BufferParams & buf_params = lv_->buffer()->params;
 
        // a little bit of loop unrolling
-       param.user_defined_bullets[0] = param.temp_bullets[0];
-       param.user_defined_bullets[1] = param.temp_bullets[1];
-       param.user_defined_bullets[2] = param.temp_bullets[2];
-       param.user_defined_bullets[3] = param.temp_bullets[3];
+       params.user_defined_bullets[0] = buf_params.temp_bullets[0];
+       params.user_defined_bullets[1] = buf_params.temp_bullets[1];
+       params.user_defined_bullets[2] = buf_params.temp_bullets[2];
+       params.user_defined_bullets[3] = buf_params.temp_bullets[3];
+}
+
+
+void FormDocument::bullets_apply()
+{
+       bullets_apply(lv_->buffer()->params);
 }
 
 
@@ -805,6 +955,11 @@ void FormDocument::class_update(BufferParams const & params)
                fl_set_button(class_->radio_doc_indent, 1);
        else
                fl_set_button(class_->radio_doc_skip, 1);
+
+       bool const input_length = fl_get_choice(class_->choice_doc_skip) == 4;
+       setEnabled(class_->choice_default_skip_units, input_length);
+       setEnabled(class_->input_doc_skip, input_length);
+
        switch (params.getDefSkip().kind()) {
        case VSpace::SMALLSKIP: 
                fl_set_choice (class_->choice_doc_skip, 1);
@@ -815,17 +970,27 @@ void FormDocument::class_update(BufferParams const & params)
        case VSpace::BIGSKIP: 
                fl_set_choice (class_->choice_doc_skip, 3);
                break;
-       case VSpace::LENGTH: 
-               fl_set_choice (class_->choice_doc_skip, 4);
-               fl_set_input (class_->input_doc_skip,
-                             params.getDefSkip().asLyXCommand().c_str());
+       case VSpace::LENGTH:
+       {
+               int const paperchoice = fl_get_choice(paper_->choice_papersize);
+               bool const metric = (paperchoice == 1 && lyxrc.default_papersize > 3)
+                       || paperchoice == 2 || paperchoice > 5;
+               string const default_unit = metric ? "cm" : "in";
+               string const length = params.getDefSkip().asLyXCommand();
+               updateWidgetsFromLengthString(class_->input_doc_skip,
+                                     class_->choice_default_skip_units,
+                                     length, default_unit);
                break;
+       }
        default:
                fl_set_choice (class_->choice_doc_skip, 2);
                break;
        }
        fl_set_button(class_->radio_doc_sides_one, 0);
        fl_set_button(class_->radio_doc_sides_two, 0);
+       setEnabled(class_->choice_doc_skip,
+                  fl_get_button(class_->radio_doc_skip));
+
        if (params.sides == LyXTextClass::TwoSides)
                fl_set_button(class_->radio_doc_sides_two, 1);
        else
@@ -836,7 +1001,10 @@ void FormDocument::class_update(BufferParams const & params)
                fl_set_button(class_->radio_doc_columns_two, 1);
        else
                fl_set_button(class_->radio_doc_columns_one, 1);
        fl_set_input(class_->input_doc_spacing, "");
+       setEnabled(class_->input_doc_spacing, false);
+
        switch (params.spacing.getSpace()) {
        case Spacing::Default: // nothing bad should happen with this
        case Spacing::Single:
@@ -857,6 +1025,7 @@ void FormDocument::class_update(BufferParams const & params)
                char sval[20];
                sprintf(sval,"%g",params.spacing.getValue()); 
                fl_set_input(class_->input_doc_spacing, sval);
+               setEnabled(class_->input_doc_spacing, true);
                break;
        }
        }
@@ -915,7 +1084,8 @@ void FormDocument::paper_update(BufferParams const & params)
        fl_set_choice(paper_->choice_paperpackage, params.paperpackage + 1);
        fl_set_button(paper_->check_use_geometry, params.use_geometry);
 
-       bool const useCustom = fl_get_choice(paper_->choice_papersize) == 2;
+       int const paperchoice = fl_get_choice(paper_->choice_papersize);
+       bool const useCustom = paperchoice == 2;
        bool const useGeom = fl_get_button(paper_->check_use_geometry);
 
        fl_set_button(paper_->radio_portrait, 0);
@@ -930,62 +1100,65 @@ void FormDocument::paper_update(BufferParams const & params)
        setEnabled(paper_->choice_paperpackage,
                   //either default papersize (preferences)
                   //or document papersize has to be A4
-                  (fl_get_choice(paper_->choice_papersize) == 7
-                   || fl_get_choice(paper_->choice_papersize) == 1
-                   && lyxrc.default_papersize == 5)
+                  (paperchoice == 7
+                   || paperchoice == 1 && lyxrc.default_papersize == 5)
                   && fl_get_button(paper_->radio_portrait));
 
+       // Default unit choice is cm if metric, inches if US paper.
+       bool const metric = (paperchoice == 1 && lyxrc.default_papersize > 3)
+                       || paperchoice == 2 || paperchoice > 5;
+       string const default_unit = metric ? "cm" : "in";
        updateWidgetsFromLengthString(paper_->input_custom_width,
-                                     paper_->choice_custom_width_units,
-                                     params.paperwidth);
+                             paper_->choice_custom_width_units,
+                             params.paperwidth, default_unit);
        setEnabled(paper_->input_custom_width, useCustom);
        setEnabled(paper_->choice_custom_width_units, useCustom);
 
        updateWidgetsFromLengthString(paper_->input_custom_height,
                                      paper_->choice_custom_height_units,
-                                     params.paperheight);
+                                     params.paperheight, default_unit);
        setEnabled(paper_->input_custom_height, useCustom);
        setEnabled(paper_->choice_custom_height_units, useCustom);
 
-       updateWidgetsFromLengthString(paper_->input_left_margin,
-                                     paper_->choice_left_margin_units,
-                                     params.leftmargin);
-       setEnabled(paper_->input_left_margin, useGeom);
-       setEnabled(paper_->choice_left_margin_units, useGeom);
+       updateWidgetsFromLengthString(paper_->input_inner_margin,
+                                     paper_->choice_inner_margin_units,
+                                     params.leftmargin, default_unit);
+       setEnabled(paper_->input_inner_margin, useGeom);
+       setEnabled(paper_->choice_inner_margin_units, useGeom);
 
        updateWidgetsFromLengthString(paper_->input_top_margin,
                                      paper_->choice_top_margin_units,
-                                     params.topmargin);
+                                     params.topmargin, default_unit);
        setEnabled(paper_->input_top_margin, useGeom);
        setEnabled(paper_->choice_top_margin_units, useGeom);
 
-       updateWidgetsFromLengthString(paper_->input_right_margin,
-                                     paper_->choice_right_margin_units,
-                                     params.rightmargin);
-       setEnabled(paper_->input_right_margin, useGeom);
-       setEnabled(paper_->choice_right_margin_units, useGeom);
+       updateWidgetsFromLengthString(paper_->input_outer_margin,
+                                     paper_->choice_outer_margin_units,
+                                     params.rightmargin, default_unit);
+       setEnabled(paper_->input_outer_margin, useGeom);
+       setEnabled(paper_->choice_outer_margin_units, useGeom);
 
        updateWidgetsFromLengthString(paper_->input_bottom_margin,
                                      paper_->choice_bottom_margin_units,
-                                     params.bottommargin);
+                                     params.bottommargin, default_unit);
        setEnabled(paper_->input_bottom_margin, useGeom);
        setEnabled(paper_->choice_bottom_margin_units, useGeom);
 
        updateWidgetsFromLengthString(paper_->input_head_height,
                                      paper_->choice_head_height_units,
-                                     params.headheight);
+                                     params.headheight, default_unit);
        setEnabled(paper_->input_head_height, useGeom);
        setEnabled(paper_->choice_head_height_units, useGeom);
 
        updateWidgetsFromLengthString(paper_->input_head_sep,
                                      paper_->choice_head_sep_units,
-                                     params.headsep);
+                                     params.headsep, default_unit);
        setEnabled(paper_->input_head_sep, useGeom);
        setEnabled(paper_->choice_head_sep_units, useGeom);
 
        updateWidgetsFromLengthString(paper_->input_foot_skip,
                                      paper_->choice_foot_skip_units,
-                                     params.footskip);
+                                     params.footskip, default_unit);
        setEnabled(paper_->input_foot_skip, useGeom);
        setEnabled(paper_->choice_foot_skip_units, useGeom);
 
@@ -1030,146 +1203,61 @@ void FormDocument::checkReadOnly()
 }
 
 
-void FormDocument::checkMarginValues()
-{
-//this is not needed after the recent redesign (JSpitzm)
-#if 0
-       bool const not_empty =
-               strlen(fl_get_input(paper_->input_top_margin)) ||
-               strlen(fl_get_input(paper_->input_bottom_margin)) ||
-               strlen(fl_get_input(paper_->input_left_margin)) ||
-               strlen(fl_get_input(paper_->input_right_margin)) ||
-               strlen(fl_get_input(paper_->input_head_height)) ||
-               strlen(fl_get_input(paper_->input_head_sep)) ||
-               strlen(fl_get_input(paper_->input_foot_skip)) ||
-               strlen(fl_get_input(paper_->input_custom_width)) ||
-               strlen(fl_get_input(paper_->input_custom_height));
-#endif
-}
-
-
-
 bool FormDocument::CheckDocumentInput(FL_OBJECT * ob, long)
 {
        string str;
        bool ok = true;
        char const * input;
 
-// this is not needed after the recent redesign (Angus)
-#if 0 
-       int val;
-       checkMarginValues();
-       if (ob == paper_->choice_papersize) {
-               val = fl_get_choice(paper_->choice_papersize)-1;
-               if (val == BufferParams::VM_PAPER_DEFAULT) {
-                       fl_set_button(paper_->check_use_geometry, 0);
-                       setEnabled(paper_->input_top_margin,
-                                  fl_get_button(paper_->check_use_geometry));
-                       setEnabled(paper_->input_bottom_margin,
-                                  fl_get_button(paper_->check_use_geometry));
-                       setEnabled(paper_->input_left_margin,
-                                  fl_get_button(paper_->check_use_geometry));
-                       setEnabled(paper_->input_right_margin,
-                                  fl_get_button(paper_->check_use_geometry));
-                       setEnabled(paper_->input_head_height,
-                                  fl_get_button(paper_->check_use_geometry));
-                       setEnabled(paper_->input_head_sep,
-                                  fl_get_button(paper_->check_use_geometry));
-                       setEnabled(paper_->input_foot_skip,
-                                  fl_get_button(paper_->check_use_geometry));
-                       checkMarginValues();
-               } else {
-                       if ((val != BufferParams::VM_PAPER_USLETTER) &&
-                           (val != BufferParams::VM_PAPER_USLEGAL) &&
-                           (val != BufferParams::VM_PAPER_USEXECUTIVE) &&
-                           (val != BufferParams::VM_PAPER_A4) &&
-                           (val != BufferParams::VM_PAPER_A5) &&
-                           (val != BufferParams::VM_PAPER_B5)) {
-                               fl_set_button(paper_->check_use_geometry, 1);
-                               setEnabled(paper_->input_top_margin,
-                                          fl_get_button(paper_->check_use_geometry));
-                               setEnabled(paper_->input_bottom_margin,
-                                          fl_get_button(paper_->check_use_geometry));
-                               setEnabled(paper_->input_left_margin,
-                                          fl_get_button(paper_->check_use_geometry));
-                               setEnabled(paper_->input_right_margin,
-                                          fl_get_button(paper_->check_use_geometry));
-                               setEnabled(paper_->input_head_height,
-                                          fl_get_button(paper_->check_use_geometry));
-                               setEnabled(paper_->input_head_sep,
-                                          fl_get_button(paper_->check_use_geometry));
-                               setEnabled(paper_->input_foot_skip,
-                                          fl_get_button(paper_->check_use_geometry));
-                       }
-                       fl_set_choice(paper_->choice_paperpackage,
-                                     BufferParams::PACKAGE_NONE + 1);
-               }
-       } else if (ob == paper_->choice_paperpackage) {
-               val = fl_get_choice(paper_->choice_paperpackage)-1;
-               if (val != BufferParams::PACKAGE_NONE) {
-                       fl_set_button(paper_->check_use_geometry, 0);
-                       setEnabled(paper_->input_top_margin,
-                                  fl_get_button(paper_->check_use_geometry));
-                       setEnabled(paper_->input_bottom_margin,
-                                  fl_get_button(paper_->check_use_geometry));
-                       setEnabled(paper_->input_left_margin,
-                                  fl_get_button(paper_->check_use_geometry));
-                       setEnabled(paper_->input_right_margin,
-                                  fl_get_button(paper_->check_use_geometry));
-                       setEnabled(paper_->input_head_height,
-                                  fl_get_button(paper_->check_use_geometry));
-                       setEnabled(paper_->input_head_sep,
-                                  fl_get_button(paper_->check_use_geometry));
-                       setEnabled(paper_->input_foot_skip,
-                                  fl_get_button(paper_->check_use_geometry));
-               }
-       } else if (ob == class_->input_doc_spacing) {
-               input = fl_get_input(class_->input_doc_spacing);
-               if (!*input) {
-                       fl_set_choice (class_->choice_doc_spacing, 1);
-               } else {
-                       fl_set_choice(class_->choice_doc_spacing, 4);
-               }
-       }
        // this has to be all out of if/elseif because it has to deactivate
        // the document buttons and so the whole stuff has to be tested again.
+       // disable OK/Apply if input is not valid
+       str = fl_get_input(class_->input_doc_skip);
+       ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
        str = fl_get_input(paper_->input_custom_width);
-       ok = ok && (str.empty() || isValidLength(str));
+       ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
        str = fl_get_input(paper_->input_custom_height);
-       ok = ok && (str.empty() || isValidLength(str));
-       str = fl_get_input(paper_->input_left_margin);
-       ok = ok && (str.empty() || isValidLength(str));
-       str = fl_get_input(paper_->input_right_margin);
-       ok = ok && (str.empty() || isValidLength(str));
+       ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
+       str = fl_get_input(paper_->input_outer_margin);
+       ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
+       str = fl_get_input(paper_->input_inner_margin);
+       ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
        str = fl_get_input(paper_->input_top_margin);
-       ok = ok && (str.empty() || isValidLength(str));
+       ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
        str = fl_get_input(paper_->input_bottom_margin);
-       ok = ok && (str.empty() || isValidLength(str));
+       ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
        str = fl_get_input(paper_->input_head_height);
-       ok = ok && (str.empty() || isValidLength(str));
+       ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
        str = fl_get_input(paper_->input_head_sep);
-       ok = ok && (str.empty() || isValidLength(str));
+       ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
        str = fl_get_input(paper_->input_foot_skip);
-       ok = ok && (str.empty() || isValidLength(str));
-#endif
+       ok = ok && (str.empty() || isValidLength(str) || isStrDbl(str));
+
+       //display warning if input is not valid
+       if (ob == class_->input_doc_skip
+                       || ob == paper_->input_custom_width
+                       || ob == paper_->input_custom_height
+                       || ob == paper_->input_outer_margin
+                       || ob == paper_->input_inner_margin
+                       || ob == paper_->input_top_margin
+                       || ob == paper_->input_bottom_margin
+                       || ob == paper_->input_head_height
+                       || ob == paper_->input_head_sep
+                       || ob == paper_->input_foot_skip) {
+               if (!ok) {
+                       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;
+               }
+       }
 
        // "Synchronize" the choice and the input field, so that it
        // is impossible to commit senseless data.
        input = fl_get_input (class_->input_doc_skip);
-       if (ob == class_->input_doc_skip) {
-               if (!*input) {
-                       fl_set_choice (class_->choice_doc_skip, 2);
-               } else if (isValidGlueLength (input)) {
-                       fl_set_choice (class_->choice_doc_skip, 4);
-               } else {
-                       fl_set_choice(class_->choice_doc_skip, 4);
-                       ok = false;
-               }
-       } else {
-               if (*input && !isValidGlueLength(input))
-                       ok = false;
-       }
-
        if ((fl_get_choice(class_->choice_doc_skip) == 4) && !*input)
                ok = false;
        else if (fl_get_choice(class_->choice_doc_skip) != 4)
@@ -1178,7 +1266,7 @@ bool FormDocument::CheckDocumentInput(FL_OBJECT * ob, long)
        input = fl_get_input(class_->input_doc_spacing);
        if ((fl_get_choice(class_->choice_doc_spacing) == 4) && !*input)
                ok = false;
-       else  if (fl_get_choice(class_->choice_doc_spacing) != 4)
+       else if (fl_get_choice(class_->choice_doc_spacing) != 4)
                fl_set_input (class_->input_doc_spacing, "");
        return ok;
 }
@@ -1340,7 +1428,7 @@ void FormDocument::CheckChoiceClass(FL_OBJECT * ob, long)
                }
        } else {
                // unable to load new style
-               WriteAlert(_("Conversion Errors!"),
+               Alert::alert(_("Conversion Errors!"),
                           _("Unable to switch to new document class."),
                           _("Reverting to original document class."));
                combo_doc_class->select(int(lv_->buffer()->params.textclass) + 1);