]> git.lyx.org Git - features.git/blob - src/frontends/qt/GuiCharacter.cpp
Move <algorithm> from DocIterator.h
[features.git] / src / frontends / qt / 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  * \author Jürgen Spitzmüller
10  *
11  * Full author contact details are available in file CREDITS.
12  */
13
14 #include <config.h>
15
16 #include "GuiCharacter.h"
17
18 #include "GuiApplication.h"
19 #include "qt_helpers.h"
20
21 #include "Font.h"
22 #include "Buffer.h"
23 #include "BufferParams.h"
24 #include "BufferView.h"
25 #include "Color.h"
26 #include "ColorCache.h"
27 #include "ColorSet.h"
28 #include "Cursor.h"
29 #include "FuncRequest.h"
30 #include "Language.h"
31 #include "Paragraph.h"
32
33 #include "support/gettext.h"
34 #include "support/lstrings.h"
35
36 #include <QAbstractItemModel>
37 #include <QPushButton>
38 #include <QComboBox>
39 #include <QMenu>
40 #include <QModelIndex>
41 #include <QSettings>
42 #include <QVariant>
43
44 #include <algorithm>
45
46 using namespace std;
47
48 namespace lyx {
49 namespace frontend {
50
51 static QList<ShapePair> shapeData()
52 {
53         QList<ShapePair> shapes;
54         shapes << ShapePair(qt_("No change"), IGNORE_SHAPE);
55         shapes << ShapePair(qt_("Default"), INHERIT_SHAPE);
56         shapes << ShapePair(qt_("Upright"), UP_SHAPE);
57         shapes << ShapePair(qt_("Italic"), ITALIC_SHAPE);
58         shapes << ShapePair(qt_("Slanted"), SLANTED_SHAPE);
59         shapes << ShapePair(qt_("Small Caps"), SMALLCAPS_SHAPE);
60         return shapes;
61 }
62
63
64 static QList<SizePair> sizeData()
65 {
66         QList<SizePair> sizes;
67         sizes << SizePair(qt_("No change"), IGNORE_SIZE);
68         sizes << SizePair(qt_("Default"), INHERIT_SIZE);
69         sizes << SizePair(qt_("Tiny"), TINY_SIZE);
70         sizes << SizePair(qt_("Smallest"), SCRIPT_SIZE);
71         sizes << SizePair(qt_("Smaller"), FOOTNOTE_SIZE);
72         sizes << SizePair(qt_("Small"), SMALL_SIZE);
73         sizes << SizePair(qt_("Normal"), NORMAL_SIZE);
74         sizes << SizePair(qt_("Large"), LARGE_SIZE);
75         sizes << SizePair(qt_("Larger"), LARGER_SIZE);
76         sizes << SizePair(qt_("Largest"), LARGEST_SIZE);
77         sizes << SizePair(qt_("Huge"), HUGE_SIZE);
78         sizes << SizePair(qt_("Huger"), HUGER_SIZE);
79         sizes << SizePair(qt_("Increase"), INCREASE_SIZE);
80         sizes << SizePair(qt_("Decrease"), DECREASE_SIZE);
81         return sizes;
82 }
83
84
85 static QList<BarPair> barData()
86 {
87         QList<BarPair> bars;
88         bars << BarPair(qt_("No change"), IGNORE);
89         bars << BarPair(qt_("Default"), INHERIT);
90         bars << BarPair(qt_("(Without)[[underlining]]"), NONE);
91         bars << BarPair(qt_("Single[[underlining]]"), UNDERBAR);
92         bars << BarPair(qt_("Double[[underlining]]"), UULINE);
93         bars << BarPair(qt_("Wavy"), UWAVE);
94         return bars;
95 }
96
97
98 static QList<BarPair> strikeData()
99 {
100         QList<BarPair> strike;
101         strike << BarPair(qt_("No change"), IGNORE);
102         strike << BarPair(qt_("Default"), INHERIT);
103         strike << BarPair(qt_("(Without)[[strikethrough]]"), NONE);
104         strike << BarPair(qt_("Single[[strikethrough]]"), STRIKEOUT);
105         strike << BarPair(qt_("With /"), XOUT);
106         return strike;
107 }
108
109
110 static QList<ColorCode> colorData()
111 {
112         QList<ColorCode> colors;
113         colors << Color_black;
114         colors << Color_blue;
115         colors << Color_brown;
116         colors << Color_cyan;
117         colors << Color_darkgray;
118         colors << Color_gray;
119         colors << Color_green;
120         colors << Color_lightgray;
121         colors << Color_lime;
122         colors << Color_magenta;
123         colors << Color_olive;
124         colors << Color_orange;
125         colors << Color_pink;
126         colors << Color_purple;
127         colors << Color_red;
128         colors << Color_teal;
129         colors << Color_violet;
130         colors << Color_white;
131         colors << Color_yellow;
132         return colors;
133 }
134
135
136 static QList<SeriesPair> seriesData()
137 {
138         QList<SeriesPair> series;
139         series << SeriesPair(qt_("No change"), IGNORE_SERIES);
140         series << SeriesPair(qt_("Default"),     INHERIT_SERIES);
141         series << SeriesPair(qt_("Medium"),    MEDIUM_SERIES);
142         series << SeriesPair(qt_("Bold"),      BOLD_SERIES);
143         return series;
144 }
145
146
147 static QList<FamilyPair> familyData()
148 {
149         QList<FamilyPair> families;
150         families << FamilyPair(qt_("No change"),  IGNORE_FAMILY);
151         families << FamilyPair(qt_("Default"),      INHERIT_FAMILY);
152         families << FamilyPair(qt_("Roman"),      ROMAN_FAMILY);
153         families << FamilyPair(qt_("Sans Serif"), SANS_FAMILY);
154         families << FamilyPair(qt_("Typewriter"), TYPEWRITER_FAMILY);
155         return families;
156 }
157
158
159 static QList<LanguagePair> languageData()
160 {
161         QList<LanguagePair> list;
162         // FIXME (Abdel 14/05/2008): it would be nice if we could use this model
163         // directly in the language combo; but, as we need also the 'No Change' and
164         // 'Default' items, this is not possible right now. Separating those two
165         // entries in radio buttons would be a better GUI IMHO.
166         QAbstractItemModel * language_model = guiApp->languageModel();
167         // Make sure the items are sorted.
168         language_model->sort(0);
169
170         for (int i = 0; i != language_model->rowCount(); ++i) {
171                 QModelIndex index = language_model->index(i, 0);
172                 list << LanguagePair(index.data(Qt::DisplayRole).toString(),
173                         index.data(Qt::UserRole).toString());
174         }
175         return list;
176 }
177
178
179 namespace {
180
181 template<typename T>
182 void fillCombo(QComboBox * combo, QList<T> const & list)
183 {
184         typename QList<T>::const_iterator cit = list.begin();
185         for (; cit != list.end(); ++cit)
186                 combo->addItem(cit->first);
187 }
188
189 template<typename T>
190 void fillComboColor(QComboBox * combo, QList<T> const & list)
191 {
192         // at first add the 2 colors "No change" and "No color"
193         combo->addItem(qt_("No change"), "ignore");
194         combo->addItem(qt_("Default"), "inherit");
195         combo->addItem(qt_("(Without)[[color]]"), "none");
196         // now add the real colors
197         QPixmap coloritem(32, 32);
198         QColor color;
199         QList<ColorCode>::const_iterator cit = list.begin();
200         for (; cit != list.end(); ++cit) {
201                 QString const lyxname = toqstr(lcolor.getLyXName(*cit));
202                 QString const guiname = toqstr(translateIfPossible(lcolor.getGUIName(*cit)));
203                 color = QColor(guiApp->colorCache().get(*cit, false));
204                 coloritem.fill(color);
205                 combo->addItem(QIcon(coloritem), guiname, lyxname);
206         }
207 }
208
209 } // namespace
210
211 GuiCharacter::GuiCharacter(GuiView & lv)
212         : GuiDialog(lv, "character", qt_("Text Properties")),
213           font_(ignore_font, ignore_language),
214           emph_(false), noun_(false), nospellcheck_(false)
215 {
216         setupUi(this);
217
218         // fix height to minimum
219         setFixedHeight(sizeHint().height());
220
221         connect(buttonBox, SIGNAL(clicked(QAbstractButton *)),
222                 this, SLOT(slotButtonBox(QAbstractButton *)));
223         connect(autoapplyCB, SIGNAL(stateChanged(int)), this,
224                 SLOT(slotAutoApply()));
225
226         connect(ulineCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
227         connect(strikeCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
228         connect(sizeCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
229         connect(familyCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
230         connect(seriesCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
231         connect(shapeCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
232         connect(colorCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
233         connect(langCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
234
235         family = familyData();
236         series = seriesData();
237         shape  = shapeData();
238         size   = sizeData();
239         bar    = barData();
240         strike = strikeData();
241         color  = colorData();
242         sort(color.begin(), color.end(), ColorSorter);
243
244         language = languageData();
245         language.prepend(LanguagePair(qt_("Default"), "reset"));
246         language.prepend(LanguagePair(qt_("No change"), "ignore"));
247
248         fillCombo(familyCO, family);
249         fillCombo(seriesCO, series);
250         fillCombo(sizeCO, size);
251         fillCombo(shapeCO, shape);
252         fillCombo(ulineCO, bar);
253         fillCombo(strikeCO, strike);
254         fillComboColor(colorCO, color);
255         fillCombo(langCO, language);
256
257         bc().setPolicy(ButtonPolicy::OkApplyCancelAutoReadOnlyPolicy);
258         bc().setOK(buttonBox->button(QDialogButtonBox::Ok));
259         bc().setApply(buttonBox->button(QDialogButtonBox::Apply));
260         bc().setCancel(buttonBox->button(QDialogButtonBox::Cancel));
261         bc().setRestore(buttonBox->button(QDialogButtonBox::Reset));
262         bc().setAutoApply(autoapplyCB);
263         bc().addReadOnly(familyCO);
264         bc().addReadOnly(seriesCO);
265         bc().addReadOnly(sizeCO);
266         bc().addReadOnly(shapeCO);
267         bc().addReadOnly(ulineCO);
268         bc().addReadOnly(strikeCO);
269         bc().addReadOnly(nounCB);
270         bc().addReadOnly(emphCB);
271         bc().addReadOnly(nospellcheckCB);
272         bc().addReadOnly(langCO);
273         bc().addReadOnly(colorCO);
274         bc().addReadOnly(autoapplyCB);
275
276         // Add button menu to restore button to reset
277         // all widgets to "Defaults" or "No Change"
278         resetdefault_ = new QAction(qt_("Reset All To &Default"), this);
279         resetnochange_ = new QAction(qt_("Reset All To No Chan&ge"), this);
280         QMenu * resetmenu = new QMenu();
281         resetmenu->addAction(resetdefault_);
282         resetmenu->addAction(resetnochange_);
283         buttonBox->button(QDialogButtonBox::RestoreDefaults)->setMenu(resetmenu);
284         buttonBox->button(QDialogButtonBox::RestoreDefaults)->setText(qt_("&Reset All Fields"));
285         connect(resetdefault_, SIGNAL(triggered()), this, SLOT(resetToDefault()));
286         connect(resetnochange_, SIGNAL(triggered()), this, SLOT(resetToNoChange()));
287
288 #ifdef Q_OS_MAC
289         // On Mac it's common to have tool windows which are always in the
290         // foreground and are hidden when the main window is not focused.
291         setWindowFlags(Qt::Tool);
292         autoapplyCB->setChecked(true);
293 #endif
294 }
295
296
297 void GuiCharacter::on_emphCB_clicked()
298 {
299         // skip intermediate state at user click
300         if (!emph_) {
301                 emphCB->setCheckState(Qt::Checked);
302                 emph_ = true;
303         }
304         change_adaptor();
305 }
306
307
308 void GuiCharacter::on_nounCB_clicked()
309 {
310         // skip intermediate state at user click
311         if (!noun_) {
312                 nounCB->setCheckState(Qt::Checked);
313                 noun_ = true;
314         }
315         change_adaptor();
316 }
317
318
319 void GuiCharacter::on_nospellcheckCB_clicked()
320 {
321         // skip intermediate state at user click
322         if (!nospellcheck_) {
323                 nospellcheckCB->setCheckState(Qt::Checked);
324                 nospellcheck_ = true;
325         }
326         change_adaptor();
327 }
328
329
330 void GuiCharacter::resetToDefault()
331 {
332         Font font(inherit_font);
333         font.setLanguage(reset_language);
334         paramsToDialog(font);
335         change_adaptor();
336 }
337
338
339 void GuiCharacter::resetToNoChange()
340 {
341         Font font(ignore_font);
342         font.setLanguage(ignore_language);
343         paramsToDialog(font);
344         change_adaptor();
345 }
346
347
348 template<class P, class B>
349 static int findPos2nd(QList<P> const & vec, B const & val)
350 {
351         for (int i = 0; i != vec.size(); ++i)
352                 if (vec[i].second == val)
353                         return i;
354         return 0;
355 }
356
357
358 namespace{
359 FontDeco getBar(FontInfo const & fi)
360 {
361         if (fi.underbar() == FONT_ON)
362                 return UNDERBAR;
363
364         if (fi.uuline() == FONT_ON)
365                 return UULINE;
366
367         if (fi.uwave() == FONT_ON)
368                 return UWAVE;
369
370         if (fi.underbar() == FONT_IGNORE)
371                 return IGNORE;
372
373         if (fi.underbar() == FONT_INHERIT)
374                 return INHERIT;
375
376         return NONE;
377 }
378
379
380 FontDeco getStrike(FontInfo const & fi)
381 {
382         if (fi.strikeout() == FONT_ON)
383                 return STRIKEOUT;
384
385         if (fi.xout() == FONT_ON)
386                 return XOUT;
387
388         if (fi.strikeout() == FONT_IGNORE)
389                 return IGNORE;
390
391         if (fi.strikeout() == FONT_INHERIT)
392                 return INHERIT;
393
394         return NONE;
395 }
396
397
398 Qt::CheckState getMarkupState(lyx::FontState fs)
399 {
400         switch (fs) {
401         case FONT_INHERIT:
402         case FONT_OFF:
403                 return Qt::Unchecked;
404         case FONT_ON:
405                 return Qt::Checked;
406         case FONT_TOGGLE:
407         case FONT_IGNORE:
408         default:
409                 return Qt::PartiallyChecked;
410         }
411 }
412
413 lyx::FontState setMarkupState(Qt::CheckState cs)
414 {
415         switch (cs) {
416         case Qt::Unchecked:
417                 return FONT_OFF;
418         case Qt::Checked:
419                 return FONT_ON;
420         case Qt::PartiallyChecked:
421         default:
422                 return FONT_IGNORE;
423         }
424 }
425
426 } // end namespace anon
427
428
429 void GuiCharacter::change_adaptor()
430 {
431         changed();
432
433         checkRestoreDefaults();
434
435         if (!autoapplyCB->isChecked())
436                 return;
437
438         // to be really good here, we should set the combos to the values of
439         // the current text, and make it appear as "no change" if the values
440         // stay the same between applies. Might be difficult though wrt to a
441         // moved cursor - jbl
442         slotApply();
443 }
444
445
446 void GuiCharacter::checkRestoreDefaults()
447 {
448         if (familyCO->currentIndex() == -1 || seriesCO->currentIndex() == -1
449             || shapeCO->currentIndex() == -1 || sizeCO->currentIndex() == -1
450             || ulineCO->currentIndex() == -1 || strikeCO->currentIndex() == -1
451             || colorCO->currentIndex() == -1 || langCO->currentIndex() == -1)
452                 // dialog not yet built
453                 return;
454
455         // (De)Activate Restore Defaults menu items
456         resetdefault_->setEnabled(
457                 family[familyCO->currentIndex()].second != INHERIT_FAMILY
458                 || series[seriesCO->currentIndex()].second != INHERIT_SERIES
459                 || shape[shapeCO->currentIndex()].second != INHERIT_SHAPE
460                 || size[sizeCO->currentIndex()].second != INHERIT_SIZE
461                 || setMarkupState(emphCB->checkState()) != FONT_OFF
462                 || setMarkupState(nounCB->checkState()) != FONT_OFF
463                 || setMarkupState(nospellcheckCB->checkState()) != FONT_OFF
464                 || bar[ulineCO->currentIndex()].second != INHERIT
465                 || strike[strikeCO->currentIndex()].second != INHERIT
466                 || lcolor.getFromLyXName(fromqstr(colorCO->itemData(colorCO->currentIndex()).toString())) != Color_inherit
467                 || languages.getLanguage(fromqstr(language[langCO->currentIndex()].second)) != reset_language);
468
469         resetnochange_->setEnabled(
470                 family[familyCO->currentIndex()].second != IGNORE_FAMILY
471                 || series[seriesCO->currentIndex()].second != IGNORE_SERIES
472                 || shape[shapeCO->currentIndex()].second != IGNORE_SHAPE
473                 || size[sizeCO->currentIndex()].second != IGNORE_SIZE
474                 || setMarkupState(emphCB->checkState()) != FONT_IGNORE
475                 || setMarkupState(nounCB->checkState()) != FONT_IGNORE
476                 || setMarkupState(nospellcheckCB->checkState()) != FONT_IGNORE
477                 || bar[ulineCO->currentIndex()].second != IGNORE
478                 || strike[strikeCO->currentIndex()].second != IGNORE
479                 || lcolor.getFromLyXName(fromqstr(colorCO->itemData(colorCO->currentIndex()).toString())) != Color_ignore
480                 || languages.getLanguage(fromqstr(language[langCO->currentIndex()].second)) != ignore_language);
481 }
482
483
484 void GuiCharacter::updateContents()
485 {
486         if (bufferview()->cursor().selection()) {
487                 Font font = bufferview()->cursor().current_font;
488                 FontInfo fi = font.fontInfo();
489                 BufferParams const & bp = buffer().masterParams();
490
491                 // Check if each font attribute is constant for the selection range.
492                 DocIterator const from = bufferview()->cursor().selectionBegin();
493                 DocIterator const to = bufferview()->cursor().selectionEnd();
494                 for (DocIterator dit = from ; dit != to && !dit.atEnd(); ) {
495                         if (!dit.inTexted()) {
496                                 dit.forwardPos();
497                                 continue;
498                         }
499                         Paragraph const & par = dit.paragraph();
500                         pos_type const pos = dit.pos();
501                         Font tmp = par.getFontSettings(bp, pos);
502                         if (font.language() != tmp.language())
503                                 font.setLanguage(ignore_language);
504                         if (fi.family() != tmp.fontInfo().family())
505                                 font.fontInfo().setFamily(IGNORE_FAMILY);
506                         if (fi.series() != tmp.fontInfo().series())
507                                 font.fontInfo().setSeries(IGNORE_SERIES);
508                         if (fi.shape() != tmp.fontInfo().shape())
509                                 font.fontInfo().setShape(IGNORE_SHAPE);
510                         if (fi.size() != tmp.fontInfo().size())
511                                 font.fontInfo().setSize(IGNORE_SIZE);
512                         if (fi.emph() != tmp.fontInfo().emph())
513                                 font.fontInfo().setEmph(FONT_IGNORE);
514                         if (fi.noun() != tmp.fontInfo().noun())
515                                 font.fontInfo().setNoun(FONT_IGNORE);
516                         if (fi.nospellcheck() != tmp.fontInfo().nospellcheck())
517                                 font.fontInfo().setNoSpellcheck(FONT_IGNORE);
518                         if (fi.color() != tmp.fontInfo().color())
519                                 font.fontInfo().setColor(Color_ignore);
520                         if (fi.underbar() != tmp.fontInfo().underbar()
521                             || fi.uuline() != tmp.fontInfo().uuline()
522                             || fi.uwave() != tmp.fontInfo().uwave())
523                                 setBar(font.fontInfo(), IGNORE);
524                         if (fi.strikeout() != tmp.fontInfo().strikeout()
525                             || fi.xout() != tmp.fontInfo().xout())
526                                 setStrike(font.fontInfo(), IGNORE);
527                         dit.forwardPos();
528                 }
529                 font_ = font;
530         } else
531                 font_ = bufferview()->cursor().current_font;
532
533         // If we use the buffer language, display "Default"
534         if (font_.language() == buffer().params().language)
535                 font_.setLanguage(reset_language);
536
537         paramsToDialog(font_);
538
539         checkRestoreDefaults();
540 }
541
542
543 void GuiCharacter::setBar(FontInfo & fi, FontDeco val)
544 {
545         switch (val) {
546         case IGNORE:
547                 fi.setUnderbar(FONT_IGNORE);
548                 fi.setUuline(FONT_IGNORE);
549                 fi.setUwave(FONT_IGNORE);
550                 break;
551         case UNDERBAR:
552                 setBar(fi, NONE);
553                 fi.setUnderbar(FONT_ON);
554                 break;
555         case UULINE:
556                 setBar(fi, NONE);
557                 fi.setUuline(FONT_ON);
558                 break;
559         case UWAVE:
560                 setBar(fi, NONE);
561                 fi.setUwave(FONT_ON);
562                 break;
563         case INHERIT:
564                 fi.setUnderbar(FONT_INHERIT);
565                 fi.setUuline(FONT_INHERIT);
566                 fi.setUwave(FONT_INHERIT);
567                 break;
568         case NONE:
569                 fi.setUnderbar(FONT_OFF);
570                 fi.setUuline(FONT_OFF);
571                 fi.setUwave(FONT_OFF);
572                 break;
573         case XOUT:
574         case STRIKEOUT:
575         default:
576                 break;
577         }
578 }
579
580
581 void GuiCharacter::setStrike(FontInfo & fi, FontDeco val)
582 {
583         switch (val) {
584         case IGNORE:
585                 fi.setStrikeout(FONT_IGNORE);
586                 fi.setXout(FONT_IGNORE);
587                 break;
588         case STRIKEOUT:
589                 setStrike(fi, NONE);
590                 fi.setStrikeout(FONT_ON);
591                 break;
592         case XOUT:
593                 setStrike(fi, NONE);
594                 fi.setXout(FONT_ON);
595                 break;
596         case INHERIT:
597                 fi.setStrikeout(FONT_INHERIT);
598                 fi.setXout(FONT_INHERIT);
599                 break;
600         case NONE:
601                 fi.setStrikeout(FONT_OFF);
602                 fi.setXout(FONT_OFF);
603                 break;
604         case UNDERBAR:
605         case UWAVE:
606         case UULINE:
607         default:
608                 break;
609         }
610 }
611
612
613 void GuiCharacter::paramsToDialog(Font const & font)
614 {
615         FontInfo const & fi = font.fontInfo();
616         familyCO->setCurrentIndex(findPos2nd(family, fi.family()));
617         seriesCO->setCurrentIndex(findPos2nd(series, fi.series()));
618         shapeCO->setCurrentIndex(findPos2nd(shape, fi.shape()));
619         sizeCO->setCurrentIndex(findPos2nd(size, fi.size()));
620         ulineCO->setCurrentIndex(findPos2nd(bar, getBar(fi)));
621         strikeCO->setCurrentIndex(findPos2nd(strike, getStrike(fi)));
622         colorCO->setCurrentIndex(colorCO->findData(toqstr(lcolor.getLyXName(fi.color()))));
623         emphCB->setCheckState(getMarkupState(fi.emph()));
624         nounCB->setCheckState(getMarkupState(fi.noun()));
625         nospellcheckCB->setCheckState(getMarkupState(fi.nospellcheck()));
626         emph_ = emphCB->checkState() == Qt::Checked;
627         noun_ = nounCB->checkState() == Qt::Checked;
628         nospellcheck_ = nospellcheckCB->checkState() == Qt::Checked;
629
630         // reset_language is a null pointer.
631         QString const lang = (font.language() == reset_language)
632                 ? "reset" : toqstr(font.language()->lang());
633         langCO->setCurrentIndex(findPos2nd(language, lang));
634 }
635
636
637 void GuiCharacter::applyView()
638 {
639         FontInfo & fi = font_.fontInfo();
640         fi.setFamily(family[familyCO->currentIndex()].second);
641         fi.setSeries(series[seriesCO->currentIndex()].second);
642         fi.setShape(shape[shapeCO->currentIndex()].second);
643         fi.setSize(size[sizeCO->currentIndex()].second);
644         fi.setEmph(setMarkupState(emphCB->checkState()));
645         fi.setNoun(setMarkupState(nounCB->checkState()));
646         fi.setNoSpellcheck(setMarkupState(nospellcheckCB->checkState()));
647         setBar(fi, bar[ulineCO->currentIndex()].second);
648         setStrike(fi, strike[strikeCO->currentIndex()].second);
649         fi.setColor(lcolor.getFromLyXName(fromqstr(colorCO->itemData(colorCO->currentIndex()).toString())));
650
651         font_.setLanguage(languages.getLanguage(
652                 fromqstr(language[langCO->currentIndex()].second)));
653 }
654
655
656 bool GuiCharacter::initialiseParams(string const &)
657 {
658         if (autoapplyCB->isChecked())
659                 return true;
660
661         FontInfo & fi = font_.fontInfo();
662
663         // so that the user can press Ok
664         if (fi.family()    != IGNORE_FAMILY
665             || fi.series() != IGNORE_SERIES
666             || fi.shape()  != IGNORE_SHAPE
667             || fi.size()   != IGNORE_SIZE
668             || getBar(fi)  != IGNORE
669             || fi.color()  != Color_ignore
670             || font_.language() != ignore_language)
671                 setButtonsValid(true);
672
673         paramsToDialog(font_);
674         // Make sure that the bc is in the INITIAL state
675         if (bc().policy().buttonStatus(ButtonPolicy::OKAY))
676                 bc().restore();
677         return true;
678 }
679
680
681 void GuiCharacter::dispatchParams()
682 {
683         dispatch(FuncRequest(getLfun(), font_.toString(false)));
684 }
685
686
687 void GuiCharacter::saveSession(QSettings & settings) const
688 {
689         Dialog::saveSession(settings);
690         settings.setValue(sessionKey() + "/autoapply", autoapplyCB->isChecked());
691 }
692
693
694 void GuiCharacter::restoreSession()
695 {
696         Dialog::restoreSession();
697         QSettings settings;
698         autoapplyCB->setChecked(
699                 settings.value(sessionKey() + "/autoapply").toBool());
700 }
701
702
703 Dialog * createGuiCharacter(GuiView & lv) { return new GuiCharacter(lv); }
704
705
706 } // namespace frontend
707 } // namespace lyx
708
709 #include "moc_GuiCharacter.cpp"