]> git.lyx.org Git - features.git/blobdiff - src/frontends/xforms/FormDocument.C
The 'Branches' mega-patch.
[features.git] / src / frontends / xforms / FormDocument.C
index b3c60b7f1b556aedce799c8e6414bd342e79d676..1f3d0a4fb3bc3b7f4051541aacf2f7a825095564 100644 (file)
@@ -5,6 +5,8 @@
  *
  * \author Jürgen Vigna
  * \author Rob Lahaye
+ * \author Martin Vermeer
+ * \author Juergen Spitzmueller
  *
  * Full author contact details are available in file CREDITS
  */
 #include "xformsBC.h"
 #include "ButtonController.h"
 
+#include "FormColorpicker.h"
+#include "LColor.h"
+#include "Lsstream.h"
 #include "bmtable.h"
 #include "checkedwidgets.h"
+#include "Tooltips.h"
 #include "input_validators.h" // fl_unsigned_float_filter
 #include "xforms_helpers.h"
 
+#include "bufferparams.h"
 #include "CutAndPaste.h"
 #include "debug.h"
 #include "language.h"
 #include "lyxrc.h"
 #include "lyxtextclasslist.h"
 #include "tex-strings.h"
+#include "ColorHandler.h"
 
 #include "controllers/frnt_lang.h"
 #include "controllers/helper_funcs.h"
@@ -35,7 +43,6 @@
 #include "support/tostr.h"
 #include "support/lstrings.h" // contains_functor, getStringFromVector
 #include "support/filetools.h" // LibFileSearch
-#include "support/BoostFormat.h"
 
 #include "lyx_xpm.h"
 #include "lyx_forms.h"
 #include <boost/bind.hpp>
 
 #include <functional>
+#include <iomanip>
+
+using namespace lyx::support;
 
 using std::bind2nd;
 using std::vector;
+using std::endl;
+using std::setw;
+using std::setfill;
 
 
 namespace {
@@ -57,6 +70,7 @@ bool const scalableTabfolders = false;
 bool const scalableTabfolders = true;
 #endif
 
+
 } // namespace anon
 
 
@@ -139,13 +153,7 @@ void FormDocument::build()
                if (tit->isTeXClassAvailable()) {
                        fl_addto_combox(obj, tit->description().c_str());
                } else {
-                       string item =
-#if USE_BOOST_FORMAT
-                               STRCONV(boost::io::str(boost::format(_("Unavailable: %1$s"))
-                                       % tit->description()));
-#else
-                               _("Unavailable: ") + tit->description();
-#endif
+                       string item = bformat(_("Unavailable: %1$s"), tit->description());
                        fl_addto_combox(obj, item.c_str());
                }
        }
@@ -347,6 +355,46 @@ void FormDocument::build()
        fl_set_bmtable_pixmap_file(bullets_->bmtable_panel, 6, 6,
                                   bmtablefile.c_str());
 
+       picker_.reset(new FormColorpicker);
+       
+       // the document branches form
+       branch_.reset(build_document_branch(this));
+
+       fl_set_object_color(branch_->button_color,
+               GUI_COLOR_CHOICE, GUI_COLOR_CHOICE);
+       
+       bcview().addReadOnly(branch_->input_all_branches);
+       bcview().addReadOnly(branch_->button_add_branch);
+       bcview().addReadOnly(branch_->button_remove_branch);
+       bcview().addReadOnly(branch_->button_select);
+       bcview().addReadOnly(branch_->button_deselect);
+       bcview().addReadOnly(branch_->button_modify);
+       bcview().addReadOnly(branch_->browser_all_branches);
+
+       // set up the tooltips for branches form
+       string str = _("Enter the name of a new branch.");
+       tooltips().init(branch_->input_all_branches, str);
+       str = _("Add a new branch to the document.");
+       tooltips().init(branch_->button_add_branch, str);
+       str = _("Remove the selected branch from the document.");
+       tooltips().init(branch_->button_remove_branch, str);
+       str = _("Activate the selected branch for output.");
+       tooltips().init(branch_->button_select, str);
+       str = _("Deactivate the selected activated branch.");
+       tooltips().init(branch_->button_deselect, str);
+       str = _("Available branches for this document.");
+       tooltips().init(branch_->browser_all_branches, str);
+       str = _("Activated branches. Content will occur in the document\'s output");
+       tooltips().init(branch_->browser_selection, str);
+       str = _("Modify background color of branch inset");
+       tooltips().init(branch_->button_modify, str);
+       str = _("Background color of branch inset");
+       tooltips().init(branch_->button_color, str);
+
+       // Handle middle mouse paint:
+       setPrehandler(branch_->input_all_branches);
+       fl_set_input_return(branch_->input_all_branches, FL_RETURN_CHANGED);
+
        // Enable the tabfolder to be rescaled correctly.
        if (scalableTabfolders)
                fl_set_tabfolder_autofit(dialog_->tabfolder, FL_FIT);
