]> git.lyx.org Git - features.git/blob - src/frontends/qt2/QBox.C
bdc1529ae4929732437502966930146dd68946f3
[features.git] / src / frontends / qt2 / QBox.C
1 /**
2  * \file QBox.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Jürgen Vigna (Minipage stuff)
7  * \author Martin Vermeer
8  * \author Jürgen Spitzmüller
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "QBox.h"
16
17 #include "checkedwidgets.h"
18 #include "lengthcombo.h"
19 #include "QBoxDialog.h"
20 #include "qt_helpers.h"
21 #include "Qt2BC.h"
22
23 #include "lengthcommon.h"
24 #include "lyxrc.h" // to set the default length values
25
26 #include "controllers/ControlBox.h"
27 #include "controllers/helper_funcs.h"
28
29 #include "insets/insetbox.h"
30
31 #include "support/lstrings.h"
32 #include "support/tostr.h"
33
34 #include <qpushbutton.h>
35 #include <qlineedit.h>
36 #include <qcombobox.h>
37 #include <qbuttongroup.h>
38
39 #include <vector>
40
41 using lyx::support::getStringFromVector;
42 using lyx::support::isStrDbl;
43 using lyx::support::subst;
44 using std::string;
45
46 namespace lyx {
47 namespace frontend {
48
49 typedef QController<ControlBox, QView<QBoxDialog> > base_class;
50
51 QBox::QBox(Dialog & parent)
52         : base_class(parent, _("LyX: Box Settings"))
53 {}
54
55
56 void QBox::build_dialog()
57 {
58         dialog_.reset(new QBoxDialog(this));
59
60         // fill the box type choice
61         box_gui_tokens(ids_, gui_names_);
62         for (unsigned int i = 0; i < gui_names_.size(); ++i)
63                 dialog_->typeCO->insertItem(toqstr(gui_names_[i]));
64
65         // add the special units to the height choice
66         // width needs different handling
67         box_gui_tokens_special_length(ids_spec_, gui_names_spec_);
68         for (unsigned int i = 1; i < gui_names_spec_.size(); ++i) {
69                 dialog_->heightUnitsLC->insertItem(toqstr(gui_names_spec_[i]));
70         }
71
72         bcview().addReadOnly(dialog_->typeCO);
73         bcview().addReadOnly(dialog_->innerBoxCO);
74         bcview().addReadOnly(dialog_->valignCO);
75         bcview().addReadOnly(dialog_->ialignCO);
76         bcview().addReadOnly(dialog_->halignCO);
77         bcview().addReadOnly(dialog_->widthED);
78         bcview().addReadOnly(dialog_->heightED);
79         bcview().addReadOnly(dialog_->widthUnitsLC);
80         bcview().addReadOnly(dialog_->heightUnitsLC);
81
82         bcview().setRestore(dialog_->restorePB);
83         bcview().setOK(dialog_->okPB);
84         bcview().setApply(dialog_->applyPB);
85         bcview().setCancel(dialog_->closePB);
86         
87         // initialize the length validator
88         addCheckedLineEdit(bcview(), dialog_->widthED, dialog_->widthLA);
89         addCheckedLineEdit(bcview(), dialog_->heightED, dialog_->heightLA);
90 }
91
92
93 void QBox::update_contents()
94 {
95         string type(controller().params().type);
96         for (unsigned int i = 0; i < gui_names_.size(); ++i) {
97                 if (type == ids_[i])
98                         dialog_->typeCO->setCurrentItem(i);
99         }
100
101         // default: minipage
102         unsigned int inner_type = 2;
103         if (!controller().params().inner_box)
104                 // none
105                 inner_type = 0;
106         if (controller().params().use_parbox)
107                 // parbox
108                 inner_type = 1;
109         bool frameless = (controller().params().type == "Frameless");
110         setInnerType(frameless, inner_type);
111
112         char c = controller().params().pos;
113         dialog_->valignCO->setCurrentItem(string("tcb").find(c, 0));
114         c = controller().params().inner_pos;
115         dialog_->ialignCO->setCurrentItem(string("tcbs").find(c, 0));
116         c = controller().params().hor_pos;
117         dialog_->halignCO->setCurrentItem(string("lcrs").find(c, 0));
118
119         bool ibox = controller().params().inner_box;
120         dialog_->valignCO->setEnabled(ibox);
121         dialog_->ialignCO->setEnabled(ibox);
122         dialog_->halignCO->setEnabled(!ibox);
123         setSpecial(ibox);
124
125         LyXLength::UNIT default_unit =
126                 (lyxrc.default_papersize > 3) ? LyXLength::CM : LyXLength::IN;
127
128         lengthToWidgets(dialog_->widthED, dialog_->widthUnitsLC,
129                 (controller().params().width).asString(), default_unit);
130
131         string const special(controller().params().special);
132         if (!special.empty() && special != "none") {
133                 QString spc;
134                 for (unsigned int i = 0; i < gui_names_spec_.size(); i++) {
135                         if (special == ids_spec_[i])
136                                 spc = toqstr(gui_names_spec_[i].c_str());
137                 }
138                 for (int j = 0; j < dialog_->widthUnitsLC->count(); j++) {
139                         if (dialog_->widthUnitsLC->text(j) == spc)
140                                 dialog_->widthUnitsLC->setCurrentItem(j);
141                 }
142         }
143
144         lengthToWidgets(dialog_->heightED, dialog_->heightUnitsLC,
145                 (controller().params().height).asString(), default_unit);
146
147         string const height_special(controller().params().height_special);
148         if (!height_special.empty() && height_special != "none") {
149                 QString hspc;
150                 for (unsigned int i = 0; i < gui_names_spec_.size(); i++) {
151                         if (height_special == ids_spec_[i]) {
152                                 hspc = toqstr(gui_names_spec_[i].c_str());
153                         }
154                 }
155                 for (int j = 0; j < dialog_->heightUnitsLC->count(); j++) {
156                         if (dialog_->heightUnitsLC->text(j) == hspc) {
157                                 dialog_->heightUnitsLC->setCurrentItem(j);
158                         }
159                 }
160         }
161
162         dialog_->heightED->setEnabled(ibox);
163         dialog_->heightUnitsLC->setEnabled(ibox);
164 }
165
166
167 void QBox::apply()
168 {
169         controller().params().type =
170                 ids_[dialog_->typeCO->currentItem()];
171
172         controller().params().inner_box =
173                 dialog_->innerBoxCO->currentText() != qt_("None");
174         controller().params().use_parbox =
175                 dialog_->innerBoxCO->currentText() ==  qt_("Parbox");
176
177         controller().params().pos =
178                 "tcb"[dialog_->valignCO->currentItem()];
179         controller().params().inner_pos =
180                 "tcbs"[dialog_->ialignCO->currentItem()];
181         controller().params().hor_pos =
182                 "lcrs"[dialog_->halignCO->currentItem()];
183
184         int i = 0;
185         bool spec = false;
186         QString special = dialog_->widthUnitsLC->currentText();
187         QString value = dialog_->widthED->text();
188         if (special == qt_("Height")) {
189                 i = 1;
190                 spec = true;
191         } else if (special == qt_("Depth")) {
192                 i = 2;
193                 spec = true;
194         } else if (special == qt_("Total Height")) {
195                 i = 3;
196                 spec = true;
197         } else if (special == qt_("Width")) {
198                 i = 4;
199                 spec = true;
200         } 
201         // the user might insert a non-special value in the line edit
202         if (isValidLength(fromqstr(value))) {
203                 i = 0;
204                 spec = false;
205         }
206         controller().params().special = ids_spec_[i];
207
208         string width;
209         if (spec) {
210                 width = fromqstr(value);
211                 // beware: bogosity! the unit is simply ignored in this case
212                 width += "in";
213         } else
214                 width = widgetsToLength(dialog_->widthED, dialog_->widthUnitsLC);
215
216         controller().params().width = LyXLength(width);
217
218         i = 0;
219         spec = false;
220         special = dialog_->heightUnitsLC->currentText();
221         value = dialog_->heightED->text();
222         if (special == qt_("Height")) {
223                 i = 1;
224                 spec = true;
225         } else if (special == qt_("Depth")) {
226                 i = 2;
227                 spec = true;
228         } else if (special == qt_("Total Height")) {
229                 i = 3;
230                 spec = true;
231         } else if (special == qt_("Width")) {
232                 i = 4;
233                 spec = true;
234         }
235         // the user might insert a non-special value in the line edit
236         if (isValidLength(fromqstr(value))) {
237                 i = 0;
238                 spec = false;
239         }
240         controller().params().height_special = ids_spec_[i];
241
242         string height;
243         if (spec  && !isValidLength(fromqstr(dialog_->heightED->text()))) {
244                 height = fromqstr(value);
245                 // beware: bogosity! the unit is simply ignored in this case
246                 height += "in";
247         } else
248                 height = widgetsToLength(dialog_->heightED, dialog_->heightUnitsLC);
249
250         controller().params().height = LyXLength(height);
251 }
252
253
254 void QBox::setSpecial(bool ibox)
255 {
256         box_gui_tokens_special_length(ids_spec_, gui_names_spec_);
257         // check if the widget contains the special units
258         int count = dialog_->widthUnitsLC->count();
259         bool has_special = false;
260         for (int i = 0; i < count; i++)
261                 if (dialog_->widthUnitsLC->text(i).contains(qt_("Total Height")) > 0)
262                         has_special = true;
263         // insert 'em if needed...
264         if (!ibox && !has_special) {
265                 for (unsigned int i = 1; i < gui_names_spec_.size(); i++)
266                         dialog_->widthUnitsLC->insertItem(toqstr(gui_names_spec_[i]));
267         // ... or remove 'em if needed
268         } else if (ibox && has_special) {
269                 dialog_->widthUnitsLC->clear();
270                 for (int i = 0; i < num_units; i++)
271                         dialog_->widthUnitsLC->insertItem(unit_name_gui[i]);
272         }
273 }
274
275
276 void QBox::setInnerType(bool frameless, int i)
277 {
278         // with "frameless" boxes, inner box is mandatory (i.e. is the actual box)
279         // we have to remove "none" then and adjust the combo
280         if (frameless) {
281                 dialog_->innerBoxCO->clear();
282                 dialog_->innerBoxCO->insertItem(qt_("Parbox"));
283                 dialog_->innerBoxCO->insertItem(qt_("Minipage"));
284                 dialog_->innerBoxCO->setCurrentItem(i - 1);
285         } else {
286                 if (dialog_->innerBoxCO->count() == 2)
287                         i += 1;
288                 dialog_->innerBoxCO->clear();
289                 dialog_->innerBoxCO->insertItem(qt_("None"));
290                 dialog_->innerBoxCO->insertItem(qt_("Parbox"));
291                 dialog_->innerBoxCO->insertItem(qt_("Minipage"));
292                 dialog_->innerBoxCO->setCurrentItem(i);
293         }
294 }
295
296 } // namespace frontend
297 } // namespace lyx