On Wed, Oct 01, 2003 at 02:09:24PM +0000, Angus Leeming spake thusly:
 
> Martin Vermeer wrote:
> [A lot. You've been busy!]
> 
> >> This stuff belongs in the InsetBoxParams constructor.
> >> Index: src/insets/insetbox.C
> >> +InsetBox::InsetBox(BufferParams const & bp, string const & label)
> >> +       : InsetCollapsable(bp)
> >> +{
> >> +       params_.type = label;
> >> +       params_.inner_box = true;
> >> +       params_.use_parbox = false;
> >> +       params_.pos ='t';
> >> +       params_.hor_pos ='c';
> >> +       params_.inner_pos ='t';
> >> +       params_.width = LyXLength("100col%");
> >> +       params_.special = "none";
> >> +       params_.height = LyXLength("1in");
> >> +       params_.height_special = "totalheight"; // default is
> >> 1\\totalheight
> > 
> > OK, except type
> 
> What's wrong with 
>         InsetBox::Params::Params(string const & label);

Don't understand. 
 
> > See attached (and it still works!). Sorry for the added files
> > separately, this is my read-only CVS tree using gcc3.
> 
> Looking again...
> 
> why not move InsetBox::BoxType into the Params struct. That way you'll be 
> able to store a
>         BoxType type;
> variable in there rather than that string. Again, you could use a 
> translator between string and enum when reading/writing.

Hmmm, feel free in due time :-)
 
> In insetbox.C:
> Personally, I would use
> namespace {
> typedef Translator<string, InsetBox::BoxType> BoxTranslator;
> BoxTranslator const & boxtranslator();
> BoxTranslator const & boxtranslator_loc();
> }
> ...
> end of file
> 
> namespace {
> BoxTranslator const init_boxtranslator() {
>         BoxTranslator translator("Boxed", InsetBox::Boxed);
>         translator.addPair("Frameless", Frameless);
>         translator.addPair("ovalbox", ovalbox);
>         translator.addPair("Ovalbox", Ovalbox);
>         translator.addPair("Shadowbox", Shadowbox);
>         translator.addPair("Doublebox", Doublebox);
> }
> BoxTranslator const init_boxtranslator_loc() {
>         BoxTranslator translator(_("Boxed"), InsetBox::Boxed);
>         translator.addPair(_("Frameless"), Frameless);
>         translator.addPair(_("ovalbox"), ovalbox);
>         translator.addPair(_("Ovalbox"), Ovalbox);
>         translator.addPair(_("Shadowbox"), Shadowbox);
>         translator.addPair(_("Doublebox"), Doublebox);
> }
> BoxTranslator const & boxtranslator() {
>         static BoxTranslator translator = init_boxtranslator();
>         return translator;
> }
> BoxTranslator const & boxtranslator_loc() {
>         static BoxTranslator translator = init_boxtranslator_loc();
>         return translator;
> }
> }

I took this as such minus the omissions :) and works fine. 
Yes 'static done' is ugly innit ;-)
 
> Change this:
> InsetBoxParams::InsetBoxParams()
> {
>         inner_box = true;
>         use_parbox = false;
>         pos ='t';
>         hor_pos ='c';
>         inner_pos ='t';
>         width = LyXLength("100col%");
>         special = "none";
>         height = LyXLength("1in");
>         height_special = "totalheight"; // default is 1\\totalheight
> }
> to this:
> InsetBoxParams::InsetBoxParams()
>         : inner_box(true),
>           use_parbox(false),
>           pos('t'),
>           hor_pos('c'),
>           inner_pos('t'),
>           width(LyXLength("100col%")),
>           special("none"),
>           height(LyXLength("1in")),
>           height_special("totalheight") // default is 1\\totalheight
> {}

Done.
 
> You must be sick to the back teeth of my suggestions ;-)

Yes. That's why I'll leave a little for you ;-)
 
> -- 
> Angus
> 

Attached modified files including André's simplifications.

Checking this in will be a major operation... my r/w cvs tree doesn't
compile but my compiling tree is readonly...

- Martin

// -*- C++ -*-
/**
 * \file insetbox.h
 * This file is part of LyX, the document processor.
 * Licence details can be found in the file COPYING.
 *
 * \author Angus Leeming
 * \author Martin Vermeer
 *
 * Full author contact details are available in file CREDITS.
 */

#ifndef INSETBOX_H
#define INSETBOX_H


