X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt4%2FGuiPrefs.cpp;h=290089b3f1bf080d999dfbfe5710e1b5510905e3;hb=ba76bf5eb85db5a10839fccee3430d906d3f7b70;hp=eeb370c6bfe1c04e306e8387a5b239b011bf3f12;hpb=94776982b2fa2b583696fca80116920d504ac41f;p=lyx.git diff --git a/src/frontends/qt4/GuiPrefs.cpp b/src/frontends/qt4/GuiPrefs.cpp index eeb370c6bf..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. */ @@ -19,11 +20,11 @@ #include "BufferList.h" #include "Color.h" #include "ConverterCache.h" -#include "debug.h" -#include "Font.h" +#include "support/debug.h" #include "FuncRequest.h" -#include "gettext.h" +#include "support/gettext.h" #include "GuiFontExample.h" +#include "GuiKeySymbol.h" #include "KeyMap.h" #include "KeySequence.h" #include "LyXAction.h" @@ -31,11 +32,14 @@ #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" @@ -52,31 +56,20 @@ #include #include #include -#include #include #include #include -#include using namespace Ui; -using std::endl; -using std::ostringstream; -using std::pair; -using std::string; -using std::vector; +using namespace std; +using namespace lyx::support; +using namespace lyx::support::os; namespace lyx { namespace frontend { -using support::compare_ascii_no_case; -using support::os::external_path; -using support::os::external_path_list; -using support::os::internal_path; -using support::os::internal_path_list; -using support::FileFilterList; - ///////////////////////////////////////////////////////////////////// // @@ -85,24 +78,29 @@ using support::FileFilterList; ///////////////////////////////////////////////////////////////////// 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 std::pair parseFontName(string const & name) +static void parseFontName(QString const & mangled0, + string & name, string & foundry) { - string::size_type const idx = name.find('['); - if (idx == string::npos || idx == 0) - return make_pair(name, string()); - return make_pair(name.substr(0, idx - 1), - name.substr(idx + 1, name.size() - idx - 2)); + 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); + } } @@ -124,20 +122,23 @@ static void setComboxFont(QComboBox * cb, string const & family, // We count in reverse in order to prefer the Xft foundry for (int i = cb->count(); --i >= 0;) { - pair tmp = parseFontName(fromqstr(cb->itemText(i))); - if (compare_ascii_no_case(tmp.first, family) == 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; } @@ -149,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; @@ -165,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) { @@ -195,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())); } @@ -224,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())); } @@ -243,49 +245,53 @@ void PrefDate::update(LyXRC const & rc) ///////////////////////////////////////////////////////////////////// // -// PrefKeyboard +// PrefInput // ///////////////////////////////////////////////////////////////////// -PrefKeyboard::PrefKeyboard(GuiPreferences * 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_->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()) @@ -293,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()) @@ -301,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); @@ -322,17 +328,17 @@ 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())); @@ -390,12 +396,12 @@ PrefScreenFonts::PrefScreenFonts(GuiPreferences * form, QWidget * 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()); @@ -404,35 +410,37 @@ PrefScreenFonts::PrefScreenFonts(GuiPreferences * 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)); @@ -450,27 +458,28 @@ PrefScreenFonts::PrefScreenFonts(GuiPreferences * form, QWidget * parent) 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 @@ -502,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); } @@ -542,7 +558,7 @@ namespace { struct ColorSorter { - bool operator()(Color::color const & lhs, Color::color const & rhs) const { + bool operator()(ColorCode lhs, ColorCode rhs) const { return lcolor.getGUIName(lhs) < lcolor.getGUIName(rhs); } }; @@ -558,25 +574,25 @@ PrefColors::PrefColors(GuiPreferences * 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); } - std::sort(lcolors_.begin(), lcolors_.end(), ColorSorter()); - vector::const_iterator cit = lcolors_.begin(); - vector::const_iterator const end = lcolors_.end(); + 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); @@ -666,20 +682,20 @@ void PrefDisplay::apply(LyXRC & rc) const 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 @@ -702,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); @@ -722,22 +738,25 @@ 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(templateDirED, SIGNAL(textChanged(const QString&)), + connect(exampleDirED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(backupDirED, SIGNAL(textChanged(const QString&)), + connect(templateDirED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(tempDirED, SIGNAL(textChanged(const QString&)), + connect(backupDirED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(lyxserverDirED, SIGNAL(textChanged(const QString&)), + connect(tempDirED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); - connect(pathPrefixED, SIGNAL(textChanged(const QString&)), + connect(lyxserverDirED, SIGNAL(textChanged(QString)), + this, SIGNAL(changed())); + connect(pathPrefixED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); } @@ -745,6 +764,7 @@ PrefPaths::PrefPaths(GuiPreferences * 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())); @@ -757,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))); @@ -766,6 +787,16 @@ 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_->browsedir( @@ -834,11 +865,11 @@ PrefSpellchecker::PrefSpellchecker(GuiPreferences * 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())); @@ -945,13 +976,13 @@ PrefConverters::PrefConverters(GuiPreferences * 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(textEdited(const QString&)), + connect(converterED, SIGNAL(textEdited(QString)), this, SLOT(converter_changed())); - connect(converterFlagED, SIGNAL(textEdited(const QString&)), + connect(converterFlagED, SIGNAL(textEdited(QString)), this, SLOT(converter_changed())); connect(converterNewPB, SIGNAL(clicked()), this, SIGNAL(changed())); @@ -959,7 +990,7 @@ PrefConverters::PrefConverters(GuiPreferences * form, QWidget * parent) this, SIGNAL(changed())); connect(converterModifyPB, SIGNAL(clicked()), this, SIGNAL(changed())); - connect(maxAgeLE, SIGNAL(textEdited(const QString&)), + connect(maxAgeLE, SIGNAL(textEdited(QString)), this, SIGNAL(changed())); maxAgeLE->setValidator(new QDoubleValidator(maxAgeLE)); @@ -1010,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); @@ -1058,7 +1089,7 @@ void PrefConverters::updateButtons() 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()); @@ -1069,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); @@ -1132,6 +1163,7 @@ void PrefConverters::on_cacheCB_stateChanged(int state) // PrefFileformats // ///////////////////////////////////////////////////////////////////// +// FormatValidator::FormatValidator(QWidget * parent, Formats const & f) : QValidator(parent), formats_(f) { @@ -1183,7 +1215,7 @@ FormatNameValidator::FormatNameValidator(QWidget * parent, Formats const & f) { } -std::string FormatNameValidator::str(Formats::const_iterator it) const +string FormatNameValidator::str(Formats::const_iterator it) const { return it->name(); } @@ -1195,7 +1227,7 @@ FormatPrettynameValidator::FormatPrettynameValidator(QWidget * parent, Formats c } -std::string FormatPrettynameValidator::str(Formats::const_iterator it) const +string FormatPrettynameValidator::str(Formats::const_iterator it) const { return it->prettyname(); } @@ -1214,7 +1246,7 @@ PrefFileformats::PrefFileformats(GuiPreferences * form, QWidget * parent) this, SLOT(setFlags())); connect(formatsCB->lineEdit(), SIGNAL(editingFinished()), this, SLOT(updatePrettyname())); - connect(formatsCB->lineEdit(), SIGNAL(textEdited(const QString &)), + connect(formatsCB->lineEdit(), SIGNAL(textEdited(QString)), this, SIGNAL(changed())); } @@ -1405,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())); @@ -1417,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())); @@ -1429,9 +1465,9 @@ PrefLanguage::PrefLanguage(QWidget * parent) defaultLanguageCO->clear(); // store the lang identifiers for later - std::vector const langs = frontend::getLanguageData(false); - 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)); @@ -1443,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(); @@ -1459,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); @@ -1487,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())); } @@ -1589,21 +1630,19 @@ PrefUserInterface::PrefUserInterface(GuiPreferences * form, QWidget * parent) TextLabel1, SLOT(setEnabled(bool))); connect(uiFilePB, SIGNAL(clicked()), this, SLOT(select_ui())); - connect(uiFileED, 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())); @@ -1611,6 +1650,8 @@ PrefUserInterface::PrefUserInterface(GuiPreferences * 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); } @@ -1620,18 +1661,18 @@ void PrefUserInterface::apply(LyXRC & rc) const rc.ui_file = internal_path(fromqstr(uiFileED->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(); } @@ -1640,14 +1681,10 @@ void PrefUserInterface::update(LyXRC const & rc) uiFileED->setText(toqstr(external_path(rc.ui_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) @@ -1655,6 +1692,7 @@ void PrefUserInterface::update(LyXRC const & rc) autoSaveSB->setValue(mins); autoSaveCB->setChecked(rc.make_backup); lastfilesSB->setValue(rc.num_lastfiles); + tooltipCB->setChecked(rc.use_tooltip); } @@ -1668,21 +1706,20 @@ void PrefUserInterface::select_ui() } -void PrefUserInterface::on_loadWindowSizeCB_toggled(bool loadwindowsize) -{ - windowWidthLA->setDisabled(loadwindowsize); - windowHeightLA->setDisabled(loadwindowsize); - windowWidthSB->setDisabled(loadwindowsize); - windowHeightSB->setDisabled(loadwindowsize); -} - - ///////////////////////////////////////////////////////////////////// // // PrefShortcuts // ///////////////////////////////////////////////////////////////////// + +GuiShortcutDialog::GuiShortcutDialog(QWidget * parent) : QDialog(parent) +{ + Ui::shortcutUi::setupUi(this); + QDialog::setModal(true); +} + + PrefShortcuts::PrefShortcuts(GuiPreferences * form, QWidget * parent) : PrefModule(_("Shortcuts"), form, parent) { @@ -1692,94 +1729,236 @@ PrefShortcuts::PrefShortcuts(GuiPreferences * form, QWidget * parent) 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(const QString &)), + 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(); - QTreeWidgetItem * editItem = new QTreeWidgetItem(shortcutsTW); - editItem->setText(0, toqstr("Cursor, Mouse and Editing functions")); + editItem_ = new QTreeWidgetItem(shortcutsTW); + editItem_->setText(0, toqstr("Cursor, Mouse and Editing functions")); + editItem_->setFlags(editItem_->flags() & ~Qt::ItemIsSelectable); - // first insert a few categories - QTreeWidgetItem * mathItem = new QTreeWidgetItem(shortcutsTW); - mathItem->setText(0, toqstr("Mathematical Symbols")); + mathItem_ = new QTreeWidgetItem(shortcutsTW); + mathItem_->setText(0, toqstr("Mathematical Symbols")); + mathItem_->setFlags(mathItem_->flags() & ~Qt::ItemIsSelectable); - QTreeWidgetItem * bufferItem = new QTreeWidgetItem(shortcutsTW); - bufferItem->setText(0, toqstr("Buffer and Window")); + bufferItem_ = new QTreeWidgetItem(shortcutsTW); + bufferItem_->setText(0, toqstr("Buffer and Window")); + bufferItem_->setFlags(bufferItem_->flags() & ~Qt::ItemIsSelectable); - QTreeWidgetItem * layoutItem = new QTreeWidgetItem(shortcutsTW); - layoutItem->setText(0, toqstr("Font, Layouts and Textclasses")); + layoutItem_ = new QTreeWidgetItem(shortcutsTW); + layoutItem_->setText(0, toqstr("Font, Layouts and Textclasses")); + layoutItem_->setFlags(layoutItem_->flags() & ~Qt::ItemIsSelectable); - QTreeWidgetItem * systemItem = new QTreeWidgetItem(shortcutsTW); - systemItem->setText(0, toqstr("System and Miscellaneous")); + 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 - KeyMap::BindingList const bindinglist = theTopLevelKeymap().listBindings(true); + // 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) { - kb_action action = it->first.action; - string const action_name = lyxaction.getActionName(action); - QString const lfun = toqstr(from_utf8(action_name) - + " " + it->first.argument()); - QString const shortcut = toqstr(it->second.print(false)); - - QTreeWidgetItem * newItem = NULL; - // if an item with the same lfun already exists, insert as a - // child item to that item. - // WARNING: this can be slow. - QList items = shortcutsTW->findItems(lfun, + 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); - if (!items.empty()) - newItem = new QTreeWidgetItem(items[0]); - else { - switch(lyxaction.getActionType(action)) { - case LyXAction::Hidden: - continue; - 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); + for (int i = 0; i < items.size(); ++i) { + if (items[i]->text(1) == shortcut) + newItem = items[i]; break; - case LyXAction::System: - newItem = new QTreeWidgetItem(systemItem); - break; - default: - // this should not happen - newItem = new QTreeWidgetItem(shortcutsTW); } + // 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); - newItem->setText(1, shortcut); - // FIXME: TreeItem can not be user-checkable? - newItem->setFlags(newItem->flags() | Qt::ItemIsEditable - | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable); + 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(); } - shortcutsTW->sortItems(0, Qt::AscendingOrder); } @@ -1788,19 +1967,162 @@ void PrefShortcuts::select_bind() docstring const name = from_utf8(internal_path(fromqstr(bindFileED->text()))); docstring file = form_->browsebind(name); - if (!file.empty()) + 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 PrefShortcuts::shortcut_clearPB_pressed() +{ + shortcut_->shortcutLE->reset(); + shortcut_->shortcutLE->setFocus(); +} + + +///////////////////////////////////////////////////////////////////// +// +// PrefIdentity +// +///////////////////////////////////////////////////////////////////// + PrefIdentity::PrefIdentity(QWidget * 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())); } @@ -1826,11 +2148,10 @@ void PrefIdentity::update(LyXRC const & rc) // ///////////////////////////////////////////////////////////////////// -GuiPreferences::GuiPreferences(LyXView & lv) - : GuiDialog(lv, "prefs"), update_screen_font_(false) +GuiPreferences::GuiPreferences(GuiView & lv) + : GuiDialog(lv, "prefs", qt_("Preferences")), update_screen_font_(false) { setupUi(this); - setViewTitle(_("Preferences")); QDialog::setModal(false); @@ -1844,7 +2165,7 @@ GuiPreferences::GuiPreferences(LyXView & lv) add(new PrefScreenFonts(this)); add(new PrefColors(this)); add(new PrefDisplay); - add(new PrefKeyboard(this)); + add(new PrefInput(this)); add(new PrefPaths(this)); @@ -1889,13 +2210,6 @@ void GuiPreferences::add(PrefModule * module) } -void GuiPreferences::closeEvent(QCloseEvent * e) -{ - slotClose(); - e->accept(); -} - - void GuiPreferences::change_adaptor() { changed(); @@ -1930,7 +2244,7 @@ void GuiPreferences::updateContents() } -bool GuiPreferences::initialiseParams(std::string const &) +bool GuiPreferences::initialiseParams(string const &) { rc_ = lyxrc; formats_ = lyx::formats; @@ -1978,7 +2292,7 @@ void GuiPreferences::dispatchParams() } -void GuiPreferences::setColor(Color_color col, string const & hex) +void GuiPreferences::setColor(ColorCode col, string const & hex) { colors_.push_back(lcolor.getLyXName(col) + ' ' + hex); } @@ -2095,7 +2409,7 @@ int GuiPreferences::fromPaperSize(PAPER_SIZE papersize) const } -Dialog * createGuiPreferences(LyXView & lv) { return new GuiPreferences(lv); } +Dialog * createGuiPreferences(GuiView & lv) { return new GuiPreferences(lv); } } // namespace frontend