#include "support/debug.h"
#include "support/FileName.h"
#include "support/filetools.h"
-#include "support/foreach.h"
#include "support/gettext.h"
#include "support/lassert.h"
#include "support/lstrings.h"
dviCB->addItem("synctex view -i $$n:0:$$t -o $$o -x \"evince -i %{page+1} $$o\"");
pdfCB->addItem("");
pdfCB->addItem("CMCDDE SUMATRA control [ForwardSearch(\\\"$$o\\\",\\\"$$t\\\",$$n,0,0,1)]");
- pdfCB->addItem("SumatraPDF -reuse-instance $$o -forward-search $$t $$n");
+ pdfCB->addItem("SumatraPDF -reuse-instance \"$$o\" -forward-search \"$$t\" $$n");
pdfCB->addItem("synctex view -i $$n:0:$$t -o $$o -x \"xpdf -raise -remote $$t.tmp $$o %{page+1}\"");
pdfCB->addItem("okular --unique \"$$o#src:$$n $$f\"");
pdfCB->addItem("qpdfview --unique \"$$o#src:$$f:$$n:0\"");
{
latexBibtexCO->clear();
+ latexBibtexCO->addItem(qt_("Automatic"), "automatic");
latexBibtexCO->addItem(qt_("Custom"), QString());
for (LyXRC::CommandSet::const_iterator it = rc.bibtex_alternatives.begin();
it != rc.bibtex_alternatives.end(); ++it) {
/////////////////////////////////////////////////////////////////////
-namespace {
-
-struct ColorSorter
-{
- bool operator()(ColorCode lhs, ColorCode rhs) const {
- return
- compare_no_case(lcolor.getGUIName(lhs), lcolor.getGUIName(rhs)) < 0;
- }
-};
-
-} // namespace anon
-
-
PrefColors::PrefColors(GuiPreferences * form)
: PrefModule(catLookAndFeel, N_("Colors"), form)
{
continue;
lcolors_.push_back(lc);
}
- sort(lcolors_.begin(), lcolors_.end(), ColorSorter());
+ qSort(lcolors_.begin(), lcolors_.end(), ColorSorter);
vector<ColorCode>::const_iterator cit = lcolors_.begin();
vector<ColorCode>::const_iterator const end = lcolors_.end();
for (; cit != end; ++cit) {
rc.preview = LyXRC::PREVIEW_OFF;
break;
case 1:
- rc.preview = LyXRC::PREVIEW_NO_MATH;
+ if (rc.preview != LyXRC::PREVIEW_NO_MATH) {
+ rc.preview = LyXRC::PREVIEW_NO_MATH;
+ form_->updatePreviews();
+ }
break;
case 2:
- rc.preview = LyXRC::PREVIEW_ON;
+ if (rc.preview != LyXRC::PREVIEW_ON) {
+ rc.preview = LyXRC::PREVIEW_ON;
+ form_->updatePreviews();
+ }
break;
}
this, SIGNAL(changed()));
connect(maxAgeLE, SIGNAL(textEdited(QString)),
this, SIGNAL(changed()));
+ connect(needauthForbiddenCB, SIGNAL(toggled(bool)),
+ this, SIGNAL(changed()));
+ connect(needauthCB, SIGNAL(toggled(bool)),
+ this, SIGNAL(changed()));
converterED->setValidator(new NoNewLineValidator(converterED));
converterFlagED->setValidator(new NoNewLineValidator(converterFlagED));
void PrefConverters::applyRC(LyXRC & rc) const
{
rc.use_converter_cache = cacheCB->isChecked();
+ rc.use_converter_needauth_forbidden = needauthForbiddenCB->isChecked();
+ rc.use_converter_needauth = needauthCB->isChecked();
rc.converter_cache_maxage = int(widgetToDouble(maxAgeLE) * 86400.0);
}
void PrefConverters::updateRC(LyXRC const & rc)
{
cacheCB->setChecked(rc.use_converter_cache);
+ needauthForbiddenCB->setChecked(rc.use_converter_needauth_forbidden);
+ needauthCB->setChecked(rc.use_converter_needauth);
QString max_age;
doubleToWidget(maxAgeLE, (double(rc.converter_cache_maxage) / 86400.0), 'g', 6);
updateGui();
void PrefConverters::updateGui()
{
+ QString const pattern("%1 -> %2");
form_->formats().sort();
form_->converters().update(form_->formats());
// save current selection
- QString current = converterFromCO->currentText()
- + " -> " + converterToCO->currentText();
+ QString current =
+ pattern
+ .arg(converterFromCO->currentText())
+ .arg(converterToCO->currentText());
converterFromCO->clear();
converterToCO->clear();
- Formats::const_iterator cit = form_->formats().begin();
- Formats::const_iterator end = form_->formats().end();
- for (; cit != end; ++cit) {
- converterFromCO->addItem(qt_(cit->prettyname()));
- converterToCO->addItem(qt_(cit->prettyname()));
+ for (Format const & f : form_->formats()) {
+ QString const name = toqstr(translateIfPossible(f.prettyname()));
+ converterFromCO->addItem(name);
+ converterToCO->addItem(name);
}
// currentRowChanged(int) is also triggered when updating the listwidget
convertersLW->blockSignals(true);
convertersLW->clear();
- Converters::const_iterator ccit = form_->converters().begin();
- Converters::const_iterator cend = form_->converters().end();
- for (; ccit != cend; ++ccit) {
+ for (Converter const & c : form_->converters()) {
QString const name =
- qt_(ccit->From()->prettyname()) + " -> " + qt_(ccit->To()->prettyname());
- int type = form_->converters().getNumber(ccit->From()->name(), ccit->To()->name());
+ pattern
+ .arg(toqstr(translateIfPossible(c.From()->prettyname())))
+ .arg(toqstr(translateIfPossible(c.To()->prettyname())));
+ int type = form_->converters().getNumber(c.From()->name(),
+ c.To()->name());
new QListWidgetItem(name, convertersLW, type);
}
convertersLW->sortItems(Qt::AscendingOrder);
convertersLW->blockSignals(false);
// restore selection
- if (!current.isEmpty()) {
+ if (current != pattern.arg(QString()).arg(QString())) {
QList<QListWidgetItem *> const item =
convertersLW->findItems(current, Qt::MatchExactly);
if (!item.isEmpty())
}
+void PrefConverters::on_needauthForbiddenCB_toggled(bool checked)
+{
+ needauthCB->setEnabled(!checked);
+}
+
+
/////////////////////////////////////////////////////////////////////
//
// FormatValidator
private:
QString toString(Format const & format) const
{
- return qt_(format.prettyname());
+ return toqstr(translateIfPossible(format.prettyname()));
}
};
namespace {
-string const l10n_shortcut(string const & prettyname, string const & shortcut)
+string const l10n_shortcut(docstring const & prettyname, string const & shortcut)
{
if (shortcut.empty())
return string();
string l10n_format =
- to_utf8(_(prettyname + '|' + shortcut));
+ to_utf8(_(to_utf8(prettyname) + '|' + shortcut));
return split(l10n_format, '|');
}
defaultFormatCB->clear();
defaultOTFFormatCB->clear();
form_->formats().sort();
- Formats::const_iterator cit = form_->formats().begin();
- Formats::const_iterator end = form_->formats().end();
- for (; cit != end; ++cit) {
- formatsCB->addItem(qt_(cit->prettyname()),
- QVariant(form_->formats().getNumber(cit->name())));
- if (cit->viewer().empty())
+ for (Format const & f : form_->formats()) {
+ QString const prettyname = toqstr(translateIfPossible(f.prettyname()));
+ formatsCB->addItem(prettyname,
+ QVariant(form_->formats().getNumber(f.name())));
+ if (f.viewer().empty())
continue;
- if (form_->converters().isReachable("xhtml", cit->name())
- || form_->converters().isReachable("dviluatex", cit->name())
- || form_->converters().isReachable("luatex", cit->name())
- || form_->converters().isReachable("xetex", cit->name())) {
- defaultFormatCB->addItem(qt_(cit->prettyname()),
- QVariant(toqstr(cit->name())));
- defaultOTFFormatCB->addItem(qt_(cit->prettyname()),
- QVariant(toqstr(cit->name())));
- } else if (form_->converters().isReachable("latex", cit->name())
- || form_->converters().isReachable("pdflatex", cit->name()))
- defaultFormatCB->addItem(qt_(cit->prettyname()),
- QVariant(toqstr(cit->name())));
+ if (form_->converters().isReachable("xhtml", f.name())
+ || form_->converters().isReachable("dviluatex", f.name())
+ || form_->converters().isReachable("luatex", f.name())
+ || form_->converters().isReachable("xetex", f.name())) {
+ defaultFormatCB->addItem(prettyname,
+ QVariant(toqstr(f.name())));
+ defaultOTFFormatCB->addItem(prettyname,
+ QVariant(toqstr(f.name())));
+ } else if (form_->converters().isReachable("latex", f.name())
+ || form_->converters().isReachable("pdflatex", f.name()))
+ defaultFormatCB->addItem(prettyname,
+ QVariant(toqstr(f.name())));
}
// restore selections
void PrefFileformats::updatePrettyname()
{
QString const newname = formatsCB->currentText();
- if (newname == qt_(currentFormat().prettyname()))
+ if (newname == toqstr(translateIfPossible(currentFormat().prettyname())))
return;
- currentFormat().setPrettyname(fromqstr(newname));
+ currentFormat().setPrettyname(qstring_to_ucs4(newname));
formatsChanged();
updateView();
changed();
void PrefFileformats::on_formatNewPB_clicked()
{
- form_->formats().add("", "", "", "", "", "", "", Format::none);
+ form_->formats().add("", "", docstring(), "", "", "", "", Format::none);
updateView();
formatsCB->setCurrentIndex(0);
formatsCB->setFocus(Qt::OtherFocusReason);
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, KeyMap::ItemType(it->tag));
+ insertShortcutItem(it->request, it->sequence, it->tag);
shortcutsTW->sortItems(0, Qt::AscendingOrder);
- QList<QTreeWidgetItem*> items = shortcutsTW->selectedItems();
- removePB->setEnabled(!items.isEmpty() && !items[0]->text(1).isEmpty());
- modifyPB->setEnabled(!items.isEmpty());
-
+ on_shortcutsTW_itemSelectionChanged();
+ on_searchLE_textEdited();
shortcutsTW->resizeColumnToContents(0);
}
+//static
+KeyMap::ItemType PrefShortcuts::itemType(QTreeWidgetItem & item)
+{
+ return static_cast<KeyMap::ItemType>(item.data(0, Qt::UserRole).toInt());
+}
+
+
+//static
+bool PrefShortcuts::isAlwaysHidden(QTreeWidgetItem & item)
+{
+ // Hide rebound system settings that are empty
+ return itemType(item) == KeyMap::UserUnbind && item.text(1).isEmpty();
+}
+
+
void PrefShortcuts::setItemType(QTreeWidgetItem * item, KeyMap::ItemType tag)
{
item->setData(0, Qt::UserRole, QVariant(tag));
font.setStrikeOut(true);
break;
}
-
+ item->setHidden(isAlwaysHidden(*item));
item->setFont(1, font);
}
if (items.isEmpty())
return;
- KeyMap::ItemType tag =
- static_cast<KeyMap::ItemType>(items[0]->data(0, Qt::UserRole).toInt());
- if (tag == KeyMap::UserUnbind)
+ if (itemType(*items[0]) == KeyMap::UserUnbind)
removePB->setText(qt_("Res&tore"));
else
removePB->setText(qt_("Remo&ve"));
}
+void PrefShortcuts::unhideEmpty(QString const & lfun, bool select)
+{
+ // list of items that match lfun
+ QList<QTreeWidgetItem*> items = shortcutsTW->findItems(lfun,
+ Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 0);
+ for (int i = 0; i < items.size(); ++i) {
+ QTreeWidgetItem * item = items[i];
+ if (isAlwaysHidden(*item)) {
+ setItemType(item, KeyMap::System);
+ if (select)
+ shortcutsTW->setCurrentItem(item);
+ return;
+ }
+ }
+}
+
+
void PrefShortcuts::removeShortcut()
{
// it seems that only one item can be selected, but I am
string shortcut = fromqstr(items[i]->data(1, Qt::UserRole).toString());
string lfun = fromqstr(items[i]->text(0));
FuncRequest func = lyxaction.lookupFunc(lfun);
- KeyMap::ItemType tag =
- static_cast<KeyMap::ItemType>(items[i]->data(0, Qt::UserRole).toInt());
- switch (tag) {
+ switch (itemType(*items[i])) {
case KeyMap::System: {
// for system bind, we do not touch the item
// but add an user unbind item
else
shortcutsTW->scrollToItem(parent);
user_bind_.unbind(shortcut, func);
+ // If this user binding hid an empty system binding, unhide the
+ // latter and select it.
+ unhideEmpty(items[i]->text(0), true);
break;
}
case KeyMap::UserUnbind: {
// for user_unbind, we remove the unbind, and the item
// become KeyMap::System again.
+ KeySequence seq;
+ seq.parse(shortcut);
+ // Ask the user to replace current binding
+ if (!validateNewShortcut(func, seq, QString()))
+ break;
user_unbind_.unbind(shortcut, func);
setItemType(items[i], KeyMap::System);
removePB->setText(qt_("Remo&ve"));
}
+void PrefShortcuts::deactivateShortcuts(QList<QTreeWidgetItem*> const & items)
+{
+ 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);
+
+ switch (itemType(*items[i])) {
+ case KeyMap::System:
+ // for system bind, we do not touch the item
+ // but add an user unbind item
+ user_unbind_.bind(shortcut, func);
+ setItemType(items[i], KeyMap::UserUnbind);
+ break;
+
+ case KeyMap::UserBind: {
+ // for user_bind, we remove this bind
+ QTreeWidgetItem * parent = items[i]->parent();
+ int itemIdx = parent->indexOfChild(items[i]);
+ parent->takeChild(itemIdx);
+ user_bind_.unbind(shortcut, func);
+ unhideEmpty(items[i]->text(0), false);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+
void PrefShortcuts::selectBind()
{
QString file = form_->browsebind(internalPath(bindFileED->text()));
if (searchLE->text().isEmpty()) {
// show all hidden items
QTreeWidgetItemIterator it(shortcutsTW, QTreeWidgetItemIterator::Hidden);
- while (*it)
- shortcutsTW->setItemHidden(*it++, false);
+ for (; *it; ++it)
+ shortcutsTW->setItemHidden(*it, isAlwaysHidden(**it));
+ // close all categories
+ for (int i = 0; i < shortcutsTW->topLevelItemCount(); ++i)
+ shortcutsTW->collapseItem(shortcutsTW->topLevelItem(i));
return;
}
// search both columns
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);
- }
+ for (int i = 0; i < matched.size(); ++i)
+ if (!isAlwaysHidden(*matched[i])) {
+ shortcutsTW->setItemHidden(matched[i], false);
+ shortcutsTW->setItemExpanded(matched[i]->parent(), true);
+ }
}
}
-void PrefShortcuts::shortcutOkPressed()
+FuncRequest PrefShortcuts::currentBinding(KeySequence const & k)
{
- QString const new_lfun = shortcut_->lfunLE->text();
- FuncRequest func = lyxaction.lookupFunc(fromqstr(new_lfun));
+ FuncRequest res = user_bind_.getBinding(k);
+ if (res.action() != LFUN_UNKNOWN_ACTION)
+ return res;
+ res = system_bind_.getBinding(k);
+ // Check if it is unbound. Note: user_unbind_ can only unbind one
+ // FuncRequest per key sequence.
+ if (user_unbind_.getBinding(k) == res)
+ return FuncRequest::unknown;
+ return res;
+}
+
+bool PrefShortcuts::validateNewShortcut(FuncRequest const & func,
+ KeySequence const & k,
+ QString const & lfun_to_modify)
+{
if (func.action() == LFUN_UNKNOWN_ACTION) {
Alert::error(_("Failed to create shortcut"),
_("Unknown or invalid LyX function"));
- return;
+ return false;
+ }
+
+ // It is not currently possible to bind Hidden lfuns such as self-insert. In
+ // the future, to remove this limitation, see GuiPrefs::insertShortcutItem
+ // and how it is used in GuiPrefs::shortcutOkPressed.
+ if (lyxaction.getActionType(func.action()) == LyXAction::Hidden) {
+ Alert::error(_("Failed to create shortcut"),
+ _("This LyX function is hidden and cannot be bound."));
+ return false;
}
- KeySequence k = shortcut_->shortcutWG->getKeySequence();
if (k.length() == 0) {
Alert::error(_("Failed to create shortcut"),
_("Invalid or empty key sequence"));
- return;
+ return false;
}
- // check to see if there's been any change
- FuncRequest oldBinding = system_bind_.getBinding(k);
- if (oldBinding.action() == LFUN_UNKNOWN_ACTION)
- oldBinding = user_bind_.getBinding(k);
+ FuncRequest oldBinding = currentBinding(k);
if (oldBinding == func)
- // nothing has changed
- return;
+ // nothing to change
+ return false;
// make sure this key isn't already bound---and, if so, prompt user
- FuncCode const unbind = user_unbind_.getBinding(k).action();
+ // (exclude the lfun the user already wants to modify)
docstring const action_string = makeCmdString(oldBinding);
- if (oldBinding.action() > LFUN_NOACTION && unbind == LFUN_UNKNOWN_ACTION
- && save_lfun_ != toqstr(action_string)) {
+ if (oldBinding.action() != LFUN_UNKNOWN_ACTION
+ && lfun_to_modify != toqstr(action_string)) {
docstring const new_action_string = makeCmdString(func);
docstring const text = bformat(_("Shortcut `%1$s' is already bound to "
"%2$s.\n"
int ret = Alert::prompt(_("Redefine shortcut?"),
text, 0, 1, _("&Redefine"), _("&Cancel"));
if (ret != 0)
- return;
+ return false;
QString const sequence_text = toqstr(k.print(KeySequence::ForGui));
QList<QTreeWidgetItem*> items = shortcutsTW->findItems(sequence_text,
Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 1);
- if (items.size() > 0) {
- // should always happen
- bool expanded = items[0]->parent()->isExpanded();
- shortcutsTW->setCurrentItem(items[0]);
- removeShortcut();
- shortcutsTW->setCurrentItem(0);
- // make sure user doesn't see tree expansion if
- // old binding wasn't in an expanded tree
- if (!expanded)
- items[0]->parent()->setExpanded(false);
- }
+ deactivateShortcuts(items);
}
+ return true;
+}
- shortcut_->accept();
- if (!save_lfun_.isEmpty())
+void PrefShortcuts::shortcutOkPressed()
+{
+ QString const new_lfun = shortcut_->lfunLE->text();
+ FuncRequest func = lyxaction.lookupFunc(fromqstr(new_lfun));
+ KeySequence k = shortcut_->shortcutWG->getKeySequence();
+
+ // save_lfun_ contains the text of the lfun to modify, if the user clicked
+ // "modify", or is empty if they clicked "new" (which I do not really like)
+ if (!validateNewShortcut(func, k, save_lfun_))
+ return;
+
+ if (!save_lfun_.isEmpty()) {
// real modification of the lfun's shortcut,
// so remove the previous one
- removeShortcut();
+ QList<QTreeWidgetItem*> to_modify = shortcutsTW->selectedItems();
+ deactivateShortcuts(to_modify);
+ }
+
+ shortcut_->accept();
QTreeWidgetItem * item = insertShortcutItem(func, k, KeyMap::UserBind);
if (item) {
user_bind_.bind(&k, func);
shortcutsTW->sortItems(0, Qt::AscendingOrder);
shortcutsTW->setItemExpanded(item->parent(), true);
+ shortcutsTW->setCurrentItem(item);
shortcutsTW->scrollToItem(item);
} else {
Alert::error(_("Failed to create shortcut"),
/////////////////////////////////////////////////////////////////////
GuiPreferences::GuiPreferences(GuiView & lv)
- : GuiDialog(lv, "prefs", qt_("Preferences")), update_screen_font_(false)
+ : GuiDialog(lv, "prefs", qt_("Preferences")), update_screen_font_(false),
+ update_previews_(false)
{
setupUi(this);
movers_ = theMovers();
colors_.clear();
update_screen_font_ = false;
+ update_previews_ = false;
updateRC(rc_);
// Make sure that the bc is in the INITIAL state
theConverters() = converters_;
theConverters().update(lyx::formats);
theConverters().buildGraph();
-
+ theBufferList().invalidateConverterCache();
+
theMovers() = movers_;
vector<string>::const_iterator it = colors_.begin();
if (update_screen_font_) {
dispatch(FuncRequest(LFUN_SCREEN_FONT_UPDATE));
+ // resets flag in case second apply in same dialog
update_screen_font_ = false;
}
- theBufferList().updatePreviews();
+ if (update_previews_) {
+ // resets flag in case second apply in same dialog
+ theBufferList().updatePreviews();
+ update_previews_ = false;
+ }
// The Save button has been pressed
if (isClosing())
}
+void GuiPreferences::updatePreviews()
+{
+ update_previews_ = true;
+}
+
+
QString GuiPreferences::browsebind(QString const & file) const
{
return browseLibFile("bind", file, "bind", qt_("Choose bind file"),