#include "insetcollapsable.h"
#include "lyxlength.h"
#include "support/translator.h"


struct InsetBoxParams {
        ///
        InsetBoxParams();
        ///     
        void write(std::ostream & os) const;
        ///
        void read(LyXLex & lex);
        ///
        string type;
        /// Use a parbox (true) or minipage (false)
        bool use_parbox;
        /// Do we have an inner parbox or minipage to format paragraphs to
        /// columnwidth?
        bool inner_box;
        ///
        LyXLength width;
        /// "special" widths, see usrguide.dvi §3.5
        string special;
        ///
        char pos;
        ///
        char hor_pos;
        ///
        char inner_pos;
        ///
        LyXLength height;
        ///
        string height_special;
};


/** The fbox/fancybox inset

*/
class InsetBox : public InsetCollapsable {
public:
        ///
        InsetBox(BufferParams const &, string const &);
        /// Copy constructor
        InsetBox(InsetBox const &);
        ///
        ~InsetBox();
        ///
        virtual std::auto_ptr<InsetBase> clone() const;
        ///
        string const editMessage() const;
        ///
        InsetOld::Code lyxCode() const { return InsetOld::BOX_CODE; }
        ///
        void write(Buffer const &, std::ostream &) const;
        ///
        void read(Buffer const & buf, LyXLex & lex);
        ///
        void setButtonLabel();
        ///
        dispatch_result InsetBox::localDispatch(FuncRequest const &);
        ///
        void metrics(MetricsInfo &, Dimension &) const;
        /// show the Box dialog
        bool showInsetDialog(BufferView * bv) const;
        ///
        int latex(Buffer const &, std::ostream &,
                        LatexRunParams const &) const;
        ///
        int linuxdoc(Buffer const &, std::ostream &) const;
        ///
        int docbook(Buffer const &, std::ostream &, bool) const;
        ///
        int ascii(Buffer const &, std::ostream &, int) const;
        ///
        void validate(LaTeXFeatures &) const;
        ///
        InsetBoxParams const & params() const { return params_; }
        ///     
        enum BoxType {
                Frameless,
                Boxed,
                ovalbox,
                Ovalbox,
                Shadowbox,
                Doublebox
        };

private:
        friend class InsetBoxParams;

        /// used by the constructors
        void init();
        ///
        InsetBoxParams params_;
};


namespace {

typedef Translator<string, InsetBox::BoxType> BoxTranslator;
BoxTranslator const & boxtranslator();
BoxTranslator const & boxtranslator_loc();

} // anon


#include "mailinset.h"

class InsetBoxMailer : public MailInset {
public:
        ///
        InsetBoxMailer(InsetBox & inset);
        ///
        virtual InsetBase & inset() const { return inset_; }
        ///
        virtual string const & name() const { return name_; }
        ///
        virtual string const inset2string(Buffer const &) const;
        ///
        static string const params2string(InsetBoxParams const &);
        ///
        static void string2params(string const &, InsetBoxParams &);

private:
        ///
        static string const name_;
        ///
        InsetBox & inset_;
};

#endif // INSET_BOX_H
/**
 * \file insetbox.C
 * This file is part of LyX, the document processor.
 * Licence details can be found in the file COPYING.
 *
 * \author Angus Leeming
 * \author Martin Vermeer
 * \author Jürgen Spitzmüller
 *
 * Full author contact details are available in file CREDITS.
 */

#include <config.h>

#include "insetbox.h"
#include "debug.h"

#include "BufferView.h"
#include "funcrequest.h"
#include "gettext.h"
#include "LaTeXFeatures.h"
#include "LColor.h"
#include "lyxlex.h"
#include "metricsinfo.h"
#include "paragraph.h"

#include "support/std_sstream.h"

using std::auto_ptr;
using std::istringstream;
using std::ostream;
using std::ostringstream;
using std::endl;