@@ -370,6 +418,9 @@ void FormDocument::build()
                fl_deactivate_object(fbullet);
                fl_set_object_lcol(fbullet, FL_INACTIVE);
        }
+
+       fl_addto_tabfolder(dialog_->tabfolder,_("Branches").c_str(),
+                                    branch_->form);
 }
 
 
@@ -382,6 +433,7 @@ void FormDocument::apply()
        language_apply(params);
        options_apply(params);
        bullets_apply(params);
+       branch_apply(params);
 }
 
 
@@ -399,6 +451,7 @@ void FormDocument::update()
        language_update(params);
        options_update(params);
        bullets_update(params);
+       branch_update(params);
 }
 
 
@@ -449,7 +502,7 @@ ButtonPolicy::SMInput FormDocument::input(FL_OBJECT * ob, long)
                // 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 > BufferParams::PAPER_EXECUTIVEPAPER)
+               bool const metric = (paperchoice == 1 && lyxrc.default_papersize > PAPER_EXECUTIVEPAPER)
                        || paperchoice == 2 || paperchoice > 5;
                string const default_unit = metric ? "cm" : "in";
                if (getString(class_->input_skip).empty())
@@ -460,6 +513,15 @@ ButtonPolicy::SMInput FormDocument::input(FL_OBJECT * ob, long)
                setEnabled(options_->choice_citation_format,
                           fl_get_button(options_->check_use_natbib));
 
+       } else if (ob == branch_->browser_all_branches ||
+                       ob == branch_->browser_selection ||
+                       ob == branch_->button_add_branch ||
+                       ob == branch_->button_remove_branch ||
+                       ob == branch_->button_modify ||
+                       ob == branch_->button_select ||
+                       ob == branch_->button_deselect ||
+                       ob == branch_->button_deselect) {
+               branch_input(ob);
        } else if (ob == dialog_->button_save_defaults) {
                apply();
                controller().saveAsDefault();
@@ -472,7 +534,7 @@ ButtonPolicy::SMInput FormDocument::input(FL_OBJECT * ob, long)
 
        } else if (ob == paper_->radio_landscape) {
                fl_set_choice(paper_->choice_paperpackage,
-                             BufferParams::PACKAGE_NONE + 1);
+                             PACKAGE_NONE + 1);
 
        } else if (ob == paper_->choice_papersize) {
                int const paperchoice = fl_get_choice(paper_->choice_papersize);
@@ -515,7 +577,7 @@ ButtonPolicy::SMInput FormDocument::input(FL_OBJECT * ob, long)
 
                // 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 > BufferParams::PAPER_EXECUTIVEPAPER)
+               bool const metric = (defsize && lyxrc.default_papersize > PAPER_EXECUTIVEPAPER)
                        || paperchoice == 2 || paperchoice > 5;
                string const default_unit = metric ? "cm" : "in";
                if (getString(paper_->input_custom_width).empty())
@@ -573,7 +635,7 @@ ButtonPolicy::SMInput FormDocument::input(FL_OBJECT * ob, long)
                        fl_set_button(paper_->check_use_geometry, 1);
 
                fl_set_choice(paper_->choice_paperpackage,
-                             BufferParams::PACKAGE_NONE + 1);
+                             PACKAGE_NONE + 1);
 
                bool const use_geom = fl_get_button(paper_->check_use_geometry);
                setEnabled(paper_->input_top_margin,    use_geom);
@@ -597,11 +659,11 @@ ButtonPolicy::SMInput FormDocument::input(FL_OBJECT * ob, long)
                // either default papersize (preferences) or document
                // papersize has to be A4
                bool const enable = ( fl_get_choice(paper_->choice_papersize) == 1
-                                     && lyxrc.default_papersize == BufferParams::PAPER_A4PAPER )
+                                     && lyxrc.default_papersize == PAPER_A4PAPER )
                        || fl_get_choice(paper_->choice_papersize) == 7;
                if (!enable)
                        fl_set_choice(paper_->choice_paperpackage,
-                                     BufferParams::PACKAGE_NONE + 1);
+                                     PACKAGE_NONE + 1);
                setEnabled(paper_->choice_paperpackage,
                           enable && fl_get_button(paper_->radio_portrait));
        }
