3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
9 * Full author contact details are available in file CREDITS.
16 #include "ColorCache.h"
17 #include "FileDialog.h"
18 #include "GuiApplication.h"
19 #include "GuiFontExample.h"
20 #include "GuiFontLoader.h"
21 #include "GuiKeySymbol.h"
22 #include "qt_helpers.h"
23 #include "Validator.h"
26 #include "BufferList.h"
29 #include "ConverterCache.h"
30 #include "FontEnums.h"
31 #include "FuncRequest.h"
33 #include "KeySequence.h"
35 #include "LyXAction.h"
37 #include "PanelStack.h"
39 #include "SpellChecker.h"
41 #include "support/debug.h"
42 #include "support/FileName.h"
43 #include "support/filetools.h"
44 #include "support/gettext.h"
45 #include "support/lassert.h"
46 #include "support/lstrings.h"
47 #include "support/Messages.h"
48 #include "support/os.h"
49 #include "support/Package.h"
51 #include "graphics/GraphicsTypes.h"
53 #include "frontends/alert.h"
54 #include "frontends/Application.h"
55 #include "frontends/FontLoader.h"
57 #include <QAbstractItemModel>
59 #include <QColorDialog>
60 #include <QFontDatabase>
61 #include <QHeaderView>
63 #include <QMessageBox>
64 #include <QPushButton>
67 #include <QTreeWidget>
68 #include <QTreeWidgetItem>
79 using namespace lyx::support;
80 using namespace lyx::support::os;
85 /////////////////////////////////////////////////////////////////////
89 /////////////////////////////////////////////////////////////////////
91 /** Launch a file dialog and return the chosen file.
92 filename: a suggested filename.
93 title: the title of the dialog.
95 dir1 = (name, dir), dir2 = (name, dir): extra buttons on the dialog.
97 QString browseFile(QString const & filename,
98 QString const & title,
99 QStringList const & filters,
101 QString const & label1 = QString(),
102 QString const & dir1 = QString(),
103 QString const & label2 = QString(),
104 QString const & dir2 = QString(),
105 QString const & fallback_dir = QString())
107 QString lastPath = ".";
108 if (!filename.isEmpty())
109 lastPath = onlyPath(filename);
110 else if(!fallback_dir.isEmpty())
111 lastPath = fallback_dir;
113 FileDialog dlg(title);
114 dlg.setButton1(label1, dir1);
115 dlg.setButton2(label2, dir2);
117 FileDialog::Result result;
120 result = dlg.save(lastPath, filters, onlyFileName(filename));
122 result = dlg.open(lastPath, filters, onlyFileName(filename));
124 return result.second;
128 /** Wrapper around browseFile which tries to provide a filename
129 * relative to the user or system directory. The dir, name and ext
130 * parameters have the same meaning as in the
131 * support::LibFileSearch function.
133 QString browseLibFile(QString const & dir,
134 QString const & name,
136 QString const & title,
137 QStringList const & filters)
140 QString const label1 = qt_("&System files");
142 toqstr(addName(package().system_support().absFileName(), fromqstr(dir)));
144 QString const label2 = qt_("&User files");
146 toqstr(addName(package().user_support().absFileName(), fromqstr(dir)));
148 QString const result = browseFile(toqstr(
149 libFileSearch(dir, name, ext).absFileName()),
150 title, filters, false, dir1, dir2, QString(), QString(), dir1);
152 // remove the extension if it is the default one
154 if (getExtension(result) == ext)
155 noextresult = removeExtension(result);
157 noextresult = result;
159 // remove the directory, if it is the default one
160 QString const file = onlyFileName(noextresult);
161 if (toqstr(libFileSearch(dir, file, ext).absFileName()) == result)
168 /** Launch a file dialog and return the chosen directory.
169 pathname: a suggested pathname.
170 title: the title of the dialog.
171 dir1 = (name, dir), dir2 = (name, dir): extra buttons on the dialog.
173 QString browseDir(QString const & pathname,
174 QString const & title,
175 QString const & label1 = QString(),
176 QString const & dir1 = QString(),
177 QString const & label2 = QString(),
178 QString const & dir2 = QString())
180 QString lastPath = ".";
181 if (!pathname.isEmpty())
182 lastPath = onlyPath(pathname);
184 FileDialog dlg(title);
185 dlg.setButton1(label1, dir1);
186 dlg.setButton2(label2, dir2);
188 FileDialog::Result const result =
189 dlg.opendir(lastPath, onlyFileName(pathname));
191 return result.second;
195 } // namespace frontend
198 QString browseRelToParent(QString const & filename, QString const & relpath,
199 QString const & title, QStringList const & filters, bool save,
200 QString const & label1, QString const & dir1,
201 QString const & label2, QString const & dir2)
203 QString const fname = makeAbsPath(filename, relpath);
205 QString const outname =
206 frontend::browseFile(fname, title, filters, save, label1, dir1, label2, dir2);
208 QString const reloutname =
209 toqstr(makeRelPath(qstring_to_ucs4(outname), qstring_to_ucs4(relpath)));
211 if (reloutname.startsWith("../"))
218 QString browseRelToSub(QString const & filename, QString const & relpath,
219 QString const & title, QStringList const & filters, bool save,
220 QString const & label1, QString const & dir1,
221 QString const & label2, QString const & dir2)
223 QString const fname = makeAbsPath(filename, relpath);
225 QString const outname =
226 frontend::browseFile(fname, title, filters, save, label1, dir1, label2, dir2);
228 QString const reloutname =
229 toqstr(makeRelPath(qstring_to_ucs4(outname), qstring_to_ucs4(relpath)));
231 QString testname = reloutname;
232 testname.remove(QRegExp("^(\\.\\./)+"));
234 if (testname.contains("/"))
242 /////////////////////////////////////////////////////////////////////
246 /////////////////////////////////////////////////////////////////////
250 QString const catLookAndFeel = N_("Look & Feel");
251 QString const catEditing = N_("Editing");
252 QString const catLanguage = N_("Language Settings");
253 QString const catOutput = N_("Output");
254 QString const catFiles = N_("File Handling");
256 static void parseFontName(QString const & mangled0,
257 string & name, string & foundry)
259 string mangled = fromqstr(mangled0);
260 size_t const idx = mangled.find('[');
261 if (idx == string::npos || idx == 0) {
265 name = mangled.substr(0, idx - 1),
266 foundry = mangled.substr(idx + 1, mangled.size() - idx - 2);
271 static void setComboxFont(QComboBox * cb, string const & family,
272 string const & foundry)
274 QString fontname = toqstr(family);
275 if (!foundry.empty())
276 fontname += " [" + toqstr(foundry) + ']';
278 for (int i = 0; i != cb->count(); ++i) {
279 if (cb->itemText(i) == fontname) {
280 cb->setCurrentIndex(i);
285 // Try matching without foundry name
287 // We count in reverse in order to prefer the Xft foundry
288 for (int i = cb->count(); --i >= 0;) {
289 string name, fnt_foundry;
290 parseFontName(cb->itemText(i), name, fnt_foundry);
291 if (compare_ascii_no_case(name, family) == 0) {
292 cb->setCurrentIndex(i);
297 // family alone can contain e.g. "Helvetica [Adobe]"
298 string tmpname, tmpfoundry;
299 parseFontName(toqstr(family), tmpname, tmpfoundry);
301 // We count in reverse in order to prefer the Xft foundry
302 for (int i = cb->count(); --i >= 0; ) {
303 string name, fnt_foundry;
304 parseFontName(cb->itemText(i), name, fnt_foundry);
305 if (compare_ascii_no_case(name, fnt_foundry) == 0) {
306 cb->setCurrentIndex(i);
311 // Bleh, default fonts, and the names couldn't be found. Hack
316 QString const font_family = toqstr(family);
317 if (font_family == guiApp->romanFontName()) {
318 font.setStyleHint(QFont::Serif);
319 font.setFamily(font_family);
320 } else if (font_family == guiApp->sansFontName()) {
321 font.setStyleHint(QFont::SansSerif);
322 font.setFamily(font_family);
323 } else if (font_family == guiApp->typewriterFontName()) {
324 font.setStyleHint(QFont::TypeWriter);
325 font.setFamily(font_family);
327 LYXERR0("FAILED to find the default font: '"
328 << foundry << "', '" << family << '\'');
332 QFontInfo info(font);
333 string default_font_name, dummyfoundry;
334 parseFontName(info.family(), default_font_name, dummyfoundry);
335 LYXERR0("Apparent font is " << default_font_name);
337 for (int i = 0; i < cb->count(); ++i) {
338 LYXERR0("Looking at " << cb->itemText(i));
339 if (compare_ascii_no_case(fromqstr(cb->itemText(i)),
340 default_font_name) == 0) {
341 cb->setCurrentIndex(i);
346 LYXERR0("FAILED to find the font: '"
347 << foundry << "', '" << family << '\'');
351 /////////////////////////////////////////////////////////////////////
355 /////////////////////////////////////////////////////////////////////
357 PrefOutput::PrefOutput(GuiPreferences * form)
358 : PrefModule(catOutput, N_("General"), form)
362 dviCB->setValidator(new NoNewLineValidator(dviCB));
363 pdfCB->setValidator(new NoNewLineValidator(pdfCB));
365 connect(plaintextLinelengthSB, SIGNAL(valueChanged(int)),
366 this, SIGNAL(changed()));
367 connect(overwriteCO, SIGNAL(activated(int)),
368 this, SIGNAL(changed()));
369 connect(dviCB, SIGNAL(editTextChanged(QString)),
370 this, SIGNAL(changed()));
371 connect(pdfCB, SIGNAL(editTextChanged(QString)),
372 this, SIGNAL(changed()));
373 connect(printerPaperTypeED, SIGNAL(textChanged(QString)),
374 this, SIGNAL(changed()));
375 connect(printerLandscapeED, SIGNAL(textChanged(QString)),
376 this, SIGNAL(changed()));
377 connect(printerPaperSizeED, SIGNAL(textChanged(QString)),
378 this, SIGNAL(changed()));
380 printerPaperTypeED->setValidator(new NoNewLineValidator(printerPaperTypeED));
381 printerLandscapeED->setValidator(new NoNewLineValidator(printerLandscapeED));
382 printerPaperSizeED->setValidator(new NoNewLineValidator(printerPaperSizeED));
385 dviCB->addItem("xdvi -sourceposition '$$n:\\ $$t' $$o");
386 dviCB->addItem("yap -1 -s \"$$n $$t\" $$o");
387 dviCB->addItem("okular --unique \"$$o#src:$$n $$f\"");
388 dviCB->addItem("synctex view -i $$n:0:$$t -o $$o -x \"evince -i %{page+1} $$o\"");
390 pdfCB->addItem("CMCDDE SUMATRA control [ForwardSearch(\\\"$$o\\\",\\\"$$t\\\",$$n,0,0,1)]");
391 pdfCB->addItem("SumatraPDF -reuse-instance \"$$o\" -forward-search \"$$t\" $$n");
392 pdfCB->addItem("synctex view -i $$n:0:$$t -o $$o -x \"xpdf -raise -remote $$t.tmp $$o %{page+1}\"");
393 pdfCB->addItem("okular --unique \"$$o#src:$$n $$f\"");
394 pdfCB->addItem("qpdfview --unique \"$$o#src:$$f:$$n:0\"");
395 pdfCB->addItem("synctex view -i $$n:0:$$t -o $$o -x \"evince -i %{page+1} $$o\"");
396 pdfCB->addItem("/Applications/Skim.app/Contents/SharedSupport/displayline $$n $$o $$t");
400 void PrefOutput::applyRC(LyXRC & rc) const
402 rc.plaintext_linelen = plaintextLinelengthSB->value();
403 rc.forward_search_dvi = fromqstr(dviCB->currentText());
404 rc.forward_search_pdf = fromqstr(pdfCB->currentText());
406 switch (overwriteCO->currentIndex()) {
408 rc.export_overwrite = NO_FILES;
411 rc.export_overwrite = MAIN_FILE;
414 rc.export_overwrite = ALL_FILES;
418 rc.print_paper_flag = fromqstr(printerPaperTypeED->text());
419 rc.print_landscape_flag = fromqstr(printerLandscapeED->text());
420 rc.print_paper_dimension_flag = fromqstr(printerPaperSizeED->text());
424 void PrefOutput::updateRC(LyXRC const & rc)
426 plaintextLinelengthSB->setValue(rc.plaintext_linelen);
427 dviCB->setEditText(toqstr(rc.forward_search_dvi));
428 pdfCB->setEditText(toqstr(rc.forward_search_pdf));
430 switch (rc.export_overwrite) {
432 overwriteCO->setCurrentIndex(0);
435 overwriteCO->setCurrentIndex(1);
438 overwriteCO->setCurrentIndex(2);
442 printerPaperTypeED->setText(toqstr(rc.print_paper_flag));
443 printerLandscapeED->setText(toqstr(rc.print_landscape_flag));
444 printerPaperSizeED->setText(toqstr(rc.print_paper_dimension_flag));
448 /////////////////////////////////////////////////////////////////////
452 /////////////////////////////////////////////////////////////////////
454 PrefInput::PrefInput(GuiPreferences * form)
455 : PrefModule(catEditing, N_("Keyboard/Mouse"), form)
459 connect(keymapCB, SIGNAL(clicked()),
460 this, SIGNAL(changed()));
461 connect(firstKeymapED, SIGNAL(textChanged(QString)),
462 this, SIGNAL(changed()));
463 connect(secondKeymapED, SIGNAL(textChanged(QString)),
464 this, SIGNAL(changed()));
465 connect(mouseWheelSpeedSB, SIGNAL(valueChanged(double)),
466 this, SIGNAL(changed()));
467 connect(scrollzoomEnableCB, SIGNAL(clicked()),
468 this, SIGNAL(changed()));
469 connect(scrollzoomValueCO, SIGNAL(activated(int)),
470 this, SIGNAL(changed()));
471 connect(dontswapCB, SIGNAL(toggled(bool)),
472 this, SIGNAL(changed()));
473 connect(mmPasteCB, SIGNAL(toggled(bool)),
474 this, SIGNAL(changed()));
476 // reveal checkbox for switching Ctrl and Meta on Mac:
479 #if QT_VERSION > 0x040600
483 dontswapCB->setVisible(swapcb);
487 void PrefInput::applyRC(LyXRC & rc) const
489 // FIXME: can derive CB from the two EDs
490 rc.use_kbmap = keymapCB->isChecked();
491 rc.primary_kbmap = internal_path(fromqstr(firstKeymapED->text()));
492 rc.secondary_kbmap = internal_path(fromqstr(secondKeymapED->text()));
493 rc.mouse_wheel_speed = mouseWheelSpeedSB->value();
494 if (scrollzoomEnableCB->isChecked()) {
495 switch (scrollzoomValueCO->currentIndex()) {
497 rc.scroll_wheel_zoom = LyXRC::SCROLL_WHEEL_ZOOM_CTRL;
500 rc.scroll_wheel_zoom = LyXRC::SCROLL_WHEEL_ZOOM_SHIFT;
503 rc.scroll_wheel_zoom = LyXRC::SCROLL_WHEEL_ZOOM_ALT;
507 rc.scroll_wheel_zoom = LyXRC::SCROLL_WHEEL_ZOOM_OFF;
509 rc.mac_dontswap_ctrl_meta = dontswapCB->isChecked();
510 rc.mouse_middlebutton_paste = mmPasteCB->isChecked();
514 void PrefInput::updateRC(LyXRC const & rc)
516 // FIXME: can derive CB from the two EDs
517 keymapCB->setChecked(rc.use_kbmap);
518 firstKeymapED->setText(toqstr(external_path(rc.primary_kbmap)));
519 secondKeymapED->setText(toqstr(external_path(rc.secondary_kbmap)));
520 mouseWheelSpeedSB->setValue(rc.mouse_wheel_speed);
521 switch (rc.scroll_wheel_zoom) {
522 case LyXRC::SCROLL_WHEEL_ZOOM_OFF:
523 scrollzoomEnableCB->setChecked(false);
525 case LyXRC::SCROLL_WHEEL_ZOOM_CTRL:
526 scrollzoomEnableCB->setChecked(true);
527 scrollzoomValueCO->setCurrentIndex(0);
529 case LyXRC::SCROLL_WHEEL_ZOOM_SHIFT:
530 scrollzoomEnableCB->setChecked(true);
531 scrollzoomValueCO->setCurrentIndex(1);
533 case LyXRC::SCROLL_WHEEL_ZOOM_ALT:
534 scrollzoomEnableCB->setChecked(true);
535 scrollzoomValueCO->setCurrentIndex(2);
538 dontswapCB->setChecked(rc.mac_dontswap_ctrl_meta);
539 mmPasteCB->setChecked(rc.mouse_middlebutton_paste);
543 QString PrefInput::testKeymap(QString const & keymap)
545 return form_->browsekbmap(internalPath(keymap));
549 void PrefInput::on_firstKeymapPB_clicked(bool)
551 QString const file = testKeymap(firstKeymapED->text());
553 firstKeymapED->setText(file);
557 void PrefInput::on_secondKeymapPB_clicked(bool)
559 QString const file = testKeymap(secondKeymapED->text());
561 secondKeymapED->setText(file);
565 void PrefInput::on_keymapCB_toggled(bool keymap)
567 firstKeymapLA->setEnabled(keymap);
568 secondKeymapLA->setEnabled(keymap);
569 firstKeymapED->setEnabled(keymap);
570 secondKeymapED->setEnabled(keymap);
571 firstKeymapPB->setEnabled(keymap);
572 secondKeymapPB->setEnabled(keymap);
576 void PrefInput::on_scrollzoomEnableCB_toggled(bool enabled)
578 scrollzoomValueCO->setEnabled(enabled);
582 /////////////////////////////////////////////////////////////////////
586 /////////////////////////////////////////////////////////////////////
588 PrefCompletion::PrefCompletion(GuiPreferences * form)
589 : PrefModule(catEditing, N_("Input Completion"), form)
593 connect(inlineDelaySB, SIGNAL(valueChanged(double)),
594 this, SIGNAL(changed()));
595 connect(inlineMathCB, SIGNAL(clicked()),
596 this, SIGNAL(changed()));
597 connect(inlineTextCB, SIGNAL(clicked()),
598 this, SIGNAL(changed()));
599 connect(inlineDotsCB, SIGNAL(clicked()),
600 this, SIGNAL(changed()));
601 connect(popupDelaySB, SIGNAL(valueChanged(double)),
602 this, SIGNAL(changed()));
603 connect(popupMathCB, SIGNAL(clicked()),
604 this, SIGNAL(changed()));
605 connect(autocorrectionCB, SIGNAL(clicked()),
606 this, SIGNAL(changed()));
607 connect(popupTextCB, SIGNAL(clicked()),
608 this, SIGNAL(changed()));
609 connect(popupAfterCompleteCB, SIGNAL(clicked()),
610 this, SIGNAL(changed()));
611 connect(cursorTextCB, SIGNAL(clicked()),
612 this, SIGNAL(changed()));
613 connect(minlengthSB, SIGNAL(valueChanged(int)),
614 this, SIGNAL(changed()));
618 void PrefCompletion::on_inlineTextCB_clicked()
624 void PrefCompletion::on_popupTextCB_clicked()
630 void PrefCompletion::enableCB()
632 cursorTextCB->setEnabled(
633 popupTextCB->isChecked() || inlineTextCB->isChecked());
637 void PrefCompletion::applyRC(LyXRC & rc) const
639 rc.completion_inline_delay = inlineDelaySB->value();
640 rc.completion_inline_math = inlineMathCB->isChecked();
641 rc.completion_inline_text = inlineTextCB->isChecked();
642 rc.completion_inline_dots = inlineDotsCB->isChecked() ? 13 : -1;
643 rc.completion_popup_delay = popupDelaySB->value();
644 rc.completion_popup_math = popupMathCB->isChecked();
645 rc.autocorrection_math = autocorrectionCB->isChecked();
646 rc.completion_popup_text = popupTextCB->isChecked();
647 rc.completion_cursor_text = cursorTextCB->isChecked();
648 rc.completion_popup_after_complete =
649 popupAfterCompleteCB->isChecked();
650 rc.completion_minlength = minlengthSB->value();
654 void PrefCompletion::updateRC(LyXRC const & rc)
656 inlineDelaySB->setValue(rc.completion_inline_delay);
657 inlineMathCB->setChecked(rc.completion_inline_math);
658 inlineTextCB->setChecked(rc.completion_inline_text);
659 inlineDotsCB->setChecked(rc.completion_inline_dots != -1);
660 popupDelaySB->setValue(rc.completion_popup_delay);
661 popupMathCB->setChecked(rc.completion_popup_math);
662 autocorrectionCB->setChecked(rc.autocorrection_math);
663 popupTextCB->setChecked(rc.completion_popup_text);
664 cursorTextCB->setChecked(rc.completion_cursor_text);
665 popupAfterCompleteCB->setChecked(rc.completion_popup_after_complete);
667 minlengthSB->setValue(rc.completion_minlength);
672 /////////////////////////////////////////////////////////////////////
676 /////////////////////////////////////////////////////////////////////
678 PrefLatex::PrefLatex(GuiPreferences * form)
679 : PrefModule(catOutput, N_("LaTeX"), form)
683 latexDviPaperED->setValidator(new NoNewLineValidator(latexDviPaperED));
684 latexBibtexED->setValidator(new NoNewLineValidator(latexBibtexED));
685 latexJBibtexED->setValidator(new NoNewLineValidator(latexJBibtexED));
686 latexIndexED->setValidator(new NoNewLineValidator(latexIndexED));
687 latexJIndexED->setValidator(new NoNewLineValidator(latexJIndexED));
688 latexNomenclED->setValidator(new NoNewLineValidator(latexNomenclED));
689 latexChecktexED->setValidator(new NoNewLineValidator(latexChecktexED));
691 connect(latexChecktexED, SIGNAL(textChanged(QString)),
692 this, SIGNAL(changed()));
693 connect(latexBibtexCO, SIGNAL(activated(int)),
694 this, SIGNAL(changed()));
695 connect(latexBibtexED, SIGNAL(textChanged(QString)),
696 this, SIGNAL(changed()));
697 connect(latexJBibtexCO, SIGNAL(activated(int)),
698 this, SIGNAL(changed()));
699 connect(latexJBibtexED, SIGNAL(textChanged(QString)),
700 this, SIGNAL(changed()));
701 connect(latexIndexCO, SIGNAL(activated(int)),
702 this, SIGNAL(changed()));
703 connect(latexIndexED, SIGNAL(textChanged(QString)),
704 this, SIGNAL(changed()));
705 connect(latexJIndexED, SIGNAL(textChanged(QString)),
706 this, SIGNAL(changed()));
707 connect(latexAutoresetCB, SIGNAL(clicked()),
708 this, SIGNAL(changed()));
709 connect(latexDviPaperED, SIGNAL(textChanged(QString)),
710 this, SIGNAL(changed()));
711 connect(latexNomenclED, SIGNAL(textChanged(QString)),
712 this, SIGNAL(changed()));
714 #if defined(__CYGWIN__) || defined(_WIN32)
715 pathCB->setVisible(true);
716 connect(pathCB, SIGNAL(clicked()),
717 this, SIGNAL(changed()));
719 pathCB->setVisible(false);
724 void PrefLatex::on_latexBibtexCO_activated(int n)
726 QString const bibtex = latexBibtexCO->itemData(n).toString();
727 if (bibtex.isEmpty()) {
728 latexBibtexED->clear();
729 latexBibtexOptionsLA->setText(qt_("C&ommand:"));
732 for (LyXRC::CommandSet::const_iterator it = bibtex_alternatives.begin();
733 it != bibtex_alternatives.end(); ++it) {
734 QString const bib = toqstr(*it);
735 int ind = bib.indexOf(" ");
736 QString sel_command = bib.left(ind);
737 QString sel_options = ind < 0 ? QString() : bib.mid(ind + 1);
738 if (bibtex == sel_command) {
740 latexBibtexED->clear();
742 latexBibtexED->setText(sel_options.trimmed());
745 latexBibtexOptionsLA->setText(qt_("&Options:"));
749 void PrefLatex::on_latexJBibtexCO_activated(int n)
751 QString const jbibtex = latexJBibtexCO->itemData(n).toString();
752 if (jbibtex.isEmpty()) {
753 latexJBibtexED->clear();
754 latexJBibtexOptionsLA->setText(qt_("Co&mmand:"));
757 for (LyXRC::CommandSet::const_iterator it = jbibtex_alternatives.begin();
758 it != jbibtex_alternatives.end(); ++it) {
759 QString const bib = toqstr(*it);
760 int ind = bib.indexOf(" ");
761 QString sel_command = bib.left(ind);
762 QString sel_options = ind < 0 ? QString() : bib.mid(ind + 1);
763 if (jbibtex == sel_command) {
765 latexJBibtexED->clear();
767 latexJBibtexED->setText(sel_options.trimmed());
770 latexJBibtexOptionsLA->setText(qt_("Opt&ions:"));
774 void PrefLatex::on_latexIndexCO_activated(int n)
776 QString const index = latexIndexCO->itemData(n).toString();
777 if (index.isEmpty()) {
778 latexIndexED->clear();
779 latexIndexOptionsLA->setText(qt_("Co&mmand:"));
782 for (LyXRC::CommandSet::const_iterator it = index_alternatives.begin();
783 it != index_alternatives.end(); ++it) {
784 QString const idx = toqstr(*it);
785 int ind = idx.indexOf(" ");
786 QString sel_command = idx.left(ind);
787 QString sel_options = ind < 0 ? QString() : idx.mid(ind + 1);
788 if (index == sel_command) {
790 latexIndexED->clear();
792 latexIndexED->setText(sel_options.trimmed());
795 latexIndexOptionsLA->setText(qt_("Op&tions:"));
799 void PrefLatex::applyRC(LyXRC & rc) const
801 // If bibtex is not empty, bibopt contains the options, otherwise
802 // it is a customized bibtex command with options.
803 QString const bibtex = latexBibtexCO->itemData(
804 latexBibtexCO->currentIndex()).toString();
805 QString const bibopt = latexBibtexED->text();
806 if (bibtex.isEmpty())
807 rc.bibtex_command = fromqstr(bibopt);
808 else if (bibopt.isEmpty())
809 rc.bibtex_command = fromqstr(bibtex);
811 rc.bibtex_command = fromqstr(bibtex) + " " + fromqstr(bibopt);
813 // If jbibtex is not empty, jbibopt contains the options, otherwise
814 // it is a customized bibtex command with options.
815 QString const jbibtex = latexJBibtexCO->itemData(
816 latexJBibtexCO->currentIndex()).toString();
817 QString const jbibopt = latexJBibtexED->text();
818 if (jbibtex.isEmpty())
819 rc.jbibtex_command = fromqstr(jbibopt);
820 else if (jbibopt.isEmpty())
821 rc.jbibtex_command = fromqstr(jbibtex);
823 rc.jbibtex_command = fromqstr(jbibtex) + " " + fromqstr(jbibopt);
825 // If index is not empty, idxopt contains the options, otherwise
826 // it is a customized index command with options.
827 QString const index = latexIndexCO->itemData(
828 latexIndexCO->currentIndex()).toString();
829 QString const idxopt = latexIndexED->text();
831 rc.index_command = fromqstr(idxopt);
832 else if (idxopt.isEmpty())
833 rc.index_command = fromqstr(index);
835 rc.index_command = fromqstr(index) + " " + fromqstr(idxopt);
837 rc.chktex_command = fromqstr(latexChecktexED->text());
838 rc.jindex_command = fromqstr(latexJIndexED->text());
839 rc.nomencl_command = fromqstr(latexNomenclED->text());
840 rc.auto_reset_options = latexAutoresetCB->isChecked();
841 rc.view_dvi_paper_option = fromqstr(latexDviPaperED->text());
842 #if defined(__CYGWIN__) || defined(_WIN32)
843 rc.windows_style_tex_paths = pathCB->isChecked();
848 void PrefLatex::updateRC(LyXRC const & rc)
850 latexBibtexCO->clear();
852 latexBibtexCO->addItem(qt_("Automatic"), "automatic");
853 latexBibtexCO->addItem(qt_("Custom"), QString());
854 for (LyXRC::CommandSet::const_iterator it = rc.bibtex_alternatives.begin();
855 it != rc.bibtex_alternatives.end(); ++it) {
856 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
857 latexBibtexCO->addItem(command, command);
860 bibtex_alternatives = rc.bibtex_alternatives;
862 QString const bib = toqstr(rc.bibtex_command);
863 int ind = bib.indexOf(" ");
864 QString sel_command = bib.left(ind);
865 QString sel_options = ind < 0 ? QString() : bib.mid(ind + 1);
867 int pos = latexBibtexCO->findData(sel_command);
869 latexBibtexCO->setCurrentIndex(pos);
870 latexBibtexED->setText(sel_options.trimmed());
871 latexBibtexOptionsLA->setText(qt_("&Options:"));
873 latexBibtexED->setText(toqstr(rc.bibtex_command));
874 latexBibtexCO->setCurrentIndex(0);
875 latexBibtexOptionsLA->setText(qt_("C&ommand:"));
878 latexJBibtexCO->clear();
880 latexJBibtexCO->addItem(qt_("Automatic"), "automatic");
881 latexJBibtexCO->addItem(qt_("Custom"), QString());
882 for (LyXRC::CommandSet::const_iterator it = rc.jbibtex_alternatives.begin();
883 it != rc.jbibtex_alternatives.end(); ++it) {
884 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
885 latexJBibtexCO->addItem(command, command);
888 jbibtex_alternatives = rc.jbibtex_alternatives;
890 QString const jbib = toqstr(rc.jbibtex_command);
891 ind = jbib.indexOf(" ");
892 sel_command = jbib.left(ind);
893 sel_options = ind < 0 ? QString() : jbib.mid(ind + 1);
895 pos = latexJBibtexCO->findData(sel_command);
897 latexJBibtexCO->setCurrentIndex(pos);
898 latexJBibtexED->setText(sel_options.trimmed());
899 latexJBibtexOptionsLA->setText(qt_("Opt&ions:"));
901 latexJBibtexED->setText(toqstr(rc.bibtex_command));
902 latexJBibtexCO->setCurrentIndex(0);
903 latexJBibtexOptionsLA->setText(qt_("Co&mmand:"));
906 latexIndexCO->clear();
908 latexIndexCO->addItem(qt_("Custom"), QString());
909 for (LyXRC::CommandSet::const_iterator it = rc.index_alternatives.begin();
910 it != rc.index_alternatives.end(); ++it) {
911 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
912 latexIndexCO->addItem(command, command);
915 index_alternatives = rc.index_alternatives;
917 QString const idx = toqstr(rc.index_command);
918 ind = idx.indexOf(" ");
919 sel_command = idx.left(ind);
920 sel_options = ind < 0 ? QString() : idx.mid(ind + 1);
922 pos = latexIndexCO->findData(sel_command);
924 latexIndexCO->setCurrentIndex(pos);
925 latexIndexED->setText(sel_options.trimmed());
926 latexIndexOptionsLA->setText(qt_("Op&tions:"));
928 latexIndexED->setText(toqstr(rc.index_command));
929 latexIndexCO->setCurrentIndex(0);
930 latexIndexOptionsLA->setText(qt_("Co&mmand:"));
933 latexChecktexED->setText(toqstr(rc.chktex_command));
934 latexJIndexED->setText(toqstr(rc.jindex_command));
935 latexNomenclED->setText(toqstr(rc.nomencl_command));
936 latexAutoresetCB->setChecked(rc.auto_reset_options);
937 latexDviPaperED->setText(toqstr(rc.view_dvi_paper_option));
938 #if defined(__CYGWIN__) || defined(_WIN32)
939 pathCB->setChecked(rc.windows_style_tex_paths);
944 /////////////////////////////////////////////////////////////////////
948 /////////////////////////////////////////////////////////////////////
950 PrefScreenFonts::PrefScreenFonts(GuiPreferences * form)
951 : PrefModule(catLookAndFeel, N_("Screen Fonts"), form)
955 connect(screenRomanCO, SIGNAL(activated(QString)),
956 this, SLOT(selectRoman(QString)));
957 connect(screenSansCO, SIGNAL(activated(QString)),
958 this, SLOT(selectSans(QString)));
959 connect(screenTypewriterCO, SIGNAL(activated(QString)),
960 this, SLOT(selectTypewriter(QString)));
962 QFontDatabase fontdb;
963 QStringList families(fontdb.families());
964 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
965 screenRomanCO->addItem(*it);
966 screenSansCO->addItem(*it);
967 screenTypewriterCO->addItem(*it);
969 connect(screenRomanCO, SIGNAL(activated(QString)),
970 this, SIGNAL(changed()));
971 connect(screenSansCO, SIGNAL(activated(QString)),
972 this, SIGNAL(changed()));
973 connect(screenTypewriterCO, SIGNAL(activated(QString)),
974 this, SIGNAL(changed()));
975 connect(screenZoomSB, SIGNAL(valueChanged(int)),
976 this, SIGNAL(changed()));
977 connect(screenTinyED, SIGNAL(textChanged(QString)),
978 this, SIGNAL(changed()));
979 connect(screenSmallestED, SIGNAL(textChanged(QString)),
980 this, SIGNAL(changed()));
981 connect(screenSmallerED, SIGNAL(textChanged(QString)),
982 this, SIGNAL(changed()));
983 connect(screenSmallED, SIGNAL(textChanged(QString)),
984 this, SIGNAL(changed()));
985 connect(screenNormalED, SIGNAL(textChanged(QString)),
986 this, SIGNAL(changed()));
987 connect(screenLargeED, SIGNAL(textChanged(QString)),
988 this, SIGNAL(changed()));
989 connect(screenLargerED, SIGNAL(textChanged(QString)),
990 this, SIGNAL(changed()));
991 connect(screenLargestED, SIGNAL(textChanged(QString)),
992 this, SIGNAL(changed()));
993 connect(screenHugeED, SIGNAL(textChanged(QString)),
994 this, SIGNAL(changed()));
995 connect(screenHugerED, SIGNAL(textChanged(QString)),
996 this, SIGNAL(changed()));
998 screenTinyED->setValidator(new QDoubleValidator(screenTinyED));
999 screenSmallestED->setValidator(new QDoubleValidator(screenSmallestED));
1000 screenSmallerED->setValidator(new QDoubleValidator(screenSmallerED));
1001 screenSmallED->setValidator(new QDoubleValidator(screenSmallED));
1002 screenNormalED->setValidator(new QDoubleValidator(screenNormalED));
1003 screenLargeED->setValidator(new QDoubleValidator(screenLargeED));
1004 screenLargerED->setValidator(new QDoubleValidator(screenLargerED));
1005 screenLargestED->setValidator(new QDoubleValidator(screenLargestED));
1006 screenHugeED->setValidator(new QDoubleValidator(screenHugeED));
1007 screenHugerED->setValidator(new QDoubleValidator(screenHugerED));
1011 void PrefScreenFonts::applyRC(LyXRC & rc) const
1013 LyXRC const oldrc = rc;
1015 parseFontName(screenRomanCO->currentText(),
1016 rc.roman_font_name, rc.roman_font_foundry);
1017 parseFontName(screenSansCO->currentText(),
1018 rc.sans_font_name, rc.sans_font_foundry);
1019 parseFontName(screenTypewriterCO->currentText(),
1020 rc.typewriter_font_name, rc.typewriter_font_foundry);
1022 rc.defaultZoom = screenZoomSB->value();
1023 rc.font_sizes[FONT_SIZE_TINY] = widgetToDoubleStr(screenTinyED);
1024 rc.font_sizes[FONT_SIZE_SCRIPT] = widgetToDoubleStr(screenSmallestED);
1025 rc.font_sizes[FONT_SIZE_FOOTNOTE] = widgetToDoubleStr(screenSmallerED);
1026 rc.font_sizes[FONT_SIZE_SMALL] = widgetToDoubleStr(screenSmallED);
1027 rc.font_sizes[FONT_SIZE_NORMAL] = widgetToDoubleStr(screenNormalED);
1028 rc.font_sizes[FONT_SIZE_LARGE] = widgetToDoubleStr(screenLargeED);
1029 rc.font_sizes[FONT_SIZE_LARGER] = widgetToDoubleStr(screenLargerED);
1030 rc.font_sizes[FONT_SIZE_LARGEST] = widgetToDoubleStr(screenLargestED);
1031 rc.font_sizes[FONT_SIZE_HUGE] = widgetToDoubleStr(screenHugeED);
1032 rc.font_sizes[FONT_SIZE_HUGER] = widgetToDoubleStr(screenHugerED);
1034 if (rc.font_sizes != oldrc.font_sizes
1035 || rc.roman_font_name != oldrc.roman_font_name
1036 || rc.sans_font_name != oldrc.sans_font_name
1037 || rc.typewriter_font_name != oldrc.typewriter_font_name
1038 || rc.defaultZoom != oldrc.defaultZoom) {
1039 guiApp->fontLoader().update();
1040 form_->updateScreenFonts();
1045 void PrefScreenFonts::updateRC(LyXRC const & rc)
1047 setComboxFont(screenRomanCO, rc.roman_font_name,
1048 rc.roman_font_foundry);
1049 setComboxFont(screenSansCO, rc.sans_font_name,
1050 rc.sans_font_foundry);
1051 setComboxFont(screenTypewriterCO, rc.typewriter_font_name,
1052 rc.typewriter_font_foundry);
1054 selectRoman(screenRomanCO->currentText());
1055 selectSans(screenSansCO->currentText());
1056 selectTypewriter(screenTypewriterCO->currentText());
1058 screenZoomSB->setValue(rc.defaultZoom);
1059 updateScreenFontSizes(rc);
1063 void PrefScreenFonts::updateScreenFontSizes(LyXRC const & rc)
1065 doubleToWidget(screenTinyED, rc.font_sizes[FONT_SIZE_TINY]);
1066 doubleToWidget(screenSmallestED, rc.font_sizes[FONT_SIZE_SCRIPT]);
1067 doubleToWidget(screenSmallerED, rc.font_sizes[FONT_SIZE_FOOTNOTE]);
1068 doubleToWidget(screenSmallED, rc.font_sizes[FONT_SIZE_SMALL]);
1069 doubleToWidget(screenNormalED, rc.font_sizes[FONT_SIZE_NORMAL]);
1070 doubleToWidget(screenLargeED, rc.font_sizes[FONT_SIZE_LARGE]);
1071 doubleToWidget(screenLargerED, rc.font_sizes[FONT_SIZE_LARGER]);
1072 doubleToWidget(screenLargestED, rc.font_sizes[FONT_SIZE_LARGEST]);
1073 doubleToWidget(screenHugeED, rc.font_sizes[FONT_SIZE_HUGE]);
1074 doubleToWidget(screenHugerED, rc.font_sizes[FONT_SIZE_HUGER]);
1078 void PrefScreenFonts::selectRoman(const QString & name)
1080 screenRomanFE->set(QFont(name), name);
1084 void PrefScreenFonts::selectSans(const QString & name)
1086 screenSansFE->set(QFont(name), name);
1090 void PrefScreenFonts::selectTypewriter(const QString & name)
1092 screenTypewriterFE->set(QFont(name), name);
1096 /////////////////////////////////////////////////////////////////////
1100 /////////////////////////////////////////////////////////////////////
1103 PrefColors::PrefColors(GuiPreferences * form)
1104 : PrefModule(catLookAndFeel, N_("Colors"), form)
1108 // FIXME: all of this initialization should be put into the controller.
1109 // See http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg113301.html
1110 // for some discussion of why that is not trivial.
1111 QPixmap icon(32, 32);
1112 for (int i = 0; i < Color_ignore; ++i) {
1113 ColorCode lc = static_cast<ColorCode>(i);
1114 if (lc == Color_none
1115 || lc == Color_black
1116 || lc == Color_white
1118 || lc == Color_brown
1120 || lc == Color_darkgray
1122 || lc == Color_green
1123 || lc == Color_lightgray
1125 || lc == Color_magenta
1126 || lc == Color_olive
1127 || lc == Color_orange
1129 || lc == Color_purple
1132 || lc == Color_violet
1133 || lc == Color_yellow
1134 || lc == Color_inherit
1135 || lc == Color_ignore)
1137 lcolors_.push_back(lc);
1139 qSort(lcolors_.begin(), lcolors_.end(), ColorSorter);
1140 vector<ColorCode>::const_iterator cit = lcolors_.begin();
1141 vector<ColorCode>::const_iterator const end = lcolors_.end();
1142 for (; cit != end; ++cit) {
1143 (void) new QListWidgetItem(QIcon(icon),
1144 toqstr(lcolor.getGUIName(*cit)), lyxObjectsLW);
1146 curcolors_.resize(lcolors_.size());
1147 newcolors_.resize(lcolors_.size());
1148 // End initialization
1150 connect(colorChangePB, SIGNAL(clicked()),
1151 this, SLOT(changeColor()));
1152 connect(lyxObjectsLW, SIGNAL(itemSelectionChanged()),
1153 this, SLOT(changeLyxObjectsSelection()));
1154 connect(lyxObjectsLW, SIGNAL(itemActivated(QListWidgetItem*)),
1155 this, SLOT(changeColor()));
1156 connect(syscolorsCB, SIGNAL(toggled(bool)),
1157 this, SIGNAL(changed()));
1158 connect(syscolorsCB, SIGNAL(toggled(bool)),
1159 this, SLOT(changeSysColor()));
1163 void PrefColors::applyRC(LyXRC & rc) const
1167 for (unsigned int i = 0; i < lcolors_.size(); ++i)
1168 if (curcolors_[i] != newcolors_[i])
1169 form_->setColor(lcolors_[i], newcolors_[i]);
1170 rc.use_system_colors = syscolorsCB->isChecked();
1172 if (oldrc.use_system_colors != rc.use_system_colors)
1173 guiApp->colorCache().clear();
1177 void PrefColors::updateRC(LyXRC const & rc)
1179 for (unsigned int i = 0; i < lcolors_.size(); ++i) {
1180 QColor color = QColor(guiApp->colorCache().get(lcolors_[i], false));
1181 QPixmap coloritem(32, 32);
1182 coloritem.fill(color);
1183 lyxObjectsLW->item(i)->setIcon(QIcon(coloritem));
1184 newcolors_[i] = curcolors_[i] = color.name();
1186 syscolorsCB->setChecked(rc.use_system_colors);
1187 changeLyxObjectsSelection();
1191 void PrefColors::changeColor()
1193 int const row = lyxObjectsLW->currentRow();
1199 QString const color = newcolors_[row];
1200 QColor c = QColorDialog::getColor(QColor(color), qApp->focusWidget());
1202 if (c.isValid() && c.name() != color) {
1203 newcolors_[row] = c.name();
1204 QPixmap coloritem(32, 32);
1206 lyxObjectsLW->currentItem()->setIcon(QIcon(coloritem));
1212 void PrefColors::changeSysColor()
1214 for (int row = 0 ; row < lyxObjectsLW->count() ; ++row) {
1215 // skip colors that are taken from system palette
1216 bool const disable = syscolorsCB->isChecked()
1217 && guiApp->colorCache().isSystem(lcolors_[row]);
1219 QListWidgetItem * const item = lyxObjectsLW->item(row);
1220 Qt::ItemFlags const flags = item->flags();
1223 item->setFlags(flags & ~Qt::ItemIsEnabled);
1225 item->setFlags(flags | Qt::ItemIsEnabled);
1229 void PrefColors::changeLyxObjectsSelection()
1231 colorChangePB->setDisabled(lyxObjectsLW->currentRow() < 0);
1235 /////////////////////////////////////////////////////////////////////
1239 /////////////////////////////////////////////////////////////////////
1241 PrefDisplay::PrefDisplay(GuiPreferences * form)
1242 : PrefModule(catLookAndFeel, N_("Display"), form)
1245 connect(displayGraphicsCB, SIGNAL(toggled(bool)), this, SIGNAL(changed()));
1246 connect(instantPreviewCO, SIGNAL(activated(int)), this, SIGNAL(changed()));
1247 connect(previewSizeSB, SIGNAL(valueChanged(double)), this, SIGNAL(changed()));
1248 connect(paragraphMarkerCB, SIGNAL(toggled(bool)), this, SIGNAL(changed()));
1252 void PrefDisplay::on_instantPreviewCO_currentIndexChanged(int index)
1254 previewSizeSB->setEnabled(index != 0);
1258 void PrefDisplay::applyRC(LyXRC & rc) const
1260 switch (instantPreviewCO->currentIndex()) {
1262 rc.preview = LyXRC::PREVIEW_OFF;
1265 if (rc.preview != LyXRC::PREVIEW_NO_MATH) {
1266 rc.preview = LyXRC::PREVIEW_NO_MATH;
1267 form_->updatePreviews();
1271 if (rc.preview != LyXRC::PREVIEW_ON) {
1272 rc.preview = LyXRC::PREVIEW_ON;
1273 form_->updatePreviews();
1278 rc.display_graphics = displayGraphicsCB->isChecked();
1279 rc.preview_scale_factor = previewSizeSB->value();
1280 rc.paragraph_markers = paragraphMarkerCB->isChecked();
1282 // FIXME!! The graphics cache no longer has a changeDisplay method.
1284 if (old_value != rc.display_graphics) {
1285 graphics::GCache & gc = graphics::GCache::get();
1292 void PrefDisplay::updateRC(LyXRC const & rc)
1294 switch (rc.preview) {
1295 case LyXRC::PREVIEW_OFF:
1296 instantPreviewCO->setCurrentIndex(0);
1298 case LyXRC::PREVIEW_NO_MATH :
1299 instantPreviewCO->setCurrentIndex(1);
1301 case LyXRC::PREVIEW_ON :
1302 instantPreviewCO->setCurrentIndex(2);
1306 displayGraphicsCB->setChecked(rc.display_graphics);
1307 previewSizeSB->setValue(rc.preview_scale_factor);
1308 paragraphMarkerCB->setChecked(rc.paragraph_markers);
1309 previewSizeSB->setEnabled(
1311 && rc.preview != LyXRC::PREVIEW_OFF);
1315 /////////////////////////////////////////////////////////////////////
1319 /////////////////////////////////////////////////////////////////////
1321 PrefPaths::PrefPaths(GuiPreferences * form)
1322 : PrefModule(QString(), N_("Paths"), form)
1326 connect(workingDirPB, SIGNAL(clicked()), this, SLOT(selectWorkingdir()));
1327 connect(workingDirED, SIGNAL(textChanged(QString)),
1328 this, SIGNAL(changed()));
1330 connect(templateDirPB, SIGNAL(clicked()), this, SLOT(selectTemplatedir()));
1331 connect(templateDirED, SIGNAL(textChanged(QString)),
1332 this, SIGNAL(changed()));
1334 connect(exampleDirPB, SIGNAL(clicked()), this, SLOT(selectExampledir()));
1335 connect(exampleDirED, SIGNAL(textChanged(QString)),
1336 this, SIGNAL(changed()));
1338 connect(backupDirPB, SIGNAL(clicked()), this, SLOT(selectBackupdir()));
1339 connect(backupDirED, SIGNAL(textChanged(QString)),
1340 this, SIGNAL(changed()));
1342 connect(lyxserverDirPB, SIGNAL(clicked()), this, SLOT(selectLyxPipe()));
1343 connect(lyxserverDirED, SIGNAL(textChanged(QString)),
1344 this, SIGNAL(changed()));
1346 connect(thesaurusDirPB, SIGNAL(clicked()), this, SLOT(selectThesaurusdir()));
1347 connect(thesaurusDirED, SIGNAL(textChanged(QString)),
1348 this, SIGNAL(changed()));
1350 connect(tempDirPB, SIGNAL(clicked()), this, SLOT(selectTempdir()));
1351 connect(tempDirED, SIGNAL(textChanged(QString)),
1352 this, SIGNAL(changed()));
1354 #if defined(USE_HUNSPELL)
1355 connect(hunspellDirPB, SIGNAL(clicked()), this, SLOT(selectHunspelldir()));
1356 connect(hunspellDirED, SIGNAL(textChanged(QString)),
1357 this, SIGNAL(changed()));
1359 hunspellDirPB->setEnabled(false);
1360 hunspellDirED->setEnabled(false);
1363 connect(pathPrefixED, SIGNAL(textChanged(QString)),
1364 this, SIGNAL(changed()));
1366 connect(texinputsPrefixED, SIGNAL(textChanged(QString)),
1367 this, SIGNAL(changed()));
1369 pathPrefixED->setValidator(new NoNewLineValidator(pathPrefixED));
1370 texinputsPrefixED->setValidator(new NoNewLineValidator(texinputsPrefixED));
1374 void PrefPaths::applyRC(LyXRC & rc) const
1376 rc.document_path = internal_path(fromqstr(workingDirED->text()));
1377 rc.example_path = internal_path(fromqstr(exampleDirED->text()));
1378 rc.template_path = internal_path(fromqstr(templateDirED->text()));
1379 rc.backupdir_path = internal_path(fromqstr(backupDirED->text()));
1380 rc.tempdir_path = internal_path(fromqstr(tempDirED->text()));
1381 rc.thesaurusdir_path = internal_path(fromqstr(thesaurusDirED->text()));
1382 rc.hunspelldir_path = internal_path(fromqstr(hunspellDirED->text()));
1383 rc.path_prefix = internal_path_list(fromqstr(pathPrefixED->text()));
1384 rc.texinputs_prefix = internal_path_list(fromqstr(texinputsPrefixED->text()));
1385 // FIXME: should be a checkbox only
1386 rc.lyxpipes = internal_path(fromqstr(lyxserverDirED->text()));
1390 void PrefPaths::updateRC(LyXRC const & rc)
1392 workingDirED->setText(toqstr(external_path(rc.document_path)));
1393 exampleDirED->setText(toqstr(external_path(rc.example_path)));
1394 templateDirED->setText(toqstr(external_path(rc.template_path)));
1395 backupDirED->setText(toqstr(external_path(rc.backupdir_path)));
1396 tempDirED->setText(toqstr(external_path(rc.tempdir_path)));
1397 thesaurusDirED->setText(toqstr(external_path(rc.thesaurusdir_path)));
1398 hunspellDirED->setText(toqstr(external_path(rc.hunspelldir_path)));
1399 pathPrefixED->setText(toqstr(external_path_list(rc.path_prefix)));
1400 texinputsPrefixED->setText(toqstr(external_path_list(rc.texinputs_prefix)));
1401 // FIXME: should be a checkbox only
1402 lyxserverDirED->setText(toqstr(external_path(rc.lyxpipes)));
1406 void PrefPaths::selectExampledir()
1408 QString file = browseDir(internalPath(exampleDirED->text()),
1409 qt_("Select directory for example files"));
1410 if (!file.isEmpty())
1411 exampleDirED->setText(file);
1415 void PrefPaths::selectTemplatedir()
1417 QString file = browseDir(internalPath(templateDirED->text()),
1418 qt_("Select a document templates directory"));
1419 if (!file.isEmpty())
1420 templateDirED->setText(file);
1424 void PrefPaths::selectTempdir()
1426 QString file = browseDir(internalPath(tempDirED->text()),
1427 qt_("Select a temporary directory"));
1428 if (!file.isEmpty())
1429 tempDirED->setText(file);
1433 void PrefPaths::selectBackupdir()
1435 QString file = browseDir(internalPath(backupDirED->text()),
1436 qt_("Select a backups directory"));
1437 if (!file.isEmpty())
1438 backupDirED->setText(file);
1442 void PrefPaths::selectWorkingdir()
1444 QString file = browseDir(internalPath(workingDirED->text()),
1445 qt_("Select a document directory"));
1446 if (!file.isEmpty())
1447 workingDirED->setText(file);
1451 void PrefPaths::selectThesaurusdir()
1453 QString file = browseDir(internalPath(thesaurusDirED->text()),
1454 qt_("Set the path to the thesaurus dictionaries"));
1455 if (!file.isEmpty())
1456 thesaurusDirED->setText(file);
1460 void PrefPaths::selectHunspelldir()
1462 QString file = browseDir(internalPath(hunspellDirED->text()),
1463 qt_("Set the path to the Hunspell dictionaries"));
1464 if (!file.isEmpty())
1465 hunspellDirED->setText(file);
1469 void PrefPaths::selectLyxPipe()
1471 QString file = form_->browse(internalPath(lyxserverDirED->text()),
1472 qt_("Give a filename for the LyX server pipe"));
1473 if (!file.isEmpty())
1474 lyxserverDirED->setText(file);
1478 /////////////////////////////////////////////////////////////////////
1482 /////////////////////////////////////////////////////////////////////
1484 PrefSpellchecker::PrefSpellchecker(GuiPreferences * form)
1485 : PrefModule(catLanguage, N_("Spellchecker"), form)
1489 // FIXME: this check should test the target platform (darwin)
1490 #if defined(USE_MACOSX_PACKAGING)
1491 spellcheckerCB->addItem(qt_("Native"), QString("native"));
1492 #define CONNECT_APPLESPELL
1494 #undef CONNECT_APPLESPELL
1496 #if defined(USE_ASPELL)
1497 spellcheckerCB->addItem(qt_("Aspell"), QString("aspell"));
1499 #if defined(USE_ENCHANT)
1500 spellcheckerCB->addItem(qt_("Enchant"), QString("enchant"));
1502 #if defined(USE_HUNSPELL)
1503 spellcheckerCB->addItem(qt_("Hunspell"), QString("hunspell"));
1506 #if defined(CONNECT_APPLESPELL) || defined(USE_ASPELL) || defined(USE_ENCHANT) || defined(USE_HUNSPELL)
1507 connect(spellcheckerCB, SIGNAL(currentIndexChanged(int)),
1508 this, SIGNAL(changed()));
1509 connect(altLanguageED, SIGNAL(textChanged(QString)),
1510 this, SIGNAL(changed()));
1511 connect(escapeCharactersED, SIGNAL(textChanged(QString)),
1512 this, SIGNAL(changed()));
1513 connect(compoundWordCB, SIGNAL(clicked()),
1514 this, SIGNAL(changed()));
1515 connect(spellcheckContinuouslyCB, SIGNAL(clicked()),
1516 this, SIGNAL(changed()));
1517 connect(spellcheckNotesCB, SIGNAL(clicked()),
1518 this, SIGNAL(changed()));
1520 altLanguageED->setValidator(new NoNewLineValidator(altLanguageED));
1521 escapeCharactersED->setValidator(new NoNewLineValidator(escapeCharactersED));
1523 spellcheckerCB->setEnabled(false);
1524 altLanguageED->setEnabled(false);
1525 escapeCharactersED->setEnabled(false);
1526 compoundWordCB->setEnabled(false);
1527 spellcheckContinuouslyCB->setEnabled(false);
1528 spellcheckNotesCB->setEnabled(false);
1533 void PrefSpellchecker::applyRC(LyXRC & rc) const
1535 string const speller = fromqstr(spellcheckerCB->
1536 itemData(spellcheckerCB->currentIndex()).toString());
1537 if (!speller.empty())
1538 rc.spellchecker = speller;
1539 rc.spellchecker_alt_lang = fromqstr(altLanguageED->text());
1540 rc.spellchecker_esc_chars = fromqstr(escapeCharactersED->text());
1541 rc.spellchecker_accept_compound = compoundWordCB->isChecked();
1542 rc.spellcheck_continuously = spellcheckContinuouslyCB->isChecked();
1543 rc.spellcheck_notes = spellcheckNotesCB->isChecked();
1547 void PrefSpellchecker::updateRC(LyXRC const & rc)
1549 spellcheckerCB->setCurrentIndex(
1550 spellcheckerCB->findData(toqstr(rc.spellchecker)));
1551 altLanguageED->setText(toqstr(rc.spellchecker_alt_lang));
1552 escapeCharactersED->setText(toqstr(rc.spellchecker_esc_chars));
1553 compoundWordCB->setChecked(rc.spellchecker_accept_compound);
1554 spellcheckContinuouslyCB->setChecked(rc.spellcheck_continuously);
1555 spellcheckNotesCB->setChecked(rc.spellcheck_notes);
1559 void PrefSpellchecker::on_spellcheckerCB_currentIndexChanged(int index)
1561 QString spellchecker = spellcheckerCB->itemData(index).toString();
1563 compoundWordCB->setEnabled(spellchecker == QString("aspell"));
1568 /////////////////////////////////////////////////////////////////////
1572 /////////////////////////////////////////////////////////////////////
1575 PrefConverters::PrefConverters(GuiPreferences * form)
1576 : PrefModule(catFiles, N_("Converters"), form)
1580 connect(converterNewPB, SIGNAL(clicked()),
1581 this, SLOT(updateConverter()));
1582 connect(converterRemovePB, SIGNAL(clicked()),
1583 this, SLOT(removeConverter()));
1584 connect(converterModifyPB, SIGNAL(clicked()),
1585 this, SLOT(updateConverter()));
1586 connect(convertersLW, SIGNAL(currentRowChanged(int)),
1587 this, SLOT(switchConverter()));
1588 connect(converterFromCO, SIGNAL(activated(QString)),
1589 this, SLOT(changeConverter()));
1590 connect(converterToCO, SIGNAL(activated(QString)),
1591 this, SLOT(changeConverter()));
1592 connect(converterED, SIGNAL(textEdited(QString)),
1593 this, SLOT(changeConverter()));
1594 connect(converterFlagED, SIGNAL(textEdited(QString)),
1595 this, SLOT(changeConverter()));
1596 connect(converterNewPB, SIGNAL(clicked()),
1597 this, SIGNAL(changed()));
1598 connect(converterRemovePB, SIGNAL(clicked()),
1599 this, SIGNAL(changed()));
1600 connect(converterModifyPB, SIGNAL(clicked()),
1601 this, SIGNAL(changed()));
1602 connect(maxAgeLE, SIGNAL(textEdited(QString)),
1603 this, SIGNAL(changed()));
1604 connect(needauthForbiddenCB, SIGNAL(toggled(bool)),
1605 this, SIGNAL(changed()));
1607 converterED->setValidator(new NoNewLineValidator(converterED));
1608 converterFlagED->setValidator(new NoNewLineValidator(converterFlagED));
1609 maxAgeLE->setValidator(new QDoubleValidator(0, HUGE_VAL, 6, maxAgeLE));
1610 //converterDefGB->setFocusProxy(convertersLW);
1614 void PrefConverters::applyRC(LyXRC & rc) const
1616 rc.use_converter_cache = cacheCB->isChecked();
1617 rc.use_converter_needauth_forbidden = needauthForbiddenCB->isChecked();
1618 rc.use_converter_needauth = needauthCB->isChecked();
1619 rc.converter_cache_maxage = int(widgetToDouble(maxAgeLE) * 86400.0);
1623 static void setCheckboxBlockSignals(QCheckBox *cb, bool checked) {
1624 cb->blockSignals(true);
1625 cb->setChecked(checked);
1626 cb->blockSignals(false);
1630 void PrefConverters::updateRC(LyXRC const & rc)
1632 cacheCB->setChecked(rc.use_converter_cache);
1633 needauthForbiddenCB->setChecked(rc.use_converter_needauth_forbidden);
1634 setCheckboxBlockSignals(needauthCB, rc.use_converter_needauth);
1636 doubleToWidget(maxAgeLE, (double(rc.converter_cache_maxage) / 86400.0), 'g', 6);
1641 void PrefConverters::updateGui()
1643 QString const pattern("%1 -> %2");
1644 form_->formats().sort();
1645 form_->converters().update(form_->formats());
1646 // save current selection
1649 .arg(converterFromCO->currentText())
1650 .arg(converterToCO->currentText());
1652 converterFromCO->clear();
1653 converterToCO->clear();
1655 for (Format const & f : form_->formats()) {
1656 QString const name = toqstr(translateIfPossible(f.prettyname()));
1657 converterFromCO->addItem(name);
1658 converterToCO->addItem(name);
1661 // currentRowChanged(int) is also triggered when updating the listwidget
1662 // block signals to avoid unnecessary calls to switchConverter()
1663 convertersLW->blockSignals(true);
1664 convertersLW->clear();
1666 for (Converter const & c : form_->converters()) {
1667 QString const name =
1669 .arg(toqstr(translateIfPossible(c.From()->prettyname())))
1670 .arg(toqstr(translateIfPossible(c.To()->prettyname())));
1671 int type = form_->converters().getNumber(c.From()->name(),
1673 new QListWidgetItem(name, convertersLW, type);
1675 convertersLW->sortItems(Qt::AscendingOrder);
1676 convertersLW->blockSignals(false);
1678 // restore selection
1679 if (current != pattern.arg(QString()).arg(QString())) {
1680 QList<QListWidgetItem *> const item =
1681 convertersLW->findItems(current, Qt::MatchExactly);
1682 if (!item.isEmpty())
1683 convertersLW->setCurrentItem(item.at(0));
1686 // select first element if restoring failed
1687 if (convertersLW->currentRow() == -1)
1688 convertersLW->setCurrentRow(0);
1694 void PrefConverters::switchConverter()
1696 int const cnr = convertersLW->currentItem()->type();
1697 Converter const & c(form_->converters().get(cnr));
1698 converterFromCO->setCurrentIndex(form_->formats().getNumber(c.from()));
1699 converterToCO->setCurrentIndex(form_->formats().getNumber(c.to()));
1700 converterED->setText(toqstr(c.command()));
1701 converterFlagED->setText(toqstr(c.flags()));
1707 void PrefConverters::changeConverter()
1713 void PrefConverters::updateButtons()
1715 if (form_->formats().empty())
1717 Format const & from = form_->formats().get(converterFromCO->currentIndex());
1718 Format const & to = form_->formats().get(converterToCO->currentIndex());
1719 int const sel = form_->converters().getNumber(from.name(), to.name());
1720 bool const known = sel >= 0;
1721 bool const valid = !(converterED->text().isEmpty()
1722 || from.name() == to.name());
1727 if (convertersLW->count() > 0) {
1728 int const cnr = convertersLW->currentItem()->type();
1729 Converter const & c = form_->converters().get(cnr);
1730 old_command = c.command();
1731 old_flag = c.flags();
1734 string const new_command = fromqstr(converterED->text());
1735 string const new_flag = fromqstr(converterFlagED->text());
1737 bool modified = (old_command != new_command || old_flag != new_flag);
1739 converterModifyPB->setEnabled(valid && known && modified);
1740 converterNewPB->setEnabled(valid && !known);
1741 converterRemovePB->setEnabled(known);
1743 maxAgeLE->setEnabled(cacheCB->isChecked());
1744 maxAgeLA->setEnabled(cacheCB->isChecked());
1749 // specify unique from/to or it doesn't appear. This is really bad UI
1750 // this is why we can use the same function for both new and modify
1751 void PrefConverters::updateConverter()
1753 Format const & from = form_->formats().get(converterFromCO->currentIndex());
1754 Format const & to = form_->formats().get(converterToCO->currentIndex());
1755 string const flags = fromqstr(converterFlagED->text());
1756 string const command = fromqstr(converterED->text());
1758 Converter const * old =
1759 form_->converters().getConverter(from.name(), to.name());
1760 form_->converters().add(from.name(), to.name(), command, flags);
1763 form_->converters().updateLast(form_->formats());
1767 // Remove all files created by this converter from the cache, since
1768 // the modified converter might create different files.
1769 ConverterCache::get().remove_all(from.name(), to.name());
1773 void PrefConverters::removeConverter()
1775 Format const & from = form_->formats().get(converterFromCO->currentIndex());
1776 Format const & to = form_->formats().get(converterToCO->currentIndex());
1777 form_->converters().erase(from.name(), to.name());
1781 // Remove all files created by this converter from the cache, since
1782 // a possible new converter might create different files.
1783 ConverterCache::get().remove_all(from.name(), to.name());
1787 void PrefConverters::on_cacheCB_stateChanged(int state)
1789 maxAgeLE->setEnabled(state == Qt::Checked);
1790 maxAgeLA->setEnabled(state == Qt::Checked);
1795 void PrefConverters::on_needauthForbiddenCB_toggled(bool checked)
1797 needauthCB->setEnabled(!checked);
1801 void PrefConverters::on_needauthCB_toggled(bool checked)
1808 int ret = frontend::Alert::prompt(
1809 _("SECURITY WARNING!"), _("Unchecking this option has the effect that potentially harmful converters would be run without asking your permission first. This is UNSAFE and NOT recommended, unless you know what you are doing. Are you sure you would like to proceed ? The recommended and safe answer is NO!"),
1810 0, 0, _("&No"), _("&Yes"));
1814 setCheckboxBlockSignals(needauthCB, true);
1818 /////////////////////////////////////////////////////////////////////
1822 /////////////////////////////////////////////////////////////////////
1824 class FormatValidator : public QValidator
1827 FormatValidator(QWidget *, Formats const & f);
1828 void fixup(QString & input) const;
1829 QValidator::State validate(QString & input, int & pos) const;
1831 virtual QString toString(Format const & format) const = 0;
1833 Formats const & formats_;
1837 FormatValidator::FormatValidator(QWidget * parent, Formats const & f)
1838 : QValidator(parent), formats_(f)
1843 void FormatValidator::fixup(QString & input) const
1845 Formats::const_iterator cit = formats_.begin();
1846 Formats::const_iterator end = formats_.end();
1847 for (; cit != end; ++cit) {
1848 QString const name = toString(*cit);
1849 if (distance(formats_.begin(), cit) == nr()) {
1857 QValidator::State FormatValidator::validate(QString & input, int & /*pos*/) const
1859 Formats::const_iterator cit = formats_.begin();
1860 Formats::const_iterator end = formats_.end();
1861 bool unknown = true;
1862 for (; unknown && cit != end; ++cit) {
1863 QString const name = toString(*cit);
1864 if (distance(formats_.begin(), cit) != nr())
1865 unknown = name != input;
1868 if (unknown && !input.isEmpty())
1869 return QValidator::Acceptable;
1871 return QValidator::Intermediate;
1875 int FormatValidator::nr() const
1877 QComboBox * p = qobject_cast<QComboBox *>(parent());
1878 return p->itemData(p->currentIndex()).toInt();
1882 /////////////////////////////////////////////////////////////////////
1884 // FormatNameValidator
1886 /////////////////////////////////////////////////////////////////////
1888 class FormatNameValidator : public FormatValidator
1891 FormatNameValidator(QWidget * parent, Formats const & f)
1892 : FormatValidator(parent, f)
1895 QString toString(Format const & format) const
1897 return toqstr(format.name());
1902 /////////////////////////////////////////////////////////////////////
1904 // FormatPrettynameValidator
1906 /////////////////////////////////////////////////////////////////////
1908 class FormatPrettynameValidator : public FormatValidator
1911 FormatPrettynameValidator(QWidget * parent, Formats const & f)
1912 : FormatValidator(parent, f)
1915 QString toString(Format const & format) const
1917 return toqstr(translateIfPossible(format.prettyname()));
1922 /////////////////////////////////////////////////////////////////////
1926 /////////////////////////////////////////////////////////////////////
1928 PrefFileformats::PrefFileformats(GuiPreferences * form)
1929 : PrefModule(catFiles, N_("File Formats"), form)
1933 formatED->setValidator(new FormatNameValidator(formatsCB, form_->formats()));
1934 formatsCB->setValidator(new FormatPrettynameValidator(formatsCB, form_->formats()));
1935 extensionsED->setValidator(new NoNewLineValidator(extensionsED));
1936 shortcutED->setValidator(new NoNewLineValidator(shortcutED));
1937 editorED->setValidator(new NoNewLineValidator(editorED));
1938 viewerED->setValidator(new NoNewLineValidator(viewerED));
1939 copierED->setValidator(new NoNewLineValidator(copierED));
1941 connect(documentCB, SIGNAL(clicked()),
1942 this, SLOT(setFlags()));
1943 connect(vectorCB, SIGNAL(clicked()),
1944 this, SLOT(setFlags()));
1945 connect(exportMenuCB, SIGNAL(clicked()),
1946 this, SLOT(setFlags()));
1947 connect(formatsCB->lineEdit(), SIGNAL(editingFinished()),
1948 this, SLOT(updatePrettyname()));
1949 connect(formatsCB->lineEdit(), SIGNAL(textEdited(QString)),
1950 this, SIGNAL(changed()));
1951 connect(defaultFormatCB, SIGNAL(activated(QString)),
1952 this, SIGNAL(changed()));
1953 connect(defaultOTFFormatCB, SIGNAL(activated(QString)),
1954 this, SIGNAL(changed()));
1955 connect(defaultPlatexFormatCB, SIGNAL(activated(QString)),
1956 this, SIGNAL(changed()));
1957 connect(viewerCO, SIGNAL(activated(int)),
1958 this, SIGNAL(changed()));
1959 connect(editorCO, SIGNAL(activated(int)),
1960 this, SIGNAL(changed()));
1966 string const l10n_shortcut(docstring const & prettyname, string const & shortcut)
1968 if (shortcut.empty())
1971 string l10n_format =
1972 to_utf8(_(to_utf8(prettyname) + '|' + shortcut));
1973 return split(l10n_format, '|');
1979 void PrefFileformats::applyRC(LyXRC & rc) const
1981 QString const default_format = defaultFormatCB->itemData(
1982 defaultFormatCB->currentIndex()).toString();
1983 rc.default_view_format = fromqstr(default_format);
1984 QString const default_otf_format = defaultOTFFormatCB->itemData(
1985 defaultOTFFormatCB->currentIndex()).toString();
1986 rc.default_otf_view_format = fromqstr(default_otf_format);
1987 QString const default_platex_format = defaultPlatexFormatCB->itemData(
1988 defaultPlatexFormatCB->currentIndex()).toString();
1989 rc.default_platex_view_format = fromqstr(default_platex_format);
1993 void PrefFileformats::updateRC(LyXRC const & rc)
1995 viewer_alternatives = rc.viewer_alternatives;
1996 editor_alternatives = rc.editor_alternatives;
1997 bool const init = defaultFormatCB->currentText().isEmpty();
2001 defaultFormatCB->findData(toqstr(rc.default_view_format));
2002 defaultFormatCB->setCurrentIndex(pos);
2003 pos = defaultOTFFormatCB->findData(toqstr(rc.default_otf_view_format));
2004 defaultOTFFormatCB->setCurrentIndex(pos);
2005 defaultOTFFormatCB->setCurrentIndex(pos);
2006 pos = defaultPlatexFormatCB->findData(toqstr(rc.default_platex_view_format));
2007 defaultPlatexFormatCB->setCurrentIndex(pos);
2008 defaultPlatexFormatCB->setCurrentIndex(pos);
2013 void PrefFileformats::updateView()
2015 QString const current = formatsCB->currentText();
2016 QString const current_def = defaultFormatCB->currentText();
2017 QString const current_def_otf = defaultOTFFormatCB->currentText();
2018 QString const current_def_platex = defaultPlatexFormatCB->currentText();
2020 // update comboboxes with formats
2021 formatsCB->blockSignals(true);
2022 defaultFormatCB->blockSignals(true);
2023 defaultOTFFormatCB->blockSignals(true);
2024 defaultPlatexFormatCB->blockSignals(true);
2026 defaultFormatCB->clear();
2027 defaultOTFFormatCB->clear();
2028 defaultPlatexFormatCB->clear();
2029 form_->formats().sort();
2030 for (Format const & f : form_->formats()) {
2031 QString const prettyname = toqstr(translateIfPossible(f.prettyname()));
2032 formatsCB->addItem(prettyname,
2033 QVariant(form_->formats().getNumber(f.name())));
2034 if (f.viewer().empty())
2036 if (form_->converters().isReachable("xhtml", f.name())
2037 || form_->converters().isReachable("dviluatex", f.name())
2038 || form_->converters().isReachable("luatex", f.name())
2039 || form_->converters().isReachable("xetex", f.name())) {
2040 defaultFormatCB->addItem(prettyname,
2041 QVariant(toqstr(f.name())));
2042 defaultOTFFormatCB->addItem(prettyname,
2043 QVariant(toqstr(f.name())));
2045 if (form_->converters().isReachable("latex", f.name())
2046 || form_->converters().isReachable("pdflatex", f.name()))
2047 defaultFormatCB->addItem(prettyname,
2048 QVariant(toqstr(f.name())));
2049 if (form_->converters().isReachable("platex", f.name()))
2050 defaultPlatexFormatCB->addItem(prettyname,
2051 QVariant(toqstr(f.name())));
2055 // restore selections
2056 int item = formatsCB->findText(current, Qt::MatchExactly);
2057 formatsCB->setCurrentIndex(item < 0 ? 0 : item);
2058 on_formatsCB_currentIndexChanged(item < 0 ? 0 : item);
2059 item = defaultFormatCB->findText(current_def, Qt::MatchExactly);
2060 defaultFormatCB->setCurrentIndex(item < 0 ? 0 : item);
2061 item = defaultOTFFormatCB->findText(current_def_otf, Qt::MatchExactly);
2062 defaultOTFFormatCB->setCurrentIndex(item < 0 ? 0 : item);
2063 item = defaultPlatexFormatCB->findText(current_def_platex, Qt::MatchExactly);
2064 defaultPlatexFormatCB->setCurrentIndex(item < 0 ? 0 : item);
2065 formatsCB->blockSignals(false);
2066 defaultFormatCB->blockSignals(false);
2067 defaultOTFFormatCB->blockSignals(false);
2068 defaultPlatexFormatCB->blockSignals(false);
2072 void PrefFileformats::on_formatsCB_currentIndexChanged(int i)
2074 if (form_->formats().empty())
2076 int const nr = formatsCB->itemData(i).toInt();
2077 Format const f = form_->formats().get(nr);
2079 formatED->setText(toqstr(f.name()));
2080 copierED->setText(toqstr(form_->movers().command(f.name())));
2081 extensionsED->setText(toqstr(f.extensions()));
2082 mimeED->setText(toqstr(f.mime()));
2083 shortcutED->setText(
2084 toqstr(l10n_shortcut(f.prettyname(), f.shortcut())));
2085 documentCB->setChecked((f.documentFormat()));
2086 vectorCB->setChecked((f.vectorFormat()));
2087 exportMenuCB->setChecked((f.inExportMenu()));
2088 exportMenuCB->setEnabled((f.documentFormat()));
2094 void PrefFileformats::setFlags()
2096 int flags = Format::none;
2097 if (documentCB->isChecked())
2098 flags |= Format::document;
2099 if (vectorCB->isChecked())
2100 flags |= Format::vector;
2101 if (exportMenuCB->isChecked())
2102 flags |= Format::export_menu;
2103 currentFormat().setFlags(flags);
2104 exportMenuCB->setEnabled(documentCB->isChecked());
2109 void PrefFileformats::on_copierED_textEdited(const QString & s)
2111 string const fmt = fromqstr(formatED->text());
2112 form_->movers().set(fmt, fromqstr(s));
2117 void PrefFileformats::on_extensionsED_textEdited(const QString & s)
2119 currentFormat().setExtensions(fromqstr(s));
2124 void PrefFileformats::on_viewerED_textEdited(const QString & s)
2126 currentFormat().setViewer(fromqstr(s));
2131 void PrefFileformats::on_editorED_textEdited(const QString & s)
2133 currentFormat().setEditor(fromqstr(s));
2138 void PrefFileformats::on_mimeED_textEdited(const QString & s)
2140 currentFormat().setMime(fromqstr(s));
2145 void PrefFileformats::on_shortcutED_textEdited(const QString & s)
2147 string const new_shortcut = fromqstr(s);
2148 if (new_shortcut == l10n_shortcut(currentFormat().prettyname(),
2149 currentFormat().shortcut()))
2151 currentFormat().setShortcut(new_shortcut);
2156 void PrefFileformats::on_formatED_editingFinished()
2158 string const newname = fromqstr(formatED->displayText());
2159 string const oldname = currentFormat().name();
2160 if (newname == oldname)
2162 if (form_->converters().formatIsUsed(oldname)) {
2163 Alert::error(_("Format in use"),
2164 _("You cannot change a format's short name "
2165 "if the format is used by a converter. "
2166 "Please remove the converter first."));
2171 currentFormat().setName(newname);
2176 void PrefFileformats::on_formatED_textChanged(const QString &)
2178 QString t = formatED->text();
2180 bool valid = formatED->validator()->validate(t, p) == QValidator::Acceptable;
2181 setValid(formatLA, valid);
2185 void PrefFileformats::on_formatsCB_editTextChanged(const QString &)
2187 QString t = formatsCB->currentText();
2189 bool valid = formatsCB->validator()->validate(t, p) == QValidator::Acceptable;
2190 setValid(formatsLA, valid);
2194 void PrefFileformats::updatePrettyname()
2196 QString const newname = formatsCB->currentText();
2197 if (newname == toqstr(translateIfPossible(currentFormat().prettyname())))
2200 currentFormat().setPrettyname(qstring_to_ucs4(newname));
2208 void updateComboBox(LyXRC::Alternatives const & alts,
2209 string const & fmt, QComboBox * combo)
2211 LyXRC::Alternatives::const_iterator it =
2213 if (it != alts.end()) {
2214 LyXRC::CommandSet const & cmds = it->second;
2215 LyXRC::CommandSet::const_iterator sit =
2217 LyXRC::CommandSet::const_iterator const sen =
2219 for (; sit != sen; ++sit) {
2220 QString const qcmd = toqstr(*sit);
2221 combo->addItem(qcmd, qcmd);
2228 void PrefFileformats::updateViewers()
2230 Format const f = currentFormat();
2231 viewerCO->blockSignals(true);
2233 viewerCO->addItem(qt_("None"), QString());
2234 updateComboBox(viewer_alternatives, f.name(), viewerCO);
2235 viewerCO->addItem(qt_("Custom"), QString("custom viewer"));
2236 viewerCO->blockSignals(false);
2238 int pos = viewerCO->findData(toqstr(f.viewer()));
2241 viewerED->setEnabled(false);
2242 viewerCO->setCurrentIndex(pos);
2244 viewerED->setEnabled(true);
2245 viewerED->setText(toqstr(f.viewer()));
2246 viewerCO->setCurrentIndex(viewerCO->findData(toqstr("custom viewer")));
2251 void PrefFileformats::updateEditors()
2253 Format const f = currentFormat();
2254 editorCO->blockSignals(true);
2256 editorCO->addItem(qt_("None"), QString());
2257 updateComboBox(editor_alternatives, f.name(), editorCO);
2258 editorCO->addItem(qt_("Custom"), QString("custom editor"));
2259 editorCO->blockSignals(false);
2261 int pos = editorCO->findData(toqstr(f.editor()));
2264 editorED->setEnabled(false);
2265 editorCO->setCurrentIndex(pos);
2267 editorED->setEnabled(true);
2268 editorED->setText(toqstr(f.editor()));
2269 editorCO->setCurrentIndex(editorCO->findData(toqstr("custom editor")));
2274 void PrefFileformats::on_viewerCO_currentIndexChanged(int i)
2276 bool const custom = viewerCO->itemData(i).toString() == "custom viewer";
2277 viewerED->setEnabled(custom);
2279 currentFormat().setViewer(fromqstr(viewerCO->itemData(i).toString()));
2283 void PrefFileformats::on_editorCO_currentIndexChanged(int i)
2285 bool const custom = editorCO->itemData(i).toString() == "custom editor";
2286 editorED->setEnabled(custom);
2288 currentFormat().setEditor(fromqstr(editorCO->itemData(i).toString()));
2292 Format & PrefFileformats::currentFormat()
2294 int const i = formatsCB->currentIndex();
2295 int const nr = formatsCB->itemData(i).toInt();
2296 return form_->formats().get(nr);
2300 void PrefFileformats::on_formatNewPB_clicked()
2302 form_->formats().add("", "", docstring(), "", "", "", "", Format::none);
2304 formatsCB->setCurrentIndex(0);
2305 formatsCB->setFocus(Qt::OtherFocusReason);
2309 void PrefFileformats::on_formatRemovePB_clicked()
2311 int const i = formatsCB->currentIndex();
2312 int const nr = formatsCB->itemData(i).toInt();
2313 string const current_text = form_->formats().get(nr).name();
2314 if (form_->converters().formatIsUsed(current_text)) {
2315 Alert::error(_("Format in use"),
2316 _("Cannot remove a Format used by a Converter. "
2317 "Remove the converter first."));
2321 form_->formats().erase(current_text);
2324 on_formatsCB_editTextChanged(formatsCB->currentText());
2329 /////////////////////////////////////////////////////////////////////
2333 /////////////////////////////////////////////////////////////////////
2335 PrefLanguage::PrefLanguage(GuiPreferences * form)
2336 : PrefModule(catLanguage, N_("Language"), form)
2340 connect(visualCursorRB, SIGNAL(clicked()),
2341 this, SIGNAL(changed()));
2342 connect(logicalCursorRB, SIGNAL(clicked()),
2343 this, SIGNAL(changed()));
2344 connect(markForeignCB, SIGNAL(clicked()),
2345 this, SIGNAL(changed()));
2346 connect(autoBeginCB, SIGNAL(clicked()),
2347 this, SIGNAL(changed()));
2348 connect(autoEndCB, SIGNAL(clicked()),
2349 this, SIGNAL(changed()));
2350 connect(languagePackageCO, SIGNAL(activated(int)),
2351 this, SIGNAL(changed()));
2352 connect(languagePackageED, SIGNAL(textChanged(QString)),
2353 this, SIGNAL(changed()));
2354 connect(globalCB, SIGNAL(clicked()),
2355 this, SIGNAL(changed()));
2356 connect(startCommandED, SIGNAL(textChanged(QString)),
2357 this, SIGNAL(changed()));
2358 connect(endCommandED, SIGNAL(textChanged(QString)),
2359 this, SIGNAL(changed()));
2360 connect(uiLanguageCO, SIGNAL(activated(int)),
2361 this, SIGNAL(changed()));
2362 connect(defaultDecimalPointLE, SIGNAL(textChanged(QString)),
2363 this, SIGNAL(changed()));
2364 connect(defaultLengthUnitCO, SIGNAL(activated(int)),
2365 this, SIGNAL(changed()));
2367 languagePackageED->setValidator(new NoNewLineValidator(languagePackageED));
2368 startCommandED->setValidator(new NoNewLineValidator(startCommandED));
2369 endCommandED->setValidator(new NoNewLineValidator(endCommandED));
2371 defaultDecimalPointLE->setInputMask("X; ");
2372 defaultDecimalPointLE->setMaxLength(1);
2374 defaultLengthUnitCO->addItem(lyx::qt_(unit_name_gui[Length::CM]), Length::CM);
2375 defaultLengthUnitCO->addItem(lyx::qt_(unit_name_gui[Length::IN]), Length::IN);
2377 QAbstractItemModel * language_model = guiApp->languageModel();
2378 language_model->sort(0);
2379 uiLanguageCO->blockSignals(true);
2380 uiLanguageCO->clear();
2381 uiLanguageCO->addItem(qt_("Default"), toqstr("auto"));
2382 for (int i = 0; i != language_model->rowCount(); ++i) {
2383 QModelIndex index = language_model->index(i, 0);
2384 // Filter the list based on the available translation and add
2385 // each language code only once
2386 string const name = fromqstr(index.data(Qt::UserRole).toString());
2387 Language const * lang = languages.getLanguage(name);
2390 // never remove the currently selected language
2391 if (name != form->rc().gui_language
2392 && name != lyxrc.gui_language
2393 && (!Messages::available(lang->code())
2394 || !lang->hasGuiSupport()))
2396 uiLanguageCO->addItem(index.data(Qt::DisplayRole).toString(),
2397 index.data(Qt::UserRole).toString());
2399 uiLanguageCO->blockSignals(false);
2403 void PrefLanguage::on_uiLanguageCO_currentIndexChanged(int)
2405 QMessageBox::information(this, qt_("LyX needs to be restarted!"),
2406 qt_("The change of user interface language will be fully "
2407 "effective only after a restart."));
2411 void PrefLanguage::on_languagePackageCO_currentIndexChanged(int i)
2413 languagePackageED->setEnabled(i == 2);
2417 void PrefLanguage::applyRC(LyXRC & rc) const
2419 rc.visual_cursor = visualCursorRB->isChecked();
2420 rc.mark_foreign_language = markForeignCB->isChecked();
2421 rc.language_auto_begin = autoBeginCB->isChecked();
2422 rc.language_auto_end = autoEndCB->isChecked();
2423 int const p = languagePackageCO->currentIndex();
2425 rc.language_package_selection = LyXRC::LP_AUTO;
2427 rc.language_package_selection = LyXRC::LP_BABEL;
2429 rc.language_package_selection = LyXRC::LP_CUSTOM;
2431 rc.language_package_selection = LyXRC::LP_NONE;
2432 rc.language_custom_package = fromqstr(languagePackageED->text());
2433 rc.language_global_options = globalCB->isChecked();
2434 rc.language_command_begin = fromqstr(startCommandED->text());
2435 rc.language_command_end = fromqstr(endCommandED->text());
2436 rc.gui_language = fromqstr(
2437 uiLanguageCO->itemData(uiLanguageCO->currentIndex()).toString());
2438 rc.default_decimal_point = fromqstr(defaultDecimalPointLE->text());
2439 rc.default_length_unit = (Length::UNIT) defaultLengthUnitCO->itemData(defaultLengthUnitCO->currentIndex()).toInt();
2443 void PrefLanguage::updateRC(LyXRC const & rc)
2445 if (rc.visual_cursor)
2446 visualCursorRB->setChecked(true);
2448 logicalCursorRB->setChecked(true);
2449 markForeignCB->setChecked(rc.mark_foreign_language);
2450 autoBeginCB->setChecked(rc.language_auto_begin);
2451 autoEndCB->setChecked(rc.language_auto_end);
2452 languagePackageCO->setCurrentIndex(rc.language_package_selection);
2453 languagePackageED->setText(toqstr(rc.language_custom_package));
2454 languagePackageED->setEnabled(languagePackageCO->currentIndex() == 2);
2455 globalCB->setChecked(rc.language_global_options);
2456 startCommandED->setText(toqstr(rc.language_command_begin));
2457 endCommandED->setText(toqstr(rc.language_command_end));
2458 defaultDecimalPointLE->setText(toqstr(rc.default_decimal_point));
2459 int pos = defaultLengthUnitCO->findData(int(rc.default_length_unit));
2460 defaultLengthUnitCO->setCurrentIndex(pos);
2462 pos = uiLanguageCO->findData(toqstr(rc.gui_language));
2463 uiLanguageCO->blockSignals(true);
2464 uiLanguageCO->setCurrentIndex(pos);
2465 uiLanguageCO->blockSignals(false);
2469 /////////////////////////////////////////////////////////////////////
2471 // PrefUserInterface
2473 /////////////////////////////////////////////////////////////////////
2475 PrefUserInterface::PrefUserInterface(GuiPreferences * form)
2476 : PrefModule(catLookAndFeel, N_("User Interface"), form)
2480 connect(uiFilePB, SIGNAL(clicked()),
2481 this, SLOT(selectUi()));
2482 connect(uiFileED, SIGNAL(textChanged(QString)),
2483 this, SIGNAL(changed()));
2484 connect(iconSetCO, SIGNAL(activated(int)),
2485 this, SIGNAL(changed()));
2486 connect(useSystemThemeIconsCB, SIGNAL(clicked()),
2487 this, SIGNAL(changed()));
2488 connect(lastfilesSB, SIGNAL(valueChanged(int)),
2489 this, SIGNAL(changed()));
2490 connect(tooltipCB, SIGNAL(toggled(bool)),
2491 this, SIGNAL(changed()));
2492 lastfilesSB->setMaximum(maxlastfiles);
2494 iconSetCO->addItem(qt_("Default"), QString());
2495 iconSetCO->addItem(qt_("Classic"), "classic");
2496 iconSetCO->addItem(qt_("Oxygen"), "oxygen");
2498 #if (!(defined Q_WS_X11 || defined(QPA_XCB)) || QT_VERSION < 0x040600)
2499 useSystemThemeIconsCB->hide();
2504 void PrefUserInterface::applyRC(LyXRC & rc) const
2506 rc.icon_set = fromqstr(iconSetCO->itemData(
2507 iconSetCO->currentIndex()).toString());
2509 rc.ui_file = internal_path(fromqstr(uiFileED->text()));
2510 rc.use_system_theme_icons = useSystemThemeIconsCB->isChecked();
2511 rc.num_lastfiles = lastfilesSB->value();
2512 rc.use_tooltip = tooltipCB->isChecked();
2516 void PrefUserInterface::updateRC(LyXRC const & rc)
2518 int iconset = iconSetCO->findData(toqstr(rc.icon_set));
2521 iconSetCO->setCurrentIndex(iconset);
2522 useSystemThemeIconsCB->setChecked(rc.use_system_theme_icons);
2523 uiFileED->setText(toqstr(external_path(rc.ui_file)));
2524 lastfilesSB->setValue(rc.num_lastfiles);
2525 tooltipCB->setChecked(rc.use_tooltip);
2529 void PrefUserInterface::selectUi()
2531 QString file = form_->browseUI(internalPath(uiFileED->text()));
2532 if (!file.isEmpty())
2533 uiFileED->setText(file);
2537 /////////////////////////////////////////////////////////////////////
2539 // PrefDocumentHandling
2541 /////////////////////////////////////////////////////////////////////
2543 PrefDocHandling::PrefDocHandling(GuiPreferences * form)
2544 : PrefModule(catLookAndFeel, N_("Document Handling"), form)
2548 connect(autoSaveCB, SIGNAL(toggled(bool)),
2549 autoSaveSB, SLOT(setEnabled(bool)));
2550 connect(autoSaveCB, SIGNAL(toggled(bool)),
2551 TextLabel1, SLOT(setEnabled(bool)));
2552 connect(openDocumentsInTabsCB, SIGNAL(clicked()),
2553 this, SIGNAL(changed()));
2554 connect(singleInstanceCB, SIGNAL(clicked()),
2555 this, SIGNAL(changed()));
2556 connect(singleCloseTabButtonCB, SIGNAL(clicked()),
2557 this, SIGNAL(changed()));
2558 connect(closeLastViewCO, SIGNAL(activated(int)),
2559 this, SIGNAL(changed()));
2560 connect(restoreCursorCB, SIGNAL(clicked()),
2561 this, SIGNAL(changed()));
2562 connect(loadSessionCB, SIGNAL(clicked()),
2563 this, SIGNAL(changed()));
2564 connect(allowGeometrySessionCB, SIGNAL(clicked()),
2565 this, SIGNAL(changed()));
2566 connect(autoSaveSB, SIGNAL(valueChanged(int)),
2567 this, SIGNAL(changed()));
2568 connect(autoSaveCB, SIGNAL(clicked()),
2569 this, SIGNAL(changed()));
2570 connect(backupCB, SIGNAL(clicked()),
2571 this, SIGNAL(changed()));
2572 connect(saveCompressedCB, SIGNAL(clicked()),
2573 this, SIGNAL(changed()));
2574 connect(saveOriginCB, SIGNAL(clicked()),
2575 this, SIGNAL(changed()));
2579 void PrefDocHandling::applyRC(LyXRC & rc) const
2581 rc.use_lastfilepos = restoreCursorCB->isChecked();
2582 rc.load_session = loadSessionCB->isChecked();
2583 rc.allow_geometry_session = allowGeometrySessionCB->isChecked();
2584 rc.autosave = autoSaveCB->isChecked() ? autoSaveSB->value() * 60 : 0;
2585 rc.make_backup = backupCB->isChecked();
2586 rc.save_compressed = saveCompressedCB->isChecked();
2587 rc.save_origin = saveOriginCB->isChecked();
2588 rc.open_buffers_in_tabs = openDocumentsInTabsCB->isChecked();
2589 rc.single_instance = singleInstanceCB->isChecked();
2590 rc.single_close_tab_button = singleCloseTabButtonCB->isChecked();
2592 switch (closeLastViewCO->currentIndex()) {
2594 rc.close_buffer_with_last_view = "yes";
2597 rc.close_buffer_with_last_view = "no";
2600 rc.close_buffer_with_last_view = "ask";
2608 void PrefDocHandling::updateRC(LyXRC const & rc)
2610 restoreCursorCB->setChecked(rc.use_lastfilepos);
2611 loadSessionCB->setChecked(rc.load_session);
2612 allowGeometrySessionCB->setChecked(rc.allow_geometry_session);
2613 // convert to minutes
2614 bool autosave = rc.autosave > 0;
2615 int mins = rc.autosave / 60;
2618 autoSaveSB->setValue(mins);
2619 autoSaveCB->setChecked(autosave);
2620 autoSaveSB->setEnabled(autosave);
2621 backupCB->setChecked(rc.make_backup);
2622 saveCompressedCB->setChecked(rc.save_compressed);
2623 saveOriginCB->setChecked(rc.save_origin);
2624 openDocumentsInTabsCB->setChecked(rc.open_buffers_in_tabs);
2625 singleInstanceCB->setChecked(rc.single_instance && !rc.lyxpipes.empty());
2626 singleInstanceCB->setEnabled(!rc.lyxpipes.empty());
2627 singleCloseTabButtonCB->setChecked(rc.single_close_tab_button);
2628 if (rc.close_buffer_with_last_view == "yes")
2629 closeLastViewCO->setCurrentIndex(0);
2630 else if (rc.close_buffer_with_last_view == "no")
2631 closeLastViewCO->setCurrentIndex(1);
2632 else if (rc.close_buffer_with_last_view == "ask")
2633 closeLastViewCO->setCurrentIndex(2);
2637 void PrefDocHandling::on_clearSessionPB_clicked()
2639 guiApp->clearSession();
2644 /////////////////////////////////////////////////////////////////////
2648 /////////////////////////////////////////////////////////////////////
2650 PrefEdit::PrefEdit(GuiPreferences * form)
2651 : PrefModule(catEditing, N_("Control"), form)
2655 connect(cursorFollowsCB, SIGNAL(clicked()),
2656 this, SIGNAL(changed()));
2657 connect(scrollBelowCB, SIGNAL(clicked()),
2658 this, SIGNAL(changed()));
2659 connect(macLikeCursorMovementCB, SIGNAL(clicked()),
2660 this, SIGNAL(changed()));
2661 connect(sortEnvironmentsCB, SIGNAL(clicked()),
2662 this, SIGNAL(changed()));
2663 connect(groupEnvironmentsCB, SIGNAL(clicked()),
2664 this, SIGNAL(changed()));
2665 connect(macroEditStyleCO, SIGNAL(activated(int)),
2666 this, SIGNAL(changed()));
2667 connect(cursorWidthSB, SIGNAL(valueChanged(int)),
2668 this, SIGNAL(changed()));
2669 connect(fullscreenLimitGB, SIGNAL(clicked()),
2670 this, SIGNAL(changed()));
2671 connect(fullscreenWidthSB, SIGNAL(valueChanged(int)),
2672 this, SIGNAL(changed()));
2673 connect(toggleTabbarCB, SIGNAL(toggled(bool)),
2674 this, SIGNAL(changed()));
2675 connect(toggleMenubarCB, SIGNAL(toggled(bool)),
2676 this, SIGNAL(changed()));
2677 connect(toggleScrollbarCB, SIGNAL(toggled(bool)),
2678 this, SIGNAL(changed()));
2679 connect(toggleStatusbarCB, SIGNAL(toggled(bool)),
2680 this, SIGNAL(changed()));
2681 connect(toggleToolbarsCB, SIGNAL(toggled(bool)),
2682 this, SIGNAL(changed()));
2686 void PrefEdit::applyRC(LyXRC & rc) const
2688 rc.cursor_follows_scrollbar = cursorFollowsCB->isChecked();
2689 rc.scroll_below_document = scrollBelowCB->isChecked();
2690 rc.mac_like_cursor_movement = macLikeCursorMovementCB->isChecked();
2691 rc.sort_layouts = sortEnvironmentsCB->isChecked();
2692 rc.group_layouts = groupEnvironmentsCB->isChecked();
2693 switch (macroEditStyleCO->currentIndex()) {
2694 case 0: rc.macro_edit_style = LyXRC::MACRO_EDIT_INLINE_BOX; break;
2695 case 1: rc.macro_edit_style = LyXRC::MACRO_EDIT_INLINE; break;
2696 case 2: rc.macro_edit_style = LyXRC::MACRO_EDIT_LIST; break;
2698 rc.cursor_width = cursorWidthSB->value();
2699 rc.full_screen_toolbars = toggleToolbarsCB->isChecked();
2700 rc.full_screen_scrollbar = toggleScrollbarCB->isChecked();
2701 rc.full_screen_statusbar = toggleStatusbarCB->isChecked();
2702 rc.full_screen_tabbar = toggleTabbarCB->isChecked();
2703 rc.full_screen_menubar = toggleMenubarCB->isChecked();
2704 rc.full_screen_width = fullscreenWidthSB->value();
2705 rc.full_screen_limit = fullscreenLimitGB->isChecked();
2709 void PrefEdit::updateRC(LyXRC const & rc)
2711 cursorFollowsCB->setChecked(rc.cursor_follows_scrollbar);
2712 scrollBelowCB->setChecked(rc.scroll_below_document);
2713 macLikeCursorMovementCB->setChecked(rc.mac_like_cursor_movement);
2714 sortEnvironmentsCB->setChecked(rc.sort_layouts);
2715 groupEnvironmentsCB->setChecked(rc.group_layouts);
2716 macroEditStyleCO->setCurrentIndex(rc.macro_edit_style);
2717 cursorWidthSB->setValue(rc.cursor_width);
2718 toggleScrollbarCB->setChecked(rc.full_screen_scrollbar);
2719 toggleStatusbarCB->setChecked(rc.full_screen_statusbar);
2720 toggleToolbarsCB->setChecked(rc.full_screen_toolbars);
2721 toggleTabbarCB->setChecked(rc.full_screen_tabbar);
2722 toggleMenubarCB->setChecked(rc.full_screen_menubar);
2723 fullscreenWidthSB->setValue(rc.full_screen_width);
2724 fullscreenLimitGB->setChecked(rc.full_screen_limit);
2728 /////////////////////////////////////////////////////////////////////
2732 /////////////////////////////////////////////////////////////////////
2735 GuiShortcutDialog::GuiShortcutDialog(QWidget * parent) : QDialog(parent)
2737 Ui::shortcutUi::setupUi(this);
2738 QDialog::setModal(true);
2742 PrefShortcuts::PrefShortcuts(GuiPreferences * form)
2743 : PrefModule(catEditing, N_("Shortcuts"), form),
2744 editItem_(0), mathItem_(0), bufferItem_(0), layoutItem_(0),
2749 shortcutsTW->setColumnCount(2);
2750 shortcutsTW->headerItem()->setText(0, qt_("Function"));
2751 shortcutsTW->headerItem()->setText(1, qt_("Shortcut"));
2752 shortcutsTW->setSortingEnabled(true);
2753 // Multi-selection can be annoying.
2754 // shortcutsTW->setSelectionMode(QAbstractItemView::MultiSelection);
2756 connect(bindFilePB, SIGNAL(clicked()),
2757 this, SLOT(selectBind()));
2758 connect(bindFileED, SIGNAL(textChanged(QString)),
2759 this, SIGNAL(changed()));
2761 shortcut_ = new GuiShortcutDialog(this);
2762 shortcut_bc_.setPolicy(ButtonPolicy::OkCancelPolicy);
2763 shortcut_bc_.setOK(shortcut_->buttonBox->button(QDialogButtonBox::Ok));
2764 shortcut_bc_.setCancel(shortcut_->buttonBox->button(QDialogButtonBox::Cancel));
2766 connect(shortcut_->buttonBox, SIGNAL(accepted()),
2767 this, SIGNAL(changed()));
2768 connect(shortcut_->buttonBox, SIGNAL(rejected()),
2769 shortcut_, SLOT(reject()));
2770 connect(shortcut_->clearPB, SIGNAL(clicked()),
2771 this, SLOT(shortcutClearPressed()));
2772 connect(shortcut_->removePB, SIGNAL(clicked()),
2773 this, SLOT(shortcutRemovePressed()));
2774 connect(shortcut_->buttonBox, SIGNAL(accepted()),
2775 this, SLOT(shortcutOkPressed()));
2776 connect(shortcut_->buttonBox, SIGNAL(rejected()),
2777 this, SLOT(shortcutCancelPressed()));
2781 void PrefShortcuts::applyRC(LyXRC & rc) const
2783 rc.bind_file = internal_path(fromqstr(bindFileED->text()));
2784 // write user_bind and user_unbind to .lyx/bind/user.bind
2785 FileName bind_dir(addPath(package().user_support().absFileName(), "bind"));
2786 if (!bind_dir.exists() && !bind_dir.createDirectory(0777)) {
2787 lyxerr << "LyX could not create the user bind directory '"
2788 << bind_dir << "'. All user-defined key bindings will be lost." << endl;
2791 if (!bind_dir.isDirWritable()) {
2792 lyxerr << "LyX could not write to the user bind directory '"
2793 << bind_dir << "'. All user-defined key bindings will be lost." << endl;
2796 FileName user_bind_file(bind_dir.absFileName() + "/user.bind");
2797 user_unbind_.write(user_bind_file.toFilesystemEncoding(), false, true);
2798 user_bind_.write(user_bind_file.toFilesystemEncoding(), true, false);
2799 // immediately apply the keybindings. Why this is not done before?
2800 // The good thing is that the menus are updated automatically.
2801 theTopLevelKeymap().clear();
2802 theTopLevelKeymap().read("site");
2803 theTopLevelKeymap().read(rc.bind_file, 0, KeyMap::Fallback);
2804 theTopLevelKeymap().read("user", 0, KeyMap::MissingOK);
2808 void PrefShortcuts::updateRC(LyXRC const & rc)
2810 bindFileED->setText(toqstr(external_path(rc.bind_file)));
2812 system_bind_.clear();
2814 user_unbind_.clear();
2815 system_bind_.read("site");
2816 system_bind_.read(rc.bind_file);
2817 // \unbind in user.bind is added to user_unbind_
2818 user_bind_.read("user", &user_unbind_, KeyMap::MissingOK);
2819 updateShortcutsTW();
2823 void PrefShortcuts::updateShortcutsTW()
2825 shortcutsTW->clear();
2827 editItem_ = new QTreeWidgetItem(shortcutsTW);
2828 editItem_->setText(0, qt_("Cursor, Mouse and Editing Functions"));
2829 editItem_->setFlags(editItem_->flags() & ~Qt::ItemIsSelectable);
2831 mathItem_ = new QTreeWidgetItem(shortcutsTW);
2832 mathItem_->setText(0, qt_("Mathematical Symbols"));
2833 mathItem_->setFlags(mathItem_->flags() & ~Qt::ItemIsSelectable);
2835 bufferItem_ = new QTreeWidgetItem(shortcutsTW);
2836 bufferItem_->setText(0, qt_("Document and Window"));
2837 bufferItem_->setFlags(bufferItem_->flags() & ~Qt::ItemIsSelectable);
2839 layoutItem_ = new QTreeWidgetItem(shortcutsTW);
2840 layoutItem_->setText(0, qt_("Font, Layouts and Textclasses"));
2841 layoutItem_->setFlags(layoutItem_->flags() & ~Qt::ItemIsSelectable);
2843 systemItem_ = new QTreeWidgetItem(shortcutsTW);
2844 systemItem_->setText(0, qt_("System and Miscellaneous"));
2845 systemItem_->setFlags(systemItem_->flags() & ~Qt::ItemIsSelectable);
2847 // listBindings(unbound=true) lists all bound and unbound lfuns
2848 // Items in this list is tagged by its source.
2849 KeyMap::BindingList bindinglist = system_bind_.listBindings(true,
2851 KeyMap::BindingList user_bindinglist = user_bind_.listBindings(false,
2853 KeyMap::BindingList user_unbindinglist = user_unbind_.listBindings(false,
2854 KeyMap::UserUnbind);
2855 bindinglist.insert(bindinglist.end(), user_bindinglist.begin(),
2856 user_bindinglist.end());
2857 bindinglist.insert(bindinglist.end(), user_unbindinglist.begin(),
2858 user_unbindinglist.end());
2860 KeyMap::BindingList::const_iterator it = bindinglist.begin();
2861 KeyMap::BindingList::const_iterator it_end = bindinglist.end();
2862 for (; it != it_end; ++it)
2863 insertShortcutItem(it->request, it->sequence, it->tag);
2865 shortcutsTW->sortItems(0, Qt::AscendingOrder);
2866 on_shortcutsTW_itemSelectionChanged();
2867 on_searchLE_textEdited();
2868 shortcutsTW->resizeColumnToContents(0);
2873 KeyMap::ItemType PrefShortcuts::itemType(QTreeWidgetItem & item)
2875 return static_cast<KeyMap::ItemType>(item.data(0, Qt::UserRole).toInt());
2880 bool PrefShortcuts::isAlwaysHidden(QTreeWidgetItem & item)
2882 // Hide rebound system settings that are empty
2883 return itemType(item) == KeyMap::UserUnbind && item.text(1).isEmpty();
2887 void PrefShortcuts::setItemType(QTreeWidgetItem * item, KeyMap::ItemType tag)
2889 item->setData(0, Qt::UserRole, QVariant(tag));
2893 case KeyMap::System:
2895 case KeyMap::UserBind:
2898 case KeyMap::UserUnbind:
2899 font.setStrikeOut(true);
2901 // this item is not displayed now.
2902 case KeyMap::UserExtraUnbind:
2903 font.setStrikeOut(true);
2906 item->setHidden(isAlwaysHidden(*item));
2907 item->setFont(1, font);
2911 QTreeWidgetItem * PrefShortcuts::insertShortcutItem(FuncRequest const & lfun,
2912 KeySequence const & seq, KeyMap::ItemType tag)
2914 FuncCode const action = lfun.action();
2915 string const action_name = lyxaction.getActionName(action);
2916 QString const lfun_name = toqstr(from_utf8(action_name)
2917 + ' ' + lfun.argument());
2918 QString const shortcut = toqstr(seq.print(KeySequence::ForGui));
2920 QTreeWidgetItem * newItem = 0;
2921 // for unbind items, try to find an existing item in the system bind list
2922 if (tag == KeyMap::UserUnbind) {
2923 QList<QTreeWidgetItem*> const items = shortcutsTW->findItems(lfun_name,
2924 Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 0);
2925 for (int i = 0; i < items.size(); ++i) {
2926 if (items[i]->text(1) == shortcut) {
2931 // if not found, this unbind item is KeyMap::UserExtraUnbind
2932 // Such an item is not displayed to avoid confusion (what is
2933 // unmatched removed?).
2939 switch(lyxaction.getActionType(action)) {
2940 case LyXAction::Hidden:
2942 case LyXAction::Edit:
2943 newItem = new QTreeWidgetItem(editItem_);
2945 case LyXAction::Math:
2946 newItem = new QTreeWidgetItem(mathItem_);
2948 case LyXAction::Buffer:
2949 newItem = new QTreeWidgetItem(bufferItem_);
2951 case LyXAction::Layout:
2952 newItem = new QTreeWidgetItem(layoutItem_);
2954 case LyXAction::System:
2955 newItem = new QTreeWidgetItem(systemItem_);
2958 // this should not happen
2959 newItem = new QTreeWidgetItem(shortcutsTW);
2963 newItem->setText(0, lfun_name);
2964 newItem->setText(1, shortcut);
2965 // record BindFile representation to recover KeySequence when needed.
2966 newItem->setData(1, Qt::UserRole, toqstr(seq.print(KeySequence::BindFile)));
2967 setItemType(newItem, tag);
2972 void PrefShortcuts::on_shortcutsTW_itemSelectionChanged()
2974 QList<QTreeWidgetItem*> items = shortcutsTW->selectedItems();
2975 removePB->setEnabled(!items.isEmpty() && !items[0]->text(1).isEmpty());
2976 modifyPB->setEnabled(!items.isEmpty());
2977 if (items.isEmpty())
2980 if (itemType(*items[0]) == KeyMap::UserUnbind)
2981 removePB->setText(qt_("Res&tore"));
2983 removePB->setText(qt_("Remo&ve"));
2987 void PrefShortcuts::on_shortcutsTW_itemDoubleClicked()
2993 void PrefShortcuts::modifyShortcut()
2995 QTreeWidgetItem * item = shortcutsTW->currentItem();
2996 if (item->flags() & Qt::ItemIsSelectable) {
2997 shortcut_->lfunLE->setText(item->text(0));
2998 save_lfun_ = item->text(0).trimmed();
2999 shortcut_->shortcutWG->setText(item->text(1));
3001 seq.parse(fromqstr(item->data(1, Qt::UserRole).toString()));
3002 shortcut_->shortcutWG->setKeySequence(seq);
3003 shortcut_->shortcutWG->setFocus();
3009 void PrefShortcuts::unhideEmpty(QString const & lfun, bool select)
3011 // list of items that match lfun
3012 QList<QTreeWidgetItem*> items = shortcutsTW->findItems(lfun,
3013 Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 0);
3014 for (int i = 0; i < items.size(); ++i) {
3015 QTreeWidgetItem * item = items[i];
3016 if (isAlwaysHidden(*item)) {
3017 setItemType(item, KeyMap::System);
3019 shortcutsTW->setCurrentItem(item);
3026 void PrefShortcuts::removeShortcut()
3028 // it seems that only one item can be selected, but I am
3029 // removing all selected items anyway.
3030 QList<QTreeWidgetItem*> items = shortcutsTW->selectedItems();
3031 for (int i = 0; i < items.size(); ++i) {
3032 string shortcut = fromqstr(items[i]->data(1, Qt::UserRole).toString());
3033 string lfun = fromqstr(items[i]->text(0));
3034 FuncRequest func = lyxaction.lookupFunc(lfun);
3036 switch (itemType(*items[i])) {
3037 case KeyMap::System: {
3038 // for system bind, we do not touch the item
3039 // but add an user unbind item
3040 user_unbind_.bind(shortcut, func);
3041 setItemType(items[i], KeyMap::UserUnbind);
3042 removePB->setText(qt_("Res&tore"));
3045 case KeyMap::UserBind: {
3046 // for user_bind, we remove this bind
3047 QTreeWidgetItem * parent = items[i]->parent();
3048 int itemIdx = parent->indexOfChild(items[i]);
3049 parent->takeChild(itemIdx);
3051 shortcutsTW->scrollToItem(parent->child(itemIdx - 1));
3053 shortcutsTW->scrollToItem(parent);
3054 user_bind_.unbind(shortcut, func);
3055 // If this user binding hid an empty system binding, unhide the
3056 // latter and select it.
3057 unhideEmpty(items[i]->text(0), true);
3060 case KeyMap::UserUnbind: {
3061 // for user_unbind, we remove the unbind, and the item
3062 // become KeyMap::System again.
3064 seq.parse(shortcut);
3065 // Ask the user to replace current binding
3066 if (!validateNewShortcut(func, seq, QString()))
3068 user_unbind_.unbind(shortcut, func);
3069 setItemType(items[i], KeyMap::System);
3070 removePB->setText(qt_("Remo&ve"));
3073 case KeyMap::UserExtraUnbind: {
3074 // for user unbind that is not in system bind file,
3075 // remove this unbind file
3076 QTreeWidgetItem * parent = items[i]->parent();
3077 parent->takeChild(parent->indexOfChild(items[i]));
3078 user_unbind_.unbind(shortcut, func);
3085 void PrefShortcuts::deactivateShortcuts(QList<QTreeWidgetItem*> const & items)
3087 for (int i = 0; i < items.size(); ++i) {
3088 string shortcut = fromqstr(items[i]->data(1, Qt::UserRole).toString());
3089 string lfun = fromqstr(items[i]->text(0));
3090 FuncRequest func = lyxaction.lookupFunc(lfun);
3092 switch (itemType(*items[i])) {
3093 case KeyMap::System:
3094 // for system bind, we do not touch the item
3095 // but add an user unbind item
3096 user_unbind_.bind(shortcut, func);
3097 setItemType(items[i], KeyMap::UserUnbind);
3100 case KeyMap::UserBind: {
3101 // for user_bind, we remove this bind
3102 QTreeWidgetItem * parent = items[i]->parent();
3103 int itemIdx = parent->indexOfChild(items[i]);
3104 parent->takeChild(itemIdx);
3105 user_bind_.unbind(shortcut, func);
3106 unhideEmpty(items[i]->text(0), false);
3116 void PrefShortcuts::selectBind()
3118 QString file = form_->browsebind(internalPath(bindFileED->text()));
3119 if (!file.isEmpty()) {
3120 bindFileED->setText(file);
3121 system_bind_ = KeyMap();
3122 system_bind_.read(fromqstr(file));
3123 updateShortcutsTW();
3128 void PrefShortcuts::on_modifyPB_pressed()
3134 void PrefShortcuts::on_newPB_pressed()
3136 shortcut_->lfunLE->clear();
3137 shortcut_->shortcutWG->reset();
3138 save_lfun_ = QString();
3143 void PrefShortcuts::on_removePB_pressed()
3150 void PrefShortcuts::on_searchLE_textEdited()
3152 if (searchLE->text().isEmpty()) {
3153 // show all hidden items
3154 QTreeWidgetItemIterator it(shortcutsTW, QTreeWidgetItemIterator::Hidden);
3156 shortcutsTW->setItemHidden(*it, isAlwaysHidden(**it));
3157 // close all categories
3158 for (int i = 0; i < shortcutsTW->topLevelItemCount(); ++i)
3159 shortcutsTW->collapseItem(shortcutsTW->topLevelItem(i));
3162 // search both columns
3163 QList<QTreeWidgetItem *> matched = shortcutsTW->findItems(searchLE->text(),
3164 Qt::MatchFlags(Qt::MatchContains | Qt::MatchRecursive), 0);
3165 matched += shortcutsTW->findItems(searchLE->text(),
3166 Qt::MatchFlags(Qt::MatchContains | Qt::MatchRecursive), 1);
3168 // hide everyone (to avoid searching in matched QList repeatedly
3169 QTreeWidgetItemIterator it(shortcutsTW, QTreeWidgetItemIterator::Selectable);
3171 shortcutsTW->setItemHidden(*it++, true);
3172 // show matched items
3173 for (int i = 0; i < matched.size(); ++i)
3174 if (!isAlwaysHidden(*matched[i])) {
3175 shortcutsTW->setItemHidden(matched[i], false);
3176 shortcutsTW->setItemExpanded(matched[i]->parent(), true);
3181 docstring makeCmdString(FuncRequest const & f)
3183 docstring actionStr = from_ascii(lyxaction.getActionName(f.action()));
3184 if (!f.argument().empty())
3185 actionStr += " " + f.argument();
3190 FuncRequest PrefShortcuts::currentBinding(KeySequence const & k)
3192 FuncRequest res = user_bind_.getBinding(k);
3193 if (res.action() != LFUN_UNKNOWN_ACTION)
3195 res = system_bind_.getBinding(k);
3196 // Check if it is unbound. Note: user_unbind_ can only unbind one
3197 // FuncRequest per key sequence.
3198 if (user_unbind_.getBinding(k) == res)
3199 return FuncRequest::unknown;
3204 bool PrefShortcuts::validateNewShortcut(FuncRequest const & func,
3205 KeySequence const & k,
3206 QString const & lfun_to_modify)
3208 if (func.action() == LFUN_UNKNOWN_ACTION) {
3209 Alert::error(_("Failed to create shortcut"),
3210 _("Unknown or invalid LyX function"));
3214 // It is not currently possible to bind Hidden lfuns such as self-insert. In
3215 // the future, to remove this limitation, see GuiPrefs::insertShortcutItem
3216 // and how it is used in GuiPrefs::shortcutOkPressed.
3217 if (lyxaction.getActionType(func.action()) == LyXAction::Hidden) {
3218 Alert::error(_("Failed to create shortcut"),
3219 _("This LyX function is hidden and cannot be bound."));
3223 if (k.length() == 0) {
3224 Alert::error(_("Failed to create shortcut"),
3225 _("Invalid or empty key sequence"));
3229 FuncRequest oldBinding = currentBinding(k);
3230 if (oldBinding == func)
3231 // nothing to change
3234 // make sure this key isn't already bound---and, if so, prompt user
3235 // (exclude the lfun the user already wants to modify)
3236 docstring const action_string = makeCmdString(oldBinding);
3237 if (oldBinding.action() != LFUN_UNKNOWN_ACTION
3238 && lfun_to_modify != toqstr(action_string)) {
3239 docstring const new_action_string = makeCmdString(func);
3240 docstring const text = bformat(_("Shortcut `%1$s' is already bound to "
3242 "Are you sure you want to unbind the "
3243 "current shortcut and bind it to %3$s?"),
3244 k.print(KeySequence::ForGui), action_string,
3246 int ret = Alert::prompt(_("Redefine shortcut?"),
3247 text, 0, 1, _("&Redefine"), _("&Cancel"));
3250 QString const sequence_text = toqstr(k.print(KeySequence::ForGui));
3251 QList<QTreeWidgetItem*> items = shortcutsTW->findItems(sequence_text,
3252 Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 1);
3253 deactivateShortcuts(items);
3259 void PrefShortcuts::shortcutOkPressed()
3261 QString const new_lfun = shortcut_->lfunLE->text();
3262 FuncRequest func = lyxaction.lookupFunc(fromqstr(new_lfun));
3263 KeySequence k = shortcut_->shortcutWG->getKeySequence();
3265 // save_lfun_ contains the text of the lfun to modify, if the user clicked
3266 // "modify", or is empty if they clicked "new" (which I do not really like)
3267 if (!validateNewShortcut(func, k, save_lfun_))
3270 if (!save_lfun_.isEmpty()) {
3271 // real modification of the lfun's shortcut,
3272 // so remove the previous one
3273 QList<QTreeWidgetItem*> to_modify = shortcutsTW->selectedItems();
3274 deactivateShortcuts(to_modify);
3277 shortcut_->accept();
3279 QTreeWidgetItem * item = insertShortcutItem(func, k, KeyMap::UserBind);
3281 user_bind_.bind(&k, func);
3282 shortcutsTW->sortItems(0, Qt::AscendingOrder);
3283 shortcutsTW->setItemExpanded(item->parent(), true);
3284 shortcutsTW->setCurrentItem(item);
3285 shortcutsTW->scrollToItem(item);
3287 Alert::error(_("Failed to create shortcut"),
3288 _("Can not insert shortcut to the list"));
3294 void PrefShortcuts::shortcutCancelPressed()
3296 shortcut_->shortcutWG->reset();
3300 void PrefShortcuts::shortcutClearPressed()
3302 shortcut_->shortcutWG->reset();
3306 void PrefShortcuts::shortcutRemovePressed()
3308 shortcut_->shortcutWG->removeFromSequence();
3312 /////////////////////////////////////////////////////////////////////
3316 /////////////////////////////////////////////////////////////////////
3318 PrefIdentity::PrefIdentity(GuiPreferences * form)
3319 : PrefModule(QString(), N_("Identity"), form)
3323 connect(nameED, SIGNAL(textChanged(QString)),
3324 this, SIGNAL(changed()));
3325 connect(emailED, SIGNAL(textChanged(QString)),
3326 this, SIGNAL(changed()));
3328 nameED->setValidator(new NoNewLineValidator(nameED));
3329 emailED->setValidator(new NoNewLineValidator(emailED));
3333 void PrefIdentity::applyRC(LyXRC & rc) const
3335 rc.user_name = fromqstr(nameED->text());
3336 rc.user_email = fromqstr(emailED->text());
3340 void PrefIdentity::updateRC(LyXRC const & rc)
3342 nameED->setText(toqstr(rc.user_name));
3343 emailED->setText(toqstr(rc.user_email));
3348 /////////////////////////////////////////////////////////////////////
3352 /////////////////////////////////////////////////////////////////////
3354 GuiPreferences::GuiPreferences(GuiView & lv)
3355 : GuiDialog(lv, "prefs", qt_("Preferences")), update_screen_font_(false),
3356 update_previews_(false)
3360 QDialog::setModal(false);
3362 connect(buttonBox, SIGNAL(clicked(QAbstractButton *)),
3363 this, SLOT(slotButtonBox(QAbstractButton *)));
3365 addModule(new PrefUserInterface(this));
3366 addModule(new PrefDocHandling(this));
3367 addModule(new PrefEdit(this));
3368 addModule(new PrefShortcuts(this));
3369 PrefScreenFonts * screenfonts = new PrefScreenFonts(this);
3370 connect(this, SIGNAL(prefsApplied(LyXRC const &)),
3371 screenfonts, SLOT(updateScreenFontSizes(LyXRC const &)));
3372 addModule(screenfonts);
3373 addModule(new PrefColors(this));
3374 addModule(new PrefDisplay(this));
3375 addModule(new PrefInput(this));
3376 addModule(new PrefCompletion(this));
3378 addModule(new PrefPaths(this));
3380 addModule(new PrefIdentity(this));
3382 addModule(new PrefLanguage(this));
3383 addModule(new PrefSpellchecker(this));
3385 PrefOutput * output = new PrefOutput(this);
3387 addModule(new PrefLatex(this));
3389 PrefConverters * converters = new PrefConverters(this);
3390 PrefFileformats * formats = new PrefFileformats(this);
3391 connect(formats, SIGNAL(formatsChanged()),
3392 converters, SLOT(updateGui()));
3393 addModule(converters);
3396 prefsPS->setCurrentPanel("User Interface");
3397 // FIXME: hack to work around resizing bug in Qt >= 4.2
3398 // bug verified with Qt 4.2.{0-3} (JSpitzm)
3399 #if QT_VERSION >= 0x040200
3400 prefsPS->updateGeometry();
3403 bc().setPolicy(ButtonPolicy::PreferencesPolicy);
3404 bc().setOK(buttonBox->button(QDialogButtonBox::Ok));
3405 bc().setApply(buttonBox->button(QDialogButtonBox::Apply));
3406 bc().setCancel(buttonBox->button(QDialogButtonBox::Cancel));
3407 bc().setRestore(buttonBox->button(QDialogButtonBox::Reset));
3411 void GuiPreferences::addModule(PrefModule * module)
3413 LASSERT(module, return);
3414 if (module->category().isEmpty())
3415 prefsPS->addPanel(module, module->title());
3417 prefsPS->addPanel(module, module->title(), module->category());
3418 connect(module, SIGNAL(changed()), this, SLOT(change_adaptor()));
3419 modules_.push_back(module);
3423 void GuiPreferences::change_adaptor()
3429 void GuiPreferences::applyRC(LyXRC & rc) const
3431 size_t end = modules_.size();
3432 for (size_t i = 0; i != end; ++i)
3433 modules_[i]->applyRC(rc);
3437 void GuiPreferences::updateRC(LyXRC const & rc)
3439 size_t const end = modules_.size();
3440 for (size_t i = 0; i != end; ++i)
3441 modules_[i]->updateRC(rc);
3445 void GuiPreferences::applyView()
3451 bool GuiPreferences::initialiseParams(string const &)
3454 formats_ = theFormats();
3455 converters_ = theConverters();
3456 converters_.update(formats_);
3457 movers_ = theMovers();
3459 update_screen_font_ = false;
3460 update_previews_ = false;
3463 // Make sure that the bc is in the INITIAL state
3464 if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
3471 void GuiPreferences::dispatchParams()
3474 rc_.write(ss, true);
3475 dispatch(FuncRequest(LFUN_LYXRC_APPLY, ss.str()));
3476 // issue prefsApplied signal. This will update the
3477 // localized screen font sizes.
3479 // FIXME: these need lfuns
3481 Author const & author =
3482 Author(from_utf8(rc_.user_name), from_utf8(rc_.user_email));
3483 theBufferList().recordCurrentAuthor(author);
3485 theFormats() = formats_;
3487 theConverters() = converters_;
3488 theConverters().update(formats_);
3489 theConverters().buildGraph();
3490 theBufferList().invalidateConverterCache();
3492 theMovers() = movers_;
3494 vector<string>::const_iterator it = colors_.begin();
3495 vector<string>::const_iterator const end = colors_.end();
3496 for (; it != end; ++it)
3497 dispatch(FuncRequest(LFUN_SET_COLOR, *it));
3500 if (update_screen_font_) {
3501 dispatch(FuncRequest(LFUN_SCREEN_FONT_UPDATE));
3502 // resets flag in case second apply in same dialog
3503 update_screen_font_ = false;
3506 if (update_previews_) {
3507 // resets flag in case second apply in same dialog
3508 theBufferList().updatePreviews();
3509 update_previews_ = false;
3513 if (!tempSaveCB->isChecked())
3514 dispatch(FuncRequest(LFUN_PREFERENCES_SAVE));
3518 void GuiPreferences::setColor(ColorCode col, QString const & hex)
3520 colors_.push_back(lcolor.getLyXName(col) + ' ' + fromqstr(hex));
3524 void GuiPreferences::updateScreenFonts()
3526 update_screen_font_ = true;
3530 void GuiPreferences::updatePreviews()
3532 update_previews_ = true;
3536 QString GuiPreferences::browsebind(QString const & file) const
3538 return browseLibFile("bind", file, "bind", qt_("Choose bind file"),
3539 QStringList(qt_("LyX bind files (*.bind)")));
3543 QString GuiPreferences::browseUI(QString const & file) const
3545 return browseLibFile("ui", file, "ui", qt_("Choose UI file"),
3546 QStringList(qt_("LyX UI files (*.ui)")));
3550 QString GuiPreferences::browsekbmap(QString const & file) const
3552 return browseLibFile("kbd", file, "kmap", qt_("Choose keyboard map"),
3553 QStringList(qt_("LyX keyboard maps (*.kmap)")));
3557 QString GuiPreferences::browse(QString const & file,
3558 QString const & title) const
3560 return browseFile(file, title, QStringList(), true);
3564 Dialog * createGuiPreferences(GuiView & lv) { return new GuiPreferences(lv); }
3567 } // namespace frontend
3570 #include "moc_GuiPrefs.cpp"