]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiCharacter.cpp
header cleanup
[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 "Font.h"
19 #include "Buffer.h"
20 #include "BufferParams.h"
21 #include "FuncRequest.h"
22 #include "Language.h"
23
24
25 using namespace std;
26
27 namespace lyx {
28 namespace frontend {
29
30 static vector<ShapePair> const getShapeData()
31 {
32         vector<ShapePair> shape(6);
33
34         ShapePair pr;
35
36         pr.first = qt_("No change");
37         pr.second = IGNORE_SHAPE;
38         shape[0] = pr;
39
40         pr.first = qt_("Upright");
41         pr.second = UP_SHAPE;
42         shape[1] = pr;
43
44         pr.first = qt_("Italic");
45         pr.second = ITALIC_SHAPE;
46         shape[2] = pr;
47
48         pr.first = qt_("Slanted");
49         pr.second = SLANTED_SHAPE;
50         shape[3] = pr;
51
52         pr.first = qt_("Small Caps");
53         pr.second = SMALLCAPS_SHAPE;
54         shape[4] = pr;
55
56         pr.first = qt_("Reset");
57         pr.second = INHERIT_SHAPE;
58         shape[5] = pr;
59
60         return shape;
61 }
62
63
64 static vector<SizePair> const getSizeData()
65 {
66         vector<SizePair> size(14);
67
68         SizePair pr;
69
70         pr.first = qt_("No change");
71         pr.second = FONT_SIZE_IGNORE;
72         size[0] = pr;
73
74         pr.first = qt_("Tiny");
75         pr.second = FONT_SIZE_TINY;
76         size[1] = pr;
77
78         pr.first = qt_("Smallest");
79         pr.second = FONT_SIZE_SCRIPT;
80         size[2] = pr;
81
82         pr.first = qt_("Smaller");
83         pr.second = FONT_SIZE_FOOTNOTE;
84         size[3] = pr;
85
86         pr.first = qt_("Small");
87         pr.second = FONT_SIZE_SMALL;
88         size[4] = pr;
89
90         pr.first = qt_("Normal");
91         pr.second = FONT_SIZE_NORMAL;
92         size[5] = pr;
93
94         pr.first = qt_("Large");
95         pr.second = FONT_SIZE_LARGE;
96         size[6] = pr;
97
98         pr.first = qt_("Larger");
99         pr.second = FONT_SIZE_LARGER;
100         size[7] = pr;
101
102         pr.first = qt_("Largest");
103         pr.second = FONT_SIZE_LARGEST;
104         size[8] = pr;
105
106         pr.first = qt_("Huge");
107         pr.second = FONT_SIZE_HUGE;
108         size[9] = pr;
109
110         pr.first = qt_("Huger");
111         pr.second = FONT_SIZE_HUGER;
112         size[10] = pr;
113
114         pr.first = qt_("Increase");
115         pr.second = FONT_SIZE_INCREASE;
116         size[11] = pr;
117
118         pr.first = qt_("Decrease");
119         pr.second = FONT_SIZE_DECREASE;
120         size[12] = pr;
121
122         pr.first = qt_("Reset");
123         pr.second = FONT_SIZE_INHERIT;
124         size[13] = pr;
125
126         return size;
127 }
128
129
130 static vector<BarPair> const getBarData()
131 {
132         vector<BarPair> bar(5);
133
134         BarPair pr;
135
136         pr.first = qt_("No change");
137         pr.second = IGNORE;
138         bar[0] = pr;
139
140         pr.first = qt_("Emph");
141         pr.second = EMPH_TOGGLE;
142         bar[1] = pr;
143
144         pr.first = qt_("Underbar");
145         pr.second = UNDERBAR_TOGGLE;
146         bar[2] = pr;
147
148         pr.first = qt_("Noun");
149         pr.second = NOUN_TOGGLE;
150         bar[3] = pr;
151
152         pr.first = qt_("Reset");
153         pr.second = INHERIT;
154         bar[4] = pr;
155
156         return bar;
157 }
158
159
160 static vector<ColorPair> const getColorData()
161 {
162         vector<ColorPair> color(11);
163
164         ColorPair pr;
165
166         pr.first = qt_("No change");
167         pr.second = Color_ignore;
168         color[0] = pr;
169
170         pr.first = qt_("No color");
171         pr.second = Color_none;
172         color[1] = pr;
173
174         pr.first = qt_("Black");
175         pr.second = Color_black;
176         color[2] = pr;
177
178         pr.first = qt_("White");
179         pr.second = Color_white;
180         color[3] = pr;
181
182         pr.first = qt_("Red");
183         pr.second = Color_red;
184         color[4] = pr;
185
186         pr.first = qt_("Green");
187         pr.second = Color_green;
188         color[5] = pr;
189
190         pr.first = qt_("Blue");
191         pr.second = Color_blue;
192         color[6] = pr;
193
194         pr.first = qt_("Cyan");
195         pr.second = Color_cyan;
196         color[7] = pr;
197
198         pr.first = qt_("Magenta");
199         pr.second = Color_magenta;
200         color[8] = pr;
201
202         pr.first = qt_("Yellow");
203         pr.second = Color_yellow;
204         color[9] = pr;
205
206         pr.first = qt_("Reset");
207         pr.second = Color_inherit;
208         color[10] = pr;
209
210         return color;
211 }
212
213
214 static vector<SeriesPair> const getSeriesData()
215 {
216         vector<SeriesPair> series(4);
217
218         SeriesPair pr;
219
220         pr.first = qt_("No change");
221         pr.second = IGNORE_SERIES;
222         series[0] = pr;
223
224         pr.first = qt_("Medium");
225         pr.second = MEDIUM_SERIES;
226         series[1] = pr;
227
228         pr.first = qt_("Bold");
229         pr.second = BOLD_SERIES;
230         series[2] = pr;
231
232         pr.first = qt_("Reset");
233         pr.second = INHERIT_SERIES;
234         series[3] = pr;
235
236         return series;
237 }
238
239
240 static vector<FamilyPair> const getFamilyData()
241 {
242         vector<FamilyPair> family(5);
243
244         FamilyPair pr;
245
246         pr.first = qt_("No change");
247         pr.second = IGNORE_FAMILY;
248         family[0] = pr;
249
250         pr.first = qt_("Roman");
251         pr.second = ROMAN_FAMILY;
252         family[1] = pr;
253
254         pr.first = qt_("Sans Serif");
255         pr.second = SANS_FAMILY;
256         family[2] = pr;
257
258         pr.first = qt_("Typewriter");
259         pr.second = TYPEWRITER_FAMILY;
260         family[3] = pr;
261
262         pr.first = qt_("Reset");
263         pr.second = INHERIT_FAMILY;
264         family[4] = pr;
265
266         return family;
267 }
268
269
270 GuiCharacter::GuiCharacter(GuiView & lv)
271         : GuiDialog(lv, "character", qt_("Text Style")), font_(ignore_font),
272           toggleall_(false), reset_lang_(false)
273 {
274         setupUi(this);
275
276         connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
277         connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
278         connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
279
280         connect(miscCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
281         connect(sizeCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
282         connect(familyCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
283         connect(seriesCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
284         connect(shapeCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
285         connect(colorCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
286         connect(langCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
287         connect(toggleallCB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
288
289 #ifdef Q_WS_MACX
290         // On Mac it's common to have tool windows which are always in the
291         // foreground and are hidden when the main window is not focused.
292         setWindowFlags(Qt::Tool);
293         autoapplyCB->setChecked(true);
294 #endif
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 template<class A, class B>
380 static int findPos2nd(vector<pair<A, B> > const & vec, B const & val)
381 {
382         typedef typename vector<pair<A, B> >::const_iterator
383                 const_iterator;
384
385         for (const_iterator cit = vec.begin(); cit != vec.end(); ++cit)
386                 if (cit->second == val)
387                         return int(cit - vec.begin());
388
389         return 0;
390 }
391
392
393 void GuiCharacter::updateContents()
394 {
395         familyCO->setCurrentIndex(findPos2nd(family, getFamily()));
396         seriesCO->setCurrentIndex(findPos2nd(series, getSeries()));
397         shapeCO->setCurrentIndex(findPos2nd(shape, getShape()));
398         sizeCO->setCurrentIndex(findPos2nd(size, getSize()));
399         miscCO->setCurrentIndex(findPos2nd(bar, getBar()));
400         colorCO->setCurrentIndex(findPos2nd(color, getColor()));
401         langCO->setCurrentIndex(findPos2nd(language, getLanguage()));
402
403         toggleallCB->setChecked(toggleall_);
404 }
405
406
407 void GuiCharacter::applyView()
408 {
409         setFamily(family[familyCO->currentIndex()].second);
410         setSeries(series[seriesCO->currentIndex()].second);
411         setShape(shape[shapeCO->currentIndex()].second);
412         setSize(size[sizeCO->currentIndex()].second);
413         setBar(bar[miscCO->currentIndex()].second);
414         setColor(color[colorCO->currentIndex()].second);
415         setLanguage(language[langCO->currentIndex()].second);
416
417         toggleall_ = toggleallCB->isChecked();
418 }
419
420
421 bool GuiCharacter::initialiseParams(string const &)
422 {
423         // so that the user can press Ok
424         if (getFamily()    != IGNORE_FAMILY
425             || getSeries() != IGNORE_SERIES
426             || getShape()  != IGNORE_SHAPE
427             || getSize()   != FONT_SIZE_IGNORE
428             || getBar()    != IGNORE
429             || getColor()  != Color_ignore
430             || font_.language() != ignore_language)
431                 setButtonsValid(true);
432
433         return true;
434 }
435
436
437 void GuiCharacter::dispatchParams()
438 {
439         dispatch(FuncRequest(getLfun(), font_.toString(toggleall_)));
440 }
441
442
443 FontFamily GuiCharacter::getFamily() const
444 {
445         return font_.fontInfo().family();
446 }
447
448
449 void GuiCharacter::setFamily(FontFamily val)
450 {
451         font_.fontInfo().setFamily(val);
452 }
453
454
455 FontSeries GuiCharacter::getSeries() const
456 {
457         return font_.fontInfo().series();
458 }
459
460
461 void GuiCharacter::setSeries(FontSeries val)
462 {
463         font_.fontInfo().setSeries(val);
464 }
465
466
467 FontShape GuiCharacter::getShape() const
468 {
469         return font_.fontInfo().shape();
470 }
471
472
473 void GuiCharacter::setShape(FontShape val)
474 {
475         font_.fontInfo().setShape(val);
476 }
477
478
479 FontSize GuiCharacter::getSize() const
480 {
481         return font_.fontInfo().size();
482 }
483
484
485 void GuiCharacter::setSize(FontSize val)
486 {
487         font_.fontInfo().setSize(val);
488 }
489
490
491 FontState GuiCharacter::getBar() const
492 {
493         if (font_.fontInfo().emph() == FONT_TOGGLE)
494                 return EMPH_TOGGLE;
495
496         if (font_.fontInfo().underbar() == FONT_TOGGLE)
497                 return UNDERBAR_TOGGLE;
498
499         if (font_.fontInfo().noun() == FONT_TOGGLE)
500                 return NOUN_TOGGLE;
501
502         if (font_.fontInfo().emph() == FONT_IGNORE
503             && font_.fontInfo().underbar() == FONT_IGNORE
504             && font_.fontInfo().noun() == FONT_IGNORE)
505                 return IGNORE;
506
507         return INHERIT;
508 }
509
510
511 void GuiCharacter::setBar(FontState val)
512 {
513         switch (val) {
514         case IGNORE:
515                 font_.fontInfo().setEmph(FONT_IGNORE);
516                 font_.fontInfo().setUnderbar(FONT_IGNORE);
517                 font_.fontInfo().setNoun(FONT_IGNORE);
518                 break;
519
520         case EMPH_TOGGLE:
521                 font_.fontInfo().setEmph(FONT_TOGGLE);
522                 break;
523
524         case UNDERBAR_TOGGLE:
525                 font_.fontInfo().setUnderbar(FONT_TOGGLE);
526                 break;
527
528         case NOUN_TOGGLE:
529                 font_.fontInfo().setNoun(FONT_TOGGLE);
530                 break;
531
532         case INHERIT:
533                 font_.fontInfo().setEmph(FONT_INHERIT);
534                 font_.fontInfo().setUnderbar(FONT_INHERIT);
535                 font_.fontInfo().setNoun(FONT_INHERIT);
536                 break;
537         }
538 }
539
540
541 ColorCode GuiCharacter::getColor() const
542 {
543         return font_.fontInfo().color();
544 }
545
546
547 void GuiCharacter::setColor(ColorCode val)
548 {
549         switch (val) {
550         case Color_ignore:
551         case Color_none:
552         case Color_black:
553         case Color_white:
554         case Color_red:
555         case Color_green:
556         case Color_blue:
557         case Color_cyan:
558         case Color_magenta:
559         case Color_yellow:
560         case Color_inherit:
561                 font_.fontInfo().setColor(val);
562                 break;
563         default:
564                 break;
565         }
566 }
567
568
569 string GuiCharacter::getLanguage() const
570 {
571         if (reset_lang_)
572                 return "reset";
573         if (font_.language())
574                 return font_.language()->lang();
575         return "ignore";
576 }
577
578
579 void GuiCharacter::setLanguage(string const & val)
580 {
581         if (val == "ignore")
582                 font_.setLanguage(ignore_language);
583         else if (val == "reset") {
584                 reset_lang_ = true;
585                 // Ignored in getLanguage, but needed for dispatchParams
586                 font_.setLanguage(buffer().params().language);
587         } else {
588                 font_.setLanguage(languages.getLanguage(val));
589         }
590 }
591
592
593 Dialog * createGuiCharacter(GuiView & lv) { return new GuiCharacter(lv); }
594
595
596 } // namespace frontend
597 } // namespace lyx
598
599 #include "GuiCharacter_moc.cpp"