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 "GuiLyXFiles.h"
24 #include "qt_helpers.h"
25 #include "Validator.h"
28 #include "BufferList.h"
31 #include "ConverterCache.h"
32 #include "FontEnums.h"
33 #include "FuncRequest.h"
35 #include "KeySequence.h"
37 #include "LyXAction.h"
39 #include "PanelStack.h"
41 #include "SpellChecker.h"
43 #include "support/debug.h"
44 #include "support/FileName.h"
45 #include "support/filetools.h"
46 #include "support/gettext.h"
47 #include "support/lassert.h"
48 #include "support/lstrings.h"
49 #include "support/Messages.h"
50 #include "support/os.h"
51 #include "support/Package.h"
53 #include "graphics/GraphicsTypes.h"
55 #include "frontends/alert.h"
56 #include "frontends/Application.h"
57 #include "frontends/FontLoader.h"
59 #include <QAbstractItemModel>
61 #include <QColorDialog>
62 #include <QFontDatabase>
63 #include <QHeaderView>
65 #include <QMessageBox>
66 #include <QPushButton>
69 #include <QTreeWidget>
70 #include <QTreeWidgetItem>
81 using namespace lyx::support;
82 using namespace lyx::support::os;
87 /////////////////////////////////////////////////////////////////////
91 /////////////////////////////////////////////////////////////////////
93 /** Launch a file dialog and return the chosen file.
94 filename: a suggested filename.
95 title: the title of the dialog.
97 dir1 = (name, dir), dir2 = (name, dir): extra buttons on the dialog.
99 QString browseFile(QString const & filename,
100 QString const & title,
101 QStringList const & filters,
103 QString const & label1 = QString(),
104 QString const & dir1 = QString(),
105 QString const & label2 = QString(),
106 QString const & dir2 = QString(),
107 QString const & fallback_dir = QString())
109 QString lastPath = ".";
110 if (!filename.isEmpty())
111 lastPath = onlyPath(filename);
112 else if(!fallback_dir.isEmpty())
113 lastPath = fallback_dir;
115 FileDialog dlg(title);
116 dlg.setButton1(label1, dir1);
117 dlg.setButton2(label2, dir2);
119 FileDialog::Result result;
122 result = dlg.save(lastPath, filters, onlyFileName(filename));
124 result = dlg.open(lastPath, filters, onlyFileName(filename));
126 return result.second;
130 /** Launch a file dialog and return the chosen directory.
131 pathname: a suggested pathname.
132 title: the title of the dialog.
133 dir1 = (name, dir), dir2 = (name, dir): extra buttons on the dialog.
135 QString browseDir(QString const & pathname,
136 QString const & title,
137 QString const & label1 = QString(),
138 QString const & dir1 = QString(),
139 QString const & label2 = QString(),
140 QString const & dir2 = QString())
142 QString lastPath = ".";
143 if (!pathname.isEmpty())
144 lastPath = onlyPath(pathname);
146 FileDialog dlg(title);
147 dlg.setButton1(label1, dir1);
148 dlg.setButton2(label2, dir2);
150 FileDialog::Result const result =
151 dlg.opendir(lastPath, onlyFileName(pathname));
153 return result.second;
157 } // namespace frontend
160 QString browseRelToParent(QString const & filename, QString const & relpath,
161 QString const & title, QStringList const & filters, bool save,
162 QString const & label1, QString const & dir1,
163 QString const & label2, QString const & dir2)
165 QString const fname = makeAbsPath(filename, relpath);
167 QString const outname =
168 frontend::browseFile(fname, title, filters, save, label1, dir1, label2, dir2);
170 QString const reloutname =
171 toqstr(makeRelPath(qstring_to_ucs4(outname), qstring_to_ucs4(relpath)));
173 if (reloutname.startsWith("../"))
180 QString browseRelToSub(QString const & filename, QString const & relpath,
181 QString const & title, QStringList const & filters, bool save,
182 QString const & label1, QString const & dir1,
183 QString const & label2, QString const & dir2)
185 QString const fname = makeAbsPath(filename, relpath);
187 QString const outname =
188 frontend::browseFile(fname, title, filters, save, label1, dir1, label2, dir2);
190 QString const reloutname =
191 toqstr(makeRelPath(qstring_to_ucs4(outname), qstring_to_ucs4(relpath)));
193 QString testname = reloutname;
194 testname.remove(QRegExp("^(\\.\\./)+"));
196 if (testname.contains("/"))
204 /////////////////////////////////////////////////////////////////////
208 /////////////////////////////////////////////////////////////////////
212 QString const catLookAndFeel = N_("Look & Feel");
213 QString const catEditing = N_("Editing");
214 QString const catLanguage = N_("Language Settings");
215 QString const catOutput = N_("Output");
216 QString const catFiles = N_("File Handling");
218 static void parseFontName(QString const & mangled0,
219 string & name, string & foundry)
221 string mangled = fromqstr(mangled0);
222 size_t const idx = mangled.find('[');
223 if (idx == string::npos || idx == 0) {
227 name = mangled.substr(0, idx - 1),
228 foundry = mangled.substr(idx + 1, mangled.size() - idx - 2);
233 static void setComboxFont(QComboBox * cb, string const & family,
234 string const & foundry)
236 QString fontname = toqstr(family);
237 if (!foundry.empty())
238 fontname += " [" + toqstr(foundry) + ']';
240 for (int i = 0; i != cb->count(); ++i) {
241 if (cb->itemText(i) == fontname) {
242 cb->setCurrentIndex(i);
247 // Try matching without foundry name
249 // We count in reverse in order to prefer the Xft foundry
250 for (int i = cb->count(); --i >= 0;) {
251 string name, fnt_foundry;
252 parseFontName(cb->itemText(i), name, fnt_foundry);
253 if (compare_ascii_no_case(name, family) == 0) {
254 cb->setCurrentIndex(i);
259 // family alone can contain e.g. "Helvetica [Adobe]"
260 string tmpname, tmpfoundry;
261 parseFontName(toqstr(family), tmpname, tmpfoundry);
263 // We count in reverse in order to prefer the Xft foundry
264 for (int i = cb->count(); --i >= 0; ) {
265 string name, fnt_foundry;
266 parseFontName(cb->itemText(i), name, fnt_foundry);
267 if (compare_ascii_no_case(name, fnt_foundry) == 0) {
268 cb->setCurrentIndex(i);
273 // Bleh, default fonts, and the names couldn't be found. Hack
278 QString const font_family = toqstr(family);
279 if (font_family == guiApp->romanFontName()) {
280 font.setStyleHint(QFont::Serif);
281 font.setFamily(font_family);
282 } else if (font_family == guiApp->sansFontName()) {
283 font.setStyleHint(QFont::SansSerif);
284 font.setFamily(font_family);
285 } else if (font_family == guiApp->typewriterFontName()) {
286 font.setStyleHint(QFont::TypeWriter);
287 font.setFamily(font_family);
289 LYXERR0("FAILED to find the default font: '"
290 << foundry << "', '" << family << '\'');
294 QFontInfo info(font);
295 string default_font_name, dummyfoundry;
296 parseFontName(info.family(), default_font_name, dummyfoundry);
297 LYXERR0("Apparent font is " << default_font_name);
299 for (int i = 0; i < cb->count(); ++i) {
300 LYXERR0("Looking at " << cb->itemText(i));
301 if (compare_ascii_no_case(fromqstr(cb->itemText(i)),
302 default_font_name) == 0) {
303 cb->setCurrentIndex(i);
308 LYXERR0("FAILED to find the font: '"
309 << foundry << "', '" << family << '\'');
313 /////////////////////////////////////////////////////////////////////
317 /////////////////////////////////////////////////////////////////////
319 PrefOutput::PrefOutput(GuiPreferences * form)
320 : PrefModule(catOutput, N_("General"), form)
324 dviCB->setValidator(new NoNewLineValidator(dviCB));
325 pdfCB->setValidator(new NoNewLineValidator(pdfCB));
327 connect(plaintextLinelengthSB, SIGNAL(valueChanged(int)),
328 this, SIGNAL(changed()));
329 connect(overwriteCO, SIGNAL(activated(int)),
330 this, SIGNAL(changed()));
331 connect(dviCB, SIGNAL(editTextChanged(QString)),
332 this, SIGNAL(changed()));
333 connect(pdfCB, SIGNAL(editTextChanged(QString)),
334 this, SIGNAL(changed()));
335 connect(printerPaperTypeED, SIGNAL(textChanged(QString)),
336 this, SIGNAL(changed()));
337 connect(printerLandscapeED, SIGNAL(textChanged(QString)),
338 this, SIGNAL(changed()));
339 connect(printerPaperSizeED, SIGNAL(textChanged(QString)),
340 this, SIGNAL(changed()));
342 printerPaperTypeED->setValidator(new NoNewLineValidator(printerPaperTypeED));
343 printerLandscapeED->setValidator(new NoNewLineValidator(printerLandscapeED));
344 printerPaperSizeED->setValidator(new NoNewLineValidator(printerPaperSizeED));
347 dviCB->addItem("xdvi -sourceposition '$$n:\\ $$t' $$o");
348 dviCB->addItem("yap -1 -s \"$$n $$t\" $$o");
349 dviCB->addItem("okular --unique \"$$o#src:$$n $$f\"");
350 dviCB->addItem("synctex view -i $$n:0:$$t -o $$o -x \"evince -i %{page+1} $$o\"");
352 pdfCB->addItem("CMCDDE SUMATRA control [ForwardSearch(\\\"$$o\\\",\\\"$$t\\\",$$n,0,0,1)]");
353 pdfCB->addItem("SumatraPDF -reuse-instance \"$$o\" -forward-search \"$$t\" $$n");
354 pdfCB->addItem("synctex view -i $$n:0:$$t -o $$o -x \"xpdf -raise -remote $$t.tmp $$o %{page+1}\"");
355 pdfCB->addItem("okular --unique \"$$o#src:$$n $$f\"");
356 pdfCB->addItem("qpdfview --unique \"$$o#src:$$f:$$n:0\"");
357 pdfCB->addItem("synctex view -i $$n:0:$$t -o $$o -x \"evince -i %{page+1} $$o\"");
358 pdfCB->addItem("/Applications/Skim.app/Contents/SharedSupport/displayline $$n $$o $$t");
362 void PrefOutput::applyRC(LyXRC & rc) const
364 rc.plaintext_linelen = plaintextLinelengthSB->value();
365 rc.forward_search_dvi = fromqstr(dviCB->currentText());
366 rc.forward_search_pdf = fromqstr(pdfCB->currentText());
368 switch (overwriteCO->currentIndex()) {
370 rc.export_overwrite = NO_FILES;
373 rc.export_overwrite = MAIN_FILE;
376 rc.export_overwrite = ALL_FILES;
380 rc.print_paper_flag = fromqstr(printerPaperTypeED->text());
381 rc.print_landscape_flag = fromqstr(printerLandscapeED->text());
382 rc.print_paper_dimension_flag = fromqstr(printerPaperSizeED->text());
386 void PrefOutput::updateRC(LyXRC const & rc)
388 plaintextLinelengthSB->setValue(rc.plaintext_linelen);
389 dviCB->setEditText(toqstr(rc.forward_search_dvi));
390 pdfCB->setEditText(toqstr(rc.forward_search_pdf));
392 switch (rc.export_overwrite) {
394 overwriteCO->setCurrentIndex(0);
397 overwriteCO->setCurrentIndex(1);
400 overwriteCO->setCurrentIndex(2);
404 printerPaperTypeED->setText(toqstr(rc.print_paper_flag));
405 printerLandscapeED->setText(toqstr(rc.print_landscape_flag));
406 printerPaperSizeED->setText(toqstr(rc.print_paper_dimension_flag));
410 /////////////////////////////////////////////////////////////////////
414 /////////////////////////////////////////////////////////////////////
416 PrefInput::PrefInput(GuiPreferences * form)
417 : PrefModule(catEditing, N_("Keyboard/Mouse"), form)
421 connect(keymapCB, SIGNAL(clicked()),
422 this, SIGNAL(changed()));
423 connect(firstKeymapED, SIGNAL(textChanged(QString)),
424 this, SIGNAL(changed()));
425 connect(secondKeymapED, SIGNAL(textChanged(QString)),
426 this, SIGNAL(changed()));
427 connect(mouseWheelSpeedSB, SIGNAL(valueChanged(double)),
428 this, SIGNAL(changed()));
429 connect(scrollzoomEnableCB, SIGNAL(clicked()),
430 this, SIGNAL(changed()));
431 connect(scrollzoomValueCO, SIGNAL(activated(int)),
432 this, SIGNAL(changed()));
433 connect(dontswapCB, SIGNAL(toggled(bool)),
434 this, SIGNAL(changed()));
435 connect(mmPasteCB, SIGNAL(toggled(bool)),
436 this, SIGNAL(changed()));
438 // reveal checkbox for switching Ctrl and Meta on Mac:
441 #if QT_VERSION > 0x040600
445 dontswapCB->setVisible(swapcb);
449 void PrefInput::applyRC(LyXRC & rc) const
451 // FIXME: can derive CB from the two EDs
452 rc.use_kbmap = keymapCB->isChecked();
453 rc.primary_kbmap = internal_path(fromqstr(firstKeymapED->text()));
454 rc.secondary_kbmap = internal_path(fromqstr(secondKeymapED->text()));
455 rc.mouse_wheel_speed = mouseWheelSpeedSB->value();
456 if (scrollzoomEnableCB->isChecked()) {
457 switch (scrollzoomValueCO->currentIndex()) {
459 rc.scroll_wheel_zoom = LyXRC::SCROLL_WHEEL_ZOOM_CTRL;
462 rc.scroll_wheel_zoom = LyXRC::SCROLL_WHEEL_ZOOM_SHIFT;
465 rc.scroll_wheel_zoom = LyXRC::SCROLL_WHEEL_ZOOM_ALT;
469 rc.scroll_wheel_zoom = LyXRC::SCROLL_WHEEL_ZOOM_OFF;
471 rc.mac_dontswap_ctrl_meta = dontswapCB->isChecked();
472 rc.mouse_middlebutton_paste = mmPasteCB->isChecked();
476 void PrefInput::updateRC(LyXRC const & rc)
478 // FIXME: can derive CB from the two EDs
479 keymapCB->setChecked(rc.use_kbmap);
480 firstKeymapED->setText(toqstr(external_path(rc.primary_kbmap)));
481 secondKeymapED->setText(toqstr(external_path(rc.secondary_kbmap)));
482 mouseWheelSpeedSB->setValue(rc.mouse_wheel_speed);
483 switch (rc.scroll_wheel_zoom) {
484 case LyXRC::SCROLL_WHEEL_ZOOM_OFF:
485 scrollzoomEnableCB->setChecked(false);
487 case LyXRC::SCROLL_WHEEL_ZOOM_CTRL:
488 scrollzoomEnableCB->setChecked(true);
489 scrollzoomValueCO->setCurrentIndex(0);
491 case LyXRC::SCROLL_WHEEL_ZOOM_SHIFT:
492 scrollzoomEnableCB->setChecked(true);
493 scrollzoomValueCO->setCurrentIndex(1);
495 case LyXRC::SCROLL_WHEEL_ZOOM_ALT:
496 scrollzoomEnableCB->setChecked(true);
497 scrollzoomValueCO->setCurrentIndex(2);
500 dontswapCB->setChecked(rc.mac_dontswap_ctrl_meta);
501 mmPasteCB->setChecked(rc.mouse_middlebutton_paste);
505 QString PrefInput::testKeymap(QString const & keymap)
507 return form_->browsekbmap(internalPath(keymap));
511 void PrefInput::on_firstKeymapPB_clicked(bool)
513 QString const file = testKeymap(firstKeymapED->text());
515 firstKeymapED->setText(file);
519 void PrefInput::on_secondKeymapPB_clicked(bool)
521 QString const file = testKeymap(secondKeymapED->text());
523 secondKeymapED->setText(file);
527 void PrefInput::on_keymapCB_toggled(bool keymap)
529 firstKeymapLA->setEnabled(keymap);
530 secondKeymapLA->setEnabled(keymap);
531 firstKeymapED->setEnabled(keymap);
532 secondKeymapED->setEnabled(keymap);
533 firstKeymapPB->setEnabled(keymap);
534 secondKeymapPB->setEnabled(keymap);
538 void PrefInput::on_scrollzoomEnableCB_toggled(bool enabled)
540 scrollzoomValueCO->setEnabled(enabled);
544 /////////////////////////////////////////////////////////////////////
548 /////////////////////////////////////////////////////////////////////
550 PrefCompletion::PrefCompletion(GuiPreferences * form)
551 : PrefModule(catEditing, N_("Input Completion"), form)
555 connect(inlineDelaySB, SIGNAL(valueChanged(double)),
556 this, SIGNAL(changed()));
557 connect(inlineMathCB, SIGNAL(clicked()),
558 this, SIGNAL(changed()));
559 connect(inlineTextCB, SIGNAL(clicked()),
560 this, SIGNAL(changed()));
561 connect(inlineDotsCB, SIGNAL(clicked()),
562 this, SIGNAL(changed()));
563 connect(popupDelaySB, SIGNAL(valueChanged(double)),
564 this, SIGNAL(changed()));
565 connect(popupMathCB, SIGNAL(clicked()),
566 this, SIGNAL(changed()));
567 connect(autocorrectionCB, SIGNAL(clicked()),
568 this, SIGNAL(changed()));
569 connect(popupTextCB, SIGNAL(clicked()),
570 this, SIGNAL(changed()));
571 connect(popupAfterCompleteCB, SIGNAL(clicked()),
572 this, SIGNAL(changed()));
573 connect(cursorTextCB, SIGNAL(clicked()),
574 this, SIGNAL(changed()));
575 connect(minlengthSB, SIGNAL(valueChanged(int)),
576 this, SIGNAL(changed()));
580 void PrefCompletion::on_inlineTextCB_clicked()
586 void PrefCompletion::on_popupTextCB_clicked()
592 void PrefCompletion::enableCB()
594 cursorTextCB->setEnabled(
595 popupTextCB->isChecked() || inlineTextCB->isChecked());
599 void PrefCompletion::applyRC(LyXRC & rc) const
601 rc.completion_inline_delay = inlineDelaySB->value();
602 rc.completion_inline_math = inlineMathCB->isChecked();
603 rc.completion_inline_text = inlineTextCB->isChecked();
604 rc.completion_inline_dots = inlineDotsCB->isChecked() ? 13 : -1;
605 rc.completion_popup_delay = popupDelaySB->value();
606 rc.completion_popup_math = popupMathCB->isChecked();
607 rc.autocorrection_math = autocorrectionCB->isChecked();
608 rc.completion_popup_text = popupTextCB->isChecked();
609 rc.completion_cursor_text = cursorTextCB->isChecked();
610 rc.completion_popup_after_complete =
611 popupAfterCompleteCB->isChecked();
612 rc.completion_minlength = minlengthSB->value();
616 void PrefCompletion::updateRC(LyXRC const & rc)
618 inlineDelaySB->setValue(rc.completion_inline_delay);
619 inlineMathCB->setChecked(rc.completion_inline_math);
620 inlineTextCB->setChecked(rc.completion_inline_text);
621 inlineDotsCB->setChecked(rc.completion_inline_dots != -1);
622 popupDelaySB->setValue(rc.completion_popup_delay);
623 popupMathCB->setChecked(rc.completion_popup_math);
624 autocorrectionCB->setChecked(rc.autocorrection_math);
625 popupTextCB->setChecked(rc.completion_popup_text);
626 cursorTextCB->setChecked(rc.completion_cursor_text);
627 popupAfterCompleteCB->setChecked(rc.completion_popup_after_complete);
629 minlengthSB->setValue(rc.completion_minlength);
634 /////////////////////////////////////////////////////////////////////
638 /////////////////////////////////////////////////////////////////////
640 PrefLatex::PrefLatex(GuiPreferences * form)
641 : PrefModule(catOutput, N_("LaTeX"), form)
645 latexDviPaperED->setValidator(new NoNewLineValidator(latexDviPaperED));
646 latexBibtexED->setValidator(new NoNewLineValidator(latexBibtexED));
647 latexJBibtexED->setValidator(new NoNewLineValidator(latexJBibtexED));
648 latexIndexED->setValidator(new NoNewLineValidator(latexIndexED));
649 latexJIndexED->setValidator(new NoNewLineValidator(latexJIndexED));
650 latexNomenclED->setValidator(new NoNewLineValidator(latexNomenclED));
651 latexChecktexED->setValidator(new NoNewLineValidator(latexChecktexED));
653 connect(latexChecktexED, SIGNAL(textChanged(QString)),
654 this, SIGNAL(changed()));
655 connect(latexBibtexCO, SIGNAL(activated(int)),
656 this, SIGNAL(changed()));
657 connect(latexBibtexED, SIGNAL(textChanged(QString)),
658 this, SIGNAL(changed()));
659 connect(latexJBibtexCO, SIGNAL(activated(int)),
660 this, SIGNAL(changed()));
661 connect(latexJBibtexED, SIGNAL(textChanged(QString)),
662 this, SIGNAL(changed()));
663 connect(latexIndexCO, SIGNAL(activated(int)),
664 this, SIGNAL(changed()));
665 connect(latexIndexED, SIGNAL(textChanged(QString)),
666 this, SIGNAL(changed()));
667 connect(latexJIndexED, SIGNAL(textChanged(QString)),
668 this, SIGNAL(changed()));
669 connect(latexAutoresetCB, SIGNAL(clicked()),
670 this, SIGNAL(changed()));
671 connect(latexDviPaperED, SIGNAL(textChanged(QString)),
672 this, SIGNAL(changed()));
673 connect(latexNomenclED, SIGNAL(textChanged(QString)),
674 this, SIGNAL(changed()));
676 #if defined(__CYGWIN__) || defined(_WIN32)
677 pathCB->setVisible(true);
678 connect(pathCB, SIGNAL(clicked()),
679 this, SIGNAL(changed()));
681 pathCB->setVisible(false);
686 void PrefLatex::on_latexBibtexCO_activated(int n)
688 QString const bibtex = latexBibtexCO->itemData(n).toString();
689 if (bibtex.isEmpty()) {
690 latexBibtexED->clear();
691 latexBibtexOptionsLA->setText(qt_("C&ommand:"));
694 for (LyXRC::CommandSet::const_iterator it = bibtex_alternatives.begin();
695 it != bibtex_alternatives.end(); ++it) {
696 QString const bib = toqstr(*it);
697 int ind = bib.indexOf(" ");
698 QString sel_command = bib.left(ind);
699 QString sel_options = ind < 0 ? QString() : bib.mid(ind + 1);
700 if (bibtex == sel_command) {
702 latexBibtexED->clear();
704 latexBibtexED->setText(sel_options.trimmed());
707 latexBibtexOptionsLA->setText(qt_("&Options:"));
711 void PrefLatex::on_latexJBibtexCO_activated(int n)
713 QString const jbibtex = latexJBibtexCO->itemData(n).toString();
714 if (jbibtex.isEmpty()) {
715 latexJBibtexED->clear();
716 latexJBibtexOptionsLA->setText(qt_("Co&mmand:"));
719 for (LyXRC::CommandSet::const_iterator it = jbibtex_alternatives.begin();
720 it != jbibtex_alternatives.end(); ++it) {
721 QString const bib = toqstr(*it);
722 int ind = bib.indexOf(" ");
723 QString sel_command = bib.left(ind);
724 QString sel_options = ind < 0 ? QString() : bib.mid(ind + 1);
725 if (jbibtex == sel_command) {
727 latexJBibtexED->clear();
729 latexJBibtexED->setText(sel_options.trimmed());
732 latexJBibtexOptionsLA->setText(qt_("Opt&ions:"));
736 void PrefLatex::on_latexIndexCO_activated(int n)
738 QString const index = latexIndexCO->itemData(n).toString();
739 if (index.isEmpty()) {
740 latexIndexED->clear();
741 latexIndexOptionsLA->setText(qt_("Co&mmand:"));
744 for (LyXRC::CommandSet::const_iterator it = index_alternatives.begin();
745 it != index_alternatives.end(); ++it) {
746 QString const idx = toqstr(*it);
747 int ind = idx.indexOf(" ");
748 QString sel_command = idx.left(ind);
749 QString sel_options = ind < 0 ? QString() : idx.mid(ind + 1);
750 if (index == sel_command) {
752 latexIndexED->clear();
754 latexIndexED->setText(sel_options.trimmed());
757 latexIndexOptionsLA->setText(qt_("Op&tions:"));
761 void PrefLatex::applyRC(LyXRC & rc) const
763 // If bibtex is not empty, bibopt contains the options, otherwise
764 // it is a customized bibtex command with options.
765 QString const bibtex = latexBibtexCO->itemData(
766 latexBibtexCO->currentIndex()).toString();
767 QString const bibopt = latexBibtexED->text();
768 if (bibtex.isEmpty())
769 rc.bibtex_command = fromqstr(bibopt);
770 else if (bibopt.isEmpty())
771 rc.bibtex_command = fromqstr(bibtex);
773 rc.bibtex_command = fromqstr(bibtex) + " " + fromqstr(bibopt);
775 // If jbibtex is not empty, jbibopt contains the options, otherwise
776 // it is a customized bibtex command with options.
777 QString const jbibtex = latexJBibtexCO->itemData(
778 latexJBibtexCO->currentIndex()).toString();
779 QString const jbibopt = latexJBibtexED->text();
780 if (jbibtex.isEmpty())
781 rc.jbibtex_command = fromqstr(jbibopt);
782 else if (jbibopt.isEmpty())
783 rc.jbibtex_command = fromqstr(jbibtex);
785 rc.jbibtex_command = fromqstr(jbibtex) + " " + fromqstr(jbibopt);
787 // If index is not empty, idxopt contains the options, otherwise
788 // it is a customized index command with options.
789 QString const index = latexIndexCO->itemData(
790 latexIndexCO->currentIndex()).toString();
791 QString const idxopt = latexIndexED->text();
793 rc.index_command = fromqstr(idxopt);
794 else if (idxopt.isEmpty())
795 rc.index_command = fromqstr(index);
797 rc.index_command = fromqstr(index) + " " + fromqstr(idxopt);
799 rc.chktex_command = fromqstr(latexChecktexED->text());
800 rc.jindex_command = fromqstr(latexJIndexED->text());
801 rc.nomencl_command = fromqstr(latexNomenclED->text());
802 rc.auto_reset_options = latexAutoresetCB->isChecked();
803 rc.view_dvi_paper_option = fromqstr(latexDviPaperED->text());
804 #if defined(__CYGWIN__) || defined(_WIN32)
805 rc.windows_style_tex_paths = pathCB->isChecked();
810 void PrefLatex::updateRC(LyXRC const & rc)
812 latexBibtexCO->clear();
814 latexBibtexCO->addItem(qt_("Automatic"), "automatic");
815 latexBibtexCO->addItem(qt_("Custom"), QString());
816 for (LyXRC::CommandSet::const_iterator it = rc.bibtex_alternatives.begin();
817 it != rc.bibtex_alternatives.end(); ++it) {
818 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
819 latexBibtexCO->addItem(command, command);
822 bibtex_alternatives = rc.bibtex_alternatives;
824 QString const bib = toqstr(rc.bibtex_command);
825 int ind = bib.indexOf(" ");
826 QString sel_command = bib.left(ind);
827 QString sel_options = ind < 0 ? QString() : bib.mid(ind + 1);
829 int pos = latexBibtexCO->findData(sel_command);
831 latexBibtexCO->setCurrentIndex(pos);
832 latexBibtexED->setText(sel_options.trimmed());
833 latexBibtexOptionsLA->setText(qt_("&Options:"));
835 latexBibtexED->setText(toqstr(rc.bibtex_command));
836 latexBibtexCO->setCurrentIndex(0);
837 latexBibtexOptionsLA->setText(qt_("C&ommand:"));
840 latexJBibtexCO->clear();
842 latexJBibtexCO->addItem(qt_("Automatic"), "automatic");
843 latexJBibtexCO->addItem(qt_("Custom"), QString());
844 for (LyXRC::CommandSet::const_iterator it = rc.jbibtex_alternatives.begin();
845 it != rc.jbibtex_alternatives.end(); ++it) {
846 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
847 latexJBibtexCO->addItem(command, command);
850 jbibtex_alternatives = rc.jbibtex_alternatives;
852 QString const jbib = toqstr(rc.jbibtex_command);
853 ind = jbib.indexOf(" ");
854 sel_command = jbib.left(ind);
855 sel_options = ind < 0 ? QString() : jbib.mid(ind + 1);
857 pos = latexJBibtexCO->findData(sel_command);
859 latexJBibtexCO->setCurrentIndex(pos);
860 latexJBibtexED->setText(sel_options.trimmed());
861 latexJBibtexOptionsLA->setText(qt_("Opt&ions:"));
863 latexJBibtexED->setText(toqstr(rc.bibtex_command));
864 latexJBibtexCO->setCurrentIndex(0);
865 latexJBibtexOptionsLA->setText(qt_("Co&mmand:"));
868 latexIndexCO->clear();
870 latexIndexCO->addItem(qt_("Custom"), QString());
871 for (LyXRC::CommandSet::const_iterator it = rc.index_alternatives.begin();
872 it != rc.index_alternatives.end(); ++it) {
873 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
874 latexIndexCO->addItem(command, command);
877 index_alternatives = rc.index_alternatives;
879 QString const idx = toqstr(rc.index_command);
880 ind = idx.indexOf(" ");
881 sel_command = idx.left(ind);
882 sel_options = ind < 0 ? QString() : idx.mid(ind + 1);
884 pos = latexIndexCO->findData(sel_command);
886 latexIndexCO->setCurrentIndex(pos);
887 latexIndexED->setText(sel_options.trimmed());
888 latexIndexOptionsLA->setText(qt_("Op&tions:"));
890 latexIndexED->setText(toqstr(rc.index_command));
891 latexIndexCO->setCurrentIndex(0);
892 latexIndexOptionsLA->setText(qt_("Co&mmand:"));
895 latexChecktexED->setText(toqstr(rc.chktex_command));
896 latexJIndexED->setText(toqstr(rc.jindex_command));
897 latexNomenclED->setText(toqstr(rc.nomencl_command));
898 latexAutoresetCB->setChecked(rc.auto_reset_options);
899 latexDviPaperED->setText(toqstr(rc.view_dvi_paper_option));
900 #if defined(__CYGWIN__) || defined(_WIN32)
901 pathCB->setChecked(rc.windows_style_tex_paths);
906 /////////////////////////////////////////////////////////////////////
910 /////////////////////////////////////////////////////////////////////
912 PrefScreenFonts::PrefScreenFonts(GuiPreferences * form)
913 : PrefModule(catLookAndFeel, N_("Screen Fonts"), form)
917 connect(screenRomanCO, SIGNAL(activated(QString)),
918 this, SLOT(selectRoman(QString)));
919 connect(screenSansCO, SIGNAL(activated(QString)),
920 this, SLOT(selectSans(QString)));
921 connect(screenTypewriterCO, SIGNAL(activated(QString)),
922 this, SLOT(selectTypewriter(QString)));
924 QFontDatabase fontdb;
925 QStringList families(fontdb.families());
926 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
927 screenRomanCO->addItem(*it);
928 screenSansCO->addItem(*it);
929 screenTypewriterCO->addItem(*it);
931 connect(screenRomanCO, SIGNAL(activated(QString)),
932 this, SIGNAL(changed()));
933 connect(screenSansCO, SIGNAL(activated(QString)),
934 this, SIGNAL(changed()));
935 connect(screenTypewriterCO, SIGNAL(activated(QString)),
936 this, SIGNAL(changed()));
937 connect(screenZoomSB, SIGNAL(valueChanged(int)),
938 this, SIGNAL(changed()));
939 connect(screenTinyED, SIGNAL(textChanged(QString)),
940 this, SIGNAL(changed()));
941 connect(screenSmallestED, SIGNAL(textChanged(QString)),
942 this, SIGNAL(changed()));
943 connect(screenSmallerED, SIGNAL(textChanged(QString)),
944 this, SIGNAL(changed()));
945 connect(screenSmallED, SIGNAL(textChanged(QString)),
946 this, SIGNAL(changed()));
947 connect(screenNormalED, SIGNAL(textChanged(QString)),
948 this, SIGNAL(changed()));
949 connect(screenLargeED, SIGNAL(textChanged(QString)),
950 this, SIGNAL(changed()));
951 connect(screenLargerED, SIGNAL(textChanged(QString)),
952 this, SIGNAL(changed()));
953 connect(screenLargestED, SIGNAL(textChanged(QString)),
954 this, SIGNAL(changed()));
955 connect(screenHugeED, SIGNAL(textChanged(QString)),
956 this, SIGNAL(changed()));
957 connect(screenHugerED, SIGNAL(textChanged(QString)),
958 this, SIGNAL(changed()));
960 screenTinyED->setValidator(new QDoubleValidator(screenTinyED));
961 screenSmallestED->setValidator(new QDoubleValidator(screenSmallestED));
962 screenSmallerED->setValidator(new QDoubleValidator(screenSmallerED));
963 screenSmallED->setValidator(new QDoubleValidator(screenSmallED));
964 screenNormalED->setValidator(new QDoubleValidator(screenNormalED));
965 screenLargeED->setValidator(new QDoubleValidator(screenLargeED));
966 screenLargerED->setValidator(new QDoubleValidator(screenLargerED));
967 screenLargestED->setValidator(new QDoubleValidator(screenLargestED));
968 screenHugeED->setValidator(new QDoubleValidator(screenHugeED));
969 screenHugerED->setValidator(new QDoubleValidator(screenHugerED));
973 void PrefScreenFonts::applyRC(LyXRC & rc) const
975 LyXRC const oldrc = rc;
977 parseFontName(screenRomanCO->currentText(),
978 rc.roman_font_name, rc.roman_font_foundry);
979 parseFontName(screenSansCO->currentText(),
980 rc.sans_font_name, rc.sans_font_foundry);
981 parseFontName(screenTypewriterCO->currentText(),
982 rc.typewriter_font_name, rc.typewriter_font_foundry);
984 rc.defaultZoom = screenZoomSB->value();
985 rc.font_sizes[TINY_SIZE] = widgetToDoubleStr(screenTinyED);
986 rc.font_sizes[SCRIPT_SIZE] = widgetToDoubleStr(screenSmallestED);
987 rc.font_sizes[FOOTNOTE_SIZE] = widgetToDoubleStr(screenSmallerED);
988 rc.font_sizes[SMALL_SIZE] = widgetToDoubleStr(screenSmallED);
989 rc.font_sizes[NORMAL_SIZE] = widgetToDoubleStr(screenNormalED);
990 rc.font_sizes[LARGE_SIZE] = widgetToDoubleStr(screenLargeED);
991 rc.font_sizes[LARGER_SIZE] = widgetToDoubleStr(screenLargerED);
992 rc.font_sizes[LARGEST_SIZE] = widgetToDoubleStr(screenLargestED);
993 rc.font_sizes[HUGE_SIZE] = widgetToDoubleStr(screenHugeED);
994 rc.font_sizes[HUGER_SIZE] = widgetToDoubleStr(screenHugerED);
998 void PrefScreenFonts::updateRC(LyXRC const & rc)
1000 setComboxFont(screenRomanCO, rc.roman_font_name,
1001 rc.roman_font_foundry);
1002 setComboxFont(screenSansCO, rc.sans_font_name,
1003 rc.sans_font_foundry);
1004 setComboxFont(screenTypewriterCO, rc.typewriter_font_name,
1005 rc.typewriter_font_foundry);
1007 selectRoman(screenRomanCO->currentText());
1008 selectSans(screenSansCO->currentText());
1009 selectTypewriter(screenTypewriterCO->currentText());
1011 screenZoomSB->setValue(rc.defaultZoom);
1012 updateScreenFontSizes(rc);
1016 void PrefScreenFonts::updateScreenFontSizes(LyXRC const & rc)
1018 doubleToWidget(screenTinyED, rc.font_sizes[TINY_SIZE]);
1019 doubleToWidget(screenSmallestED, rc.font_sizes[SCRIPT_SIZE]);
1020 doubleToWidget(screenSmallerED, rc.font_sizes[FOOTNOTE_SIZE]);
1021 doubleToWidget(screenSmallED, rc.font_sizes[SMALL_SIZE]);
1022 doubleToWidget(screenNormalED, rc.font_sizes[NORMAL_SIZE]);
1023 doubleToWidget(screenLargeED, rc.font_sizes[LARGE_SIZE]);
1024 doubleToWidget(screenLargerED, rc.font_sizes[LARGER_SIZE]);
1025 doubleToWidget(screenLargestED, rc.font_sizes[LARGEST_SIZE]);
1026 doubleToWidget(screenHugeED, rc.font_sizes[HUGE_SIZE]);
1027 doubleToWidget(screenHugerED, rc.font_sizes[HUGER_SIZE]);
1031 void PrefScreenFonts::selectRoman(const QString & name)
1033 screenRomanFE->set(QFont(name), name);
1037 void PrefScreenFonts::selectSans(const QString & name)
1039 screenSansFE->set(QFont(name), name);
1043 void PrefScreenFonts::selectTypewriter(const QString & name)
1045 screenTypewriterFE->set(QFont(name), name);
1049 /////////////////////////////////////////////////////////////////////
1053 /////////////////////////////////////////////////////////////////////
1056 PrefColors::PrefColors(GuiPreferences * form)
1057 : PrefModule(catLookAndFeel, N_("Colors"), form)
1061 // FIXME: all of this initialization should be put into the controller.
1062 // See http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg113301.html
1063 // for some discussion of why that is not trivial.
1064 QPixmap icon(32, 32);
1065 for (int i = 0; i < Color_ignore; ++i) {
1066 ColorCode lc = static_cast<ColorCode>(i);
1067 if (lc == Color_none
1068 || lc == Color_black
1069 || lc == Color_white
1071 || lc == Color_brown
1073 || lc == Color_darkgray
1075 || lc == Color_green
1076 || lc == Color_lightgray
1078 || lc == Color_magenta
1079 || lc == Color_olive
1080 || lc == Color_orange
1082 || lc == Color_purple
1085 || lc == Color_violet
1086 || lc == Color_yellow
1087 || lc == Color_inherit
1088 || lc == Color_ignore)
1090 lcolors_.push_back(lc);
1092 qSort(lcolors_.begin(), lcolors_.end(), ColorSorter);
1093 vector<ColorCode>::const_iterator cit = lcolors_.begin();
1094 vector<ColorCode>::const_iterator const end = lcolors_.end();
1095 for (; cit != end; ++cit) {
1096 (void) new QListWidgetItem(QIcon(icon),
1097 toqstr(lcolor.getGUIName(*cit)), lyxObjectsLW);
1099 curcolors_.resize(lcolors_.size());
1100 newcolors_.resize(lcolors_.size());
1101 // End initialization
1103 connect(colorChangePB, SIGNAL(clicked()),
1104 this, SLOT(changeColor()));
1105 connect(colorResetPB, SIGNAL(clicked()),
1106 this, SLOT(resetColor()));
1107 connect(colorResetAllPB, SIGNAL(clicked()),
1108 this, SLOT(resetAllColor()));
1109 connect(lyxObjectsLW, SIGNAL(itemSelectionChanged()),
1110 this, SLOT(changeLyxObjectsSelection()));
1111 connect(lyxObjectsLW, SIGNAL(itemActivated(QListWidgetItem*)),
1112 this, SLOT(changeColor()));
1113 connect(syscolorsCB, SIGNAL(toggled(bool)),
1114 this, SIGNAL(changed()));
1115 connect(syscolorsCB, SIGNAL(toggled(bool)),
1116 this, SLOT(changeSysColor()));
1120 void PrefColors::applyRC(LyXRC & rc) const
1124 for (unsigned int i = 0; i < lcolors_.size(); ++i)
1125 if (curcolors_[i] != newcolors_[i])
1126 form_->setColor(lcolors_[i], newcolors_[i]);
1127 rc.use_system_colors = syscolorsCB->isChecked();
1129 if (oldrc.use_system_colors != rc.use_system_colors)
1130 guiApp->colorCache().clear();
1134 void PrefColors::updateRC(LyXRC const & rc)
1136 for (size_type i = 0; i < lcolors_.size(); ++i) {
1137 QColor color = QColor(guiApp->colorCache().get(lcolors_[i], false));
1138 QPixmap coloritem(32, 32);
1139 coloritem.fill(color);
1140 lyxObjectsLW->item(int(i))->setIcon(QIcon(coloritem));
1141 newcolors_[i] = curcolors_[i] = color.name();
1143 syscolorsCB->setChecked(rc.use_system_colors);
1144 changeLyxObjectsSelection();
1146 setDisabledResets();
1150 void PrefColors::changeColor()
1152 int const row = lyxObjectsLW->currentRow();
1158 QString const color = newcolors_[size_t(row)];
1159 QColor const c = QColorDialog::getColor(QColor(color), qApp->focusWidget());
1161 if (setColor(row, c, color)) {
1162 setDisabledResets();
1169 void PrefColors::resetColor()
1171 int const row = lyxObjectsLW->currentRow();
1177 QString const color = newcolors_[size_t(row)];
1178 QColor const c = getDefaultColorByRow(row);
1180 if (setColor(row, c, color)) {
1181 setDisabledResets();
1188 void PrefColors::resetAllColor()
1190 bool isChanged = false;
1192 colorResetAllPB->setDisabled(true);
1194 for (int irow = 0, count = lyxObjectsLW->count(); irow < count; ++irow) {
1195 QString const color = newcolors_[size_t(irow)];
1196 QColor const c = getDefaultColorByRow(irow);
1198 if (setColor(irow, c, color))
1203 setDisabledResets();
1210 bool PrefColors::setColor(int const row, QColor const new_color,
1211 QString const old_color)
1213 if (new_color.isValid() && new_color.name() != old_color) {
1214 newcolors_[size_t(row)] = new_color.name();
1215 QPixmap coloritem(32, 32);
1216 coloritem.fill(new_color);
1217 lyxObjectsLW->item(row)->setIcon(QIcon(coloritem));
1224 void PrefColors::setDisabledResets()
1226 int const row = lyxObjectsLW->currentRow();
1227 // set disable reset buttons ...
1229 colorResetPB->setDisabled(isDefaultColor(row, newcolors_[size_t(row)]));
1231 colorResetAllPB->setDisabled(true);
1233 // ... in between process qt events to give quicker visual feedback to the user ...
1234 guiApp->processEvents();
1236 // ... set disable Reset All button
1237 for (int irow = 0, count = lyxObjectsLW->count(); irow < count; ++irow) {
1238 if (!isDefaultColor(irow, newcolors_[size_t(irow)])) {
1239 colorResetAllPB->setDisabled(false);
1240 // the break condition might hide performance issues
1241 // if a non-default color is at the top of the list
1248 bool PrefColors::isDefaultColor(int const row, QString const color)
1250 return color == getDefaultColorByRow(row).name();
1254 QColor PrefColors::getDefaultColorByRow(int const row)
1256 ColorSet const defaultcolor;
1257 return defaultcolor.getX11Name(lcolors_[size_t(row)]).c_str();
1261 void PrefColors::changeSysColor()
1263 for (int row = 0 ; row < lyxObjectsLW->count() ; ++row) {
1264 // skip colors that are taken from system palette
1265 bool const disable = syscolorsCB->isChecked()
1266 && guiApp->colorCache().isSystem(lcolors_[size_t(row)]);
1268 QListWidgetItem * const item = lyxObjectsLW->item(row);
1269 Qt::ItemFlags const flags = item->flags();
1272 item->setFlags(flags & ~Qt::ItemIsEnabled);
1274 item->setFlags(flags | Qt::ItemIsEnabled);
1279 void PrefColors::changeLyxObjectsSelection()
1281 int currentRow = lyxObjectsLW->currentRow();
1282 colorChangePB->setDisabled(currentRow < 0);
1285 colorResetPB->setDisabled(true);
1287 colorResetPB->setDisabled(
1288 isDefaultColor(currentRow, newcolors_[size_t(currentRow)]));
1292 /////////////////////////////////////////////////////////////////////
1296 /////////////////////////////////////////////////////////////////////
1298 PrefDisplay::PrefDisplay(GuiPreferences * form)
1299 : PrefModule(catLookAndFeel, N_("Display"), form)
1302 connect(displayGraphicsCB, SIGNAL(toggled(bool)), this, SIGNAL(changed()));
1303 connect(instantPreviewCO, SIGNAL(activated(int)), this, SIGNAL(changed()));
1304 connect(previewSizeSB, SIGNAL(valueChanged(double)), this, SIGNAL(changed()));
1305 connect(paragraphMarkerCB, SIGNAL(toggled(bool)), this, SIGNAL(changed()));
1309 void PrefDisplay::on_instantPreviewCO_currentIndexChanged(int index)
1311 previewSizeSB->setEnabled(index != 0);
1315 void PrefDisplay::applyRC(LyXRC & rc) const
1317 switch (instantPreviewCO->currentIndex()) {
1319 rc.preview = LyXRC::PREVIEW_OFF;
1322 rc.preview = LyXRC::PREVIEW_NO_MATH;
1325 rc.preview = LyXRC::PREVIEW_ON;
1329 rc.display_graphics = displayGraphicsCB->isChecked();
1330 rc.preview_scale_factor = previewSizeSB->value();
1331 rc.paragraph_markers = paragraphMarkerCB->isChecked();
1333 // FIXME!! The graphics cache no longer has a changeDisplay method.
1335 if (old_value != rc.display_graphics) {
1336 graphics::GCache & gc = graphics::GCache::get();
1343 void PrefDisplay::updateRC(LyXRC const & rc)
1345 switch (rc.preview) {
1346 case LyXRC::PREVIEW_OFF:
1347 instantPreviewCO->setCurrentIndex(0);
1349 case LyXRC::PREVIEW_NO_MATH :
1350 instantPreviewCO->setCurrentIndex(1);
1352 case LyXRC::PREVIEW_ON :
1353 instantPreviewCO->setCurrentIndex(2);
1357 displayGraphicsCB->setChecked(rc.display_graphics);
1358 previewSizeSB->setValue(rc.preview_scale_factor);
1359 paragraphMarkerCB->setChecked(rc.paragraph_markers);
1360 previewSizeSB->setEnabled(
1362 && rc.preview != LyXRC::PREVIEW_OFF);
1366 /////////////////////////////////////////////////////////////////////
1370 /////////////////////////////////////////////////////////////////////
1372 PrefPaths::PrefPaths(GuiPreferences * form)
1373 : PrefModule(QString(), N_("Paths"), form)
1377 connect(workingDirPB, SIGNAL(clicked()), this, SLOT(selectWorkingdir()));
1378 connect(workingDirED, SIGNAL(textChanged(QString)),
1379 this, SIGNAL(changed()));
1381 connect(templateDirPB, SIGNAL(clicked()), this, SLOT(selectTemplatedir()));
1382 connect(templateDirED, SIGNAL(textChanged(QString)),
1383 this, SIGNAL(changed()));
1385 connect(exampleDirPB, SIGNAL(clicked()), this, SLOT(selectExampledir()));
1386 connect(exampleDirED, SIGNAL(textChanged(QString)),
1387 this, SIGNAL(changed()));
1389 connect(backupDirPB, SIGNAL(clicked()), this, SLOT(selectBackupdir()));
1390 connect(backupDirED, SIGNAL(textChanged(QString)),
1391 this, SIGNAL(changed()));
1393 connect(lyxserverDirPB, SIGNAL(clicked()), this, SLOT(selectLyxPipe()));
1394 connect(lyxserverDirED, SIGNAL(textChanged(QString)),
1395 this, SIGNAL(changed()));
1397 connect(thesaurusDirPB, SIGNAL(clicked()), this, SLOT(selectThesaurusdir()));
1398 connect(thesaurusDirED, SIGNAL(textChanged(QString)),
1399 this, SIGNAL(changed()));
1401 connect(tempDirPB, SIGNAL(clicked()), this, SLOT(selectTempdir()));
1402 connect(tempDirED, SIGNAL(textChanged(QString)),
1403 this, SIGNAL(changed()));
1405 #if defined(USE_HUNSPELL)
1406 connect(hunspellDirPB, SIGNAL(clicked()), this, SLOT(selectHunspelldir()));
1407 connect(hunspellDirED, SIGNAL(textChanged(QString)),
1408 this, SIGNAL(changed()));
1410 hunspellDirPB->setEnabled(false);
1411 hunspellDirED->setEnabled(false);
1414 connect(pathPrefixED, SIGNAL(textChanged(QString)),
1415 this, SIGNAL(changed()));
1417 connect(texinputsPrefixED, SIGNAL(textChanged(QString)),
1418 this, SIGNAL(changed()));
1420 pathPrefixED->setValidator(new NoNewLineValidator(pathPrefixED));
1421 texinputsPrefixED->setValidator(new NoNewLineValidator(texinputsPrefixED));
1425 void PrefPaths::applyRC(LyXRC & rc) const
1427 rc.document_path = internal_path(fromqstr(workingDirED->text()));
1428 rc.example_path = internal_path(fromqstr(exampleDirED->text()));
1429 rc.template_path = internal_path(fromqstr(templateDirED->text()));
1430 rc.backupdir_path = internal_path(fromqstr(backupDirED->text()));
1431 rc.tempdir_path = internal_path(fromqstr(tempDirED->text()));
1432 rc.thesaurusdir_path = internal_path(fromqstr(thesaurusDirED->text()));
1433 rc.hunspelldir_path = internal_path(fromqstr(hunspellDirED->text()));
1434 rc.path_prefix = internal_path_list(fromqstr(pathPrefixED->text()));
1435 rc.texinputs_prefix = internal_path_list(fromqstr(texinputsPrefixED->text()));
1436 // FIXME: should be a checkbox only
1437 rc.lyxpipes = internal_path(fromqstr(lyxserverDirED->text()));
1441 void PrefPaths::updateRC(LyXRC const & rc)
1443 workingDirED->setText(toqstr(external_path(rc.document_path)));
1444 exampleDirED->setText(toqstr(external_path(rc.example_path)));
1445 templateDirED->setText(toqstr(external_path(rc.template_path)));
1446 backupDirED->setText(toqstr(external_path(rc.backupdir_path)));
1447 tempDirED->setText(toqstr(external_path(rc.tempdir_path)));
1448 thesaurusDirED->setText(toqstr(external_path(rc.thesaurusdir_path)));
1449 hunspellDirED->setText(toqstr(external_path(rc.hunspelldir_path)));
1450 pathPrefixED->setText(toqstr(external_path_list(rc.path_prefix)));
1451 texinputsPrefixED->setText(toqstr(external_path_list(rc.texinputs_prefix)));
1452 // FIXME: should be a checkbox only
1453 lyxserverDirED->setText(toqstr(external_path(rc.lyxpipes)));
1457 void PrefPaths::selectExampledir()
1459 QString file = browseDir(internalPath(exampleDirED->text()),
1460 qt_("Select directory for example files"));
1461 if (!file.isEmpty())
1462 exampleDirED->setText(file);
1466 void PrefPaths::selectTemplatedir()
1468 QString file = browseDir(internalPath(templateDirED->text()),
1469 qt_("Select a document templates directory"));
1470 if (!file.isEmpty())
1471 templateDirED->setText(file);
1475 void PrefPaths::selectTempdir()
1477 QString file = browseDir(internalPath(tempDirED->text()),
1478 qt_("Select a temporary directory"));
1479 if (!file.isEmpty())
1480 tempDirED->setText(file);
1484 void PrefPaths::selectBackupdir()
1486 QString file = browseDir(internalPath(backupDirED->text()),
1487 qt_("Select a backups directory"));
1488 if (!file.isEmpty())
1489 backupDirED->setText(file);
1493 void PrefPaths::selectWorkingdir()
1495 QString file = browseDir(internalPath(workingDirED->text()),
1496 qt_("Select a document directory"));
1497 if (!file.isEmpty())
1498 workingDirED->setText(file);
1502 void PrefPaths::selectThesaurusdir()
1504 QString file = browseDir(internalPath(thesaurusDirED->text()),
1505 qt_("Set the path to the thesaurus dictionaries"));
1506 if (!file.isEmpty())
1507 thesaurusDirED->setText(file);
1511 void PrefPaths::selectHunspelldir()
1513 QString file = browseDir(internalPath(hunspellDirED->text()),
1514 qt_("Set the path to the Hunspell dictionaries"));
1515 if (!file.isEmpty())
1516 hunspellDirED->setText(file);
1520 void PrefPaths::selectLyxPipe()
1522 QString file = form_->browse(internalPath(lyxserverDirED->text()),
1523 qt_("Give a filename for the LyX server pipe"));
1524 if (!file.isEmpty())
1525 lyxserverDirED->setText(file);
1529 /////////////////////////////////////////////////////////////////////
1533 /////////////////////////////////////////////////////////////////////
1535 PrefSpellchecker::PrefSpellchecker(GuiPreferences * form)
1536 : PrefModule(catLanguage, N_("Spellchecker"), form)
1540 // FIXME: this check should test the target platform (darwin)
1541 #if defined(USE_MACOSX_PACKAGING)
1542 spellcheckerCB->addItem(qt_("Native"), QString("native"));
1543 #define CONNECT_APPLESPELL
1545 #undef CONNECT_APPLESPELL
1547 #if defined(USE_ASPELL)
1548 spellcheckerCB->addItem(qt_("Aspell"), QString("aspell"));
1550 #if defined(USE_ENCHANT)
1551 spellcheckerCB->addItem(qt_("Enchant"), QString("enchant"));
1553 #if defined(USE_HUNSPELL)
1554 spellcheckerCB->addItem(qt_("Hunspell"), QString("hunspell"));
1557 #if defined(CONNECT_APPLESPELL) || defined(USE_ASPELL) || defined(USE_ENCHANT) || defined(USE_HUNSPELL)
1558 connect(spellcheckerCB, SIGNAL(currentIndexChanged(int)),
1559 this, SIGNAL(changed()));
1560 connect(altLanguageED, SIGNAL(textChanged(QString)),
1561 this, SIGNAL(changed()));
1562 connect(escapeCharactersED, SIGNAL(textChanged(QString)),
1563 this, SIGNAL(changed()));
1564 connect(compoundWordCB, SIGNAL(clicked()),
1565 this, SIGNAL(changed()));
1566 connect(spellcheckContinuouslyCB, SIGNAL(clicked()),
1567 this, SIGNAL(changed()));
1568 connect(spellcheckNotesCB, SIGNAL(clicked()),
1569 this, SIGNAL(changed()));
1571 altLanguageED->setValidator(new NoNewLineValidator(altLanguageED));
1572 escapeCharactersED->setValidator(new NoNewLineValidator(escapeCharactersED));
1574 spellcheckerCB->setEnabled(false);
1575 altLanguageED->setEnabled(false);
1576 escapeCharactersED->setEnabled(false);
1577 compoundWordCB->setEnabled(false);
1578 spellcheckContinuouslyCB->setEnabled(false);
1579 spellcheckNotesCB->setEnabled(false);
1584 void PrefSpellchecker::applyRC(LyXRC & rc) const
1586 string const speller = fromqstr(spellcheckerCB->
1587 itemData(spellcheckerCB->currentIndex()).toString());
1588 if (!speller.empty())
1589 rc.spellchecker = speller;
1590 rc.spellchecker_alt_lang = fromqstr(altLanguageED->text());
1591 rc.spellchecker_esc_chars = fromqstr(escapeCharactersED->text());
1592 rc.spellchecker_accept_compound = compoundWordCB->isChecked();
1593 rc.spellcheck_continuously = spellcheckContinuouslyCB->isChecked();
1594 rc.spellcheck_notes = spellcheckNotesCB->isChecked();
1598 void PrefSpellchecker::updateRC(LyXRC const & rc)
1600 spellcheckerCB->setCurrentIndex(
1601 spellcheckerCB->findData(toqstr(rc.spellchecker)));
1602 altLanguageED->setText(toqstr(rc.spellchecker_alt_lang));
1603 escapeCharactersED->setText(toqstr(rc.spellchecker_esc_chars));
1604 compoundWordCB->setChecked(rc.spellchecker_accept_compound);
1605 spellcheckContinuouslyCB->setChecked(rc.spellcheck_continuously);
1606 spellcheckNotesCB->setChecked(rc.spellcheck_notes);
1610 void PrefSpellchecker::on_spellcheckerCB_currentIndexChanged(int index)
1612 QString spellchecker = spellcheckerCB->itemData(index).toString();
1614 compoundWordCB->setEnabled(spellchecker == QString("aspell"));
1619 /////////////////////////////////////////////////////////////////////
1623 /////////////////////////////////////////////////////////////////////
1626 PrefConverters::PrefConverters(GuiPreferences * form)
1627 : PrefModule(catFiles, N_("Converters"), form)
1631 connect(converterNewPB, SIGNAL(clicked()),
1632 this, SLOT(updateConverter()));
1633 connect(converterRemovePB, SIGNAL(clicked()),
1634 this, SLOT(removeConverter()));
1635 connect(converterModifyPB, SIGNAL(clicked()),
1636 this, SLOT(updateConverter()));
1637 connect(convertersLW, SIGNAL(currentRowChanged(int)),
1638 this, SLOT(switchConverter()));
1639 connect(converterFromCO, SIGNAL(activated(QString)),
1640 this, SLOT(changeConverter()));
1641 connect(converterToCO, SIGNAL(activated(QString)),
1642 this, SLOT(changeConverter()));
1643 connect(converterED, SIGNAL(textEdited(QString)),
1644 this, SLOT(changeConverter()));
1645 connect(converterFlagED, SIGNAL(textEdited(QString)),
1646 this, SLOT(changeConverter()));
1647 connect(converterNewPB, SIGNAL(clicked()),
1648 this, SIGNAL(changed()));
1649 connect(converterRemovePB, SIGNAL(clicked()),
1650 this, SIGNAL(changed()));
1651 connect(converterModifyPB, SIGNAL(clicked()),
1652 this, SIGNAL(changed()));
1653 connect(maxAgeLE, SIGNAL(textEdited(QString)),
1654 this, SIGNAL(changed()));
1655 connect(needauthForbiddenCB, SIGNAL(toggled(bool)),
1656 this, SIGNAL(changed()));
1658 converterED->setValidator(new NoNewLineValidator(converterED));
1659 converterFlagED->setValidator(new NoNewLineValidator(converterFlagED));
1660 maxAgeLE->setValidator(new QDoubleValidator(0, HUGE_VAL, 6, maxAgeLE));
1661 //converterDefGB->setFocusProxy(convertersLW);
1665 void PrefConverters::applyRC(LyXRC & rc) const
1667 rc.use_converter_cache = cacheCB->isChecked();
1668 rc.use_converter_needauth_forbidden = needauthForbiddenCB->isChecked();
1669 rc.use_converter_needauth = needauthCB->isChecked();
1670 rc.converter_cache_maxage = int(widgetToDouble(maxAgeLE) * 86400.0);
1674 static void setCheckboxBlockSignals(QCheckBox *cb, bool checked) {
1675 cb->blockSignals(true);
1676 cb->setChecked(checked);
1677 cb->blockSignals(false);
1681 void PrefConverters::updateRC(LyXRC const & rc)
1683 cacheCB->setChecked(rc.use_converter_cache);
1684 needauthForbiddenCB->setChecked(rc.use_converter_needauth_forbidden);
1685 setCheckboxBlockSignals(needauthCB, rc.use_converter_needauth);
1687 doubleToWidget(maxAgeLE, (double(rc.converter_cache_maxage) / 86400.0), 'g', 6);
1692 void PrefConverters::updateGui()
1694 QString const pattern("%1 -> %2");
1695 form_->formats().sort();
1696 form_->converters().update(form_->formats());
1697 // save current selection
1700 .arg(converterFromCO->currentText())
1701 .arg(converterToCO->currentText());
1703 converterFromCO->clear();
1704 converterToCO->clear();
1706 for (Format const & f : form_->formats()) {
1707 QString const name = toqstr(translateIfPossible(f.prettyname()));
1708 converterFromCO->addItem(name);
1709 converterToCO->addItem(name);
1712 // currentRowChanged(int) is also triggered when updating the listwidget
1713 // block signals to avoid unnecessary calls to switchConverter()
1714 convertersLW->blockSignals(true);
1715 convertersLW->clear();
1717 for (Converter const & c : form_->converters()) {
1718 QString const name =
1720 .arg(toqstr(translateIfPossible(c.From()->prettyname())))
1721 .arg(toqstr(translateIfPossible(c.To()->prettyname())));
1722 int type = form_->converters().getNumber(c.From()->name(),
1724 new QListWidgetItem(name, convertersLW, type);
1726 convertersLW->sortItems(Qt::AscendingOrder);
1727 convertersLW->blockSignals(false);
1729 // restore selection
1730 if (current != pattern.arg(QString()).arg(QString())) {
1731 QList<QListWidgetItem *> const item =
1732 convertersLW->findItems(current, Qt::MatchExactly);
1733 if (!item.isEmpty())
1734 convertersLW->setCurrentItem(item.at(0));
1737 // select first element if restoring failed
1738 if (convertersLW->currentRow() == -1)
1739 convertersLW->setCurrentRow(0);
1745 void PrefConverters::switchConverter()
1747 int const cnr = convertersLW->currentItem()->type();
1748 Converter const & c(form_->converters().get(cnr));
1749 converterFromCO->setCurrentIndex(form_->formats().getNumber(c.from()));
1750 converterToCO->setCurrentIndex(form_->formats().getNumber(c.to()));
1751 converterED->setText(toqstr(c.command()));
1752 converterFlagED->setText(toqstr(c.flags()));
1758 void PrefConverters::changeConverter()
1764 void PrefConverters::updateButtons()
1766 if (form_->formats().empty())
1768 Format const & from = form_->formats().get(converterFromCO->currentIndex());
1769 Format const & to = form_->formats().get(converterToCO->currentIndex());
1770 int const sel = form_->converters().getNumber(from.name(), to.name());
1771 bool const known = sel >= 0;
1772 bool const valid = !(converterED->text().isEmpty()
1773 || from.name() == to.name());
1778 if (convertersLW->count() > 0) {
1779 int const cnr = convertersLW->currentItem()->type();
1780 Converter const & c = form_->converters().get(cnr);
1781 old_command = c.command();
1782 old_flag = c.flags();
1785 string const new_command = fromqstr(converterED->text());
1786 string const new_flag = fromqstr(converterFlagED->text());
1788 bool modified = (old_command != new_command || old_flag != new_flag);
1790 converterModifyPB->setEnabled(valid && known && modified);
1791 converterNewPB->setEnabled(valid && !known);
1792 converterRemovePB->setEnabled(known);
1794 maxAgeLE->setEnabled(cacheCB->isChecked());
1795 maxAgeLA->setEnabled(cacheCB->isChecked());
1800 // specify unique from/to or it doesn't appear. This is really bad UI
1801 // this is why we can use the same function for both new and modify
1802 void PrefConverters::updateConverter()
1804 Format const & from = form_->formats().get(converterFromCO->currentIndex());
1805 Format const & to = form_->formats().get(converterToCO->currentIndex());
1806 string const flags = fromqstr(converterFlagED->text());
1807 string const command = fromqstr(converterED->text());
1809 Converter const * old =
1810 form_->converters().getConverter(from.name(), to.name());
1811 form_->converters().add(from.name(), to.name(), command, flags);
1814 form_->converters().updateLast(form_->formats());
1818 // Remove all files created by this converter from the cache, since
1819 // the modified converter might create different files.
1820 ConverterCache::get().remove_all(from.name(), to.name());
1824 void PrefConverters::removeConverter()
1826 Format const & from = form_->formats().get(converterFromCO->currentIndex());
1827 Format const & to = form_->formats().get(converterToCO->currentIndex());
1828 form_->converters().erase(from.name(), to.name());
1832 // Remove all files created by this converter from the cache, since
1833 // a possible new converter might create different files.
1834 ConverterCache::get().remove_all(from.name(), to.name());
1838 void PrefConverters::on_cacheCB_stateChanged(int state)
1840 maxAgeLE->setEnabled(state == Qt::Checked);
1841 maxAgeLA->setEnabled(state == Qt::Checked);
1846 void PrefConverters::on_needauthForbiddenCB_toggled(bool checked)
1848 needauthCB->setEnabled(!checked);
1852 void PrefConverters::on_needauthCB_toggled(bool checked)
1859 int ret = frontend::Alert::prompt(
1860 _("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!"),
1861 0, 0, _("&No"), _("&Yes"));
1865 setCheckboxBlockSignals(needauthCB, true);
1869 /////////////////////////////////////////////////////////////////////
1873 /////////////////////////////////////////////////////////////////////
1875 class FormatValidator : public QValidator
1878 FormatValidator(QWidget *, Formats const & f);
1879 void fixup(QString & input) const;
1880 QValidator::State validate(QString & input, int & pos) const;
1882 virtual QString toString(Format const & format) const = 0;
1884 Formats const & formats_;
1888 FormatValidator::FormatValidator(QWidget * parent, Formats const & f)
1889 : QValidator(parent), formats_(f)
1894 void FormatValidator::fixup(QString & input) const
1896 Formats::const_iterator cit = formats_.begin();
1897 Formats::const_iterator end = formats_.end();
1898 for (; cit != end; ++cit) {
1899 QString const name = toString(*cit);
1900 if (distance(formats_.begin(), cit) == nr()) {
1908 QValidator::State FormatValidator::validate(QString & input, int & /*pos*/) const
1910 Formats::const_iterator cit = formats_.begin();
1911 Formats::const_iterator end = formats_.end();
1912 bool unknown = true;
1913 for (; unknown && cit != end; ++cit) {
1914 QString const name = toString(*cit);
1915 if (distance(formats_.begin(), cit) != nr())
1916 unknown = name != input;
1919 if (unknown && !input.isEmpty())
1920 return QValidator::Acceptable;
1922 return QValidator::Intermediate;
1926 int FormatValidator::nr() const
1928 QComboBox * p = qobject_cast<QComboBox *>(parent());
1929 return p->itemData(p->currentIndex()).toInt();
1933 /////////////////////////////////////////////////////////////////////
1935 // FormatNameValidator
1937 /////////////////////////////////////////////////////////////////////
1939 class FormatNameValidator : public FormatValidator
1942 FormatNameValidator(QWidget * parent, Formats const & f)
1943 : FormatValidator(parent, f)
1946 QString toString(Format const & format) const
1948 return toqstr(format.name());
1953 /////////////////////////////////////////////////////////////////////
1955 // FormatPrettynameValidator
1957 /////////////////////////////////////////////////////////////////////
1959 class FormatPrettynameValidator : public FormatValidator
1962 FormatPrettynameValidator(QWidget * parent, Formats const & f)
1963 : FormatValidator(parent, f)
1966 QString toString(Format const & format) const
1968 return toqstr(translateIfPossible(format.prettyname()));
1973 /////////////////////////////////////////////////////////////////////
1977 /////////////////////////////////////////////////////////////////////
1979 PrefFileformats::PrefFileformats(GuiPreferences * form)
1980 : PrefModule(catFiles, N_("File Formats"), form)
1984 formatED->setValidator(new FormatNameValidator(formatsCB, form_->formats()));
1985 formatsCB->setValidator(new FormatPrettynameValidator(formatsCB, form_->formats()));
1986 extensionsED->setValidator(new NoNewLineValidator(extensionsED));
1987 shortcutED->setValidator(new NoNewLineValidator(shortcutED));
1988 editorED->setValidator(new NoNewLineValidator(editorED));
1989 viewerED->setValidator(new NoNewLineValidator(viewerED));
1990 copierED->setValidator(new NoNewLineValidator(copierED));
1992 connect(documentCB, SIGNAL(clicked()),
1993 this, SLOT(setFlags()));
1994 connect(vectorCB, SIGNAL(clicked()),
1995 this, SLOT(setFlags()));
1996 connect(exportMenuCB, SIGNAL(clicked()),
1997 this, SLOT(setFlags()));
1998 connect(formatsCB->lineEdit(), SIGNAL(editingFinished()),
1999 this, SLOT(updatePrettyname()));
2000 connect(formatsCB->lineEdit(), SIGNAL(textEdited(QString)),
2001 this, SIGNAL(changed()));
2002 connect(defaultFormatCB, SIGNAL(activated(QString)),
2003 this, SIGNAL(changed()));
2004 connect(defaultOTFFormatCB, SIGNAL(activated(QString)),
2005 this, SIGNAL(changed()));
2006 connect(defaultPlatexFormatCB, SIGNAL(activated(QString)),
2007 this, SIGNAL(changed()));
2008 connect(viewerCO, SIGNAL(activated(int)),
2009 this, SIGNAL(changed()));
2010 connect(editorCO, SIGNAL(activated(int)),
2011 this, SIGNAL(changed()));
2017 string const l10n_shortcut(docstring const & prettyname, string const & shortcut)
2019 if (shortcut.empty())
2022 string l10n_format =
2023 to_utf8(_(to_utf8(prettyname) + '|' + shortcut));
2024 return split(l10n_format, '|');
2030 void PrefFileformats::applyRC(LyXRC & rc) const
2032 QString const default_format = defaultFormatCB->itemData(
2033 defaultFormatCB->currentIndex()).toString();
2034 rc.default_view_format = fromqstr(default_format);
2035 QString const default_otf_format = defaultOTFFormatCB->itemData(
2036 defaultOTFFormatCB->currentIndex()).toString();
2037 rc.default_otf_view_format = fromqstr(default_otf_format);
2038 QString const default_platex_format = defaultPlatexFormatCB->itemData(
2039 defaultPlatexFormatCB->currentIndex()).toString();
2040 rc.default_platex_view_format = fromqstr(default_platex_format);
2044 void PrefFileformats::updateRC(LyXRC const & rc)
2046 viewer_alternatives = rc.viewer_alternatives;
2047 editor_alternatives = rc.editor_alternatives;
2048 bool const init = defaultFormatCB->currentText().isEmpty();
2052 defaultFormatCB->findData(toqstr(rc.default_view_format));
2053 defaultFormatCB->setCurrentIndex(pos);
2054 pos = defaultOTFFormatCB->findData(toqstr(rc.default_otf_view_format));
2055 defaultOTFFormatCB->setCurrentIndex(pos);
2056 defaultOTFFormatCB->setCurrentIndex(pos);
2057 pos = defaultPlatexFormatCB->findData(toqstr(rc.default_platex_view_format));
2058 defaultPlatexFormatCB->setCurrentIndex(pos);
2059 defaultPlatexFormatCB->setCurrentIndex(pos);
2064 void PrefFileformats::updateView()
2066 QString const current = formatsCB->currentText();
2067 QString const current_def = defaultFormatCB->currentText();
2068 QString const current_def_otf = defaultOTFFormatCB->currentText();
2069 QString const current_def_platex = defaultPlatexFormatCB->currentText();
2071 // update comboboxes with formats
2072 formatsCB->blockSignals(true);
2073 defaultFormatCB->blockSignals(true);
2074 defaultOTFFormatCB->blockSignals(true);
2075 defaultPlatexFormatCB->blockSignals(true);
2077 defaultFormatCB->clear();
2078 defaultOTFFormatCB->clear();
2079 defaultPlatexFormatCB->clear();
2080 form_->formats().sort();
2081 for (Format const & f : form_->formats()) {
2082 QString const prettyname = toqstr(translateIfPossible(f.prettyname()));
2083 formatsCB->addItem(prettyname,
2084 QVariant(form_->formats().getNumber(f.name())));
2085 if (f.viewer().empty())
2087 if (form_->converters().isReachable("xhtml", f.name())
2088 || form_->converters().isReachable("dviluatex", f.name())
2089 || form_->converters().isReachable("luatex", f.name())
2090 || form_->converters().isReachable("xetex", f.name())) {
2091 defaultFormatCB->addItem(prettyname,
2092 QVariant(toqstr(f.name())));
2093 defaultOTFFormatCB->addItem(prettyname,
2094 QVariant(toqstr(f.name())));
2096 if (form_->converters().isReachable("latex", f.name())
2097 || form_->converters().isReachable("pdflatex", f.name()))
2098 defaultFormatCB->addItem(prettyname,
2099 QVariant(toqstr(f.name())));
2100 if (form_->converters().isReachable("platex", f.name()))
2101 defaultPlatexFormatCB->addItem(prettyname,
2102 QVariant(toqstr(f.name())));
2106 // restore selections
2107 int item = formatsCB->findText(current, Qt::MatchExactly);
2108 formatsCB->setCurrentIndex(item < 0 ? 0 : item);
2109 on_formatsCB_currentIndexChanged(item < 0 ? 0 : item);
2110 item = defaultFormatCB->findText(current_def, Qt::MatchExactly);
2111 defaultFormatCB->setCurrentIndex(item < 0 ? 0 : item);
2112 item = defaultOTFFormatCB->findText(current_def_otf, Qt::MatchExactly);
2113 defaultOTFFormatCB->setCurrentIndex(item < 0 ? 0 : item);
2114 item = defaultPlatexFormatCB->findText(current_def_platex, Qt::MatchExactly);
2115 defaultPlatexFormatCB->setCurrentIndex(item < 0 ? 0 : item);
2116 formatsCB->blockSignals(false);
2117 defaultFormatCB->blockSignals(false);
2118 defaultOTFFormatCB->blockSignals(false);
2119 defaultPlatexFormatCB->blockSignals(false);
2123 void PrefFileformats::on_formatsCB_currentIndexChanged(int i)
2125 if (form_->formats().empty())
2127 int const nr = formatsCB->itemData(i).toInt();
2128 Format const f = form_->formats().get(nr);
2130 formatED->setText(toqstr(f.name()));
2131 copierED->setText(toqstr(form_->movers().command(f.name())));
2132 extensionsED->setText(toqstr(f.extensions()));
2133 mimeED->setText(toqstr(f.mime()));
2134 shortcutED->setText(
2135 toqstr(l10n_shortcut(f.prettyname(), f.shortcut())));
2136 documentCB->setChecked((f.documentFormat()));
2137 vectorCB->setChecked((f.vectorFormat()));
2138 exportMenuCB->setChecked((f.inExportMenu()));
2139 exportMenuCB->setEnabled((f.documentFormat()));
2145 void PrefFileformats::setFlags()
2147 int flags = Format::none;
2148 if (documentCB->isChecked())
2149 flags |= Format::document;
2150 if (vectorCB->isChecked())
2151 flags |= Format::vector;
2152 if (exportMenuCB->isChecked())
2153 flags |= Format::export_menu;
2154 currentFormat().setFlags(flags);
2155 exportMenuCB->setEnabled(documentCB->isChecked());
2160 void PrefFileformats::on_copierED_textEdited(const QString & s)
2162 string const fmt = fromqstr(formatED->text());
2163 form_->movers().set(fmt, fromqstr(s));
2168 void PrefFileformats::on_extensionsED_textEdited(const QString & s)
2170 currentFormat().setExtensions(fromqstr(s));
2175 void PrefFileformats::on_viewerED_textEdited(const QString & s)
2177 currentFormat().setViewer(fromqstr(s));
2182 void PrefFileformats::on_editorED_textEdited(const QString & s)
2184 currentFormat().setEditor(fromqstr(s));
2189 void PrefFileformats::on_mimeED_textEdited(const QString & s)
2191 currentFormat().setMime(fromqstr(s));
2196 void PrefFileformats::on_shortcutED_textEdited(const QString & s)
2198 string const new_shortcut = fromqstr(s);
2199 if (new_shortcut == l10n_shortcut(currentFormat().prettyname(),
2200 currentFormat().shortcut()))
2202 currentFormat().setShortcut(new_shortcut);
2207 void PrefFileformats::on_formatED_editingFinished()
2209 string const newname = fromqstr(formatED->displayText());
2210 string const oldname = currentFormat().name();
2211 if (newname == oldname)
2213 if (form_->converters().formatIsUsed(oldname)) {
2214 Alert::error(_("Format in use"),
2215 _("You cannot change a format's short name "
2216 "if the format is used by a converter. "
2217 "Please remove the converter first."));
2222 currentFormat().setName(newname);
2227 void PrefFileformats::on_formatED_textChanged(const QString &)
2229 QString t = formatED->text();
2231 bool valid = formatED->validator()->validate(t, p) == QValidator::Acceptable;
2232 setValid(formatLA, valid);
2236 void PrefFileformats::on_formatsCB_editTextChanged(const QString &)
2238 QString t = formatsCB->currentText();
2240 bool valid = formatsCB->validator()->validate(t, p) == QValidator::Acceptable;
2241 setValid(formatsLA, valid);
2245 void PrefFileformats::updatePrettyname()
2247 QString const newname = formatsCB->currentText();
2248 if (newname == toqstr(translateIfPossible(currentFormat().prettyname())))
2251 currentFormat().setPrettyname(qstring_to_ucs4(newname));
2259 void updateComboBox(LyXRC::Alternatives const & alts,
2260 string const & fmt, QComboBox * combo)
2262 LyXRC::Alternatives::const_iterator it =
2264 if (it != alts.end()) {
2265 LyXRC::CommandSet const & cmds = it->second;
2266 LyXRC::CommandSet::const_iterator sit =
2268 LyXRC::CommandSet::const_iterator const sen =
2270 for (; sit != sen; ++sit) {
2271 QString const qcmd = toqstr(*sit);
2272 combo->addItem(qcmd, qcmd);
2279 void PrefFileformats::updateViewers()
2281 Format const f = currentFormat();
2282 viewerCO->blockSignals(true);
2284 viewerCO->addItem(qt_("None"), QString());
2285 updateComboBox(viewer_alternatives, f.name(), viewerCO);
2286 viewerCO->addItem(qt_("Custom"), QString("custom viewer"));
2287 viewerCO->blockSignals(false);
2289 int pos = viewerCO->findData(toqstr(f.viewer()));
2292 viewerED->setEnabled(false);
2293 viewerCO->setCurrentIndex(pos);
2295 viewerED->setEnabled(true);
2296 viewerED->setText(toqstr(f.viewer()));
2297 viewerCO->setCurrentIndex(viewerCO->findData(toqstr("custom viewer")));
2302 void PrefFileformats::updateEditors()
2304 Format const f = currentFormat();
2305 editorCO->blockSignals(true);
2307 editorCO->addItem(qt_("None"), QString());
2308 updateComboBox(editor_alternatives, f.name(), editorCO);
2309 editorCO->addItem(qt_("Custom"), QString("custom editor"));
2310 editorCO->blockSignals(false);
2312 int pos = editorCO->findData(toqstr(f.editor()));
2315 editorED->setEnabled(false);
2316 editorCO->setCurrentIndex(pos);
2318 editorED->setEnabled(true);
2319 editorED->setText(toqstr(f.editor()));
2320 editorCO->setCurrentIndex(editorCO->findData(toqstr("custom editor")));
2325 void PrefFileformats::on_viewerCO_currentIndexChanged(int i)
2327 bool const custom = viewerCO->itemData(i).toString() == "custom viewer";
2328 viewerED->setEnabled(custom);
2330 currentFormat().setViewer(fromqstr(viewerCO->itemData(i).toString()));
2334 void PrefFileformats::on_editorCO_currentIndexChanged(int i)
2336 bool const custom = editorCO->itemData(i).toString() == "custom editor";
2337 editorED->setEnabled(custom);
2339 currentFormat().setEditor(fromqstr(editorCO->itemData(i).toString()));
2343 Format & PrefFileformats::currentFormat()
2345 int const i = formatsCB->currentIndex();
2346 int const nr = formatsCB->itemData(i).toInt();
2347 return form_->formats().get(nr);
2351 void PrefFileformats::on_formatNewPB_clicked()
2353 form_->formats().add("", "", docstring(), "", "", "", "", Format::none);
2355 formatsCB->setCurrentIndex(0);
2356 formatsCB->setFocus(Qt::OtherFocusReason);
2360 void PrefFileformats::on_formatRemovePB_clicked()
2362 int const i = formatsCB->currentIndex();
2363 int const nr = formatsCB->itemData(i).toInt();
2364 string const current_text = form_->formats().get(nr).name();
2365 if (form_->converters().formatIsUsed(current_text)) {
2366 Alert::error(_("Format in use"),
2367 _("Cannot remove a Format used by a Converter. "
2368 "Remove the converter first."));
2372 form_->formats().erase(current_text);
2375 on_formatsCB_editTextChanged(formatsCB->currentText());
2380 /////////////////////////////////////////////////////////////////////
2384 /////////////////////////////////////////////////////////////////////
2386 PrefLanguage::PrefLanguage(GuiPreferences * form)
2387 : PrefModule(catLanguage, N_("Language"), form)
2391 connect(visualCursorRB, SIGNAL(clicked()),
2392 this, SIGNAL(changed()));
2393 connect(logicalCursorRB, SIGNAL(clicked()),
2394 this, SIGNAL(changed()));
2395 connect(markForeignCB, SIGNAL(clicked()),
2396 this, SIGNAL(changed()));
2397 connect(respectOSkbdCB, SIGNAL(clicked()),
2398 this, SIGNAL(changed()));
2399 connect(explicitDocLangBeginCB, SIGNAL(clicked()),
2400 this, SIGNAL(changed()));
2401 connect(explicitDocLangEndCB, SIGNAL(clicked()),
2402 this, SIGNAL(changed()));
2403 connect(languagePackageCO, SIGNAL(activated(int)),
2404 this, SIGNAL(changed()));
2405 connect(languagePackageED, SIGNAL(textChanged(QString)),
2406 this, SIGNAL(changed()));
2407 connect(globalCB, SIGNAL(clicked()),
2408 this, SIGNAL(changed()));
2409 connect(startCommandED, SIGNAL(textChanged(QString)),
2410 this, SIGNAL(changed()));
2411 connect(endCommandED, SIGNAL(textChanged(QString)),
2412 this, SIGNAL(changed()));
2413 connect(uiLanguageCO, SIGNAL(activated(int)),
2414 this, SIGNAL(changed()));
2415 connect(defaultDecimalPointLE, SIGNAL(textChanged(QString)),
2416 this, SIGNAL(changed()));
2417 connect(defaultLengthUnitCO, SIGNAL(activated(int)),
2418 this, SIGNAL(changed()));
2420 languagePackageED->setValidator(new NoNewLineValidator(languagePackageED));
2421 startCommandED->setValidator(new NoNewLineValidator(startCommandED));
2422 endCommandED->setValidator(new NoNewLineValidator(endCommandED));
2424 defaultDecimalPointLE->setInputMask("X; ");
2425 defaultDecimalPointLE->setMaxLength(1);
2427 defaultLengthUnitCO->addItem(lyx::qt_(unit_name_gui[Length::CM]), Length::CM);
2428 defaultLengthUnitCO->addItem(lyx::qt_(unit_name_gui[Length::IN]), Length::IN);
2430 QAbstractItemModel * language_model = guiApp->languageModel();
2431 language_model->sort(0);
2432 uiLanguageCO->blockSignals(true);
2433 uiLanguageCO->clear();
2434 uiLanguageCO->addItem(qt_("Default"), toqstr("auto"));
2435 for (int i = 0; i != language_model->rowCount(); ++i) {
2436 QModelIndex index = language_model->index(i, 0);
2437 // Filter the list based on the available translation and add
2438 // each language code only once
2439 string const name = fromqstr(index.data(Qt::UserRole).toString());
2440 Language const * lang = languages.getLanguage(name);
2443 // never remove the currently selected language
2444 if (name != form->rc().gui_language
2445 && name != lyxrc.gui_language
2446 && (!Messages::available(lang->code())
2447 || !lang->hasGuiSupport()))
2449 uiLanguageCO->addItem(index.data(Qt::DisplayRole).toString(),
2450 index.data(Qt::UserRole).toString());
2452 uiLanguageCO->blockSignals(false);
2456 void PrefLanguage::on_uiLanguageCO_currentIndexChanged(int)
2458 QMessageBox::information(this, qt_("LyX needs to be restarted!"),
2459 qt_("The change of user interface language will be fully "
2460 "effective only after a restart."));
2464 void PrefLanguage::on_languagePackageCO_currentIndexChanged(int i)
2466 languagePackageED->setEnabled(i == 2);
2470 void PrefLanguage::applyRC(LyXRC & rc) const
2472 rc.visual_cursor = visualCursorRB->isChecked();
2473 rc.mark_foreign_language = markForeignCB->isChecked();
2474 rc.respect_os_kbd_language = respectOSkbdCB->isChecked();
2475 rc.language_auto_begin = !explicitDocLangBeginCB->isChecked();
2476 rc.language_auto_end = !explicitDocLangEndCB->isChecked();
2477 int const p = languagePackageCO->currentIndex();
2479 rc.language_package_selection = LyXRC::LP_AUTO;
2481 rc.language_package_selection = LyXRC::LP_BABEL;
2483 rc.language_package_selection = LyXRC::LP_CUSTOM;
2485 rc.language_package_selection = LyXRC::LP_NONE;
2486 rc.language_custom_package = fromqstr(languagePackageED->text());
2487 rc.language_global_options = globalCB->isChecked();
2488 rc.language_command_begin = fromqstr(startCommandED->text());
2489 rc.language_command_end = fromqstr(endCommandED->text());
2490 rc.gui_language = fromqstr(
2491 uiLanguageCO->itemData(uiLanguageCO->currentIndex()).toString());
2492 rc.default_decimal_point = fromqstr(defaultDecimalPointLE->text());
2493 rc.default_length_unit = (Length::UNIT) defaultLengthUnitCO->itemData(defaultLengthUnitCO->currentIndex()).toInt();
2497 void PrefLanguage::updateRC(LyXRC const & rc)
2499 if (rc.visual_cursor)
2500 visualCursorRB->setChecked(true);
2502 logicalCursorRB->setChecked(true);
2503 markForeignCB->setChecked(rc.mark_foreign_language);
2504 respectOSkbdCB->setChecked(rc.respect_os_kbd_language);
2505 explicitDocLangBeginCB->setChecked(!rc.language_auto_begin);
2506 explicitDocLangEndCB->setChecked(!rc.language_auto_end);
2507 languagePackageCO->setCurrentIndex(rc.language_package_selection);
2508 languagePackageED->setText(toqstr(rc.language_custom_package));
2509 languagePackageED->setEnabled(languagePackageCO->currentIndex() == 2);
2510 globalCB->setChecked(rc.language_global_options);
2511 startCommandED->setText(toqstr(rc.language_command_begin));
2512 endCommandED->setText(toqstr(rc.language_command_end));
2513 defaultDecimalPointLE->setText(toqstr(rc.default_decimal_point));
2514 int pos = defaultLengthUnitCO->findData(int(rc.default_length_unit));
2515 defaultLengthUnitCO->setCurrentIndex(pos);
2517 pos = uiLanguageCO->findData(toqstr(rc.gui_language));
2518 uiLanguageCO->blockSignals(true);
2519 uiLanguageCO->setCurrentIndex(pos);
2520 uiLanguageCO->blockSignals(false);
2524 /////////////////////////////////////////////////////////////////////
2526 // PrefUserInterface
2528 /////////////////////////////////////////////////////////////////////
2530 PrefUserInterface::PrefUserInterface(GuiPreferences * form)
2531 : PrefModule(catLookAndFeel, N_("User Interface"), form)
2535 connect(uiFilePB, SIGNAL(clicked()),
2536 this, SLOT(selectUi()));
2537 connect(uiFileED, SIGNAL(textChanged(QString)),
2538 this, SIGNAL(changed()));
2539 connect(iconSetCO, SIGNAL(activated(int)),
2540 this, SIGNAL(changed()));
2541 connect(useSystemThemeIconsCB, SIGNAL(clicked()),
2542 this, SIGNAL(changed()));
2543 connect(lastfilesSB, SIGNAL(valueChanged(int)),
2544 this, SIGNAL(changed()));
2545 connect(tooltipCB, SIGNAL(toggled(bool)),
2546 this, SIGNAL(changed()));
2547 lastfilesSB->setMaximum(maxlastfiles);
2549 iconSetCO->addItem(qt_("Default"), QString());
2550 iconSetCO->addItem(qt_("Classic"), "classic");
2551 iconSetCO->addItem(qt_("Oxygen"), "oxygen");
2553 #if (!(defined Q_WS_X11 || defined(QPA_XCB)) || QT_VERSION < 0x040600)
2554 useSystemThemeIconsCB->hide();
2559 void PrefUserInterface::applyRC(LyXRC & rc) const
2561 rc.icon_set = fromqstr(iconSetCO->itemData(
2562 iconSetCO->currentIndex()).toString());
2564 rc.ui_file = internal_path(fromqstr(uiFileED->text()));
2565 rc.use_system_theme_icons = useSystemThemeIconsCB->isChecked();
2566 rc.num_lastfiles = lastfilesSB->value();
2567 rc.use_tooltip = tooltipCB->isChecked();
2571 void PrefUserInterface::updateRC(LyXRC const & rc)
2573 int iconset = iconSetCO->findData(toqstr(rc.icon_set));
2576 iconSetCO->setCurrentIndex(iconset);
2577 useSystemThemeIconsCB->setChecked(rc.use_system_theme_icons);
2578 uiFileED->setText(toqstr(external_path(rc.ui_file)));
2579 lastfilesSB->setValue(rc.num_lastfiles);
2580 tooltipCB->setChecked(rc.use_tooltip);
2584 void PrefUserInterface::selectUi()
2586 QString file = form_->browseUI(internalPath(uiFileED->text()));
2587 if (!file.isEmpty())
2588 uiFileED->setText(file);
2592 /////////////////////////////////////////////////////////////////////
2594 // PrefDocumentHandling
2596 /////////////////////////////////////////////////////////////////////
2598 PrefDocHandling::PrefDocHandling(GuiPreferences * form)
2599 : PrefModule(catLookAndFeel, N_("Document Handling"), form)
2603 connect(autoSaveCB, SIGNAL(toggled(bool)),
2604 autoSaveSB, SLOT(setEnabled(bool)));
2605 connect(autoSaveCB, SIGNAL(toggled(bool)),
2606 TextLabel1, SLOT(setEnabled(bool)));
2607 connect(openDocumentsInTabsCB, SIGNAL(clicked()),
2608 this, SIGNAL(changed()));
2609 connect(singleInstanceCB, SIGNAL(clicked()),
2610 this, SIGNAL(changed()));
2611 connect(singleCloseTabButtonCB, SIGNAL(clicked()),
2612 this, SIGNAL(changed()));
2613 connect(closeLastViewCO, SIGNAL(activated(int)),
2614 this, SIGNAL(changed()));
2615 connect(restoreCursorCB, SIGNAL(clicked()),
2616 this, SIGNAL(changed()));
2617 connect(loadSessionCB, SIGNAL(clicked()),
2618 this, SIGNAL(changed()));
2619 connect(allowGeometrySessionCB, SIGNAL(clicked()),
2620 this, SIGNAL(changed()));
2621 connect(autoSaveSB, SIGNAL(valueChanged(int)),
2622 this, SIGNAL(changed()));
2623 connect(autoSaveCB, SIGNAL(clicked()),
2624 this, SIGNAL(changed()));
2625 connect(backupCB, SIGNAL(clicked()),
2626 this, SIGNAL(changed()));
2627 connect(saveCompressedCB, SIGNAL(clicked()),
2628 this, SIGNAL(changed()));
2629 connect(saveOriginCB, SIGNAL(clicked()),
2630 this, SIGNAL(changed()));
2634 void PrefDocHandling::applyRC(LyXRC & rc) const
2636 rc.use_lastfilepos = restoreCursorCB->isChecked();
2637 rc.load_session = loadSessionCB->isChecked();
2638 rc.allow_geometry_session = allowGeometrySessionCB->isChecked();
2639 rc.autosave = autoSaveCB->isChecked() ? autoSaveSB->value() * 60 : 0;
2640 rc.make_backup = backupCB->isChecked();
2641 rc.save_compressed = saveCompressedCB->isChecked();
2642 rc.save_origin = saveOriginCB->isChecked();
2643 rc.open_buffers_in_tabs = openDocumentsInTabsCB->isChecked();
2644 rc.single_instance = singleInstanceCB->isChecked();
2645 rc.single_close_tab_button = singleCloseTabButtonCB->isChecked();
2647 switch (closeLastViewCO->currentIndex()) {
2649 rc.close_buffer_with_last_view = "yes";
2652 rc.close_buffer_with_last_view = "no";
2655 rc.close_buffer_with_last_view = "ask";
2663 void PrefDocHandling::updateRC(LyXRC const & rc)
2665 restoreCursorCB->setChecked(rc.use_lastfilepos);
2666 loadSessionCB->setChecked(rc.load_session);
2667 allowGeometrySessionCB->setChecked(rc.allow_geometry_session);
2668 // convert to minutes
2669 bool autosave = rc.autosave > 0;
2670 int mins = rc.autosave / 60;
2673 autoSaveSB->setValue(mins);
2674 autoSaveCB->setChecked(autosave);
2675 autoSaveSB->setEnabled(autosave);
2676 backupCB->setChecked(rc.make_backup);
2677 saveCompressedCB->setChecked(rc.save_compressed);
2678 saveOriginCB->setChecked(rc.save_origin);
2679 openDocumentsInTabsCB->setChecked(rc.open_buffers_in_tabs);
2680 singleInstanceCB->setChecked(rc.single_instance && !rc.lyxpipes.empty());
2681 singleInstanceCB->setEnabled(!rc.lyxpipes.empty());
2682 singleCloseTabButtonCB->setChecked(rc.single_close_tab_button);
2683 if (rc.close_buffer_with_last_view == "yes")
2684 closeLastViewCO->setCurrentIndex(0);
2685 else if (rc.close_buffer_with_last_view == "no")
2686 closeLastViewCO->setCurrentIndex(1);
2687 else if (rc.close_buffer_with_last_view == "ask")
2688 closeLastViewCO->setCurrentIndex(2);
2692 void PrefDocHandling::on_clearSessionPB_clicked()
2694 guiApp->clearSession();
2699 /////////////////////////////////////////////////////////////////////
2703 /////////////////////////////////////////////////////////////////////
2705 PrefEdit::PrefEdit(GuiPreferences * form)
2706 : PrefModule(catEditing, N_("Control"), form)
2710 connect(cursorFollowsCB, SIGNAL(clicked()),
2711 this, SIGNAL(changed()));
2712 connect(scrollBelowCB, SIGNAL(clicked()),
2713 this, SIGNAL(changed()));
2714 connect(macLikeCursorMovementCB, SIGNAL(clicked()),
2715 this, SIGNAL(changed()));
2716 connect(sortEnvironmentsCB, SIGNAL(clicked()),
2717 this, SIGNAL(changed()));
2718 connect(groupEnvironmentsCB, SIGNAL(clicked()),
2719 this, SIGNAL(changed()));
2720 connect(macroEditStyleCO, SIGNAL(activated(int)),
2721 this, SIGNAL(changed()));
2722 connect(cursorWidthSB, SIGNAL(valueChanged(int)),
2723 this, SIGNAL(changed()));
2724 connect(fullscreenLimitGB, SIGNAL(clicked()),
2725 this, SIGNAL(changed()));
2726 connect(fullscreenWidthSB, SIGNAL(valueChanged(int)),
2727 this, SIGNAL(changed()));
2728 connect(toggleTabbarCB, SIGNAL(toggled(bool)),
2729 this, SIGNAL(changed()));
2730 connect(toggleMenubarCB, SIGNAL(toggled(bool)),
2731 this, SIGNAL(changed()));
2732 connect(toggleScrollbarCB, SIGNAL(toggled(bool)),
2733 this, SIGNAL(changed()));
2734 connect(toggleStatusbarCB, SIGNAL(toggled(bool)),
2735 this, SIGNAL(changed()));
2736 connect(toggleToolbarsCB, SIGNAL(toggled(bool)),
2737 this, SIGNAL(changed()));
2741 void PrefEdit::applyRC(LyXRC & rc) const
2743 rc.cursor_follows_scrollbar = cursorFollowsCB->isChecked();
2744 rc.scroll_below_document = scrollBelowCB->isChecked();
2745 rc.mac_like_cursor_movement = macLikeCursorMovementCB->isChecked();
2746 rc.sort_layouts = sortEnvironmentsCB->isChecked();
2747 rc.group_layouts = groupEnvironmentsCB->isChecked();
2748 switch (macroEditStyleCO->currentIndex()) {
2749 case 0: rc.macro_edit_style = LyXRC::MACRO_EDIT_INLINE_BOX; break;
2750 case 1: rc.macro_edit_style = LyXRC::MACRO_EDIT_INLINE; break;
2751 case 2: rc.macro_edit_style = LyXRC::MACRO_EDIT_LIST; break;
2753 rc.cursor_width = cursorWidthSB->value();
2754 rc.full_screen_toolbars = toggleToolbarsCB->isChecked();
2755 rc.full_screen_scrollbar = toggleScrollbarCB->isChecked();
2756 rc.full_screen_statusbar = toggleStatusbarCB->isChecked();
2757 rc.full_screen_tabbar = toggleTabbarCB->isChecked();
2758 rc.full_screen_menubar = toggleMenubarCB->isChecked();
2759 rc.full_screen_width = fullscreenWidthSB->value();
2760 rc.full_screen_limit = fullscreenLimitGB->isChecked();
2764 void PrefEdit::updateRC(LyXRC const & rc)
2766 cursorFollowsCB->setChecked(rc.cursor_follows_scrollbar);
2767 scrollBelowCB->setChecked(rc.scroll_below_document);
2768 macLikeCursorMovementCB->setChecked(rc.mac_like_cursor_movement);
2769 sortEnvironmentsCB->setChecked(rc.sort_layouts);
2770 groupEnvironmentsCB->setChecked(rc.group_layouts);
2771 macroEditStyleCO->setCurrentIndex(rc.macro_edit_style);
2772 cursorWidthSB->setValue(rc.cursor_width);
2773 toggleScrollbarCB->setChecked(rc.full_screen_scrollbar);
2774 toggleStatusbarCB->setChecked(rc.full_screen_statusbar);
2775 toggleToolbarsCB->setChecked(rc.full_screen_toolbars);
2776 toggleTabbarCB->setChecked(rc.full_screen_tabbar);
2777 toggleMenubarCB->setChecked(rc.full_screen_menubar);
2778 fullscreenWidthSB->setValue(rc.full_screen_width);
2779 fullscreenLimitGB->setChecked(rc.full_screen_limit);
2783 /////////////////////////////////////////////////////////////////////
2787 /////////////////////////////////////////////////////////////////////
2790 GuiShortcutDialog::GuiShortcutDialog(QWidget * parent) : QDialog(parent)
2792 Ui::shortcutUi::setupUi(this);
2793 QDialog::setModal(true);
2797 PrefShortcuts::PrefShortcuts(GuiPreferences * form)
2798 : PrefModule(catEditing, N_("Shortcuts"), form),
2799 editItem_(0), mathItem_(0), bufferItem_(0), layoutItem_(0),
2804 shortcutsTW->setColumnCount(2);
2805 shortcutsTW->headerItem()->setText(0, qt_("Function"));
2806 shortcutsTW->headerItem()->setText(1, qt_("Shortcut"));
2807 shortcutsTW->setSortingEnabled(true);
2808 // Multi-selection can be annoying.
2809 // shortcutsTW->setSelectionMode(QAbstractItemView::MultiSelection);
2811 connect(bindFilePB, SIGNAL(clicked()),
2812 this, SLOT(selectBind()));
2813 connect(bindFileED, SIGNAL(textChanged(QString)),
2814 this, SIGNAL(changed()));
2816 shortcut_ = new GuiShortcutDialog(this);
2817 shortcut_bc_.setPolicy(ButtonPolicy::OkCancelPolicy);
2818 shortcut_bc_.setOK(shortcut_->buttonBox->button(QDialogButtonBox::Ok));
2819 shortcut_bc_.setCancel(shortcut_->buttonBox->button(QDialogButtonBox::Cancel));
2821 connect(shortcut_->buttonBox, SIGNAL(accepted()),
2822 this, SIGNAL(changed()));
2823 connect(shortcut_->buttonBox, SIGNAL(rejected()),
2824 shortcut_, SLOT(reject()));
2825 connect(shortcut_->clearPB, SIGNAL(clicked()),
2826 this, SLOT(shortcutClearPressed()));
2827 connect(shortcut_->removePB, SIGNAL(clicked()),
2828 this, SLOT(shortcutRemovePressed()));
2829 connect(shortcut_->buttonBox, SIGNAL(accepted()),
2830 this, SLOT(shortcutOkPressed()));
2831 connect(shortcut_->buttonBox, SIGNAL(rejected()),
2832 this, SLOT(shortcutCancelPressed()));
2836 void PrefShortcuts::applyRC(LyXRC & rc) const
2838 rc.bind_file = internal_path(fromqstr(bindFileED->text()));
2839 // write user_bind and user_unbind to .lyx/bind/user.bind
2840 FileName bind_dir(addPath(package().user_support().absFileName(), "bind"));
2841 if (!bind_dir.exists() && !bind_dir.createDirectory(0777)) {
2842 lyxerr << "LyX could not create the user bind directory '"
2843 << bind_dir << "'. All user-defined key bindings will be lost." << endl;
2846 if (!bind_dir.isDirWritable()) {
2847 lyxerr << "LyX could not write to the user bind directory '"
2848 << bind_dir << "'. All user-defined key bindings will be lost." << endl;
2851 FileName user_bind_file(bind_dir.absFileName() + "/user.bind");
2852 user_unbind_.write(user_bind_file.toFilesystemEncoding(), false, true);
2853 user_bind_.write(user_bind_file.toFilesystemEncoding(), true, false);
2854 // immediately apply the keybindings. Why this is not done before?
2855 // The good thing is that the menus are updated automatically.
2856 theTopLevelKeymap().clear();
2857 theTopLevelKeymap().read("site");
2858 theTopLevelKeymap().read(rc.bind_file, 0, KeyMap::Fallback);
2859 theTopLevelKeymap().read("user", 0, KeyMap::MissingOK);
2863 void PrefShortcuts::updateRC(LyXRC const & rc)
2865 bindFileED->setText(toqstr(external_path(rc.bind_file)));
2867 system_bind_.clear();
2869 user_unbind_.clear();
2870 system_bind_.read("site");
2871 system_bind_.read(rc.bind_file);
2872 // \unbind in user.bind is added to user_unbind_
2873 user_bind_.read("user", &user_unbind_, KeyMap::MissingOK);
2874 updateShortcutsTW();
2878 void PrefShortcuts::updateShortcutsTW()
2880 shortcutsTW->clear();
2882 editItem_ = new QTreeWidgetItem(shortcutsTW);
2883 editItem_->setText(0, qt_("Cursor, Mouse and Editing Functions"));
2884 editItem_->setFlags(editItem_->flags() & ~Qt::ItemIsSelectable);
2886 mathItem_ = new QTreeWidgetItem(shortcutsTW);
2887 mathItem_->setText(0, qt_("Mathematical Symbols"));
2888 mathItem_->setFlags(mathItem_->flags() & ~Qt::ItemIsSelectable);
2890 bufferItem_ = new QTreeWidgetItem(shortcutsTW);
2891 bufferItem_->setText(0, qt_("Document and Window"));
2892 bufferItem_->setFlags(bufferItem_->flags() & ~Qt::ItemIsSelectable);
2894 layoutItem_ = new QTreeWidgetItem(shortcutsTW);
2895 layoutItem_->setText(0, qt_("Font, Layouts and Textclasses"));
2896 layoutItem_->setFlags(layoutItem_->flags() & ~Qt::ItemIsSelectable);
2898 systemItem_ = new QTreeWidgetItem(shortcutsTW);
2899 systemItem_->setText(0, qt_("System and Miscellaneous"));
2900 systemItem_->setFlags(systemItem_->flags() & ~Qt::ItemIsSelectable);
2902 // listBindings(unbound=true) lists all bound and unbound lfuns
2903 // Items in this list is tagged by its source.
2904 KeyMap::BindingList bindinglist = system_bind_.listBindings(true,
2906 KeyMap::BindingList user_bindinglist = user_bind_.listBindings(false,
2908 KeyMap::BindingList user_unbindinglist = user_unbind_.listBindings(false,
2909 KeyMap::UserUnbind);
2910 bindinglist.insert(bindinglist.end(), user_bindinglist.begin(),
2911 user_bindinglist.end());
2912 bindinglist.insert(bindinglist.end(), user_unbindinglist.begin(),
2913 user_unbindinglist.end());
2915 KeyMap::BindingList::const_iterator it = bindinglist.begin();
2916 KeyMap::BindingList::const_iterator it_end = bindinglist.end();
2917 for (; it != it_end; ++it)
2918 insertShortcutItem(it->request, it->sequence, it->tag);
2920 shortcutsTW->sortItems(0, Qt::AscendingOrder);
2921 on_shortcutsTW_itemSelectionChanged();
2922 on_searchLE_textEdited();
2923 shortcutsTW->resizeColumnToContents(0);
2928 KeyMap::ItemType PrefShortcuts::itemType(QTreeWidgetItem & item)
2930 return static_cast<KeyMap::ItemType>(item.data(0, Qt::UserRole).toInt());
2935 bool PrefShortcuts::isAlwaysHidden(QTreeWidgetItem & item)
2937 // Hide rebound system settings that are empty
2938 return itemType(item) == KeyMap::UserUnbind && item.text(1).isEmpty();
2942 void PrefShortcuts::setItemType(QTreeWidgetItem * item, KeyMap::ItemType tag)
2944 item->setData(0, Qt::UserRole, QVariant(tag));
2948 case KeyMap::System:
2950 case KeyMap::UserBind:
2953 case KeyMap::UserUnbind:
2954 font.setStrikeOut(true);
2956 // this item is not displayed now.
2957 case KeyMap::UserExtraUnbind:
2958 font.setStrikeOut(true);
2961 item->setHidden(isAlwaysHidden(*item));
2962 item->setFont(1, font);
2966 QTreeWidgetItem * PrefShortcuts::insertShortcutItem(FuncRequest const & lfun,
2967 KeySequence const & seq, KeyMap::ItemType tag)
2969 FuncCode const action = lfun.action();
2970 string const action_name = lyxaction.getActionName(action);
2971 QString const lfun_name = toqstr(from_utf8(action_name)
2972 + ' ' + lfun.argument());
2973 QString const shortcut = toqstr(seq.print(KeySequence::ForGui));
2975 QTreeWidgetItem * newItem = 0;
2976 // for unbind items, try to find an existing item in the system bind list
2977 if (tag == KeyMap::UserUnbind) {
2978 QList<QTreeWidgetItem*> const items = shortcutsTW->findItems(lfun_name,
2979 Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 0);
2980 for (int i = 0; i < items.size(); ++i) {
2981 if (items[i]->text(1) == shortcut) {
2986 // if not found, this unbind item is KeyMap::UserExtraUnbind
2987 // Such an item is not displayed to avoid confusion (what is
2988 // unmatched removed?).
2994 switch(lyxaction.getActionType(action)) {
2995 case LyXAction::Hidden:
2997 case LyXAction::Edit:
2998 newItem = new QTreeWidgetItem(editItem_);
3000 case LyXAction::Math:
3001 newItem = new QTreeWidgetItem(mathItem_);
3003 case LyXAction::Buffer:
3004 newItem = new QTreeWidgetItem(bufferItem_);
3006 case LyXAction::Layout:
3007 newItem = new QTreeWidgetItem(layoutItem_);
3009 case LyXAction::System:
3010 newItem = new QTreeWidgetItem(systemItem_);
3013 // this should not happen
3014 newItem = new QTreeWidgetItem(shortcutsTW);
3018 newItem->setText(0, lfun_name);
3019 newItem->setText(1, shortcut);
3020 // record BindFile representation to recover KeySequence when needed.
3021 newItem->setData(1, Qt::UserRole, toqstr(seq.print(KeySequence::BindFile)));
3022 setItemType(newItem, tag);
3027 void PrefShortcuts::on_shortcutsTW_itemSelectionChanged()
3029 QList<QTreeWidgetItem*> items = shortcutsTW->selectedItems();
3030 removePB->setEnabled(!items.isEmpty() && !items[0]->text(1).isEmpty());
3031 modifyPB->setEnabled(!items.isEmpty());
3032 if (items.isEmpty())
3035 if (itemType(*items[0]) == KeyMap::UserUnbind)
3036 removePB->setText(qt_("Res&tore"));
3038 removePB->setText(qt_("Remo&ve"));
3042 void PrefShortcuts::on_shortcutsTW_itemDoubleClicked()
3048 void PrefShortcuts::modifyShortcut()
3050 QTreeWidgetItem * item = shortcutsTW->currentItem();
3051 if (item->flags() & Qt::ItemIsSelectable) {
3052 shortcut_->lfunLE->setText(item->text(0));
3053 save_lfun_ = item->text(0).trimmed();
3054 shortcut_->shortcutWG->setText(item->text(1));
3056 seq.parse(fromqstr(item->data(1, Qt::UserRole).toString()));
3057 shortcut_->shortcutWG->setKeySequence(seq);
3058 shortcut_->shortcutWG->setFocus();
3064 void PrefShortcuts::unhideEmpty(QString const & lfun, bool select)
3066 // list of items that match lfun
3067 QList<QTreeWidgetItem*> items = shortcutsTW->findItems(lfun,
3068 Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 0);
3069 for (int i = 0; i < items.size(); ++i) {
3070 QTreeWidgetItem * item = items[i];
3071 if (isAlwaysHidden(*item)) {
3072 setItemType(item, KeyMap::System);
3074 shortcutsTW->setCurrentItem(item);
3081 void PrefShortcuts::removeShortcut()
3083 // it seems that only one item can be selected, but I am
3084 // removing all selected items anyway.
3085 QList<QTreeWidgetItem*> items = shortcutsTW->selectedItems();
3086 for (int i = 0; i < items.size(); ++i) {
3087 string shortcut = fromqstr(items[i]->data(1, Qt::UserRole).toString());
3088 string lfun = fromqstr(items[i]->text(0));
3089 FuncRequest func = lyxaction.lookupFunc(lfun);
3091 switch (itemType(*items[i])) {
3092 case KeyMap::System: {
3093 // for system bind, we do not touch the item
3094 // but add an user unbind item
3095 user_unbind_.bind(shortcut, func);
3096 setItemType(items[i], KeyMap::UserUnbind);
3097 removePB->setText(qt_("Res&tore"));
3100 case KeyMap::UserBind: {
3101 // for user_bind, we remove this bind
3102 QTreeWidgetItem * parent = items[i]->parent();
3103 int itemIdx = parent->indexOfChild(items[i]);
3104 parent->takeChild(itemIdx);
3106 shortcutsTW->scrollToItem(parent->child(itemIdx - 1));
3108 shortcutsTW->scrollToItem(parent);
3109 user_bind_.unbind(shortcut, func);
3110 // If this user binding hid an empty system binding, unhide the
3111 // latter and select it.
3112 unhideEmpty(items[i]->text(0), true);
3115 case KeyMap::UserUnbind: {
3116 // for user_unbind, we remove the unbind, and the item
3117 // become KeyMap::System again.
3119 seq.parse(shortcut);
3120 // Ask the user to replace current binding
3121 if (!validateNewShortcut(func, seq, QString()))
3123 user_unbind_.unbind(shortcut, func);
3124 setItemType(items[i], KeyMap::System);
3125 removePB->setText(qt_("Remo&ve"));
3128 case KeyMap::UserExtraUnbind: {
3129 // for user unbind that is not in system bind file,
3130 // remove this unbind file
3131 QTreeWidgetItem * parent = items[i]->parent();
3132 parent->takeChild(parent->indexOfChild(items[i]));
3133 user_unbind_.unbind(shortcut, func);
3140 void PrefShortcuts::deactivateShortcuts(QList<QTreeWidgetItem*> const & items)
3142 for (int i = 0; i < items.size(); ++i) {
3143 string shortcut = fromqstr(items[i]->data(1, Qt::UserRole).toString());
3144 string lfun = fromqstr(items[i]->text(0));
3145 FuncRequest func = lyxaction.lookupFunc(lfun);
3147 switch (itemType(*items[i])) {
3148 case KeyMap::System:
3149 // for system bind, we do not touch the item
3150 // but add an user unbind item
3151 user_unbind_.bind(shortcut, func);
3152 setItemType(items[i], KeyMap::UserUnbind);
3155 case KeyMap::UserBind: {
3156 // for user_bind, we remove this bind
3157 QTreeWidgetItem * parent = items[i]->parent();
3158 int itemIdx = parent->indexOfChild(items[i]);
3159 parent->takeChild(itemIdx);
3160 user_bind_.unbind(shortcut, func);
3161 unhideEmpty(items[i]->text(0), false);
3171 void PrefShortcuts::selectBind()
3173 QString file = form_->browsebind(internalPath(bindFileED->text()));
3174 if (!file.isEmpty()) {
3175 bindFileED->setText(file);
3176 system_bind_ = KeyMap();
3177 system_bind_.read(fromqstr(file));
3178 updateShortcutsTW();
3183 void PrefShortcuts::on_modifyPB_pressed()
3189 void PrefShortcuts::on_newPB_pressed()
3191 shortcut_->lfunLE->clear();
3192 shortcut_->shortcutWG->reset();
3193 save_lfun_ = QString();
3198 void PrefShortcuts::on_removePB_pressed()
3205 void PrefShortcuts::on_searchLE_textEdited()
3207 if (searchLE->text().isEmpty()) {
3208 // show all hidden items
3209 QTreeWidgetItemIterator it(shortcutsTW, QTreeWidgetItemIterator::Hidden);
3211 shortcutsTW->setItemHidden(*it, isAlwaysHidden(**it));
3212 // close all categories
3213 for (int i = 0; i < shortcutsTW->topLevelItemCount(); ++i)
3214 shortcutsTW->collapseItem(shortcutsTW->topLevelItem(i));
3217 // search both columns
3218 QList<QTreeWidgetItem *> matched = shortcutsTW->findItems(searchLE->text(),
3219 Qt::MatchFlags(Qt::MatchContains | Qt::MatchRecursive), 0);
3220 matched += shortcutsTW->findItems(searchLE->text(),
3221 Qt::MatchFlags(Qt::MatchContains | Qt::MatchRecursive), 1);
3223 // hide everyone (to avoid searching in matched QList repeatedly
3224 QTreeWidgetItemIterator it(shortcutsTW, QTreeWidgetItemIterator::Selectable);
3226 shortcutsTW->setItemHidden(*it++, true);
3227 // show matched items
3228 for (int i = 0; i < matched.size(); ++i)
3229 if (!isAlwaysHidden(*matched[i])) {
3230 shortcutsTW->setItemHidden(matched[i], false);
3231 shortcutsTW->setItemExpanded(matched[i]->parent(), true);
3236 docstring makeCmdString(FuncRequest const & f)
3238 docstring actionStr = from_ascii(lyxaction.getActionName(f.action()));
3239 if (!f.argument().empty())
3240 actionStr += " " + f.argument();
3245 FuncRequest PrefShortcuts::currentBinding(KeySequence const & k)
3247 FuncRequest res = user_bind_.getBinding(k);
3248 if (res.action() != LFUN_UNKNOWN_ACTION)
3250 res = system_bind_.getBinding(k);
3251 // Check if it is unbound. Note: user_unbind_ can only unbind one
3252 // FuncRequest per key sequence.
3253 if (user_unbind_.getBinding(k) == res)
3254 return FuncRequest::unknown;
3259 bool PrefShortcuts::validateNewShortcut(FuncRequest const & func,
3260 KeySequence const & k,
3261 QString const & lfun_to_modify)
3263 if (func.action() == LFUN_UNKNOWN_ACTION) {
3264 Alert::error(_("Failed to create shortcut"),
3265 _("Unknown or invalid LyX function"));
3269 // It is not currently possible to bind Hidden lfuns such as self-insert. In
3270 // the future, to remove this limitation, see GuiPrefs::insertShortcutItem
3271 // and how it is used in GuiPrefs::shortcutOkPressed.
3272 if (lyxaction.getActionType(func.action()) == LyXAction::Hidden) {
3273 Alert::error(_("Failed to create shortcut"),
3274 _("This LyX function is hidden and cannot be bound."));
3278 if (k.length() == 0) {
3279 Alert::error(_("Failed to create shortcut"),
3280 _("Invalid or empty key sequence"));
3284 FuncRequest oldBinding = currentBinding(k);
3285 if (oldBinding == func)
3286 // nothing to change
3289 // make sure this key isn't already bound---and, if so, prompt user
3290 // (exclude the lfun the user already wants to modify)
3291 docstring const action_string = makeCmdString(oldBinding);
3292 if (oldBinding.action() != LFUN_UNKNOWN_ACTION
3293 && lfun_to_modify != toqstr(action_string)) {
3294 docstring const new_action_string = makeCmdString(func);
3295 docstring const text = bformat(_("Shortcut `%1$s' is already bound to "
3297 "Are you sure you want to unbind the "
3298 "current shortcut and bind it to %3$s?"),
3299 k.print(KeySequence::ForGui), action_string,
3301 int ret = Alert::prompt(_("Redefine shortcut?"),
3302 text, 0, 1, _("&Redefine"), _("&Cancel"));
3305 QString const sequence_text = toqstr(k.print(KeySequence::ForGui));
3306 QList<QTreeWidgetItem*> items = shortcutsTW->findItems(sequence_text,
3307 Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 1);
3308 deactivateShortcuts(items);
3314 void PrefShortcuts::shortcutOkPressed()
3316 QString const new_lfun = shortcut_->lfunLE->text();
3317 FuncRequest func = lyxaction.lookupFunc(fromqstr(new_lfun));
3318 KeySequence k = shortcut_->shortcutWG->getKeySequence();
3320 // save_lfun_ contains the text of the lfun to modify, if the user clicked
3321 // "modify", or is empty if they clicked "new" (which I do not really like)
3322 if (!validateNewShortcut(func, k, save_lfun_))
3325 if (!save_lfun_.isEmpty()) {
3326 // real modification of the lfun's shortcut,
3327 // so remove the previous one
3328 QList<QTreeWidgetItem*> to_modify = shortcutsTW->selectedItems();
3329 deactivateShortcuts(to_modify);
3332 shortcut_->accept();
3334 QTreeWidgetItem * item = insertShortcutItem(func, k, KeyMap::UserBind);
3336 user_bind_.bind(&k, func);
3337 shortcutsTW->sortItems(0, Qt::AscendingOrder);
3338 shortcutsTW->setItemExpanded(item->parent(), true);
3339 shortcutsTW->setCurrentItem(item);
3340 shortcutsTW->scrollToItem(item);
3342 Alert::error(_("Failed to create shortcut"),
3343 _("Can not insert shortcut to the list"));
3349 void PrefShortcuts::shortcutCancelPressed()
3351 shortcut_->shortcutWG->reset();
3355 void PrefShortcuts::shortcutClearPressed()
3357 shortcut_->shortcutWG->reset();
3361 void PrefShortcuts::shortcutRemovePressed()
3363 shortcut_->shortcutWG->removeFromSequence();
3367 /////////////////////////////////////////////////////////////////////
3371 /////////////////////////////////////////////////////////////////////
3373 PrefIdentity::PrefIdentity(GuiPreferences * form)
3374 : PrefModule(QString(), N_("Identity"), form)
3378 connect(nameED, SIGNAL(textChanged(QString)),
3379 this, SIGNAL(changed()));
3380 connect(emailED, SIGNAL(textChanged(QString)),
3381 this, SIGNAL(changed()));
3383 nameED->setValidator(new NoNewLineValidator(nameED));
3384 emailED->setValidator(new NoNewLineValidator(emailED));
3388 void PrefIdentity::applyRC(LyXRC & rc) const
3390 rc.user_name = fromqstr(nameED->text());
3391 rc.user_email = fromqstr(emailED->text());
3395 void PrefIdentity::updateRC(LyXRC const & rc)
3397 nameED->setText(toqstr(rc.user_name));
3398 emailED->setText(toqstr(rc.user_email));
3403 /////////////////////////////////////////////////////////////////////
3407 /////////////////////////////////////////////////////////////////////
3409 GuiPreferences::GuiPreferences(GuiView & lv)
3410 : GuiDialog(lv, "prefs", qt_("Preferences"))
3414 QDialog::setModal(false);
3416 connect(buttonBox, SIGNAL(clicked(QAbstractButton *)),
3417 this, SLOT(slotButtonBox(QAbstractButton *)));
3419 addModule(new PrefUserInterface(this));
3420 addModule(new PrefDocHandling(this));
3421 addModule(new PrefEdit(this));
3422 addModule(new PrefShortcuts(this));
3423 PrefScreenFonts * screenfonts = new PrefScreenFonts(this);
3424 connect(this, SIGNAL(prefsApplied(LyXRC const &)),
3425 screenfonts, SLOT(updateScreenFontSizes(LyXRC const &)));
3426 addModule(screenfonts);
3427 addModule(new PrefColors(this));
3428 addModule(new PrefDisplay(this));
3429 addModule(new PrefInput(this));
3430 addModule(new PrefCompletion(this));
3432 addModule(new PrefPaths(this));
3434 addModule(new PrefIdentity(this));
3436 addModule(new PrefLanguage(this));
3437 addModule(new PrefSpellchecker(this));
3439 PrefOutput * output = new PrefOutput(this);
3441 addModule(new PrefLatex(this));
3443 PrefConverters * converters = new PrefConverters(this);
3444 PrefFileformats * formats = new PrefFileformats(this);
3445 connect(formats, SIGNAL(formatsChanged()),
3446 converters, SLOT(updateGui()));
3447 addModule(converters);
3450 prefsPS->setCurrentPanel("User Interface");
3451 // FIXME: hack to work around resizing bug in Qt >= 4.2
3452 // bug verified with Qt 4.2.{0-3} (JSpitzm)
3453 #if QT_VERSION >= 0x040200
3454 prefsPS->updateGeometry();
3457 bc().setPolicy(ButtonPolicy::PreferencesPolicy);
3458 bc().setOK(buttonBox->button(QDialogButtonBox::Ok));
3459 bc().setApply(buttonBox->button(QDialogButtonBox::Apply));
3460 bc().setCancel(buttonBox->button(QDialogButtonBox::Cancel));
3461 bc().setRestore(buttonBox->button(QDialogButtonBox::Reset));
3463 guilyxfiles_ = new GuiLyXFiles(lv);
3464 connect(guilyxfiles_, SIGNAL(fileSelected(QString)),
3465 this, SLOT(slotFileSelected(QString)));
3469 void GuiPreferences::addModule(PrefModule * module)
3471 LASSERT(module, return);
3472 if (module->category().isEmpty())
3473 prefsPS->addPanel(module, module->title());
3475 prefsPS->addPanel(module, module->title(), module->category());
3476 connect(module, SIGNAL(changed()), this, SLOT(change_adaptor()));
3477 modules_.push_back(module);
3481 void GuiPreferences::change_adaptor()
3487 void GuiPreferences::applyRC(LyXRC & rc) const
3489 size_t end = modules_.size();
3490 for (size_t i = 0; i != end; ++i)
3491 modules_[i]->applyRC(rc);
3495 void GuiPreferences::updateRC(LyXRC const & rc)
3497 size_t const end = modules_.size();
3498 for (size_t i = 0; i != end; ++i)
3499 modules_[i]->updateRC(rc);
3503 void GuiPreferences::applyView()
3509 bool GuiPreferences::initialiseParams(string const &)
3512 formats_ = theFormats();
3513 converters_ = theConverters();
3514 converters_.update(formats_);
3515 movers_ = theMovers();
3519 // Make sure that the bc is in the INITIAL state
3520 if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
3527 void GuiPreferences::dispatchParams()
3530 rc_.write(ss, true);
3531 dispatch(FuncRequest(LFUN_LYXRC_APPLY, ss.str()));
3532 // issue prefsApplied signal. This will update the
3533 // localized screen font sizes.
3535 // FIXME: these need lfuns
3537 Author const & author =
3538 Author(from_utf8(rc_.user_name), from_utf8(rc_.user_email));
3539 theBufferList().recordCurrentAuthor(author);
3541 theFormats() = formats_;
3543 theConverters() = converters_;
3544 theConverters().update(formats_);
3545 theConverters().buildGraph();
3546 theBufferList().invalidateConverterCache();
3548 theMovers() = movers_;
3550 for (string const & color : colors_)
3551 dispatch(FuncRequest(LFUN_SET_COLOR, color));
3555 if (!tempSaveCB->isChecked())
3556 dispatch(FuncRequest(LFUN_PREFERENCES_SAVE));
3560 void GuiPreferences::setColor(ColorCode col, QString const & hex)
3562 colors_.push_back(lcolor.getLyXName(col) + ' ' + fromqstr(hex));
3566 void GuiPreferences::slotFileSelected(QString const file)
3572 QString GuiPreferences::browseLibFile(QString const & dir,
3573 QString const & name, QString const & ext)
3577 guilyxfiles_->passParams(fromqstr(dir));
3578 guilyxfiles_->selectItem(name);
3579 guilyxfiles_->exec();
3581 QString const result = uifile_;
3583 // remove the extension if it is the default one
3584 QString noextresult;
3585 if (getExtension(result) == ext)
3586 noextresult = removeExtension(result);
3588 noextresult = result;
3590 // remove the directory, if it is the default one
3591 QString const file = onlyFileName(noextresult);
3592 if (toqstr(libFileSearch(dir, file, ext).absFileName()) == result)
3599 QString GuiPreferences::browsebind(QString const & file)
3601 return browseLibFile("bind", file, "bind");
3605 QString GuiPreferences::browseUI(QString const & file)
3607 return browseLibFile("ui", file, "ui");
3611 QString GuiPreferences::browsekbmap(QString const & file)
3613 return browseLibFile("kbd", file, "kmap");
3617 QString GuiPreferences::browse(QString const & file,
3618 QString const & title) const
3620 return browseFile(file, title, QStringList(), true);
3624 Dialog * createGuiPreferences(GuiView & lv) { return new GuiPreferences(lv); }
3627 } // namespace frontend
3630 #include "moc_GuiPrefs.cpp"