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