namespace {

BoxTranslator const init_boxtranslator() {
        BoxTranslator translator("Boxed", InsetBox::Boxed);
        translator.addPair("Frameless", InsetBox::Frameless);
        translator.addPair("ovalbox", InsetBox::ovalbox);
        translator.addPair("Ovalbox", InsetBox::Ovalbox);
        translator.addPair("Shadowbox", InsetBox::Shadowbox);
        translator.addPair("Doublebox",InsetBox::Doublebox);
        return translator;
}


BoxTranslator const init_boxtranslator_loc() {
        BoxTranslator translator(_("Boxed"), InsetBox::Boxed);
        translator.addPair(_("Frameless"), InsetBox::Frameless);
        translator.addPair(_("ovalbox"), InsetBox::ovalbox);
        translator.addPair(_("Ovalbox"), InsetBox::Ovalbox);
        translator.addPair(_("Shadowbox"), InsetBox::Shadowbox);
        translator.addPair(_("Doublebox"), InsetBox::Doublebox);
        return translator;
}


BoxTranslator const & boxtranslator() {
        static BoxTranslator translator = init_boxtranslator();
        return translator;
}


BoxTranslator const & boxtranslator_loc() {
        static BoxTranslator translator = init_boxtranslator_loc();
        return translator;
}

} // anon


void InsetBox::init()
{
        setInsetName("Box");
        setButtonLabel();
}


InsetBox::InsetBox(BufferParams const & bp, string const & label)
        : InsetCollapsable(bp)
{
        params_.type = label;
/*
        if (!done) {
                done = true;
                // Initialize only once:
                boxtranslator.addPair("Frameless", Frameless);
                boxTranslator.addPair("Boxed", Boxed);
                boxTranslator.addPair("ovalbox", ovalbox);
                boxTranslator.addPair("Ovalbox", Ovalbox);
                boxTranslator.addPair("Shadowbox", Shadowbox);
                boxTranslator.addPair("Doublebox", Doublebox);
                // Localizable strings:
                boxLocTranslator.addPair(_("Boxed"), Boxed);
                boxLocTranslator.addPair(_("ovalbox"), ovalbox);
                boxLocTranslator.addPair(_("Ovalbox"), Ovalbox);
                boxLocTranslator.addPair(_("Shadowbox"), Shadowbox);
                boxLocTranslator.addPair(_("Doublebox"), Doublebox);
        }
*/

        init();
}


InsetBox::InsetBox(InsetBox const & in)
        : InsetCollapsable(in), params_(in.params_)
{
        init();
}


InsetBox::~InsetBox()
{
        InsetBoxMailer mailer(*this);
        mailer.hideDialog();
}


auto_ptr<InsetBase> InsetBox::clone() const
{
        return auto_ptr<InsetBase>(new InsetBox(*this));
}


string const InsetBox::editMessage() const
{
        return _("Opened Box Inset");
}


void InsetBox::write(Buffer const & buf, ostream & os) const
{
        params_.write(os);
        InsetCollapsable::write(buf, os);
}


void InsetBox::read(Buffer const & buf, LyXLex & lex)
{
        params_.read(lex);
        InsetCollapsable::read(buf, lex);
        setButtonLabel();
}


void InsetBox::setButtonLabel()
{
        LyXFont font(LyXFont::ALL_SANE);
        font.decSize();
        font.decSize();

        BoxType btype = boxtranslator().find(params_.type);
        if (btype == Frameless) {
                if (params_.use_parbox)
                        setLabel(_("Parbox"));
                else
                        setLabel(_("Minipage"));
        } else
                setLabel(boxtranslator_loc().find(btype));

        font.setColor(LColor::foreground);
        setBackgroundColor(LColor::background);
        setLabelFont(font);
}


void InsetBox::metrics(MetricsInfo & mi, Dimension & dim) const
{
        InsetCollapsable::metrics(mi, dim);
        if (params_.inner_box)
                if (isOpen())
                        dim.wid = mi.base.textwidth;
        dim_ = dim;
}


bool InsetBox::showInsetDialog(BufferView * bv) const
{
        InsetBoxMailer(const_cast<InsetBox &>(*this)).showDialog(bv);
        return true;
}


dispatch_result InsetBox::localDispatch(FuncRequest const & cmd)
{
        BufferView * bv = cmd.view();

        switch (cmd.action) {

        case LFUN_INSET_MODIFY: {
                InsetBoxMailer::string2params(cmd.argument, params_);
                setButtonLabel();
                bv->updateInset(this);
                return DISPATCHED;
        }
        case LFUN_INSET_DIALOG_UPDATE:
                InsetBoxMailer(*this).updateDialog(bv);
                return DISPATCHED;

        case LFUN_MOUSE_RELEASE:
                if (cmd.button() == mouse_button::button3 && hitButton(cmd)) {
                        InsetBoxMailer(*this).showDialog(bv);
                        return DISPATCHED;
                }
                // fallthrough:

        default:
                return InsetCollapsable::localDispatch(cmd);
        }
}


