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 <QPixmapCache>
65 #include <QPushButton>
68 #include <QTreeWidget>
69 #include <QTreeWidgetItem>
80 using namespace lyx::support;
81 using namespace lyx::support::os;
86 /////////////////////////////////////////////////////////////////////
90 /////////////////////////////////////////////////////////////////////
92 /** Launch a file dialog and return the chosen file.
93 filename: a suggested filename.
94 title: the title of the dialog.
96 dir1 = (name, dir), dir2 = (name, dir): extra buttons on the dialog.
98 QString browseFile(QString const & filename,
99 QString const & title,
100 QStringList const & filters,
102 QString const & label1 = QString(),
103 QString const & dir1 = QString(),
104 QString const & label2 = QString(),
105 QString const & dir2 = QString(),
106 QString const & fallback_dir = QString())
108 QString lastPath = ".";
109 if (!filename.isEmpty())
110 lastPath = onlyPath(filename);
111 else if(!fallback_dir.isEmpty())
112 lastPath = fallback_dir;
114 FileDialog dlg(title);
115 dlg.setButton1(label1, dir1);
116 dlg.setButton2(label2, dir2);
118 FileDialog::Result result;
121 result = dlg.save(lastPath, filters, onlyFileName(filename));
123 result = dlg.open(lastPath, filters, onlyFileName(filename));
125 return result.second;
129 /** Wrapper around browseFile which tries to provide a filename
130 * relative to the user or system directory. The dir, name and ext
131 * parameters have the same meaning as in the
132 * support::LibFileSearch function.
134 QString browseLibFile(QString const & dir,
135 QString const & name,
137 QString const & title,
138 QStringList const & filters)
141 QString const label1 = qt_("&System files");
143 toqstr(addName(package().system_support().absFileName(), fromqstr(dir)));
145 QString const label2 = qt_("&User files");
147 toqstr(addName(package().user_support().absFileName(), fromqstr(dir)));
149 QString const result = browseFile(toqstr(
150 libFileSearch(dir, name, ext).absFileName()),
151 title, filters, false, dir1, dir2, QString(), QString(), dir1);
153 // remove the extension if it is the default one
155 if (getExtension(result) == ext)
156 noextresult = removeExtension(result);
158 noextresult = result;
160 // remove the directory, if it is the default one
161 QString const file = onlyFileName(noextresult);
162 if (toqstr(libFileSearch(dir, file, ext).absFileName()) == result)
169 /** Launch a file dialog and return the chosen directory.
170 pathname: a suggested pathname.
171 title: the title of the dialog.
172 dir1 = (name, dir), dir2 = (name, dir): extra buttons on the dialog.
174 QString browseDir(QString const & pathname,
175 QString const & title,
176 QString const & label1 = QString(),
177 QString const & dir1 = QString(),
178 QString const & label2 = QString(),
179 QString const & dir2 = QString())
181 QString lastPath = ".";
182 if (!pathname.isEmpty())
183 lastPath = onlyPath(pathname);
185 FileDialog dlg(title);
186 dlg.setButton1(label1, dir1);
187 dlg.setButton2(label2, dir2);
189 FileDialog::Result const result =
190 dlg.opendir(lastPath, onlyFileName(pathname));
192 return result.second;
196 } // namespace frontend
199 QString browseRelToParent(QString const & filename, QString const & relpath,
200 QString const & title, QStringList const & filters, bool save,
201 QString const & label1, QString const & dir1,
202 QString const & label2, QString const & dir2)
204 QString const fname = makeAbsPath(filename, relpath);
206 QString const outname =
207 frontend::browseFile(fname, title, filters, save, label1, dir1, label2, dir2);
209 QString const reloutname =
210 toqstr(makeRelPath(qstring_to_ucs4(outname), qstring_to_ucs4(relpath)));
212 if (reloutname.startsWith("../"))
219 QString browseRelToSub(QString const & filename, QString const & relpath,
220 QString const & title, QStringList const & filters, bool save,
221 QString const & label1, QString const & dir1,
222 QString const & label2, QString const & dir2)
224 QString const fname = makeAbsPath(filename, relpath);
226 QString const outname =
227 frontend::browseFile(fname, title, filters, save, label1, dir1, label2, dir2);
229 QString const reloutname =
230 toqstr(makeRelPath(qstring_to_ucs4(outname), qstring_to_ucs4(relpath)));
232 QString testname = reloutname;
233 testname.remove(QRegExp("^(\\.\\./)+"));
235 if (testname.contains("/"))
243 /////////////////////////////////////////////////////////////////////
247 /////////////////////////////////////////////////////////////////////
251 QString const catLookAndFeel = N_("Look & Feel");
252 QString const catEditing = N_("Editing");
253 QString const catLanguage = N_("Language Settings");
254 QString const catOutput = N_("Output");
255 QString const catFiles = N_("File Handling");
257 static void parseFontName(QString const & mangled0,
258 string & name, string & foundry)
260 string mangled = fromqstr(mangled0);
261 size_t const idx = mangled.find('[');
262 if (idx == string::npos || idx == 0) {
266 name = mangled.substr(0, idx - 1),
267 foundry = mangled.substr(idx + 1, mangled.size() - idx - 2);
272 static void setComboxFont(QComboBox * cb, string const & family,
273 string const & foundry)
275 QString fontname = toqstr(family);
276 if (!foundry.empty())
277 fontname += " [" + toqstr(foundry) + ']';
279 for (int i = 0; i != cb->count(); ++i) {
280 if (cb->itemText(i) == fontname) {
281 cb->setCurrentIndex(i);
286 // Try matching without foundry name
288 // We count in reverse in order to prefer the Xft foundry
289 for (int i = cb->count(); --i >= 0;) {
290 string name, fnt_foundry;
291 parseFontName(cb->itemText(i), name, fnt_foundry);
292 if (compare_ascii_no_case(name, family) == 0) {
293 cb->setCurrentIndex(i);
298 // family alone can contain e.g. "Helvetica [Adobe]"
299 string tmpname, tmpfoundry;
300 parseFontName(toqstr(family), tmpname, tmpfoundry);
302 // We count in reverse in order to prefer the Xft foundry
303 for (int i = cb->count(); --i >= 0; ) {
304 string name, fnt_foundry;
305 parseFontName(cb->itemText(i), name, fnt_foundry);
306 if (compare_ascii_no_case(name, fnt_foundry) == 0) {
307 cb->setCurrentIndex(i);
312 // Bleh, default fonts, and the names couldn't be found. Hack
317 QString const font_family = toqstr(family);
318 if (font_family == guiApp->romanFontName()) {
319 font.setStyleHint(QFont::Serif);
320 font.setFamily(font_family);
321 } else if (font_family == guiApp->sansFontName()) {
322 font.setStyleHint(QFont::SansSerif);
323 font.setFamily(font_family);
324 } else if (font_family == guiApp->typewriterFontName()) {
325 font.setStyleHint(QFont::TypeWriter);
326 font.setFamily(font_family);
328 LYXERR0("FAILED to find the default font: '"
329 << foundry << "', '" << family << '\'');
333 QFontInfo info(font);
334 string default_font_name, dummyfoundry;
335 parseFontName(info.family(), default_font_name, dummyfoundry);
336 LYXERR0("Apparent font is " << default_font_name);
338 for (int i = 0; i < cb->count(); ++i) {
339 LYXERR0("Looking at " << cb->itemText(i));
340 if (compare_ascii_no_case(fromqstr(cb->itemText(i)),
341 default_font_name) == 0) {
342 cb->setCurrentIndex(i);
347 LYXERR0("FAILED to find the font: '"
348 << foundry << "', '" << family << '\'');
352 /////////////////////////////////////////////////////////////////////
356 /////////////////////////////////////////////////////////////////////
358 PrefOutput::PrefOutput(GuiPreferences * form)
359 : PrefModule(catOutput, N_("General"), form)
363 dviCB->setValidator(new NoNewLineValidator(dviCB));
364 pdfCB->setValidator(new NoNewLineValidator(pdfCB));
366 connect(plaintextLinelengthSB, SIGNAL(valueChanged(int)),
367 this, SIGNAL(changed()));
368 connect(overwriteCO, SIGNAL(activated(int)),
369 this, SIGNAL(changed()));
370 connect(dviCB, SIGNAL(editTextChanged(QString)),
371 this, SIGNAL(changed()));
372 connect(pdfCB, SIGNAL(editTextChanged(QString)),
373 this, SIGNAL(changed()));
374 connect(printerPaperTypeED, SIGNAL(textChanged(QString)),
375 this, SIGNAL(changed()));
376 connect(printerLandscapeED, SIGNAL(textChanged(QString)),
377 this, SIGNAL(changed()));
378 connect(printerPaperSizeED, SIGNAL(textChanged(QString)),
379 this, SIGNAL(changed()));
381 printerPaperTypeED->setValidator(new NoNewLineValidator(printerPaperTypeED));
382 printerLandscapeED->setValidator(new NoNewLineValidator(printerLandscapeED));
383 printerPaperSizeED->setValidator(new NoNewLineValidator(printerPaperSizeED));
386 dviCB->addItem("xdvi -sourceposition '$$n:\\ $$t' $$o");
387 dviCB->addItem("yap -1 -s \"$$n $$t\" $$o");
388 dviCB->addItem("okular --unique \"$$o#src:$$n $$f\"");
389 dviCB->addItem("synctex view -i $$n:0:$$t -o $$o -x \"evince -i %{page+1} $$o\"");
391 pdfCB->addItem("CMCDDE SUMATRA control [ForwardSearch(\\\"$$o\\\",\\\"$$t\\\",$$n,0,0,1)]");
392 pdfCB->addItem("SumatraPDF -reuse-instance \"$$o\" -forward-search \"$$t\" $$n");
393 pdfCB->addItem("synctex view -i $$n:0:$$t -o $$o -x \"xpdf -raise -remote $$t.tmp $$o %{page+1}\"");
394 pdfCB->addItem("okular --unique \"$$o#src:$$n $$f\"");
395 pdfCB->addItem("qpdfview --unique \"$$o#src:$$f:$$n:0\"");
396 pdfCB->addItem("synctex view -i $$n:0:$$t -o $$o -x \"evince -i %{page+1} $$o\"");
397 pdfCB->addItem("/Applications/Skim.app/Contents/SharedSupport/displayline $$n $$o $$t");
401 void PrefOutput::applyRC(LyXRC & rc) const
403 rc.plaintext_linelen = plaintextLinelengthSB->value();
404 rc.forward_search_dvi = fromqstr(dviCB->currentText());
405 rc.forward_search_pdf = fromqstr(pdfCB->currentText());
407 switch (overwriteCO->currentIndex()) {
409 rc.export_overwrite = NO_FILES;
412 rc.export_overwrite = MAIN_FILE;
415 rc.export_overwrite = ALL_FILES;
419 rc.print_paper_flag = fromqstr(printerPaperTypeED->text());
420 rc.print_landscape_flag = fromqstr(printerLandscapeED->text());
421 rc.print_paper_dimension_flag = fromqstr(printerPaperSizeED->text());
425 void PrefOutput::updateRC(LyXRC const & rc)
427 plaintextLinelengthSB->setValue(rc.plaintext_linelen);
428 dviCB->setEditText(toqstr(rc.forward_search_dvi));
429 pdfCB->setEditText(toqstr(rc.forward_search_pdf));
431 switch (rc.export_overwrite) {
433 overwriteCO->setCurrentIndex(0);
436 overwriteCO->setCurrentIndex(1);
439 overwriteCO->setCurrentIndex(2);
443 printerPaperTypeED->setText(toqstr(rc.print_paper_flag));
444 printerLandscapeED->setText(toqstr(rc.print_landscape_flag));
445 printerPaperSizeED->setText(toqstr(rc.print_paper_dimension_flag));
449 /////////////////////////////////////////////////////////////////////
453 /////////////////////////////////////////////////////////////////////
455 PrefInput::PrefInput(GuiPreferences * form)
456 : PrefModule(catEditing, N_("Keyboard/Mouse"), form)
460 connect(keymapCB, SIGNAL(clicked()),
461 this, SIGNAL(changed()));
462 connect(firstKeymapED, SIGNAL(textChanged(QString)),
463 this, SIGNAL(changed()));
464 connect(secondKeymapED, SIGNAL(textChanged(QString)),
465 this, SIGNAL(changed()));
466 connect(mouseWheelSpeedSB, SIGNAL(valueChanged(double)),
467 this, SIGNAL(changed()));
468 connect(scrollzoomEnableCB, SIGNAL(clicked()),
469 this, SIGNAL(changed()));
470 connect(scrollzoomValueCO, SIGNAL(activated(int)),
471 this, SIGNAL(changed()));
472 connect(dontswapCB, SIGNAL(toggled(bool)),
473 this, SIGNAL(changed()));
474 connect(mmPasteCB, SIGNAL(toggled(bool)),
475 this, SIGNAL(changed()));
477 // reveal checkbox for switching Ctrl and Meta on Mac:
480 #if QT_VERSION > 0x040600
484 dontswapCB->setVisible(swapcb);
488 void PrefInput::applyRC(LyXRC & rc) const
490 // FIXME: can derive CB from the two EDs
491 rc.use_kbmap = keymapCB->isChecked();
492 rc.primary_kbmap = internal_path(fromqstr(firstKeymapED->text()));
493 rc.secondary_kbmap = internal_path(fromqstr(secondKeymapED->text()));
494 rc.mouse_wheel_speed = mouseWheelSpeedSB->value();
495 if (scrollzoomEnableCB->isChecked()) {
496 switch (scrollzoomValueCO->currentIndex()) {
498 rc.scroll_wheel_zoom = LyXRC::SCROLL_WHEEL_ZOOM_CTRL;
501 rc.scroll_wheel_zoom = LyXRC::SCROLL_WHEEL_ZOOM_SHIFT;
504 rc.scroll_wheel_zoom = LyXRC::SCROLL_WHEEL_ZOOM_ALT;
508 rc.scroll_wheel_zoom = LyXRC::SCROLL_WHEEL_ZOOM_OFF;
510 rc.mac_dontswap_ctrl_meta = dontswapCB->isChecked();
511 rc.mouse_middlebutton_paste = mmPasteCB->isChecked();
515 void PrefInput::updateRC(LyXRC const & rc)
517 // FIXME: can derive CB from the two EDs
518 keymapCB->setChecked(rc.use_kbmap);
519 firstKeymapED->setText(toqstr(external_path(rc.primary_kbmap)));
520 secondKeymapED->setText(toqstr(external_path(rc.secondary_kbmap)));
521 mouseWheelSpeedSB->setValue(rc.mouse_wheel_speed);
522 switch (rc.scroll_wheel_zoom) {
523 case LyXRC::SCROLL_WHEEL_ZOOM_OFF:
524 scrollzoomEnableCB->setChecked(false);
526 case LyXRC::SCROLL_WHEEL_ZOOM_CTRL:
527 scrollzoomEnableCB->setChecked(true);
528 scrollzoomValueCO->setCurrentIndex(0);
530 case LyXRC::SCROLL_WHEEL_ZOOM_SHIFT:
531 scrollzoomEnableCB->setChecked(true);
532 scrollzoomValueCO->setCurrentIndex(1);
534 case LyXRC::SCROLL_WHEEL_ZOOM_ALT:
535 scrollzoomEnableCB->setChecked(true);
536 scrollzoomValueCO->setCurrentIndex(2);
539 dontswapCB->setChecked(rc.mac_dontswap_ctrl_meta);
540 mmPasteCB->setChecked(rc.mouse_middlebutton_paste);
544 QString PrefInput::testKeymap(QString const & keymap)
546 return form_->browsekbmap(internalPath(keymap));
550 void PrefInput::on_firstKeymapPB_clicked(bool)
552 QString const file = testKeymap(firstKeymapED->text());
554 firstKeymapED->setText(file);
558 void PrefInput::on_secondKeymapPB_clicked(bool)
560 QString const file = testKeymap(secondKeymapED->text());
562 secondKeymapED->setText(file);
566 void PrefInput::on_keymapCB_toggled(bool keymap)
568 firstKeymapLA->setEnabled(keymap);
569 secondKeymapLA->setEnabled(keymap);
570 firstKeymapED->setEnabled(keymap);
571 secondKeymapED->setEnabled(keymap);
572 firstKeymapPB->setEnabled(keymap);
573 secondKeymapPB->setEnabled(keymap);
577 void PrefInput::on_scrollzoomEnableCB_toggled(bool enabled)
579 scrollzoomValueCO->setEnabled(enabled);
583 /////////////////////////////////////////////////////////////////////
587 /////////////////////////////////////////////////////////////////////
589 PrefCompletion::PrefCompletion(GuiPreferences * form)
590 : PrefModule(catEditing, N_("Input Completion"), form)
594 connect(inlineDelaySB, SIGNAL(valueChanged(double)),
595 this, SIGNAL(changed()));
596 connect(inlineMathCB, SIGNAL(clicked()),
597 this, SIGNAL(changed()));
598 connect(inlineTextCB, SIGNAL(clicked()),
599 this, SIGNAL(changed()));
600 connect(inlineDotsCB, SIGNAL(clicked()),
601 this, SIGNAL(changed()));
602 connect(popupDelaySB, SIGNAL(valueChanged(double)),
603 this, SIGNAL(changed()));
604 connect(popupMathCB, SIGNAL(clicked()),
605 this, SIGNAL(changed()));
606 connect(autocorrectionCB, SIGNAL(clicked()),
607 this, SIGNAL(changed()));
608 connect(popupTextCB, SIGNAL(clicked()),
609 this, SIGNAL(changed()));
610 connect(popupAfterCompleteCB, SIGNAL(clicked()),
611 this, SIGNAL(changed()));
612 connect(cursorTextCB, SIGNAL(clicked()),
613 this, SIGNAL(changed()));
614 connect(minlengthSB, SIGNAL(valueChanged(int)),
615 this, SIGNAL(changed()));
619 void PrefCompletion::on_inlineTextCB_clicked()
625 void PrefCompletion::on_popupTextCB_clicked()
631 void PrefCompletion::enableCB()
633 cursorTextCB->setEnabled(
634 popupTextCB->isChecked() || inlineTextCB->isChecked());
638 void PrefCompletion::applyRC(LyXRC & rc) const
640 rc.completion_inline_delay = inlineDelaySB->value();
641 rc.completion_inline_math = inlineMathCB->isChecked();
642 rc.completion_inline_text = inlineTextCB->isChecked();
643 rc.completion_inline_dots = inlineDotsCB->isChecked() ? 13 : -1;
644 rc.completion_popup_delay = popupDelaySB->value();
645 rc.completion_popup_math = popupMathCB->isChecked();
646 rc.autocorrection_math = autocorrectionCB->isChecked();
647 rc.completion_popup_text = popupTextCB->isChecked();
648 rc.completion_cursor_text = cursorTextCB->isChecked();
649 rc.completion_popup_after_complete =
650 popupAfterCompleteCB->isChecked();
651 rc.completion_minlength = minlengthSB->value();
655 void PrefCompletion::updateRC(LyXRC const & rc)
657 inlineDelaySB->setValue(rc.completion_inline_delay);
658 inlineMathCB->setChecked(rc.completion_inline_math);
659 inlineTextCB->setChecked(rc.completion_inline_text);
660 inlineDotsCB->setChecked(rc.completion_inline_dots != -1);
661 popupDelaySB->setValue(rc.completion_popup_delay);
662 popupMathCB->setChecked(rc.completion_popup_math);
663 autocorrectionCB->setChecked(rc.autocorrection_math);
664 popupTextCB->setChecked(rc.completion_popup_text);
665 cursorTextCB->setChecked(rc.completion_cursor_text);
666 popupAfterCompleteCB->setChecked(rc.completion_popup_after_complete);
668 minlengthSB->setValue(rc.completion_minlength);
673 /////////////////////////////////////////////////////////////////////
677 /////////////////////////////////////////////////////////////////////
679 PrefLatex::PrefLatex(GuiPreferences * form)
680 : PrefModule(catOutput, N_("LaTeX"), form)
684 latexDviPaperED->setValidator(new NoNewLineValidator(latexDviPaperED));
685 latexBibtexED->setValidator(new NoNewLineValidator(latexBibtexED));
686 latexJBibtexED->setValidator(new NoNewLineValidator(latexJBibtexED));
687 latexIndexED->setValidator(new NoNewLineValidator(latexIndexED));
688 latexJIndexED->setValidator(new NoNewLineValidator(latexJIndexED));
689 latexNomenclED->setValidator(new NoNewLineValidator(latexNomenclED));
690 latexChecktexED->setValidator(new NoNewLineValidator(latexChecktexED));
692 connect(latexChecktexED, SIGNAL(textChanged(QString)),
693 this, SIGNAL(changed()));
694 connect(latexBibtexCO, SIGNAL(activated(int)),
695 this, SIGNAL(changed()));
696 connect(latexBibtexED, SIGNAL(textChanged(QString)),
697 this, SIGNAL(changed()));
698 connect(latexJBibtexCO, SIGNAL(activated(int)),
699 this, SIGNAL(changed()));
700 connect(latexJBibtexED, SIGNAL(textChanged(QString)),
701 this, SIGNAL(changed()));
702 connect(latexIndexCO, SIGNAL(activated(int)),
703 this, SIGNAL(changed()));
704 connect(latexIndexED, SIGNAL(textChanged(QString)),
705 this, SIGNAL(changed()));
706 connect(latexJIndexED, SIGNAL(textChanged(QString)),
707 this, SIGNAL(changed()));
708 connect(latexAutoresetCB, SIGNAL(clicked()),
709 this, SIGNAL(changed()));
710 connect(latexDviPaperED, SIGNAL(textChanged(QString)),
711 this, SIGNAL(changed()));
712 connect(latexNomenclED, SIGNAL(textChanged(QString)),
713 this, SIGNAL(changed()));
715 #if defined(__CYGWIN__) || defined(_WIN32)
716 pathCB->setVisible(true);
717 connect(pathCB, SIGNAL(clicked()),
718 this, SIGNAL(changed()));
720 pathCB->setVisible(false);
725 void PrefLatex::on_latexBibtexCO_activated(int n)
727 QString const bibtex = latexBibtexCO->itemData(n).toString();
728 if (bibtex.isEmpty()) {
729 latexBibtexED->clear();
730 latexBibtexOptionsLA->setText(qt_("C&ommand:"));
733 for (LyXRC::CommandSet::const_iterator it = bibtex_alternatives.begin();
734 it != bibtex_alternatives.end(); ++it) {
735 QString const bib = toqstr(*it);
736 int ind = bib.indexOf(" ");
737 QString sel_command = bib.left(ind);
738 QString sel_options = ind < 0 ? QString() : bib.mid(ind + 1);
739 if (bibtex == sel_command) {
741 latexBibtexED->clear();
743 latexBibtexED->setText(sel_options.trimmed());
746 latexBibtexOptionsLA->setText(qt_("&Options:"));
750 void PrefLatex::on_latexJBibtexCO_activated(int n)
752 QString const jbibtex = latexJBibtexCO->itemData(n).toString();
753 if (jbibtex.isEmpty()) {
754 latexJBibtexED->clear();
755 latexJBibtexOptionsLA->setText(qt_("Co&mmand:"));
758 for (LyXRC::CommandSet::const_iterator it = jbibtex_alternatives.begin();
759 it != jbibtex_alternatives.end(); ++it) {
760 QString const bib = toqstr(*it);
761 int ind = bib.indexOf(" ");
762 QString sel_command = bib.left(ind);
763 QString sel_options = ind < 0 ? QString() : bib.mid(ind + 1);
764 if (jbibtex == sel_command) {
766 latexJBibtexED->clear();
768 latexJBibtexED->setText(sel_options.trimmed());
771 latexJBibtexOptionsLA->setText(qt_("Opt&ions:"));
775 void PrefLatex::on_latexIndexCO_activated(int n)
777 QString const index = latexIndexCO->itemData(n).toString();
778 if (index.isEmpty()) {
779 latexIndexED->clear();
780 latexIndexOptionsLA->setText(qt_("Co&mmand:"));
783 for (LyXRC::CommandSet::const_iterator it = index_alternatives.begin();
784 it != index_alternatives.end(); ++it) {
785 QString const idx = toqstr(*it);
786 int ind = idx.indexOf(" ");
787 QString sel_command = idx.left(ind);
788 QString sel_options = ind < 0 ? QString() : idx.mid(ind + 1);
789 if (index == sel_command) {
791 latexIndexED->clear();
793 latexIndexED->setText(sel_options.trimmed());
796 latexIndexOptionsLA->setText(qt_("Op&tions:"));
800 void PrefLatex::applyRC(LyXRC & rc) const
802 // If bibtex is not empty, bibopt contains the options, otherwise
803 // it is a customized bibtex command with options.
804 QString const bibtex = latexBibtexCO->itemData(
805 latexBibtexCO->currentIndex()).toString();
806 QString const bibopt = latexBibtexED->text();
807 if (bibtex.isEmpty())
808 rc.bibtex_command = fromqstr(bibopt);
809 else if (bibopt.isEmpty())
810 rc.bibtex_command = fromqstr(bibtex);
812 rc.bibtex_command = fromqstr(bibtex) + " " + fromqstr(bibopt);
814 // If jbibtex is not empty, jbibopt contains the options, otherwise
815 // it is a customized bibtex command with options.
816 QString const jbibtex = latexJBibtexCO->itemData(
817 latexJBibtexCO->currentIndex()).toString();
818 QString const jbibopt = latexJBibtexED->text();
819 if (jbibtex.isEmpty())
820 rc.jbibtex_command = fromqstr(jbibopt);
821 else if (jbibopt.isEmpty())
822 rc.jbibtex_command = fromqstr(jbibtex);
824 rc.jbibtex_command = fromqstr(jbibtex) + " " + fromqstr(jbibopt);
826 // If index is not empty, idxopt contains the options, otherwise
827 // it is a customized index command with options.
828 QString const index = latexIndexCO->itemData(
829 latexIndexCO->currentIndex()).toString();
830 QString const idxopt = latexIndexED->text();
832 rc.index_command = fromqstr(idxopt);
833 else if (idxopt.isEmpty())
834 rc.index_command = fromqstr(index);
836 rc.index_command = fromqstr(index) + " " + fromqstr(idxopt);
838 rc.chktex_command = fromqstr(latexChecktexED->text());
839 rc.jindex_command = fromqstr(latexJIndexED->text());
840 rc.nomencl_command = fromqstr(latexNomenclED->text());
841 rc.auto_reset_options = latexAutoresetCB->isChecked();
842 rc.view_dvi_paper_option = fromqstr(latexDviPaperED->text());
843 #if defined(__CYGWIN__) || defined(_WIN32)
844 rc.windows_style_tex_paths = pathCB->isChecked();
849 void PrefLatex::updateRC(LyXRC const & rc)
851 latexBibtexCO->clear();
853 latexBibtexCO->addItem(qt_("Automatic"), "automatic");
854 latexBibtexCO->addItem(qt_("Custom"), QString());
855 for (LyXRC::CommandSet::const_iterator it = rc.bibtex_alternatives.begin();
856 it != rc.bibtex_alternatives.end(); ++it) {
857 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
858 latexBibtexCO->addItem(command, command);
861 bibtex_alternatives = rc.bibtex_alternatives;
863 QString const bib = toqstr(rc.bibtex_command);
864 int ind = bib.indexOf(" ");
865 QString sel_command = bib.left(ind);
866 QString sel_options = ind < 0 ? QString() : bib.mid(ind + 1);
868 int pos = latexBibtexCO->findData(sel_command);
870 latexBibtexCO->setCurrentIndex(pos);
871 latexBibtexED->setText(sel_options.trimmed());
872 latexBibtexOptionsLA->setText(qt_("&Options:"));
874 latexBibtexED->setText(toqstr(rc.bibtex_command));
875 latexBibtexCO->setCurrentIndex(0);
876 latexBibtexOptionsLA->setText(qt_("C&ommand:"));
879 latexJBibtexCO->clear();
881 latexJBibtexCO->addItem(qt_("Automatic"), "automatic");
882 latexJBibtexCO->addItem(qt_("Custom"), QString());
883 for (LyXRC::CommandSet::const_iterator it = rc.jbibtex_alternatives.begin();
884 it != rc.jbibtex_alternatives.end(); ++it) {
885 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
886 latexJBibtexCO->addItem(command, command);
889 jbibtex_alternatives = rc.jbibtex_alternatives;
891 QString const jbib = toqstr(rc.jbibtex_command);
892 ind = jbib.indexOf(" ");
893 sel_command = jbib.left(ind);
894 sel_options = ind < 0 ? QString() : jbib.mid(ind + 1);
896 pos = latexJBibtexCO->findData(sel_command);
898 latexJBibtexCO->setCurrentIndex(pos);
899 latexJBibtexED->setText(sel_options.trimmed());
900 latexJBibtexOptionsLA->setText(qt_("Opt&ions:"));
902 latexJBibtexED->setText(toqstr(rc.bibtex_command));
903 latexJBibtexCO->setCurrentIndex(0);
904 latexJBibtexOptionsLA->setText(qt_("Co&mmand:"));
907 latexIndexCO->clear();
909 latexIndexCO->addItem(qt_("Custom"), QString());
910 for (LyXRC::CommandSet::const_iterator it = rc.index_alternatives.begin();
911 it != rc.index_alternatives.end(); ++it) {
912 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
913 latexIndexCO->addItem(command, command);
916 index_alternatives = rc.index_alternatives;
918 QString const idx = toqstr(rc.index_command);
919 ind = idx.indexOf(" ");
920 sel_command = idx.left(ind);
921 sel_options = ind < 0 ? QString() : idx.mid(ind + 1);
923 pos = latexIndexCO->findData(sel_command);
925 latexIndexCO->setCurrentIndex(pos);
926 latexIndexED->setText(sel_options.trimmed());
927 latexIndexOptionsLA->setText(qt_("Op&tions:"));
929 latexIndexED->setText(toqstr(rc.index_command));
930 latexIndexCO->setCurrentIndex(0);
931 latexIndexOptionsLA->setText(qt_("Co&mmand:"));
934 latexChecktexED->setText(toqstr(rc.chktex_command));
935 latexJIndexED->setText(toqstr(rc.jindex_command));
936 latexNomenclED->setText(toqstr(rc.nomencl_command));
937 latexAutoresetCB->setChecked(rc.auto_reset_options);
938 latexDviPaperED->setText(toqstr(rc.view_dvi_paper_option));
939 #if defined(__CYGWIN__) || defined(_WIN32)
940 pathCB->setChecked(rc.windows_style_tex_paths);
945 /////////////////////////////////////////////////////////////////////
949 /////////////////////////////////////////////////////////////////////
951 PrefScreenFonts::PrefScreenFonts(GuiPreferences * form)
952 : PrefModule(catLookAndFeel, N_("Screen Fonts"), form)
956 connect(screenRomanCO, SIGNAL(activated(QString)),
957 this, SLOT(selectRoman(QString)));
958 connect(screenSansCO, SIGNAL(activated(QString)),
959 this, SLOT(selectSans(QString)));
960 connect(screenTypewriterCO, SIGNAL(activated(QString)),
961 this, SLOT(selectTypewriter(QString)));
963 QFontDatabase fontdb;
964 QStringList families(fontdb.families());
965 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
966 screenRomanCO->addItem(*it);
967 screenSansCO->addItem(*it);
968 screenTypewriterCO->addItem(*it);
970 connect(screenRomanCO, SIGNAL(activated(QString)),
971 this, SIGNAL(changed()));
972 connect(screenSansCO, SIGNAL(activated(QString)),
973 this, SIGNAL(changed()));
974 connect(screenTypewriterCO, SIGNAL(activated(QString)),
975 this, SIGNAL(changed()));
976 connect(screenZoomSB, SIGNAL(valueChanged(int)),
977 this, SIGNAL(changed()));
978 connect(screenTinyED, SIGNAL(textChanged(QString)),
979 this, SIGNAL(changed()));
980 connect(screenSmallestED, SIGNAL(textChanged(QString)),
981 this, SIGNAL(changed()));
982 connect(screenSmallerED, SIGNAL(textChanged(QString)),
983 this, SIGNAL(changed()));
984 connect(screenSmallED, SIGNAL(textChanged(QString)),
985 this, SIGNAL(changed()));
986 connect(screenNormalED, SIGNAL(textChanged(QString)),
987 this, SIGNAL(changed()));
988 connect(screenLargeED, SIGNAL(textChanged(QString)),
989 this, SIGNAL(changed()));
990 connect(screenLargerED, SIGNAL(textChanged(QString)),
991 this, SIGNAL(changed()));
992 connect(screenLargestED, SIGNAL(textChanged(QString)),
993 this, SIGNAL(changed()));
994 connect(screenHugeED, SIGNAL(textChanged(QString)),
995 this, SIGNAL(changed()));
996 connect(screenHugerED, SIGNAL(textChanged(QString)),
997 this, SIGNAL(changed()));
998 connect(pixmapCacheCB, SIGNAL(toggled(bool)),
999 this, SIGNAL(changed()));
1001 screenTinyED->setValidator(new QDoubleValidator(screenTinyED));
1002 screenSmallestED->setValidator(new QDoubleValidator(screenSmallestED));
1003 screenSmallerED->setValidator(new QDoubleValidator(screenSmallerED));
1004 screenSmallED->setValidator(new QDoubleValidator(screenSmallED));
1005 screenNormalED->setValidator(new QDoubleValidator(screenNormalED));
1006 screenLargeED->setValidator(new QDoubleValidator(screenLargeED));
1007 screenLargerED->setValidator(new QDoubleValidator(screenLargerED));
1008 screenLargestED->setValidator(new QDoubleValidator(screenLargestED));
1009 screenHugeED->setValidator(new QDoubleValidator(screenHugeED));
1010 screenHugerED->setValidator(new QDoubleValidator(screenHugerED));
1014 void PrefScreenFonts::applyRC(LyXRC & rc) const
1016 LyXRC const oldrc = rc;
1018 parseFontName(screenRomanCO->currentText(),
1019 rc.roman_font_name, rc.roman_font_foundry);
1020 parseFontName(screenSansCO->currentText(),
1021 rc.sans_font_name, rc.sans_font_foundry);
1022 parseFontName(screenTypewriterCO->currentText(),
1023 rc.typewriter_font_name, rc.typewriter_font_foundry);
1025 rc.defaultZoom = screenZoomSB->value();
1026 rc.font_sizes[FONT_SIZE_TINY] = widgetToDoubleStr(screenTinyED);
1027 rc.font_sizes[FONT_SIZE_SCRIPT] = widgetToDoubleStr(screenSmallestED);
1028 rc.font_sizes[FONT_SIZE_FOOTNOTE] = widgetToDoubleStr(screenSmallerED);
1029 rc.font_sizes[FONT_SIZE_SMALL] = widgetToDoubleStr(screenSmallED);
1030 rc.font_sizes[FONT_SIZE_NORMAL] = widgetToDoubleStr(screenNormalED);
1031 rc.font_sizes[FONT_SIZE_LARGE] = widgetToDoubleStr(screenLargeED);
1032 rc.font_sizes[FONT_SIZE_LARGER] = widgetToDoubleStr(screenLargerED);
1033 rc.font_sizes[FONT_SIZE_LARGEST] = widgetToDoubleStr(screenLargestED);
1034 rc.font_sizes[FONT_SIZE_HUGE] = widgetToDoubleStr(screenHugeED);
1035 rc.font_sizes[FONT_SIZE_HUGER] = widgetToDoubleStr(screenHugerED);
1036 rc.use_pixmap_cache = pixmapCacheCB->isChecked();
1038 if (rc.font_sizes != oldrc.font_sizes
1039 || rc.roman_font_name != oldrc.roman_font_name
1040 || rc.sans_font_name != oldrc.sans_font_name
1041 || rc.typewriter_font_name != oldrc.typewriter_font_name
1042 || rc.defaultZoom != oldrc.defaultZoom) {
1043 // The global QPixmapCache is used in GuiPainter to cache text
1044 // painting so we must reset it in case any of the above
1045 // parameter is changed.
1046 QPixmapCache::clear();
1047 guiApp->fontLoader().update();
1048 form_->updateScreenFonts();
1053 void PrefScreenFonts::updateRC(LyXRC const & rc)
1055 setComboxFont(screenRomanCO, rc.roman_font_name,
1056 rc.roman_font_foundry);
1057 setComboxFont(screenSansCO, rc.sans_font_name,
1058 rc.sans_font_foundry);
1059 setComboxFont(screenTypewriterCO, rc.typewriter_font_name,
1060 rc.typewriter_font_foundry);
1062 selectRoman(screenRomanCO->currentText());
1063 selectSans(screenSansCO->currentText());
1064 selectTypewriter(screenTypewriterCO->currentText());
1066 screenZoomSB->setValue(rc.defaultZoom);
1067 updateScreenFontSizes(rc);
1069 pixmapCacheCB->setChecked(rc.use_pixmap_cache);
1070 #if defined(Q_WS_X11) || defined(QPA_XCB)
1071 pixmapCacheCB->setEnabled(false);
1077 void PrefScreenFonts::updateScreenFontSizes(LyXRC const & rc)
1079 doubleToWidget(screenTinyED, rc.font_sizes[FONT_SIZE_TINY]);
1080 doubleToWidget(screenSmallestED, rc.font_sizes[FONT_SIZE_SCRIPT]);
1081 doubleToWidget(screenSmallerED, rc.font_sizes[FONT_SIZE_FOOTNOTE]);
1082 doubleToWidget(screenSmallED, rc.font_sizes[FONT_SIZE_SMALL]);
1083 doubleToWidget(screenNormalED, rc.font_sizes[FONT_SIZE_NORMAL]);
1084 doubleToWidget(screenLargeED, rc.font_sizes[FONT_SIZE_LARGE]);
1085 doubleToWidget(screenLargerED, rc.font_sizes[FONT_SIZE_LARGER]);
1086 doubleToWidget(screenLargestED, rc.font_sizes[FONT_SIZE_LARGEST]);
1087 doubleToWidget(screenHugeED, rc.font_sizes[FONT_SIZE_HUGE]);
1088 doubleToWidget(screenHugerED, rc.font_sizes[FONT_SIZE_HUGER]);
1092 void PrefScreenFonts::selectRoman(const QString & name)
1094 screenRomanFE->set(QFont(name), name);
1098 void PrefScreenFonts::selectSans(const QString & name)
1100 screenSansFE->set(QFont(name), name);
1104 void PrefScreenFonts::selectTypewriter(const QString & name)
1106 screenTypewriterFE->set(QFont(name), name);
1110 /////////////////////////////////////////////////////////////////////
1114 /////////////////////////////////////////////////////////////////////
1117 PrefColors::PrefColors(GuiPreferences * form)
1118 : PrefModule(catLookAndFeel, N_("Colors"), form)
1122 // FIXME: all of this initialization should be put into the controller.
1123 // See http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg113301.html
1124 // for some discussion of why that is not trivial.
1125 QPixmap icon(32, 32);
1126 for (int i = 0; i < Color_ignore; ++i) {
1127 ColorCode lc = static_cast<ColorCode>(i);
1128 if (lc == Color_none
1129 || lc == Color_black
1130 || lc == Color_white
1132 || lc == Color_brown
1134 || lc == Color_darkgray
1136 || lc == Color_green
1137 || lc == Color_lightgray
1139 || lc == Color_magenta
1140 || lc == Color_olive
1141 || lc == Color_orange
1143 || lc == Color_purple
1146 || lc == Color_violet
1147 || lc == Color_yellow
1148 || lc == Color_inherit
1149 || lc == Color_ignore)
1151 lcolors_.push_back(lc);
1153 qSort(lcolors_.begin(), lcolors_.end(), ColorSorter);
1154 vector<ColorCode>::const_iterator cit = lcolors_.begin();
1155 vector<ColorCode>::const_iterator const end = lcolors_.end();
1156 for (; cit != end; ++cit) {
1157 (void) new QListWidgetItem(QIcon(icon),
1158 toqstr(lcolor.getGUIName(*cit)), lyxObjectsLW);
1160 curcolors_.resize(lcolors_.size());
1161 newcolors_.resize(lcolors_.size());
1162 // End initialization
1164 connect(colorChangePB, SIGNAL(clicked()),
1165 this, SLOT(changeColor()));
1166 connect(lyxObjectsLW, SIGNAL(itemSelectionChanged()),
1167 this, SLOT(changeLyxObjectsSelection()));
1168 connect(lyxObjectsLW, SIGNAL(itemActivated(QListWidgetItem*)),
1169 this, SLOT(changeColor()));
1170 connect(syscolorsCB, SIGNAL(toggled(bool)),
1171 this, SIGNAL(changed()));
1172 connect(syscolorsCB, SIGNAL(toggled(bool)),
1173 this, SLOT(changeSysColor()));
1177 void PrefColors::applyRC(LyXRC & rc) const
1181 for (unsigned int i = 0; i < lcolors_.size(); ++i)
1182 if (curcolors_[i] != newcolors_[i])
1183 form_->setColor(lcolors_[i], newcolors_[i]);
1184 rc.use_system_colors = syscolorsCB->isChecked();
1186 if (oldrc.use_system_colors != rc.use_system_colors)
1187 guiApp->colorCache().clear();
1191 void PrefColors::updateRC(LyXRC const & rc)
1193 for (unsigned int i = 0; i < lcolors_.size(); ++i) {
1194 QColor color = QColor(guiApp->colorCache().get(lcolors_[i], false));
1195 QPixmap coloritem(32, 32);
1196 coloritem.fill(color);
1197 lyxObjectsLW->item(i)->setIcon(QIcon(coloritem));
1198 newcolors_[i] = curcolors_[i] = color.name();
1200 syscolorsCB->setChecked(rc.use_system_colors);
1201 changeLyxObjectsSelection();
1205 void PrefColors::changeColor()
1207 int const row = lyxObjectsLW->currentRow();
1213 QString const color = newcolors_[row];
1214 QColor c = QColorDialog::getColor(QColor(color), qApp->focusWidget());
1216 if (c.isValid() && c.name() != color) {
1217 newcolors_[row] = c.name();
1218 QPixmap coloritem(32, 32);
1220 lyxObjectsLW->currentItem()->setIcon(QIcon(coloritem));
1226 void PrefColors::changeSysColor()
1228 for (int row = 0 ; row < lyxObjectsLW->count() ; ++row) {
1229 // skip colors that are taken from system palette
1230 bool const disable = syscolorsCB->isChecked()
1231 && guiApp->colorCache().isSystem(lcolors_[row]);
1233 QListWidgetItem * const item = lyxObjectsLW->item(row);
1234 Qt::ItemFlags const flags = item->flags();
1237 item->setFlags(flags & ~Qt::ItemIsEnabled);
1239 item->setFlags(flags | Qt::ItemIsEnabled);
1243 void PrefColors::changeLyxObjectsSelection()
1245 colorChangePB->setDisabled(lyxObjectsLW->currentRow() < 0);
1249 /////////////////////////////////////////////////////////////////////
1253 /////////////////////////////////////////////////////////////////////
1255 PrefDisplay::PrefDisplay(GuiPreferences * form)
1256 : PrefModule(catLookAndFeel, N_("Display"), form)
1259 connect(displayGraphicsCB, SIGNAL(toggled(bool)), this, SIGNAL(changed()));
1260 connect(instantPreviewCO, SIGNAL(activated(int)), this, SIGNAL(changed()));
1261 connect(previewSizeSB, SIGNAL(valueChanged(double)), this, SIGNAL(changed()));
1262 connect(paragraphMarkerCB, SIGNAL(toggled(bool)), this, SIGNAL(changed()));
1266 void PrefDisplay::on_instantPreviewCO_currentIndexChanged(int index)
1268 previewSizeSB->setEnabled(index != 0);
1272 void PrefDisplay::applyRC(LyXRC & rc) const
1274 switch (instantPreviewCO->currentIndex()) {
1276 rc.preview = LyXRC::PREVIEW_OFF;
1279 if (rc.preview != LyXRC::PREVIEW_NO_MATH) {
1280 rc.preview = LyXRC::PREVIEW_NO_MATH;
1281 form_->updatePreviews();
1285 if (rc.preview != LyXRC::PREVIEW_ON) {
1286 rc.preview = LyXRC::PREVIEW_ON;
1287 form_->updatePreviews();
1292 rc.display_graphics = displayGraphicsCB->isChecked();
1293 rc.preview_scale_factor = previewSizeSB->value();
1294 rc.paragraph_markers = paragraphMarkerCB->isChecked();
1296 // FIXME!! The graphics cache no longer has a changeDisplay method.
1298 if (old_value != rc.display_graphics) {
1299 graphics::GCache & gc = graphics::GCache::get();
1306 void PrefDisplay::updateRC(LyXRC const & rc)
1308 switch (rc.preview) {
1309 case LyXRC::PREVIEW_OFF:
1310 instantPreviewCO->setCurrentIndex(0);
1312 case LyXRC::PREVIEW_NO_MATH :
1313 instantPreviewCO->setCurrentIndex(1);
1315 case LyXRC::PREVIEW_ON :
1316 instantPreviewCO->setCurrentIndex(2);
1320 displayGraphicsCB->setChecked(rc.display_graphics);
1321 previewSizeSB->setValue(rc.preview_scale_factor);
1322 paragraphMarkerCB->setChecked(rc.paragraph_markers);
1323 previewSizeSB->setEnabled(
1325 && rc.preview != LyXRC::PREVIEW_OFF);
1329 /////////////////////////////////////////////////////////////////////
1333 /////////////////////////////////////////////////////////////////////
1335 PrefPaths::PrefPaths(GuiPreferences * form)
1336 : PrefModule(QString(), N_("Paths"), form)
1340 connect(workingDirPB, SIGNAL(clicked()), this, SLOT(selectWorkingdir()));
1341 connect(workingDirED, SIGNAL(textChanged(QString)),
1342 this, SIGNAL(changed()));
1344 connect(templateDirPB, SIGNAL(clicked()), this, SLOT(selectTemplatedir()));
1345 connect(templateDirED, SIGNAL(textChanged(QString)),
1346 this, SIGNAL(changed()));
1348 connect(exampleDirPB, SIGNAL(clicked()), this, SLOT(selectExampledir()));
1349 connect(exampleDirED, SIGNAL(textChanged(QString)),
1350 this, SIGNAL(changed()));
1352 connect(backupDirPB, SIGNAL(clicked()), this, SLOT(selectBackupdir()));
1353 connect(backupDirED, SIGNAL(textChanged(QString)),
1354 this, SIGNAL(changed()));
1356 connect(lyxserverDirPB, SIGNAL(clicked()), this, SLOT(selectLyxPipe()));
1357 connect(lyxserverDirED, SIGNAL(textChanged(QString)),
1358 this, SIGNAL(changed()));
1360 connect(thesaurusDirPB, SIGNAL(clicked()), this, SLOT(selectThesaurusdir()));
1361 connect(thesaurusDirED, SIGNAL(textChanged(QString)),
1362 this, SIGNAL(changed()));
1364 connect(tempDirPB, SIGNAL(clicked()), this, SLOT(selectTempdir()));
1365 connect(tempDirED, SIGNAL(textChanged(QString)),
1366 this, SIGNAL(changed()));
1368 #if defined(USE_HUNSPELL)
1369 connect(hunspellDirPB, SIGNAL(clicked()), this, SLOT(selectHunspelldir()));
1370 connect(hunspellDirED, SIGNAL(textChanged(QString)),
1371 this, SIGNAL(changed()));
1373 hunspellDirPB->setEnabled(false);
1374 hunspellDirED->setEnabled(false);
1377 connect(pathPrefixED, SIGNAL(textChanged(QString)),
1378 this, SIGNAL(changed()));
1380 connect(texinputsPrefixED, SIGNAL(textChanged(QString)),
1381 this, SIGNAL(changed()));
1383 pathPrefixED->setValidator(new NoNewLineValidator(pathPrefixED));
1384 texinputsPrefixED->setValidator(new NoNewLineValidator(texinputsPrefixED));
1388 void PrefPaths::applyRC(LyXRC & rc) const
1390 rc.document_path = internal_path(fromqstr(workingDirED->text()));
1391 rc.example_path = internal_path(fromqstr(exampleDirED->text()));
1392 rc.template_path = internal_path(fromqstr(templateDirED->text()));
1393 rc.backupdir_path = internal_path(fromqstr(backupDirED->text()));
1394 rc.tempdir_path = internal_path(fromqstr(tempDirED->text()));
1395 rc.thesaurusdir_path = internal_path(fromqstr(thesaurusDirED->text()));
1396 rc.hunspelldir_path = internal_path(fromqstr(hunspellDirED->text()));
1397 rc.path_prefix = internal_path_list(fromqstr(pathPrefixED->text()));
1398 rc.texinputs_prefix = internal_path_list(fromqstr(texinputsPrefixED->text()));
1399 // FIXME: should be a checkbox only
1400 rc.lyxpipes = internal_path(fromqstr(lyxserverDirED->text()));
1404 void PrefPaths::updateRC(LyXRC const & rc)
1406 workingDirED->setText(toqstr(external_path(rc.document_path)));
1407 exampleDirED->setText(toqstr(external_path(rc.example_path)));
1408 templateDirED->setText(toqstr(external_path(rc.template_path)));
1409 backupDirED->setText(toqstr(external_path(rc.backupdir_path)));
1410 tempDirED->setText(toqstr(external_path(rc.tempdir_path)));
1411 thesaurusDirED->setText(toqstr(external_path(rc.thesaurusdir_path)));
1412 hunspellDirED->setText(toqstr(external_path(rc.hunspelldir_path)));
1413 pathPrefixED->setText(toqstr(external_path_list(rc.path_prefix)));
1414 texinputsPrefixED->setText(toqstr(external_path_list(rc.texinputs_prefix)));
1415 // FIXME: should be a checkbox only
1416 lyxserverDirED->setText(toqstr(external_path(rc.lyxpipes)));
1420 void PrefPaths::selectExampledir()
1422 QString file = browseDir(internalPath(exampleDirED->text()),
1423 qt_("Select directory for example files"));
1424 if (!file.isEmpty())
1425 exampleDirED->setText(file);
1429 void PrefPaths::selectTemplatedir()
1431 QString file = browseDir(internalPath(templateDirED->text()),
1432 qt_("Select a document templates directory"));
1433 if (!file.isEmpty())
1434 templateDirED->setText(file);
1438 void PrefPaths::selectTempdir()
1440 QString file = browseDir(internalPath(tempDirED->text()),
1441 qt_("Select a temporary directory"));
1442 if (!file.isEmpty())
1443 tempDirED->setText(file);
1447 void PrefPaths::selectBackupdir()
1449 QString file = browseDir(internalPath(backupDirED->text()),
1450 qt_("Select a backups directory"));
1451 if (!file.isEmpty())
1452 backupDirED->setText(file);
1456 void PrefPaths::selectWorkingdir()
1458 QString file = browseDir(internalPath(workingDirED->text()),
1459 qt_("Select a document directory"));
1460 if (!file.isEmpty())
1461 workingDirED->setText(file);
1465 void PrefPaths::selectThesaurusdir()
1467 QString file = browseDir(internalPath(thesaurusDirED->text()),
1468 qt_("Set the path to the thesaurus dictionaries"));
1469 if (!file.isEmpty())
1470 thesaurusDirED->setText(file);
1474 void PrefPaths::selectHunspelldir()
1476 QString file = browseDir(internalPath(hunspellDirED->text()),
1477 qt_("Set the path to the Hunspell dictionaries"));
1478 if (!file.isEmpty())
1479 hunspellDirED->setText(file);
1483 void PrefPaths::selectLyxPipe()
1485 QString file = form_->browse(internalPath(lyxserverDirED->text()),
1486 qt_("Give a filename for the LyX server pipe"));
1487 if (!file.isEmpty())
1488 lyxserverDirED->setText(file);
1492 /////////////////////////////////////////////////////////////////////
1496 /////////////////////////////////////////////////////////////////////
1498 PrefSpellchecker::PrefSpellchecker(GuiPreferences * form)
1499 : PrefModule(catLanguage, N_("Spellchecker"), form)
1503 // FIXME: this check should test the target platform (darwin)
1504 #if defined(USE_MACOSX_PACKAGING)
1505 spellcheckerCB->addItem(qt_("Native"), QString("native"));
1506 #define CONNECT_APPLESPELL
1508 #undef CONNECT_APPLESPELL
1510 #if defined(USE_ASPELL)
1511 spellcheckerCB->addItem(qt_("Aspell"), QString("aspell"));
1513 #if defined(USE_ENCHANT)
1514 spellcheckerCB->addItem(qt_("Enchant"), QString("enchant"));
1516 #if defined(USE_HUNSPELL)
1517 spellcheckerCB->addItem(qt_("Hunspell"), QString("hunspell"));
1520 #if defined(CONNECT_APPLESPELL) || defined(USE_ASPELL) || defined(USE_ENCHANT) || defined(USE_HUNSPELL)
1521 connect(spellcheckerCB, SIGNAL(currentIndexChanged(int)),
1522 this, SIGNAL(changed()));
1523 connect(altLanguageED, SIGNAL(textChanged(QString)),
1524 this, SIGNAL(changed()));
1525 connect(escapeCharactersED, SIGNAL(textChanged(QString)),
1526 this, SIGNAL(changed()));
1527 connect(compoundWordCB, SIGNAL(clicked()),
1528 this, SIGNAL(changed()));
1529 connect(spellcheckContinuouslyCB, SIGNAL(clicked()),
1530 this, SIGNAL(changed()));
1531 connect(spellcheckNotesCB, SIGNAL(clicked()),
1532 this, SIGNAL(changed()));
1534 altLanguageED->setValidator(new NoNewLineValidator(altLanguageED));
1535 escapeCharactersED->setValidator(new NoNewLineValidator(escapeCharactersED));
1537 spellcheckerCB->setEnabled(false);
1538 altLanguageED->setEnabled(false);
1539 escapeCharactersED->setEnabled(false);
1540 compoundWordCB->setEnabled(false);
1541 spellcheckContinuouslyCB->setEnabled(false);
1542 spellcheckNotesCB->setEnabled(false);
1547 void PrefSpellchecker::applyRC(LyXRC & rc) const
1549 string const speller = fromqstr(spellcheckerCB->
1550 itemData(spellcheckerCB->currentIndex()).toString());
1551 if (!speller.empty())
1552 rc.spellchecker = speller;
1553 rc.spellchecker_alt_lang = fromqstr(altLanguageED->text());
1554 rc.spellchecker_esc_chars = fromqstr(escapeCharactersED->text());
1555 rc.spellchecker_accept_compound = compoundWordCB->isChecked();
1556 rc.spellcheck_continuously = spellcheckContinuouslyCB->isChecked();
1557 rc.spellcheck_notes = spellcheckNotesCB->isChecked();
1561 void PrefSpellchecker::updateRC(LyXRC const & rc)
1563 spellcheckerCB->setCurrentIndex(
1564 spellcheckerCB->findData(toqstr(rc.spellchecker)));
1565 altLanguageED->setText(toqstr(rc.spellchecker_alt_lang));
1566 escapeCharactersED->setText(toqstr(rc.spellchecker_esc_chars));
1567 compoundWordCB->setChecked(rc.spellchecker_accept_compound);
1568 spellcheckContinuouslyCB->setChecked(rc.spellcheck_continuously);
1569 spellcheckNotesCB->setChecked(rc.spellcheck_notes);
1573 void PrefSpellchecker::on_spellcheckerCB_currentIndexChanged(int index)
1575 QString spellchecker = spellcheckerCB->itemData(index).toString();
1577 compoundWordCB->setEnabled(spellchecker == QString("aspell"));
1582 /////////////////////////////////////////////////////////////////////
1586 /////////////////////////////////////////////////////////////////////
1589 PrefConverters::PrefConverters(GuiPreferences * form)
1590 : PrefModule(catFiles, N_("Converters"), form)
1594 connect(converterNewPB, SIGNAL(clicked()),
1595 this, SLOT(updateConverter()));
1596 connect(converterRemovePB, SIGNAL(clicked()),
1597 this, SLOT(removeConverter()));
1598 connect(converterModifyPB, SIGNAL(clicked()),
1599 this, SLOT(updateConverter()));
1600 connect(convertersLW, SIGNAL(currentRowChanged(int)),
1601 this, SLOT(switchConverter()));
1602 connect(converterFromCO, SIGNAL(activated(QString)),
1603 this, SLOT(changeConverter()));
1604 connect(converterToCO, SIGNAL(activated(QString)),
1605 this, SLOT(changeConverter()));
1606 connect(converterED, SIGNAL(textEdited(QString)),
1607 this, SLOT(changeConverter()));
1608 connect(converterFlagED, SIGNAL(textEdited(QString)),
1609 this, SLOT(changeConverter()));
1610 connect(converterNewPB, SIGNAL(clicked()),
1611 this, SIGNAL(changed()));
1612 connect(converterRemovePB, SIGNAL(clicked()),
1613 this, SIGNAL(changed()));
1614 connect(converterModifyPB, SIGNAL(clicked()),
1615 this, SIGNAL(changed()));
1616 connect(maxAgeLE, SIGNAL(textEdited(QString)),
1617 this, SIGNAL(changed()));
1618 connect(needauthForbiddenCB, SIGNAL(toggled(bool)),
1619 this, SIGNAL(changed()));
1621 converterED->setValidator(new NoNewLineValidator(converterED));
1622 converterFlagED->setValidator(new NoNewLineValidator(converterFlagED));
1623 maxAgeLE->setValidator(new QDoubleValidator(0, HUGE_VAL, 6, maxAgeLE));
1624 //converterDefGB->setFocusProxy(convertersLW);
1628 void PrefConverters::applyRC(LyXRC & rc) const
1630 rc.use_converter_cache = cacheCB->isChecked();
1631 rc.use_converter_needauth_forbidden = needauthForbiddenCB->isChecked();
1632 rc.use_converter_needauth = needauthCB->isChecked();
1633 rc.converter_cache_maxage = int(widgetToDouble(maxAgeLE) * 86400.0);
1637 static void setCheckboxBlockSignals(QCheckBox *cb, bool checked) {
1638 cb->blockSignals(true);
1639 cb->setChecked(checked);
1640 cb->blockSignals(false);
1644 void PrefConverters::updateRC(LyXRC const & rc)
1646 cacheCB->setChecked(rc.use_converter_cache);
1647 needauthForbiddenCB->setChecked(rc.use_converter_needauth_forbidden);
1648 setCheckboxBlockSignals(needauthCB, rc.use_converter_needauth);
1650 doubleToWidget(maxAgeLE, (double(rc.converter_cache_maxage) / 86400.0), 'g', 6);
1655 void PrefConverters::updateGui()
1657 QString const pattern("%1 -> %2");
1658 form_->formats().sort();
1659 form_->converters().update(form_->formats());
1660 // save current selection
1663 .arg(converterFromCO->currentText())
1664 .arg(converterToCO->currentText());
1666 converterFromCO->clear();
1667 converterToCO->clear();
1669 for (Format const & f : form_->formats()) {
1670 QString const name = toqstr(translateIfPossible(f.prettyname()));
1671 converterFromCO->addItem(name);
1672 converterToCO->addItem(name);
1675 // currentRowChanged(int) is also triggered when updating the listwidget
1676 // block signals to avoid unnecessary calls to switchConverter()
1677 convertersLW->blockSignals(true);
1678 convertersLW->clear();
1680 for (Converter const & c : form_->converters()) {
1681 QString const name =
1683 .arg(toqstr(translateIfPossible(c.From()->prettyname())))
1684 .arg(toqstr(translateIfPossible(c.To()->prettyname())));
1685 int type = form_->converters().getNumber(c.From()->name(),
1687 new QListWidgetItem(name, convertersLW, type);
1689 convertersLW->sortItems(Qt::AscendingOrder);
1690 convertersLW->blockSignals(false);
1692 // restore selection
1693 if (current != pattern.arg(QString()).arg(QString())) {
1694 QList<QListWidgetItem *> const item =
1695 convertersLW->findItems(current, Qt::MatchExactly);
1696 if (!item.isEmpty())
1697 convertersLW->setCurrentItem(item.at(0));
1700 // select first element if restoring failed
1701 if (convertersLW->currentRow() == -1)
1702 convertersLW->setCurrentRow(0);
1708 void PrefConverters::switchConverter()
1710 int const cnr = convertersLW->currentItem()->type();
1711 Converter const & c(form_->converters().get(cnr));
1712 converterFromCO->setCurrentIndex(form_->formats().getNumber(c.from()));
1713 converterToCO->setCurrentIndex(form_->formats().getNumber(c.to()));
1714 converterED->setText(toqstr(c.command()));
1715 converterFlagED->setText(toqstr(c.flags()));
1721 void PrefConverters::changeConverter()
1727 void PrefConverters::updateButtons()
1729 if (form_->formats().empty())
1731 Format const & from = form_->formats().get(converterFromCO->currentIndex());
1732 Format const & to = form_->formats().get(converterToCO->currentIndex());
1733 int const sel = form_->converters().getNumber(from.name(), to.name());
1734 bool const known = sel >= 0;
1735 bool const valid = !(converterED->text().isEmpty()
1736 || from.name() == to.name());
1741 if (convertersLW->count() > 0) {
1742 int const cnr = convertersLW->currentItem()->type();
1743 Converter const & c = form_->converters().get(cnr);
1744 old_command = c.command();
1745 old_flag = c.flags();
1748 string const new_command = fromqstr(converterED->text());
1749 string const new_flag = fromqstr(converterFlagED->text());
1751 bool modified = (old_command != new_command || old_flag != new_flag);
1753 converterModifyPB->setEnabled(valid && known && modified);
1754 converterNewPB->setEnabled(valid && !known);
1755 converterRemovePB->setEnabled(known);
1757 maxAgeLE->setEnabled(cacheCB->isChecked());
1758 maxAgeLA->setEnabled(cacheCB->isChecked());
1763 // specify unique from/to or it doesn't appear. This is really bad UI
1764 // this is why we can use the same function for both new and modify
1765 void PrefConverters::updateConverter()
1767 Format const & from = form_->formats().get(converterFromCO->currentIndex());
1768 Format const & to = form_->formats().get(converterToCO->currentIndex());
1769 string const flags = fromqstr(converterFlagED->text());
1770 string const command = fromqstr(converterED->text());
1772 Converter const * old =
1773 form_->converters().getConverter(from.name(), to.name());
1774 form_->converters().add(from.name(), to.name(), command, flags);
1777 form_->converters().updateLast(form_->formats());
1781 // Remove all files created by this converter from the cache, since
1782 // the modified converter might create different files.
1783 ConverterCache::get().remove_all(from.name(), to.name());
1787 void PrefConverters::removeConverter()
1789 Format const & from = form_->formats().get(converterFromCO->currentIndex());
1790 Format const & to = form_->formats().get(converterToCO->currentIndex());
1791 form_->converters().erase(from.name(), to.name());
1795 // Remove all files created by this converter from the cache, since
1796 // a possible new converter might create different files.
1797 ConverterCache::get().remove_all(from.name(), to.name());
1801 void PrefConverters::on_cacheCB_stateChanged(int state)
1803 maxAgeLE->setEnabled(state == Qt::Checked);
1804 maxAgeLA->setEnabled(state == Qt::Checked);
1809 void PrefConverters::on_needauthForbiddenCB_toggled(bool checked)
1811 needauthCB->setEnabled(!checked);
1815 void PrefConverters::on_needauthCB_toggled(bool checked)
1822 int ret = frontend::Alert::prompt(
1823 _("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!"),
1824 0, 0, _("&No"), _("&Yes"));
1828 setCheckboxBlockSignals(needauthCB, true);
1832 /////////////////////////////////////////////////////////////////////
1836 /////////////////////////////////////////////////////////////////////
1838 class FormatValidator : public QValidator
1841 FormatValidator(QWidget *, Formats const & f);
1842 void fixup(QString & input) const;
1843 QValidator::State validate(QString & input, int & pos) const;
1845 virtual QString toString(Format const & format) const = 0;
1847 Formats const & formats_;
1851 FormatValidator::FormatValidator(QWidget * parent, Formats const & f)
1852 : QValidator(parent), formats_(f)
1857 void FormatValidator::fixup(QString & input) const
1859 Formats::const_iterator cit = formats_.begin();
1860 Formats::const_iterator end = formats_.end();
1861 for (; cit != end; ++cit) {
1862 QString const name = toString(*cit);
1863 if (distance(formats_.begin(), cit) == nr()) {
1871 QValidator::State FormatValidator::validate(QString & input, int & /*pos*/) const
1873 Formats::const_iterator cit = formats_.begin();
1874 Formats::const_iterator end = formats_.end();
1875 bool unknown = true;
1876 for (; unknown && cit != end; ++cit) {
1877 QString const name = toString(*cit);
1878 if (distance(formats_.begin(), cit) != nr())
1879 unknown = name != input;
1882 if (unknown && !input.isEmpty())
1883 return QValidator::Acceptable;
1885 return QValidator::Intermediate;
1889 int FormatValidator::nr() const
1891 QComboBox * p = qobject_cast<QComboBox *>(parent());
1892 return p->itemData(p->currentIndex()).toInt();
1896 /////////////////////////////////////////////////////////////////////
1898 // FormatNameValidator
1900 /////////////////////////////////////////////////////////////////////
1902 class FormatNameValidator : public FormatValidator
1905 FormatNameValidator(QWidget * parent, Formats const & f)
1906 : FormatValidator(parent, f)
1909 QString toString(Format const & format) const
1911 return toqstr(format.name());
1916 /////////////////////////////////////////////////////////////////////
1918 // FormatPrettynameValidator
1920 /////////////////////////////////////////////////////////////////////
1922 class FormatPrettynameValidator : public FormatValidator
1925 FormatPrettynameValidator(QWidget * parent, Formats const & f)
1926 : FormatValidator(parent, f)
1929 QString toString(Format const & format) const
1931 return toqstr(translateIfPossible(format.prettyname()));
1936 /////////////////////////////////////////////////////////////////////
1940 /////////////////////////////////////////////////////////////////////
1942 PrefFileformats::PrefFileformats(GuiPreferences * form)
1943 : PrefModule(catFiles, N_("File Formats"), form)
1947 formatED->setValidator(new FormatNameValidator(formatsCB, form_->formats()));
1948 formatsCB->setValidator(new FormatPrettynameValidator(formatsCB, form_->formats()));
1949 extensionsED->setValidator(new NoNewLineValidator(extensionsED));
1950 shortcutED->setValidator(new NoNewLineValidator(shortcutED));
1951 editorED->setValidator(new NoNewLineValidator(editorED));
1952 viewerED->setValidator(new NoNewLineValidator(viewerED));
1953 copierED->setValidator(new NoNewLineValidator(copierED));
1955 connect(documentCB, SIGNAL(clicked()),
1956 this, SLOT(setFlags()));
1957 connect(vectorCB, SIGNAL(clicked()),
1958 this, SLOT(setFlags()));
1959 connect(exportMenuCB, SIGNAL(clicked()),
1960 this, SLOT(setFlags()));
1961 connect(formatsCB->lineEdit(), SIGNAL(editingFinished()),
1962 this, SLOT(updatePrettyname()));
1963 connect(formatsCB->lineEdit(), SIGNAL(textEdited(QString)),
1964 this, SIGNAL(changed()));
1965 connect(defaultFormatCB, SIGNAL(activated(QString)),
1966 this, SIGNAL(changed()));
1967 connect(defaultOTFFormatCB, SIGNAL(activated(QString)),
1968 this, SIGNAL(changed()));
1969 connect(defaultPlatexFormatCB, SIGNAL(activated(QString)),
1970 this, SIGNAL(changed()));
1971 connect(viewerCO, SIGNAL(activated(int)),
1972 this, SIGNAL(changed()));
1973 connect(editorCO, SIGNAL(activated(int)),
1974 this, SIGNAL(changed()));
1980 string const l10n_shortcut(docstring const & prettyname, string const & shortcut)
1982 if (shortcut.empty())
1985 string l10n_format =
1986 to_utf8(_(to_utf8(prettyname) + '|' + shortcut));
1987 return split(l10n_format, '|');
1993 void PrefFileformats::applyRC(LyXRC & rc) const
1995 QString const default_format = defaultFormatCB->itemData(
1996 defaultFormatCB->currentIndex()).toString();
1997 rc.default_view_format = fromqstr(default_format);
1998 QString const default_otf_format = defaultOTFFormatCB->itemData(
1999 defaultOTFFormatCB->currentIndex()).toString();
2000 rc.default_otf_view_format = fromqstr(default_otf_format);
2001 QString const default_platex_format = defaultPlatexFormatCB->itemData(
2002 defaultPlatexFormatCB->currentIndex()).toString();
2003 rc.default_platex_view_format = fromqstr(default_platex_format);
2007 void PrefFileformats::updateRC(LyXRC const & rc)
2009 viewer_alternatives = rc.viewer_alternatives;
2010 editor_alternatives = rc.editor_alternatives;
2011 bool const init = defaultFormatCB->currentText().isEmpty();
2015 defaultFormatCB->findData(toqstr(rc.default_view_format));
2016 defaultFormatCB->setCurrentIndex(pos);
2017 pos = defaultOTFFormatCB->findData(toqstr(rc.default_otf_view_format));
2018 defaultOTFFormatCB->setCurrentIndex(pos);
2019 defaultOTFFormatCB->setCurrentIndex(pos);
2020 pos = defaultPlatexFormatCB->findData(toqstr(rc.default_platex_view_format));
2021 defaultPlatexFormatCB->setCurrentIndex(pos);
2022 defaultPlatexFormatCB->setCurrentIndex(pos);
2027 void PrefFileformats::updateView()
2029 QString const current = formatsCB->currentText();
2030 QString const current_def = defaultFormatCB->currentText();
2031 QString const current_def_otf = defaultOTFFormatCB->currentText();
2032 QString const current_def_platex = defaultPlatexFormatCB->currentText();
2034 // update comboboxes with formats
2035 formatsCB->blockSignals(true);
2036 defaultFormatCB->blockSignals(true);
2037 defaultOTFFormatCB->blockSignals(true);
2038 defaultPlatexFormatCB->blockSignals(true);
2040 defaultFormatCB->clear();
2041 defaultOTFFormatCB->clear();
2042 defaultPlatexFormatCB->clear();
2043 form_->formats().sort();
2044 for (Format const & f : form_->formats()) {
2045 QString const prettyname = toqstr(translateIfPossible(f.prettyname()));
2046 formatsCB->addItem(prettyname,
2047 QVariant(form_->formats().getNumber(f.name())));
2048 if (f.viewer().empty())
2050 if (form_->converters().isReachable("xhtml", f.name())
2051 || form_->converters().isReachable("dviluatex", f.name())
2052 || form_->converters().isReachable("luatex", f.name())
2053 || form_->converters().isReachable("xetex", f.name())) {
2054 defaultFormatCB->addItem(prettyname,
2055 QVariant(toqstr(f.name())));
2056 defaultOTFFormatCB->addItem(prettyname,
2057 QVariant(toqstr(f.name())));
2059 if (form_->converters().isReachable("latex", f.name())
2060 || form_->converters().isReachable("pdflatex", f.name()))
2061 defaultFormatCB->addItem(prettyname,
2062 QVariant(toqstr(f.name())));
2063 if (form_->converters().isReachable("platex", f.name()))
2064 defaultPlatexFormatCB->addItem(prettyname,
2065 QVariant(toqstr(f.name())));
2069 // restore selections
2070 int item = formatsCB->findText(current, Qt::MatchExactly);
2071 formatsCB->setCurrentIndex(item < 0 ? 0 : item);
2072 on_formatsCB_currentIndexChanged(item < 0 ? 0 : item);
2073 item = defaultFormatCB->findText(current_def, Qt::MatchExactly);
2074 defaultFormatCB->setCurrentIndex(item < 0 ? 0 : item);
2075 item = defaultOTFFormatCB->findText(current_def_otf, Qt::MatchExactly);
2076 defaultOTFFormatCB->setCurrentIndex(item < 0 ? 0 : item);
2077 item = defaultPlatexFormatCB->findText(current_def_platex, Qt::MatchExactly);
2078 defaultPlatexFormatCB->setCurrentIndex(item < 0 ? 0 : item);
2079 formatsCB->blockSignals(false);
2080 defaultFormatCB->blockSignals(false);
2081 defaultOTFFormatCB->blockSignals(false);
2082 defaultPlatexFormatCB->blockSignals(false);
2086 void PrefFileformats::on_formatsCB_currentIndexChanged(int i)
2088 if (form_->formats().empty())
2090 int const nr = formatsCB->itemData(i).toInt();
2091 Format const f = form_->formats().get(nr);
2093 formatED->setText(toqstr(f.name()));
2094 copierED->setText(toqstr(form_->movers().command(f.name())));
2095 extensionsED->setText(toqstr(f.extensions()));
2096 mimeED->setText(toqstr(f.mime()));
2097 shortcutED->setText(
2098 toqstr(l10n_shortcut(f.prettyname(), f.shortcut())));
2099 documentCB->setChecked((f.documentFormat()));
2100 vectorCB->setChecked((f.vectorFormat()));
2101 exportMenuCB->setChecked((f.inExportMenu()));
2102 exportMenuCB->setEnabled((f.documentFormat()));
2108 void PrefFileformats::setFlags()
2110 int flags = Format::none;
2111 if (documentCB->isChecked())
2112 flags |= Format::document;
2113 if (vectorCB->isChecked())
2114 flags |= Format::vector;
2115 if (exportMenuCB->isChecked())
2116 flags |= Format::export_menu;
2117 currentFormat().setFlags(flags);
2118 exportMenuCB->setEnabled(documentCB->isChecked());
2123 void PrefFileformats::on_copierED_textEdited(const QString & s)
2125 string const fmt = fromqstr(formatED->text());
2126 form_->movers().set(fmt, fromqstr(s));
2131 void PrefFileformats::on_extensionsED_textEdited(const QString & s)
2133 currentFormat().setExtensions(fromqstr(s));
2138 void PrefFileformats::on_viewerED_textEdited(const QString & s)
2140 currentFormat().setViewer(fromqstr(s));
2145 void PrefFileformats::on_editorED_textEdited(const QString & s)
2147 currentFormat().setEditor(fromqstr(s));
2152 void PrefFileformats::on_mimeED_textEdited(const QString & s)
2154 currentFormat().setMime(fromqstr(s));
2159 void PrefFileformats::on_shortcutED_textEdited(const QString & s)
2161 string const new_shortcut = fromqstr(s);
2162 if (new_shortcut == l10n_shortcut(currentFormat().prettyname(),
2163 currentFormat().shortcut()))
2165 currentFormat().setShortcut(new_shortcut);
2170 void PrefFileformats::on_formatED_editingFinished()
2172 string const newname = fromqstr(formatED->displayText());
2173 string const oldname = currentFormat().name();
2174 if (newname == oldname)
2176 if (form_->converters().formatIsUsed(oldname)) {
2177 Alert::error(_("Format in use"),
2178 _("You cannot change a format's short name "
2179 "if the format is used by a converter. "
2180 "Please remove the converter first."));
2185 currentFormat().setName(newname);
2190 void PrefFileformats::on_formatED_textChanged(const QString &)
2192 QString t = formatED->text();
2194 bool valid = formatED->validator()->validate(t, p) == QValidator::Acceptable;
2195 setValid(formatLA, valid);
2199 void PrefFileformats::on_formatsCB_editTextChanged(const QString &)
2201 QString t = formatsCB->currentText();
2203 bool valid = formatsCB->validator()->validate(t, p) == QValidator::Acceptable;
2204 setValid(formatsLA, valid);
2208 void PrefFileformats::updatePrettyname()
2210 QString const newname = formatsCB->currentText();
2211 if (newname == toqstr(translateIfPossible(currentFormat().prettyname())))
2214 currentFormat().setPrettyname(qstring_to_ucs4(newname));
2222 void updateComboBox(LyXRC::Alternatives const & alts,
2223 string const & fmt, QComboBox * combo)
2225 LyXRC::Alternatives::const_iterator it =
2227 if (it != alts.end()) {
2228 LyXRC::CommandSet const & cmds = it->second;
2229 LyXRC::CommandSet::const_iterator sit =
2231 LyXRC::CommandSet::const_iterator const sen =
2233 for (; sit != sen; ++sit) {
2234 QString const qcmd = toqstr(*sit);
2235 combo->addItem(qcmd, qcmd);
2242 void PrefFileformats::updateViewers()
2244 Format const f = currentFormat();
2245 viewerCO->blockSignals(true);
2247 viewerCO->addItem(qt_("None"), QString());
2248 updateComboBox(viewer_alternatives, f.name(), viewerCO);
2249 viewerCO->addItem(qt_("Custom"), QString("custom viewer"));
2250 viewerCO->blockSignals(false);
2252 int pos = viewerCO->findData(toqstr(f.viewer()));
2255 viewerED->setEnabled(false);
2256 viewerCO->setCurrentIndex(pos);
2258 viewerED->setEnabled(true);
2259 viewerED->setText(toqstr(f.viewer()));
2260 viewerCO->setCurrentIndex(viewerCO->findData(toqstr("custom viewer")));
2265 void PrefFileformats::updateEditors()
2267 Format const f = currentFormat();
2268 editorCO->blockSignals(true);
2270 editorCO->addItem(qt_("None"), QString());
2271 updateComboBox(editor_alternatives, f.name(), editorCO);
2272 editorCO->addItem(qt_("Custom"), QString("custom editor"));
2273 editorCO->blockSignals(false);
2275 int pos = editorCO->findData(toqstr(f.editor()));
2278 editorED->setEnabled(false);
2279 editorCO->setCurrentIndex(pos);
2281 editorED->setEnabled(true);
2282 editorED->setText(toqstr(f.editor()));
2283 editorCO->setCurrentIndex(editorCO->findData(toqstr("custom editor")));
2288 void PrefFileformats::on_viewerCO_currentIndexChanged(int i)
2290 bool const custom = viewerCO->itemData(i).toString() == "custom viewer";
2291 viewerED->setEnabled(custom);
2293 currentFormat().setViewer(fromqstr(viewerCO->itemData(i).toString()));
2297 void PrefFileformats::on_editorCO_currentIndexChanged(int i)
2299 bool const custom = editorCO->itemData(i).toString() == "custom editor";
2300 editorED->setEnabled(custom);
2302 currentFormat().setEditor(fromqstr(editorCO->itemData(i).toString()));
2306 Format & PrefFileformats::currentFormat()
2308 int const i = formatsCB->currentIndex();
2309 int const nr = formatsCB->itemData(i).toInt();
2310 return form_->formats().get(nr);
2314 void PrefFileformats::on_formatNewPB_clicked()
2316 form_->formats().add("", "", docstring(), "", "", "", "", Format::none);
2318 formatsCB->setCurrentIndex(0);
2319 formatsCB->setFocus(Qt::OtherFocusReason);
2323 void PrefFileformats::on_formatRemovePB_clicked()
2325 int const i = formatsCB->currentIndex();
2326 int const nr = formatsCB->itemData(i).toInt();
2327 string const current_text = form_->formats().get(nr).name();
2328 if (form_->converters().formatIsUsed(current_text)) {
2329 Alert::error(_("Format in use"),
2330 _("Cannot remove a Format used by a Converter. "
2331 "Remove the converter first."));
2335 form_->formats().erase(current_text);
2338 on_formatsCB_editTextChanged(formatsCB->currentText());
2343 /////////////////////////////////////////////////////////////////////
2347 /////////////////////////////////////////////////////////////////////
2349 PrefLanguage::PrefLanguage(GuiPreferences * form)
2350 : PrefModule(catLanguage, N_("Language"), form)
2354 connect(visualCursorRB, SIGNAL(clicked()),
2355 this, SIGNAL(changed()));
2356 connect(logicalCursorRB, SIGNAL(clicked()),
2357 this, SIGNAL(changed()));
2358 connect(markForeignCB, SIGNAL(clicked()),
2359 this, SIGNAL(changed()));
2360 connect(autoBeginCB, SIGNAL(clicked()),
2361 this, SIGNAL(changed()));
2362 connect(autoEndCB, SIGNAL(clicked()),
2363 this, SIGNAL(changed()));
2364 connect(languagePackageCO, SIGNAL(activated(int)),
2365 this, SIGNAL(changed()));
2366 connect(languagePackageED, SIGNAL(textChanged(QString)),
2367 this, SIGNAL(changed()));
2368 connect(globalCB, SIGNAL(clicked()),
2369 this, SIGNAL(changed()));
2370 connect(startCommandED, SIGNAL(textChanged(QString)),
2371 this, SIGNAL(changed()));
2372 connect(endCommandED, SIGNAL(textChanged(QString)),
2373 this, SIGNAL(changed()));
2374 connect(uiLanguageCO, SIGNAL(activated(int)),
2375 this, SIGNAL(changed()));
2376 connect(defaultDecimalPointLE, SIGNAL(textChanged(QString)),
2377 this, SIGNAL(changed()));
2378 connect(defaultLengthUnitCO, SIGNAL(activated(int)),
2379 this, SIGNAL(changed()));
2381 languagePackageED->setValidator(new NoNewLineValidator(languagePackageED));
2382 startCommandED->setValidator(new NoNewLineValidator(startCommandED));
2383 endCommandED->setValidator(new NoNewLineValidator(endCommandED));
2385 defaultDecimalPointLE->setInputMask("X; ");
2386 defaultDecimalPointLE->setMaxLength(1);
2388 defaultLengthUnitCO->addItem(lyx::qt_(unit_name_gui[Length::CM]), Length::CM);
2389 defaultLengthUnitCO->addItem(lyx::qt_(unit_name_gui[Length::IN]), Length::IN);
2391 QAbstractItemModel * language_model = guiApp->languageModel();
2392 language_model->sort(0);
2393 uiLanguageCO->blockSignals(true);
2394 uiLanguageCO->clear();
2395 uiLanguageCO->addItem(qt_("Default"), toqstr("auto"));
2396 for (int i = 0; i != language_model->rowCount(); ++i) {
2397 QModelIndex index = language_model->index(i, 0);
2398 // Filter the list based on the available translation and add
2399 // each language code only once
2400 string const name = fromqstr(index.data(Qt::UserRole).toString());
2401 Language const * lang = languages.getLanguage(name);
2404 // never remove the currently selected language
2405 if (name != form->rc().gui_language
2406 && name != lyxrc.gui_language
2407 && (!Messages::available(lang->code())
2408 || !lang->hasGuiSupport()))
2410 uiLanguageCO->addItem(index.data(Qt::DisplayRole).toString(),
2411 index.data(Qt::UserRole).toString());
2413 uiLanguageCO->blockSignals(false);
2417 void PrefLanguage::on_uiLanguageCO_currentIndexChanged(int)
2419 QMessageBox::information(this, qt_("LyX needs to be restarted!"),
2420 qt_("The change of user interface language will be fully "
2421 "effective only after a restart."));
2425 void PrefLanguage::on_languagePackageCO_currentIndexChanged(int i)
2427 languagePackageED->setEnabled(i == 2);
2431 void PrefLanguage::applyRC(LyXRC & rc) const
2433 rc.visual_cursor = visualCursorRB->isChecked();
2434 rc.mark_foreign_language = markForeignCB->isChecked();
2435 rc.language_auto_begin = autoBeginCB->isChecked();
2436 rc.language_auto_end = autoEndCB->isChecked();
2437 int const p = languagePackageCO->currentIndex();
2439 rc.language_package_selection = LyXRC::LP_AUTO;
2441 rc.language_package_selection = LyXRC::LP_BABEL;
2443 rc.language_package_selection = LyXRC::LP_CUSTOM;
2445 rc.language_package_selection = LyXRC::LP_NONE;
2446 rc.language_custom_package = fromqstr(languagePackageED->text());
2447 rc.language_global_options = globalCB->isChecked();
2448 rc.language_command_begin = fromqstr(startCommandED->text());
2449 rc.language_command_end = fromqstr(endCommandED->text());
2450 rc.gui_language = fromqstr(
2451 uiLanguageCO->itemData(uiLanguageCO->currentIndex()).toString());
2452 rc.default_decimal_point = fromqstr(defaultDecimalPointLE->text());
2453 rc.default_length_unit = (Length::UNIT) defaultLengthUnitCO->itemData(defaultLengthUnitCO->currentIndex()).toInt();
2457 void PrefLanguage::updateRC(LyXRC const & rc)
2459 if (rc.visual_cursor)
2460 visualCursorRB->setChecked(true);
2462 logicalCursorRB->setChecked(true);
2463 markForeignCB->setChecked(rc.mark_foreign_language);
2464 autoBeginCB->setChecked(rc.language_auto_begin);
2465 autoEndCB->setChecked(rc.language_auto_end);
2466 languagePackageCO->setCurrentIndex(rc.language_package_selection);
2467 languagePackageED->setText(toqstr(rc.language_custom_package));
2468 languagePackageED->setEnabled(languagePackageCO->currentIndex() == 2);
2469 globalCB->setChecked(rc.language_global_options);
2470 startCommandED->setText(toqstr(rc.language_command_begin));
2471 endCommandED->setText(toqstr(rc.language_command_end));
2472 defaultDecimalPointLE->setText(toqstr(rc.default_decimal_point));
2473 int pos = defaultLengthUnitCO->findData(int(rc.default_length_unit));
2474 defaultLengthUnitCO->setCurrentIndex(pos);
2476 pos = uiLanguageCO->findData(toqstr(rc.gui_language));
2477 uiLanguageCO->blockSignals(true);
2478 uiLanguageCO->setCurrentIndex(pos);
2479 uiLanguageCO->blockSignals(false);
2483 /////////////////////////////////////////////////////////////////////
2485 // PrefUserInterface
2487 /////////////////////////////////////////////////////////////////////
2489 PrefUserInterface::PrefUserInterface(GuiPreferences * form)
2490 : PrefModule(catLookAndFeel, N_("User Interface"), form)
2494 connect(uiFilePB, SIGNAL(clicked()),
2495 this, SLOT(selectUi()));
2496 connect(uiFileED, SIGNAL(textChanged(QString)),
2497 this, SIGNAL(changed()));
2498 connect(iconSetCO, SIGNAL(activated(int)),
2499 this, SIGNAL(changed()));
2500 connect(useSystemThemeIconsCB, SIGNAL(clicked()),
2501 this, SIGNAL(changed()));
2502 connect(lastfilesSB, SIGNAL(valueChanged(int)),
2503 this, SIGNAL(changed()));
2504 connect(tooltipCB, SIGNAL(toggled(bool)),
2505 this, SIGNAL(changed()));
2506 lastfilesSB->setMaximum(maxlastfiles);
2508 iconSetCO->addItem(qt_("Default"), QString());
2509 iconSetCO->addItem(qt_("Classic"), "classic");
2510 iconSetCO->addItem(qt_("Oxygen"), "oxygen");
2512 #if (!(defined Q_WS_X11 || defined(QPA_XCB)) || QT_VERSION < 0x040600)
2513 useSystemThemeIconsCB->hide();
2518 void PrefUserInterface::applyRC(LyXRC & rc) const
2520 rc.icon_set = fromqstr(iconSetCO->itemData(
2521 iconSetCO->currentIndex()).toString());
2523 rc.ui_file = internal_path(fromqstr(uiFileED->text()));
2524 rc.use_system_theme_icons = useSystemThemeIconsCB->isChecked();
2525 rc.num_lastfiles = lastfilesSB->value();
2526 rc.use_tooltip = tooltipCB->isChecked();
2530 void PrefUserInterface::updateRC(LyXRC const & rc)
2532 int iconset = iconSetCO->findData(toqstr(rc.icon_set));
2535 iconSetCO->setCurrentIndex(iconset);
2536 useSystemThemeIconsCB->setChecked(rc.use_system_theme_icons);
2537 uiFileED->setText(toqstr(external_path(rc.ui_file)));
2538 lastfilesSB->setValue(rc.num_lastfiles);
2539 tooltipCB->setChecked(rc.use_tooltip);
2543 void PrefUserInterface::selectUi()
2545 QString file = form_->browseUI(internalPath(uiFileED->text()));
2546 if (!file.isEmpty())
2547 uiFileED->setText(file);
2551 /////////////////////////////////////////////////////////////////////
2553 // PrefDocumentHandling
2555 /////////////////////////////////////////////////////////////////////
2557 PrefDocHandling::PrefDocHandling(GuiPreferences * form)
2558 : PrefModule(catLookAndFeel, N_("Document Handling"), form)
2562 connect(autoSaveCB, SIGNAL(toggled(bool)),
2563 autoSaveSB, SLOT(setEnabled(bool)));
2564 connect(autoSaveCB, SIGNAL(toggled(bool)),
2565 TextLabel1, SLOT(setEnabled(bool)));
2566 connect(openDocumentsInTabsCB, SIGNAL(clicked()),
2567 this, SIGNAL(changed()));
2568 connect(singleInstanceCB, SIGNAL(clicked()),
2569 this, SIGNAL(changed()));
2570 connect(singleCloseTabButtonCB, SIGNAL(clicked()),
2571 this, SIGNAL(changed()));
2572 connect(closeLastViewCO, SIGNAL(activated(int)),
2573 this, SIGNAL(changed()));
2574 connect(restoreCursorCB, SIGNAL(clicked()),
2575 this, SIGNAL(changed()));
2576 connect(loadSessionCB, SIGNAL(clicked()),
2577 this, SIGNAL(changed()));
2578 connect(allowGeometrySessionCB, SIGNAL(clicked()),
2579 this, SIGNAL(changed()));
2580 connect(autoSaveSB, SIGNAL(valueChanged(int)),
2581 this, SIGNAL(changed()));
2582 connect(autoSaveCB, SIGNAL(clicked()),
2583 this, SIGNAL(changed()));
2584 connect(backupCB, SIGNAL(clicked()),
2585 this, SIGNAL(changed()));
2586 connect(saveCompressedCB, SIGNAL(clicked()),
2587 this, SIGNAL(changed()));
2588 connect(saveOriginCB, SIGNAL(clicked()),
2589 this, SIGNAL(changed()));
2593 void PrefDocHandling::applyRC(LyXRC & rc) const
2595 rc.use_lastfilepos = restoreCursorCB->isChecked();
2596 rc.load_session = loadSessionCB->isChecked();
2597 rc.allow_geometry_session = allowGeometrySessionCB->isChecked();
2598 rc.autosave = autoSaveCB->isChecked() ? autoSaveSB->value() * 60 : 0;
2599 rc.make_backup = backupCB->isChecked();
2600 rc.save_compressed = saveCompressedCB->isChecked();
2601 rc.save_origin = saveOriginCB->isChecked();
2602 rc.open_buffers_in_tabs = openDocumentsInTabsCB->isChecked();
2603 rc.single_instance = singleInstanceCB->isChecked();
2604 rc.single_close_tab_button = singleCloseTabButtonCB->isChecked();
2606 switch (closeLastViewCO->currentIndex()) {
2608 rc.close_buffer_with_last_view = "yes";
2611 rc.close_buffer_with_last_view = "no";
2614 rc.close_buffer_with_last_view = "ask";
2622 void PrefDocHandling::updateRC(LyXRC const & rc)
2624 restoreCursorCB->setChecked(rc.use_lastfilepos);
2625 loadSessionCB->setChecked(rc.load_session);
2626 allowGeometrySessionCB->setChecked(rc.allow_geometry_session);
2627 // convert to minutes
2628 bool autosave = rc.autosave > 0;
2629 int mins = rc.autosave / 60;
2632 autoSaveSB->setValue(mins);
2633 autoSaveCB->setChecked(autosave);
2634 autoSaveSB->setEnabled(autosave);
2635 backupCB->setChecked(rc.make_backup);
2636 saveCompressedCB->setChecked(rc.save_compressed);
2637 saveOriginCB->setChecked(rc.save_origin);
2638 openDocumentsInTabsCB->setChecked(rc.open_buffers_in_tabs);
2639 singleInstanceCB->setChecked(rc.single_instance && !rc.lyxpipes.empty());
2640 singleInstanceCB->setEnabled(!rc.lyxpipes.empty());
2641 singleCloseTabButtonCB->setChecked(rc.single_close_tab_button);
2642 if (rc.close_buffer_with_last_view == "yes")
2643 closeLastViewCO->setCurrentIndex(0);
2644 else if (rc.close_buffer_with_last_view == "no")
2645 closeLastViewCO->setCurrentIndex(1);
2646 else if (rc.close_buffer_with_last_view == "ask")
2647 closeLastViewCO->setCurrentIndex(2);
2651 void PrefDocHandling::on_clearSessionPB_clicked()
2653 guiApp->clearSession();
2658 /////////////////////////////////////////////////////////////////////
2662 /////////////////////////////////////////////////////////////////////
2664 PrefEdit::PrefEdit(GuiPreferences * form)
2665 : PrefModule(catEditing, N_("Control"), form)
2669 connect(cursorFollowsCB, SIGNAL(clicked()),
2670 this, SIGNAL(changed()));
2671 connect(scrollBelowCB, SIGNAL(clicked()),
2672 this, SIGNAL(changed()));
2673 connect(macLikeCursorMovementCB, SIGNAL(clicked()),
2674 this, SIGNAL(changed()));
2675 connect(sortEnvironmentsCB, SIGNAL(clicked()),
2676 this, SIGNAL(changed()));
2677 connect(groupEnvironmentsCB, SIGNAL(clicked()),
2678 this, SIGNAL(changed()));
2679 connect(macroEditStyleCO, SIGNAL(activated(int)),
2680 this, SIGNAL(changed()));
2681 connect(cursorWidthSB, SIGNAL(valueChanged(int)),
2682 this, SIGNAL(changed()));
2683 connect(fullscreenLimitGB, SIGNAL(clicked()),
2684 this, SIGNAL(changed()));
2685 connect(fullscreenWidthSB, SIGNAL(valueChanged(int)),
2686 this, SIGNAL(changed()));
2687 connect(toggleTabbarCB, SIGNAL(toggled(bool)),
2688 this, SIGNAL(changed()));
2689 connect(toggleMenubarCB, SIGNAL(toggled(bool)),
2690 this, SIGNAL(changed()));
2691 connect(toggleScrollbarCB, SIGNAL(toggled(bool)),
2692 this, SIGNAL(changed()));
2693 connect(toggleStatusbarCB, SIGNAL(toggled(bool)),
2694 this, SIGNAL(changed()));
2695 connect(toggleToolbarsCB, SIGNAL(toggled(bool)),
2696 this, SIGNAL(changed()));
2700 void PrefEdit::applyRC(LyXRC & rc) const
2702 rc.cursor_follows_scrollbar = cursorFollowsCB->isChecked();
2703 rc.scroll_below_document = scrollBelowCB->isChecked();
2704 rc.mac_like_cursor_movement = macLikeCursorMovementCB->isChecked();
2705 rc.sort_layouts = sortEnvironmentsCB->isChecked();
2706 rc.group_layouts = groupEnvironmentsCB->isChecked();
2707 switch (macroEditStyleCO->currentIndex()) {
2708 case 0: rc.macro_edit_style = LyXRC::MACRO_EDIT_INLINE_BOX; break;
2709 case 1: rc.macro_edit_style = LyXRC::MACRO_EDIT_INLINE; break;
2710 case 2: rc.macro_edit_style = LyXRC::MACRO_EDIT_LIST; break;
2712 rc.cursor_width = cursorWidthSB->value();
2713 rc.full_screen_toolbars = toggleToolbarsCB->isChecked();
2714 rc.full_screen_scrollbar = toggleScrollbarCB->isChecked();
2715 rc.full_screen_statusbar = toggleStatusbarCB->isChecked();
2716 rc.full_screen_tabbar = toggleTabbarCB->isChecked();
2717 rc.full_screen_menubar = toggleMenubarCB->isChecked();
2718 rc.full_screen_width = fullscreenWidthSB->value();
2719 rc.full_screen_limit = fullscreenLimitGB->isChecked();
2723 void PrefEdit::updateRC(LyXRC const & rc)
2725 cursorFollowsCB->setChecked(rc.cursor_follows_scrollbar);
2726 scrollBelowCB->setChecked(rc.scroll_below_document);
2727 macLikeCursorMovementCB->setChecked(rc.mac_like_cursor_movement);
2728 sortEnvironmentsCB->setChecked(rc.sort_layouts);
2729 groupEnvironmentsCB->setChecked(rc.group_layouts);
2730 macroEditStyleCO->setCurrentIndex(rc.macro_edit_style);
2731 cursorWidthSB->setValue(rc.cursor_width);
2732 toggleScrollbarCB->setChecked(rc.full_screen_scrollbar);
2733 toggleStatusbarCB->setChecked(rc.full_screen_statusbar);
2734 toggleToolbarsCB->setChecked(rc.full_screen_toolbars);
2735 toggleTabbarCB->setChecked(rc.full_screen_tabbar);
2736 toggleMenubarCB->setChecked(rc.full_screen_menubar);
2737 fullscreenWidthSB->setValue(rc.full_screen_width);
2738 fullscreenLimitGB->setChecked(rc.full_screen_limit);
2742 /////////////////////////////////////////////////////////////////////
2746 /////////////////////////////////////////////////////////////////////
2749 GuiShortcutDialog::GuiShortcutDialog(QWidget * parent) : QDialog(parent)
2751 Ui::shortcutUi::setupUi(this);
2752 QDialog::setModal(true);
2756 PrefShortcuts::PrefShortcuts(GuiPreferences * form)
2757 : PrefModule(catEditing, N_("Shortcuts"), form),
2758 editItem_(0), mathItem_(0), bufferItem_(0), layoutItem_(0),
2763 shortcutsTW->setColumnCount(2);
2764 shortcutsTW->headerItem()->setText(0, qt_("Function"));
2765 shortcutsTW->headerItem()->setText(1, qt_("Shortcut"));
2766 shortcutsTW->setSortingEnabled(true);
2767 // Multi-selection can be annoying.
2768 // shortcutsTW->setSelectionMode(QAbstractItemView::MultiSelection);
2770 connect(bindFilePB, SIGNAL(clicked()),
2771 this, SLOT(selectBind()));
2772 connect(bindFileED, SIGNAL(textChanged(QString)),
2773 this, SIGNAL(changed()));
2775 shortcut_ = new GuiShortcutDialog(this);
2776 shortcut_bc_.setPolicy(ButtonPolicy::OkCancelPolicy);
2777 shortcut_bc_.setOK(shortcut_->buttonBox->button(QDialogButtonBox::Ok));
2778 shortcut_bc_.setCancel(shortcut_->buttonBox->button(QDialogButtonBox::Cancel));
2780 connect(shortcut_->buttonBox, SIGNAL(accepted()),
2781 this, SIGNAL(changed()));
2782 connect(shortcut_->buttonBox, SIGNAL(rejected()),
2783 shortcut_, SLOT(reject()));
2784 connect(shortcut_->clearPB, SIGNAL(clicked()),
2785 this, SLOT(shortcutClearPressed()));
2786 connect(shortcut_->removePB, SIGNAL(clicked()),
2787 this, SLOT(shortcutRemovePressed()));
2788 connect(shortcut_->buttonBox, SIGNAL(accepted()),
2789 this, SLOT(shortcutOkPressed()));
2790 connect(shortcut_->buttonBox, SIGNAL(rejected()),
2791 this, SLOT(shortcutCancelPressed()));
2795 void PrefShortcuts::applyRC(LyXRC & rc) const
2797 rc.bind_file = internal_path(fromqstr(bindFileED->text()));
2798 // write user_bind and user_unbind to .lyx/bind/user.bind
2799 FileName bind_dir(addPath(package().user_support().absFileName(), "bind"));
2800 if (!bind_dir.exists() && !bind_dir.createDirectory(0777)) {
2801 lyxerr << "LyX could not create the user bind directory '"
2802 << bind_dir << "'. All user-defined key bindings will be lost." << endl;
2805 if (!bind_dir.isDirWritable()) {
2806 lyxerr << "LyX could not write to the user bind directory '"
2807 << bind_dir << "'. All user-defined key bindings will be lost." << endl;
2810 FileName user_bind_file(bind_dir.absFileName() + "/user.bind");
2811 user_unbind_.write(user_bind_file.toFilesystemEncoding(), false, true);
2812 user_bind_.write(user_bind_file.toFilesystemEncoding(), true, false);
2813 // immediately apply the keybindings. Why this is not done before?
2814 // The good thing is that the menus are updated automatically.
2815 theTopLevelKeymap().clear();
2816 theTopLevelKeymap().read("site");
2817 theTopLevelKeymap().read(rc.bind_file, 0, KeyMap::Fallback);
2818 theTopLevelKeymap().read("user", 0, KeyMap::MissingOK);
2822 void PrefShortcuts::updateRC(LyXRC const & rc)
2824 bindFileED->setText(toqstr(external_path(rc.bind_file)));
2826 system_bind_.clear();
2828 user_unbind_.clear();
2829 system_bind_.read("site");
2830 system_bind_.read(rc.bind_file);
2831 // \unbind in user.bind is added to user_unbind_
2832 user_bind_.read("user", &user_unbind_, KeyMap::MissingOK);
2833 updateShortcutsTW();
2837 void PrefShortcuts::updateShortcutsTW()
2839 shortcutsTW->clear();
2841 editItem_ = new QTreeWidgetItem(shortcutsTW);
2842 editItem_->setText(0, qt_("Cursor, Mouse and Editing Functions"));
2843 editItem_->setFlags(editItem_->flags() & ~Qt::ItemIsSelectable);
2845 mathItem_ = new QTreeWidgetItem(shortcutsTW);
2846 mathItem_->setText(0, qt_("Mathematical Symbols"));
2847 mathItem_->setFlags(mathItem_->flags() & ~Qt::ItemIsSelectable);
2849 bufferItem_ = new QTreeWidgetItem(shortcutsTW);
2850 bufferItem_->setText(0, qt_("Document and Window"));
2851 bufferItem_->setFlags(bufferItem_->flags() & ~Qt::ItemIsSelectable);
2853 layoutItem_ = new QTreeWidgetItem(shortcutsTW);
2854 layoutItem_->setText(0, qt_("Font, Layouts and Textclasses"));
2855 layoutItem_->setFlags(layoutItem_->flags() & ~Qt::ItemIsSelectable);
2857 systemItem_ = new QTreeWidgetItem(shortcutsTW);
2858 systemItem_->setText(0, qt_("System and Miscellaneous"));
2859 systemItem_->setFlags(systemItem_->flags() & ~Qt::ItemIsSelectable);
2861 // listBindings(unbound=true) lists all bound and unbound lfuns
2862 // Items in this list is tagged by its source.
2863 KeyMap::BindingList bindinglist = system_bind_.listBindings(true,
2865 KeyMap::BindingList user_bindinglist = user_bind_.listBindings(false,
2867 KeyMap::BindingList user_unbindinglist = user_unbind_.listBindings(false,
2868 KeyMap::UserUnbind);
2869 bindinglist.insert(bindinglist.end(), user_bindinglist.begin(),
2870 user_bindinglist.end());
2871 bindinglist.insert(bindinglist.end(), user_unbindinglist.begin(),
2872 user_unbindinglist.end());
2874 KeyMap::BindingList::const_iterator it = bindinglist.begin();
2875 KeyMap::BindingList::const_iterator it_end = bindinglist.end();
2876 for (; it != it_end; ++it)
2877 insertShortcutItem(it->request, it->sequence, it->tag);
2879 shortcutsTW->sortItems(0, Qt::AscendingOrder);
2880 on_shortcutsTW_itemSelectionChanged();
2881 on_searchLE_textEdited();
2882 shortcutsTW->resizeColumnToContents(0);
2887 KeyMap::ItemType PrefShortcuts::itemType(QTreeWidgetItem & item)
2889 return static_cast<KeyMap::ItemType>(item.data(0, Qt::UserRole).toInt());
2894 bool PrefShortcuts::isAlwaysHidden(QTreeWidgetItem & item)
2896 // Hide rebound system settings that are empty
2897 return itemType(item) == KeyMap::UserUnbind && item.text(1).isEmpty();
2901 void PrefShortcuts::setItemType(QTreeWidgetItem * item, KeyMap::ItemType tag)
2903 item->setData(0, Qt::UserRole, QVariant(tag));
2907 case KeyMap::System:
2909 case KeyMap::UserBind:
2912 case KeyMap::UserUnbind:
2913 font.setStrikeOut(true);
2915 // this item is not displayed now.
2916 case KeyMap::UserExtraUnbind:
2917 font.setStrikeOut(true);
2920 item->setHidden(isAlwaysHidden(*item));
2921 item->setFont(1, font);
2925 QTreeWidgetItem * PrefShortcuts::insertShortcutItem(FuncRequest const & lfun,
2926 KeySequence const & seq, KeyMap::ItemType tag)
2928 FuncCode const action = lfun.action();
2929 string const action_name = lyxaction.getActionName(action);
2930 QString const lfun_name = toqstr(from_utf8(action_name)
2931 + ' ' + lfun.argument());
2932 QString const shortcut = toqstr(seq.print(KeySequence::ForGui));
2934 QTreeWidgetItem * newItem = 0;
2935 // for unbind items, try to find an existing item in the system bind list
2936 if (tag == KeyMap::UserUnbind) {
2937 QList<QTreeWidgetItem*> const items = shortcutsTW->findItems(lfun_name,
2938 Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 0);
2939 for (int i = 0; i < items.size(); ++i) {
2940 if (items[i]->text(1) == shortcut) {
2945 // if not found, this unbind item is KeyMap::UserExtraUnbind
2946 // Such an item is not displayed to avoid confusion (what is
2947 // unmatched removed?).
2953 switch(lyxaction.getActionType(action)) {
2954 case LyXAction::Hidden:
2956 case LyXAction::Edit:
2957 newItem = new QTreeWidgetItem(editItem_);
2959 case LyXAction::Math:
2960 newItem = new QTreeWidgetItem(mathItem_);
2962 case LyXAction::Buffer:
2963 newItem = new QTreeWidgetItem(bufferItem_);
2965 case LyXAction::Layout:
2966 newItem = new QTreeWidgetItem(layoutItem_);
2968 case LyXAction::System:
2969 newItem = new QTreeWidgetItem(systemItem_);
2972 // this should not happen
2973 newItem = new QTreeWidgetItem(shortcutsTW);
2977 newItem->setText(0, lfun_name);
2978 newItem->setText(1, shortcut);
2979 // record BindFile representation to recover KeySequence when needed.
2980 newItem->setData(1, Qt::UserRole, toqstr(seq.print(KeySequence::BindFile)));
2981 setItemType(newItem, tag);
2986 void PrefShortcuts::on_shortcutsTW_itemSelectionChanged()
2988 QList<QTreeWidgetItem*> items = shortcutsTW->selectedItems();
2989 removePB->setEnabled(!items.isEmpty() && !items[0]->text(1).isEmpty());
2990 modifyPB->setEnabled(!items.isEmpty());
2991 if (items.isEmpty())
2994 if (itemType(*items[0]) == KeyMap::UserUnbind)
2995 removePB->setText(qt_("Res&tore"));
2997 removePB->setText(qt_("Remo&ve"));
3001 void PrefShortcuts::on_shortcutsTW_itemDoubleClicked()
3007 void PrefShortcuts::modifyShortcut()
3009 QTreeWidgetItem * item = shortcutsTW->currentItem();
3010 if (item->flags() & Qt::ItemIsSelectable) {
3011 shortcut_->lfunLE->setText(item->text(0));
3012 save_lfun_ = item->text(0).trimmed();
3013 shortcut_->shortcutWG->setText(item->text(1));
3015 seq.parse(fromqstr(item->data(1, Qt::UserRole).toString()));
3016 shortcut_->shortcutWG->setKeySequence(seq);
3017 shortcut_->shortcutWG->setFocus();
3023 void PrefShortcuts::unhideEmpty(QString const & lfun, bool select)
3025 // list of items that match lfun
3026 QList<QTreeWidgetItem*> items = shortcutsTW->findItems(lfun,
3027 Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 0);
3028 for (int i = 0; i < items.size(); ++i) {
3029 QTreeWidgetItem * item = items[i];
3030 if (isAlwaysHidden(*item)) {
3031 setItemType(item, KeyMap::System);
3033 shortcutsTW->setCurrentItem(item);
3040 void PrefShortcuts::removeShortcut()
3042 // it seems that only one item can be selected, but I am
3043 // removing all selected items anyway.
3044 QList<QTreeWidgetItem*> items = shortcutsTW->selectedItems();
3045 for (int i = 0; i < items.size(); ++i) {
3046 string shortcut = fromqstr(items[i]->data(1, Qt::UserRole).toString());
3047 string lfun = fromqstr(items[i]->text(0));
3048 FuncRequest func = lyxaction.lookupFunc(lfun);
3050 switch (itemType(*items[i])) {
3051 case KeyMap::System: {
3052 // for system bind, we do not touch the item
3053 // but add an user unbind item
3054 user_unbind_.bind(shortcut, func);
3055 setItemType(items[i], KeyMap::UserUnbind);
3056 removePB->setText(qt_("Res&tore"));
3059 case KeyMap::UserBind: {
3060 // for user_bind, we remove this bind
3061 QTreeWidgetItem * parent = items[i]->parent();
3062 int itemIdx = parent->indexOfChild(items[i]);
3063 parent->takeChild(itemIdx);
3065 shortcutsTW->scrollToItem(parent->child(itemIdx - 1));
3067 shortcutsTW->scrollToItem(parent);
3068 user_bind_.unbind(shortcut, func);
3069 // If this user binding hid an empty system binding, unhide the
3070 // latter and select it.
3071 unhideEmpty(items[i]->text(0), true);
3074 case KeyMap::UserUnbind: {
3075 // for user_unbind, we remove the unbind, and the item
3076 // become KeyMap::System again.
3078 seq.parse(shortcut);
3079 // Ask the user to replace current binding
3080 if (!validateNewShortcut(func, seq, QString()))
3082 user_unbind_.unbind(shortcut, func);
3083 setItemType(items[i], KeyMap::System);
3084 removePB->setText(qt_("Remo&ve"));
3087 case KeyMap::UserExtraUnbind: {
3088 // for user unbind that is not in system bind file,
3089 // remove this unbind file
3090 QTreeWidgetItem * parent = items[i]->parent();
3091 parent->takeChild(parent->indexOfChild(items[i]));
3092 user_unbind_.unbind(shortcut, func);
3099 void PrefShortcuts::deactivateShortcuts(QList<QTreeWidgetItem*> const & items)
3101 for (int i = 0; i < items.size(); ++i) {
3102 string shortcut = fromqstr(items[i]->data(1, Qt::UserRole).toString());
3103 string lfun = fromqstr(items[i]->text(0));
3104 FuncRequest func = lyxaction.lookupFunc(lfun);
3106 switch (itemType(*items[i])) {
3107 case KeyMap::System:
3108 // for system bind, we do not touch the item
3109 // but add an user unbind item
3110 user_unbind_.bind(shortcut, func);
3111 setItemType(items[i], KeyMap::UserUnbind);
3114 case KeyMap::UserBind: {
3115 // for user_bind, we remove this bind
3116 QTreeWidgetItem * parent = items[i]->parent();
3117 int itemIdx = parent->indexOfChild(items[i]);
3118 parent->takeChild(itemIdx);
3119 user_bind_.unbind(shortcut, func);
3120 unhideEmpty(items[i]->text(0), false);
3130 void PrefShortcuts::selectBind()
3132 QString file = form_->browsebind(internalPath(bindFileED->text()));
3133 if (!file.isEmpty()) {
3134 bindFileED->setText(file);
3135 system_bind_ = KeyMap();
3136 system_bind_.read(fromqstr(file));
3137 updateShortcutsTW();
3142 void PrefShortcuts::on_modifyPB_pressed()
3148 void PrefShortcuts::on_newPB_pressed()
3150 shortcut_->lfunLE->clear();
3151 shortcut_->shortcutWG->reset();
3152 save_lfun_ = QString();
3157 void PrefShortcuts::on_removePB_pressed()
3164 void PrefShortcuts::on_searchLE_textEdited()
3166 if (searchLE->text().isEmpty()) {
3167 // show all hidden items
3168 QTreeWidgetItemIterator it(shortcutsTW, QTreeWidgetItemIterator::Hidden);
3170 shortcutsTW->setItemHidden(*it, isAlwaysHidden(**it));
3171 // close all categories
3172 for (int i = 0; i < shortcutsTW->topLevelItemCount(); ++i)
3173 shortcutsTW->collapseItem(shortcutsTW->topLevelItem(i));
3176 // search both columns
3177 QList<QTreeWidgetItem *> matched = shortcutsTW->findItems(searchLE->text(),
3178 Qt::MatchFlags(Qt::MatchContains | Qt::MatchRecursive), 0);
3179 matched += shortcutsTW->findItems(searchLE->text(),
3180 Qt::MatchFlags(Qt::MatchContains | Qt::MatchRecursive), 1);
3182 // hide everyone (to avoid searching in matched QList repeatedly
3183 QTreeWidgetItemIterator it(shortcutsTW, QTreeWidgetItemIterator::Selectable);
3185 shortcutsTW->setItemHidden(*it++, true);
3186 // show matched items
3187 for (int i = 0; i < matched.size(); ++i)
3188 if (!isAlwaysHidden(*matched[i])) {
3189 shortcutsTW->setItemHidden(matched[i], false);
3190 shortcutsTW->setItemExpanded(matched[i]->parent(), true);
3195 docstring makeCmdString(FuncRequest const & f)
3197 docstring actionStr = from_ascii(lyxaction.getActionName(f.action()));
3198 if (!f.argument().empty())
3199 actionStr += " " + f.argument();
3204 FuncRequest PrefShortcuts::currentBinding(KeySequence const & k)
3206 FuncRequest res = user_bind_.getBinding(k);
3207 if (res.action() != LFUN_UNKNOWN_ACTION)
3209 res = system_bind_.getBinding(k);
3210 // Check if it is unbound. Note: user_unbind_ can only unbind one
3211 // FuncRequest per key sequence.
3212 if (user_unbind_.getBinding(k) == res)
3213 return FuncRequest::unknown;
3218 bool PrefShortcuts::validateNewShortcut(FuncRequest const & func,
3219 KeySequence const & k,
3220 QString const & lfun_to_modify)
3222 if (func.action() == LFUN_UNKNOWN_ACTION) {
3223 Alert::error(_("Failed to create shortcut"),
3224 _("Unknown or invalid LyX function"));
3228 // It is not currently possible to bind Hidden lfuns such as self-insert. In
3229 // the future, to remove this limitation, see GuiPrefs::insertShortcutItem
3230 // and how it is used in GuiPrefs::shortcutOkPressed.
3231 if (lyxaction.getActionType(func.action()) == LyXAction::Hidden) {
3232 Alert::error(_("Failed to create shortcut"),
3233 _("This LyX function is hidden and cannot be bound."));
3237 if (k.length() == 0) {
3238 Alert::error(_("Failed to create shortcut"),
3239 _("Invalid or empty key sequence"));
3243 FuncRequest oldBinding = currentBinding(k);
3244 if (oldBinding == func)
3245 // nothing to change
3248 // make sure this key isn't already bound---and, if so, prompt user
3249 // (exclude the lfun the user already wants to modify)
3250 docstring const action_string = makeCmdString(oldBinding);
3251 if (oldBinding.action() != LFUN_UNKNOWN_ACTION
3252 && lfun_to_modify != toqstr(action_string)) {
3253 docstring const new_action_string = makeCmdString(func);
3254 docstring const text = bformat(_("Shortcut `%1$s' is already bound to "
3256 "Are you sure you want to unbind the "
3257 "current shortcut and bind it to %3$s?"),
3258 k.print(KeySequence::ForGui), action_string,
3260 int ret = Alert::prompt(_("Redefine shortcut?"),
3261 text, 0, 1, _("&Redefine"), _("&Cancel"));
3264 QString const sequence_text = toqstr(k.print(KeySequence::ForGui));
3265 QList<QTreeWidgetItem*> items = shortcutsTW->findItems(sequence_text,
3266 Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 1);
3267 deactivateShortcuts(items);
3273 void PrefShortcuts::shortcutOkPressed()
3275 QString const new_lfun = shortcut_->lfunLE->text();
3276 FuncRequest func = lyxaction.lookupFunc(fromqstr(new_lfun));
3277 KeySequence k = shortcut_->shortcutWG->getKeySequence();
3279 // save_lfun_ contains the text of the lfun to modify, if the user clicked
3280 // "modify", or is empty if they clicked "new" (which I do not really like)
3281 if (!validateNewShortcut(func, k, save_lfun_))
3284 if (!save_lfun_.isEmpty()) {
3285 // real modification of the lfun's shortcut,
3286 // so remove the previous one
3287 QList<QTreeWidgetItem*> to_modify = shortcutsTW->selectedItems();
3288 deactivateShortcuts(to_modify);
3291 shortcut_->accept();
3293 QTreeWidgetItem * item = insertShortcutItem(func, k, KeyMap::UserBind);
3295 user_bind_.bind(&k, func);
3296 shortcutsTW->sortItems(0, Qt::AscendingOrder);
3297 shortcutsTW->setItemExpanded(item->parent(), true);
3298 shortcutsTW->setCurrentItem(item);
3299 shortcutsTW->scrollToItem(item);
3301 Alert::error(_("Failed to create shortcut"),
3302 _("Can not insert shortcut to the list"));
3308 void PrefShortcuts::shortcutCancelPressed()
3310 shortcut_->shortcutWG->reset();
3314 void PrefShortcuts::shortcutClearPressed()
3316 shortcut_->shortcutWG->reset();
3320 void PrefShortcuts::shortcutRemovePressed()
3322 shortcut_->shortcutWG->removeFromSequence();
3326 /////////////////////////////////////////////////////////////////////
3330 /////////////////////////////////////////////////////////////////////
3332 PrefIdentity::PrefIdentity(GuiPreferences * form)
3333 : PrefModule(QString(), N_("Identity"), form)
3337 connect(nameED, SIGNAL(textChanged(QString)),
3338 this, SIGNAL(changed()));
3339 connect(emailED, SIGNAL(textChanged(QString)),
3340 this, SIGNAL(changed()));
3342 nameED->setValidator(new NoNewLineValidator(nameED));
3343 emailED->setValidator(new NoNewLineValidator(emailED));
3347 void PrefIdentity::applyRC(LyXRC & rc) const
3349 rc.user_name = fromqstr(nameED->text());
3350 rc.user_email = fromqstr(emailED->text());
3354 void PrefIdentity::updateRC(LyXRC const & rc)
3356 nameED->setText(toqstr(rc.user_name));
3357 emailED->setText(toqstr(rc.user_email));
3362 /////////////////////////////////////////////////////////////////////
3366 /////////////////////////////////////////////////////////////////////
3368 GuiPreferences::GuiPreferences(GuiView & lv)
3369 : GuiDialog(lv, "prefs", qt_("Preferences")), update_screen_font_(false),
3370 update_previews_(false)
3374 QDialog::setModal(false);
3376 connect(buttonBox, SIGNAL(clicked(QAbstractButton *)),
3377 this, SLOT(slotButtonBox(QAbstractButton *)));
3379 addModule(new PrefUserInterface(this));
3380 addModule(new PrefDocHandling(this));
3381 addModule(new PrefEdit(this));
3382 addModule(new PrefShortcuts(this));
3383 PrefScreenFonts * screenfonts = new PrefScreenFonts(this);
3384 connect(this, SIGNAL(prefsApplied(LyXRC const &)),
3385 screenfonts, SLOT(updateScreenFontSizes(LyXRC const &)));
3386 addModule(screenfonts);
3387 addModule(new PrefColors(this));
3388 addModule(new PrefDisplay(this));
3389 addModule(new PrefInput(this));
3390 addModule(new PrefCompletion(this));
3392 addModule(new PrefPaths(this));
3394 addModule(new PrefIdentity(this));
3396 addModule(new PrefLanguage(this));
3397 addModule(new PrefSpellchecker(this));
3399 PrefOutput * output = new PrefOutput(this);
3401 addModule(new PrefLatex(this));
3403 PrefConverters * converters = new PrefConverters(this);
3404 PrefFileformats * formats = new PrefFileformats(this);
3405 connect(formats, SIGNAL(formatsChanged()),
3406 converters, SLOT(updateGui()));
3407 addModule(converters);
3410 prefsPS->setCurrentPanel("User Interface");
3411 // FIXME: hack to work around resizing bug in Qt >= 4.2
3412 // bug verified with Qt 4.2.{0-3} (JSpitzm)
3413 #if QT_VERSION >= 0x040200
3414 prefsPS->updateGeometry();
3417 bc().setPolicy(ButtonPolicy::PreferencesPolicy);
3418 bc().setOK(buttonBox->button(QDialogButtonBox::Ok));
3419 bc().setApply(buttonBox->button(QDialogButtonBox::Apply));
3420 bc().setCancel(buttonBox->button(QDialogButtonBox::Cancel));
3421 bc().setRestore(buttonBox->button(QDialogButtonBox::Reset));
3425 void GuiPreferences::addModule(PrefModule * module)
3427 LASSERT(module, return);
3428 if (module->category().isEmpty())
3429 prefsPS->addPanel(module, module->title());
3431 prefsPS->addPanel(module, module->title(), module->category());
3432 connect(module, SIGNAL(changed()), this, SLOT(change_adaptor()));
3433 modules_.push_back(module);
3437 void GuiPreferences::change_adaptor()
3443 void GuiPreferences::applyRC(LyXRC & rc) const
3445 size_t end = modules_.size();
3446 for (size_t i = 0; i != end; ++i)
3447 modules_[i]->applyRC(rc);
3451 void GuiPreferences::updateRC(LyXRC const & rc)
3453 size_t const end = modules_.size();
3454 for (size_t i = 0; i != end; ++i)
3455 modules_[i]->updateRC(rc);
3459 void GuiPreferences::applyView()
3465 bool GuiPreferences::initialiseParams(string const &)
3468 formats_ = theFormats();
3469 converters_ = theConverters();
3470 converters_.update(formats_);
3471 movers_ = theMovers();
3473 update_screen_font_ = false;
3474 update_previews_ = false;
3477 // Make sure that the bc is in the INITIAL state
3478 if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
3485 void GuiPreferences::dispatchParams()
3488 rc_.write(ss, true);
3489 dispatch(FuncRequest(LFUN_LYXRC_APPLY, ss.str()));
3490 // issue prefsApplied signal. This will update the
3491 // localized screen font sizes.
3493 // FIXME: these need lfuns
3495 Author const & author =
3496 Author(from_utf8(rc_.user_name), from_utf8(rc_.user_email));
3497 theBufferList().recordCurrentAuthor(author);
3499 theFormats() = formats_;
3501 theConverters() = converters_;
3502 theConverters().update(formats_);
3503 theConverters().buildGraph();
3504 theBufferList().invalidateConverterCache();
3506 theMovers() = movers_;
3508 vector<string>::const_iterator it = colors_.begin();
3509 vector<string>::const_iterator const end = colors_.end();
3510 for (; it != end; ++it)
3511 dispatch(FuncRequest(LFUN_SET_COLOR, *it));
3514 if (update_screen_font_) {
3515 dispatch(FuncRequest(LFUN_SCREEN_FONT_UPDATE));
3516 // resets flag in case second apply in same dialog
3517 update_screen_font_ = false;
3520 if (update_previews_) {
3521 // resets flag in case second apply in same dialog
3522 theBufferList().updatePreviews();
3523 update_previews_ = false;
3527 if (!tempSaveCB->isChecked())
3528 dispatch(FuncRequest(LFUN_PREFERENCES_SAVE));
3532 void GuiPreferences::setColor(ColorCode col, QString const & hex)
3534 colors_.push_back(lcolor.getLyXName(col) + ' ' + fromqstr(hex));
3538 void GuiPreferences::updateScreenFonts()
3540 update_screen_font_ = true;
3544 void GuiPreferences::updatePreviews()
3546 update_previews_ = true;
3550 QString GuiPreferences::browsebind(QString const & file) const
3552 return browseLibFile("bind", file, "bind", qt_("Choose bind file"),
3553 QStringList(qt_("LyX bind files (*.bind)")));
3557 QString GuiPreferences::browseUI(QString const & file) const
3559 return browseLibFile("ui", file, "ui", qt_("Choose UI file"),
3560 QStringList(qt_("LyX UI files (*.ui)")));
3564 QString GuiPreferences::browsekbmap(QString const & file) const
3566 return browseLibFile("kbd", file, "kmap", qt_("Choose keyboard map"),
3567 QStringList(qt_("LyX keyboard maps (*.kmap)")));
3571 QString GuiPreferences::browse(QString const & file,
3572 QString const & title) const
3574 return browseFile(file, title, QStringList(), true);
3578 Dialog * createGuiPreferences(GuiView & lv) { return new GuiPreferences(lv); }
3581 } // namespace frontend
3584 #include "moc_GuiPrefs.cpp"