X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt4%2FGuiPrefs.cpp;h=4518838456d131f635df510acedb43869c3f44fb;hb=425d092204118ea6c24c28e85fdf03fcf2bb51a4;hp=d58c26d23259e3002cc707dce506a35d3fb278c6;hpb=419c7ed4811a8d2a8a707c4188cf110bfcf35b73;p=lyx.git diff --git a/src/frontends/qt4/GuiPrefs.cpp b/src/frontends/qt4/GuiPrefs.cpp index d58c26d232..4518838456 100644 --- a/src/frontends/qt4/GuiPrefs.cpp +++ b/src/frontends/qt4/GuiPrefs.cpp @@ -13,6 +13,7 @@ #include "GuiPrefs.h" +#include "ColorCache.h" #include "FileDialog.h" #include "GuiApplication.h" #include "GuiFontExample.h" @@ -22,7 +23,9 @@ #include "BufferList.h" #include "Color.h" +#include "ColorSet.h" #include "ConverterCache.h" +#include "FontEnums.h" #include "FuncRequest.h" #include "KeyMap.h" #include "KeySequence.h" @@ -31,6 +34,7 @@ #include "PanelStack.h" #include "paper.h" #include "Session.h" +#include "SpellChecker.h" #include "support/debug.h" #include "support/FileName.h" @@ -45,16 +49,18 @@ #include "frontends/alert.h" #include "frontends/Application.h" +#include "frontends/FontLoader.h" +#include #include #include #include #include #include +#include #include #include #include -#include #include #include #include @@ -92,11 +98,14 @@ QString browseFile(QString const & filename, QString const & label1 = QString(), QString const & dir1 = QString(), QString const & label2 = QString(), - QString const & dir2 = QString()) + QString const & dir2 = QString(), + QString const & fallback_dir = QString()) { QString lastPath = "."; if (!filename.isEmpty()) lastPath = onlyPath(filename); + else if(!fallback_dir.isEmpty()) + lastPath = fallback_dir; FileDialog dlg(title, LFUN_SELECT_FILE_SYNC); dlg.setButton2(label1, dir1); @@ -135,7 +144,7 @@ QString browseLibFile(QString const & dir, QString const result = browseFile(toqstr( libFileSearch(dir, name, ext).absFilename()), - title, filters, false, dir1, dir2); + title, filters, false, dir1, dir2, QString(), QString(), dir1); // remove the extension if it is the default one QString noextresult; @@ -322,28 +331,53 @@ static void setComboxFont(QComboBox * cb, string const & family, // ///////////////////////////////////////////////////////////////////// -PrefPlaintext::PrefPlaintext(QWidget * parent) - : PrefModule(qt_(catOutput), qt_("Plain text"), 0, parent) +PrefPlaintext::PrefPlaintext(GuiPreferences * form) + : PrefModule(qt_(catOutput), qt_("Plain text"), form) { setupUi(this); connect(plaintextLinelengthSB, SIGNAL(valueChanged(int)), this, SIGNAL(changed())); - connect(plaintextRoffED, SIGNAL(textChanged(QString)), - this, SIGNAL(changed())); } void PrefPlaintext::apply(LyXRC & rc) const { rc.plaintext_linelen = plaintextLinelengthSB->value(); - rc.plaintext_roff_command = fromqstr(plaintextRoffED->text()); } void PrefPlaintext::update(LyXRC const & rc) { plaintextLinelengthSB->setValue(rc.plaintext_linelen); - plaintextRoffED->setText(toqstr(rc.plaintext_roff_command)); +} + + +///////////////////////////////////////////////////////////////////// +// +// StrftimeValidator +// +///////////////////////////////////////////////////////////////////// + +class StrftimeValidator : public QValidator +{ +public: + StrftimeValidator(QWidget *); + QValidator::State validate(QString & input, int & pos) const; +}; + + +StrftimeValidator::StrftimeValidator(QWidget * parent) + : QValidator(parent) +{ +} + + +QValidator::State StrftimeValidator::validate(QString & input, int & /*pos*/) const +{ + if (is_valid_strftime(fromqstr(input))) + return QValidator::Acceptable; + else + return QValidator::Intermediate; } @@ -353,15 +387,26 @@ void PrefPlaintext::update(LyXRC const & rc) // ///////////////////////////////////////////////////////////////////// -PrefDate::PrefDate(QWidget * parent) - : PrefModule(qt_(catOutput), qt_("Date format"), 0, parent) +PrefDate::PrefDate(GuiPreferences * form) + : PrefModule(qt_(catOutput), qt_("Date format"), form) { setupUi(this); + DateED->setValidator(new StrftimeValidator(DateED)); connect(DateED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); } +void PrefDate::on_DateED_textChanged(const QString &) +{ + QString t = DateED->text(); + int p = 0; + bool valid = DateED->validator()->validate(t, p) + == QValidator::Acceptable; + setValid(DateLA, valid); +} + + void PrefDate::apply(LyXRC & rc) const { rc.date_insert_format = fromqstr(DateED->text()); @@ -380,8 +425,8 @@ void PrefDate::update(LyXRC const & rc) // ///////////////////////////////////////////////////////////////////// -PrefInput::PrefInput(GuiPreferences * form, QWidget * parent) - : PrefModule(qt_(catEditing), qt_("Keyboard/Mouse"), form, parent) +PrefInput::PrefInput(GuiPreferences * form) + : PrefModule(qt_(catEditing), qt_("Keyboard/Mouse"), form) { setupUi(this); @@ -416,9 +461,9 @@ void PrefInput::update(LyXRC const & rc) } -QString PrefInput::testKeymap(QString keymap) +QString PrefInput::testKeymap(QString const & keymap) { - return form_->browsekbmap(toqstr(internal_path(fromqstr(keymap)))); + return form_->browsekbmap(internalPath(keymap)); } @@ -455,8 +500,8 @@ void PrefInput::on_keymapCB_toggled(bool keymap) // ///////////////////////////////////////////////////////////////////// -PrefCompletion::PrefCompletion(GuiPreferences * form, QWidget * parent) - : PrefModule(qt_(catEditing), qt_("Input Completion"), form, parent) +PrefCompletion::PrefCompletion(GuiPreferences * form) + : PrefModule(qt_(catEditing), qt_("Input Completion"), form) { setupUi(this); @@ -472,6 +517,8 @@ PrefCompletion::PrefCompletion(GuiPreferences * form, QWidget * parent) this, SIGNAL(changed())); connect(popupMathCB, SIGNAL(clicked()), this, SIGNAL(changed())); + connect(autocorrectionCB, SIGNAL(clicked()), + this, SIGNAL(changed())); connect(popupTextCB, SIGNAL(clicked()), this, SIGNAL(changed())); connect(popupAfterCompleteCB, SIGNAL(clicked()), @@ -481,6 +528,25 @@ PrefCompletion::PrefCompletion(GuiPreferences * form, QWidget * parent) } +void PrefCompletion::on_inlineTextCB_clicked() +{ + enableCB(); +} + + +void PrefCompletion::on_popupTextCB_clicked() +{ + enableCB(); +} + + +void PrefCompletion::enableCB() +{ + cursorTextCB->setEnabled( + popupTextCB->isChecked() || inlineTextCB->isChecked()); +} + + void PrefCompletion::apply(LyXRC & rc) const { rc.completion_inline_delay = inlineDelaySB->value(); @@ -489,6 +555,7 @@ void PrefCompletion::apply(LyXRC & rc) const rc.completion_inline_dots = inlineDotsCB->isChecked() ? 13 : -1; rc.completion_popup_delay = popupDelaySB->value(); rc.completion_popup_math = popupMathCB->isChecked(); + rc.autocorrection_math = autocorrectionCB->isChecked(); rc.completion_popup_text = popupTextCB->isChecked(); rc.completion_cursor_text = cursorTextCB->isChecked(); rc.completion_popup_after_complete = @@ -504,9 +571,11 @@ void PrefCompletion::update(LyXRC const & rc) inlineDotsCB->setChecked(rc.completion_inline_dots != -1); popupDelaySB->setValue(rc.completion_popup_delay); popupMathCB->setChecked(rc.completion_popup_math); + autocorrectionCB->setChecked(rc.autocorrection_math); popupTextCB->setChecked(rc.completion_popup_text); cursorTextCB->setChecked(rc.completion_cursor_text); popupAfterCompleteCB->setChecked(rc.completion_popup_after_complete); + enableCB(); } @@ -517,18 +586,28 @@ void PrefCompletion::update(LyXRC const & rc) // ///////////////////////////////////////////////////////////////////// -PrefLatex::PrefLatex(GuiPreferences * form, QWidget * parent) - : PrefModule(qt_(catOutput), qt_("LaTeX"), form, parent) +PrefLatex::PrefLatex(GuiPreferences * form) + : PrefModule(qt_(catOutput), qt_("LaTeX"), form) { setupUi(this); + connect(latexEncodingCB, SIGNAL(clicked()), + this, SIGNAL(changed())); connect(latexEncodingED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); connect(latexChecktexED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); + connect(latexBibtexCO, SIGNAL(activated(int)), + this, SIGNAL(changed())); connect(latexBibtexED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); + connect(latexJBibtexED, SIGNAL(textChanged(QString)), + this, SIGNAL(changed())); + connect(latexIndexCO, SIGNAL(activated(int)), + this, SIGNAL(changed())); connect(latexIndexED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); + connect(latexJIndexED, SIGNAL(textChanged(QString)), + this, SIGNAL(changed())); connect(latexAutoresetCB, SIGNAL(clicked()), this, SIGNAL(changed())); connect(latexDviPaperED, SIGNAL(textChanged(QString)), @@ -538,7 +617,7 @@ PrefLatex::PrefLatex(GuiPreferences * form, QWidget * parent) #if defined(__CYGWIN__) || defined(_WIN32) pathCB->setVisible(true); - connect(pathCB, SIGNAL(clicked()), + connect(pathCB, SIGNAL(clicked()), this, SIGNAL(changed())); #else pathCB->setVisible(false); @@ -546,12 +625,96 @@ PrefLatex::PrefLatex(GuiPreferences * form, QWidget * parent) } +void PrefLatex::on_latexEncodingCB_stateChanged(int state) +{ + latexEncodingED->setEnabled(state == Qt::Checked); +} + + +void PrefLatex::on_latexBibtexCO_activated(int n) +{ + QString const bibtex = latexBibtexCO->itemData(n).toString(); + if (bibtex.isEmpty()) { + latexBibtexED->clear(); + latexBibtexOptionsLA->setText(qt_("Co&mmand:")); + return; + } + for (LyXRC::CommandSet::const_iterator it = bibtex_alternatives.begin(); + it != bibtex_alternatives.end(); ++it) { + QString const bib = toqstr(*it); + int ind = bib.indexOf(" "); + QString sel_command = bib.left(ind); + QString sel_options = ind < 0 ? QString() : bib.mid(ind + 1); + if (bibtex == sel_command) { + if (ind < 0) + latexBibtexED->clear(); + else + latexBibtexED->setText(sel_options.trimmed()); + } + } + latexBibtexOptionsLA->setText(qt_("&Options:")); +} + + +void PrefLatex::on_latexIndexCO_activated(int n) +{ + QString const index = latexIndexCO->itemData(n).toString(); + if (index.isEmpty()) { + latexIndexED->clear(); + latexIndexOptionsLA->setText(qt_("Co&mmand:")); + return; + } + for (LyXRC::CommandSet::const_iterator it = index_alternatives.begin(); + it != index_alternatives.end(); ++it) { + QString const idx = toqstr(*it); + int ind = idx.indexOf(" "); + QString sel_command = idx.left(ind); + QString sel_options = ind < 0 ? QString() : idx.mid(ind + 1); + if (index == sel_command) { + if (ind < 0) + latexIndexED->clear(); + else + latexIndexED->setText(sel_options.trimmed()); + } + } + latexIndexOptionsLA->setText(qt_("Op&tions:")); +} + + void PrefLatex::apply(LyXRC & rc) const { - rc.fontenc = fromqstr(latexEncodingED->text()); + // If bibtex is not empty, bibopt contains the options, otherwise + // it is a customized bibtex command with options. + QString const bibtex = latexBibtexCO->itemData( + latexBibtexCO->currentIndex()).toString(); + QString const bibopt = latexBibtexED->text(); + if (bibtex.isEmpty()) + rc.bibtex_command = fromqstr(bibopt); + else if (bibopt.isEmpty()) + rc.bibtex_command = fromqstr(bibtex); + else + rc.bibtex_command = fromqstr(bibtex) + " " + fromqstr(bibopt); + + // If index is not empty, idxopt contains the options, otherwise + // it is a customized index command with options. + QString const index = latexIndexCO->itemData( + latexIndexCO->currentIndex()).toString(); + QString const idxopt = latexIndexED->text(); + if (index.isEmpty()) + rc.index_command = fromqstr(idxopt); + else if (idxopt.isEmpty()) + rc.index_command = fromqstr(index); + else + rc.index_command = fromqstr(index) + " " + fromqstr(idxopt); + + if (latexEncodingCB->isChecked()) + rc.fontenc = fromqstr(latexEncodingED->text()); + else + rc.fontenc = "default"; rc.chktex_command = fromqstr(latexChecktexED->text()); - rc.bibtex_command = fromqstr(latexBibtexED->text()); - rc.index_command = fromqstr(latexIndexED->text()); + rc.jbibtex_command = fromqstr(latexJBibtexED->text()); + rc.jindex_command = fromqstr(latexJIndexED->text()); + rc.nomencl_command = fromqstr(latexNomenclED->text()); rc.auto_reset_options = latexAutoresetCB->isChecked(); rc.view_dvi_paper_option = fromqstr(latexDviPaperED->text()); rc.default_papersize = @@ -564,10 +727,72 @@ void PrefLatex::apply(LyXRC & rc) const void PrefLatex::update(LyXRC const & rc) { - latexEncodingED->setText(toqstr(rc.fontenc)); + latexBibtexCO->clear(); + + latexBibtexCO->addItem(qt_("Custom"), QString()); + for (LyXRC::CommandSet::const_iterator it = rc.bibtex_alternatives.begin(); + it != rc.bibtex_alternatives.end(); ++it) { + QString const command = toqstr(*it).left(toqstr(*it).indexOf(" ")); + latexBibtexCO->addItem(command, command); + } + + bibtex_alternatives = rc.bibtex_alternatives; + + QString const bib = toqstr(rc.bibtex_command); + int ind = bib.indexOf(" "); + QString sel_command = bib.left(ind); + QString sel_options = ind < 0 ? QString() : bib.mid(ind + 1); + + int pos = latexBibtexCO->findData(sel_command); + if (pos != -1) { + latexBibtexCO->setCurrentIndex(pos); + latexBibtexED->setText(sel_options.trimmed()); + latexBibtexOptionsLA->setText(qt_("&Options:")); + } else { + latexBibtexED->setText(toqstr(rc.bibtex_command)); + latexBibtexCO->setCurrentIndex(0); + latexBibtexOptionsLA->setText(qt_("Co&mmand:")); + } + + latexIndexCO->clear(); + + latexIndexCO->addItem(qt_("Custom"), QString()); + for (LyXRC::CommandSet::const_iterator it = rc.index_alternatives.begin(); + it != rc.index_alternatives.end(); ++it) { + QString const command = toqstr(*it).left(toqstr(*it).indexOf(" ")); + latexIndexCO->addItem(command, command); + } + + index_alternatives = rc.index_alternatives; + + QString const idx = toqstr(rc.index_command); + ind = idx.indexOf(" "); + sel_command = idx.left(ind); + sel_options = ind < 0 ? QString() : idx.mid(ind + 1); + + pos = latexIndexCO->findData(sel_command); + if (pos != -1) { + latexIndexCO->setCurrentIndex(pos); + latexIndexED->setText(sel_options.trimmed()); + latexIndexOptionsLA->setText(qt_("Op&tions:")); + } else { + latexIndexED->setText(toqstr(rc.index_command)); + latexIndexCO->setCurrentIndex(0); + latexIndexOptionsLA->setText(qt_("Co&mmand:")); + } + + if (rc.fontenc == "default") { + latexEncodingCB->setChecked(false); + latexEncodingED->setEnabled(false); + } else { + latexEncodingCB->setChecked(true); + latexEncodingED->setEnabled(true); + latexEncodingED->setText(toqstr(rc.fontenc)); + } latexChecktexED->setText(toqstr(rc.chktex_command)); - latexBibtexED->setText(toqstr(rc.bibtex_command)); - latexIndexED->setText(toqstr(rc.index_command)); + latexJBibtexED->setText(toqstr(rc.jbibtex_command)); + latexJIndexED->setText(toqstr(rc.jindex_command)); + latexNomenclED->setText(toqstr(rc.nomencl_command)); latexAutoresetCB->setChecked(rc.auto_reset_options); latexDviPaperED->setText(toqstr(rc.view_dvi_paper_option)); latexPaperSizeCO->setCurrentIndex( @@ -584,17 +809,17 @@ void PrefLatex::update(LyXRC const & rc) // ///////////////////////////////////////////////////////////////////// -PrefScreenFonts::PrefScreenFonts(GuiPreferences * form, QWidget * parent) - : PrefModule(qt_(catLookAndFeel), qt_("Screen fonts"), form, parent) +PrefScreenFonts::PrefScreenFonts(GuiPreferences * form) + : PrefModule(qt_(catLookAndFeel), qt_("Screen fonts"), form) { setupUi(this); connect(screenRomanCO, SIGNAL(activated(QString)), - this, SLOT(select_roman(QString))); + this, SLOT(selectRoman(QString))); connect(screenSansCO, SIGNAL(activated(QString)), - this, SLOT(select_sans(QString))); + this, SLOT(selectSans(QString))); connect(screenTypewriterCO, SIGNAL(activated(QString)), - this, SLOT(select_typewriter(QString))); + this, SLOT(selectTypewriter(QString))); QFontDatabase fontdb; QStringList families(fontdb.families()); @@ -662,16 +887,16 @@ void PrefScreenFonts::apply(LyXRC & rc) const rc.zoom = screenZoomSB->value(); rc.dpi = screenDpiSB->value(); - rc.font_sizes[FONT_SIZE_TINY] = fromqstr(screenTinyED->text()); - rc.font_sizes[FONT_SIZE_SCRIPT] = fromqstr(screenSmallestED->text()); - rc.font_sizes[FONT_SIZE_FOOTNOTE] = fromqstr(screenSmallerED->text()); - rc.font_sizes[FONT_SIZE_SMALL] = fromqstr(screenSmallED->text()); - rc.font_sizes[FONT_SIZE_NORMAL] = fromqstr(screenNormalED->text()); - rc.font_sizes[FONT_SIZE_LARGE] = fromqstr(screenLargeED->text()); - rc.font_sizes[FONT_SIZE_LARGER] = fromqstr(screenLargerED->text()); - rc.font_sizes[FONT_SIZE_LARGEST] = fromqstr(screenLargestED->text()); - rc.font_sizes[FONT_SIZE_HUGE] = fromqstr(screenHugeED->text()); - rc.font_sizes[FONT_SIZE_HUGER] = fromqstr(screenHugerED->text()); + rc.font_sizes[FONT_SIZE_TINY] = widgetToDoubleStr(screenTinyED); + rc.font_sizes[FONT_SIZE_SCRIPT] = widgetToDoubleStr(screenSmallestED); + rc.font_sizes[FONT_SIZE_FOOTNOTE] = widgetToDoubleStr(screenSmallerED); + rc.font_sizes[FONT_SIZE_SMALL] = widgetToDoubleStr(screenSmallED); + rc.font_sizes[FONT_SIZE_NORMAL] = widgetToDoubleStr(screenNormalED); + rc.font_sizes[FONT_SIZE_LARGE] = widgetToDoubleStr(screenLargeED); + rc.font_sizes[FONT_SIZE_LARGER] = widgetToDoubleStr(screenLargerED); + rc.font_sizes[FONT_SIZE_LARGEST] = widgetToDoubleStr(screenLargestED); + rc.font_sizes[FONT_SIZE_HUGE] = widgetToDoubleStr(screenHugeED); + rc.font_sizes[FONT_SIZE_HUGER] = widgetToDoubleStr(screenHugerED); rc.use_pixmap_cache = pixmapCacheCB->isChecked(); if (rc.font_sizes != oldrc.font_sizes @@ -698,44 +923,44 @@ void PrefScreenFonts::update(LyXRC const & rc) setComboxFont(screenTypewriterCO, rc.typewriter_font_name, rc.typewriter_font_foundry); - select_roman(screenRomanCO->currentText()); - select_sans(screenSansCO->currentText()); - select_typewriter(screenTypewriterCO->currentText()); + selectRoman(screenRomanCO->currentText()); + selectSans(screenSansCO->currentText()); + selectTypewriter(screenTypewriterCO->currentText()); screenZoomSB->setValue(rc.zoom); screenDpiSB->setValue(rc.dpi); - screenTinyED->setText(toqstr(rc.font_sizes[FONT_SIZE_TINY])); - screenSmallestED->setText(toqstr(rc.font_sizes[FONT_SIZE_SCRIPT])); - screenSmallerED->setText(toqstr(rc.font_sizes[FONT_SIZE_FOOTNOTE])); - screenSmallED->setText(toqstr(rc.font_sizes[FONT_SIZE_SMALL])); - screenNormalED->setText(toqstr(rc.font_sizes[FONT_SIZE_NORMAL])); - screenLargeED->setText(toqstr(rc.font_sizes[FONT_SIZE_LARGE])); - screenLargerED->setText(toqstr(rc.font_sizes[FONT_SIZE_LARGER])); - screenLargestED->setText(toqstr(rc.font_sizes[FONT_SIZE_LARGEST])); - screenHugeED->setText(toqstr(rc.font_sizes[FONT_SIZE_HUGE])); - screenHugerED->setText(toqstr(rc.font_sizes[FONT_SIZE_HUGER])); + doubleToWidget(screenTinyED, rc.font_sizes[FONT_SIZE_TINY]); + doubleToWidget(screenSmallestED, rc.font_sizes[FONT_SIZE_SCRIPT]); + doubleToWidget(screenSmallerED, rc.font_sizes[FONT_SIZE_FOOTNOTE]); + doubleToWidget(screenSmallED, rc.font_sizes[FONT_SIZE_SMALL]); + doubleToWidget(screenNormalED, rc.font_sizes[FONT_SIZE_NORMAL]); + doubleToWidget(screenLargeED, rc.font_sizes[FONT_SIZE_LARGE]); + doubleToWidget(screenLargerED, rc.font_sizes[FONT_SIZE_LARGER]); + doubleToWidget(screenLargestED, rc.font_sizes[FONT_SIZE_LARGEST]); + doubleToWidget(screenHugeED, rc.font_sizes[FONT_SIZE_HUGE]); + doubleToWidget(screenHugerED, rc.font_sizes[FONT_SIZE_HUGER]); pixmapCacheCB->setChecked(rc.use_pixmap_cache); #if defined(Q_WS_X11) pixmapCacheCB->setEnabled(false); #endif - + } -void PrefScreenFonts::select_roman(const QString & name) +void PrefScreenFonts::selectRoman(const QString & name) { screenRomanFE->set(QFont(name), name); } -void PrefScreenFonts::select_sans(const QString & name) +void PrefScreenFonts::selectSans(const QString & name) { screenSansFE->set(QFont(name), name); } -void PrefScreenFonts::select_typewriter(const QString & name) +void PrefScreenFonts::selectTypewriter(const QString & name) { screenTypewriterFE->set(QFont(name), name); } @@ -752,14 +977,15 @@ namespace { struct ColorSorter { bool operator()(ColorCode lhs, ColorCode rhs) const { - return lcolor.getGUIName(lhs) < lcolor.getGUIName(rhs); + return + compare_no_case(lcolor.getGUIName(lhs), lcolor.getGUIName(rhs)) < 0; } }; } // namespace anon -PrefColors::PrefColors(GuiPreferences * form, QWidget * parent) - : PrefModule(qt_(catLookAndFeel), qt_("Colors"), form, parent) +PrefColors::PrefColors(GuiPreferences * form) + : PrefModule(qt_(catLookAndFeel), qt_("Colors"), form) { setupUi(this); @@ -795,11 +1021,11 @@ PrefColors::PrefColors(GuiPreferences * form, QWidget * parent) // End initialization connect(colorChangePB, SIGNAL(clicked()), - this, SLOT(change_color())); + this, SLOT(changeColor())); connect(lyxObjectsLW, SIGNAL(itemSelectionChanged()), - this, SLOT(change_lyxObjects_selection())); + this, SLOT(changeLyxObjectsSelection())); connect(lyxObjectsLW, SIGNAL(itemActivated(QListWidgetItem*)), - this, SLOT(change_color())); + this, SLOT(changeColor())); } @@ -807,7 +1033,7 @@ void PrefColors::apply(LyXRC & /*rc*/) const { for (unsigned int i = 0; i < lcolors_.size(); ++i) if (curcolors_[i] != newcolors_[i]) - form_->setColor(lcolors_[i], fromqstr(newcolors_[i])); + form_->setColor(lcolors_[i], newcolors_[i]); } @@ -820,11 +1046,11 @@ void PrefColors::update(LyXRC const & /*rc*/) lyxObjectsLW->item(i)->setIcon(QIcon(coloritem)); newcolors_[i] = curcolors_[i] = color.name(); } - change_lyxObjects_selection(); + changeLyxObjectsSelection(); } -void PrefColors::change_color() +void PrefColors::changeColor() { int const row = lyxObjectsLW->currentRow(); @@ -845,7 +1071,7 @@ void PrefColors::change_color() } } -void PrefColors::change_lyxObjects_selection() +void PrefColors::changeLyxObjectsSelection() { colorChangePB->setDisabled(lyxObjectsLW->currentRow() < 0); } @@ -857,14 +1083,27 @@ void PrefColors::change_lyxObjects_selection() // ///////////////////////////////////////////////////////////////////// -PrefDisplay::PrefDisplay(QWidget * parent) - : PrefModule(qt_(catLookAndFeel), qt_("Graphics"), 0, parent) +PrefDisplay::PrefDisplay(GuiPreferences * form) + : PrefModule(qt_(catLookAndFeel), qt_("Display"), form) { setupUi(this); - connect(instantPreviewCO, SIGNAL(activated(int)), - this, SIGNAL(changed())); - connect(displayGraphicsCO, SIGNAL(activated(int)), - this, SIGNAL(changed())); + connect(displayGraphicsCB, SIGNAL(toggled(bool)), this, SIGNAL(changed())); + connect(instantPreviewCO, SIGNAL(activated(int)), this, SIGNAL(changed())); + connect(previewSizeSB, SIGNAL(valueChanged(double)), this, SIGNAL(changed())); + connect(paragraphMarkerCB, SIGNAL(toggled(bool)), this, SIGNAL(changed())); + if (instantPreviewCO->currentIndex() == 0) + previewSizeSB->setEnabled(false); + else + previewSizeSB->setEnabled(true); +} + + +void PrefDisplay::on_instantPreviewCO_currentIndexChanged(int index) +{ + if (index == 0) + previewSizeSB->setEnabled(false); + else + previewSizeSB->setEnabled(true); } @@ -876,15 +1115,9 @@ void PrefDisplay::apply(LyXRC & rc) const case 2: rc.preview = LyXRC::PREVIEW_ON; break; } - graphics::DisplayType dtype; - switch (displayGraphicsCO->currentIndex()) { - case 3: dtype = graphics::NoDisplay; break; - case 2: dtype = graphics::ColorDisplay; break; - case 1: dtype = graphics::GrayscaleDisplay; break; - case 0: dtype = graphics::MonochromeDisplay; break; - default: dtype = graphics::GrayscaleDisplay; - } - rc.display_graphics = dtype; + rc.display_graphics = displayGraphicsCB->isChecked(); + rc.preview_scale_factor = previewSizeSB->value(); + rc.paragraph_markers = paragraphMarkerCB->isChecked(); // FIXME!! The graphics cache no longer has a changeDisplay method. #if 0 @@ -910,15 +1143,10 @@ void PrefDisplay::update(LyXRC const & rc) break; } - int item = 2; - switch (rc.display_graphics) { - case graphics::NoDisplay: item = 3; break; - case graphics::ColorDisplay: item = 2; break; - case graphics::GrayscaleDisplay: item = 1; break; - case graphics::MonochromeDisplay: item = 0; break; - default: break; - } - displayGraphicsCO->setCurrentIndex(item); + displayGraphicsCB->setChecked(rc.display_graphics); + instantPreviewCO->setEnabled(rc.display_graphics); + previewSizeSB->setValue(rc.preview_scale_factor); + paragraphMarkerCB->setChecked(rc.paragraph_markers); } @@ -928,28 +1156,43 @@ void PrefDisplay::update(LyXRC const & rc) // ///////////////////////////////////////////////////////////////////// -PrefPaths::PrefPaths(GuiPreferences * form, QWidget * parent) - : PrefModule(QString(), qt_("Paths"), form, parent) +PrefPaths::PrefPaths(GuiPreferences * form) + : PrefModule(QString(), qt_("Paths"), form) { setupUi(this); - connect(exampleDirPB, SIGNAL(clicked()), this, SLOT(select_exampledir())); - connect(templateDirPB, SIGNAL(clicked()), this, SLOT(select_templatedir())); - connect(tempDirPB, SIGNAL(clicked()), this, SLOT(select_tempdir())); - connect(backupDirPB, SIGNAL(clicked()), this, SLOT(select_backupdir())); - connect(workingDirPB, SIGNAL(clicked()), this, SLOT(select_workingdir())); - connect(lyxserverDirPB, SIGNAL(clicked()), this, SLOT(select_lyxpipe())); + + connect(workingDirPB, SIGNAL(clicked()), this, SLOT(selectWorkingdir())); connect(workingDirED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(exampleDirED, SIGNAL(textChanged(QString)), - this, SIGNAL(changed())); + + connect(templateDirPB, SIGNAL(clicked()), this, SLOT(selectTemplatedir())); connect(templateDirED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); + + connect(exampleDirPB, SIGNAL(clicked()), this, SLOT(selectExampledir())); + connect(exampleDirED, SIGNAL(textChanged(QString)), + this, SIGNAL(changed())); + + connect(backupDirPB, SIGNAL(clicked()), this, SLOT(selectBackupdir())); connect(backupDirED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); + + connect(lyxserverDirPB, SIGNAL(clicked()), this, SLOT(selectLyxPipe())); + connect(lyxserverDirED, SIGNAL(textChanged(QString)), + this, SIGNAL(changed())); + + connect(thesaurusDirPB, SIGNAL(clicked()), this, SLOT(selectThesaurusdir())); + connect(thesaurusDirED, SIGNAL(textChanged(QString)), + this, SIGNAL(changed())); + + connect(tempDirPB, SIGNAL(clicked()), this, SLOT(selectTempdir())); connect(tempDirED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(lyxserverDirED, SIGNAL(textChanged(QString)), + + connect(hunspellDirPB, SIGNAL(clicked()), this, SLOT(selectHunspelldir())); + connect(hunspellDirED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); + connect(pathPrefixED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); } @@ -962,6 +1205,8 @@ void PrefPaths::apply(LyXRC & rc) const rc.template_path = internal_path(fromqstr(templateDirED->text())); rc.backupdir_path = internal_path(fromqstr(backupDirED->text())); rc.tempdir_path = internal_path(fromqstr(tempDirED->text())); + rc.thesaurusdir_path = internal_path(fromqstr(thesaurusDirED->text())); + rc.hunspelldir_path = internal_path(fromqstr(hunspellDirED->text())); rc.path_prefix = internal_path_list(fromqstr(pathPrefixED->text())); // FIXME: should be a checkbox only rc.lyxpipes = internal_path(fromqstr(lyxserverDirED->text())); @@ -975,13 +1220,15 @@ void PrefPaths::update(LyXRC const & rc) templateDirED->setText(toqstr(external_path(rc.template_path))); backupDirED->setText(toqstr(external_path(rc.backupdir_path))); tempDirED->setText(toqstr(external_path(rc.tempdir_path))); + thesaurusDirED->setText(toqstr(external_path(rc.thesaurusdir_path))); + hunspellDirED->setText(toqstr(external_path(rc.hunspelldir_path))); pathPrefixED->setText(toqstr(external_path_list(rc.path_prefix))); // FIXME: should be a checkbox only lyxserverDirED->setText(toqstr(external_path(rc.lyxpipes))); } -void PrefPaths::select_exampledir() +void PrefPaths::selectExampledir() { QString file = browseDir(internalPath(exampleDirED->text()), qt_("Select directory for example files")); @@ -990,7 +1237,7 @@ void PrefPaths::select_exampledir() } -void PrefPaths::select_templatedir() +void PrefPaths::selectTemplatedir() { QString file = browseDir(internalPath(templateDirED->text()), qt_("Select a document templates directory")); @@ -999,7 +1246,7 @@ void PrefPaths::select_templatedir() } -void PrefPaths::select_tempdir() +void PrefPaths::selectTempdir() { QString file = browseDir(internalPath(tempDirED->text()), qt_("Select a temporary directory")); @@ -1008,7 +1255,7 @@ void PrefPaths::select_tempdir() } -void PrefPaths::select_backupdir() +void PrefPaths::selectBackupdir() { QString file = browseDir(internalPath(backupDirED->text()), qt_("Select a backups directory")); @@ -1017,7 +1264,7 @@ void PrefPaths::select_backupdir() } -void PrefPaths::select_workingdir() +void PrefPaths::selectWorkingdir() { QString file = browseDir(internalPath(workingDirED->text()), qt_("Select a document directory")); @@ -1026,7 +1273,25 @@ void PrefPaths::select_workingdir() } -void PrefPaths::select_lyxpipe() +void PrefPaths::selectThesaurusdir() +{ + QString file = browseDir(internalPath(thesaurusDirED->text()), + qt_("Set the path to the thesaurus dictionaries")); + if (!file.isEmpty()) + thesaurusDirED->setText(file); +} + + +void PrefPaths::selectHunspelldir() +{ + QString file = browseDir(internalPath(hunspellDirED->text()), + qt_("Set the path to the Hunspell dictionaries")); + if (!file.isEmpty()) + hunspellDirED->setText(file); +} + + +void PrefPaths::selectLyxPipe() { QString file = form_->browse(internalPath(lyxserverDirED->text()), qt_("Give a filename for the LyX server pipe")); @@ -1041,104 +1306,61 @@ void PrefPaths::select_lyxpipe() // ///////////////////////////////////////////////////////////////////// -PrefSpellchecker::PrefSpellchecker(GuiPreferences * form, QWidget * parent) - : PrefModule(qt_(catLanguage), qt_("Spellchecker"), form, parent) +PrefSpellchecker::PrefSpellchecker(GuiPreferences * form) + : PrefModule(qt_(catLanguage), qt_("Spellchecker"), form) { setupUi(this); - connect(persDictionaryPB, SIGNAL(clicked()), this, SLOT(select_dict())); -#if defined (USE_ISPELL) - connect(spellCommandCO, SIGNAL(activated(int)), - this, SIGNAL(changed())); -#else - spellCommandCO->setEnabled(false); +#if defined(USE_ASPELL) + spellcheckerCB->addItem(qt_("aspell"), QString("aspell")); #endif - connect(altLanguageED, SIGNAL(textChanged(QString)), - this, SIGNAL(changed())); - connect(escapeCharactersED, SIGNAL(textChanged(QString)), - this, SIGNAL(changed())); - connect(persDictionaryED, SIGNAL(textChanged(QString)), - this, SIGNAL(changed())); - connect(compoundWordCB, SIGNAL(clicked()), - this, SIGNAL(changed())); - connect(inputEncodingCB, SIGNAL(clicked()), - this, SIGNAL(changed())); - - spellCommandCO->addItem(qt_("ispell")); - spellCommandCO->addItem(qt_("aspell")); - spellCommandCO->addItem(qt_("hspell")); -#ifdef USE_PSPELL - spellCommandCO->addItem(qt_("pspell (library)")); -#else -#ifdef USE_ASPELL - spellCommandCO->addItem(qt_("aspell (library)")); +#if defined(USE_ENCHANT) + spellcheckerCB->addItem(qt_("enchant"), QString("enchant")); #endif +#if defined(USE_HUNSPELL) + spellcheckerCB->addItem(qt_("hunspell"), QString("hunspell")); #endif -} - -void PrefSpellchecker::apply(LyXRC & rc) const -{ - switch (spellCommandCO->currentIndex()) { - case 0: - case 1: - case 2: - rc.use_spell_lib = false; - rc.isp_command = fromqstr(spellCommandCO->currentText()); - break; - case 3: - rc.use_spell_lib = true; - break; + if (theSpellChecker()) { + connect(spellcheckerCB, SIGNAL(currentIndexChanged(int)), + this, SIGNAL(changed())); + connect(altLanguageED, SIGNAL(textChanged(QString)), + this, SIGNAL(changed())); + connect(escapeCharactersED, SIGNAL(textChanged(QString)), + this, SIGNAL(changed())); + connect(compoundWordCB, SIGNAL(clicked()), + this, SIGNAL(changed())); + connect(spellcheckContinuouslyCB, SIGNAL(clicked()), + this, SIGNAL(changed())); + } else { + spellcheckerCB->setEnabled(false); + altLanguageED->setEnabled(false); + escapeCharactersED->setEnabled(false); + compoundWordCB->setEnabled(false); + spellcheckContinuouslyCB->setEnabled(false); } - - // FIXME: remove isp_use_alt_lang - rc.isp_alt_lang = fromqstr(altLanguageED->text()); - rc.isp_use_alt_lang = !rc.isp_alt_lang.empty(); - // FIXME: remove isp_use_esc_chars - rc.isp_esc_chars = fromqstr(escapeCharactersED->text()); - rc.isp_use_esc_chars = !rc.isp_esc_chars.empty(); - // FIXME: remove isp_use_pers_dict - rc.isp_pers_dict = internal_path(fromqstr(persDictionaryED->text())); - rc.isp_use_pers_dict = !rc.isp_pers_dict.empty(); - rc.isp_accept_compound = compoundWordCB->isChecked(); - rc.isp_use_input_encoding = inputEncodingCB->isChecked(); } -void PrefSpellchecker::update(LyXRC const & rc) +void PrefSpellchecker::apply(LyXRC & rc) const { - spellCommandCO->setCurrentIndex(0); - - if (rc.isp_command == "ispell") { - spellCommandCO->setCurrentIndex(0); - } else if (rc.isp_command == "aspell") { - spellCommandCO->setCurrentIndex(1); - } else if (rc.isp_command == "hspell") { - spellCommandCO->setCurrentIndex(2); - } - - if (rc.use_spell_lib) { -#if defined(USE_ASPELL) || defined(USE_PSPELL) - spellCommandCO->setCurrentIndex(3); -#endif - } - - // FIXME: remove isp_use_alt_lang - altLanguageED->setText(toqstr(rc.isp_alt_lang)); - // FIXME: remove isp_use_esc_chars - escapeCharactersED->setText(toqstr(rc.isp_esc_chars)); - // FIXME: remove isp_use_pers_dict - persDictionaryED->setText(toqstr(external_path(rc.isp_pers_dict))); - compoundWordCB->setChecked(rc.isp_accept_compound); - inputEncodingCB->setChecked(rc.isp_use_input_encoding); + rc.spellchecker = fromqstr(spellcheckerCB->itemData( + spellcheckerCB->currentIndex()).toString()); + rc.spellchecker_alt_lang = fromqstr(altLanguageED->text()); + rc.spellchecker_esc_chars = fromqstr(escapeCharactersED->text()); + rc.spellchecker_accept_compound = compoundWordCB->isChecked(); + rc.spellcheck_continuously = spellcheckContinuouslyCB->isChecked(); } -void PrefSpellchecker::select_dict() +void PrefSpellchecker::update(LyXRC const & rc) { - QString file = form_->browsedict(internalPath(persDictionaryED->text())); - if (!file.isEmpty()) - persDictionaryED->setText(file); + spellcheckerCB->setCurrentIndex( + spellcheckerCB->findData(toqstr(rc.spellchecker))); + altLanguageED->setText(toqstr(rc.spellchecker_alt_lang)); + escapeCharactersED->setText(toqstr(rc.spellchecker_esc_chars)); + compoundWordCB->setChecked(rc.spellchecker_accept_compound); + spellcheckContinuouslyCB->setChecked(rc.spellcheck_continuously); } @@ -1150,27 +1372,27 @@ void PrefSpellchecker::select_dict() ///////////////////////////////////////////////////////////////////// -PrefConverters::PrefConverters(GuiPreferences * form, QWidget * parent) - : PrefModule(qt_(catFiles), qt_("Converters"), form, parent) +PrefConverters::PrefConverters(GuiPreferences * form) + : PrefModule(qt_(catFiles), qt_("Converters"), form) { setupUi(this); connect(converterNewPB, SIGNAL(clicked()), - this, SLOT(update_converter())); + this, SLOT(updateConverter())); connect(converterRemovePB, SIGNAL(clicked()), - this, SLOT(remove_converter())); + this, SLOT(removeConverter())); connect(converterModifyPB, SIGNAL(clicked()), - this, SLOT(update_converter())); + this, SLOT(updateConverter())); connect(convertersLW, SIGNAL(currentRowChanged(int)), - this, SLOT(switch_converter())); + this, SLOT(switchConverter())); connect(converterFromCO, SIGNAL(activated(QString)), - this, SLOT(converter_changed())); + this, SLOT(changeConverter())); connect(converterToCO, SIGNAL(activated(QString)), - this, SLOT(converter_changed())); + this, SLOT(changeConverter())); connect(converterED, SIGNAL(textEdited(QString)), - this, SLOT(converter_changed())); + this, SLOT(changeConverter())); connect(converterFlagED, SIGNAL(textEdited(QString)), - this, SLOT(converter_changed())); + this, SLOT(changeConverter())); connect(converterNewPB, SIGNAL(clicked()), this, SIGNAL(changed())); connect(converterRemovePB, SIGNAL(clicked()), @@ -1188,7 +1410,7 @@ PrefConverters::PrefConverters(GuiPreferences * form, QWidget * parent) void PrefConverters::apply(LyXRC & rc) const { rc.use_converter_cache = cacheCB->isChecked(); - rc.converter_cache_maxage = int(maxAgeLE->text().toDouble() * 86400.0); + rc.converter_cache_maxage = int(widgetToDouble(maxAgeLE) * 86400.0); } @@ -1196,8 +1418,7 @@ void PrefConverters::update(LyXRC const & rc) { cacheCB->setChecked(rc.use_converter_cache); QString max_age; - max_age.setNum(double(rc.converter_cache_maxage) / 86400.0, 'g', 6); - maxAgeLE->setText(max_age); + doubleToWidget(maxAgeLE, (double(rc.converter_cache_maxage) / 86400.0), 'g', 6); updateGui(); } @@ -1216,22 +1437,22 @@ void PrefConverters::updateGui() Formats::const_iterator cit = form_->formats().begin(); Formats::const_iterator end = form_->formats().end(); for (; cit != end; ++cit) { - converterFromCO->addItem(toqstr(cit->prettyname())); - converterToCO->addItem(toqstr(cit->prettyname())); + converterFromCO->addItem(qt_(cit->prettyname())); + converterToCO->addItem(qt_(cit->prettyname())); } // currentRowChanged(int) is also triggered when updating the listwidget - // block signals to avoid unnecessary calls to switch_converter() + // block signals to avoid unnecessary calls to switchConverter() convertersLW->blockSignals(true); convertersLW->clear(); Converters::const_iterator ccit = form_->converters().begin(); Converters::const_iterator cend = form_->converters().end(); for (; ccit != cend; ++ccit) { - string const name = - ccit->From->prettyname() + " -> " + ccit->To->prettyname(); + QString const name = + qt_(ccit->From->prettyname()) + " -> " + qt_(ccit->To->prettyname()); int type = form_->converters().getNumber(ccit->From->name(), ccit->To->name()); - new QListWidgetItem(toqstr(name), convertersLW, type); + new QListWidgetItem(name, convertersLW, type); } convertersLW->sortItems(Qt::AscendingOrder); convertersLW->blockSignals(false); @@ -1252,7 +1473,7 @@ void PrefConverters::updateGui() } -void PrefConverters::switch_converter() +void PrefConverters::switchConverter() { int const cnr = convertersLW->currentItem()->type(); Converter const & c(form_->converters().get(cnr)); @@ -1265,7 +1486,7 @@ void PrefConverters::switch_converter() } -void PrefConverters::converter_changed() +void PrefConverters::changeConverter() { updateButtons(); } @@ -1281,13 +1502,13 @@ void PrefConverters::updateButtons() || from.name() == to.name()); int const cnr = convertersLW->currentItem()->type(); - Converter const & c(form_->converters().get(cnr)); + Converter const & c = form_->converters().get(cnr); string const old_command = c.command; string const old_flag = c.flags; - string const new_command(fromqstr(converterED->text())); - string const new_flag(fromqstr(converterFlagED->text())); + string const new_command = fromqstr(converterED->text()); + string const new_flag = fromqstr(converterFlagED->text()); - bool modified = (old_command != new_command) || (old_flag != new_flag); + bool modified = (old_command != new_command || old_flag != new_flag); converterModifyPB->setEnabled(valid && known && modified); converterNewPB->setEnabled(valid && !known); @@ -1301,7 +1522,7 @@ void PrefConverters::updateButtons() // FIXME: user must // specify unique from/to or it doesn't appear. This is really bad UI // this is why we can use the same function for both new and modify -void PrefConverters::update_converter() +void PrefConverters::updateConverter() { Format const & from = form_->formats().get(converterFromCO->currentIndex()); Format const & to = form_->formats().get(converterToCO->currentIndex()); @@ -1323,7 +1544,7 @@ void PrefConverters::update_converter() } -void PrefConverters::remove_converter() +void PrefConverters::removeConverter() { Format const & from = form_->formats().get(converterFromCO->currentIndex()); Format const & to = form_->formats().get(converterToCO->currentIndex()); @@ -1347,11 +1568,24 @@ void PrefConverters::on_cacheCB_stateChanged(int state) ///////////////////////////////////////////////////////////////////// // -// PrefFileformats +// FormatValidator // ///////////////////////////////////////////////////////////////////// -// -FormatValidator::FormatValidator(QWidget * parent, Formats const & f) + +class FormatValidator : public QValidator +{ +public: + FormatValidator(QWidget *, Formats const & f); + void fixup(QString & input) const; + QValidator::State validate(QString & input, int & pos) const; +private: + virtual QString toString(Format const & format) const = 0; + int nr() const; + Formats const & formats_; +}; + + +FormatValidator::FormatValidator(QWidget * parent, Formats const & f) : QValidator(parent), formats_(f) { } @@ -1362,11 +1596,10 @@ void FormatValidator::fixup(QString & input) const Formats::const_iterator cit = formats_.begin(); Formats::const_iterator end = formats_.end(); for (; cit != end; ++cit) { - string const name = str(cit); + QString const name = toString(*cit); if (distance(formats_.begin(), cit) == nr()) { - input = toqstr(name); + input = name; return; - } } } @@ -1378,12 +1611,12 @@ QValidator::State FormatValidator::validate(QString & input, int & /*pos*/) cons Formats::const_iterator end = formats_.end(); bool unknown = true; for (; unknown && cit != end; ++cit) { - string const name = str(cit); + QString const name = toString(*cit); if (distance(formats_.begin(), cit) != nr()) - unknown = toqstr(name) != input; + unknown = name != input; } - if (unknown && !input.isEmpty()) + if (unknown && !input.isEmpty()) return QValidator::Acceptable; else return QValidator::Intermediate; @@ -1397,31 +1630,54 @@ int FormatValidator::nr() const } -FormatNameValidator::FormatNameValidator(QWidget * parent, Formats const & f) - : FormatValidator(parent, f) -{ -} +///////////////////////////////////////////////////////////////////// +// +// FormatNameValidator +// +///////////////////////////////////////////////////////////////////// -string FormatNameValidator::str(Formats::const_iterator it) const +class FormatNameValidator : public FormatValidator { - return it->name(); -} +public: + FormatNameValidator(QWidget * parent, Formats const & f) + : FormatValidator(parent, f) + {} +private: + QString toString(Format const & format) const + { + return toqstr(format.name()); + } +}; -FormatPrettynameValidator::FormatPrettynameValidator(QWidget * parent, Formats const & f) - : FormatValidator(parent, f) -{ -} - +///////////////////////////////////////////////////////////////////// +// +// FormatPrettynameValidator +// +///////////////////////////////////////////////////////////////////// -string FormatPrettynameValidator::str(Formats::const_iterator it) const +class FormatPrettynameValidator : public FormatValidator { - return it->prettyname(); -} +public: + FormatPrettynameValidator(QWidget * parent, Formats const & f) + : FormatValidator(parent, f) + {} +private: + QString toString(Format const & format) const + { + return qt_(format.prettyname()); + } +}; -PrefFileformats::PrefFileformats(GuiPreferences * form, QWidget * parent) - : PrefModule(qt_(catFiles), qt_("File formats"), form, parent) +///////////////////////////////////////////////////////////////////// +// +// PrefFileformats +// +///////////////////////////////////////////////////////////////////// + +PrefFileformats::PrefFileformats(GuiPreferences * form) + : PrefModule(qt_(catFiles), qt_("File formats"), form) { setupUi(this); formatED->setValidator(new FormatNameValidator(formatsCB, form_->formats())); @@ -1435,39 +1691,82 @@ PrefFileformats::PrefFileformats(GuiPreferences * form, QWidget * parent) this, SLOT(updatePrettyname())); connect(formatsCB->lineEdit(), SIGNAL(textEdited(QString)), this, SIGNAL(changed())); + connect(defaultFormatCB, SIGNAL(activated(QString)), + this, SIGNAL(changed())); + connect(viewerCO, SIGNAL(activated(int)), + this, SIGNAL(changed())); + connect(editorCO, SIGNAL(activated(int)), + this, SIGNAL(changed())); +} + + +namespace { + +string const l10n_shortcut(string const prettyname, string const shortcut) +{ + if (shortcut.empty()) + return string(); + + string l10n_format = + to_utf8(_(prettyname + '|' + shortcut)); + return split(l10n_format, '|'); } +}; // namespace anon -void PrefFileformats::apply(LyXRC & /*rc*/) const + +void PrefFileformats::apply(LyXRC & rc) const { + QString const default_format = defaultFormatCB->itemData( + defaultFormatCB->currentIndex()).toString(); + rc.default_view_format = fromqstr(default_format); } -void PrefFileformats::update(LyXRC const & /*rc*/) +void PrefFileformats::update(LyXRC const & rc) { + viewer_alternatives = rc.viewer_alternatives; + editor_alternatives = rc.editor_alternatives; + bool const init = defaultFormatCB->currentText().isEmpty(); updateView(); + if (init) { + int const pos = + defaultFormatCB->findData(toqstr(rc.default_view_format)); + defaultFormatCB->setCurrentIndex(pos); + } } void PrefFileformats::updateView() { QString const current = formatsCB->currentText(); + QString const current_def = defaultFormatCB->currentText(); - // update combobox with formats + // update comboboxes with formats formatsCB->blockSignals(true); + defaultFormatCB->blockSignals(true); formatsCB->clear(); + defaultFormatCB->clear(); form_->formats().sort(); Formats::const_iterator cit = form_->formats().begin(); Formats::const_iterator end = form_->formats().end(); - for (; cit != end; ++cit) - formatsCB->addItem(toqstr(cit->prettyname()), - QVariant(form_->formats().getNumber(cit->name())) ); + for (; cit != end; ++cit) { + formatsCB->addItem(qt_(cit->prettyname()), + QVariant(form_->formats().getNumber(cit->name()))); + if (form_->converters().isReachable("latex", cit->name()) + || form_->converters().isReachable("pdflatex", cit->name())) + defaultFormatCB->addItem(qt_(cit->prettyname()), + QVariant(toqstr(cit->name()))); + } // restore selection - int const item = formatsCB->findText(current, Qt::MatchExactly); + int item = formatsCB->findText(current, Qt::MatchExactly); formatsCB->setCurrentIndex(item < 0 ? 0 : item); on_formatsCB_currentIndexChanged(item < 0 ? 0 : item); + item = defaultFormatCB->findText(current_def, Qt::MatchExactly); + defaultFormatCB->setCurrentIndex(item < 0 ? 0 : item); formatsCB->blockSignals(false); + defaultFormatCB->blockSignals(false); } @@ -1479,11 +1778,12 @@ void PrefFileformats::on_formatsCB_currentIndexChanged(int i) formatED->setText(toqstr(f.name())); copierED->setText(toqstr(form_->movers().command(f.name()))); extensionED->setText(toqstr(f.extension())); - shortcutED->setText(toqstr(f.shortcut())); - viewerED->setText(toqstr(f.viewer())); - editorED->setText(toqstr(f.editor())); + shortcutED->setText( + toqstr(l10n_shortcut(f.prettyname(), f.shortcut()))); documentCB->setChecked((f.documentFormat())); vectorCB->setChecked((f.vectorFormat())); + updateViewers(); + updateEditors(); } @@ -1529,7 +1829,11 @@ void PrefFileformats::on_editorED_textEdited(const QString & s) void PrefFileformats::on_shortcutED_textEdited(const QString & s) { - currentFormat().setShortcut(fromqstr(s)); + string const new_shortcut = fromqstr(s); + if (new_shortcut == l10n_shortcut(currentFormat().prettyname(), + currentFormat().shortcut())) + return; + currentFormat().setShortcut(new_shortcut); changed(); } @@ -1565,17 +1869,102 @@ void PrefFileformats::on_formatsCB_editTextChanged(const QString &) void PrefFileformats::updatePrettyname() { - string const newname = fromqstr(formatsCB->currentText()); - if (newname == currentFormat().prettyname()) + QString const newname = formatsCB->currentText(); + if (newname == qt_(currentFormat().prettyname())) return; - currentFormat().setPrettyname(newname); + currentFormat().setPrettyname(fromqstr(newname)); formatsChanged(); updateView(); changed(); } +namespace { + void updateComboBox(LyXRC::Alternatives const & alts, + string const & fmt, QComboBox * combo) + { + LyXRC::Alternatives::const_iterator it = + alts.find(fmt); + if (it != alts.end()) { + LyXRC::CommandSet const & cmds = it->second; + LyXRC::CommandSet::const_iterator sit = + cmds.begin(); + LyXRC::CommandSet::const_iterator const sen = + cmds.end(); + for (; sit != sen; ++sit) { + QString const qcmd = toqstr(*sit); + combo->addItem(qcmd, qcmd); + } + } + } +} + + +void PrefFileformats::updateViewers() +{ + Format const f = currentFormat(); + viewerCO->blockSignals(true); + viewerCO->clear(); + viewerCO->addItem(qt_("None"), QString()); + updateComboBox(viewer_alternatives, f.name(), viewerCO); + viewerCO->addItem(qt_("Custom"), QString("custom viewer")); + viewerCO->blockSignals(false); + + int pos = viewerCO->findData(toqstr(f.viewer())); + if (pos != -1) { + viewerED->clear(); + viewerED->setEnabled(false); + viewerCO->setCurrentIndex(pos); + } else { + viewerED->setEnabled(true); + viewerED->setText(toqstr(f.viewer())); + viewerCO->setCurrentIndex(viewerCO->findData(toqstr("custom viewer"))); + } +} + + +void PrefFileformats::updateEditors() +{ + Format const f = currentFormat(); + editorCO->blockSignals(true); + editorCO->clear(); + editorCO->addItem(qt_("None"), QString()); + updateComboBox(editor_alternatives, f.name(), editorCO); + editorCO->addItem(qt_("Custom"), QString("custom editor")); + editorCO->blockSignals(false); + + int pos = editorCO->findData(toqstr(f.editor())); + if (pos != -1) { + editorED->clear(); + editorED->setEnabled(false); + editorCO->setCurrentIndex(pos); + } else { + editorED->setEnabled(true); + editorED->setText(toqstr(f.editor())); + editorCO->setCurrentIndex(editorCO->findData(toqstr("custom editor"))); + } +} + + +void PrefFileformats::on_viewerCO_currentIndexChanged(int i) +{ + bool const custom = viewerCO->itemData(i).toString() == "custom viewer"; + viewerED->setEnabled(custom); + if (!custom) + currentFormat().setViewer(fromqstr(viewerCO->itemData(i).toString())); +} + + +void PrefFileformats::on_editorCO_currentIndexChanged(int i) +{ + bool const custom = editorCO->itemData(i).toString() == "custom editor"; + editorED->setEnabled(custom); + if (!custom) + currentFormat().setEditor(fromqstr(editorCO->itemData(i).toString())); +} + + Format & PrefFileformats::currentFormat() { int const i = formatsCB->currentIndex(); @@ -1619,8 +2008,8 @@ void PrefFileformats::on_formatRemovePB_clicked() // ///////////////////////////////////////////////////////////////////// -PrefLanguage::PrefLanguage(QWidget * parent) - : PrefModule(qt_(catLanguage), qt_("Language"), 0, parent) +PrefLanguage::PrefLanguage(GuiPreferences * form) + : PrefModule(qt_(catLanguage), qt_("Language"), form) { setupUi(this); @@ -1646,12 +2035,33 @@ PrefLanguage::PrefLanguage(QWidget * parent) this, SIGNAL(changed())); connect(endCommandED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(defaultLanguageCO, SIGNAL(activated(int)), + connect(uiLanguageCO, SIGNAL(activated(int)), this, SIGNAL(changed())); - defaultLanguageCO->clear(); + uiLanguageCO->clear(); + + QAbstractItemModel * language_model = guiApp->languageModel(); + // FIXME: it would be nice if sorting was enabled/disabled via a checkbox. + language_model->sort(0); - defaultLanguageCO->setModel(guiApp->languageModel()); + // FIXME: This is wrong, we need filter this list based on the available + // translation. + uiLanguageCO->blockSignals(true); + uiLanguageCO->addItem(qt_("Default"), toqstr("auto")); + for (int i = 0; i != language_model->rowCount(); ++i) { + QModelIndex index = language_model->index(i, 0); + uiLanguageCO->addItem(index.data(Qt::DisplayRole).toString(), + index.data(Qt::UserRole).toString()); + } + uiLanguageCO->blockSignals(false); +} + + +void PrefLanguage::on_uiLanguageCO_currentIndexChanged(int) +{ + QMessageBox::information(this, qt_("LyX needs to be restarted!"), + qt_("The change of user interface language will be fully " + "effective only after a restart.")); } @@ -1668,8 +2078,8 @@ void PrefLanguage::apply(LyXRC & rc) const rc.language_package = fromqstr(languagePackageED->text()); rc.language_command_begin = fromqstr(startCommandED->text()); rc.language_command_end = fromqstr(endCommandED->text()); - rc.default_language = fromqstr( - defaultLanguageCO->itemData(defaultLanguageCO->currentIndex()).toString()); + rc.gui_language = fromqstr( + uiLanguageCO->itemData(uiLanguageCO->currentIndex()).toString()); } @@ -1690,8 +2100,10 @@ void PrefLanguage::update(LyXRC const & rc) startCommandED->setText(toqstr(rc.language_command_begin)); endCommandED->setText(toqstr(rc.language_command_end)); - int const pos = defaultLanguageCO->findData(toqstr(rc.default_language)); - defaultLanguageCO->setCurrentIndex(pos); + int pos = uiLanguageCO->findData(toqstr(rc.gui_language)); + uiLanguageCO->blockSignals(true); + uiLanguageCO->setCurrentIndex(pos); + uiLanguageCO->blockSignals(false); } @@ -1701,8 +2113,8 @@ void PrefLanguage::update(LyXRC const & rc) // ///////////////////////////////////////////////////////////////////// -PrefPrinter::PrefPrinter(QWidget * parent) - : PrefModule(qt_(catOutput), qt_("Printer"), 0, parent) +PrefPrinter::PrefPrinter(GuiPreferences * form) + : PrefModule(qt_(catOutput), qt_("Printer"), form) { setupUi(this); @@ -1799,8 +2211,8 @@ void PrefPrinter::update(LyXRC const & rc) // ///////////////////////////////////////////////////////////////////// -PrefUserInterface::PrefUserInterface(GuiPreferences * form, QWidget * parent) - : PrefModule(qt_(catLookAndFeel), qt_("User interface"), form, parent) +PrefUserInterface::PrefUserInterface(GuiPreferences * form) + : PrefModule(qt_(catLookAndFeel), qt_("User interface"), form) { setupUi(this); @@ -1810,8 +2222,13 @@ PrefUserInterface::PrefUserInterface(GuiPreferences * form, QWidget * parent) TextLabel1, SLOT(setEnabled(bool))); connect(openDocumentsInTabsCB, SIGNAL(clicked()), this, SIGNAL(changed())); +#if QT_VERSION < 0x040500 + singleCloseTabButtonCB->setEnabled(false); +#endif + connect(singleCloseTabButtonCB, SIGNAL(clicked()), + this, SIGNAL(changed())); connect(uiFilePB, SIGNAL(clicked()), - this, SLOT(select_ui())); + this, SLOT(selectUi())); connect(uiFileED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); connect(restoreCursorCB, SIGNAL(clicked()), @@ -1824,6 +2241,8 @@ PrefUserInterface::PrefUserInterface(GuiPreferences * form, QWidget * parent) this, SIGNAL(changed())); connect(autoSaveCB, SIGNAL(clicked()), this, SIGNAL(changed())); + connect(backupCB, SIGNAL(clicked()), + this, SIGNAL(changed())); connect(lastfilesSB, SIGNAL(valueChanged(int)), this, SIGNAL(changed())); connect(tooltipCB, SIGNAL(toggled(bool)), @@ -1838,11 +2257,15 @@ void PrefUserInterface::apply(LyXRC & rc) const rc.use_lastfilepos = restoreCursorCB->isChecked(); rc.load_session = loadSessionCB->isChecked(); rc.allow_geometry_session = allowGeometrySessionCB->isChecked(); - rc.autosave = autoSaveSB->value() * 60; - rc.make_backup = autoSaveCB->isChecked(); + rc.autosave = autoSaveCB->isChecked()? autoSaveSB->value() * 60 : 0; + rc.make_backup = backupCB->isChecked(); rc.num_lastfiles = lastfilesSB->value(); rc.use_tooltip = tooltipCB->isChecked(); rc.open_buffers_in_tabs = openDocumentsInTabsCB->isChecked(); + rc.single_close_tab_button = singleCloseTabButtonCB->isChecked(); +#if QT_VERSION < 0x040500 + rc.single_close_tab_button = true; +#endif } @@ -1853,37 +2276,51 @@ void PrefUserInterface::update(LyXRC const & rc) loadSessionCB->setChecked(rc.load_session); allowGeometrySessionCB->setChecked(rc.allow_geometry_session); // convert to minutes - int mins(rc.autosave / 60); - if (rc.autosave && !mins) - mins = 1; + bool autosave = rc.autosave > 0; + int mins = rc.autosave / 60; + if (!mins) + mins = 5; autoSaveSB->setValue(mins); - autoSaveCB->setChecked(rc.make_backup); + autoSaveCB->setChecked(autosave); + autoSaveSB->setEnabled(autosave); + backupCB->setChecked(rc.make_backup); lastfilesSB->setValue(rc.num_lastfiles); tooltipCB->setChecked(rc.use_tooltip); openDocumentsInTabsCB->setChecked(rc.open_buffers_in_tabs); + singleCloseTabButtonCB->setChecked(rc.single_close_tab_button); } -void PrefUserInterface::select_ui() +void PrefUserInterface::selectUi() { QString file = form_->browseUI(internalPath(uiFileED->text())); if (!file.isEmpty()) uiFileED->setText(file); } + +void PrefUserInterface::on_clearSessionPB_clicked() +{ + guiApp->clearSession(); +} + + + ///////////////////////////////////////////////////////////////////// // // PrefEdit // ///////////////////////////////////////////////////////////////////// -PrefEdit::PrefEdit(GuiPreferences * form, QWidget * parent) - : PrefModule(qt_(catEditing), qt_("Control"), form, parent) +PrefEdit::PrefEdit(GuiPreferences * form) + : PrefModule(qt_(catEditing), qt_("Control"), form) { setupUi(this); connect(cursorFollowsCB, SIGNAL(clicked()), this, SIGNAL(changed())); + connect(scrollBelowCB, SIGNAL(clicked()), + this, SIGNAL(changed())); connect(sortEnvironmentsCB, SIGNAL(clicked()), this, SIGNAL(changed())); connect(groupEnvironmentsCB, SIGNAL(clicked()), @@ -1896,6 +2333,8 @@ PrefEdit::PrefEdit(GuiPreferences * form, QWidget * parent) this, SIGNAL(changed())); connect(toggleTabbarCB, SIGNAL(toggled(bool)), this, SIGNAL(changed())); + connect(toggleMenubarCB, SIGNAL(toggled(bool)), + this, SIGNAL(changed())); connect(toggleScrollbarCB, SIGNAL(toggled(bool)), this, SIGNAL(changed())); connect(toggleToolbarsCB, SIGNAL(toggled(bool)), @@ -1906,6 +2345,7 @@ PrefEdit::PrefEdit(GuiPreferences * form, QWidget * parent) void PrefEdit::apply(LyXRC & rc) const { rc.cursor_follows_scrollbar = cursorFollowsCB->isChecked(); + rc.scroll_below_document = scrollBelowCB->isChecked(); rc.sort_layouts = sortEnvironmentsCB->isChecked(); rc.group_layouts = groupEnvironmentsCB->isChecked(); switch (macroEditStyleCO->currentIndex()) { @@ -1916,6 +2356,7 @@ void PrefEdit::apply(LyXRC & rc) const rc.full_screen_toolbars = toggleToolbarsCB->isChecked(); rc.full_screen_scrollbar = toggleScrollbarCB->isChecked(); rc.full_screen_tabbar = toggleTabbarCB->isChecked(); + rc.full_screen_menubar = toggleMenubarCB->isChecked(); rc.full_screen_width = fullscreenWidthSB->value(); rc.full_screen_limit = fullscreenLimitGB->isChecked(); } @@ -1924,12 +2365,14 @@ void PrefEdit::apply(LyXRC & rc) const void PrefEdit::update(LyXRC const & rc) { cursorFollowsCB->setChecked(rc.cursor_follows_scrollbar); + scrollBelowCB->setChecked(rc.scroll_below_document); sortEnvironmentsCB->setChecked(rc.sort_layouts); groupEnvironmentsCB->setChecked(rc.group_layouts); macroEditStyleCO->setCurrentIndex(rc.macro_edit_style); toggleScrollbarCB->setChecked(rc.full_screen_scrollbar); toggleToolbarsCB->setChecked(rc.full_screen_toolbars); toggleTabbarCB->setChecked(rc.full_screen_tabbar); + toggleMenubarCB->setChecked(rc.full_screen_menubar); fullscreenWidthSB->setValue(rc.full_screen_width); fullscreenLimitGB->setChecked(rc.full_screen_limit); } @@ -1949,8 +2392,8 @@ GuiShortcutDialog::GuiShortcutDialog(QWidget * parent) : QDialog(parent) } -PrefShortcuts::PrefShortcuts(GuiPreferences * form, QWidget * parent) - : PrefModule(qt_(catEditing), qt_("Shortcuts"), form, parent) +PrefShortcuts::PrefShortcuts(GuiPreferences * form) + : PrefModule(qt_(catEditing), qt_("Shortcuts"), form) { setupUi(this); @@ -1962,12 +2405,12 @@ PrefShortcuts::PrefShortcuts(GuiPreferences * form, QWidget * parent) // shortcutsTW->setSelectionMode(QAbstractItemView::MultiSelection); connect(bindFilePB, SIGNAL(clicked()), - this, SLOT(select_bind())); + this, SLOT(selectBind())); connect(bindFileED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(removePB, SIGNAL(clicked()), + connect(removePB, SIGNAL(clicked()), this, SIGNAL(changed())); - + shortcut_ = new GuiShortcutDialog(this); shortcut_bc_.setPolicy(ButtonPolicy::OkCancelPolicy); shortcut_bc_.setOK(shortcut_->okPB); @@ -1975,14 +2418,18 @@ PrefShortcuts::PrefShortcuts(GuiPreferences * form, QWidget * parent) connect(shortcut_->okPB, SIGNAL(clicked()), shortcut_, SLOT(accept())); - connect(shortcut_->okPB, SIGNAL(clicked()), + connect(shortcut_->okPB, SIGNAL(clicked()), this, SIGNAL(changed())); - connect(shortcut_->cancelPB, SIGNAL(clicked()), + connect(shortcut_->cancelPB, SIGNAL(clicked()), shortcut_, SLOT(reject())); connect(shortcut_->clearPB, SIGNAL(clicked()), - this, SLOT(shortcut_clearPB_pressed())); - connect(shortcut_->okPB, SIGNAL(clicked()), - this, SLOT(shortcut_okPB_pressed())); + this, SLOT(shortcutClearPressed())); + connect(shortcut_->removePB, SIGNAL(clicked()), + this, SLOT(shortcutRemovePressed())); + connect(shortcut_->okPB, SIGNAL(clicked()), + this, SLOT(shortcutOkPressed())); + connect(shortcut_->cancelPB, SIGNAL(clicked()), + this, SLOT(shortcutCancelPressed())); } @@ -2002,14 +2449,14 @@ void PrefShortcuts::apply(LyXRC & rc) const return; } FileName user_bind_file(bind_dir.absFilename() + "/user.bind"); - user_bind_.write(user_bind_file.toFilesystemEncoding(), false, false); - user_unbind_.write(user_bind_file.toFilesystemEncoding(), true, true); + user_unbind_.write(user_bind_file.toFilesystemEncoding(), false, true); + user_bind_.write(user_bind_file.toFilesystemEncoding(), true, false); // immediately apply the keybindings. Why this is not done before? // The good thing is that the menus are updated automatically. theTopLevelKeymap().clear(); theTopLevelKeymap().read("site"); - theTopLevelKeymap().read(rc.bind_file); - theTopLevelKeymap().read("user"); + theTopLevelKeymap().read(rc.bind_file, 0, KeyMap::Fallback); + theTopLevelKeymap().read("user", 0, KeyMap::MissingOK); } @@ -2020,9 +2467,10 @@ void PrefShortcuts::update(LyXRC const & rc) system_bind_.clear(); user_bind_.clear(); user_unbind_.clear(); + system_bind_.read("site"); system_bind_.read(rc.bind_file); // \unbind in user.bind is added to user_unbind_ - user_bind_.read("user", &user_unbind_); + user_bind_.read("user", &user_unbind_, KeyMap::MissingOK); updateShortcutsTW(); } @@ -2038,11 +2486,11 @@ void PrefShortcuts::updateShortcutsTW() mathItem_ = new QTreeWidgetItem(shortcutsTW); mathItem_->setText(0, qt_("Mathematical Symbols")); mathItem_->setFlags(mathItem_->flags() & ~Qt::ItemIsSelectable); - + bufferItem_ = new QTreeWidgetItem(shortcutsTW); bufferItem_->setText(0, qt_("Document and Window")); bufferItem_->setFlags(bufferItem_->flags() & ~Qt::ItemIsSelectable); - + layoutItem_ = new QTreeWidgetItem(shortcutsTW); layoutItem_->setText(0, qt_("Font, Layouts and Textclasses")); layoutItem_->setFlags(layoutItem_->flags() & ~Qt::ItemIsSelectable); @@ -2053,12 +2501,12 @@ void PrefShortcuts::updateShortcutsTW() // listBindings(unbound=true) lists all bound and unbound lfuns // Items in this list is tagged by its source. - KeyMap::BindingList bindinglist = system_bind_.listBindings(true, - static_cast(System)); + KeyMap::BindingList bindinglist = system_bind_.listBindings(true, + KeyMap::System); KeyMap::BindingList user_bindinglist = user_bind_.listBindings(false, - static_cast(UserBind)); + KeyMap::UserBind); KeyMap::BindingList user_unbindinglist = user_unbind_.listBindings(false, - static_cast(UserUnbind)); + KeyMap::UserUnbind); bindinglist.insert(bindinglist.end(), user_bindinglist.begin(), user_bindinglist.end()); bindinglist.insert(bindinglist.end(), user_unbindinglist.begin(), @@ -2067,7 +2515,7 @@ void PrefShortcuts::updateShortcutsTW() KeyMap::BindingList::const_iterator it = bindinglist.begin(); KeyMap::BindingList::const_iterator it_end = bindinglist.end(); for (; it != it_end; ++it) - insertShortcutItem(it->request, it->sequence, item_type(it->tag)); + insertShortcutItem(it->request, it->sequence, KeyMap::ItemType(it->tag)); shortcutsTW->sortItems(0, Qt::AscendingOrder); QList items = shortcutsTW->selectedItems(); @@ -2078,22 +2526,22 @@ void PrefShortcuts::updateShortcutsTW() } -void PrefShortcuts::setItemType(QTreeWidgetItem * item, item_type tag) +void PrefShortcuts::setItemType(QTreeWidgetItem * item, KeyMap::ItemType tag) { item->setData(0, Qt::UserRole, QVariant(tag)); QFont font; switch (tag) { - case System: + case KeyMap::System: break; - case UserBind: + case KeyMap::UserBind: font.setBold(true); break; - case UserUnbind: + case KeyMap::UserUnbind: font.setStrikeOut(true); break; // this item is not displayed now. - case UserExtraUnbind: + case KeyMap::UserExtraUnbind: font.setStrikeOut(true); break; } @@ -2103,30 +2551,30 @@ void PrefShortcuts::setItemType(QTreeWidgetItem * item, item_type tag) QTreeWidgetItem * PrefShortcuts::insertShortcutItem(FuncRequest const & lfun, - KeySequence const & seq, item_type tag) + KeySequence const & seq, KeyMap::ItemType tag) { FuncCode action = lfun.action; string const action_name = lyxaction.getActionName(action); - QString const lfun_name = toqstr(from_utf8(action_name) + QString const lfun_name = toqstr(from_utf8(action_name) + ' ' + lfun.argument()); QString const shortcut = toqstr(seq.print(KeySequence::ForGui)); - item_type item_tag = tag; + KeyMap::ItemType item_tag = tag; QTreeWidgetItem * newItem = 0; // for unbind items, try to find an existing item in the system bind list - if (tag == UserUnbind) { - QList const items = shortcutsTW->findItems(lfun_name, + if (tag == KeyMap::UserUnbind) { + QList const items = shortcutsTW->findItems(lfun_name, Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 0); for (int i = 0; i < items.size(); ++i) { if (items[i]->text(1) == shortcut) newItem = items[i]; break; } - // if not found, this unbind item is UserExtraUnbind - // Such an item is not displayed to avoid confusion (what is + // if not found, this unbind item is KeyMap::UserExtraUnbind + // Such an item is not displayed to avoid confusion (what is // unmatched removed?). if (!newItem) { - item_tag = UserExtraUnbind; + item_tag = KeyMap::UserExtraUnbind; return 0; } } @@ -2171,9 +2619,10 @@ void PrefShortcuts::on_shortcutsTW_itemSelectionChanged() modifyPB->setEnabled(!items.isEmpty()); if (items.isEmpty()) return; - - item_type tag = static_cast(items[0]->data(0, Qt::UserRole).toInt()); - if (tag == UserUnbind) + + KeyMap::ItemType tag = + static_cast(items[0]->data(0, Qt::UserRole).toInt()); + if (tag == KeyMap::UserUnbind) removePB->setText(qt_("Res&tore")); else removePB->setText(qt_("Remo&ve")); @@ -2191,40 +2640,18 @@ void PrefShortcuts::modifyShortcut() QTreeWidgetItem * item = shortcutsTW->currentItem(); if (item->flags() & Qt::ItemIsSelectable) { shortcut_->lfunLE->setText(item->text(0)); - shortcut_->shortcutLE->setText(item->text(1)); - shortcut_->shortcutLE->setFocus(); + save_lfun_ = item->text(0); + shortcut_->shortcutWG->setText(item->text(1)); + KeySequence seq; + seq.parse(fromqstr(item->data(1, Qt::UserRole).toString())); + shortcut_->shortcutWG->setKeySequence(seq); + shortcut_->shortcutWG->setFocus(); shortcut_->exec(); } } -void PrefShortcuts::select_bind() -{ - QString file = form_->browsebind(internalPath(bindFileED->text())); - if (!file.isEmpty()) { - bindFileED->setText(file); - system_bind_ = KeyMap(); - system_bind_.read(fromqstr(file)); - updateShortcutsTW(); - } -} - - -void PrefShortcuts::on_modifyPB_pressed() -{ - modifyShortcut(); -} - - -void PrefShortcuts::on_newPB_pressed() -{ - shortcut_->lfunLE->clear(); - shortcut_->shortcutLE->reset(); - shortcut_->exec(); -} - - -void PrefShortcuts::on_removePB_pressed() +void PrefShortcuts::removeShortcut() { // it seems that only one item can be selected, but I am // removing all selected items anyway. @@ -2233,18 +2660,19 @@ void PrefShortcuts::on_removePB_pressed() string shortcut = fromqstr(items[i]->data(1, Qt::UserRole).toString()); string lfun = fromqstr(items[i]->text(0)); FuncRequest func = lyxaction.lookupFunc(lfun); - item_type tag = static_cast(items[i]->data(0, Qt::UserRole).toInt()); - + KeyMap::ItemType tag = + static_cast(items[i]->data(0, Qt::UserRole).toInt()); + switch (tag) { - case System: { + case KeyMap::System: { // for system bind, we do not touch the item // but add an user unbind item user_unbind_.bind(shortcut, func); - setItemType(items[i], UserUnbind); + setItemType(items[i], KeyMap::UserUnbind); removePB->setText(qt_("Res&tore")); break; } - case UserBind: { + case KeyMap::UserBind: { // for user_bind, we remove this bind QTreeWidgetItem * parent = items[i]->parent(); int itemIdx = parent->indexOfChild(items[i]); @@ -2256,15 +2684,15 @@ void PrefShortcuts::on_removePB_pressed() user_bind_.unbind(shortcut, func); break; } - case UserUnbind: { + case KeyMap::UserUnbind: { // for user_unbind, we remove the unbind, and the item - // become System again. + // become KeyMap::System again. user_unbind_.unbind(shortcut, func); - setItemType(items[i], System); + setItemType(items[i], KeyMap::System); removePB->setText(qt_("Remo&ve")); break; } - case UserExtraUnbind: { + case KeyMap::UserExtraUnbind: { // for user unbind that is not in system bind file, // remove this unbind file QTreeWidgetItem * parent = items[i]->parent(); @@ -2276,6 +2704,39 @@ void PrefShortcuts::on_removePB_pressed() } +void PrefShortcuts::selectBind() +{ + QString file = form_->browsebind(internalPath(bindFileED->text())); + if (!file.isEmpty()) { + bindFileED->setText(file); + system_bind_ = KeyMap(); + system_bind_.read(fromqstr(file)); + updateShortcutsTW(); + } +} + + +void PrefShortcuts::on_modifyPB_pressed() +{ + modifyShortcut(); +} + + +void PrefShortcuts::on_newPB_pressed() +{ + shortcut_->lfunLE->clear(); + shortcut_->shortcutWG->reset(); + save_lfun_ = QString(); + shortcut_->exec(); +} + + +void PrefShortcuts::on_removePB_pressed() +{ + removeShortcut(); +} + + void PrefShortcuts::on_searchLE_textEdited() { if (searchLE->text().isEmpty()) { @@ -2290,7 +2751,7 @@ void PrefShortcuts::on_searchLE_textEdited() Qt::MatchFlags(Qt::MatchContains | Qt::MatchRecursive), 0); matched += shortcutsTW->findItems(searchLE->text(), Qt::MatchFlags(Qt::MatchContains | Qt::MatchRecursive), 1); - + // hide everyone (to avoid searching in matched QList repeatedly QTreeWidgetItemIterator it(shortcutsTW, QTreeWidgetItemIterator::Selectable); while (*it) @@ -2303,10 +2764,19 @@ void PrefShortcuts::on_searchLE_textEdited() } -void PrefShortcuts::shortcut_okPB_pressed() +docstring makeCmdString(FuncRequest const & f) { - string lfun = fromqstr(shortcut_->lfunLE->text()); - FuncRequest func = lyxaction.lookupFunc(lfun); + docstring actionStr = from_ascii(lyxaction.getActionName(f.action)); + if (!f.argument().empty()) + actionStr += " " + f.argument(); + return actionStr; +} + + +void PrefShortcuts::shortcutOkPressed() +{ + QString const new_lfun = shortcut_->lfunLE->text(); + FuncRequest func = lyxaction.lookupFunc(fromqstr(new_lfun)); if (func.action == LFUN_UNKNOWN_ACTION) { Alert::error(_("Failed to create shortcut"), @@ -2314,21 +2784,45 @@ void PrefShortcuts::shortcut_okPB_pressed() return; } - KeySequence k = shortcut_->shortcutLE->getKeySequence(); + KeySequence k = shortcut_->shortcutWG->getKeySequence(); if (k.length() == 0) { Alert::error(_("Failed to create shortcut"), _("Invalid or empty key sequence")); return; } - // if both lfun and shortcut is valid - if (user_bind_.hasBinding(k, func) || system_bind_.hasBinding(k, func)) { + // check to see if there's been any change + FuncRequest oldBinding = system_bind_.getBinding(k); + if (oldBinding.action == LFUN_UNKNOWN_ACTION) + oldBinding = user_bind_.getBinding(k); + if (oldBinding == func) { + docstring const actionStr = makeCmdString(func); + Alert::error(_("Failed to create shortcut"), + bformat(_("Shortcut `%1$s' is already bound to:\n%2$s"), + k.print(KeySequence::ForGui), actionStr)); + return; + } + + // make sure this key isn't already bound---and, if so, not unbound + FuncCode const unbind = user_unbind_.getBinding(k).action; + if (oldBinding.action != LFUN_UNKNOWN_ACTION && unbind == LFUN_UNKNOWN_ACTION) + { + // FIXME Perhaps we should offer to over-write the old shortcut? + // If so, we'll need to remove it from our list, etc. + docstring const actionStr = makeCmdString(oldBinding); Alert::error(_("Failed to create shortcut"), - _("Shortcut is already defined")); + bformat(_("Shortcut `%1$s' is already bound to:\n%2$s\n" + "You need to remove that binding before creating a new one."), + k.print(KeySequence::ForGui), actionStr)); return; } - - QTreeWidgetItem * item = insertShortcutItem(func, k, UserBind); + + if (!save_lfun_.isEmpty() && new_lfun == save_lfun_) + // real modification of the lfun's shortcut, + // so remove the previous one + removeShortcut(); + + QTreeWidgetItem * item = insertShortcutItem(func, k, KeyMap::UserBind); if (item) { user_bind_.bind(&k, func); shortcutsTW->sortItems(0, Qt::AscendingOrder); @@ -2342,10 +2836,21 @@ void PrefShortcuts::shortcut_okPB_pressed() } -void PrefShortcuts::shortcut_clearPB_pressed() +void PrefShortcuts::shortcutCancelPressed() +{ + shortcut_->shortcutWG->reset(); +} + + +void PrefShortcuts::shortcutClearPressed() { - shortcut_->shortcutLE->reset(); - shortcut_->shortcutLE->setFocus(); + shortcut_->shortcutWG->reset(); +} + + +void PrefShortcuts::shortcutRemovePressed() +{ + shortcut_->shortcutWG->removeFromSequence(); } @@ -2355,8 +2860,8 @@ void PrefShortcuts::shortcut_clearPB_pressed() // ///////////////////////////////////////////////////////////////////// -PrefIdentity::PrefIdentity(QWidget * parent) - : PrefModule(QString(), qt_("Identity"), 0, parent) +PrefIdentity::PrefIdentity(GuiPreferences * form) + : PrefModule(QString(), qt_("Identity"), form) { setupUi(this); @@ -2400,33 +2905,34 @@ GuiPreferences::GuiPreferences(GuiView & lv) connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose())); connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore())); - add(new PrefUserInterface(this)); - add(new PrefEdit(this)); - add(new PrefShortcuts(this)); - add(new PrefScreenFonts(this)); - add(new PrefColors(this)); - add(new PrefDisplay); - add(new PrefInput(this)); - add(new PrefCompletion(this)); + addModule(new PrefUserInterface(this)); + addModule(new PrefEdit(this)); + addModule(new PrefShortcuts(this)); + addModule(new PrefScreenFonts(this)); + addModule(new PrefColors(this)); + addModule(new PrefDisplay(this)); + addModule(new PrefInput(this)); + addModule(new PrefCompletion(this)); - add(new PrefPaths(this)); + addModule(new PrefPaths(this)); - add(new PrefIdentity); + addModule(new PrefIdentity(this)); - add(new PrefLanguage); - add(new PrefSpellchecker(this)); + addModule(new PrefLanguage(this)); + addModule(new PrefSpellchecker(this)); - add(new PrefPrinter); - add(new PrefDate); - add(new PrefPlaintext); - add(new PrefLatex(this)); + addModule(new PrefPrinter(this)); + PrefDate * dateFormat = new PrefDate(this); + addModule(dateFormat); + addModule(new PrefPlaintext(this)); + addModule(new PrefLatex(this)); PrefConverters * converters = new PrefConverters(this); PrefFileformats * formats = new PrefFileformats(this); connect(formats, SIGNAL(formatsChanged()), converters, SLOT(updateGui())); - add(converters); - add(formats); + addModule(converters); + addModule(formats); prefsPS->setCurrentPanel(qt_("User interface")); // FIXME: hack to work around resizing bug in Qt >= 4.2 @@ -2440,12 +2946,15 @@ GuiPreferences::GuiPreferences(GuiView & lv) bc().setApply(applyPB); bc().setCancel(closePB); bc().setRestore(restorePB); + + // initialize the strftime validator + bc().addCheckedLineEdit(dateFormat->DateED); } -void GuiPreferences::add(PrefModule * module) +void GuiPreferences::addModule(PrefModule * module) { - LASSERT(module, /**/); + LASSERT(module, return); if (module->category().isEmpty()) prefsPS->addPanel(module, module->title()); else @@ -2482,13 +2991,6 @@ void GuiPreferences::applyView() apply(rc()); } - -void GuiPreferences::updateContents() -{ - updateRc(rc()); -} - - bool GuiPreferences::initialiseParams(string const &) { rc_ = lyxrc; @@ -2498,6 +3000,11 @@ bool GuiPreferences::initialiseParams(string const &) movers_ = theMovers(); colors_.clear(); update_screen_font_ = false; + + updateRc(rc_); + // Make sure that the bc is in the INITIAL state + if (bc().policy().buttonStatus(ButtonPolicy::RESTORE)) + bc().restore(); return true; } @@ -2507,7 +3014,7 @@ void GuiPreferences::dispatchParams() { ostringstream ss; rc_.write(ss, true); - dispatch(FuncRequest(LFUN_LYXRC_APPLY, ss.str())); + dispatch(FuncRequest(LFUN_LYXRC_APPLY, ss.str())); // FIXME: these need lfuns // FIXME UNICODE theBufferList().setCurrentAuthor(from_utf8(rc_.user_name), from_utf8(rc_.user_email)); @@ -2537,9 +3044,9 @@ void GuiPreferences::dispatchParams() } -void GuiPreferences::setColor(ColorCode col, string const & hex) +void GuiPreferences::setColor(ColorCode col, QString const & hex) { - colors_.push_back(lcolor.getLyXName(col) + ' ' + hex); + colors_.push_back(lcolor.getLyXName(col) + ' ' + fromqstr(hex)); } @@ -2570,15 +3077,8 @@ QString GuiPreferences::browsekbmap(QString const & file) const } -QString GuiPreferences::browsedict(QString const & file) const -{ - return browseFile(file, qt_("Choose personal dictionary"), - QStringList(lyxrc.use_spell_lib ? qt_("*.pws") : qt_("*.ispell"))); -} - - QString GuiPreferences::browse(QString const & file, - QString const & title) const + QString const & title) const { return browseFile(file, title, QStringList(), true); } @@ -2644,4 +3144,4 @@ Dialog * createGuiPreferences(GuiView & lv) { return new GuiPreferences(lv); } } // namespace frontend } // namespace lyx -#include "GuiPrefs_moc.cpp" +#include "moc_GuiPrefs.cpp"