]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiHSpace.cpp
Fix some bugs related to spaces in math:
[lyx.git] / src / frontends / qt4 / GuiHSpace.cpp
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
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"), toqstr("normal"));
46                 spacingCO->addItem(qt_("Thin Space"), toqstr("thinspace"));
47                 spacingCO->addItem(qt_("Medium Space"), toqstr("medspace"));
48                 spacingCO->addItem(qt_("Thick Space"), toqstr("thickspace"));
49                 spacingCO->addItem(qt_("Negative Thin Space"), toqstr("negthinspace"));
50                 spacingCO->addItem(qt_("Negative Medium Space"), toqstr("negmedspace"));
51                 spacingCO->addItem(qt_("Negative Thick Space"), toqstr("negthickspace"));
52                 spacingCO->addItem(qt_("Half Quad (0.5 em)"), toqstr("halfquad"));
53                 spacingCO->addItem(qt_("Quad (1 em)"), toqstr("quad"));
54                 spacingCO->addItem(qt_("Double Quad (2 em)"), toqstr("qquad"));
55                 spacingCO->addItem(qt_("Horizontal Fill"), toqstr("hfill"));
56                 spacingCO->addItem(qt_("Custom"), toqstr("custom"));
57         } else {
58                 spacingCO->addItem(qt_("Interword Space"), toqstr("normal"));
59                 spacingCO->addItem(qt_("Thin Space"), toqstr("thinspace"));
60                 spacingCO->addItem(qt_("Negative Thin Space"), toqstr("negthinspace"));
61                 spacingCO->addItem(qt_("Negative Medium Space"), toqstr("negmedspace"));
62                 spacingCO->addItem(qt_("Negative Thick Space"), toqstr("negthickspace"));
63                 spacingCO->addItem(qt_("Half Quad (0.5 em)"), toqstr("halfquad"));
64                 spacingCO->addItem(qt_("Quad (1 em)"), toqstr("quad"));
65                 spacingCO->addItem(qt_("Double Quad (2 em)"), toqstr("qquad"));
66                 spacingCO->addItem(qt_("Horizontal Fill"), toqstr("hfill"));
67                 spacingCO->addItem(qt_("Custom"), toqstr("custom"));
68                 spacingCO->addItem(qt_("Visible Space"), toqstr("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         if (math_mode_)
85                 valueLE->setValidator(unsignedLengthValidator(valueLE));
86         else
87                 valueLE->setValidator(unsignedGlueLengthValidator(valueLE));
88
89         // initialize the length validator
90         addCheckedWidget(valueLE, valueL);
91 }
92
93
94 void GuiHSpace::changedSlot()
95 {
96         enableWidgets();
97         changed();
98 }
99
100
101 void GuiHSpace::enableWidgets()
102 {
103         QString const selection = spacingCO->itemData(spacingCO->currentIndex()).toString();
104         bool const custom = selection == "custom";
105         valueLE->setEnabled(custom);
106         unitCO->setEnabled(custom);
107         fillPatternCO->setEnabled(!math_mode_ && selection == "hfill");
108         bool const no_pattern = fillPatternCO->currentIndex() == 0 || math_mode_;
109         bool const enable_keep =
110                 selection == "normal" || selection == "halfquad" || (selection == "hfill" && no_pattern) || custom;
111         keepCB->setEnabled(enable_keep);
112 }
113
114
115 void GuiHSpace::paramsToDialog(Inset const * inset)
116 {
117         InsetSpaceParams const params = math_mode_
118                 ? static_cast<InsetMathSpace const *>(inset)->params()
119                 : static_cast<InsetSpace const *>(inset)->params();
120
121         QString item;
122         int pattern = 0;
123         bool protect = false;
124         switch (params.kind) {
125                 case InsetSpaceParams::NORMAL:
126                         item = "normal";
127                         break;
128                 case InsetSpaceParams::PROTECTED:
129                         item = "normal";
130                         protect = true;
131                         break;
132                 case InsetSpaceParams::VISIBLE:
133                         item = "visible";
134                         protect = true;
135                         break;
136                 case InsetSpaceParams::THIN:
137                         item = "thinspace";
138                         break;
139                 case InsetSpaceParams::MEDIUM:
140                         item = "medspace";
141                         break;
142                 case InsetSpaceParams::THICK:
143                         item = "thickspace";
144                         break;
145                 case InsetSpaceParams::NEGTHIN:
146                         item = "negthinspace";
147                         break;
148                 case InsetSpaceParams::NEGMEDIUM:
149                         item = "negmedspace";
150                         break;
151                 case InsetSpaceParams::NEGTHICK:
152                         item = "negthickspace";
153                         break;
154                 case InsetSpaceParams::ENSKIP:
155                         item = "halfquad";
156                         break;
157                 case InsetSpaceParams::ENSPACE:
158                         item = "halfquad";
159                         protect = true;
160                         break;
161                 case InsetSpaceParams::QUAD:
162                         item = "quad";
163                         break;
164                 case InsetSpaceParams::QQUAD:
165                         item = "qquad";
166                         break;
167                 case InsetSpaceParams::HFILL:
168                         item = "hfill";
169                         break;
170                 case InsetSpaceParams::HFILL_PROTECTED:
171                         item = "hfill";
172                         protect = true;
173                         break;
174                 case InsetSpaceParams::DOTFILL:
175                         item = "hfill";
176                         pattern = 1;
177                         break;
178                 case InsetSpaceParams::HRULEFILL:
179                         item = "hfill";
180                         pattern = 2;
181                         break;
182                 case InsetSpaceParams::LEFTARROWFILL:
183                         item = "hfill";
184                         pattern = 3;
185                         break;
186                 case InsetSpaceParams::RIGHTARROWFILL:
187                         item = "hfill";
188                         pattern = 4;
189                         break;
190                 case InsetSpaceParams::UPBRACEFILL:
191                         item = "hfill";
192                         pattern = 5;
193                         break;
194                 case InsetSpaceParams::DOWNBRACEFILL:
195                         item = "hfill";
196                         pattern = 6;
197                         break;
198                 case InsetSpaceParams::CUSTOM:
199                         item = "custom";
200                         break;
201                 case InsetSpaceParams::CUSTOM_PROTECTED:
202                         item = "custom";
203                         protect = true;
204                         break;
205         }
206         spacingCO->setCurrentIndex(spacingCO->findData(item));
207         fillPatternCO->setCurrentIndex(pattern);
208         keepCB->setChecked(protect);
209         if (item == "halfquad") {
210                 keepCB->setToolTip(qt_("Insert the spacing even after a line break.\n"
211                                        "Note that a protected Half Quad will be turned into\n"
212                                        "a vertical space if used at the beginning of a paragraph!"));
213         } else {
214                 keepCB->setToolTip(qt_("Insert the spacing even after a line break"));
215         }
216         Length::UNIT const default_unit = Length::defaultUnit();
217         if (item == "custom") {
218                 string length = params.length.asString();
219                 lengthToWidgets(valueLE, unitCO, length, default_unit);
220         } else
221                 lengthToWidgets(valueLE, unitCO, "", default_unit);
222
223         enableWidgets();
224 }
225
226
227 docstring GuiHSpace::dialogToParams() const
228 {
229         InsetSpaceParams params = math_mode_ ?
230                 InsetSpaceParams(true) : InsetSpaceParams(false);
231
232         QString const item =
233                 spacingCO->itemData(spacingCO->currentIndex()).toString();
234
235         if (item == "normal")
236                 params.kind = keepCB->isChecked() ?
237                         InsetSpaceParams::PROTECTED : InsetSpaceParams::NORMAL;
238         else if (item == "thinspace")
239                 params.kind = InsetSpaceParams::THIN;
240         else if (item == "medspace")
241                 params.kind = InsetSpaceParams::MEDIUM;
242         else if (item == "thickspace")
243                 params.kind = InsetSpaceParams::THICK;
244         else if (item == "negthinspace")
245                 params.kind = InsetSpaceParams::NEGTHIN;
246         else if (item == "negmedspace")
247                 params.kind = InsetSpaceParams::NEGMEDIUM;
248         else if (item == "negthickspace")
249                 params.kind = InsetSpaceParams::NEGTHICK;
250         else if (item == "halfquad")
251                 params.kind = keepCB->isChecked() ?
252                         InsetSpaceParams::ENSPACE : InsetSpaceParams::ENSKIP;
253         else if (item == "quad")
254                         params.kind = InsetSpaceParams::QUAD;
255         else if (item == "qquad")
256                         params.kind = InsetSpaceParams::QQUAD;
257         else if (item == "hfill") {
258                 switch (fillPatternCO->currentIndex()) {
259                 case 1:
260                         params.kind = InsetSpaceParams::DOTFILL;
261                         break;
262                 case 2:
263                         params.kind = InsetSpaceParams::HRULEFILL;
264                         break;
265                 case 3:
266                         params.kind = InsetSpaceParams::LEFTARROWFILL;
267                         break;
268                 case 4:
269                         params.kind = InsetSpaceParams::RIGHTARROWFILL;
270                         break;
271                 case 5:
272                         params.kind = InsetSpaceParams::UPBRACEFILL;
273                         break;
274                 case 6:
275                         params.kind = InsetSpaceParams::DOWNBRACEFILL;
276                         break;
277                 default:
278                         if (keepCB->isChecked())
279                                 params.kind = InsetSpaceParams::HFILL_PROTECTED;
280                         else
281                                 params.kind = InsetSpaceParams::HFILL;
282                         break;
283                 }
284         } else if (item == "custom") {
285                         params.kind = keepCB->isChecked() ?
286                                 InsetSpaceParams::CUSTOM_PROTECTED : InsetSpaceParams::CUSTOM;
287                         params.length = GlueLength(widgetsToLength(valueLE, unitCO));
288         } else if (item == "visible") 
289                 params.kind = InsetSpaceParams::VISIBLE;
290
291         return from_ascii(InsetSpace::params2string(params));
292 }
293
294
295 bool GuiHSpace::checkWidgets() const
296 {
297         if (!InsetParamsWidget::checkWidgets())
298                 return false;
299         return spacingCO->itemData(spacingCO->currentIndex()).toString() != "custom"
300                 || !valueLE->text().isEmpty();
301 }
302
303 } // namespace frontend
304 } // namespace lyx
305
306
307 #include "moc_GuiHSpace.cpp"