int InsetBox::latex(Buffer const & buf, ostream & os,
                                LatexRunParams const & runparams) const
{
        BoxType btype = boxtranslator().find(params_.type);

        string width_string = params_.width.asLatexString();
        bool stdwidth(false);
        if (params_.inner_box &&
                        (width_string.find("1.0\\columnwidth") != string::npos
                        || width_string.find("1.0\\textwidth") != string::npos)) {
                stdwidth = true;
                switch (btype) {
                case Frameless:
                        break;
                case Boxed:
                        width_string += " - 2\\fboxsep - 2\\fboxrule";
                        break;
                case ovalbox:
                        width_string += " - 2\\fboxsep - 0.8pt";
                        break;
                case Ovalbox:
                        width_string += " - 2\\fboxsep - 1.6pt";
                        break;
                case Shadowbox:
                        // Shadow falls outside right margin... opinions?
                        width_string += " - 2\\fboxsep - 2\\fboxrule"/* 
"-\\shadowsize"*/;
                        break;
                case Doublebox:
                        width_string += " - 2\\fboxsep - 7.5\\fboxrule - 1.0pt";
                        break;
                }
        }
        
        int i = 0;
        os << "%\n";
        // Adapt to column/text width correctly also if paragraphs indented:
        if (stdwidth)
                os << "\\noindent";
        
        switch (btype) {
        case Frameless:
                break;
        case Boxed:
                os << "\\framebox";
                if (!params_.inner_box) {
                        os << "{\\makebox";
                        // Special widths, see usrguide §3.5
                        if (params_.special != "none") {
                                os << "[" << params_.width.value()
                                   << "\\" << params_.special << "]";
                        } else
                                os << "[" << width_string << "]";
                        if (params_.hor_pos != 'c')
                                os << "[" << params_.hor_pos << "]";
                }
                
                os << "{";
                break;
        case ovalbox:
                os << "\\ovalbox{";
                break;
        case Ovalbox:
                os << "\\Ovalbox{";
                break;
        case Shadowbox:
                os << "\\shadowbox{";
                break;
        case Doublebox:
                os << "\\doublebox{";
                break;
        }

        if (params_.inner_box) {
                if (params_.use_parbox)
                        os << "\\parbox";
                else
                        os << "\\begin{minipage}";

                os << "[" << params_.pos << "]";
                if (params_.height_special == "none") {
                        os << "[" << params_.height.asLatexString() << "]";
                } else {
                        // Special heights
                        os << "[" << params_.height.value()
                           << "\\" << params_.height_special << "]";
                }
                if (params_.inner_pos != params_.pos)
                        os << "[" << params_.inner_pos << "]";

                os << "{" << width_string << "}";

                if (params_.use_parbox)
                        os << "{";
                os << "%\n";
                i += 1;
        }

        i += inset.latex(buf, os, runparams);

        if (params_.inner_box) {
                if (params_.use_parbox)
                        os << "%\n}";
                else
                        os << "%\n\\end{minipage}";
        }
        
        switch (btype) {
        case Frameless:
                break;
        case Boxed:
                if (!params_.inner_box)
                        os << "}"; // for makebox
                os << "}";
                break;
        case ovalbox:
        case Ovalbox:
        case Doublebox:
        case Shadowbox:
                os << "}";
                break;
        }       
        os << "%\n";
        
        i += 3;

        return i;
}


int InsetBox::linuxdoc(Buffer const & buf, std::ostream & os) const
{
        return inset.linuxdoc(buf, os);
}


int InsetBox::docbook(Buffer const & buf, std::ostream & os, bool mixcont) const
{
        return inset.docbook(buf, os, mixcont);
}


int InsetBox::ascii(Buffer const & buf, std::ostream & os, int ll) const
{
        int i = 0;
        string const pt = params_.type;
        BoxType btype = boxtranslator().find(params_.type);
        switch (btype) {
                case Frameless:
                break;
                case Boxed:
                os << "[";
                break;
                case ovalbox:
                os << "(";
                break;
                case Ovalbox:
                os << "((";
                break;
                case Shadowbox:
                os << "[";
                break;
                case Doublebox:
                os << "[[";
                break;
        }

        i = inset.ascii(buf, os, ll);

        switch (btype) {
                case Frameless:
                break;
                case Boxed:
                os << "]";
                break;
                case ovalbox:
                os << ")";
                break;
                case Ovalbox:
                os << "))";
                break;
                case Shadowbox:
                os << "]/";
                break;
                case Doublebox:
                os << "]]";
                break;
        }

        return i;
}


