3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
8 * Full author contact details are available in file CREDITS.
13 // Too hard to make concept checks work with this file
14 #ifdef _GLIBCXX_CONCEPT_CHECKS
15 #undef _GLIBCXX_CONCEPT_CHECKS
17 #ifdef _GLIBCPP_CONCEPT_CHECKS
18 #undef _GLIBCPP_CONCEPT_CHECKS
25 #include "controllers/ControlBox.h"
27 #include "insets/insetbox.h"
28 #include "lengthcommon.h"
29 #include "lyxrc.h" // to set the default length values
38 string defaultUnit("cm");
42 GBox::GBox(Dialog & parent)
43 : GViewCB<ControlBox, GViewGladeB>(parent, lyx::to_utf8(_("Box Settings")), false)
49 string const gladeName = findGladeFile("box");
50 xml_ = Gnome::Glade::Xml::create(gladeName);
52 Gtk::Button * closebutton;
53 xml_->get_widget("Close", closebutton);
54 setCancel(closebutton);
56 xml_->get_widget("Type", typecombo_);
57 bcview().addReadOnly(typecombo_);
58 xml_->get_widget("InnerBox", innerboxcombo_);
59 bcview().addReadOnly(innerboxcombo_);
60 xml_->get_widget("WidthUnits", widthunitscombo_);
61 bcview().addReadOnly(widthunitscombo_);
62 xml_->get_widget("HeightUnits", heightunitscombo_);
63 bcview().addReadOnly(heightunitscombo_);
64 xml_->get_widget("BoxVertical", boxvertcombo_);
65 bcview().addReadOnly(boxvertcombo_);
66 xml_->get_widget("ContentVertical", contentvertcombo_);
67 bcview().addReadOnly(contentvertcombo_);
68 xml_->get_widget("ContentHorizontal", contenthorzcombo_);
69 bcview().addReadOnly(contenthorzcombo_);
70 xml_->get_widget("Width", widthspin_);
71 bcview().addReadOnly(widthspin_);
72 xml_->get_widget("Height", heightspin_);
73 bcview().addReadOnly(heightspin_);
75 cols_.add(stringcol_);
77 // fill the box type choice
78 box_gui_tokens(ids_, gui_names_);
79 PopulateComboBox(typecombo_, gui_names_);
80 typecombo_->signal_changed().connect(
81 sigc::mem_fun(*this, &GBox::onTypeComboChanged));
83 // set up innerbox (populated in setInnerType)
84 innerboxstore_ = Gtk::ListStore::create(cols_);
85 innerboxcombo_->set_model(innerboxstore_);
86 Gtk::CellRendererText * cell = Gtk::manage(new Gtk::CellRendererText);
87 innerboxcombo_->pack_start(*cell, true);
88 innerboxcombo_->add_attribute(*cell, "text", 0);
90 innerboxcombo_->signal_changed().connect(
91 sigc::mem_fun(*this, &GBox::onInnerBoxComboChanged));
93 boxvertcombo_->signal_changed().connect(
94 sigc::mem_fun(*this, &GBox::onAlignChanged));
95 contenthorzcombo_->signal_changed().connect(
96 sigc::mem_fun(*this, &GBox::onAlignChanged));
97 contentvertcombo_->signal_changed().connect(
98 sigc::mem_fun(*this, &GBox::onAlignChanged));
100 heightunitscombo_->signal_changed().connect(
101 sigc::mem_fun(*this, &GBox::onHeightChanged));
102 widthunitscombo_->signal_changed().connect(
103 sigc::mem_fun(*this, &GBox::onWidthChanged));
105 heightspin_->signal_value_changed().connect(
106 sigc::mem_fun(*this, &GBox::onHeightChanged));
107 widthspin_->signal_value_changed().connect(
108 sigc::mem_fun(*this, &GBox::onWidthChanged));
111 widthunitsstore_ = Gtk::ListStore::create(cols_);
112 widthunitscombo_->set_model(widthunitsstore_);
113 cell = Gtk::manage(new Gtk::CellRendererText);
114 widthunitscombo_->pack_start(*cell, true);
115 widthunitscombo_->add_attribute(*cell, "text", 0);
116 //widthunitscombo_ is populated in setSpecial
118 box_gui_tokens_special_length(ids_spec_, gui_names_spec_);
119 vector<string> heightunits = buildLengthUnitList(true);
120 // Append special entries, skipping the first item "None"
121 heightunits.insert(heightunits.end(),
122 ++gui_names_spec_.begin(), gui_names_spec_.end());
124 PopulateComboBox(heightunitscombo_, heightunits);
128 void GBox::PopulateComboBox(Gtk::ComboBox * combo,
129 vector<string> const & strings
132 Glib::RefPtr<Gtk::ListStore> model = Gtk::ListStore::create(cols_);
133 vector<string>::const_iterator it = strings.begin();
134 vector<string>::const_iterator end = strings.end();
135 for(; it != end; ++it)
136 (*model->append())[stringcol_] = *it;
138 combo->set_model(model);
139 Gtk::CellRendererText * cell = Gtk::manage(new Gtk::CellRendererText);
140 combo->pack_start(*cell, true);
141 combo->add_attribute(*cell, "text", 0);
149 defaultUnit = getDefaultUnit();
151 char c = controller().params().pos;
152 boxvertcombo_->set_active(string("tcb").find(c, 0));
153 c = controller().params().inner_pos;
154 contentvertcombo_->set_active(string("tcbs").find(c, 0));
155 c = controller().params().hor_pos;
156 contenthorzcombo_->set_active(string("lcrs").find(c, 0));
158 string type(controller().params().type);
159 for (size_t i = 0; i < gui_names_.size(); ++i) {
161 typecombo_->set_active(i);
165 updateInnerBoxCombo();
168 bool ibox = controller().params().inner_box;
169 boxvertcombo_->set_sensitive(ibox);
170 contentvertcombo_->set_sensitive(ibox);
171 contenthorzcombo_->set_sensitive(!ibox);
174 widthspin_->get_adjustment()->set_value(controller().params().width.value());
175 unitsComboFromLength(widthunitscombo_, stringcol_,
176 controller().params().width, defaultUnit);
178 string const special(controller().params().special);
179 if (!special.empty() && special != "none") {
181 for (size_t i = 0; i < gui_names_spec_.size(); ++i) {
182 if (special == ids_spec_[i])
183 spc = gui_names_spec_[i];
186 < widthunitsstore_->children().size(); ++j) {
187 if (widthunitsstore_->children()[j][stringcol_] == spc)
188 widthunitscombo_->set_active(j);
192 heightspin_->get_adjustment()->set_value(controller().params().height.value());
193 unitsComboFromLength(heightunitscombo_, stringcol_,
194 controller().params().height, defaultUnit);
196 string const height_special(controller().params().height_special);
197 if (!height_special.empty() && height_special != "none") {
199 for (size_t i = 0; i < gui_names_spec_.size(); ++i) {
200 if (height_special == ids_spec_[i]) {
201 hspc = gui_names_spec_[i];
204 for (size_t j = 0; j < heightunitscombo_->get_model()->children().size(); ++j) {
205 if (heightunitscombo_->get_model()->children()[j][stringcol_] == hspc) {
206 heightunitscombo_->set_active(j);
211 heightspin_->set_sensitive(ibox);
212 heightunitscombo_->set_sensitive(ibox);
217 void GBox::setSpecial(bool ibox)
219 bool const oldlock = applylock_;
222 unsigned int const initselection = widthunitscombo_->get_active_row_number();
223 widthunitsstore_->clear();
224 vector<string> normalunits = buildLengthUnitList(true);
226 vector<string>::const_iterator it = normalunits.begin();
227 vector<string>::const_iterator end = normalunits.end();
228 for(; it != end; ++it)
229 (*widthunitsstore_->append())[stringcol_] = *it;
231 vector<string>::const_iterator it = normalunits.begin();
232 vector<string>::const_iterator end = normalunits.end();
233 for(; it != end; ++it)
234 (*widthunitsstore_->append())[stringcol_] = *it;
235 // Skip the first item "None"
236 it = ++gui_names_spec_.begin();
237 end = gui_names_spec_.end();
238 for(; it != end; ++it)
239 (*widthunitsstore_->append())[stringcol_] = *it;
242 size_t const store_size = widthunitsstore_->children().size();
243 if (initselection >= store_size) {
244 widthunitscombo_->set_active(0);
247 widthunitscombo_->set_active(initselection);
249 applylock_ = oldlock;
253 void GBox::updateInnerBoxCombo()
255 bool const oldlock = applylock_;
257 // with "frameless" boxes, inner box is mandatory (i.e. is the actual box)
258 // we have to remove "none" then and adjust the combo
262 if (!controller().params().inner_box)
265 if (controller().params().use_parbox)
268 bool frameless = (controller().params().type == "Frameless");
270 int const oldsize = innerboxstore_->children().size();
271 // Store the initial selection in 0,1,2 format
272 int oldselection = -1;
274 oldselection = innerboxcombo_->get_active_row_number() + 1;
275 else if (oldsize == 3)
276 oldselection = innerboxcombo_->get_active_row_number();
278 if (frameless && oldsize != 2) {
279 innerboxstore_->clear();
280 (*innerboxstore_->append())[stringcol_] = lyx::to_utf8(_("Parbox"));
281 (*innerboxstore_->append())[stringcol_] = lyx::to_utf8(_("Minipage"));
282 // Cope when the backend asks for no inner box in
286 innerboxcombo_->set_active(i);
289 innerboxcombo_->set_active(i - 1);
290 } else if (!frameless && oldsize != 3) {
291 innerboxstore_->clear();
292 (*innerboxstore_->append())[stringcol_] = lyx::to_utf8(_("None"));
293 (*innerboxstore_->append())[stringcol_] = lyx::to_utf8(_("Parbox"));
294 (*innerboxstore_->append())[stringcol_] = lyx::to_utf8(_("Minipage"));
295 innerboxcombo_->set_active(i);
297 // we're not changing the liststore, just selecting i
299 innerboxcombo_->set_active(i - 1);
301 innerboxcombo_->set_active(i);
304 // Update the width units list if we've changed inner box type
305 if (i != oldselection)
308 applylock_ = oldlock;
312 void GBox::onInnerBoxComboChanged()
317 controller().params().use_parbox =
318 (*innerboxcombo_->get_active())[stringcol_] == lyx::to_utf8(_("Parbox"));
320 bool const ibox = (*innerboxcombo_->get_active())[stringcol_] != lyx::to_utf8(_("None"));
321 controller().params().inner_box = ibox;
324 boxvertcombo_->set_sensitive(ibox);
325 contentvertcombo_->set_sensitive(ibox);
326 contenthorzcombo_->set_sensitive(!ibox);
327 heightspin_->set_sensitive(ibox);
328 heightunitscombo_->set_sensitive(ibox);
329 // wtf? form_->set_sensitive(ibox);
331 controller().dispatchParams();
335 void GBox::onTypeComboChanged()
337 int const index = typecombo_->get_active_row_number();
338 controller().params().type = ids_[index];
340 bool frameless = (index == 0);
342 boxvertcombo_->set_sensitive(true);
343 contentvertcombo_->set_sensitive(true);
344 contenthorzcombo_->set_sensitive(false);
345 heightspin_->set_sensitive(true);
346 heightunitscombo_->set_sensitive(true);
347 //wtf? form_->setSpecial(true);
349 //int itype = innerboxcombo_->get_active_row_number();
350 controller().dispatchParams();
352 updateInnerBoxCombo();
356 void GBox::onHeightChanged()
364 Glib::ustring special = (*heightunitscombo_->get_active())[stringcol_];
365 for (size_t j = 1; j < gui_names_spec_.size() ; ++j) {
366 if (gui_names_spec_[j] == special) {
371 controller().params().height_special = ids_spec_[i];
375 height = heightspin_->get_text();
376 // beware: bogosity! the unit is simply ignored in this case
379 Glib::ustring const heightunit =
380 (*heightunitscombo_->get_active())[stringcol_];
381 height = heightspin_->get_text() + heightunit;
384 controller().params().height = LyXLength(height);
385 controller().dispatchParams();
389 void GBox::onWidthChanged()
396 Glib::ustring special = (*widthunitscombo_->get_active())[stringcol_];
397 for (size_t j = 1; j < gui_names_spec_.size() ; ++j) {
398 if (gui_names_spec_[j] == special) {
403 controller().params().special = ids_spec_[i];
407 width = widthspin_->get_text();
408 // beware: bogosity! the unit is simply ignored in this case
411 Glib::ustring const widthunit =
412 (*widthunitscombo_->get_active())[stringcol_];
413 width = widthspin_->get_text() + widthunit;
416 controller().params().width = LyXLength(width);
417 controller().dispatchParams();
421 void GBox::onAlignChanged()
426 controller().params().pos =
427 "tcb"[boxvertcombo_->get_active_row_number()];
428 controller().params().inner_pos =
429 "tcbs"[contenthorzcombo_->get_active_row_number()];
430 controller().params().hor_pos =
431 "lcrs"[contentvertcombo_->get_active_row_number()];
433 controller().dispatchParams();
436 } // namespace frontend