X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt4%2FGuiCharacter.cpp;h=53ca720d2f2ac129451d935ffa76fa5d8bd1ff3c;hb=d3312032eeea9a682840e3a6b6a762cb4adec729;hp=35f0a7f1bf01df516b6b6df74de0c61c6119628f;hpb=c9ea6e6eef090b863fb54445010f24443b15eb23;p=lyx.git diff --git a/src/frontends/qt4/GuiCharacter.cpp b/src/frontends/qt4/GuiCharacter.cpp index 35f0a7f1bf..53ca720d2f 100644 --- a/src/frontends/qt4/GuiCharacter.cpp +++ b/src/frontends/qt4/GuiCharacter.cpp @@ -3,6 +3,7 @@ * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * + * \author Angus Leeming * \author Edwin Leuven * \author John Levon * @@ -13,28 +14,161 @@ #include "GuiCharacter.h" -#include "ControlCharacter.h" +#include "GuiApplication.h" #include "qt_helpers.h" -#include "frontend_helpers.h" -#include "Color.h" -#include +#include "Font.h" +#include "Buffer.h" +#include "BufferParams.h" +#include "BufferView.h" +#include "Cursor.h" +#include "FuncRequest.h" +#include "Language.h" +#include "Paragraph.h" -using std::vector; +#include +#include +#include +#include + +using namespace std; namespace lyx { namespace frontend { -GuiCharacterDialog::GuiCharacterDialog(LyXView & lv) - : GuiDialog(lv, "character") +static QList shapeData() +{ + QList shapes; + shapes << ShapePair(qt_("No change"), IGNORE_SHAPE); + shapes << ShapePair(qt_("Upright"), UP_SHAPE); + shapes << ShapePair(qt_("Italic"), ITALIC_SHAPE); + shapes << ShapePair(qt_("Slanted"), SLANTED_SHAPE); + shapes << ShapePair(qt_("Small Caps"), SMALLCAPS_SHAPE); + shapes << ShapePair(qt_("Reset"), INHERIT_SHAPE); + return shapes; +} + + +static QList sizeData() +{ + QList sizes; + sizes << SizePair(qt_("No change"), FONT_SIZE_IGNORE); + sizes << SizePair(qt_("Tiny"), FONT_SIZE_TINY); + sizes << SizePair(qt_("Smallest"), FONT_SIZE_SCRIPT); + sizes << SizePair(qt_("Smaller"), FONT_SIZE_FOOTNOTE); + sizes << SizePair(qt_("Small"), FONT_SIZE_SMALL); + sizes << SizePair(qt_("Normal"), FONT_SIZE_NORMAL); + sizes << SizePair(qt_("Large"), FONT_SIZE_LARGE); + sizes << SizePair(qt_("Larger"), FONT_SIZE_LARGER); + sizes << SizePair(qt_("Largest"), FONT_SIZE_LARGEST); + sizes << SizePair(qt_("Huge"), FONT_SIZE_HUGE); + sizes << SizePair(qt_("Huger"), FONT_SIZE_HUGER); + sizes << SizePair(qt_("Increase"), FONT_SIZE_INCREASE); + sizes << SizePair(qt_("Decrease"), FONT_SIZE_DECREASE); + sizes << SizePair(qt_("Reset"), FONT_SIZE_INHERIT); + return sizes; +} + + +static QList barData() +{ + QList bars; + bars << BarPair(qt_("No change"), IGNORE); + bars << BarPair(qt_("Emph"), EMPH_TOGGLE); + bars << BarPair(qt_("Underbar"), UNDERBAR_TOGGLE); + bars << BarPair(qt_("Double underbar"), UULINE_TOGGLE); + bars << BarPair(qt_("Wavy underbar"), UWAVE_TOGGLE); + bars << BarPair(qt_("Strikeout"), STRIKEOUT_TOGGLE); + bars << BarPair(qt_("Noun"), NOUN_TOGGLE); + bars << BarPair(qt_("Reset"), INHERIT); + return bars; +} + + +static QList colorData() +{ + QList colors; + colors << ColorPair(qt_("No change"), Color_ignore); + colors << ColorPair(qt_("No color"), Color_none); + colors << ColorPair(qt_("Black"), Color_black); + colors << ColorPair(qt_("White"), Color_white); + colors << ColorPair(qt_("Red"), Color_red); + colors << ColorPair(qt_("Green"), Color_green); + colors << ColorPair(qt_("Blue"), Color_blue); + colors << ColorPair(qt_("Cyan"), Color_cyan); + colors << ColorPair(qt_("Magenta"), Color_magenta); + colors << ColorPair(qt_("Yellow"), Color_yellow); + colors << ColorPair(qt_("Reset"), Color_inherit); + return colors; +} + + +static QList seriesData() +{ + QList series; + series << SeriesPair(qt_("No change"), IGNORE_SERIES); + series << SeriesPair(qt_("Medium"), MEDIUM_SERIES); + series << SeriesPair(qt_("Bold"), BOLD_SERIES); + series << SeriesPair(qt_("Reset"), INHERIT_SERIES); + return series; +} + + +static QList familyData() +{ + QList families; + families << FamilyPair(qt_("No change"), IGNORE_FAMILY); + families << FamilyPair(qt_("Roman"), ROMAN_FAMILY); + families << FamilyPair(qt_("Sans Serif"), SANS_FAMILY); + families << FamilyPair(qt_("Typewriter"), TYPEWRITER_FAMILY); + families << FamilyPair(qt_("Reset"), INHERIT_FAMILY); + return families; +} + + +static QList languageData() +{ + QList list; + // FIXME (Abdel 14/05/2008): it would be nice if we could use this model + // directly in the language combo; but, as we need also the 'No Change' and + // 'Reset' items, this is not possible right now. Separating those two + // entries in radio buttons would be a better GUI IMHO. + QAbstractItemModel * language_model = guiApp->languageModel(); + // Make sure the items are sorted. + language_model->sort(0); + + for (int i = 0; i != language_model->rowCount(); ++i) { + QModelIndex index = language_model->index(i, 0); + list << LanguagePair(index.data(Qt::DisplayRole).toString(), + index.data(Qt::UserRole).toString()); + } + return list; +} + + +namespace { + +template +void fillCombo(QComboBox * combo, QList const & list) +{ + typename QList::const_iterator cit = list.begin(); + for (; cit != list.end(); ++cit) + combo->addItem(cit->first); +} + +} + +GuiCharacter::GuiCharacter(GuiView & lv) + : GuiDialog(lv, "character", qt_("Text Style")), font_(ignore_font, ignore_language), + toggleall_(false), reset_lang_(false) { setupUi(this); - setController(new ControlCharacter(*this)); - setViewTitle(_("Text Style")); connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK())); connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply())); connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose())); + connect(autoapplyCB, SIGNAL(stateChanged(int)), this, + SLOT(slotAutoApply())); connect(miscCO, SIGNAL(activated(int)), this, SLOT(change_adaptor())); connect(sizeCO, SIGNAL(activated(int)), this, SLOT(change_adaptor())); @@ -45,48 +179,30 @@ GuiCharacterDialog::GuiCharacterDialog(LyXView & lv) connect(langCO, SIGNAL(activated(int)), this, SLOT(change_adaptor())); connect(toggleallCB, SIGNAL(clicked()), this, SLOT(change_adaptor())); - family = getFamilyData(); - series = getSeriesData(); - shape = getShapeData(); - size = getSizeData(); - bar = getBarData(); - color = getColorData(); - language = getLanguageData(true); - - for (vector::const_iterator cit = family.begin(); - cit != family.end(); ++cit) { - familyCO->addItem(toqstr(cit->first)); - } - - for (vector::const_iterator cit = series.begin(); - cit != series.end(); ++cit) { - seriesCO->addItem(toqstr(cit->first)); - } - for (vector::const_iterator cit = shape.begin(); - cit != shape.end(); ++cit) { - shapeCO->addItem(toqstr(cit->first)); - } - for (vector::const_iterator cit = size.begin(); - cit != size.end(); ++cit) { - sizeCO->addItem(toqstr(cit->first)); - } - for (vector::const_iterator cit = bar.begin(); - cit != bar.end(); ++cit) { - miscCO->addItem(toqstr(cit->first)); - } - for (vector::const_iterator cit = color.begin(); - cit != color.end(); ++cit) { - colorCO->addItem(toqstr(cit->first)); - } - for (vector::const_iterator cit = language.begin(); - cit != language.end(); ++cit) { - langCO->addItem(toqstr(cit->first)); - } - - bc().setPolicy(ButtonPolicy::OkApplyCancelReadOnlyPolicy); + family = familyData(); + series = seriesData(); + shape = shapeData(); + size = sizeData(); + bar = barData(); + color = colorData(); + + language = languageData(); + language.prepend(LanguagePair(qt_("Reset"), "reset")); + language.prepend(LanguagePair(qt_("No change"), "ignore")); + + fillCombo(familyCO, family); + fillCombo(seriesCO, series); + fillCombo(sizeCO, size); + fillCombo(shapeCO, shape); + fillCombo(miscCO, bar); + fillCombo(colorCO, color); + fillCombo(langCO, language); + + bc().setPolicy(ButtonPolicy::OkApplyCancelAutoReadOnlyPolicy); bc().setOK(okPB); bc().setApply(applyPB); bc().setCancel(closePB); + bc().setAutoApply(autoapplyCB); bc().addReadOnly(familyCO); bc().addReadOnly(seriesCO); bc().addReadOnly(sizeCO); @@ -97,6 +213,13 @@ GuiCharacterDialog::GuiCharacterDialog(LyXView & lv) bc().addReadOnly(toggleallCB); bc().addReadOnly(autoapplyCB); +#ifdef Q_WS_MACX + // On Mac it's common to have tool windows which are always in the + // foreground and are hidden when the main window is not focused. + setWindowFlags(Qt::Tool); + autoapplyCB->setChecked(true); +#endif + // FIXME: hack to work around resizing bug in Qt >= 4.2 // bug verified with Qt 4.2.{0-3} (JSpitzm) #if QT_VERSION >= 0x040200 @@ -106,13 +229,7 @@ GuiCharacterDialog::GuiCharacterDialog(LyXView & lv) } -ControlCharacter & GuiCharacterDialog::controller() const -{ - return static_cast(Dialog::controller()); -} - - -void GuiCharacterDialog::change_adaptor() +void GuiCharacter::change_adaptor() { changed(); @@ -124,73 +241,199 @@ void GuiCharacterDialog::change_adaptor() // stay the same between applys. Might be difficult though wrt to a // moved cursor - jbl slotApply(); - familyCO->setCurrentIndex(0); - seriesCO->setCurrentIndex(0); - sizeCO->setCurrentIndex(0); - shapeCO->setCurrentIndex(0); - miscCO->setCurrentIndex(0); - langCO->setCurrentIndex(0); - colorCO->setCurrentIndex(0); } -void GuiCharacterDialog::closeEvent(QCloseEvent * e) +template +static int findPos2nd(QList