void InsetBox::validate(LaTeXFeatures & features) const
{
        features.require("calc");
        BoxType btype = boxtranslator().find(params_.type);
        switch (btype) {
        case Frameless:
        case Boxed:
                break;
        case ovalbox:
        case Ovalbox:
        case Shadowbox:
        case Doublebox:
                features.require("fancybox");
                break;
        }
        inset.validate(features);
}


InsetBoxMailer::InsetBoxMailer(InsetBox & inset)
        : inset_(inset)
{
}


string const InsetBoxMailer::name_ = "box";


string const InsetBoxMailer::inset2string(Buffer const &) const
{
        return params2string(inset_.params());
}


string const InsetBoxMailer::params2string(InsetBoxParams const & params)
{
        ostringstream data;
        data << "box" << ' ';
        params.write(data);
        return data.str();
}


void InsetBoxMailer::string2params(string const & in,
        InsetBoxParams & params)
{
        params = InsetBoxParams();

        if (in.empty())
                return;

        istringstream data(in);
        LyXLex lex(0,0);
        lex.setStream(data);

        string token;
        lex.next();
        token = lex.getString();
        lex.next();

        params.read(lex);
}


InsetBoxParams::InsetBoxParams()
        : inner_box(true),
          use_parbox(false),
          pos('t'),
          hor_pos('c'),
          inner_pos('t'),
          width(LyXLength("100col%")),
          special("none"),
          height(LyXLength("1in")),
          height_special("totalheight") // default is 1\\totalheight
{}


void InsetBoxParams::write(ostream & os) const
{
        os << type << "\n";
        os << "position \"" << pos << "\"\n";
        os << "hor_pos \"" << hor_pos << "\"\n";
        os << "has_inner_box " << inner_box << "\n";
        os << "inner_pos \"" << inner_pos << "\"\n";
        os << "use_parbox " << use_parbox << "\n";
        os << "width \"" << width.asString() << "\"\n";
        os << "special \"" << special << "\"\n";
        os << "height \"" << height.asString() << "\"\n";
        os << "height_special \"" << height_special << "\"\n";
}


void InsetBoxParams::read(LyXLex & lex)
{
        if (lex.isOK()) {
                type = lex.getString();
        }
        string token;
        if (!lex.isOK())
                return;
        lex.next();
        token = lex.getString();
        if (token == "position") {
                lex.next();
                // The [0] is needed. We need the first and only char in
                // this string -- MV
                pos = lex.getString()[0];
        } else {
                lyxerr << "InsetBox::Read: Missing 'position'-tag!" << token << endl;
                lex.pushToken(token);
        }
        if (!lex.isOK())
                return;
        lex.next();
        token = lex.getString();
        if (token == "hor_pos") {
                lex.next();
                hor_pos = lex.getString()[0];
        } else {
                lyxerr << "InsetBox::Read: Missing 'hor_pos'-tag!" << token << endl;
                lex.pushToken(token);
        }
        if (!lex.isOK())
                return;
        lex.next();
        token = lex.getString();
        if (token == "has_inner_box") {
                lex.next();
                inner_box = lex.getInteger();
        } else {
                lyxerr << "InsetBox::Read: Missing 'has_inner_box'-tag!" << endl;
                lex.pushToken(token);
        }

        if (!lex.isOK())
                return;
        lex.next();
        token = lex.getString();
        if (token == "inner_pos") {
                lex.next();
                inner_pos = lex.getString()[0];
        } else {
                lyxerr << "InsetBox::Read: Missing 'inner_pos'-tag!"
                        << token << endl;
                lex.pushToken(token);
        }
        if (!lex.isOK())
                return;
        lex.next();
        token = lex.getString();
        if (token == "use_parbox") {
                lex.next();
                use_parbox = lex.getInteger();
        } else {
                lyxerr << "InsetBox::Read: Missing 'use_parbox'-tag!" << endl;
                lex.pushToken(token);
        }
        if (!lex.isOK())
                return;
        lex.next();
        token = lex.getString();
        if (token == "width") {
                lex.next();
                width = LyXLength(lex.getString());
        } else {
                lyxerr << "InsetBox::Read: Missing 'width'-tag!" << endl;
                lex.pushToken(token);
        }
        if (!lex.isOK())
                return;
        lex.next();
        token = lex.getString();
        if (token == "special") {
                lex.next();
                special = lex.getString();
        } else {
                lyxerr << "InsetBox::Read: Missing 'special'-tag!" << endl;
                lex.pushToken(token);
        }
        if (!lex.isOK())
                return;
        lex.next();
        token = lex.getString();
        if (token == "height") {
                lex.next();
                height = LyXLength(lex.getString());
        } else {
                lyxerr << "InsetBox::Read: Missing 'height'-tag!" << endl;
                lex.pushToken(token);
        }
        if (!lex.isOK())
                return;
        lex.next();
        token = lex.getString();
        if (token == "height_special") {
                lex.next();
                height_special = lex.getString();
        } else {
                lyxerr << "InsetBox::Read: Missing 'height_special'-tag!" << endl;
                lex.pushToken(token);
        }
}
/**
 * \file FormBox.C
 * This file is part of LyX, the document processor.
 * Licence details can be found in the file COPYING.
 *
 * \author Jürgen Vigna (Minipage stuff)
 * \author Martin Vermeer
 *
 * Full author contact details are available in file CREDITS.
 */

