2 * \file GuiCharacter.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Angus Leeming
10 * Full author contact details are available in file CREDITS.
15 #include "GuiCharacter.h"
17 #include "GuiApplication.h"
18 #include "qt_helpers.h"
22 #include "BufferParams.h"
23 #include "BufferView.h"
25 #include "FuncRequest.h"
27 #include "Paragraph.h"
29 #include <QAbstractItemModel>
30 #include <QModelIndex>
39 static QList
<ShapePair
> shapeData()
41 QList
<ShapePair
> shapes
;
42 shapes
<< ShapePair(qt_("No change"), IGNORE_SHAPE
);
43 shapes
<< ShapePair(qt_("Upright"), UP_SHAPE
);
44 shapes
<< ShapePair(qt_("Italic"), ITALIC_SHAPE
);
45 shapes
<< ShapePair(qt_("Slanted"), SLANTED_SHAPE
);
46 shapes
<< ShapePair(qt_("Small Caps"), SMALLCAPS_SHAPE
);
47 shapes
<< ShapePair(qt_("Reset"), INHERIT_SHAPE
);
52 static QList
<SizePair
> sizeData()
54 QList
<SizePair
> sizes
;
55 sizes
<< SizePair(qt_("No change"), FONT_SIZE_IGNORE
);
56 sizes
<< SizePair(qt_("Tiny"), FONT_SIZE_TINY
);
57 sizes
<< SizePair(qt_("Smallest"), FONT_SIZE_SCRIPT
);
58 sizes
<< SizePair(qt_("Smaller"), FONT_SIZE_FOOTNOTE
);
59 sizes
<< SizePair(qt_("Small"), FONT_SIZE_SMALL
);
60 sizes
<< SizePair(qt_("Normal"), FONT_SIZE_NORMAL
);
61 sizes
<< SizePair(qt_("Large"), FONT_SIZE_LARGE
);
62 sizes
<< SizePair(qt_("Larger"), FONT_SIZE_LARGER
);
63 sizes
<< SizePair(qt_("Largest"), FONT_SIZE_LARGEST
);
64 sizes
<< SizePair(qt_("Huge"), FONT_SIZE_HUGE
);
65 sizes
<< SizePair(qt_("Huger"), FONT_SIZE_HUGER
);
66 sizes
<< SizePair(qt_("Increase"), FONT_SIZE_INCREASE
);
67 sizes
<< SizePair(qt_("Decrease"), FONT_SIZE_DECREASE
);
68 sizes
<< SizePair(qt_("Reset"), FONT_SIZE_INHERIT
);
73 static QList
<BarPair
> barData()
76 bars
<< BarPair(qt_("No change"), IGNORE
);
77 bars
<< BarPair(qt_("Emph"), EMPH_TOGGLE
);
78 bars
<< BarPair(qt_("Underbar"), UNDERBAR_TOGGLE
);
79 bars
<< BarPair(qt_("Double underbar"), UULINE_TOGGLE
);
80 bars
<< BarPair(qt_("Wavy underbar"), UWAVE_TOGGLE
);
81 bars
<< BarPair(qt_("Strikeout"), STRIKEOUT_TOGGLE
);
82 bars
<< BarPair(qt_("Noun"), NOUN_TOGGLE
);
83 bars
<< BarPair(qt_("Reset"), INHERIT
);
88 static QList
<ColorPair
> colorData()
90 QList
<ColorPair
> colors
;
91 colors
<< ColorPair(qt_("No change"), Color_ignore
);
92 colors
<< ColorPair(qt_("No color"), Color_none
);
93 colors
<< ColorPair(qt_("Black"), Color_black
);
94 colors
<< ColorPair(qt_("White"), Color_white
);
95 colors
<< ColorPair(qt_("Red"), Color_red
);
96 colors
<< ColorPair(qt_("Green"), Color_green
);
97 colors
<< ColorPair(qt_("Blue"), Color_blue
);
98 colors
<< ColorPair(qt_("Cyan"), Color_cyan
);
99 colors
<< ColorPair(qt_("Magenta"), Color_magenta
);
100 colors
<< ColorPair(qt_("Yellow"), Color_yellow
);
101 colors
<< ColorPair(qt_("Reset"), Color_inherit
);
106 static QList
<SeriesPair
> seriesData()
108 QList
<SeriesPair
> series
;
109 series
<< SeriesPair(qt_("No change"), IGNORE_SERIES
);
110 series
<< SeriesPair(qt_("Medium"), MEDIUM_SERIES
);
111 series
<< SeriesPair(qt_("Bold"), BOLD_SERIES
);
112 series
<< SeriesPair(qt_("Reset"), INHERIT_SERIES
);
117 static QList
<FamilyPair
> familyData()
119 QList
<FamilyPair
> families
;
120 families
<< FamilyPair(qt_("No change"), IGNORE_FAMILY
);
121 families
<< FamilyPair(qt_("Roman"), ROMAN_FAMILY
);
122 families
<< FamilyPair(qt_("Sans Serif"), SANS_FAMILY
);
123 families
<< FamilyPair(qt_("Typewriter"), TYPEWRITER_FAMILY
);
124 families
<< FamilyPair(qt_("Reset"), INHERIT_FAMILY
);
129 static QList
<LanguagePair
> languageData()
131 QList
<LanguagePair
> list
;
132 // FIXME (Abdel 14/05/2008): it would be nice if we could use this model
133 // directly in the language combo; but, as we need also the 'No Change' and
134 // 'Reset' items, this is not possible right now. Separating those two
135 // entries in radio buttons would be a better GUI IMHO.
136 QAbstractItemModel
* language_model
= guiApp
->languageModel();
137 // Make sure the items are sorted.
138 language_model
->sort(0);
140 for (int i
= 0; i
!= language_model
->rowCount(); ++i
) {
141 QModelIndex index
= language_model
->index(i
, 0);
142 list
<< LanguagePair(index
.data(Qt::DisplayRole
).toString(),
143 index
.data(Qt::UserRole
).toString());
152 void fillCombo(QComboBox
* combo
, QList
<T
> const & list
)
154 typename QList
<T
>::const_iterator cit
= list
.begin();
155 for (; cit
!= list
.end(); ++cit
)
156 combo
->addItem(cit
->first
);
161 GuiCharacter::GuiCharacter(GuiView
& lv
)
162 : GuiDialog(lv
, "character", qt_("Text Style")), font_(ignore_font
, ignore_language
),
163 toggleall_(false), reset_lang_(false)
167 connect(okPB
, SIGNAL(clicked()), this, SLOT(slotOK()));
168 connect(applyPB
, SIGNAL(clicked()), this, SLOT(slotApply()));
169 connect(closePB
, SIGNAL(clicked()), this, SLOT(slotClose()));
170 connect(autoapplyCB
, SIGNAL(stateChanged(int)), this,
171 SLOT(slotAutoApply()));
173 connect(miscCO
, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
174 connect(sizeCO
, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
175 connect(familyCO
, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
176 connect(seriesCO
, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
177 connect(shapeCO
, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
178 connect(colorCO
, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
179 connect(langCO
, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
180 connect(toggleallCB
, SIGNAL(clicked()), this, SLOT(change_adaptor()));
182 family
= familyData();
183 series
= seriesData();
189 language
= languageData();
190 language
.prepend(LanguagePair(qt_("Reset"), "reset"));
191 language
.prepend(LanguagePair(qt_("No change"), "ignore"));
193 fillCombo(familyCO
, family
);
194 fillCombo(seriesCO
, series
);
195 fillCombo(sizeCO
, size
);
196 fillCombo(shapeCO
, shape
);
197 fillCombo(miscCO
, bar
);
198 fillCombo(colorCO
, color
);
199 fillCombo(langCO
, language
);
201 bc().setPolicy(ButtonPolicy::OkApplyCancelAutoReadOnlyPolicy
);
203 bc().setApply(applyPB
);
204 bc().setCancel(closePB
);
205 bc().setAutoApply(autoapplyCB
);
206 bc().addReadOnly(familyCO
);
207 bc().addReadOnly(seriesCO
);
208 bc().addReadOnly(sizeCO
);
209 bc().addReadOnly(shapeCO
);
210 bc().addReadOnly(miscCO
);
211 bc().addReadOnly(langCO
);
212 bc().addReadOnly(colorCO
);
213 bc().addReadOnly(toggleallCB
);
214 bc().addReadOnly(autoapplyCB
);
217 // On Mac it's common to have tool windows which are always in the
218 // foreground and are hidden when the main window is not focused.
219 setWindowFlags(Qt::Tool
);
220 autoapplyCB
->setChecked(true);
223 // FIXME: hack to work around resizing bug in Qt >= 4.2
224 // bug verified with Qt 4.2.{0-3} (JSpitzm)
225 #if QT_VERSION >= 0x040200
226 // qt resizes the comboboxes only after show(), so ...
232 void GuiCharacter::change_adaptor()
236 if (!autoapplyCB
->isChecked())
239 // to be really good here, we should set the combos to the values of
240 // the current text, and make it appear as "no change" if the values
241 // stay the same between applys. Might be difficult though wrt to a
242 // moved cursor - jbl
247 template<class P
, class B
>
248 static int findPos2nd(QList
<P
> const & vec
, B
const & val
)
250 for (int i
= 0; i
!= vec
.size(); ++i
)
251 if (vec
[i
].second
== val
)
257 void GuiCharacter::updateContents()
259 if (!autoapplyCB
->isChecked()) {
263 if (bufferview()->cursor().selection()) {
264 //FIXME: it would be better to check if each font attribute is constant
265 // for the selection range.
266 font_
= Font(ignore_font
, ignore_language
);
268 font_
= bufferview()->cursor().current_font
;
270 paramsToDialog(font_
);
274 static FontState
getBar(FontInfo
const & fi
)
276 if (fi
.emph() == FONT_TOGGLE
)
279 if (fi
.underbar() == FONT_TOGGLE
)
280 return UNDERBAR_TOGGLE
;
282 if (fi
.strikeout() == FONT_TOGGLE
)
283 return STRIKEOUT_TOGGLE
;
285 if (fi
.uuline() == FONT_TOGGLE
)
286 return UULINE_TOGGLE
;
288 if (fi
.uwave() == FONT_TOGGLE
)
291 if (fi
.noun() == FONT_TOGGLE
)
294 if (fi
.emph() == FONT_IGNORE
295 && fi
.underbar() == FONT_IGNORE
296 && fi
.noun() == FONT_IGNORE
)
303 static void setBar(FontInfo
& fi
, FontState val
)
307 fi
.setEmph(FONT_IGNORE
);
308 fi
.setUnderbar(FONT_IGNORE
);
309 fi
.setStrikeout(FONT_IGNORE
);
310 fi
.setNoun(FONT_IGNORE
);
314 fi
.setEmph(FONT_TOGGLE
);
317 case UNDERBAR_TOGGLE
:
318 fi
.setUnderbar(FONT_TOGGLE
);
321 case STRIKEOUT_TOGGLE
:
322 fi
.setStrikeout(FONT_TOGGLE
);
326 fi
.setUuline(FONT_TOGGLE
);
330 fi
.setUwave(FONT_TOGGLE
);
334 fi
.setNoun(FONT_TOGGLE
);
338 fi
.setEmph(FONT_INHERIT
);
339 fi
.setUnderbar(FONT_INHERIT
);
340 fi
.setStrikeout(FONT_INHERIT
);
341 fi
.setUuline(FONT_INHERIT
);
342 fi
.setUwave(FONT_INHERIT
);
343 fi
.setNoun(FONT_INHERIT
);
349 void GuiCharacter::paramsToDialog(Font
const & font
)
351 FontInfo
const & fi
= font
.fontInfo();
352 familyCO
->setCurrentIndex(findPos2nd(family
, fi
.family()));
353 seriesCO
->setCurrentIndex(findPos2nd(series
, fi
.series()));
354 shapeCO
->setCurrentIndex(findPos2nd(shape
, fi
.shape()));
355 sizeCO
->setCurrentIndex(findPos2nd(size
, fi
.size()));
356 miscCO
->setCurrentIndex(findPos2nd(bar
, getBar(fi
)));
357 colorCO
->setCurrentIndex(findPos2nd(color
, fi
.color()));
359 // reset_language is a null pointer.
360 QString
const lang
= (font
.language() == reset_language
)
361 ? "reset" : toqstr(font
.language()->lang());
362 langCO
->setCurrentIndex(findPos2nd(language
, lang
));
364 toggleallCB
->setChecked(toggleall_
);
368 void GuiCharacter::applyView()
370 FontInfo
& fi
= font_
.fontInfo();
371 fi
.setFamily(family
[familyCO
->currentIndex()].second
);
372 fi
.setSeries(series
[seriesCO
->currentIndex()].second
);
373 fi
.setShape(shape
[shapeCO
->currentIndex()].second
);
374 fi
.setSize(size
[sizeCO
->currentIndex()].second
);
375 setBar(fi
, bar
[miscCO
->currentIndex()].second
);
376 fi
.setColor(color
[colorCO
->currentIndex()].second
);
378 font_
.setLanguage(languages
.getLanguage(
379 fromqstr(language
[langCO
->currentIndex()].second
)));
381 toggleall_
= toggleallCB
->isChecked();
385 bool GuiCharacter::initialiseParams(string
const &)
387 if (autoapplyCB
->isChecked())
390 FontInfo
& fi
= font_
.fontInfo();
392 // so that the user can press Ok
393 if (fi
.family() != IGNORE_FAMILY
394 || fi
.series() != IGNORE_SERIES
395 || fi
.shape() != IGNORE_SHAPE
396 || fi
.size() != FONT_SIZE_IGNORE
397 || getBar(fi
) != IGNORE
398 || fi
.color() != Color_ignore
399 || font_
.language() != ignore_language
)
400 setButtonsValid(true);
402 paramsToDialog(font_
);
407 void GuiCharacter::dispatchParams()
409 dispatch(FuncRequest(getLfun(), font_
.toString(toggleall_
)));
413 void GuiCharacter::saveSession() const
415 Dialog::saveSession();
417 settings
.setValue(sessionKey() + "/toggleall", toggleallCB
->isChecked());
418 settings
.setValue(sessionKey() + "/autoapply", autoapplyCB
->isChecked());
422 void GuiCharacter::restoreSession()
424 Dialog::restoreSession();
426 toggleallCB
->setChecked(
427 settings
.value(sessionKey() + "/toggleall").toBool());
428 autoapplyCB
->setChecked(
429 settings
.value(sessionKey() + "/autoapply").toBool());
433 Dialog
* createGuiCharacter(GuiView
& lv
) { return new GuiCharacter(lv
); }
436 } // namespace frontend
439 #include "moc_GuiCharacter.cpp"