1 /**
2 * \file GuiHSpace.cpp
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 Spitzmüller
7 *
8 * Full author contact details are available in file CREDITS.
9 */
10
11 #include <config.h>
12
13 #include "GuiHSpace.h"
14
15 #include "LengthCombo.h"
16 #include "qt_helpers.h"
17 #include "Validator.h"
18
19 #include "Spacing.h"
20
21 #include "insets/InsetSpace.h"
22
23 #include "mathed/InsetMathSpace.h"
24
25 #include "support/gettext.h"
26 #include "support/lstrings.h"
27
28 #include <QCheckBox>
29 #include <QLineEdit>
30 #include <QPushButton>
31 #include <QValidator>
32
33 using namespace std;
34
35 namespace lyx {
36 namespace frontend {
37
GuiHSpace(bool math_mode,QWidget * parent)38 GuiHSpace::GuiHSpace(bool math_mode, QWidget * parent)
39 : InsetParamsWidget(parent), math_mode_(math_mode)
40 {
41 setupUi(this);
42
43 spacingCO->clear();
44 if (math_mode_) {
45 spacingCO->addItem(qt_("Interword Space"), "normal");
46 spacingCO->addItem(qt_("Thin Space"), "thinspace");
47 spacingCO->addItem(qt_("Medium Space"), "medspace");
48 spacingCO->addItem(qt_("Thick Space"), "thickspace");
49 spacingCO->addItem(qt_("Negative Thin Space"), "negthinspace");
50 spacingCO->addItem(qt_("Negative Medium Space"), "negmedspace");
51 spacingCO->addItem(qt_("Negative Thick Space"), "negthickspace");
52 spacingCO->addItem(qt_("Half Quad (0.5 em)"), "halfquad");
53 spacingCO->addItem(qt_("Quad (1 em)"), "quad");
54 spacingCO->addItem(qt_("Double Quad (2 em)"), "qquad");
55 spacingCO->addItem(qt_("Horizontal Fill"), "hfill");
56 spacingCO->addItem(qt_("Custom"), "custom");
57 } else {
58 spacingCO->addItem(qt_("Interword Space"), "normal");
59 spacingCO->addItem(qt_("Thin Space"), "thinspace");
60 spacingCO->addItem(qt_("Negative Thin Space"), "negthinspace");
61 spacingCO->addItem(qt_("Negative Medium Space"), "negmedspace");
62 spacingCO->addItem(qt_("Negative Thick Space"), "negthickspace");
63 spacingCO->addItem(qt_("Half Quad (0.5 em)"), "halfquad");
64 spacingCO->addItem(qt_("Quad (1 em)"), "quad");
65 spacingCO->addItem(qt_("Double Quad (2 em)"), "qquad");
66 spacingCO->addItem(qt_("Horizontal Fill"), "hfill");
67 spacingCO->addItem(qt_("Custom"), "custom");
68 spacingCO->addItem(qt_("Visible Space"), "visible");
69 }
70
71 connect(spacingCO, SIGNAL(highlighted(QString)),
72 this, SLOT(changedSlot()));
73 connect(valueLE, SIGNAL(textChanged(QString)),
74 this, SLOT(changedSlot()));
75 connect(spacingCO, SIGNAL(activated(int)),
76 this, SLOT(changedSlot()));
77 connect(keepCB, SIGNAL(clicked()),
78 this, SLOT(changedSlot()));
79 connect(unitCO, SIGNAL(selectionChanged(lyx::Length::UNIT)),
80 this, SLOT(changedSlot()));
81 connect(fillPatternCO, SIGNAL(activated(int)),
82 this, SLOT(changedSlot()));
83
84 // Set up a signed (glue) length validator
85 LengthValidator * v = new LengthValidator(valueLE);
86 if (math_mode_)
87 v->setBottom(Length());
88 else
89 v->setBottom(GlueLength());
90 valueLE->setValidator(v);
91
92 // initialize the length validator
93 addCheckedWidget(valueLE, valueL);
94 enableWidgets();
95 }
96
97
changedSlot()98 void GuiHSpace::changedSlot()
99 {
100 enableWidgets();
101 changed();
102 }
103
104
enableWidgets() const105 void GuiHSpace::enableWidgets() const
106 {
107 QString const selection = spacingCO->itemData(spacingCO->currentIndex()).toString();
108 bool const custom = selection == "custom";
109 valueLE->setEnabled(custom);
110 if (custom)
111 valueLE->setFocus();
112 valueL->setEnabled(custom);
113 unitCO->setEnabled(custom);
114 fillPatternCO->setEnabled(!math_mode_ && selection == "hfill");
115 fillPatternL->setEnabled(!math_mode_ && selection == "hfill");
116 bool const no_pattern = fillPatternCO->currentIndex() == 0 || math_mode_;
117 bool const enable_keep =
118 selection == "normal" || selection == "halfquad"
119 || (selection == "hfill" && no_pattern) || custom;
120 keepCB->setEnabled(enable_keep);
121 keepL->setEnabled(enable_keep);
122 }
123
124
paramsToDialog(Inset const * inset)125 void GuiHSpace::paramsToDialog(Inset const * inset)
126 {
127 InsetSpaceParams const params = math_mode_
128 ? static_cast<InsetMathSpace const *>(inset)->params()
129 : static_cast<InsetSpace const *>(inset)->params();
130
131 QString item;
132 int pattern = 0;
133 bool protect = false;
134 switch (params.kind) {
135 case InsetSpaceParams::NORMAL:
136 item = "normal";
137 break;
138 case InsetSpaceParams::PROTECTED:
139 item = "normal";
140 protect = true;
141 break;
142 case InsetSpaceParams::VISIBLE:
143 item = "visible";
144 protect = true;
145 break;
146 case InsetSpaceParams::THIN:
147 item = "thinspace";
148 break;
149 case InsetSpaceParams::MEDIUM:
150 item = "medspace";
151 break;
152 case InsetSpaceParams::THICK:
153 item = "thickspace";
154 break;
155 case InsetSpaceParams::NEGTHIN:
156 item = "negthinspace";
157 break;
158 case InsetSpaceParams::NEGMEDIUM:
159 item = "negmedspace";
160 break;
161 case InsetSpaceParams::NEGTHICK:
162 item = "negthickspace";
163 break;
164 case InsetSpaceParams::ENSKIP:
165 item = "halfquad";
166 break;
167 case InsetSpaceParams::ENSPACE:
168 item = "halfquad";
169 protect = true;
170 break;
171 case InsetSpaceParams::QUAD:
172 item = "quad";
173 break;
174 case InsetSpaceParams::QQUAD:
175 item = "qquad";
176 break;
177 case InsetSpaceParams::HFILL:
178 item = "hfill";
179 break;
180 case InsetSpaceParams::HFILL_PROTECTED:
181 item = "hfill";
182 protect = true;
183 break;
184 case InsetSpaceParams::DOTFILL:
185 item = "hfill";
186 pattern = 1;
187 break;
188 case InsetSpaceParams::HRULEFILL:
189 item = "hfill";
190 pattern = 2;
191 break;
192 case InsetSpaceParams::LEFTARROWFILL:
193 item = "hfill";
194 pattern = 3;
195 break;
196 case InsetSpaceParams::RIGHTARROWFILL:
197 item = "hfill";
198 pattern = 4;
199 break;
200 case InsetSpaceParams::UPBRACEFILL:
201 item = "hfill";
202 pattern = 5;
203 break;
204 case InsetSpaceParams::DOWNBRACEFILL:
205 item = "hfill";
206 pattern = 6;
207 break;
208 case InsetSpaceParams::CUSTOM:
209 item = "custom";
210 break;
211 case InsetSpaceParams::CUSTOM_PROTECTED:
212 item = "custom";
213 protect = true;
214 break;
215 }
216 spacingCO->setCurrentIndex(spacingCO->findData(item));
217 fillPatternCO->setCurrentIndex(pattern);
218 keepCB->setChecked(protect);
219 if (item == "halfquad") {
220 keepCB->setToolTip(qt_("Insert the spacing even after a line break.\n"
221 "Note that a protected Half Quad will be turned into\n"
222 "a vertical space if used at the beginning of a paragraph!"));
223 } else {
224 keepCB->setToolTip(qt_("Insert the spacing even after a line break"));
225 }
226 Length::UNIT const default_unit = Length::defaultUnit();
227 if (item == "custom") {
228 string length = params.length.asString();
229 lengthToWidgets(valueLE, unitCO, length, default_unit);
230 } else
231 lengthToWidgets(valueLE, unitCO, "", default_unit);
232
233 enableWidgets();
234 }
235
236
dialogToParams() const237 docstring GuiHSpace::dialogToParams() const
238 {
239 InsetSpaceParams params = math_mode_ ?
240 InsetSpaceParams(true) : InsetSpaceParams(false);
241
242 QString const item =
243 spacingCO->itemData(spacingCO->currentIndex()).toString();
244
245 if (item == "normal")
246 params.kind = keepCB->isChecked() ?
247 InsetSpaceParams::PROTECTED : InsetSpaceParams::NORMAL;
248 else if (item == "thinspace")
249 params.kind = InsetSpaceParams::THIN;
250 else if (item == "medspace")
251 params.kind = InsetSpaceParams::MEDIUM;
252 else if (item == "thickspace")
253 params.kind = InsetSpaceParams::THICK;
254 else if (item == "negthinspace")
255 params.kind = InsetSpaceParams::NEGTHIN;
256 else if (item == "negmedspace")
257 params.kind = InsetSpaceParams::NEGMEDIUM;
258 else if (item == "negthickspace")
259 params.kind = InsetSpaceParams::NEGTHICK;
260 else if (item == "halfquad")
261 params.kind = keepCB->isChecked() ?
262 InsetSpaceParams::ENSPACE : InsetSpaceParams::ENSKIP;
263 else if (item == "quad")
264 params.kind = InsetSpaceParams::QUAD;
265 else if (item == "qquad")
266 params.kind = InsetSpaceParams::QQUAD;
267 else if (item == "hfill") {
268 switch (fillPatternCO->currentIndex()) {
269 case 1:
270 params.kind = InsetSpaceParams::DOTFILL;
271 break;
272 case 2:
273 params.kind = InsetSpaceParams::HRULEFILL;
274 break;
275 case 3:
276 params.kind = InsetSpaceParams::LEFTARROWFILL;
277 break;
278 case 4:
279 params.kind = InsetSpaceParams::RIGHTARROWFILL;
280 break;
281 case 5:
282 params.kind = InsetSpaceParams::UPBRACEFILL;
283 break;
284 case 6:
285 params.kind = InsetSpaceParams::DOWNBRACEFILL;
286 break;
287 default:
288 if (keepCB->isChecked())
289 params.kind = InsetSpaceParams::HFILL_PROTECTED;
290 else
291 params.kind = InsetSpaceParams::HFILL;
292 break;
293 }
294 } else if (item == "custom") {
295 params.kind = keepCB->isChecked() ?
296 InsetSpaceParams::CUSTOM_PROTECTED : InsetSpaceParams::CUSTOM;
297 params.length = GlueLength(widgetsToLength(valueLE, unitCO));
298 } else if (item == "visible")
299 params.kind = InsetSpaceParams::VISIBLE;
300
301 return from_ascii(InsetSpace::params2string(params));
302 }
303
304
checkWidgets(bool readonly) const305 bool GuiHSpace::checkWidgets(bool readonly) const
306 {
307 valueLE->setReadOnly(readonly);
308
309 if (readonly) {
310 spacingCO->setEnabled(false);
311 unitCO->setEnabled(false);
312 fillPatternCO->setEnabled(false);
313 keepCB->setEnabled(false);
314 valueLE->setEnabled(false);
315 } else
316 enableWidgets();
317
318 if (!InsetParamsWidget::checkWidgets())
319 return false;
320 return spacingCO->itemData(spacingCO->currentIndex()).toString() != "custom"
321 || !valueLE->text().isEmpty();
322 }
323
324 } // namespace frontend
325 } // namespace lyx
326
327
328 #include "moc_GuiHSpace.cpp"
329