#include <config.h>

#include "FormBox.h"
#include "ControlBox.h"
#include "forms/form_box.h"
#include "controllers/ButtonPolicies.h"
#include "controllers/helper_funcs.h"
#include "support/lstrings.h"
#include "support/tostr.h"

#include "Tooltips.h"
#include "xforms_helpers.h"
#include "xformsBC.h"

#include "insets/insetbox.h"

#include "lyx_forms.h"
#include "debug.h"

#include <vector>

using lyx::support::getStringFromVector;
using lyx::support::isStrDbl;
using lyx::support::subst;


typedef FormController<ControlBox, FormView<FD_box> > base_class;

FormBox::FormBox(Dialog & parent)
        : base_class(parent, _("Box"))
{}


void FormBox::build()
{
        dialog_.reset(build_box(this));

        box_gui_tokens(ids_, gui_names_);

        for (unsigned int i = 0; i < gui_names_.size(); ++i) {
                fl_addto_choice(dialog_->choice_type, gui_names_[i].c_str());
        }

        string str = _("Frameless: No border\n"
                       "Boxed: Rectangular\n"
                       "ovalbox: Oval, thin border\n"
                       "Ovalbox: Oval, thick border\n"
                       "Shadowbox: Box casting shadow\n"
                       "Doublebox: Double line border");
        tooltips().init(dialog_->choice_type, str);

        bcview().addReadOnly(dialog_->check_inner_box);

        str = _("The inner box may be a parbox or a minipage,\n"
                "with appropriate arguments from this dialog.");
        tooltips().init(dialog_->check_inner_box, str);

        bcview().addReadOnly(dialog_->radio_parbox);
        bcview().addReadOnly(dialog_->radio_minipage);

        bcview().addReadOnly(dialog_->choice_pos);
        fl_addto_choice(dialog_->choice_pos, _("top").c_str());
        fl_addto_choice(dialog_->choice_pos, _("middle").c_str());
        fl_addto_choice(dialog_->choice_pos, _("bottom").c_str());

        bcview().addReadOnly(dialog_->choice_inner_pos);
        fl_addto_choice(dialog_->choice_inner_pos, _("top").c_str());
        fl_addto_choice(dialog_->choice_inner_pos, _("middle").c_str());
        fl_addto_choice(dialog_->choice_inner_pos, _("bottom").c_str());
        fl_addto_choice(dialog_->choice_inner_pos, _("stretch").c_str());

        bcview().addReadOnly(dialog_->choice_hor_pos);
        fl_addto_choice(dialog_->choice_hor_pos, _("left").c_str());
        fl_addto_choice(dialog_->choice_hor_pos, _("center").c_str());
        fl_addto_choice(dialog_->choice_hor_pos, _("right").c_str());
        fl_addto_choice(dialog_->choice_hor_pos, _("stretch").c_str());

        bcview().addReadOnly(dialog_->input_width);
        bcview().addReadOnly(dialog_->choice_width_unit);
        bcview().addReadOnly(dialog_->choice_special);

        box_gui_tokens_special_length(ids_spec_, gui_names_spec_);
        for (unsigned int i = 0; i < gui_names_spec_.size(); ++i) {
                fl_addto_choice(dialog_->choice_special, gui_names_spec_[i].c_str());
        }

        string choice = getStringFromVector(getLatexUnits(), "|");
        fl_addto_choice(dialog_->choice_width_unit, 
                subst(choice, "%", "%%").c_str());

        bcview().addReadOnly(dialog_->input_height);
        bcview().addReadOnly(dialog_->choice_height_unit);
        bcview().addReadOnly(dialog_->choice_height_special);
        for (unsigned int i = 0; i < gui_names_spec_.size(); ++i) {
                fl_addto_choice(dialog_->choice_height_special, 
                        gui_names_spec_[i].c_str());
        }

        choice = getStringFromVector(getLatexUnits(), "|");
        fl_addto_choice(dialog_->choice_height_unit, 
                subst(choice, "%", "%%").c_str());

        bcview().setOK(dialog_->button_ok);
        bcview().setApply(dialog_->button_apply);
        bcview().setCancel(dialog_->button_cancel);
}