@@ -610,6 +672,139 @@ ButtonPolicy::SMInput FormDocument::input(FL_OBJECT * ob, long)
 }
 
 
+void FormDocument::branch_input(FL_OBJECT * ob)
+{
+       BufferParams & params = controller().params();
+       std::vector<string> vec;
+
+       if (ob == branch_->button_add_branch) {
+               string new_branch = fl_get_input(branch_->input_all_branches);
+               if (!new_branch.empty()) {
+                       params.branchlist.add(new_branch);
+                       fl_set_input(branch_->input_all_branches, "");
+                       // Update branch list
+                       string const all_branches = params.branchlist.allBranches();
+                       fl_clear_browser(branch_->browser_all_branches);
+                       vec = getVectorFromString(all_branches, "|");
+                       for (unsigned i = 0; i < vec.size(); ++i) {
+                               fl_addto_browser(branch_->browser_all_branches,
+                                                               vec[i].c_str());
+                       }
+                       LColor::color c = static_cast<LColor::color>(lcolor.size());
+                       lcolor.fill(c, new_branch, lcolor.getX11Name(LColor::background));
+               }
+
+       } else if (ob == branch_->button_remove_branch) {
+               unsigned i = fl_get_browser(branch_->browser_all_branches);
+               string const current_branch =
+                       fl_get_browser_line(branch_->browser_all_branches, i);
+               if (!current_branch.empty()) {
+                       params.branchlist.remove(current_branch);
+                       // Update branch list
+                       string const all_branches = params.branchlist.allBranches();
+                       fl_clear_browser(branch_->browser_all_branches);
+                       vec = getVectorFromString(all_branches, "|");
+                       for (unsigned i = 0; i < vec.size(); ++i) {
+                               fl_addto_browser(branch_->browser_all_branches,
+                                                               vec[i].c_str());
+                       }
+                       // Update selected-list...
+                       string const all_selected = params.branchlist.allSelected();
+                       fl_clear_browser(branch_->browser_selection);
+                       vec = getVectorFromString(all_selected, "|");
+                       for (unsigned i = 0; i < vec.size(); ++i) {
+                               fl_addto_browser(branch_->browser_selection, vec[i].c_str());
+                       }
+               }
+       } else if (ob == branch_->button_select) {
+               unsigned i = fl_get_browser(branch_->browser_all_branches);
+               string const current_branch =
+                       fl_get_browser_line(branch_->browser_all_branches, i);
+               if (!current_branch.empty()) {
+                       fl_clear_browser(branch_->browser_selection);
+                       params.branchlist.setSelected(current_branch, true);
+                       string const all_selected = params.branchlist.allSelected();
+                       vec = getVectorFromString(all_selected, "|");
+                       for (unsigned i = 0; i < vec.size(); ++i) {
+                               fl_addto_browser(branch_->browser_selection,
+                                                       vec[i].c_str());
+                       }
+               }
+       } else if (ob == branch_->button_deselect) {
+               unsigned i = fl_get_browser(branch_->browser_selection);
+               string const current_sel =
+                       fl_get_browser_line(branch_->browser_selection, i);
+               if (!current_sel.empty()) {
+                       fl_clear_browser(branch_->browser_selection);
+                       params.branchlist.setSelected(current_sel, false);
+                       string const all_selected = params.branchlist.allSelected();
+                       vec = getVectorFromString(all_selected, "|");
+                       for (unsigned i = 0; i < vec.size(); ++i) {
+                               fl_addto_browser(branch_->browser_selection,
+                                                       vec[i].c_str());
+                       }
+               }
+       } else if (ob == branch_->button_modify) {
+               unsigned i = fl_get_browser(branch_->browser_all_branches);
+               string const current_branch =
+                       fl_get_browser_line(branch_->browser_all_branches, i);
+               
+               RGBColor before;
+               string x11hexname = params.branchlist.getColor(current_branch);
+               if (x11hexname[0] == '#') {
+                       before = RGBColor(x11hexname);
+               } else{
+                       fl_getmcolor(FL_COL1, &before.r, &before.g, &before.b);
+               }
+
+               RGBColor col = picker_->requestColor(before);
+               if (before != col) {
+                       fl_mapcolor(GUI_COLOR_CHOICE, col.r, col.g, col.b);
+                       fl_redraw_object(branch_->button_color);
+                       // Figure out here how to stash the new colour into the
+                       // LyX colour database.
+
+                       x11hexname = X11hexname(col);
+
+                       // current_branch already in database
+                       LColor::color c = lcolor.getFromLyXName(current_branch);
+                       lcolor.setColor(current_branch, x11hexname);
+                       // Make sure that new colour is also displayed ;-)
+                       lyxColorHandler->getGCForeground(c);
+                       lyxColorHandler->updateColor(c);
+                       // what about system_lcolor?
+                       // Here set colour in BranchList:
+                       params.branchlist.setColor(current_branch, x11hexname);
+               }
+       } else if (ob == branch_->browser_all_branches) {
+               unsigned i = fl_get_browser(branch_->browser_all_branches);
+               string const current_branch =
+                       fl_get_browser_line(branch_->browser_all_branches, i);
+               // make button_color track selected branch:
+
+               RGBColor rgb;
+               string x11hexname = params.branchlist.getColor(current_branch);
+               if (x11hexname[0] == '#') {
+                       rgb = RGBColor(x11hexname);
+               } else {
+                       fl_getmcolor(FL_COL1, &rgb.r, &rgb.g, &rgb.b);
+               }
+               fl_mapcolor(GUI_COLOR_CHOICE, rgb.r, rgb.g, rgb.b);
+               fl_redraw_object(branch_->button_color);
+       }
+       setEnabled(branch_->button_select,
+               (fl_get_browser(branch_->browser_all_branches) > 0));
+       setEnabled(branch_->button_deselect,
+               (fl_get_browser(branch_->browser_selection) > 0));
+       setEnabled(branch_->button_remove_branch,
+               (fl_get_browser(branch_->browser_all_branches) > 0));
+       setEnabled(branch_->button_modify,
+               (fl_get_browser(branch_->browser_all_branches) > 0));
+
+       branchlist_ = params.branchlist;
+}
+
+
 bool FormDocument::class_apply(BufferParams &params)
 {
        bool redo = false;
@@ -674,19 +869,19 @@ bool FormDocument::class_apply(BufferParams &params)
        Spacing tmpSpacing = params.spacing;
        switch (fl_get_choice(class_->choice_spacing)) {
        case 1:
-               lyxerr[Debug::INFO] << "Spacing: SINGLE\n";
+               lyxerr[Debug::INFO] << "Spacing: SINGLE" << endl;
                params.spacing.set(Spacing::Single);
                break;
        case 2:
-               lyxerr[Debug::INFO] << "Spacing: ONEHALF\n";
+               lyxerr[Debug::INFO] << "Spacing: ONEHALF" << endl;
                params.spacing.set(Spacing::Onehalf);
                break;
        case 3:
-               lyxerr[Debug::INFO] << "Spacing: DOUBLE\n";
+               lyxerr[Debug::INFO] << "Spacing: DOUBLE" << endl;
                params.spacing.set(Spacing::Double);
                break;
        case 4:
-               lyxerr[Debug::INFO] << "Spacing: OTHER\n";
+               lyxerr[Debug::INFO] << "Spacing: OTHER" << endl;
                params.spacing.set(Spacing::Other,
                                   getString(class_->input_spacing));
                break;
@@ -702,10 +897,10 @@ bool FormDocument::class_apply(BufferParams &params)
 
 void FormDocument::paper_apply(BufferParams & params)
 {
-       params.papersize2 = BufferParams::VMARGIN_PAPER_TYPE(fl_get_choice(paper_->choice_papersize) - 1);
+       params.papersize2 = VMARGIN_PAPER_TYPE(fl_get_choice(paper_->choice_papersize) - 1);
 
        params.paperpackage =
-               BufferParams::PAPER_PACKAGES(fl_get_choice(paper_->choice_paperpackage) - 1);
+               PAPER_PACKAGES(fl_get_choice(paper_->choice_paperpackage) - 1);
 
        // set params.papersize from params.papersize2 and params.paperpackage
        params.setPaperStuff();
@@ -713,9 +908,9 @@ void FormDocument::paper_apply(BufferParams & params)
        params.use_geometry = fl_get_button(paper_->check_use_geometry);
 
        if (fl_get_button(paper_->radio_landscape))
-               params.orientation = BufferParams::ORIENTATION_LANDSCAPE;
+               params.orientation = ORIENTATION_LANDSCAPE;
        else
-               params.orientation = BufferParams::ORIENTATION_PORTRAIT;
+               params.orientation = ORIENTATION_PORTRAIT;
 
        params.paperwidth =
                getLengthFromWidgets(paper_->input_custom_width,
@@ -834,6 +1029,16 @@ void FormDocument::bullets_apply(BufferParams & params)
 }
 
 
+void FormDocument::branch_apply(BufferParams & params)
+{
+       BufferParams & prms = controller().params();
+       if (branchlist_.empty())
+               branchlist_ = prms.branchlist;
+       params.branchlist = branchlist_;
+       branchlist_.clear();
+}
+
+               
 void FormDocument::UpdateClassParams(BufferParams const & params)
 {
        // These are the params that have to be updated on any class change
@@ -895,7 +1100,7 @@ void FormDocument::class_update(BufferParams const & params)
        bool const length_input = pos == 4;
        if (length_input) {
                int const paperchoice = fl_get_choice(paper_->choice_papersize);
-               bool const metric = (paperchoice == 1 && lyxrc.default_papersize > BufferParams::PAPER_EXECUTIVEPAPER)
+               bool const metric = (paperchoice == 1 && lyxrc.default_papersize > PAPER_EXECUTIVEPAPER)
                        || paperchoice == 2 || paperchoice > 5;
                string const default_unit = metric ? "cm" : "in";
                string const length = params.getDefSkip().asLyXCommand();
@@ -1004,7 +1209,7 @@ void FormDocument::paper_update(BufferParams const & params)
        fl_set_button(paper_->radio_landscape, 0);
        setEnabled(paper_->radio_landscape, !useCustom);
 
-       if (params.orientation == BufferParams::ORIENTATION_LANDSCAPE)
+       if (params.orientation == ORIENTATION_LANDSCAPE)
                fl_set_button(paper_->radio_landscape, 1);
        else
                fl_set_button(paper_->radio_portrait, 1);
@@ -1012,11 +1217,11 @@ void FormDocument::paper_update(BufferParams const & params)
                   //either default papersize (preferences)
                   //or document papersize has to be A4
                   (paperchoice == 7
-                   || paperchoice == 1 && lyxrc.default_papersize == BufferParams::PAPER_A4PAPER)
+                   || paperchoice == 1 && lyxrc.default_papersize == PAPER_A4PAPER)
                   && 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 > BufferParams::PAPER_EXECUTIVEPAPER)
+       bool const metric = (paperchoice == 1 && lyxrc.default_papersize > PAPER_EXECUTIVEPAPER)
                || paperchoice == 2 || paperchoice > 5;
        string const default_unit = metric ? "cm" : "in";
        updateWidgetsFromLengthString(paper_->input_custom_width,
@@ -1098,6 +1303,56 @@ void FormDocument::bullets_update(BufferParams const & params)
 }
 
 
+void FormDocument::branch_update(BufferParams const & params)
+{
+       if (!branch_.get())
+               return;
+       
+       string const all_branches = params.branchlist.allBranches();
+       fl_clear_browser(branch_->browser_all_branches);
+       string current_branch("none");
+       
+       if (!all_branches.empty()) {
+               std::vector<string> vec = getVectorFromString(all_branches, "|");
+               for (unsigned i = 0; i < vec.size(); ++i) {
+                       fl_addto_browser(branch_->browser_all_branches, vec[i].c_str());
+               }
+               fl_select_browser_line(branch_->browser_all_branches, 1);
+               current_branch =
+                       fl_get_browser_line(branch_->browser_all_branches, 1);
+       }
+
+       // display proper selection...
+       string const all_selected = params.branchlist.allSelected();
+       fl_clear_browser(branch_->browser_selection);
+       if (!all_selected.empty()) {
+               std::vector<string> vec = getVectorFromString(all_selected, "|");
+               for (unsigned i = 0; i < vec.size(); ++i) {
+                       fl_addto_browser(branch_->browser_selection, vec[i].c_str());
+                       }
+       }
+       // display proper colour...
+       RGBColor rgb;
+       string x11hexname = params.branchlist.getColor(current_branch);
+       if (x11hexname[0] == '#') {
+               rgb = RGBColor(x11hexname);
+       } else {
+               fl_getmcolor(FL_COL1, &rgb.r, &rgb.g, &rgb.b);
+       }
+       fl_mapcolor(GUI_COLOR_CHOICE, rgb.r, rgb.g, rgb.b);
+       fl_redraw_object(branch_->button_color);
+
+       setEnabled(branch_->button_select,
+               (fl_get_browser(branch_->browser_all_branches) > 0));
+       setEnabled(branch_->button_deselect,
+               (fl_get_browser(branch_->browser_selection) > 0));
+       setEnabled(branch_->button_remove_branch,
+               (fl_get_browser(branch_->browser_all_branches) > 0));
+       setEnabled(branch_->button_modify,
+               (fl_get_browser(branch_->browser_all_branches) > 0));
+}
+
+
 void FormDocument::checkReadOnly()
 {
        if (bc().readOnly(controller().bufferIsReadonly())) {