X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt4%2FGuiPrefs.cpp;h=290089b3f1bf080d999dfbfe5710e1b5510905e3;hb=ba76bf5eb85db5a10839fccee3430d906d3f7b70;hp=709d82dcad0ec5f81622ed9f46ffc199324f9077;hpb=34492a9d033aef3d4369d4d758b01f3969ef3af0;p=lyx.git diff --git a/src/frontends/qt4/GuiPrefs.cpp b/src/frontends/qt4/GuiPrefs.cpp index 709d82dcad..290089b3f1 100644 --- a/src/frontends/qt4/GuiPrefs.cpp +++ b/src/frontends/qt4/GuiPrefs.cpp @@ -4,6 +4,7 @@ * Licence details can be found in the file COPYING. * * \author John Levon + * \author Bo Peng * * Full author contact details are available in file CREDITS. */ @@ -11,24 +12,34 @@ #include #include "GuiPrefs.h" -#include "ControlPrefs.h" #include "qt_helpers.h" #include "GuiApplication.h" +#include "GuiFontLoader.h" -#include "ConverterCache.h" -#include "Session.h" -#include "debug.h" +#include "BufferList.h" #include "Color.h" -#include "Font.h" -#include "PanelStack.h" +#include "ConverterCache.h" +#include "support/debug.h" +#include "FuncRequest.h" +#include "support/gettext.h" #include "GuiFontExample.h" -#include "gettext.h" +#include "GuiKeySymbol.h" +#include "KeyMap.h" +#include "KeySequence.h" +#include "LyXAction.h" +#include "PanelStack.h" +#include "paper.h" +#include "Session.h" +#include "support/FileName.h" +#include "support/filetools.h" #include "support/lstrings.h" #include "support/os.h" +#include "support/Package.h" +#include "support/FileFilterList.h" -#include "frontend_helpers.h" +#include "graphics/GraphicsTypes.h" #include "frontends/alert.h" #include "frontends/Application.h" @@ -36,15 +47,15 @@ #include #include #include +#include #include +#include #include #include #include +#include +#include #include -#include - -#include -#include #include #include @@ -52,47 +63,56 @@ using namespace Ui; -using lyx::support::compare_ascii_no_case; -using lyx::support::os::external_path; -using lyx::support::os::external_path_list; -using lyx::support::os::internal_path; -using lyx::support::os::internal_path_list; - -using std::endl; -using std::string; -using std::pair; -using std::vector; - +using namespace std; +using namespace lyx::support; +using namespace lyx::support::os; namespace lyx { namespace frontend { + ///////////////////////////////////////////////////////////////////// // // Helpers // ///////////////////////////////////////////////////////////////////// -// FIXME: move to frontend_helpers.h - template -static size_t findPos_helper(std::vector const & vec, A const & val) +static size_t findPos_helper(vector const & vec, A const & val) { - typedef typename std::vector::const_iterator Cit; + typedef typename vector::const_iterator Cit; - Cit it = std::find(vec.begin(), vec.end(), val); + Cit it = find(vec.begin(), vec.end(), val); if (it == vec.end()) return 0; - return std::distance(vec.begin(), it); + return distance(vec.begin(), it); +} + + +static void parseFontName(QString const & mangled0, + string & name, string & foundry) +{ + string mangled = fromqstr(mangled0); + size_t const idx = mangled.find('['); + if (idx == string::npos || idx == 0) { + name = mangled; + foundry.clear(); + } else { + name = mangled.substr(0, idx - 1), + foundry = mangled.substr(idx + 1, mangled.size() - idx - 2); + } } static void setComboxFont(QComboBox * cb, string const & family, string const & foundry) { - string const name = makeFontName(family, foundry); + QString fontname = toqstr(family); + if (!foundry.empty()) + fontname += " [" + toqstr(foundry) + ']'; + for (int i = 0; i < cb->count(); ++i) { - if (fromqstr(cb->itemText(i)) == name) { + if (cb->itemText(i) == fontname) { cb->setCurrentIndex(i); return; } @@ -101,21 +121,24 @@ static void setComboxFont(QComboBox * cb, string const & family, // Try matching without foundry name // We count in reverse in order to prefer the Xft foundry - for (int i = cb->count() - 1; i >= 0; --i) { - pair tmp = parseFontName(fromqstr(cb->itemText(i))); - if (compare_ascii_no_case(tmp.first, family) == 0) { + for (int i = cb->count(); --i >= 0;) { + string name, foundry; + parseFontName(cb->itemText(i), name, foundry); + if (compare_ascii_no_case(name, family) == 0) { cb->setCurrentIndex(i); return; } } // family alone can contain e.g. "Helvetica [Adobe]" - pair tmpfam = parseFontName(family); + string tmpname, tmpfoundry; + parseFontName(toqstr(family), tmpname, tmpfoundry); // We count in reverse in order to prefer the Xft foundry - for (int i = cb->count() - 1; i >= 0; --i) { - pair tmp = parseFontName(fromqstr(cb->itemText(i))); - if (compare_ascii_no_case(tmp.first, tmpfam.first) == 0) { + for (int i = cb->count(); --i >= 0; ) { + string name, foundry; + parseFontName(cb->itemText(i), name, foundry); + if (compare_ascii_no_case(name, foundry) == 0) { cb->setCurrentIndex(i); return; } @@ -127,15 +150,16 @@ static void setComboxFont(QComboBox * cb, string const & family, QFont font; font.setKerning(false); - if (family == theApp()->romanFontName()) { + QString const font_family = toqstr(family); + if (font_family == guiApp->romanFontName()) { font.setStyleHint(QFont::Serif); - font.setFamily(family.c_str()); - } else if (family == theApp()->sansFontName()) { + font.setFamily(font_family); + } else if (font_family == guiApp->sansFontName()) { font.setStyleHint(QFont::SansSerif); - font.setFamily(family.c_str()); - } else if (family == theApp()->typewriterFontName()) { + font.setFamily(font_family); + } else if (font_family == guiApp->typewriterFontName()) { font.setStyleHint(QFont::TypeWriter); - font.setFamily(family.c_str()); + font.setFamily(font_family); } else { lyxerr << "FAILED to find the default font: '" << foundry << "', '" << family << '\''<< endl; @@ -143,8 +167,8 @@ static void setComboxFont(QComboBox * cb, string const & family, } QFontInfo info(font); - pair tmp = parseFontName(fromqstr(info.family())); - string const & default_font_name = tmp.first; + string default_font_name, dummyfoundry; + parseFontName(info.family(), default_font_name, dummyfoundry); lyxerr << "Apparent font is " << default_font_name << endl; for (int i = 0; i < cb->count(); ++i) { @@ -173,7 +197,7 @@ PrefPlaintext::PrefPlaintext(QWidget * parent) setupUi(this); connect(plaintextLinelengthSB, SIGNAL(valueChanged(int)), this, SIGNAL(changed())); - connect(plaintextRoffED, SIGNAL(textChanged(const QString&)), + connect(plaintextRoffED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); } @@ -202,7 +226,7 @@ PrefDate::PrefDate(QWidget * parent) : PrefModule(_("Date format"), 0, parent) { setupUi(this); - connect(DateED, SIGNAL(textChanged(const QString &)), + connect(DateED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); } @@ -221,49 +245,53 @@ void PrefDate::update(LyXRC const & rc) ///////////////////////////////////////////////////////////////////// // -// PrefKeyboard +// PrefInput // ///////////////////////////////////////////////////////////////////// -PrefKeyboard::PrefKeyboard(GuiPrefsDialog * form, QWidget * parent) - : PrefModule(_("Keyboard"), form, parent) +PrefInput::PrefInput(GuiPreferences * form, QWidget * parent) + : PrefModule(_("Keyboard/Mouse"), form, parent) { setupUi(this); connect(keymapCB, SIGNAL(clicked()), this, SIGNAL(changed())); - connect(firstKeymapED, SIGNAL(textChanged(const QString&)), + connect(firstKeymapED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(secondKeymapED, SIGNAL(textChanged(const QString&)), + connect(secondKeymapED, SIGNAL(textChanged(QString)), + this, SIGNAL(changed())); + connect(mouseWheelSpeedSB, SIGNAL(valueChanged(double)), this, SIGNAL(changed())); } -void PrefKeyboard::apply(LyXRC & rc) const +void PrefInput::apply(LyXRC & rc) const { // FIXME: can derive CB from the two EDs rc.use_kbmap = keymapCB->isChecked(); rc.primary_kbmap = internal_path(fromqstr(firstKeymapED->text())); rc.secondary_kbmap = internal_path(fromqstr(secondKeymapED->text())); + rc.mouse_wheel_speed = mouseWheelSpeedSB->value(); } -void PrefKeyboard::update(LyXRC const & rc) +void PrefInput::update(LyXRC const & rc) { // FIXME: can derive CB from the two EDs keymapCB->setChecked(rc.use_kbmap); firstKeymapED->setText(toqstr(external_path(rc.primary_kbmap))); secondKeymapED->setText(toqstr(external_path(rc.secondary_kbmap))); + mouseWheelSpeedSB->setValue(rc.mouse_wheel_speed); } -QString PrefKeyboard::testKeymap(QString keymap) +QString PrefInput::testKeymap(QString keymap) { - return toqstr(form_->controller().browsekbmap(from_utf8(internal_path(fromqstr(keymap))))); + return toqstr(form_->browsekbmap(from_utf8(internal_path(fromqstr(keymap))))); } -void PrefKeyboard::on_firstKeymapPB_clicked(bool) +void PrefInput::on_firstKeymapPB_clicked(bool) { QString const file = testKeymap(firstKeymapED->text()); if (!file.isEmpty()) @@ -271,7 +299,7 @@ void PrefKeyboard::on_firstKeymapPB_clicked(bool) } -void PrefKeyboard::on_secondKeymapPB_clicked(bool) +void PrefInput::on_secondKeymapPB_clicked(bool) { QString const file = testKeymap(secondKeymapED->text()); if (!file.isEmpty()) @@ -279,7 +307,7 @@ void PrefKeyboard::on_secondKeymapPB_clicked(bool) } -void PrefKeyboard::on_keymapCB_toggled(bool keymap) +void PrefInput::on_keymapCB_toggled(bool keymap) { firstKeymapLA->setEnabled(keymap); secondKeymapLA->setEnabled(keymap); @@ -296,21 +324,21 @@ void PrefKeyboard::on_keymapCB_toggled(bool keymap) // ///////////////////////////////////////////////////////////////////// -PrefLatex::PrefLatex(GuiPrefsDialog * form, QWidget * parent) +PrefLatex::PrefLatex(GuiPreferences * form, QWidget * parent) : PrefModule(_("LaTeX"), form, parent) { setupUi(this); - connect(latexEncodingED, SIGNAL(textChanged(const QString&)), + connect(latexEncodingED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(latexChecktexED, SIGNAL(textChanged(const QString&)), + connect(latexChecktexED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(latexBibtexED, SIGNAL(textChanged(const QString&)), + connect(latexBibtexED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(latexIndexED, SIGNAL(textChanged(const QString&)), + connect(latexIndexED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); connect(latexAutoresetCB, SIGNAL(clicked()), this, SIGNAL(changed())); - connect(latexDviPaperED, SIGNAL(textChanged(const QString&)), + connect(latexDviPaperED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); connect(latexPaperSizeCO, SIGNAL(activated(int)), this, SIGNAL(changed())); @@ -322,7 +350,6 @@ PrefLatex::PrefLatex(GuiPrefsDialog * form, QWidget * parent) #else pathCB->setVisible(false); #endif - } @@ -335,7 +362,7 @@ void PrefLatex::apply(LyXRC & rc) const rc.auto_reset_options = latexAutoresetCB->isChecked(); rc.view_dvi_paper_option = fromqstr(latexDviPaperED->text()); rc.default_papersize = - form_->controller().toPaperSize(latexPaperSizeCO->currentIndex()); + form_->toPaperSize(latexPaperSizeCO->currentIndex()); #if defined(__CYGWIN__) || defined(_WIN32) rc.windows_style_tex_paths = pathCB->isChecked(); #endif @@ -351,7 +378,7 @@ void PrefLatex::update(LyXRC const & rc) latexAutoresetCB->setChecked(rc.auto_reset_options); latexDviPaperED->setText(toqstr(rc.view_dvi_paper_option)); latexPaperSizeCO->setCurrentIndex( - form_->controller().fromPaperSize(rc.default_papersize)); + form_->fromPaperSize(rc.default_papersize)); #if defined(__CYGWIN__) || defined(_WIN32) pathCB->setChecked(rc.windows_style_tex_paths); #endif @@ -364,17 +391,17 @@ void PrefLatex::update(LyXRC const & rc) // ///////////////////////////////////////////////////////////////////// -PrefScreenFonts::PrefScreenFonts(GuiPrefsDialog * form, QWidget * parent) +PrefScreenFonts::PrefScreenFonts(GuiPreferences * form, QWidget * parent) : PrefModule(_("Screen fonts"), form, parent) { setupUi(this); - connect(screenRomanCO, SIGNAL(activated(const QString&)), - this, SLOT(select_roman(const QString&))); - connect(screenSansCO, SIGNAL(activated(const QString&)), - this, SLOT(select_sans(const QString&))); - connect(screenTypewriterCO, SIGNAL(activated(const QString&)), - this, SLOT(select_typewriter(const QString&))); + connect(screenRomanCO, SIGNAL(activated(QString)), + this, SLOT(select_roman(QString))); + connect(screenSansCO, SIGNAL(activated(QString)), + this, SLOT(select_sans(QString))); + connect(screenTypewriterCO, SIGNAL(activated(QString)), + this, SLOT(select_typewriter(QString))); QFontDatabase fontdb; QStringList families(fontdb.families()); @@ -383,90 +410,88 @@ PrefScreenFonts::PrefScreenFonts(GuiPrefsDialog * form, QWidget * parent) screenSansCO->addItem(*it); screenTypewriterCO->addItem(*it); } - connect(screenRomanCO, SIGNAL(activated(const QString&)), + connect(screenRomanCO, SIGNAL(activated(QString)), this, SIGNAL(changed())); - connect(screenSansCO, SIGNAL(activated(const QString&)), + connect(screenSansCO, SIGNAL(activated(QString)), this, SIGNAL(changed())); - connect(screenTypewriterCO, SIGNAL(activated(const QString&)), + connect(screenTypewriterCO, SIGNAL(activated(QString)), this, SIGNAL(changed())); connect(screenZoomSB, SIGNAL(valueChanged(int)), this, SIGNAL(changed())); connect(screenDpiSB, SIGNAL(valueChanged(int)), this, SIGNAL(changed())); - connect(screenTinyED, SIGNAL(textChanged(const QString&)), + connect(screenTinyED, SIGNAL(textChanged(QString)), + this, SIGNAL(changed())); + connect(screenSmallestED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(screenSmallestED, SIGNAL(textChanged(const QString&)), + connect(screenSmallerED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(screenSmallerED, SIGNAL(textChanged(const QString&)), + connect(screenSmallED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(screenSmallED, SIGNAL(textChanged(const QString&)), + connect(screenNormalED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(screenNormalED, SIGNAL(textChanged(const QString&)), + connect(screenLargeED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(screenLargeED, SIGNAL(textChanged(const QString&)), + connect(screenLargerED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(screenLargerED, SIGNAL(textChanged(const QString&)), + connect(screenLargestED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(screenLargestED, SIGNAL(textChanged(const QString&)), + connect(screenHugeED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(screenHugeED, SIGNAL(textChanged(const QString&)), + connect(screenHugerED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(screenHugerED, SIGNAL(textChanged(const QString&)), + connect(pixmapCacheCB, SIGNAL(toggled(bool)), this, SIGNAL(changed())); - screenTinyED->setValidator(new QDoubleValidator( - screenTinyED)); - screenSmallestED->setValidator(new QDoubleValidator( - screenSmallestED)); - screenSmallerED->setValidator(new QDoubleValidator( - screenSmallerED)); - screenSmallED->setValidator(new QDoubleValidator( - screenSmallED)); - screenNormalED->setValidator(new QDoubleValidator( - screenNormalED)); - screenLargeED->setValidator(new QDoubleValidator( - screenLargeED)); - screenLargerED->setValidator(new QDoubleValidator( - screenLargerED)); - screenLargestED->setValidator(new QDoubleValidator( - screenLargestED)); - screenHugeED->setValidator(new QDoubleValidator( - screenHugeED)); - screenHugerED->setValidator(new QDoubleValidator( - screenHugerED)); + screenTinyED->setValidator(new QDoubleValidator(screenTinyED)); + screenSmallestED->setValidator(new QDoubleValidator(screenSmallestED)); + screenSmallerED->setValidator(new QDoubleValidator(screenSmallerED)); + screenSmallED->setValidator(new QDoubleValidator(screenSmallED)); + screenNormalED->setValidator(new QDoubleValidator(screenNormalED)); + screenLargeED->setValidator(new QDoubleValidator(screenLargeED)); + screenLargerED->setValidator(new QDoubleValidator(screenLargerED)); + screenLargestED->setValidator(new QDoubleValidator(screenLargestED)); + screenHugeED->setValidator(new QDoubleValidator(screenHugeED)); + screenHugerED->setValidator(new QDoubleValidator(screenHugerED)); } void PrefScreenFonts::apply(LyXRC & rc) const { - LyXRC const oldrc(rc); + LyXRC const oldrc = rc; - boost::tie(rc.roman_font_name, rc.roman_font_foundry) - = parseFontName(fromqstr(screenRomanCO->currentText())); - boost::tie(rc.sans_font_name, rc.sans_font_foundry) = - parseFontName(fromqstr(screenSansCO->currentText())); - boost::tie(rc.typewriter_font_name, rc.typewriter_font_foundry) = - parseFontName(fromqstr(screenTypewriterCO->currentText())); + parseFontName(screenRomanCO->currentText(), + rc.roman_font_name, rc.roman_font_foundry); + parseFontName(screenSansCO->currentText(), + rc.sans_font_name, rc.sans_font_foundry); + parseFontName(screenTypewriterCO->currentText(), + rc.typewriter_font_name, rc.typewriter_font_foundry); 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] = 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.use_pixmap_cache = pixmapCacheCB->isChecked(); if (rc.font_sizes != oldrc.font_sizes || rc.roman_font_name != oldrc.roman_font_name || rc.sans_font_name != oldrc.sans_font_name || rc.typewriter_font_name != oldrc.typewriter_font_name || rc.zoom != oldrc.zoom || rc.dpi != oldrc.dpi) { - form_->controller().updateScreenFonts(); + // The global QPixmapCache is used in GuiPainter to cache text + // painting so we must reset it in case any of the above + // parameter is changed. + QPixmapCache::clear(); + guiApp->fontLoader().update(); + form_->updateScreenFonts(); } } @@ -486,31 +511,38 @@ void PrefScreenFonts::update(LyXRC const & rc) 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])); + 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])); + + pixmapCacheCB->setChecked(rc.use_pixmap_cache); +#if defined(Q_WS_X11) + pixmapCacheCB->setEnabled(false); +#endif + } -void PrefScreenFonts::select_roman(const QString& name) + +void PrefScreenFonts::select_roman(const QString & name) { screenRomanFE->set(QFont(name), name); } -void PrefScreenFonts::select_sans(const QString& name) +void PrefScreenFonts::select_sans(const QString & name) { screenSansFE->set(QFont(name), name); } -void PrefScreenFonts::select_typewriter(const QString& name) +void PrefScreenFonts::select_typewriter(const QString & name) { screenTypewriterFE->set(QFont(name), name); } @@ -522,7 +554,18 @@ void PrefScreenFonts::select_typewriter(const QString& name) // ///////////////////////////////////////////////////////////////////// -PrefColors::PrefColors(GuiPrefsDialog * form, QWidget * parent) +namespace { + +struct ColorSorter +{ + bool operator()(ColorCode lhs, ColorCode rhs) const { + return lcolor.getGUIName(lhs) < lcolor.getGUIName(rhs); + } +}; + +} // namespace anon + +PrefColors::PrefColors(GuiPreferences * form, QWidget * parent) : PrefModule( _("Colors"), form, parent) { setupUi(this); @@ -531,29 +574,27 @@ PrefColors::PrefColors(GuiPrefsDialog * form, QWidget * parent) // See http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg113301.html // for some discussion of why that is not trivial. QPixmap icon(32, 32); - for (int i = 0; i < Color::ignore; ++i) { - Color::color lc = static_cast(i); - if (lc == Color::none - || lc == Color::black - || lc == Color::white - || lc == Color::red - || lc == Color::green - || lc == Color::blue - || lc == Color::cyan - || lc == Color::magenta - || lc == Color::yellow - || lc == Color::inherit - || lc == Color::ignore) continue; + for (int i = 0; i < Color_ignore; ++i) { + ColorCode lc = static_cast(i); + if (lc == Color_none + || lc == Color_black + || lc == Color_white + || lc == Color_red + || lc == Color_green + || lc == Color_blue + || lc == Color_cyan + || lc == Color_magenta + || lc == Color_yellow + || lc == Color_inherit + || lc == Color_ignore) continue; lcolors_.push_back(lc); } - lcolors_ = frontend::getSortedColors(lcolors_); - vector::const_iterator cit = lcolors_.begin(); - vector::const_iterator const end = lcolors_.end(); - for (; cit != end; ++cit) - { - // This is not a memory leak: - /*QListWidgetItem * newItem =*/ new QListWidgetItem(QIcon(icon), + sort(lcolors_.begin(), lcolors_.end(), ColorSorter()); + vector::const_iterator cit = lcolors_.begin(); + vector::const_iterator const end = lcolors_.end(); + for (; cit != end; ++cit) { + (void) new QListWidgetItem(QIcon(icon), toqstr(lcolor.getGUIName(*cit)), lyxObjectsLW); } curcolors_.resize(lcolors_.size()); @@ -571,11 +612,9 @@ PrefColors::PrefColors(GuiPrefsDialog * form, QWidget * parent) void PrefColors::apply(LyXRC & /*rc*/) const { - for (unsigned int i = 0; i < lcolors_.size(); ++i) { - if (curcolors_[i] != newcolors_[i]) { - form_->controller().setColor(lcolors_[i], fromqstr(newcolors_[i])); - } - } + for (unsigned int i = 0; i < lcolors_.size(); ++i) + if (curcolors_[i] != newcolors_[i]) + form_->setColor(lcolors_[i], fromqstr(newcolors_[i])); } @@ -596,10 +635,11 @@ void PrefColors::change_color() int const row = lyxObjectsLW->currentRow(); // just to be sure - if (row < 0) return; + if (row < 0) + return; QString const color = newcolors_[row]; - QColor c(QColorDialog::getColor(QColor(color), qApp->focusWidget())); + QColor c = QColorDialog::getColor(QColor(color), qApp->focusWidget()); if (c.isValid() && c.name() != color) { newcolors_[row] = c.name(); @@ -637,25 +677,25 @@ PrefDisplay::PrefDisplay(QWidget * parent) void PrefDisplay::apply(LyXRC & rc) const { switch (instantPreviewCO->currentIndex()) { - case 0: rc.preview = LyXRC::PREVIEW_OFF; break; - case 1: rc.preview = LyXRC::PREVIEW_NO_MATH; break; - case 2: rc.preview = LyXRC::PREVIEW_ON; break; + case 0: rc.preview = LyXRC::PREVIEW_OFF; break; + case 1: rc.preview = LyXRC::PREVIEW_NO_MATH; break; + case 2: rc.preview = LyXRC::PREVIEW_ON; break; } - lyx::graphics::DisplayType dtype; + graphics::DisplayType dtype; switch (displayGraphicsCO->currentIndex()) { - case 3: dtype = lyx::graphics::NoDisplay; break; - case 2: dtype = lyx::graphics::ColorDisplay; break; - case 1: dtype = lyx::graphics::GrayscaleDisplay; break; - case 0: dtype = lyx::graphics::MonochromeDisplay; break; - default: dtype = lyx::graphics::GrayscaleDisplay; + 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; // FIXME!! The graphics cache no longer has a changeDisplay method. #if 0 if (old_value != rc.display_graphics) { - lyx::graphics::GCache & gc = lyx::graphics::GCache::get(); + graphics::GCache & gc = graphics::GCache::get(); gc.changeDisplay(); } #endif @@ -678,10 +718,10 @@ void PrefDisplay::update(LyXRC const & rc) int item = 2; switch (rc.display_graphics) { - case lyx::graphics::NoDisplay: item = 3; break; - case lyx::graphics::ColorDisplay: item = 2; break; - case lyx::graphics::GrayscaleDisplay: item = 1; break; - case lyx::graphics::MonochromeDisplay: item = 0; break; + 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); @@ -694,26 +734,29 @@ void PrefDisplay::update(LyXRC const & rc) // ///////////////////////////////////////////////////////////////////// -PrefPaths::PrefPaths(GuiPrefsDialog * form, QWidget * parent) +PrefPaths::PrefPaths(GuiPreferences * form, QWidget * parent) : PrefModule(_("Paths"), form, parent) { 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(workingDirED, SIGNAL(textChanged(const QString&)), + connect(workingDirED, SIGNAL(textChanged(QString)), + this, SIGNAL(changed())); + connect(exampleDirED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(templateDirED, SIGNAL(textChanged(const QString&)), + connect(templateDirED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(backupDirED, SIGNAL(textChanged(const QString&)), + connect(backupDirED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(tempDirED, SIGNAL(textChanged(const QString&)), + connect(tempDirED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(lyxserverDirED, SIGNAL(textChanged(const QString&)), + connect(lyxserverDirED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(pathPrefixED, SIGNAL(textChanged(const QString&)), + connect(pathPrefixED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); } @@ -721,6 +764,7 @@ PrefPaths::PrefPaths(GuiPrefsDialog * form, QWidget * parent) void PrefPaths::apply(LyXRC & rc) const { rc.document_path = internal_path(fromqstr(workingDirED->text())); + rc.example_path = internal_path(fromqstr(exampleDirED->text())); rc.template_path = internal_path(fromqstr(templateDirED->text())); rc.backupdir_path = internal_path(fromqstr(backupDirED->text())); rc.tempdir_path = internal_path(fromqstr(tempDirED->text())); @@ -733,6 +777,7 @@ void PrefPaths::apply(LyXRC & rc) const void PrefPaths::update(LyXRC const & rc) { workingDirED->setText(toqstr(external_path(rc.document_path))); + exampleDirED->setText(toqstr(external_path(rc.example_path))); templateDirED->setText(toqstr(external_path(rc.template_path))); backupDirED->setText(toqstr(external_path(rc.backupdir_path))); tempDirED->setText(toqstr(external_path(rc.tempdir_path))); @@ -742,9 +787,19 @@ void PrefPaths::update(LyXRC const & rc) } +void PrefPaths::select_exampledir() +{ + docstring file(form_->browsedir( + from_utf8(internal_path(fromqstr(exampleDirED->text()))), + _("Select directory for example files"))); + if (!file.empty()) + exampleDirED->setText(toqstr(file)); +} + + void PrefPaths::select_templatedir() { - docstring file(form_->controller().browsedir( + docstring file(form_->browsedir( from_utf8(internal_path(fromqstr(templateDirED->text()))), _("Select a document templates directory"))); if (!file.empty()) @@ -754,7 +809,7 @@ void PrefPaths::select_templatedir() void PrefPaths::select_tempdir() { - docstring file(form_->controller().browsedir( + docstring file(form_->browsedir( from_utf8(internal_path(fromqstr(tempDirED->text()))), _("Select a temporary directory"))); if (!file.empty()) @@ -764,7 +819,7 @@ void PrefPaths::select_tempdir() void PrefPaths::select_backupdir() { - docstring file(form_->controller().browsedir( + docstring file(form_->browsedir( from_utf8(internal_path(fromqstr(backupDirED->text()))), _("Select a backups directory"))); if (!file.empty()) @@ -774,7 +829,7 @@ void PrefPaths::select_backupdir() void PrefPaths::select_workingdir() { - docstring file(form_->controller().browsedir( + docstring file(form_->browsedir( from_utf8(internal_path(fromqstr(workingDirED->text()))), _("Select a document directory"))); if (!file.empty()) @@ -784,7 +839,7 @@ void PrefPaths::select_workingdir() void PrefPaths::select_lyxpipe() { - docstring file(form_->controller().browse( + docstring file(form_->browse( from_utf8(internal_path(fromqstr(lyxserverDirED->text()))), _("Give a filename for the LyX server pipe"))); if (!file.empty()) @@ -798,7 +853,7 @@ void PrefPaths::select_lyxpipe() // ///////////////////////////////////////////////////////////////////// -PrefSpellchecker::PrefSpellchecker(GuiPrefsDialog * form, QWidget * parent) +PrefSpellchecker::PrefSpellchecker(GuiPreferences * form, QWidget * parent) : PrefModule(_("Spellchecker"), form, parent) { setupUi(this); @@ -810,11 +865,11 @@ PrefSpellchecker::PrefSpellchecker(GuiPrefsDialog * form, QWidget * parent) #else spellCommandCO->setEnabled(false); #endif - connect(altLanguageED, SIGNAL(textChanged(const QString&)), + connect(altLanguageED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(escapeCharactersED, SIGNAL(textChanged(const QString&)), + connect(escapeCharactersED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(persDictionaryED, SIGNAL(textChanged(const QString&)), + connect(persDictionaryED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); connect(compoundWordCB, SIGNAL(clicked()), this, SIGNAL(changed())); @@ -893,7 +948,7 @@ void PrefSpellchecker::update(LyXRC const & rc) void PrefSpellchecker::select_dict() { - docstring file(form_->controller().browsedict( + docstring file(form_->browsedict( from_utf8(internal_path(fromqstr(persDictionaryED->text()))))); if (!file.empty()) persDictionaryED->setText(toqstr(file)); @@ -908,7 +963,7 @@ void PrefSpellchecker::select_dict() ///////////////////////////////////////////////////////////////////// -PrefConverters::PrefConverters(GuiPrefsDialog * form, QWidget * parent) +PrefConverters::PrefConverters(GuiPreferences * form, QWidget * parent) : PrefModule(_("Converters"), form, parent) { setupUi(this); @@ -921,13 +976,13 @@ PrefConverters::PrefConverters(GuiPrefsDialog * form, QWidget * parent) this, SLOT(update_converter())); connect(convertersLW, SIGNAL(currentRowChanged(int)), this, SLOT(switch_converter())); - connect(converterFromCO, SIGNAL(activated(const QString&)), + connect(converterFromCO, SIGNAL(activated(QString)), this, SLOT(converter_changed())); - connect(converterToCO, SIGNAL(activated(const QString&)), + connect(converterToCO, SIGNAL(activated(QString)), this, SLOT(converter_changed())); - connect(converterED, SIGNAL(textChanged(const QString&)), + connect(converterED, SIGNAL(textEdited(QString)), this, SLOT(converter_changed())); - connect(converterFlagED, SIGNAL(textChanged(const QString&)), + connect(converterFlagED, SIGNAL(textEdited(QString)), this, SLOT(converter_changed())); connect(converterNewPB, SIGNAL(clicked()), this, SIGNAL(changed())); @@ -935,7 +990,7 @@ PrefConverters::PrefConverters(GuiPrefsDialog * form, QWidget * parent) this, SIGNAL(changed())); connect(converterModifyPB, SIGNAL(clicked()), this, SIGNAL(changed())); - connect(maxAgeLE, SIGNAL(textChanged(const QString&)), + connect(maxAgeLE, SIGNAL(textEdited(QString)), this, SIGNAL(changed())); maxAgeLE->setValidator(new QDoubleValidator(maxAgeLE)); @@ -962,6 +1017,8 @@ void PrefConverters::update(LyXRC const & rc) void PrefConverters::updateGui() { + form_->formats().sort(); + form_->converters().update(form_->formats()); // save current selection QString current = converterFromCO->currentText() + " -> " + converterToCO->currentText(); @@ -984,7 +1041,7 @@ void PrefConverters::updateGui() Converters::const_iterator ccit = form_->converters().begin(); Converters::const_iterator cend = form_->converters().end(); for (; ccit != cend; ++ccit) { - std::string const name = + string const name = ccit->From->prettyname() + " -> " + ccit->To->prettyname(); int type = form_->converters().getNumber(ccit->From->name(), ccit->To->name()); new QListWidgetItem(toqstr(name), convertersLW, type); @@ -996,7 +1053,7 @@ void PrefConverters::updateGui() if (!current.isEmpty()) { QList const item = convertersLW->findItems(current, Qt::MatchExactly); - if (item.size()>0) + if (!item.isEmpty()) convertersLW->setCurrentItem(item.at(0)); } @@ -1029,10 +1086,10 @@ void PrefConverters::converter_changed() void PrefConverters::updateButtons() { - Format const & from(form_->formats().get(converterFromCO->currentIndex())); - Format const & to(form_->formats().get(converterToCO->currentIndex())); + Format const & from = form_->formats().get(converterFromCO->currentIndex()); + Format const & to = form_->formats().get(converterToCO->currentIndex()); int const sel = form_->converters().getNumber(from.name(), to.name()); - bool const known = !(sel < 0); + bool const known = sel >= 0; bool const valid = !(converterED->text().isEmpty() || from.name() == to.name()); @@ -1043,7 +1100,7 @@ void PrefConverters::updateButtons() 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); @@ -1059,16 +1116,17 @@ void PrefConverters::updateButtons() // this is why we can use the same function for both new and modify void PrefConverters::update_converter() { - Format const & from(form_->formats().get(converterFromCO->currentIndex())); - Format const & to(form_->formats().get(converterToCO->currentIndex())); + Format const & from = form_->formats().get(converterFromCO->currentIndex()); + Format const & to = form_->formats().get(converterToCO->currentIndex()); string const flags = fromqstr(converterFlagED->text()); string const command = fromqstr(converterED->text()); - Converter const * old = form_->converters().getConverter(from.name(), to.name()); + Converter const * old = + form_->converters().getConverter(from.name(), to.name()); form_->converters().add(from.name(), to.name(), command, flags); - if (!old) { + + if (!old) form_->converters().updateLast(form_->formats()); - } updateGui(); @@ -1080,8 +1138,8 @@ void PrefConverters::update_converter() void PrefConverters::remove_converter() { - Format const & from(form_->formats().get(converterFromCO->currentIndex())); - Format const & to(form_->formats().get(converterToCO->currentIndex())); + Format const & from = form_->formats().get(converterFromCO->currentIndex()); + Format const & to = form_->formats().get(converterToCO->currentIndex()); form_->converters().erase(from.name(), to.name()); updateGui(); @@ -1102,297 +1160,93 @@ void PrefConverters::on_cacheCB_stateChanged(int state) ///////////////////////////////////////////////////////////////////// // -// PrefCopiers +// PrefFileformats // ///////////////////////////////////////////////////////////////////// - -PrefCopiers::PrefCopiers(GuiPrefsDialog * form, QWidget * parent) - : PrefModule(_("Copiers"), form, parent) -{ - setupUi(this); - - connect(copierNewPB, SIGNAL(clicked()), this, SLOT(new_copier())); - connect(copierRemovePB, SIGNAL(clicked()), this, SLOT(remove_copier())); - connect(copierModifyPB, SIGNAL(clicked()), this, SLOT(modify_copier())); - connect(AllCopiersLW, SIGNAL(currentRowChanged(int)), - this, SLOT(switch_copierLB(int))); - connect(copierFormatCO, SIGNAL(activated(int)), - this, SLOT(switch_copierCO(int))); - connect(copierNewPB, SIGNAL(clicked()), - this, SIGNAL(changed())); - connect(copierRemovePB, SIGNAL(clicked()), - this, SIGNAL(changed())); - connect(copierModifyPB, SIGNAL(clicked()), - this, SIGNAL(changed())); - connect(copierFormatCO, SIGNAL(activated(const QString &)), - this, SLOT(copiers_changed())); - connect(copierED, SIGNAL(textChanged(const QString &)), - this, SLOT(copiers_changed())); -} - - -void PrefCopiers::apply(LyXRC & /*rc*/) const -{ -} - - -void PrefCopiers::update(LyXRC const & /*rc*/) -{ - updateView(); -} - - -void PrefCopiers::updateView() -{ - // The choice widget - // save current selection - QString current = copierFormatCO->currentText(); - copierFormatCO->clear(); - - for (Formats::const_iterator it = form_->formats().begin(), - end = form_->formats().end(); - it != end; ++it) { - copierFormatCO->addItem(toqstr(it->prettyname())); - } - - // The browser widget - AllCopiersLW->clear(); - - for (Movers::const_iterator it = form_->movers().begin(), - end = form_->movers().end(); - it != end; ++it) { - std::string const & command = it->second.command(); - if (command.empty()) - continue; - QString const pretty = toqstr(form_->formats().prettyName(it->first)); - AllCopiersLW->addItem(pretty); - } - AllCopiersLW->sortItems(Qt::AscendingOrder); - - // restore selection - if (!current.isEmpty()) { - QList item = - AllCopiersLW->findItems(current, Qt::MatchExactly); - if (item.size()>0) - AllCopiersLW->setCurrentItem(item.at(0)); - } - // select first element if restoring failed - if (AllCopiersLW->currentRow() == -1) - AllCopiersLW->setCurrentRow(0); -} - - -namespace { - -class SamePrettyName { -public: - SamePrettyName(string const & n) : pretty_name_(n) {} - - bool operator()(Format const & fmt) const { - return fmt.prettyname() == pretty_name_; - } - -private: - string const pretty_name_; -}; - - -Format const * getFormat(std::string const & prettyname) +// +FormatValidator::FormatValidator(QWidget * parent, Formats const & f) + : QValidator(parent), formats_(f) { - Formats::const_iterator it = formats.begin(); - Formats::const_iterator const end = formats.end(); - it = std::find_if(it, end, SamePrettyName(prettyname)); - return it == end ? 0 : &*it; } -} // namespace anon - -void PrefCopiers::switch_copierLB(int row) +void FormatValidator::fixup(QString & input) const { - if (row < 0) - return; - - // FIXME UNICODE? - std::string const browser_text = - fromqstr(AllCopiersLW->currentItem()->text()); - Format const * fmt = getFormat(browser_text); - if (fmt == 0) - return; - - QString const gui_name = toqstr(fmt->prettyname()); - QString const command = toqstr(form_->movers().command(fmt->name())); + Formats::const_iterator cit = formats_.begin(); + Formats::const_iterator end = formats_.end(); + for (; cit != end; ++cit) { + string const name = str(cit); + if (distance(formats_.begin(), cit) == nr()) { + input = toqstr(name); + return; - copierED->clear(); - int const combo_size = copierFormatCO->count(); - for (int i = 0; i < combo_size; ++i) { - QString const text = copierFormatCO->itemText(i); - if (text == gui_name) { - copierFormatCO->setCurrentIndex(i); - copierED->setText(command); - break; } } - updateButtons(); } -void PrefCopiers::switch_copierCO(int row) +QValidator::State FormatValidator::validate(QString & input, int & /*pos*/) const { - if (row<0) - return; - - std::string const combo_text = - fromqstr(copierFormatCO->currentText()); - Format const * fmt = getFormat(combo_text); - if (fmt == 0) - return; - - QString const command = toqstr(form_->movers().command(fmt->name())); - copierED->setText(command); - - QListWidgetItem * const index = AllCopiersLW->currentItem(); - if (index >= 0) - AllCopiersLW->setItemSelected(index, false); - - QString const gui_name = toqstr(fmt->prettyname()); - int const browser_size = AllCopiersLW->count(); - for (int i = 0; i < browser_size; ++i) { - QString const text = AllCopiersLW->item(i)->text(); - if (text == gui_name) { - QListWidgetItem * item = AllCopiersLW->item(i); - AllCopiersLW->setItemSelected(item, true); - break; - } + Formats::const_iterator cit = formats_.begin(); + Formats::const_iterator end = formats_.end(); + bool unknown = true; + for (; unknown && cit != end; ++cit) { + string const name = str(cit); + if (distance(formats_.begin(), cit) != nr()) + unknown = toqstr(name) != input; } + + if (unknown && !input.isEmpty()) + return QValidator::Acceptable; + else + return QValidator::Intermediate; } -void PrefCopiers::copiers_changed() +int FormatValidator::nr() const { - updateButtons(); + QComboBox * p = qobject_cast(parent()); + return p->itemData(p->currentIndex()).toInt(); } -void PrefCopiers::updateButtons() +FormatNameValidator::FormatNameValidator(QWidget * parent, Formats const & f) + : FormatValidator(parent, f) { - QString selected = copierFormatCO->currentText(); - - bool known = false; - for (int i = 0; i < AllCopiersLW->count(); ++i) { - if (AllCopiersLW->item(i)->text() == selected) - known = true; - } - - bool const valid = !copierED->text().isEmpty(); - - Format const * fmt = getFormat(fromqstr(selected)); - string const old_command = form_->movers().command(fmt->name()); - string const new_command(fromqstr(copierED->text())); - - bool modified = (old_command != new_command); - - copierModifyPB->setEnabled(valid && known && modified); - copierNewPB->setEnabled(valid && !known); - copierRemovePB->setEnabled(known); } - -void PrefCopiers::new_copier() +string FormatNameValidator::str(Formats::const_iterator it) const { - std::string const combo_text = - fromqstr(copierFormatCO->currentText()); - Format const * fmt = getFormat(combo_text); - if (fmt == 0) - return; - - string const command = fromqstr(copierED->text()); - if (command.empty()) - return; - - form_->movers().set(fmt->name(), command); - - updateView(); - int const last = AllCopiersLW->count() - 1; - AllCopiersLW->setCurrentRow(last); - - updateButtons(); + return it->name(); } -void PrefCopiers::modify_copier() +FormatPrettynameValidator::FormatPrettynameValidator(QWidget * parent, Formats const & f) + : FormatValidator(parent, f) { - std::string const combo_text = - fromqstr(copierFormatCO->currentText()); - Format const * fmt = getFormat(combo_text); - if (fmt == 0) - return; - - string const command = fromqstr(copierED->text()); - form_->movers().set(fmt->name(), command); - - updateView(); - updateButtons(); } -void PrefCopiers::remove_copier() +string FormatPrettynameValidator::str(Formats::const_iterator it) const { - std::string const combo_text = - fromqstr(copierFormatCO->currentText()); - Format const * fmt = getFormat(combo_text); - if (fmt == 0) - return; - - string const & fmt_name = fmt->name(); - form_->movers().set(fmt_name, string()); - - updateView(); - updateButtons(); + return it->prettyname(); } - -///////////////////////////////////////////////////////////////////// -// -// PrefFileformats -// -///////////////////////////////////////////////////////////////////// - -PrefFileformats::PrefFileformats(GuiPrefsDialog * form, QWidget * parent) +PrefFileformats::PrefFileformats(GuiPreferences * form, QWidget * parent) : PrefModule(_("File formats"), form, parent) { setupUi(this); + formatED->setValidator(new FormatNameValidator(formatsCB, form_->formats())); + formatsCB->setValidator(new FormatPrettynameValidator(formatsCB, form_->formats())); - connect(formatNewPB, SIGNAL(clicked()), - this, SLOT(new_format())); - connect(formatRemovePB, SIGNAL(clicked()), - this, SLOT(remove_format())); - connect(formatModifyPB, SIGNAL(clicked()), - this, SLOT(modify_format())); - connect(formatsLW, SIGNAL(currentRowChanged(int)), - this, SLOT(switch_format(int))); - connect(formatED, SIGNAL(textChanged(const QString&)), - this, SLOT(fileformat_changed())); - connect(guiNameED, SIGNAL(textChanged(const QString&)), - this, SLOT(fileformat_changed())); - connect(shortcutED, SIGNAL(textChanged(const QString&)), - this, SLOT(fileformat_changed())); - connect(extensionED, SIGNAL(textChanged(const QString&)), - this, SLOT(fileformat_changed())); - connect(viewerED, SIGNAL(textChanged(const QString&)), - this, SLOT(fileformat_changed())); - connect(editorED, SIGNAL(textChanged(const QString&)), - this, SLOT(fileformat_changed())); connect(documentCB, SIGNAL(clicked()), - this, SLOT(fileformat_changed())); + this, SLOT(setFlags())); connect(vectorCB, SIGNAL(clicked()), - this, SLOT(fileformat_changed())); - connect(formatNewPB, SIGNAL(clicked()), - this, SIGNAL(changed())); - connect(formatRemovePB, SIGNAL(clicked()), - this, SIGNAL(changed())); - connect(formatModifyPB, SIGNAL(clicked()), + this, SLOT(setFlags())); + connect(formatsCB->lineEdit(), SIGNAL(editingFinished()), + this, SLOT(updatePrettyname())); + connect(formatsCB->lineEdit(), SIGNAL(textEdited(QString)), this, SIGNAL(changed())); } @@ -1410,146 +1264,152 @@ void PrefFileformats::update(LyXRC const & /*rc*/) void PrefFileformats::updateView() { - // save current selection - QString current = guiNameED->text(); + QString const current = formatsCB->currentText(); - // update listwidget with formats - formatsLW->blockSignals(true); - formatsLW->clear(); + // update combobox with formats + formatsCB->blockSignals(true); + formatsCB->clear(); + form_->formats().sort(); Formats::const_iterator cit = form_->formats().begin(); Formats::const_iterator end = form_->formats().end(); - for (; cit != end; ++cit) { - new QListWidgetItem(toqstr(cit->prettyname()), - formatsLW, - form_->formats().getNumber(cit->name()) ); - } - formatsLW->sortItems(Qt::AscendingOrder); - formatsLW->blockSignals(false); + for (; cit != end; ++cit) + formatsCB->addItem(toqstr(cit->prettyname()), + QVariant(form_->formats().getNumber(cit->name())) ); // restore selection - if (!current.isEmpty()) { - QList item = formatsLW->findItems(current, Qt::MatchExactly); - if (item.size()>0) - formatsLW->setCurrentItem(item.at(0)); - } - // select first element if restoring failed - if (formatsLW->currentRow() == -1) - formatsLW->setCurrentRow(0); + int const item = formatsCB->findText(current, Qt::MatchExactly); + formatsCB->setCurrentIndex(item < 0 ? 0 : item); + on_formatsCB_currentIndexChanged(item < 0 ? 0 : item); + formatsCB->blockSignals(false); } -void PrefFileformats::switch_format(int nr) +void PrefFileformats::on_formatsCB_currentIndexChanged(int i) { - int const ftype = formatsLW->item(nr)->type(); - Format const f = form_->formats().get(ftype); + int const nr = formatsCB->itemData(i).toInt(); + Format const f = form_->formats().get(nr); formatED->setText(toqstr(f.name())); - guiNameED->setText(toqstr(f.prettyname())); + 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())); documentCB->setChecked((f.documentFormat())); vectorCB->setChecked((f.vectorFormat())); +} - updateButtons(); + +void PrefFileformats::setFlags() +{ + int flags = Format::none; + if (documentCB->isChecked()) + flags |= Format::document; + if (vectorCB->isChecked()) + flags |= Format::vector; + currentFormat().setFlags(flags); + changed(); } -void PrefFileformats::fileformat_changed() +void PrefFileformats::on_copierED_textEdited(const QString & s) { - updateButtons(); + string const fmt = fromqstr(formatED->text()); + form_->movers().set(fmt, fromqstr(s)); + changed(); } -void PrefFileformats::updateButtons() +void PrefFileformats::on_extensionED_textEdited(const QString & s) { - QString const format = formatED->text(); - QString const gui_name = guiNameED->text(); - int const sel = form_->formats().getNumber(fromqstr(format)); - bool gui_name_known = false; - int where = sel; - for (int i = 0; i < formatsLW->count(); ++i) { - if (formatsLW->item(i)->text() == gui_name) { - gui_name_known = true; - where = formatsLW->item(i)->type(); - } - } + currentFormat().setExtension(fromqstr(s)); + changed(); +} - // assure that a gui name cannot be chosen twice - bool const known_otherwise = gui_name_known && (where != sel); - - bool const known = !(sel < 0); - bool const valid = (!formatED->text().isEmpty() - && !guiNameED->text().isEmpty()); - - int const ftype = formatsLW->currentItem()->type(); - Format const & f(form_->formats().get(ftype)); - string const old_pretty(f.prettyname()); - string const old_shortcut(f.shortcut()); - string const old_extension(f.extension()); - string const old_viewer(f.viewer()); - string const old_editor(f.editor()); - bool const old_document(f.documentFormat()); - bool const old_vector(f.vectorFormat()); - - string const new_pretty(fromqstr(gui_name)); - string const new_shortcut(fromqstr(shortcutED->text())); - string const new_extension(fromqstr(extensionED->text())); - string const new_viewer(fromqstr(viewerED->text())); - string const new_editor(fromqstr(editorED->text())); - bool const new_document(documentCB->isChecked()); - bool const new_vector(vectorCB->isChecked()); - - bool modified = ((old_pretty != new_pretty) || (old_shortcut != new_shortcut) - || (old_extension != new_extension) || (old_viewer != new_viewer) - || old_editor != new_editor || old_document != new_document - || old_vector != new_vector); - - formatModifyPB->setEnabled(valid && known && modified && !known_otherwise); - formatNewPB->setEnabled(valid && !known && !gui_name_known); - formatRemovePB->setEnabled(known); -} - - -void PrefFileformats::new_format() -{ - string const name = fromqstr(formatED->text()); - string const prettyname = fromqstr(guiNameED->text()); - string const extension = fromqstr(extensionED->text()); - string const shortcut = fromqstr(shortcutED->text()); - string const viewer = fromqstr(viewerED->text()); - string const editor = fromqstr(editorED->text()); - int flags = Format::none; - if (documentCB->isChecked()) - flags |= Format::document; - if (vectorCB->isChecked()) - flags |= Format::vector; +void PrefFileformats::on_viewerED_textEdited(const QString & s) +{ + currentFormat().setViewer(fromqstr(s)); + changed(); +} - form_->formats().add(name, extension, prettyname, shortcut, viewer, - editor, flags); - form_->formats().sort(); - form_->converters().update(form_->formats()); - updateView(); - updateButtons(); +void PrefFileformats::on_editorED_textEdited(const QString & s) +{ + currentFormat().setEditor(fromqstr(s)); + changed(); +} + + +void PrefFileformats::on_shortcutED_textEdited(const QString & s) +{ + currentFormat().setShortcut(fromqstr(s)); + changed(); +} + + +void PrefFileformats::on_formatED_editingFinished() +{ + string const newname = fromqstr(formatED->displayText()); + if (newname == currentFormat().name()) + return; + + currentFormat().setName(newname); + changed(); +} + + +void PrefFileformats::on_formatED_textChanged(const QString &) +{ + QString t = formatED->text(); + int p = 0; + bool valid = formatED->validator()->validate(t, p) == QValidator::Acceptable; + setValid(formatLA, valid); +} + + +void PrefFileformats::on_formatsCB_editTextChanged(const QString &) +{ + QString t = formatsCB->currentText(); + int p = 0; + bool valid = formatsCB->validator()->validate(t, p) == QValidator::Acceptable; + setValid(formatsLA, valid); +} + + +void PrefFileformats::updatePrettyname() +{ + string const newname = fromqstr(formatsCB->currentText()); + if (newname == currentFormat().prettyname()) + return; + + currentFormat().setPrettyname(newname); formatsChanged(); + updateView(); + changed(); } -void PrefFileformats::modify_format() +Format & PrefFileformats::currentFormat() { - int const current_item = formatsLW->currentItem()->type(); - Format const & oldformat = form_->formats().get(current_item); - form_->formats().erase(oldformat.name()); + int const i = formatsCB->currentIndex(); + int const nr = formatsCB->itemData(i).toInt(); + return form_->formats().get(nr); +} - new_format(); + +void PrefFileformats::on_formatNewPB_clicked() +{ + form_->formats().add("", "", "", "", "", "", Format::none); + updateView(); + formatsCB->setCurrentIndex(0); + formatsCB->setFocus(Qt::OtherFocusReason); } -void PrefFileformats::remove_format() +void PrefFileformats::on_formatRemovePB_clicked() { - int const nr = formatsLW->currentItem()->type(); + int const i = formatsCB->currentIndex(); + int const nr = formatsCB->itemData(i).toInt(); string const current_text = form_->formats().get(nr).name(); if (form_->converters().formatIsUsed(current_text)) { Alert::error(_("Format in use"), @@ -1559,11 +1419,10 @@ void PrefFileformats::remove_format() } form_->formats().erase(current_text); - form_->converters().update(form_->formats()); - - updateView(); - updateButtons(); formatsChanged(); + updateView(); + on_formatsCB_editTextChanged(formatsCB->currentText()); + changed(); } @@ -1578,7 +1437,11 @@ PrefLanguage::PrefLanguage(QWidget * parent) { setupUi(this); - connect(rtlCB, SIGNAL(clicked()), + connect(rtlGB, SIGNAL(clicked()), + this, SIGNAL(changed())); + connect(visualCursorRB, SIGNAL(clicked()), + this, SIGNAL(changed())); + connect(logicalCursorRB, SIGNAL(clicked()), this, SIGNAL(changed())); connect(markForeignCB, SIGNAL(clicked()), this, SIGNAL(changed())); @@ -1590,11 +1453,11 @@ PrefLanguage::PrefLanguage(QWidget * parent) this, SIGNAL(changed())); connect(globalCB, SIGNAL(clicked()), this, SIGNAL(changed())); - connect(languagePackageED, SIGNAL(textChanged(const QString&)), + connect(languagePackageED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(startCommandED, SIGNAL(textChanged(const QString&)), + connect(startCommandED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(endCommandED, SIGNAL(textChanged(const QString&)), + connect(endCommandED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); connect(defaultLanguageCO, SIGNAL(activated(int)), this, SIGNAL(changed())); @@ -1602,13 +1465,13 @@ PrefLanguage::PrefLanguage(QWidget * parent) defaultLanguageCO->clear(); // store the lang identifiers for later - std::vector const langs = frontend::getLanguageData(false); - lang_ = getSecond(langs); - - std::vector::const_iterator lit = langs.begin(); - std::vector::const_iterator lend = langs.end(); + vector const langs = getLanguageData(false); + vector::const_iterator lit = langs.begin(); + vector::const_iterator lend = langs.end(); + lang_.clear(); for (; lit != lend; ++lit) { defaultLanguageCO->addItem(toqstr(lit->first)); + lang_.push_back(lit->second); } } @@ -1616,7 +1479,8 @@ PrefLanguage::PrefLanguage(QWidget * parent) void PrefLanguage::apply(LyXRC & rc) const { // FIXME: remove rtl_support bool - rc.rtl_support = rtlCB->isChecked(); + rc.rtl_support = rtlGB->isChecked(); + rc.visual_cursor = rtlGB->isChecked() && visualCursorRB->isChecked(); rc.mark_foreign_language = markForeignCB->isChecked(); rc.language_auto_begin = autoBeginCB->isChecked(); rc.language_auto_end = autoEndCB->isChecked(); @@ -1632,7 +1496,11 @@ void PrefLanguage::apply(LyXRC & rc) const void PrefLanguage::update(LyXRC const & rc) { // FIXME: remove rtl_support bool - rtlCB->setChecked(rc.rtl_support); + rtlGB->setChecked(rc.rtl_support); + if (rc.visual_cursor) + visualCursorRB->setChecked(true); + else + logicalCursorRB->setChecked(true); markForeignCB->setChecked(rc.mark_foreign_language); autoBeginCB->setChecked(rc.language_auto_begin); autoEndCB->setChecked(rc.language_auto_end); @@ -1660,39 +1528,39 @@ PrefPrinter::PrefPrinter(QWidget * parent) connect(printerAdaptCB, SIGNAL(clicked()), this, SIGNAL(changed())); - connect(printerCommandED, SIGNAL(textChanged(const QString&)), + connect(printerCommandED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(printerNameED, SIGNAL(textChanged(const QString&)), + connect(printerNameED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(printerPageRangeED, SIGNAL(textChanged(const QString&)), + connect(printerPageRangeED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(printerCopiesED, SIGNAL(textChanged(const QString&)), + connect(printerCopiesED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(printerReverseED, SIGNAL(textChanged(const QString&)), + connect(printerReverseED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(printerToPrinterED, SIGNAL(textChanged(const QString&)), + connect(printerToPrinterED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(printerExtensionED, SIGNAL(textChanged(const QString&)), + connect(printerExtensionED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(printerSpoolCommandED, SIGNAL(textChanged(const QString&)), + connect(printerSpoolCommandED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(printerPaperTypeED, SIGNAL(textChanged(const QString&)), + connect(printerPaperTypeED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(printerEvenED, SIGNAL(textChanged(const QString&)), + connect(printerEvenED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(printerOddED, SIGNAL(textChanged(const QString&)), + connect(printerOddED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(printerCollatedED, SIGNAL(textChanged(const QString&)), + connect(printerCollatedED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(printerLandscapeED, SIGNAL(textChanged(const QString&)), + connect(printerLandscapeED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(printerToFileED, SIGNAL(textChanged(const QString&)), + connect(printerToFileED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(printerExtraED, SIGNAL(textChanged(const QString&)), + connect(printerExtraED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(printerSpoolPrefixED, SIGNAL(textChanged(const QString&)), + connect(printerSpoolPrefixED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(printerPaperSizeED, SIGNAL(textChanged(const QString&)), + connect(printerPaperSizeED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); } @@ -1751,38 +1619,30 @@ void PrefPrinter::update(LyXRC const & rc) // ///////////////////////////////////////////////////////////////////// -PrefUserInterface::PrefUserInterface(GuiPrefsDialog * form, QWidget * parent) +PrefUserInterface::PrefUserInterface(GuiPreferences * form, QWidget * parent) : PrefModule(_("User interface"), form, parent) { setupUi(this); - connect(autoSaveCB, SIGNAL(toggled(bool)), - autoSaveLA, SLOT(setEnabled(bool))); connect(autoSaveCB, SIGNAL(toggled(bool)), autoSaveSB, SLOT(setEnabled(bool))); connect(autoSaveCB, SIGNAL(toggled(bool)), TextLabel1, SLOT(setEnabled(bool))); connect(uiFilePB, SIGNAL(clicked()), this, SLOT(select_ui())); - connect(bindFilePB, SIGNAL(clicked()), - this, SLOT(select_bind())); - connect(uiFileED, SIGNAL(textChanged(const QString &)), - this, SIGNAL(changed())); - connect(bindFileED, SIGNAL(textChanged(const QString &)), + connect(uiFileED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); connect(restoreCursorCB, SIGNAL(clicked()), this, SIGNAL(changed())); connect(loadSessionCB, SIGNAL(clicked()), this, SIGNAL(changed())); - connect(loadWindowSizeCB, SIGNAL(clicked()), + connect(allowGeometrySessionCB, SIGNAL(clicked()), this, SIGNAL(changed())); - connect(loadWindowLocationCB, SIGNAL(clicked()), - this, SIGNAL(changed())); - connect(windowWidthSB, SIGNAL(valueChanged(int)), + connect(cursorFollowsCB, SIGNAL(clicked()), this, SIGNAL(changed())); - connect(windowHeightSB, SIGNAL(valueChanged(int)), + connect(sortEnvironmentsCB, SIGNAL(clicked()), this, SIGNAL(changed())); - connect(cursorFollowsCB, SIGNAL(clicked()), + connect(macroEditStyleCO, SIGNAL(activated(int)), this, SIGNAL(changed())); connect(autoSaveSB, SIGNAL(valueChanged(int)), this, SIGNAL(changed())); @@ -1790,6 +1650,8 @@ PrefUserInterface::PrefUserInterface(GuiPrefsDialog * form, QWidget * parent) this, SIGNAL(changed())); connect(lastfilesSB, SIGNAL(valueChanged(int)), this, SIGNAL(changed())); + connect(tooltipCB, SIGNAL(toggled(bool)), + this, SIGNAL(changed())); lastfilesSB->setMaximum(maxlastfiles); } @@ -1797,38 +1659,32 @@ PrefUserInterface::PrefUserInterface(GuiPrefsDialog * form, QWidget * parent) void PrefUserInterface::apply(LyXRC & rc) const { rc.ui_file = internal_path(fromqstr(uiFileED->text())); - rc.bind_file = internal_path(fromqstr(bindFileED->text())); rc.use_lastfilepos = restoreCursorCB->isChecked(); rc.load_session = loadSessionCB->isChecked(); - if (loadWindowSizeCB->isChecked()) { - rc.geometry_width = 0; - rc.geometry_height = 0; - } else { - rc.geometry_width = windowWidthSB->value(); - rc.geometry_height = windowHeightSB->value(); - } - rc.geometry_xysaved = loadWindowLocationCB->isChecked(); + rc.allow_geometry_session = allowGeometrySessionCB->isChecked(); rc.cursor_follows_scrollbar = cursorFollowsCB->isChecked(); + rc.sort_layouts = sortEnvironmentsCB->isChecked(); + switch (macroEditStyleCO->currentIndex()) { + case 0: rc.macro_edit_style = LyXRC::MACRO_EDIT_INLINE_BOX; break; + case 1: rc.macro_edit_style = LyXRC::MACRO_EDIT_INLINE; break; + case 2: rc.macro_edit_style = LyXRC::MACRO_EDIT_LIST; break; + } rc.autosave = autoSaveSB->value() * 60; rc.make_backup = autoSaveCB->isChecked(); rc.num_lastfiles = lastfilesSB->value(); + rc.use_tooltip = tooltipCB->isChecked(); } void PrefUserInterface::update(LyXRC const & rc) { uiFileED->setText(toqstr(external_path(rc.ui_file))); - bindFileED->setText(toqstr(external_path(rc.bind_file))); restoreCursorCB->setChecked(rc.use_lastfilepos); loadSessionCB->setChecked(rc.load_session); - bool loadWindowSize = rc.geometry_width == 0 && rc.geometry_height == 0; - loadWindowSizeCB->setChecked(loadWindowSize); - if (!loadWindowSize) { - windowWidthSB->setValue(rc.geometry_width); - windowHeightSB->setValue(rc.geometry_height); - } - loadWindowLocationCB->setChecked(rc.geometry_xysaved); + allowGeometrySessionCB->setChecked(rc.allow_geometry_session); cursorFollowsCB->setChecked(rc.cursor_follows_scrollbar); + sortEnvironmentsCB->setChecked(rc.sort_layouts); + macroEditStyleCO->setCurrentIndex(rc.macro_edit_style); // convert to minutes int mins(rc.autosave / 60); if (rc.autosave && !mins) @@ -1836,47 +1692,437 @@ void PrefUserInterface::update(LyXRC const & rc) autoSaveSB->setValue(mins); autoSaveCB->setChecked(rc.make_backup); lastfilesSB->setValue(rc.num_lastfiles); + tooltipCB->setChecked(rc.use_tooltip); } - void PrefUserInterface::select_ui() { docstring const name = from_utf8(internal_path(fromqstr(uiFileED->text()))); - docstring file(form_->controller().browseUI(name)); + docstring file = form_->browseUI(name); if (!file.empty()) uiFileED->setText(toqstr(file)); } -void PrefUserInterface::select_bind() +///////////////////////////////////////////////////////////////////// +// +// PrefShortcuts +// +///////////////////////////////////////////////////////////////////// + + +GuiShortcutDialog::GuiShortcutDialog(QWidget * parent) : QDialog(parent) +{ + Ui::shortcutUi::setupUi(this); + QDialog::setModal(true); +} + + +PrefShortcuts::PrefShortcuts(GuiPreferences * form, QWidget * parent) + : PrefModule(_("Shortcuts"), form, parent) +{ + setupUi(this); + + shortcutsTW->setColumnCount(2); + shortcutsTW->headerItem()->setText(0, qt_("Function")); + shortcutsTW->headerItem()->setText(1, qt_("Shortcut")); + shortcutsTW->setSortingEnabled(true); + // Multi-selection can be annoying. + // shortcutsTW->setSelectionMode(QAbstractItemView::MultiSelection); + shortcutsTW->header()->resizeSection(0, 200); + + connect(bindFilePB, SIGNAL(clicked()), + this, SLOT(select_bind())); + connect(bindFileED, SIGNAL(textChanged(QString)), + this, SIGNAL(changed())); + connect(removePB, SIGNAL(clicked()), + this, SIGNAL(changed())); + + shortcut_ = new GuiShortcutDialog(this); + shortcut_bc_.setPolicy(ButtonPolicy::OkCancelPolicy); + shortcut_bc_.setOK(shortcut_->okPB); + shortcut_bc_.setCancel(shortcut_->cancelPB); + + connect(shortcut_->okPB, SIGNAL(clicked()), + shortcut_, SLOT(accept())); + connect(shortcut_->okPB, SIGNAL(clicked()), + this, SIGNAL(changed())); + 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())); +} + + +void PrefShortcuts::apply(LyXRC & rc) const +{ + rc.bind_file = internal_path(fromqstr(bindFileED->text())); + // write user_bind and user_unbind to .lyx/bind/user.bind + FileName bind_dir(addPath(package().user_support().absFilename(), "bind")); + if (!bind_dir.exists() && !bind_dir.createDirectory(0777)) { + lyxerr << "LyX could not create the user bind directory '" + << bind_dir << "'. All user-defined key bindings will be lost." << endl; + return; + } + if (!bind_dir.isDirWritable()) { + lyxerr << "LyX could not write to the user bind directory '" + << bind_dir << "'. All user-defined key bindings will be lost." << endl; + 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); + // 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"); +} + + +void PrefShortcuts::update(LyXRC const & rc) +{ + bindFileED->setText(toqstr(external_path(rc.bind_file))); + // + system_bind_.clear(); + user_bind_.clear(); + user_unbind_.clear(); + system_bind_.read(rc.bind_file); + // \unbind in user.bind is added to user_unbind_ + user_bind_.read("user", &user_unbind_); + updateShortcutsTW(); +} + + +void PrefShortcuts::updateShortcutsTW() +{ + shortcutsTW->clear(); + + editItem_ = new QTreeWidgetItem(shortcutsTW); + editItem_->setText(0, toqstr("Cursor, Mouse and Editing functions")); + editItem_->setFlags(editItem_->flags() & ~Qt::ItemIsSelectable); + + mathItem_ = new QTreeWidgetItem(shortcutsTW); + mathItem_->setText(0, toqstr("Mathematical Symbols")); + mathItem_->setFlags(mathItem_->flags() & ~Qt::ItemIsSelectable); + + bufferItem_ = new QTreeWidgetItem(shortcutsTW); + bufferItem_->setText(0, toqstr("Buffer and Window")); + bufferItem_->setFlags(bufferItem_->flags() & ~Qt::ItemIsSelectable); + + layoutItem_ = new QTreeWidgetItem(shortcutsTW); + layoutItem_->setText(0, toqstr("Font, Layouts and Textclasses")); + layoutItem_->setFlags(layoutItem_->flags() & ~Qt::ItemIsSelectable); + + systemItem_ = new QTreeWidgetItem(shortcutsTW); + systemItem_->setText(0, toqstr("System and Miscellaneous")); + systemItem_->setFlags(systemItem_->flags() & ~Qt::ItemIsSelectable); + + // 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 user_bindinglist = user_bind_.listBindings(false, + static_cast(UserBind)); + KeyMap::BindingList user_unbindinglist = user_unbind_.listBindings(false, + static_cast(UserUnbind)); + bindinglist.insert(bindinglist.end(), user_bindinglist.begin(), + user_bindinglist.end()); + bindinglist.insert(bindinglist.end(), user_unbindinglist.begin(), + user_unbindinglist.end()); + + 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)); + + shortcutsTW->sortItems(0, Qt::AscendingOrder); + QList items = shortcutsTW->selectedItems(); + removePB->setEnabled(!items.isEmpty() && !items[0]->text(1).isEmpty()); +} + + +void PrefShortcuts::setItemType(QTreeWidgetItem * item, item_type tag) +{ + item->setData(0, Qt::UserRole, QVariant(tag)); + QFont font; + + switch (tag) { + case System: + break; + case UserBind: + font.setBold(true); + break; + case UserUnbind: + font.setStrikeOut(true); + break; + // this item is not displayed now. + case UserExtraUnbind: + font.setStrikeOut(true); + break; + } + + item->setFont(1, font); +} + + +QTreeWidgetItem * PrefShortcuts::insertShortcutItem(FuncRequest const & lfun, + KeySequence const & seq, item_type tag) +{ + kb_action action = lfun.action; + string const action_name = lyxaction.getActionName(action); + QString const lfun_name = toqstr(from_utf8(action_name) + + " " + lfun.argument()); + QString const shortcut = toqstr(seq.print(KeySequence::ForGui)); + item_type item_tag = tag; + + QTreeWidgetItem * newItem = NULL; + // for unbind items, try to find an existing item in the system bind list + if (tag == 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 + // unmatched removed?). + if (!newItem) { + item_tag = UserExtraUnbind; + return NULL; + } + } + if (!newItem) { + switch(lyxaction.getActionType(action)) { + case LyXAction::Hidden: + return NULL; + case LyXAction::Edit: + newItem = new QTreeWidgetItem(editItem_); + break; + case LyXAction::Math: + newItem = new QTreeWidgetItem(mathItem_); + break; + case LyXAction::Buffer: + newItem = new QTreeWidgetItem(bufferItem_); + break; + case LyXAction::Layout: + newItem = new QTreeWidgetItem(layoutItem_); + break; + case LyXAction::System: + newItem = new QTreeWidgetItem(systemItem_); + break; + default: + // this should not happen + newItem = new QTreeWidgetItem(shortcutsTW); + } + } + + newItem->setText(0, lfun_name); + newItem->setText(1, shortcut); + // record BindFile representation to recover KeySequence when needed. + newItem->setData(1, Qt::UserRole, toqstr(seq.print(KeySequence::BindFile))); + setItemType(newItem, item_tag); + return newItem; +} + + +void PrefShortcuts::on_shortcutsTW_itemSelectionChanged() +{ + QList items = shortcutsTW->selectedItems(); + removePB->setEnabled(!items.isEmpty() && !items[0]->text(1).isEmpty()); + if (items.isEmpty()) + return; + + item_type tag = static_cast(items[0]->data(0, Qt::UserRole).toInt()); + if (tag == UserUnbind) + removePB->setText(toqstr("Restore")); + else + removePB->setText(toqstr("Remove")); +} + + +void PrefShortcuts::on_shortcutsTW_itemDoubleClicked() +{ + QTreeWidgetItem * item = shortcutsTW->currentItem(); + if (item->flags() & Qt::ItemIsSelectable) { + shortcut_->lfunLE->setText(item->text(0)); + // clear the shortcut because I assume that a user will enter + // a new shortcut. + shortcut_->shortcutLE->reset(); + shortcut_->shortcutLE->setFocus(); + shortcut_->exec(); + } +} + + +void PrefShortcuts::select_bind() { docstring const name = from_utf8(internal_path(fromqstr(bindFileED->text()))); - docstring file(form_->controller().browsebind(name)); - if (!file.empty()) + docstring file = form_->browsebind(name); + if (!file.empty()) { bindFileED->setText(toqstr(file)); + system_bind_ = KeyMap(); + system_bind_.read(to_utf8(file)); + updateShortcutsTW(); + } +} + + +void PrefShortcuts::on_newPB_pressed() +{ + shortcut_->lfunLE->clear(); + shortcut_->shortcutLE->reset(); + shortcut_->exec(); +} + + +void PrefShortcuts::on_removePB_pressed() +{ + // it seems that only one item can be selected, but I am + // removing all selected items anyway. + QList items = shortcutsTW->selectedItems(); + for (int i = 0; i < items.size(); ++i) { + 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()); + + switch (tag) { + case 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); + removePB->setText(toqstr("Restore")); + break; + } + case UserBind: { + // for user_bind, we remove this bind + QTreeWidgetItem * parent = items[i]->parent(); + int itemIdx = parent->indexOfChild(items[i]); + parent->takeChild(itemIdx); + if (itemIdx > 0) + shortcutsTW->scrollToItem(parent->child(itemIdx - 1)); + else + shortcutsTW->scrollToItem(parent); + user_bind_.unbind(shortcut, func); + break; + } + case UserUnbind: { + // for user_unbind, we remove the unbind, and the item + // become System again. + user_unbind_.unbind(shortcut, func); + setItemType(items[i], System); + removePB->setText(toqstr("Remove")); + break; + } + case UserExtraUnbind: { + // for user unbind that is not in system bind file, + // remove this unbind file + QTreeWidgetItem * parent = items[i]->parent(); + parent->takeChild(parent->indexOfChild(items[i])); + user_unbind_.unbind(shortcut, func); + } + } + } +} + + +void PrefShortcuts::on_searchLE_textEdited() +{ + if (searchLE->text().isEmpty()) { + // show all hidden items + QTreeWidgetItemIterator it(shortcutsTW, QTreeWidgetItemIterator::Hidden); + while (*it) + shortcutsTW->setItemHidden(*it++, false); + return; + } + // search both columns + QList matched = shortcutsTW->findItems(searchLE->text(), + 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) + shortcutsTW->setItemHidden(*it++, true); + // show matched items + for (int i = 0; i < matched.size(); ++i) { + shortcutsTW->setItemHidden(matched[i], false); + shortcutsTW->setItemExpanded(matched[i]->parent(), true); + } +} + + +void PrefShortcuts::shortcut_okPB_pressed() +{ + string lfun = fromqstr(shortcut_->lfunLE->text()); + FuncRequest func = lyxaction.lookupFunc(lfun); + + if (func.action == LFUN_UNKNOWN_ACTION) { + Alert::error(_("Failed to create shortcut"), + _("Unknown or invalid LyX function")); + return; + } + + KeySequence k = shortcut_->shortcutLE->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)) { + Alert::error(_("Failed to create shortcut"), + _("Shortcut is already defined")); + return; + } + + QTreeWidgetItem * item = insertShortcutItem(func, k, UserBind); + if (item) { + user_bind_.bind(&k, func); + shortcutsTW->sortItems(0, Qt::AscendingOrder); + shortcutsTW->setItemExpanded(item->parent(), true); + shortcutsTW->scrollToItem(item); + } else { + Alert::error(_("Failed to create shortcut"), + _("Can not insert shortcut to the list")); + return; + } } -void PrefUserInterface::on_loadWindowSizeCB_toggled(bool loadwindowsize) +void PrefShortcuts::shortcut_clearPB_pressed() { - windowWidthLA->setDisabled(loadwindowsize); - windowHeightLA->setDisabled(loadwindowsize); - windowWidthSB->setDisabled(loadwindowsize); - windowHeightSB->setDisabled(loadwindowsize); + shortcut_->shortcutLE->reset(); + shortcut_->shortcutLE->setFocus(); } +///////////////////////////////////////////////////////////////////// +// +// PrefIdentity +// +///////////////////////////////////////////////////////////////////// + PrefIdentity::PrefIdentity(QWidget * parent) -: PrefModule(_("Identity"), 0, parent) + : PrefModule(_("Identity"), 0, parent) { setupUi(this); - connect(nameED, SIGNAL(textChanged(const QString&)), + connect(nameED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(emailED, SIGNAL(textChanged(const QString&)), + connect(emailED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); } @@ -1898,16 +2144,14 @@ void PrefIdentity::update(LyXRC const & rc) ///////////////////////////////////////////////////////////////////// // -// GuiPrefsDialog +// GuiPreferences // ///////////////////////////////////////////////////////////////////// -GuiPrefsDialog::GuiPrefsDialog(LyXView & lv) - : GuiDialog(lv, "prefs") +GuiPreferences::GuiPreferences(GuiView & lv) + : GuiDialog(lv, "prefs", qt_("Preferences")), update_screen_font_(false) { setupUi(this); - setViewTitle(_("Preferences")); - setController(new ControlPrefs(*this)); QDialog::setModal(false); @@ -1917,10 +2161,11 @@ GuiPrefsDialog::GuiPrefsDialog(LyXView & lv) connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore())); add(new PrefUserInterface(this)); + add(new PrefShortcuts(this)); add(new PrefScreenFonts(this)); add(new PrefColors(this)); add(new PrefDisplay); - add(new PrefKeyboard(this)); + add(new PrefInput(this)); add(new PrefPaths(this)); @@ -1941,9 +2186,6 @@ GuiPrefsDialog::GuiPrefsDialog(LyXView & lv) add(converters); add(formats); - add(new PrefCopiers(this)); - - prefsPS->setCurrentPanel(_("User interface")); // FIXME: hack to work around resizing bug in Qt >= 4.2 // bug verified with Qt 4.2.{0-3} (JSpitzm) @@ -1959,13 +2201,7 @@ GuiPrefsDialog::GuiPrefsDialog(LyXView & lv) } -ControlPrefs & GuiPrefsDialog::controller() const -{ - return static_cast(GuiDialog::controller()); -} - - -void GuiPrefsDialog::add(PrefModule * module) +void GuiPreferences::add(PrefModule * module) { BOOST_ASSERT(module); prefsPS->addPanel(module, module->title()); @@ -1974,20 +2210,13 @@ void GuiPrefsDialog::add(PrefModule * module) } -void GuiPrefsDialog::closeEvent(QCloseEvent * e) -{ - slotClose(); - e->accept(); -} - - -void GuiPrefsDialog::change_adaptor() +void GuiPreferences::change_adaptor() { changed(); } -void GuiPrefsDialog::apply(LyXRC & rc) const +void GuiPreferences::apply(LyXRC & rc) const { size_t end = modules_.size(); for (size_t i = 0; i != end; ++i) @@ -1995,7 +2224,7 @@ void GuiPrefsDialog::apply(LyXRC & rc) const } -void GuiPrefsDialog::updateRc(LyXRC const & rc) +void GuiPreferences::updateRc(LyXRC const & rc) { size_t const end = modules_.size(); for (size_t i = 0; i != end; ++i) @@ -2003,31 +2232,186 @@ void GuiPrefsDialog::updateRc(LyXRC const & rc) } -Converters & GuiPrefsDialog::converters() +void GuiPreferences::applyView() +{ + apply(rc()); +} + + +void GuiPreferences::updateContents() +{ + updateRc(rc()); +} + + +bool GuiPreferences::initialiseParams(string const &) +{ + rc_ = lyxrc; + formats_ = lyx::formats; + converters_ = theConverters(); + converters_.update(formats_); + movers_ = theMovers(); + colors_.clear(); + update_screen_font_ = false; + + return true; +} + + +void GuiPreferences::dispatchParams() +{ + ostringstream ss; + rc_.write(ss, true); + 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)); + + lyx::formats = formats_; + + theConverters() = converters_; + theConverters().update(lyx::formats); + theConverters().buildGraph(); + + theMovers() = movers_; + + vector::const_iterator it = colors_.begin(); + vector::const_iterator const end = colors_.end(); + for (; it != end; ++it) + dispatch(FuncRequest(LFUN_SET_COLOR, *it)); + colors_.clear(); + + if (update_screen_font_) { + dispatch(FuncRequest(LFUN_SCREEN_FONT_UPDATE)); + update_screen_font_ = false; + } + + // The Save button has been pressed + if (isClosing()) + dispatch(FuncRequest(LFUN_PREFERENCES_SAVE)); +} + + +void GuiPreferences::setColor(ColorCode col, string const & hex) +{ + colors_.push_back(lcolor.getLyXName(col) + ' ' + hex); +} + + +void GuiPreferences::updateScreenFonts() +{ + update_screen_font_ = true; +} + + +docstring const GuiPreferences::browsebind(docstring const & file) const +{ + return browseLibFile(from_ascii("bind"), file, from_ascii("bind"), + _("Choose bind file"), + FileFilterList(_("LyX bind files (*.bind)"))); +} + + +docstring const GuiPreferences::browseUI(docstring const & file) const +{ + return browseLibFile(from_ascii("ui"), file, from_ascii("ui"), + _("Choose UI file"), + FileFilterList(_("LyX UI files (*.ui)"))); +} + + +docstring const GuiPreferences::browsekbmap(docstring const & file) const +{ + return browseLibFile(from_ascii("kbd"), file, from_ascii("kmap"), + _("Choose keyboard map"), + FileFilterList(_("LyX keyboard maps (*.kmap)"))); +} + + +docstring const GuiPreferences::browsedict(docstring const & file) const { - return controller().converters(); + if (lyxrc.use_spell_lib) + return browseFile(file, + _("Choose personal dictionary"), + FileFilterList(_("*.pws"))); + else + return browseFile(file, + _("Choose personal dictionary"), + FileFilterList(_("*.ispell"))); } -Formats & GuiPrefsDialog::formats() + +docstring const GuiPreferences::browse(docstring const & file, + docstring const & title) const { - return controller().formats(); + return browseFile(file, title, FileFilterList(), true); } -Movers & GuiPrefsDialog::movers() + +docstring const GuiPreferences::browsedir(docstring const & path, + docstring const & title) const { - return controller().movers(); + return browseDir(path, title); } -void GuiPrefsDialog::applyView() + +// We support less paper sizes than the document dialog +// Therefore this adjustment is needed. +PAPER_SIZE GuiPreferences::toPaperSize(int i) const { - apply(controller().rc()); + switch (i) { + case 0: + return PAPER_DEFAULT; + case 1: + return PAPER_USLETTER; + case 2: + return PAPER_USLEGAL; + case 3: + return PAPER_USEXECUTIVE; + case 4: + return PAPER_A3; + case 5: + return PAPER_A4; + case 6: + return PAPER_A5; + case 7: + return PAPER_B5; + default: + // should not happen + return PAPER_DEFAULT; + } } -void GuiPrefsDialog::update_contents() + +int GuiPreferences::fromPaperSize(PAPER_SIZE papersize) const { - updateRc(controller().rc()); + switch (papersize) { + case PAPER_DEFAULT: + return 0; + case PAPER_USLETTER: + return 1; + case PAPER_USLEGAL: + return 2; + case PAPER_USEXECUTIVE: + return 3; + case PAPER_A3: + return 4; + case PAPER_A4: + return 5; + case PAPER_A5: + return 6; + case PAPER_B5: + return 7; + default: + // should not happen + return 0; + } } + +Dialog * createGuiPreferences(GuiView & lv) { return new GuiPreferences(lv); } + + } // namespace frontend } // namespace lyx