void FormBox::update()
{
        string type(controller().params().type);
        for (unsigned int i = 0; i < gui_names_.size(); ++i) {
                if (type == ids_[i])
                        fl_set_choice_text(dialog_->choice_type, 
gui_names_[i].c_str());
                }

        fl_set_button(dialog_->check_inner_box, controller().params().inner_box);
        if (controller().params().type == "Frameless")
                setEnabled(dialog_->check_inner_box, false);

        char c = controller().params().pos;
        fl_set_choice(dialog_->choice_pos, string("tcb").find(c, 0) + 1);
        c = controller().params().inner_pos;
        fl_set_choice(dialog_->choice_inner_pos, string("tcbs").find(c, 0) + 1);
        c = controller().params().hor_pos;
        fl_set_choice(dialog_->choice_hor_pos, string("lcrs").find(c, 0) + 1);
        setEnabled(dialog_->choice_pos, controller().params().inner_box);
        setEnabled(dialog_->choice_inner_pos, controller().params().inner_box);
        setEnabled(dialog_->choice_hor_pos, !controller().params().inner_box);

        fl_set_button(dialog_->radio_parbox,    controller().params().use_parbox);
        fl_set_button(dialog_->radio_minipage, !controller().params().use_parbox);
        setEnabled(dialog_->radio_parbox, controller().params().inner_box);
        setEnabled(dialog_->radio_minipage, controller().params().inner_box);

        LyXLength len(controller().params().width);
        fl_set_input(dialog_->input_width, tostr(len.value()).c_str());
        fl_set_choice(dialog_->choice_width_unit, len.unit() + 1);
        string special(controller().params().special);
        for (unsigned int i = 0; i < gui_names_spec_.size(); ++i) {
                if (special == ids_spec_[i])
                        fl_set_choice_text(dialog_->choice_special, 
                                gui_names_spec_[i].c_str());
                }
        // Special width unit must be default for general units to be enabled
        if(controller().params().special != "none")
                setEnabled(dialog_->choice_width_unit, false);
        setEnabled(dialog_->choice_special, !controller().params().inner_box);

        LyXLength ht(controller().params().height);
        fl_set_input(dialog_->input_height, tostr(ht.value()).c_str());
        fl_set_choice(dialog_->choice_height_unit, ht.unit() + 1);
        string const height_special(controller().params().height_special);
        for (unsigned int i = 0; i < gui_names_spec_.size(); ++i) {
                if (height_special == ids_spec_[i])
                        fl_set_choice_text(dialog_->choice_height_special, 
                                gui_names_spec_[i].c_str());
                }
        setEnabled(dialog_->input_height, controller().params().inner_box);
        setEnabled(dialog_->choice_height_unit, controller().params().inner_box);
        setEnabled(dialog_->choice_height_special, controller().params().inner_box);
        // Same here
        if(height_special != "none")
                setEnabled(dialog_->choice_height_unit, false);
}


