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.
17 #include "controllers/ControlBox.h"
19 #include "insets/insetbox.h"
20 #include "lengthcommon.h"
21 #include "lyxrc.h" // to set the default length values
30 string defaultUnit("cm");
33 GBox::GBox(Dialog & parent)
34 : GViewCB<ControlBox, GViewGladeB>(parent, _("Box Settings"), false)
40 string const gladeName = findGladeFile("box");
41 xml_ = Gnome::Glade::Xml::create(gladeName);
43 Gtk::Button * closebutton;
44 xml_->get_widget("Close", closebutton);
45 setCancel(closebutton);
47 xml_->get_widget("Type", typecombo_);
48 bcview().addReadOnly(typecombo_);
49 xml_->get_widget("InnerBox", innerboxcombo_);
50 bcview().addReadOnly(innerboxcombo_);
51 xml_->get_widget("WidthUnits", widthunitscombo_);
52 bcview().addReadOnly(widthunitscombo_);
53 xml_->get_widget("HeightUnits", heightunitscombo_);
54 bcview().addReadOnly(heightunitscombo_);
55 xml_->get_widget("BoxVertical", boxvertcombo_);
56 bcview().addReadOnly(boxvertcombo_);
57 xml_->get_widget("ContentVertical", contentvertcombo_);
58 bcview().addReadOnly(contentvertcombo_);
59 xml_->get_widget("ContentHorizontal", contenthorzcombo_);
60 bcview().addReadOnly(contenthorzcombo_);
61 xml_->get_widget("Width", widthspin_);
62 bcview().addReadOnly(widthspin_);
63 xml_->get_widget("Height", heightspin_);
64 bcview().addReadOnly(heightspin_);
66 cols_.add(stringcol_);
68 // fill the box type choice
69 box_gui_tokens(ids_, gui_names_);
70 PopulateComboBox(typecombo_, gui_names_);
71 typecombo_->signal_changed().connect(
72 sigc::mem_fun(*this, &GBox::onTypeComboChanged));
74 // set up innerbox (populated in setInnerType)
75 innerboxstore_ = Gtk::ListStore::create(cols_);
76 innerboxcombo_->set_model(innerboxstore_);
77 Gtk::CellRendererText * cell = Gtk::manage(new Gtk::CellRendererText);
78 innerboxcombo_->pack_start(*cell, true);
79 innerboxcombo_->add_attribute(*cell, "text", 0);
81 innerboxcombo_->signal_changed().connect(
82 sigc::mem_fun(*this, &GBox::onInnerBoxComboChanged));
84 boxvertcombo_->signal_changed().connect(
85 sigc::mem_fun(*this, &GBox::onAlignChanged));
86 contenthorzcombo_->signal_changed().connect(
87 sigc::mem_fun(*this, &GBox::onAlignChanged));
88 contentvertcombo_->signal_changed().connect(
89 sigc::mem_fun(*this, &GBox::onAlignChanged));
91 heightunitscombo_->signal_changed().connect(
92 sigc::mem_fun(*this, &GBox::onHeightChanged));
93 widthunitscombo_->signal_changed().connect(
94 sigc::mem_fun(*this, &GBox::onWidthChanged));
96 heightspin_->signal_value_changed().connect(
97 sigc::mem_fun(*this, &GBox::onHeightChanged));
98 widthspin_->signal_value_changed().connect(
99 sigc::mem_fun(*this, &GBox::onWidthChanged));
102 widthunitsstore_ = Gtk::ListStore::create(cols_);
103 widthunitscombo_->set_model(widthunitsstore_);
104 cell = Gtk::manage(new Gtk::CellRendererText);
105 widthunitscombo_->pack_start(*cell, true);
106 widthunitscombo_->add_attribute(*cell, "text", 0);
107 //widthunitscombo_ is populated in setSpecial
109 box_gui_tokens_special_length(ids_spec_, gui_names_spec_);
110 vector<string> heightunits = buildLengthUnitList();
111 // Append special entries, skipping the first item "None"
112 heightunits.insert(heightunits.end(),
113 ++gui_names_spec_.begin(), gui_names_spec_.end());
115 PopulateComboBox(heightunitscombo_, heightunits);
119 void GBox::PopulateComboBox(Gtk::ComboBox * combo,
120 vector<string> const & strings
123 Glib::RefPtr<Gtk::ListStore> model = Gtk::ListStore::create(cols_);
124 vector<string>::const_iterator it = strings.begin();
125 vector<string>::const_iterator end = strings.end();
126 for(; it != end; ++it)
127 (*model->append())[stringcol_] = *it;
129 combo->set_model(model);
130 Gtk::CellRendererText * cell = Gtk::manage(new Gtk::CellRendererText);
131 combo->pack_start(*cell, true);
132 combo->add_attribute(*cell, "text", 0);
140 defaultUnit = getDefaultUnit();
142 char c = controller().params().pos;
143 boxvertcombo_->set_active(string("tcb").find(c, 0));
144 c = controller().params().inner_pos;
145 contentvertcombo_->set_active(string("tcbs").find(c, 0));
146 c = controller().params().hor_pos;
147 contenthorzcombo_->set_active(string("lcrs").find(c, 0));
149 string type(controller().params().type);
150 for (unsigned int i = 0; i < gui_names_.size(); ++i) {
152 typecombo_->set_active(i);
156 updateInnerBoxCombo();
159 bool ibox = controller().params().inner_box;
160 boxvertcombo_->set_sensitive(ibox);
161 contentvertcombo_->set_sensitive(ibox);
162 contenthorzcombo_->set_sensitive(!ibox);
165 widthspin_->get_adjustment()->set_value(controller().params().width.value());
166 unitsComboFromLength(widthunitscombo_, stringcol_,
167 controller().params().width, defaultUnit);
169 string const special(controller().params().special);
170 if (!special.empty() && special != "none") {
172 for (unsigned int i = 0; i < gui_names_spec_.size(); ++i) {
173 if (special == ids_spec_[i])
174 spc = gui_names_spec_[i];
176 for (int j = 0; j < widthunitsstore_->children().size(); ++j) {
177 if (widthunitsstore_->children()[j][stringcol_] == spc)
178 widthunitscombo_->set_active(j);
182 heightspin_->get_adjustment()->set_value(controller().params().height.value());
183 unitsComboFromLength(heightunitscombo_, stringcol_,
184 controller().params().height, defaultUnit);
186 string const height_special(controller().params().height_special);
187 if (!height_special.empty() && height_special != "none") {
189 for (unsigned int i = 0; i < gui_names_spec_.size(); ++i) {
190 if (height_special == ids_spec_[i]) {
191 hspc = gui_names_spec_[i];
194 for (int j = 0; j < heightunitscombo_->get_model()->children().size(); ++j) {
195 if (heightunitscombo_->get_model()->children()[j][stringcol_] == hspc) {
196 heightunitscombo_->set_active(j);
201 heightspin_->set_sensitive(ibox);
202 heightunitscombo_->set_sensitive(ibox);
207 void GBox::setSpecial(bool ibox)
209 bool const oldlock = applylock_;
212 unsigned int const initselection = widthunitscombo_->get_active_row_number();
213 widthunitsstore_->clear();
214 vector<string> normalunits = buildLengthUnitList();
216 vector<string>::const_iterator it = normalunits.begin();
217 vector<string>::const_iterator end = normalunits.end();
218 for(; it != end; ++it)
219 (*widthunitsstore_->append())[stringcol_] = *it;
221 vector<string>::const_iterator it = normalunits.begin();
222 vector<string>::const_iterator end = normalunits.end();
223 for(; it != end; ++it)
224 (*widthunitsstore_->append())[stringcol_] = *it;
225 // Skip the first item "None"
226 it = ++gui_names_spec_.begin();
227 end = gui_names_spec_.end();
228 for(; it != end; ++it)
229 (*widthunitsstore_->append())[stringcol_] = *it;
232 int const store_size = widthunitsstore_->children().size();
233 if (initselection >= store_size) {
234 widthunitscombo_->set_active(0);
237 widthunitscombo_->set_active(initselection);
239 applylock_ = oldlock;
243 void GBox::updateInnerBoxCombo()
245 bool const oldlock = applylock_;
247 // with "frameless" boxes, inner box is mandatory (i.e. is the actual box)
248 // we have to remove "none" then and adjust the combo
252 if (!controller().params().inner_box)
255 if (controller().params().use_parbox)
258 bool frameless = (controller().params().type == "Frameless");
260 int const oldsize = innerboxstore_->children().size();
261 // Store the initial selection in 0,1,2 format
262 int oldselection = -1;
264 oldselection = innerboxcombo_->get_active_row_number() + 1;
265 else if (oldsize == 3)
266 oldselection = innerboxcombo_->get_active_row_number();
268 if (frameless && oldsize != 2) {
269 innerboxstore_->clear();
270 (*innerboxstore_->append())[stringcol_] = _("Parbox");
271 (*innerboxstore_->append())[stringcol_] = _("Minipage");
272 // Cope when the backend asks for no inner box in
276 innerboxcombo_->set_active(i);
279 innerboxcombo_->set_active(i - 1);
280 } else if (!frameless && oldsize != 3) {
281 innerboxstore_->clear();
282 (*innerboxstore_->append())[stringcol_] = _("None");
283 (*innerboxstore_->append())[stringcol_] = _("Parbox");
284 (*innerboxstore_->append())[stringcol_] = _("Minipage");
285 innerboxcombo_->set_active(i);
287 // we're not changing the liststore, just selecting i
289 innerboxcombo_->set_active(i - 1);
291 innerboxcombo_->set_active(i);
294 // Update the width units list if we've changed inner box type
295 if (i != oldselection)
298 applylock_ = oldlock;
302 void GBox::onInnerBoxComboChanged()
307 controller().params().use_parbox =
308 (*innerboxcombo_->get_active())[stringcol_] == _("Parbox");
310 bool const ibox = (*innerboxcombo_->get_active())[stringcol_] != _("None");
311 controller().params().inner_box = ibox;
314 boxvertcombo_->set_sensitive(ibox);
315 contentvertcombo_->set_sensitive(ibox);
316 contenthorzcombo_->set_sensitive(!ibox);
317 heightspin_->set_sensitive(ibox);
318 heightunitscombo_->set_sensitive(ibox);
319 // wtf? form_->set_sensitive(ibox);
321 controller().dispatchParams();
325 void GBox::onTypeComboChanged()
327 int const index = typecombo_->get_active_row_number();
328 controller().params().type = ids_[index];
330 bool frameless = (index == 0);
332 boxvertcombo_->set_sensitive(true);
333 contentvertcombo_->set_sensitive(true);
334 contenthorzcombo_->set_sensitive(false);
335 heightspin_->set_sensitive(true);
336 heightunitscombo_->set_sensitive(true);
337 //wtf? form_->setSpecial(true);
339 //int itype = innerboxcombo_->get_active_row_number();
340 controller().dispatchParams();
342 updateInnerBoxCombo();
346 void GBox::onHeightChanged()
354 Glib::ustring special = (*heightunitscombo_->get_active())[stringcol_];
355 for (int j = 1; j < gui_names_spec_.size() ; ++j) {
356 if (gui_names_spec_[j] == special) {
361 controller().params().height_special = ids_spec_[i];
365 height = heightspin_->get_text();
366 // beware: bogosity! the unit is simply ignored in this case
369 Glib::ustring const heightunit =
370 (*heightunitscombo_->get_active())[stringcol_];
371 height = heightspin_->get_text() + heightunit;
374 controller().params().height = LyXLength(height);
375 controller().dispatchParams();
379 void GBox::onWidthChanged()
386 Glib::ustring special = (*widthunitscombo_->get_active())[stringcol_];
387 for (int j = 1; j < gui_names_spec_.size() ; ++j) {
388 if (gui_names_spec_[j] == special) {
393 controller().params().special = ids_spec_[i];
397 width = widthspin_->get_text();
398 // beware: bogosity! the unit is simply ignored in this case
401 Glib::ustring const widthunit =
402 (*widthunitscombo_->get_active())[stringcol_];
403 width = widthspin_->get_text() + widthunit;
406 controller().params().width = LyXLength(width);
407 controller().dispatchParams();
411 void GBox::onAlignChanged()
416 controller().params().pos =
417 "tcb"[boxvertcombo_->get_active_row_number()];
418 controller().params().inner_pos =
419 "tcbs"[contenthorzcombo_->get_active_row_number()];
420 controller().params().hor_pos =
421 "lcrs"[contentvertcombo_->get_active_row_number()];
423 controller().dispatchParams();
426 } // namespace frontend