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