void FormBox::apply()
{
        int i = fl_get_choice(dialog_->choice_type);
        controller().params().type = ids_[i - 1];

        controller().params().inner_box = fl_get_button(dialog_->check_inner_box);
        controller().params().use_parbox = 
                fl_get_button(dialog_->radio_parbox);
        controller().params().width =
                LyXLength(getLengthFromWidgets(dialog_->input_width,
                dialog_->choice_width_unit));
        
        controller().params().pos =
                "tcb"[fl_get_choice(dialog_->choice_pos) - 1];
        controller().params().inner_pos =
                "tcbs"[fl_get_choice(dialog_->choice_inner_pos) - 1];
        controller().params().hor_pos =
                "lcrs"[fl_get_choice(dialog_->choice_hor_pos) - 1];
        
        i = fl_get_choice(dialog_->choice_special);     
        controller().params().special = ids_spec_[i - 1];
        
        controller().params().height =
                LyXLength(getLengthFromWidgets(dialog_->input_height,
                dialog_->choice_height_unit));
        i = fl_get_choice(dialog_->choice_height_special);      
        controller().params().height_special = ids_spec_[i - 1];
}

ButtonPolicy::SMInput FormBox::input(FL_OBJECT * ob, long)
{
        if (ob == dialog_->check_inner_box) {
                setEnabled(dialog_->choice_pos, 
                        fl_get_button(dialog_->check_inner_box));
                setEnabled(dialog_->radio_parbox, 
                        fl_get_button(dialog_->check_inner_box));
                setEnabled(dialog_->radio_minipage, 
                        fl_get_button(dialog_->check_inner_box));
                setEnabled(dialog_->choice_width_unit, true);
                setEnabled(dialog_->choice_special, 
                        !fl_get_button(dialog_->check_inner_box));
                setEnabled(dialog_->input_height,
                        fl_get_button(dialog_->check_inner_box));
                setEnabled(dialog_->choice_height_unit,
                        fl_get_button(dialog_->check_inner_box));
                setEnabled(dialog_->choice_height_special, 
                        fl_get_button(dialog_->check_inner_box));
                setEnabled(dialog_->choice_hor_pos,
                        !fl_get_button(dialog_->check_inner_box));
                setEnabled(dialog_->choice_inner_pos,
                        fl_get_button(dialog_->check_inner_box));

                // Reset to defaults to not confuse users:
                if (fl_get_button(dialog_->check_inner_box))
                        fl_set_choice(dialog_->choice_special, NONE);
                else
                        fl_set_choice(dialog_->choice_height_special, NONE);
        }

        if (ob == dialog_->choice_special || ob == dialog_->check_inner_box)
                setEnabled(dialog_->choice_width_unit, 
                        fl_get_choice(dialog_->choice_special) == NONE);
        if (ob == dialog_->choice_height_special || ob == dialog_->check_inner_box)
                if (fl_get_choice(dialog_->choice_height_special) != NONE)
                    setEnabled(dialog_->choice_height_unit, false);
                else
                    setEnabled(dialog_->choice_height_unit, 
                                fl_get_button(dialog_->check_inner_box));
        
        // An inner box (parbox, minipage) is mandatory if no outer box
        if (ob == dialog_->choice_type) {
                int i = fl_get_choice(dialog_->choice_type);
                if (ids_[i - 1] == "Frameless") {
                        setEnabled(dialog_->check_inner_box, false);
                        fl_set_button(dialog_->check_inner_box, true);
                } else {
                        setEnabled(dialog_->check_inner_box, true);
                }
        }
        // disallow senseless data, warnings if input is senseless
        if (ob == dialog_->input_width) {
                string const input = getString(dialog_->input_width);
                bool const invalid = !isValidLength(input) && !isStrDbl(input);
                if (invalid) {
                        postWarning(_("Invalid Length!"));
                        return ButtonPolicy::SMI_INVALID;
                } 
        }
        if (ob == dialog_->input_height) {
                string const input = getString(dialog_->input_height);
                bool const invalid = !isValidLength(input) && !isStrDbl(input);
                if (invalid) {
                        postWarning(_("Invalid Length!"));
                        return ButtonPolicy::SMI_INVALID;
                } 
        }
        if (ob == dialog_->button_defaults) {
                fl_set_button(dialog_->check_inner_box, true);  
                fl_set_button(dialog_->radio_parbox, false);
                fl_set_input(dialog_->input_width, "100");
                fl_set_choice(dialog_->choice_width_unit, LyXLength::PCW + 1);
                fl_set_choice(dialog_->choice_special, NONE);
                fl_set_input(dialog_->input_height, "1");
                fl_set_choice(dialog_->choice_height_special, TOTALHEIGHT);
        }
        
        return ButtonPolicy::SMI_VALID;
}

Attachment: pgp00000.pgp
Description: PGP signature

Reply via email to