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