]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiCharacter.cpp
math stuff
[lyx.git] / src / frontends / qt4 / GuiCharacter.cpp
1 /**
2  * \file GuiCharacter.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Angus Leeming
7  * \author Edwin Leuven
8  * \author John Levon
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "GuiCharacter.h"
16
17 #include "qt_helpers.h"
18 #include "Color.h"
19 #include "Font.h"
20 #include "Buffer.h"
21 #include "BufferParams.h"
22 #include "FuncRequest.h"
23 #include "Language.h"
24 #include "Color.h"
25
26 #include <QCloseEvent>
27
28 using std::vector;
29 using std::string;
30
31
32 namespace lyx {
33 namespace frontend {
34
35 static vector<ShapePair> const getShapeData()
36 {
37         vector<ShapePair> shape(6);
38
39         ShapePair pr;
40
41         pr.first = qt_("No change");
42         pr.second = Font::IGNORE_SHAPE;
43         shape[0] = pr;
44
45         pr.first = qt_("Upright");
46         pr.second = Font::UP_SHAPE;
47         shape[1] = pr;
48
49         pr.first = qt_("Italic");
50         pr.second = Font::ITALIC_SHAPE;
51         shape[2] = pr;
52
53         pr.first = qt_("Slanted");
54         pr.second = Font::SLANTED_SHAPE;
55         shape[3] = pr;
56
57         pr.first = qt_("Small Caps");
58         pr.second = Font::SMALLCAPS_SHAPE;
59         shape[4] = pr;
60
61         pr.first = qt_("Reset");
62         pr.second = Font::INHERIT_SHAPE;
63         shape[5] = pr;
64
65         return shape;
66 }
67
68
69 static vector<SizePair> const getSizeData()
70 {
71         vector<SizePair> size(14);
72
73         SizePair pr;
74
75         pr.first = qt_("No change");
76         pr.second = Font::IGNORE_SIZE;
77         size[0] = pr;
78
79         pr.first = qt_("Tiny");
80         pr.second = Font::SIZE_TINY;
81         size[1] = pr;
82
83         pr.first = qt_("Smallest");
84         pr.second = Font::SIZE_SCRIPT;
85         size[2] = pr;
86
87         pr.first = qt_("Smaller");
88         pr.second = Font::SIZE_FOOTNOTE;
89         size[3] = pr;
90
91         pr.first = qt_("Small");
92         pr.second = Font::SIZE_SMALL;
93         size[4] = pr;
94
95         pr.first = qt_("Normal");
96         pr.second = Font::SIZE_NORMAL;
97         size[5] = pr;
98
99         pr.first = qt_("Large");
100         pr.second = Font::SIZE_LARGE;
101         size[6] = pr;
102
103         pr.first = qt_("Larger");
104         pr.second = Font::SIZE_LARGER;
105         size[7] = pr;
106
107         pr.first = qt_("Largest");
108         pr.second = Font::SIZE_LARGEST;
109         size[8] = pr;
110
111         pr.first = qt_("Huge");
112         pr.second = Font::SIZE_HUGE;
113         size[9] = pr;
114
115         pr.first = qt_("Huger");
116         pr.second = Font::SIZE_HUGER;
117         size[10] = pr;
118
119         pr.first = qt_("Increase");
120         pr.second = Font::INCREASE_SIZE;
121         size[11] = pr;
122
123         pr.first = qt_("Decrease");
124         pr.second = Font::DECREASE_SIZE;
125         size[12] = pr;
126
127         pr.first = qt_("Reset");
128         pr.second = Font::INHERIT_SIZE;
129         size[13] = pr;
130
131         return size;
132 }
133
134
135 static vector<BarPair> const getBarData()
136 {
137         vector<BarPair> bar(5);
138
139         BarPair pr;
140
141         pr.first = qt_("No change");
142         pr.second = IGNORE;
143         bar[0] = pr;
144
145         pr.first = qt_("Emph");
146         pr.second = EMPH_TOGGLE;
147         bar[1] = pr;
148
149         pr.first = qt_("Underbar");
150         pr.second = UNDERBAR_TOGGLE;
151         bar[2] = pr;
152
153         pr.first = qt_("Noun");
154         pr.second = NOUN_TOGGLE;
155         bar[3] = pr;
156
157         pr.first = qt_("Reset");
158         pr.second = INHERIT;
159         bar[4] = pr;
160
161         return bar;
162 }
163
164
165 static vector<ColorPair> const getColorData()
166 {
167         vector<ColorPair> color(11);
168
169         ColorPair pr;
170
171         pr.first = qt_("No change");
172         pr.second = Color::ignore;
173         color[0] = pr;
174
175         pr.first = qt_("No color");
176         pr.second = Color::none;
177         color[1] = pr;
178
179         pr.first = qt_("Black");
180         pr.second = Color::black;
181         color[2] = pr;
182
183         pr.first = qt_("White");
184         pr.second = Color::white;
185         color[3] = pr;
186
187         pr.first = qt_("Red");
188         pr.second = Color::red;
189         color[4] = pr;
190
191         pr.first = qt_("Green");
192         pr.second = Color::green;
193         color[5] = pr;
194
195         pr.first = qt_("Blue");
196         pr.second = Color::blue;
197         color[6] = pr;
198
199         pr.first = qt_("Cyan");
200         pr.second = Color::cyan;
201         color[7] = pr;
202
203         pr.first = qt_("Magenta");
204         pr.second = Color::magenta;
205         color[8] = pr;
206
207         pr.first = qt_("Yellow");
208         pr.second = Color::yellow;
209         color[9] = pr;
210
211         pr.first = qt_("Reset");
212         pr.second = Color::inherit;
213         color[10] = pr;
214
215         return color;
216 }
217
218
219 static vector<SeriesPair> const getSeriesData()
220 {
221         vector<SeriesPair> series(4);
222
223         SeriesPair pr;
224
225         pr.first = qt_("No change");
226         pr.second = Font::IGNORE_SERIES;
227         series[0] = pr;
228
229         pr.first = qt_("Medium");
230         pr.second = Font::MEDIUM_SERIES;
231         series[1] = pr;
232
233         pr.first = qt_("Bold");
234         pr.second = Font::BOLD_SERIES;
235         series[2] = pr;
236
237         pr.first = qt_("Reset");
238         pr.second = Font::INHERIT_SERIES;
239         series[3] = pr;
240
241         return series;
242 }
243
244
245 static vector<FamilyPair> const getFamilyData()
246 {
247         vector<FamilyPair> family(5);
248
249         FamilyPair pr;
250
251         pr.first = qt_("No change");
252         pr.second = Font::IGNORE_FAMILY;
253         family[0] = pr;
254
255         pr.first = qt_("Roman");
256         pr.second = Font::ROMAN_FAMILY;
257         family[1] = pr;
258
259         pr.first = qt_("Sans Serif");
260         pr.second = Font::SANS_FAMILY;
261         family[2] = pr;
262
263         pr.first = qt_("Typewriter");
264         pr.second = Font::TYPEWRITER_FAMILY;
265         family[3] = pr;
266
267         pr.first = qt_("Reset");
268         pr.second = Font::INHERIT_FAMILY;
269         family[4] = pr;
270
271         return family;
272 }
273
274
275 GuiCharacter::GuiCharacter(LyXView & lv)
276         : GuiDialog(lv, "character"), Controller(this), font_(Font::ALL_IGNORE),
277           toggleall_(false), reset_lang_(false)
278 {
279         setupUi(this);
280         setController(this, false);
281         setViewTitle(_("Text Style"));
282
283         connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
284         connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
285         connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
286
287         connect(miscCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
288         connect(sizeCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
289         connect(familyCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
290         connect(seriesCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
291         connect(shapeCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
292         connect(colorCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
293         connect(langCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
294         connect(toggleallCB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
295
296         family = getFamilyData();
297         series = getSeriesData();
298         shape  = getShapeData();
299         size   = getSizeData();
300         bar    = getBarData();
301         color  = getColorData();
302         language = getLanguageData(true);
303
304         for (vector<FamilyPair>::const_iterator cit = family.begin();
305                 cit != family.end(); ++cit) {
306                 familyCO->addItem(cit->first);
307         }
308
309         for (vector<SeriesPair>::const_iterator cit = series.begin();
310                 cit != series.end(); ++cit) {
311                 seriesCO->addItem(cit->first);
312         }
313         for (vector<ShapePair>::const_iterator cit = shape.begin();
314                 cit != shape.end(); ++cit) {
315                 shapeCO->addItem(cit->first);
316         }
317         for (vector<SizePair>::const_iterator cit = size.begin();
318                 cit != size.end(); ++cit) {
319                 sizeCO->addItem(cit->first);
320         }
321         for (vector<BarPair>::const_iterator cit = bar.begin();
322                 cit != bar.end(); ++cit) {
323                 miscCO->addItem(cit->first);
324         }
325         for (vector<ColorPair>::const_iterator cit = color.begin();
326                 cit != color.end(); ++cit) {
327                 colorCO->addItem(cit->first);
328         }
329         for (vector<LanguagePair>::const_iterator cit = language.begin();
330                 cit != language.end(); ++cit) {
331                 langCO->addItem(toqstr(cit->first));
332         }
333
334         bc().setPolicy(ButtonPolicy::OkApplyCancelReadOnlyPolicy);
335         bc().setOK(okPB);
336         bc().setApply(applyPB);
337         bc().setCancel(closePB);
338         bc().addReadOnly(familyCO);
339         bc().addReadOnly(seriesCO);
340         bc().addReadOnly(sizeCO);
341         bc().addReadOnly(shapeCO);
342         bc().addReadOnly(miscCO);
343         bc().addReadOnly(langCO);
344         bc().addReadOnly(colorCO);
345         bc().addReadOnly(toggleallCB);
346         bc().addReadOnly(autoapplyCB);
347
348 // FIXME: hack to work around resizing bug in Qt >= 4.2
349 // bug verified with Qt 4.2.{0-3} (JSpitzm)
350 #if QT_VERSION >= 0x040200
351         // qt resizes the comboboxes only after show(), so ...
352         QDialog::show();
353 #endif
354 }
355
356
357 void GuiCharacter::change_adaptor()
358 {
359         changed();
360
361         if (!autoapplyCB->isChecked())
362                 return;
363
364         // to be really good here, we should set the combos to the values of
365         // the current text, and make it appear as "no change" if the values
366         // stay the same between applys. Might be difficult though wrt to a
367         // moved cursor - jbl
368         slotApply();
369         familyCO->setCurrentIndex(0);
370         seriesCO->setCurrentIndex(0);
371         sizeCO->setCurrentIndex(0);
372         shapeCO->setCurrentIndex(0);
373         miscCO->setCurrentIndex(0);
374         langCO->setCurrentIndex(0);
375         colorCO->setCurrentIndex(0);
376 }
377
378
379 void GuiCharacter::closeEvent(QCloseEvent * e)
380 {
381         slotClose();
382         GuiDialog::closeEvent(e);
383 }
384
385
386 template<class A, class B>
387 static int findPos2nd(vector<std::pair<A, B> > const & vec, B const & val)
388 {
389         typedef typename vector<std::pair<A, B> >::const_iterator
390                 const_iterator;
391
392         for (const_iterator cit = vec.begin(); cit != vec.end(); ++cit)
393                 if (cit->second == val)
394                         return int(cit - vec.begin());
395
396         return 0;
397 }
398
399
400 void GuiCharacter::updateContents()
401 {
402         familyCO->setCurrentIndex(findPos2nd(family, getFamily()));
403         seriesCO->setCurrentIndex(findPos2nd(series, getSeries()));
404         shapeCO->setCurrentIndex(findPos2nd(shape, getShape()));
405         sizeCO->setCurrentIndex(findPos2nd(size, getSize()));
406         miscCO->setCurrentIndex(findPos2nd(bar, getBar()));
407         colorCO->setCurrentIndex(findPos2nd(color, getColor()));
408         langCO->setCurrentIndex(findPos2nd(language, getLanguage()));
409
410         toggleallCB->setChecked(getToggleAll());
411 }
412
413
414 void GuiCharacter::applyView()
415 {
416         setFamily(family[familyCO->currentIndex()].second);
417         setSeries(series[seriesCO->currentIndex()].second);
418         setShape(shape[shapeCO->currentIndex()].second);
419         setSize(size[sizeCO->currentIndex()].second);
420         setBar(bar[miscCO->currentIndex()].second);
421         setColor(color[colorCO->currentIndex()].second);
422         setLanguage(language[langCO->currentIndex()].second);
423
424         setToggleAll(toggleallCB->isChecked());
425 }
426
427
428 bool GuiCharacter::initialiseParams(string const &)
429 {
430         // so that the user can press Ok
431         if (getFamily()    != Font::IGNORE_FAMILY
432             || getSeries() != Font::IGNORE_SERIES
433             || getShape()  != Font::IGNORE_SHAPE
434             || getSize()   != Font::IGNORE_SIZE
435             || getBar()    != IGNORE
436             || getColor()  != Color::ignore
437             || font_.language() != ignore_language)
438                 dialog().setButtonsValid(true);
439
440         return true;
441 }
442
443
444 void GuiCharacter::dispatchParams()
445 {
446         dispatch(FuncRequest(getLfun(), font_.toString(toggleall_)));
447 }
448
449
450 Font::FONT_FAMILY GuiCharacter::getFamily() const
451 {
452         return font_.family();
453 }
454
455
456 void GuiCharacter::setFamily(Font::FONT_FAMILY val)
457 {
458         font_.setFamily(val);
459 }
460
461
462 Font::FONT_SERIES GuiCharacter::getSeries() const
463 {
464         return font_.series();
465 }
466
467
468 void GuiCharacter::setSeries(Font::FONT_SERIES val)
469 {
470         font_.setSeries(val);
471 }
472
473
474 Font::FONT_SHAPE GuiCharacter::getShape() const
475 {
476         return font_.shape();
477 }
478
479
480 void GuiCharacter::setShape(Font::FONT_SHAPE val)
481 {
482         font_.setShape(val);
483 }
484
485
486 Font::FONT_SIZE GuiCharacter::getSize() const
487 {
488         return font_.size();
489 }
490
491
492 void GuiCharacter::setSize(Font::FONT_SIZE val)
493 {
494         font_.setSize(val);
495 }
496
497
498 FontState GuiCharacter::getBar() const
499 {
500         if (font_.emph() == Font::TOGGLE)
501                 return EMPH_TOGGLE;
502
503         if (font_.underbar() == Font::TOGGLE)
504                 return UNDERBAR_TOGGLE;
505
506         if (font_.noun() == Font::TOGGLE)
507                 return NOUN_TOGGLE;
508
509         if (font_.emph() == Font::IGNORE
510             && font_.underbar() == Font::IGNORE
511             && font_.noun() == Font::IGNORE)
512                 return IGNORE;
513
514         return INHERIT;
515 }
516
517
518 void GuiCharacter::setBar(FontState val)
519 {
520         switch (val) {
521         case IGNORE:
522                 font_.setEmph(Font::IGNORE);
523                 font_.setUnderbar(Font::IGNORE);
524                 font_.setNoun(Font::IGNORE);
525                 break;
526
527         case EMPH_TOGGLE:
528                 font_.setEmph(Font::TOGGLE);
529                 break;
530
531         case UNDERBAR_TOGGLE:
532                 font_.setUnderbar(Font::TOGGLE);
533                 break;
534
535         case NOUN_TOGGLE:
536                 font_.setNoun(Font::TOGGLE);
537                 break;
538
539         case INHERIT:
540                 font_.setEmph(Font::INHERIT);
541                 font_.setUnderbar(Font::INHERIT);
542                 font_.setNoun(Font::INHERIT);
543                 break;
544         }
545 }
546
547
548 Color_color GuiCharacter::getColor() const
549 {
550         return font_.color();
551 }
552
553
554 void GuiCharacter::setColor(Color_color val)
555 {
556         switch (val) {
557         case Color::ignore:
558         case Color::none:
559         case Color::black:
560         case Color::white:
561         case Color::red:
562         case Color::green:
563         case Color::blue:
564         case Color::cyan:
565         case Color::magenta:
566         case Color::yellow:
567         case Color::inherit:
568                 font_.setColor(val);
569                 break;
570         default:
571                 break;
572         }
573 }
574
575
576 string GuiCharacter::getLanguage() const
577 {
578         if (reset_lang_)
579                 return "reset";
580         if (font_.language())
581                 return font_.language()->lang();
582         return "ignore";
583 }
584
585
586 void GuiCharacter::setLanguage(string const & val)
587 {
588         if (val == "ignore")
589                 font_.setLanguage(ignore_language);
590         else if (val == "reset") {
591                 reset_lang_ = true;
592                 // Ignored in getLanguage, but needed for dispatchParams
593                 font_.setLanguage(buffer().params().language);
594         } else {
595                 font_.setLanguage(languages.getLanguage(val));
596         }
597 }
598
599
600 bool GuiCharacter::getToggleAll() const
601 {
602         return toggleall_;
603 }
604
605
606 void GuiCharacter::setToggleAll(bool t)
607 {
608         toggleall_ = t;
609 }
610
611
612 Dialog * createGuiCharacter(LyXView & lv) { return new GuiCharacter(lv); }
613
614
615 } // namespace frontend
616 } // namespace lyx
617
618 #include "GuiCharacter_moc.cpp"