const & vec, B const & val) { - slotWMHide(); - e->accept(); + for (int i = 0; i != vec.size(); ++i) + if (vec[i].second == val) + return i; + return 0; } -template -static int findPos2nd(vector > const & vec, B const & val) +void GuiCharacter::updateContents() { - typedef typename vector >::const_iterator - const_iterator; + if (!autoapplyCB->isChecked()) { + bc().setValid(true); + return; + } + if (bufferview()->cursor().selection()) { + //FIXME: it would be better to check if each font attribute is constant + // for the selection range. + font_ = Font(ignore_font, ignore_language); + } else + font_ = bufferview()->cursor().current_font; + + paramsToDialog(font_); +} + + +static FontState getBar(FontInfo const & fi) +{ + if (fi.emph() == FONT_TOGGLE) + return EMPH_TOGGLE; + + if (fi.underbar() == FONT_TOGGLE) + return UNDERBAR_TOGGLE; + + if (fi.strikeout() == FONT_TOGGLE) + return STRIKEOUT_TOGGLE; + + if (fi.uuline() == FONT_TOGGLE) + return UULINE_TOGGLE; + + if (fi.uwave() == FONT_TOGGLE) + return UWAVE_TOGGLE; + + if (fi.noun() == FONT_TOGGLE) + return NOUN_TOGGLE; - const_iterator cit = vec.begin(); - for (; cit != vec.end(); ++cit) { - if (cit->second == val) - return int(cit - vec.begin()); + if (fi.emph() == FONT_IGNORE + && fi.underbar() == FONT_IGNORE + && fi.noun() == FONT_IGNORE) + return IGNORE; + + return INHERIT; +} + + +static void setBar(FontInfo & fi, FontState val) +{ + switch (val) { + case IGNORE: + fi.setEmph(FONT_IGNORE); + fi.setUnderbar(FONT_IGNORE); + fi.setStrikeout(FONT_IGNORE); + fi.setNoun(FONT_IGNORE); + break; + + case EMPH_TOGGLE: + fi.setEmph(FONT_TOGGLE); + break; + + case UNDERBAR_TOGGLE: + fi.setUnderbar(FONT_TOGGLE); + break; + + case STRIKEOUT_TOGGLE: + fi.setStrikeout(FONT_TOGGLE); + break; + + case UULINE_TOGGLE: + fi.setUuline(FONT_TOGGLE); + break; + + case UWAVE_TOGGLE: + fi.setUwave(FONT_TOGGLE); + break; + + case NOUN_TOGGLE: + fi.setNoun(FONT_TOGGLE); + break; + + case INHERIT: + fi.setEmph(FONT_INHERIT); + fi.setUnderbar(FONT_INHERIT); + fi.setStrikeout(FONT_INHERIT); + fi.setUuline(FONT_INHERIT); + fi.setUwave(FONT_INHERIT); + fi.setNoun(FONT_INHERIT); + break; } - return 0; } -void GuiCharacterDialog::update_contents() +void GuiCharacter::paramsToDialog(Font const & font) { - ControlCharacter const & ctrl = controller(); + FontInfo const & fi = font.fontInfo(); + familyCO->setCurrentIndex(findPos2nd(family, fi.family())); + seriesCO->setCurrentIndex(findPos2nd(series, fi.series())); + shapeCO->setCurrentIndex(findPos2nd(shape, fi.shape())); + sizeCO->setCurrentIndex(findPos2nd(size, fi.size())); + miscCO->setCurrentIndex(findPos2nd(bar, getBar(fi))); + colorCO->setCurrentIndex(findPos2nd(color, fi.color())); + + // reset_language is a null pointer. + QString const lang = (font.language() == reset_language) + ? "reset" : toqstr(font.language()->lang()); + langCO->setCurrentIndex(findPos2nd(language, lang)); + + toggleallCB->setChecked(toggleall_); +} - familyCO->setCurrentIndex(findPos2nd(family, - ctrl.getFamily())); - seriesCO->setCurrentIndex(findPos2nd(series, - ctrl.getSeries())); - shapeCO->setCurrentIndex(findPos2nd(shape, ctrl.getShape())); - sizeCO->setCurrentIndex(findPos2nd(size, ctrl.getSize())); - miscCO->setCurrentIndex(findPos2nd(bar, ctrl.getBar())); - colorCO->setCurrentIndex(findPos2nd(color, ctrl.getColor())); - langCO->setCurrentIndex(findPos2nd(language, - ctrl.getLanguage())); - toggleallCB->setChecked(ctrl.getToggleAll()); +void GuiCharacter::applyView() +{ + FontInfo & fi = font_.fontInfo(); + fi.setFamily(family[familyCO->currentIndex()].second); + fi.setSeries(series[seriesCO->currentIndex()].second); + fi.setShape(shape[shapeCO->currentIndex()].second); + fi.setSize(size[sizeCO->currentIndex()].second); + setBar(fi, bar[miscCO->currentIndex()].second); + fi.setColor(color[colorCO->currentIndex()].second); + + font_.setLanguage(languages.getLanguage( + fromqstr(language[langCO->currentIndex()].second))); + + toggleall_ = toggleallCB->isChecked(); } -void GuiCharacterDialog::applyView() +bool GuiCharacter::initialiseParams(string const &) { - ControlCharacter & ctrl = controller(); + if (autoapplyCB->isChecked()) + return true; + + FontInfo & fi = font_.fontInfo(); + + // so that the user can press Ok + if (fi.family() != IGNORE_FAMILY + || fi.series() != IGNORE_SERIES + || fi.shape() != IGNORE_SHAPE + || fi.size() != FONT_SIZE_IGNORE + || getBar(fi) != IGNORE + || fi.color() != Color_ignore + || font_.language() != ignore_language) + setButtonsValid(true); + + paramsToDialog(font_); + return true; +} - ctrl.setFamily(family[familyCO->currentIndex()].second); - ctrl.setSeries(series[seriesCO->currentIndex()].second); - ctrl.setShape(shape[shapeCO->currentIndex()].second); - ctrl.setSize(size[sizeCO->currentIndex()].second); - ctrl.setBar(bar[miscCO->currentIndex()].second); - ctrl.setColor(color[colorCO->currentIndex()].second); - ctrl.setLanguage(language[langCO->currentIndex()].second); - ctrl.setToggleAll(toggleallCB->isChecked()); +void GuiCharacter::dispatchParams() +{ + dispatch(FuncRequest(getLfun(), font_.toString(toggleall_))); } + +void GuiCharacter::saveSession() const +{ + Dialog::saveSession(); + QSettings settings; + settings.setValue(sessionKey() + "/toggleall", toggleallCB->isChecked()); + settings.setValue(sessionKey() + "/autoapply", autoapplyCB->isChecked()); +} + + +void GuiCharacter::restoreSession() +{ + Dialog::restoreSession(); + QSettings settings; + toggleallCB->setChecked( + settings.value(sessionKey() + "/toggleall").toBool()); + autoapplyCB->setChecked( + settings.value(sessionKey() + "/autoapply").toBool()); +} + + +Dialog * createGuiCharacter(GuiView & lv) { return new GuiCharacter(lv); } + + } // namespace frontend } // namespace lyx -#include "GuiCharacter_moc.cpp" +#include "moc_GuiCharacter.cpp"