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(defaultDecimalSepED, SIGNAL(textChanged(QString)),
2416 this, SIGNAL(changed()));
2417 connect(defaultDecimalSepCO, SIGNAL(activated(int)),
2418 this, SIGNAL(changed()));
2419 connect(defaultLengthUnitCO, SIGNAL(activated(int)),
2420 this, SIGNAL(changed()));
2422 languagePackageED->setValidator(new NoNewLineValidator(languagePackageED));
2423 startCommandED->setValidator(new NoNewLineValidator(startCommandED));
2424 endCommandED->setValidator(new NoNewLineValidator(endCommandED));
2426 defaultDecimalSepED->setInputMask("X; ");
2427 defaultDecimalSepED->setMaxLength(1);
2429 defaultLengthUnitCO->addItem(lyx::qt_(unit_name_gui[Length::CM]), Length::CM);
2430 defaultLengthUnitCO->addItem(lyx::qt_(unit_name_gui[Length::IN]), Length::IN);
2432 QAbstractItemModel * language_model = guiApp->languageModel();
2433 language_model->sort(0);
2434 uiLanguageCO->blockSignals(true);
2435 uiLanguageCO->clear();
2436 uiLanguageCO->addItem(qt_("Default"), toqstr("auto"));
2437 for (int i = 0; i != language_model->rowCount(); ++i) {
2438 QModelIndex index = language_model->index(i, 0);
2439 // Filter the list based on the available translation and add
2440 // each language code only once
2441 string const name = fromqstr(index.data(Qt::UserRole).toString());
2442 Language const * lang = languages.getLanguage(name);
2445 // never remove the currently selected language
2446 if (name != form->rc().gui_language
2447 && name != lyxrc.gui_language
2448 && (!Messages::available(lang->code())
2449 || !lang->hasGuiSupport()))
2451 uiLanguageCO->addItem(index.data(Qt::DisplayRole).toString(),
2452 index.data(Qt::UserRole).toString());
2454 uiLanguageCO->blockSignals(false);
2458 void PrefLanguage::on_uiLanguageCO_currentIndexChanged(int)
2460 QMessageBox::information(this, qt_("LyX needs to be restarted!"),
2461 qt_("The change of user interface language will be fully "
2462 "effective only after a restart."));
2466 void PrefLanguage::on_languagePackageCO_currentIndexChanged(int i)
2469 languagePackageED->setText(save_langpack_);
2470 else if (!languagePackageED->text().isEmpty()) {
2471 save_langpack_ = languagePackageED->text();
2472 languagePackageED->clear();
2474 languagePackageED->setEnabled(i == 2);
2478 void PrefLanguage::on_defaultDecimalSepCO_currentIndexChanged(int i)
2480 defaultDecimalSepED->setEnabled(i == 1);
2484 void PrefLanguage::applyRC(LyXRC & rc) const
2486 rc.visual_cursor = visualCursorRB->isChecked();
2487 rc.mark_foreign_language = markForeignCB->isChecked();
2488 rc.respect_os_kbd_language = respectOSkbdCB->isChecked();
2489 rc.language_auto_begin = !explicitDocLangBeginCB->isChecked();
2490 rc.language_auto_end = !explicitDocLangEndCB->isChecked();
2491 int const p = languagePackageCO->currentIndex();
2493 rc.language_package_selection = LyXRC::LP_AUTO;
2495 rc.language_package_selection = LyXRC::LP_BABEL;
2497 rc.language_package_selection = LyXRC::LP_CUSTOM;
2499 rc.language_package_selection = LyXRC::LP_NONE;
2500 rc.language_custom_package = fromqstr(languagePackageED->text());
2501 rc.language_global_options = globalCB->isChecked();
2502 rc.language_command_begin = fromqstr(startCommandED->text());
2503 rc.language_command_end = fromqstr(endCommandED->text());
2504 rc.gui_language = fromqstr(
2505 uiLanguageCO->itemData(uiLanguageCO->currentIndex()).toString());
2506 if (defaultDecimalSepCO->currentIndex() == 0)
2507 rc.default_decimal_sep = "locale";
2509 rc.default_decimal_sep = fromqstr(defaultDecimalSepED->text());
2510 rc.default_length_unit = (Length::UNIT) defaultLengthUnitCO->itemData(defaultLengthUnitCO->currentIndex()).toInt();
2514 void PrefLanguage::updateRC(LyXRC const & rc)
2516 if (rc.visual_cursor)
2517 visualCursorRB->setChecked(true);
2519 logicalCursorRB->setChecked(true);
2520 markForeignCB->setChecked(rc.mark_foreign_language);
2521 respectOSkbdCB->setChecked(rc.respect_os_kbd_language);
2522 explicitDocLangBeginCB->setChecked(!rc.language_auto_begin);
2523 explicitDocLangEndCB->setChecked(!rc.language_auto_end);
2524 languagePackageCO->setCurrentIndex(rc.language_package_selection);
2525 if (languagePackageCO->currentIndex() == 2) {
2526 languagePackageED->setText(toqstr(rc.language_custom_package));
2527 languagePackageED->setEnabled(true);
2529 languagePackageED->clear();
2530 save_langpack_ = toqstr(rc.language_custom_package);
2531 languagePackageED->setEnabled(false);
2533 defaultDecimalSepED->setEnabled(defaultDecimalSepCO->currentIndex() == 1);
2534 globalCB->setChecked(rc.language_global_options);
2535 startCommandED->setText(toqstr(rc.language_command_begin));
2536 endCommandED->setText(toqstr(rc.language_command_end));
2537 if (rc.default_decimal_sep == "locale") {
2538 defaultDecimalSepCO->setCurrentIndex(0);
2539 defaultDecimalSepED->clear();
2541 defaultDecimalSepCO->setCurrentIndex(1);
2542 defaultDecimalSepED->setText(toqstr(rc.default_decimal_sep));
2544 int pos = defaultLengthUnitCO->findData(int(rc.default_length_unit));
2545 defaultLengthUnitCO->setCurrentIndex(pos);
2547 pos = uiLanguageCO->findData(toqstr(rc.gui_language));
2548 uiLanguageCO->blockSignals(true);
2549 uiLanguageCO->setCurrentIndex(pos);
2550 uiLanguageCO->blockSignals(false);
2554 /////////////////////////////////////////////////////////////////////
2556 // PrefUserInterface
2558 /////////////////////////////////////////////////////////////////////
2560 PrefUserInterface::PrefUserInterface(GuiPreferences * form)
2561 : PrefModule(catLookAndFeel, N_("User Interface"), form)
2565 connect(uiFilePB, SIGNAL(clicked()),
2566 this, SLOT(selectUi()));
2567 connect(uiFileED, SIGNAL(textChanged(QString)),
2568 this, SIGNAL(changed()));
2569 connect(iconSetCO, SIGNAL(activated(int)),
2570 this, SIGNAL(changed()));
2571 connect(useSystemThemeIconsCB, SIGNAL(clicked()),
2572 this, SIGNAL(changed()));
2573 connect(lastfilesSB, SIGNAL(valueChanged(int)),
2574 this, SIGNAL(changed()));
2575 connect(tooltipCB, SIGNAL(toggled(bool)),
2576 this, SIGNAL(changed()));
2577 lastfilesSB->setMaximum(maxlastfiles);
2579 iconSetCO->addItem(qt_("Default"), QString());
2580 iconSetCO->addItem(qt_("Classic"), "classic");
2581 iconSetCO->addItem(qt_("Oxygen"), "oxygen");
2583 #if (!(defined Q_WS_X11 || defined(QPA_XCB)) || QT_VERSION < 0x040600)
2584 useSystemThemeIconsCB->hide();
2589 void PrefUserInterface::applyRC(LyXRC & rc) const
2591 rc.icon_set = fromqstr(iconSetCO->itemData(
2592 iconSetCO->currentIndex()).toString());
2594 rc.ui_file = internal_path(fromqstr(uiFileED->text()));
2595 rc.use_system_theme_icons = useSystemThemeIconsCB->isChecked();
2596 rc.num_lastfiles = lastfilesSB->value();
2597 rc.use_tooltip = tooltipCB->isChecked();
2601 void PrefUserInterface::updateRC(LyXRC const & rc)
2603 int iconset = iconSetCO->findData(toqstr(rc.icon_set));
2606 iconSetCO->setCurrentIndex(iconset);
2607 useSystemThemeIconsCB->setChecked(rc.use_system_theme_icons);
2608 uiFileED->setText(toqstr(external_path(rc.ui_file)));
2609 lastfilesSB->setValue(rc.num_lastfiles);
2610 tooltipCB->setChecked(rc.use_tooltip);
2614 void PrefUserInterface::selectUi()
2616 QString file = form_->browseUI(internalPath(uiFileED->text()));
2617 if (!file.isEmpty())
2618 uiFileED->setText(file);
2622 /////////////////////////////////////////////////////////////////////
2624 // PrefDocumentHandling
2626 /////////////////////////////////////////////////////////////////////
2628 PrefDocHandling::PrefDocHandling(GuiPreferences * form)
2629 : PrefModule(catLookAndFeel, N_("Document Handling"), form)
2633 connect(autoSaveCB, SIGNAL(toggled(bool)),
2634 autoSaveSB, SLOT(setEnabled(bool)));
2635 connect(autoSaveCB, SIGNAL(toggled(bool)),
2636 TextLabel1, SLOT(setEnabled(bool)));
2637 connect(openDocumentsInTabsCB, SIGNAL(clicked()),
2638 this, SIGNAL(changed()));
2639 connect(singleInstanceCB, SIGNAL(clicked()),
2640 this, SIGNAL(changed()));
2641 connect(singleCloseTabButtonCB, SIGNAL(clicked()),
2642 this, SIGNAL(changed()));
2643 connect(closeLastViewCO, SIGNAL(activated(int)),
2644 this, SIGNAL(changed()));
2645 connect(restoreCursorCB, SIGNAL(clicked()),
2646 this, SIGNAL(changed()));
2647 connect(loadSessionCB, SIGNAL(clicked()),
2648 this, SIGNAL(changed()));
2649 connect(allowGeometrySessionCB, SIGNAL(clicked()),
2650 this, SIGNAL(changed()));
2651 connect(autoSaveSB, SIGNAL(valueChanged(int)),
2652 this, SIGNAL(changed()));
2653 connect(autoSaveCB, SIGNAL(clicked()),
2654 this, SIGNAL(changed()));
2655 connect(backupCB, SIGNAL(clicked()),
2656 this, SIGNAL(changed()));
2657 connect(saveCompressedCB, SIGNAL(clicked()),
2658 this, SIGNAL(changed()));
2659 connect(saveOriginCB, SIGNAL(clicked()),
2660 this, SIGNAL(changed()));
2664 void PrefDocHandling::applyRC(LyXRC & rc) const
2666 rc.use_lastfilepos = restoreCursorCB->isChecked();
2667 rc.load_session = loadSessionCB->isChecked();
2668 rc.allow_geometry_session = allowGeometrySessionCB->isChecked();
2669 rc.autosave = autoSaveCB->isChecked() ? autoSaveSB->value() * 60 : 0;
2670 rc.make_backup = backupCB->isChecked();
2671 rc.save_compressed = saveCompressedCB->isChecked();
2672 rc.save_origin = saveOriginCB->isChecked();
2673 rc.open_buffers_in_tabs = openDocumentsInTabsCB->isChecked();
2674 rc.single_instance = singleInstanceCB->isChecked();
2675 rc.single_close_tab_button = singleCloseTabButtonCB->isChecked();
2677 switch (closeLastViewCO->currentIndex()) {
2679 rc.close_buffer_with_last_view = "yes";
2682 rc.close_buffer_with_last_view = "no";
2685 rc.close_buffer_with_last_view = "ask";
2693 void PrefDocHandling::updateRC(LyXRC const & rc)
2695 restoreCursorCB->setChecked(rc.use_lastfilepos);
2696 loadSessionCB->setChecked(rc.load_session);
2697 allowGeometrySessionCB->setChecked(rc.allow_geometry_session);
2698 // convert to minutes
2699 bool autosave = rc.autosave > 0;
2700 int mins = rc.autosave / 60;
2703 autoSaveSB->setValue(mins);
2704 autoSaveCB->setChecked(autosave);
2705 autoSaveSB->setEnabled(autosave);
2706 backupCB->setChecked(rc.make_backup);
2707 saveCompressedCB->setChecked(rc.save_compressed);
2708 saveOriginCB->setChecked(rc.save_origin);
2709 openDocumentsInTabsCB->setChecked(rc.open_buffers_in_tabs);
2710 singleInstanceCB->setChecked(rc.single_instance && !rc.lyxpipes.empty());
2711 singleInstanceCB->setEnabled(!rc.lyxpipes.empty());
2712 singleCloseTabButtonCB->setChecked(rc.single_close_tab_button);
2713 if (rc.close_buffer_with_last_view == "yes")
2714 closeLastViewCO->setCurrentIndex(0);
2715 else if (rc.close_buffer_with_last_view == "no")
2716 closeLastViewCO->setCurrentIndex(1);
2717 else if (rc.close_buffer_with_last_view == "ask")
2718 closeLastViewCO->setCurrentIndex(2);
2722 void PrefDocHandling::on_clearSessionPB_clicked()
2724 guiApp->clearSession();
2729 /////////////////////////////////////////////////////////////////////
2733 /////////////////////////////////////////////////////////////////////
2735 PrefEdit::PrefEdit(GuiPreferences * form)
2736 : PrefModule(catEditing, N_("Control"), form)
2740 connect(cursorFollowsCB, SIGNAL(clicked()),
2741 this, SIGNAL(changed()));
2742 connect(scrollBelowCB, SIGNAL(clicked()),
2743 this, SIGNAL(changed()));
2744 connect(macLikeCursorMovementCB, SIGNAL(clicked()),
2745 this, SIGNAL(changed()));
2746 connect(sortEnvironmentsCB, SIGNAL(clicked()),
2747 this, SIGNAL(changed()));
2748 connect(groupEnvironmentsCB, SIGNAL(clicked()),
2749 this, SIGNAL(changed()));
2750 connect(macroEditStyleCO, SIGNAL(activated(int)),
2751 this, SIGNAL(changed()));
2752 connect(cursorWidthSB, SIGNAL(valueChanged(int)),
2753 this, SIGNAL(changed()));
2754 connect(fullscreenLimitGB, SIGNAL(clicked()),
2755 this, SIGNAL(changed()));
2756 connect(fullscreenWidthSB, SIGNAL(valueChanged(int)),
2757 this, SIGNAL(changed()));
2758 connect(toggleTabbarCB, SIGNAL(toggled(bool)),
2759 this, SIGNAL(changed()));
2760 connect(toggleMenubarCB, SIGNAL(toggled(bool)),
2761 this, SIGNAL(changed()));
2762 connect(toggleScrollbarCB, SIGNAL(toggled(bool)),
2763 this, SIGNAL(changed()));
2764 connect(toggleStatusbarCB, SIGNAL(toggled(bool)),
2765 this, SIGNAL(changed()));
2766 connect(toggleToolbarsCB, SIGNAL(toggled(bool)),
2767 this, SIGNAL(changed()));
2771 void PrefEdit::applyRC(LyXRC & rc) const
2773 rc.cursor_follows_scrollbar = cursorFollowsCB->isChecked();
2774 rc.scroll_below_document = scrollBelowCB->isChecked();
2775 rc.mac_like_cursor_movement = macLikeCursorMovementCB->isChecked();
2776 rc.sort_layouts = sortEnvironmentsCB->isChecked();
2777 rc.group_layouts = groupEnvironmentsCB->isChecked();
2778 switch (macroEditStyleCO->currentIndex()) {
2779 case 0: rc.macro_edit_style = LyXRC::MACRO_EDIT_INLINE_BOX; break;
2780 case 1: rc.macro_edit_style = LyXRC::MACRO_EDIT_INLINE; break;
2781 case 2: rc.macro_edit_style = LyXRC::MACRO_EDIT_LIST; break;
2783 rc.cursor_width = cursorWidthSB->value();
2784 rc.full_screen_toolbars = toggleToolbarsCB->isChecked();
2785 rc.full_screen_scrollbar = toggleScrollbarCB->isChecked();
2786 rc.full_screen_statusbar = toggleStatusbarCB->isChecked();
2787 rc.full_screen_tabbar = toggleTabbarCB->isChecked();
2788 rc.full_screen_menubar = toggleMenubarCB->isChecked();
2789 rc.full_screen_width = fullscreenWidthSB->value();
2790 rc.full_screen_limit = fullscreenLimitGB->isChecked();
2794 void PrefEdit::updateRC(LyXRC const & rc)
2796 cursorFollowsCB->setChecked(rc.cursor_follows_scrollbar);
2797 scrollBelowCB->setChecked(rc.scroll_below_document);
2798 macLikeCursorMovementCB->setChecked(rc.mac_like_cursor_movement);
2799 sortEnvironmentsCB->setChecked(rc.sort_layouts);
2800 groupEnvironmentsCB->setChecked(rc.group_layouts);
2801 macroEditStyleCO->setCurrentIndex(rc.macro_edit_style);
2802 cursorWidthSB->setValue(rc.cursor_width);
2803 toggleScrollbarCB->setChecked(rc.full_screen_scrollbar);
2804 toggleStatusbarCB->setChecked(rc.full_screen_statusbar);
2805 toggleToolbarsCB->setChecked(rc.full_screen_toolbars);
2806 toggleTabbarCB->setChecked(rc.full_screen_tabbar);
2807 toggleMenubarCB->setChecked(rc.full_screen_menubar);
2808 fullscreenWidthSB->setValue(rc.full_screen_width);
2809 fullscreenLimitGB->setChecked(rc.full_screen_limit);
2813 /////////////////////////////////////////////////////////////////////
2817 /////////////////////////////////////////////////////////////////////
2820 GuiShortcutDialog::GuiShortcutDialog(QWidget * parent) : QDialog(parent)
2822 Ui::shortcutUi::setupUi(this);
2823 QDialog::setModal(true);
2827 PrefShortcuts::PrefShortcuts(GuiPreferences * form)
2828 : PrefModule(catEditing, N_("Shortcuts"), form),
2829 editItem_(0), mathItem_(0), bufferItem_(0), layoutItem_(0),
2834 shortcutsTW->setColumnCount(2);
2835 shortcutsTW->headerItem()->setText(0, qt_("Function"));
2836 shortcutsTW->headerItem()->setText(1, qt_("Shortcut"));
2837 shortcutsTW->setSortingEnabled(true);
2838 // Multi-selection can be annoying.
2839 // shortcutsTW->setSelectionMode(QAbstractItemView::MultiSelection);
2841 connect(bindFilePB, SIGNAL(clicked()),
2842 this, SLOT(selectBind()));
2843 connect(bindFileED, SIGNAL(textChanged(QString)),
2844 this, SIGNAL(changed()));
2846 shortcut_ = new GuiShortcutDialog(this);
2847 shortcut_bc_.setPolicy(ButtonPolicy::OkCancelPolicy);
2848 shortcut_bc_.setOK(shortcut_->buttonBox->button(QDialogButtonBox::Ok));
2849 shortcut_bc_.setCancel(shortcut_->buttonBox->button(QDialogButtonBox::Cancel));
2851 connect(shortcut_->buttonBox, SIGNAL(accepted()),
2852 this, SIGNAL(changed()));
2853 connect(shortcut_->buttonBox, SIGNAL(rejected()),
2854 shortcut_, SLOT(reject()));
2855 connect(shortcut_->clearPB, SIGNAL(clicked()),
2856 this, SLOT(shortcutClearPressed()));
2857 connect(shortcut_->removePB, SIGNAL(clicked()),
2858 this, SLOT(shortcutRemovePressed()));
2859 connect(shortcut_->buttonBox, SIGNAL(accepted()),
2860 this, SLOT(shortcutOkPressed()));
2861 connect(shortcut_->buttonBox, SIGNAL(rejected()),
2862 this, SLOT(shortcutCancelPressed()));
2866 void PrefShortcuts::applyRC(LyXRC & rc) const
2868 rc.bind_file = internal_path(fromqstr(bindFileED->text()));
2869 // write user_bind and user_unbind to .lyx/bind/user.bind
2870 FileName bind_dir(addPath(package().user_support().absFileName(), "bind"));
2871 if (!bind_dir.exists() && !bind_dir.createDirectory(0777)) {
2872 lyxerr << "LyX could not create the user bind directory '"
2873 << bind_dir << "'. All user-defined key bindings will be lost." << endl;
2876 if (!bind_dir.isDirWritable()) {
2877 lyxerr << "LyX could not write to the user bind directory '"
2878 << bind_dir << "'. All user-defined key bindings will be lost." << endl;
2881 FileName user_bind_file(bind_dir.absFileName() + "/user.bind");
2882 user_unbind_.write(user_bind_file.toFilesystemEncoding(), false, true);
2883 user_bind_.write(user_bind_file.toFilesystemEncoding(), true, false);
2884 // immediately apply the keybindings. Why this is not done before?
2885 // The good thing is that the menus are updated automatically.
2886 theTopLevelKeymap().clear();
2887 theTopLevelKeymap().read("site");
2888 theTopLevelKeymap().read(rc.bind_file, 0, KeyMap::Fallback);
2889 theTopLevelKeymap().read("user", 0, KeyMap::MissingOK);
2893 void PrefShortcuts::updateRC(LyXRC const & rc)
2895 bindFileED->setText(toqstr(external_path(rc.bind_file)));
2897 system_bind_.clear();
2899 user_unbind_.clear();
2900 system_bind_.read("site");
2901 system_bind_.read(rc.bind_file);
2902 // \unbind in user.bind is added to user_unbind_
2903 user_bind_.read("user", &user_unbind_, KeyMap::MissingOK);
2904 updateShortcutsTW();
2908 void PrefShortcuts::updateShortcutsTW()
2910 shortcutsTW->clear();
2912 editItem_ = new QTreeWidgetItem(shortcutsTW);
2913 editItem_->setText(0, qt_("Cursor, Mouse and Editing Functions"));
2914 editItem_->setFlags(editItem_->flags() & ~Qt::ItemIsSelectable);
2916 mathItem_ = new QTreeWidgetItem(shortcutsTW);
2917 mathItem_->setText(0, qt_("Mathematical Symbols"));
2918 mathItem_->setFlags(mathItem_->flags() & ~Qt::ItemIsSelectable);
2920 bufferItem_ = new QTreeWidgetItem(shortcutsTW);
2921 bufferItem_->setText(0, qt_("Document and Window"));
2922 bufferItem_->setFlags(bufferItem_->flags() & ~Qt::ItemIsSelectable);
2924 layoutItem_ = new QTreeWidgetItem(shortcutsTW);
2925 layoutItem_->setText(0, qt_("Font, Layouts and Textclasses"));
2926 layoutItem_->setFlags(layoutItem_->flags() & ~Qt::ItemIsSelectable);
2928 systemItem_ = new QTreeWidgetItem(shortcutsTW);
2929 systemItem_->setText(0, qt_("System and Miscellaneous"));
2930 systemItem_->setFlags(systemItem_->flags() & ~Qt::ItemIsSelectable);
2932 // listBindings(unbound=true) lists all bound and unbound lfuns
2933 // Items in this list is tagged by its source.
2934 KeyMap::BindingList bindinglist = system_bind_.listBindings(true,
2936 KeyMap::BindingList user_bindinglist = user_bind_.listBindings(false,
2938 KeyMap::BindingList user_unbindinglist = user_unbind_.listBindings(false,
2939 KeyMap::UserUnbind);
2940 bindinglist.insert(bindinglist.end(), user_bindinglist.begin(),
2941 user_bindinglist.end());
2942 bindinglist.insert(bindinglist.end(), user_unbindinglist.begin(),
2943 user_unbindinglist.end());
2945 KeyMap::BindingList::const_iterator it = bindinglist.begin();
2946 KeyMap::BindingList::const_iterator it_end = bindinglist.end();
2947 for (; it != it_end; ++it)
2948 insertShortcutItem(it->request, it->sequence, it->tag);
2950 shortcutsTW->sortItems(0, Qt::AscendingOrder);
2951 on_shortcutsTW_itemSelectionChanged();
2952 on_searchLE_textEdited();
2953 shortcutsTW->resizeColumnToContents(0);
2958 KeyMap::ItemType PrefShortcuts::itemType(QTreeWidgetItem & item)
2960 return static_cast<KeyMap::ItemType>(item.data(0, Qt::UserRole).toInt());
2965 bool PrefShortcuts::isAlwaysHidden(QTreeWidgetItem & item)
2967 // Hide rebound system settings that are empty
2968 return itemType(item) == KeyMap::UserUnbind && item.text(1).isEmpty();
2972 void PrefShortcuts::setItemType(QTreeWidgetItem * item, KeyMap::ItemType tag)
2974 item->setData(0, Qt::UserRole, QVariant(tag));
2978 case KeyMap::System:
2980 case KeyMap::UserBind:
2983 case KeyMap::UserUnbind:
2984 font.setStrikeOut(true);
2986 // this item is not displayed now.
2987 case KeyMap::UserExtraUnbind:
2988 font.setStrikeOut(true);
2991 item->setHidden(isAlwaysHidden(*item));
2992 item->setFont(1, font);
2996 QTreeWidgetItem * PrefShortcuts::insertShortcutItem(FuncRequest const & lfun,
2997 KeySequence const & seq, KeyMap::ItemType tag)
2999 FuncCode const action = lfun.action();
3000 string const action_name = lyxaction.getActionName(action);
3001 QString const lfun_name = toqstr(from_utf8(action_name)
3002 + ' ' + lfun.argument());
3003 QString const shortcut = toqstr(seq.print(KeySequence::ForGui));
3005 QTreeWidgetItem * newItem = 0;
3006 // for unbind items, try to find an existing item in the system bind list
3007 if (tag == KeyMap::UserUnbind) {
3008 QList<QTreeWidgetItem*> const items = shortcutsTW->findItems(lfun_name,
3009 Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 0);
3010 for (int i = 0; i < items.size(); ++i) {
3011 if (items[i]->text(1) == shortcut) {
3016 // if not found, this unbind item is KeyMap::UserExtraUnbind
3017 // Such an item is not displayed to avoid confusion (what is
3018 // unmatched removed?).
3024 switch(lyxaction.getActionType(action)) {
3025 case LyXAction::Hidden:
3027 case LyXAction::Edit:
3028 newItem = new QTreeWidgetItem(editItem_);
3030 case LyXAction::Math:
3031 newItem = new QTreeWidgetItem(mathItem_);
3033 case LyXAction::Buffer:
3034 newItem = new QTreeWidgetItem(bufferItem_);
3036 case LyXAction::Layout:
3037 newItem = new QTreeWidgetItem(layoutItem_);
3039 case LyXAction::System:
3040 newItem = new QTreeWidgetItem(systemItem_);
3043 // this should not happen
3044 newItem = new QTreeWidgetItem(shortcutsTW);
3048 newItem->setText(0, lfun_name);
3049 newItem->setText(1, shortcut);
3050 // record BindFile representation to recover KeySequence when needed.
3051 newItem->setData(1, Qt::UserRole, toqstr(seq.print(KeySequence::BindFile)));
3052 setItemType(newItem, tag);
3057 void PrefShortcuts::on_shortcutsTW_itemSelectionChanged()
3059 QList<QTreeWidgetItem*> items = shortcutsTW->selectedItems();
3060 removePB->setEnabled(!items.isEmpty() && !items[0]->text(1).isEmpty());
3061 modifyPB->setEnabled(!items.isEmpty());
3062 if (items.isEmpty())
3065 if (itemType(*items[0]) == KeyMap::UserUnbind)
3066 removePB->setText(qt_("Res&tore"));
3068 removePB->setText(qt_("Remo&ve"));
3072 void PrefShortcuts::on_shortcutsTW_itemDoubleClicked()
3078 void PrefShortcuts::modifyShortcut()
3080 QTreeWidgetItem * item = shortcutsTW->currentItem();
3081 if (item->flags() & Qt::ItemIsSelectable) {
3082 shortcut_->lfunLE->setText(item->text(0));
3083 save_lfun_ = item->text(0).trimmed();
3084 shortcut_->shortcutWG->setText(item->text(1));
3086 seq.parse(fromqstr(item->data(1, Qt::UserRole).toString()));
3087 shortcut_->shortcutWG->setKeySequence(seq);
3088 shortcut_->shortcutWG->setFocus();
3094 void PrefShortcuts::unhideEmpty(QString const & lfun, bool select)
3096 // list of items that match lfun
3097 QList<QTreeWidgetItem*> items = shortcutsTW->findItems(lfun,
3098 Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 0);
3099 for (int i = 0; i < items.size(); ++i) {
3100 QTreeWidgetItem * item = items[i];
3101 if (isAlwaysHidden(*item)) {
3102 setItemType(item, KeyMap::System);
3104 shortcutsTW->setCurrentItem(item);
3111 void PrefShortcuts::removeShortcut()
3113 // it seems that only one item can be selected, but I am
3114 // removing all selected items anyway.
3115 QList<QTreeWidgetItem*> items = shortcutsTW->selectedItems();
3116 for (int i = 0; i < items.size(); ++i) {
3117 string shortcut = fromqstr(items[i]->data(1, Qt::UserRole).toString());
3118 string lfun = fromqstr(items[i]->text(0));
3119 FuncRequest func = lyxaction.lookupFunc(lfun);
3121 switch (itemType(*items[i])) {
3122 case KeyMap::System: {
3123 // for system bind, we do not touch the item
3124 // but add an user unbind item
3125 user_unbind_.bind(shortcut, func);
3126 setItemType(items[i], KeyMap::UserUnbind);
3127 removePB->setText(qt_("Res&tore"));
3130 case KeyMap::UserBind: {
3131 // for user_bind, we remove this bind
3132 QTreeWidgetItem * parent = items[i]->parent();
3133 int itemIdx = parent->indexOfChild(items[i]);
3134 parent->takeChild(itemIdx);
3136 shortcutsTW->scrollToItem(parent->child(itemIdx - 1));
3138 shortcutsTW->scrollToItem(parent);
3139 user_bind_.unbind(shortcut, func);
3140 // If this user binding hid an empty system binding, unhide the
3141 // latter and select it.
3142 unhideEmpty(items[i]->text(0), true);
3145 case KeyMap::UserUnbind: {
3146 // for user_unbind, we remove the unbind, and the item
3147 // become KeyMap::System again.
3149 seq.parse(shortcut);
3150 // Ask the user to replace current binding
3151 if (!validateNewShortcut(func, seq, QString()))
3153 user_unbind_.unbind(shortcut, func);
3154 setItemType(items[i], KeyMap::System);
3155 removePB->setText(qt_("Remo&ve"));
3158 case KeyMap::UserExtraUnbind: {
3159 // for user unbind that is not in system bind file,
3160 // remove this unbind file
3161 QTreeWidgetItem * parent = items[i]->parent();
3162 parent->takeChild(parent->indexOfChild(items[i]));
3163 user_unbind_.unbind(shortcut, func);
3170 void PrefShortcuts::deactivateShortcuts(QList<QTreeWidgetItem*> const & items)
3172 for (int i = 0; i < items.size(); ++i) {
3173 string shortcut = fromqstr(items[i]->data(1, Qt::UserRole).toString());
3174 string lfun = fromqstr(items[i]->text(0));
3175 FuncRequest func = lyxaction.lookupFunc(lfun);
3177 switch (itemType(*items[i])) {
3178 case KeyMap::System:
3179 // for system bind, we do not touch the item
3180 // but add an user unbind item
3181 user_unbind_.bind(shortcut, func);
3182 setItemType(items[i], KeyMap::UserUnbind);
3185 case KeyMap::UserBind: {
3186 // for user_bind, we remove this bind
3187 QTreeWidgetItem * parent = items[i]->parent();
3188 int itemIdx = parent->indexOfChild(items[i]);
3189 parent->takeChild(itemIdx);
3190 user_bind_.unbind(shortcut, func);
3191 unhideEmpty(items[i]->text(0), false);
3201 void PrefShortcuts::selectBind()
3203 QString file = form_->browsebind(internalPath(bindFileED->text()));
3204 if (!file.isEmpty()) {
3205 bindFileED->setText(file);
3206 system_bind_ = KeyMap();
3207 system_bind_.read(fromqstr(file));
3208 updateShortcutsTW();
3213 void PrefShortcuts::on_modifyPB_pressed()
3219 void PrefShortcuts::on_newPB_pressed()
3221 shortcut_->lfunLE->clear();
3222 shortcut_->shortcutWG->reset();
3223 save_lfun_ = QString();
3228 void PrefShortcuts::on_removePB_pressed()
3235 void PrefShortcuts::on_searchLE_textEdited()
3237 if (searchLE->text().isEmpty()) {
3238 // show all hidden items
3239 QTreeWidgetItemIterator it(shortcutsTW, QTreeWidgetItemIterator::Hidden);
3241 shortcutsTW->setItemHidden(*it, isAlwaysHidden(**it));
3242 // close all categories
3243 for (int i = 0; i < shortcutsTW->topLevelItemCount(); ++i)
3244 shortcutsTW->collapseItem(shortcutsTW->topLevelItem(i));
3247 // search both columns
3248 QList<QTreeWidgetItem *> matched = shortcutsTW->findItems(searchLE->text(),
3249 Qt::MatchFlags(Qt::MatchContains | Qt::MatchRecursive), 0);
3250 matched += shortcutsTW->findItems(searchLE->text(),
3251 Qt::MatchFlags(Qt::MatchContains | Qt::MatchRecursive), 1);
3253 // hide everyone (to avoid searching in matched QList repeatedly
3254 QTreeWidgetItemIterator it(shortcutsTW, QTreeWidgetItemIterator::Selectable);
3256 shortcutsTW->setItemHidden(*it++, true);
3257 // show matched items
3258 for (int i = 0; i < matched.size(); ++i)
3259 if (!isAlwaysHidden(*matched[i])) {
3260 shortcutsTW->setItemHidden(matched[i], false);
3261 shortcutsTW->setItemExpanded(matched[i]->parent(), true);
3266 docstring makeCmdString(FuncRequest const & f)
3268 docstring actionStr = from_ascii(lyxaction.getActionName(f.action()));
3269 if (!f.argument().empty())
3270 actionStr += " " + f.argument();
3275 FuncRequest PrefShortcuts::currentBinding(KeySequence const & k)
3277 FuncRequest res = user_bind_.getBinding(k);
3278 if (res.action() != LFUN_UNKNOWN_ACTION)
3280 res = system_bind_.getBinding(k);
3281 // Check if it is unbound. Note: user_unbind_ can only unbind one
3282 // FuncRequest per key sequence.
3283 if (user_unbind_.getBinding(k) == res)
3284 return FuncRequest::unknown;
3289 bool PrefShortcuts::validateNewShortcut(FuncRequest const & func,
3290 KeySequence const & k,
3291 QString const & lfun_to_modify)
3293 if (func.action() == LFUN_UNKNOWN_ACTION) {
3294 Alert::error(_("Failed to create shortcut"),
3295 _("Unknown or invalid LyX function"));
3299 // It is not currently possible to bind Hidden lfuns such as self-insert. In
3300 // the future, to remove this limitation, see GuiPrefs::insertShortcutItem
3301 // and how it is used in GuiPrefs::shortcutOkPressed.
3302 if (lyxaction.getActionType(func.action()) == LyXAction::Hidden) {
3303 Alert::error(_("Failed to create shortcut"),
3304 _("This LyX function is hidden and cannot be bound."));
3308 if (k.length() == 0) {
3309 Alert::error(_("Failed to create shortcut"),
3310 _("Invalid or empty key sequence"));
3314 FuncRequest oldBinding = currentBinding(k);
3315 if (oldBinding == func)
3316 // nothing to change
3319 // make sure this key isn't already bound---and, if so, prompt user
3320 // (exclude the lfun the user already wants to modify)
3321 docstring const action_string = makeCmdString(oldBinding);
3322 if (oldBinding.action() != LFUN_UNKNOWN_ACTION
3323 && lfun_to_modify != toqstr(action_string)) {
3324 docstring const new_action_string = makeCmdString(func);
3325 docstring const text = bformat(_("Shortcut `%1$s' is already bound to "
3327 "Are you sure you want to unbind the "
3328 "current shortcut and bind it to %3$s?"),
3329 k.print(KeySequence::ForGui), action_string,
3331 int ret = Alert::prompt(_("Redefine shortcut?"),
3332 text, 0, 1, _("&Redefine"), _("&Cancel"));
3335 QString const sequence_text = toqstr(k.print(KeySequence::ForGui));
3336 QList<QTreeWidgetItem*> items = shortcutsTW->findItems(sequence_text,
3337 Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 1);
3338 deactivateShortcuts(items);
3344 void PrefShortcuts::shortcutOkPressed()
3346 QString const new_lfun = shortcut_->lfunLE->text();
3347 FuncRequest func = lyxaction.lookupFunc(fromqstr(new_lfun));
3348 KeySequence k = shortcut_->shortcutWG->getKeySequence();
3350 // save_lfun_ contains the text of the lfun to modify, if the user clicked
3351 // "modify", or is empty if they clicked "new" (which I do not really like)
3352 if (!validateNewShortcut(func, k, save_lfun_))
3355 if (!save_lfun_.isEmpty()) {
3356 // real modification of the lfun's shortcut,
3357 // so remove the previous one
3358 QList<QTreeWidgetItem*> to_modify = shortcutsTW->selectedItems();
3359 deactivateShortcuts(to_modify);
3362 shortcut_->accept();
3364 QTreeWidgetItem * item = insertShortcutItem(func, k, KeyMap::UserBind);
3366 user_bind_.bind(&k, func);
3367 shortcutsTW->sortItems(0, Qt::AscendingOrder);
3368 shortcutsTW->setItemExpanded(item->parent(), true);
3369 shortcutsTW->setCurrentItem(item);
3370 shortcutsTW->scrollToItem(item);
3372 Alert::error(_("Failed to create shortcut"),
3373 _("Can not insert shortcut to the list"));
3379 void PrefShortcuts::shortcutCancelPressed()
3381 shortcut_->shortcutWG->reset();
3385 void PrefShortcuts::shortcutClearPressed()
3387 shortcut_->shortcutWG->reset();
3391 void PrefShortcuts::shortcutRemovePressed()
3393 shortcut_->shortcutWG->removeFromSequence();
3397 /////////////////////////////////////////////////////////////////////
3401 /////////////////////////////////////////////////////////////////////
3403 PrefIdentity::PrefIdentity(GuiPreferences * form)
3404 : PrefModule(QString(), N_("Identity"), form)
3408 connect(nameED, SIGNAL(textChanged(QString)),
3409 this, SIGNAL(changed()));
3410 connect(emailED, SIGNAL(textChanged(QString)),
3411 this, SIGNAL(changed()));
3413 nameED->setValidator(new NoNewLineValidator(nameED));
3414 emailED->setValidator(new NoNewLineValidator(emailED));
3418 void PrefIdentity::applyRC(LyXRC & rc) const
3420 rc.user_name = fromqstr(nameED->text());
3421 rc.user_email = fromqstr(emailED->text());
3425 void PrefIdentity::updateRC(LyXRC const & rc)
3427 nameED->setText(toqstr(rc.user_name));
3428 emailED->setText(toqstr(rc.user_email));
3433 /////////////////////////////////////////////////////////////////////
3437 /////////////////////////////////////////////////////////////////////
3439 GuiPreferences::GuiPreferences(GuiView & lv)
3440 : GuiDialog(lv, "prefs", qt_("Preferences"))
3444 QDialog::setModal(false);
3446 connect(buttonBox, SIGNAL(clicked(QAbstractButton *)),
3447 this, SLOT(slotButtonBox(QAbstractButton *)));
3449 addModule(new PrefUserInterface(this));
3450 addModule(new PrefDocHandling(this));
3451 addModule(new PrefEdit(this));
3452 addModule(new PrefShortcuts(this));
3453 PrefScreenFonts * screenfonts = new PrefScreenFonts(this);
3454 connect(this, SIGNAL(prefsApplied(LyXRC const &)),
3455 screenfonts, SLOT(updateScreenFontSizes(LyXRC const &)));
3456 addModule(screenfonts);
3457 addModule(new PrefColors(this));
3458 addModule(new PrefDisplay(this));
3459 addModule(new PrefInput(this));
3460 addModule(new PrefCompletion(this));
3462 addModule(new PrefPaths(this));
3464 addModule(new PrefIdentity(this));
3466 addModule(new PrefLanguage(this));
3467 addModule(new PrefSpellchecker(this));
3469 PrefOutput * output = new PrefOutput(this);
3471 addModule(new PrefLatex(this));
3473 PrefConverters * converters = new PrefConverters(this);
3474 PrefFileformats * formats = new PrefFileformats(this);
3475 connect(formats, SIGNAL(formatsChanged()),
3476 converters, SLOT(updateGui()));
3477 addModule(converters);
3480 prefsPS->setCurrentPanel("User Interface");
3481 // FIXME: hack to work around resizing bug in Qt >= 4.2
3482 // bug verified with Qt 4.2.{0-3} (JSpitzm)
3483 #if QT_VERSION >= 0x040200
3484 prefsPS->updateGeometry();
3487 bc().setPolicy(ButtonPolicy::PreferencesPolicy);
3488 bc().setOK(buttonBox->button(QDialogButtonBox::Ok));
3489 bc().setApply(buttonBox->button(QDialogButtonBox::Apply));
3490 bc().setCancel(buttonBox->button(QDialogButtonBox::Cancel));
3491 bc().setRestore(buttonBox->button(QDialogButtonBox::Reset));
3493 guilyxfiles_ = new GuiLyXFiles(lv);
3494 connect(guilyxfiles_, SIGNAL(fileSelected(QString)),
3495 this, SLOT(slotFileSelected(QString)));
3499 void GuiPreferences::addModule(PrefModule * module)
3501 LASSERT(module, return);
3502 if (module->category().isEmpty())
3503 prefsPS->addPanel(module, module->title());
3505 prefsPS->addPanel(module, module->title(), module->category());
3506 connect(module, SIGNAL(changed()), this, SLOT(change_adaptor()));
3507 modules_.push_back(module);
3511 void GuiPreferences::change_adaptor()
3517 void GuiPreferences::applyRC(LyXRC & rc) const
3519 size_t end = modules_.size();
3520 for (size_t i = 0; i != end; ++i)
3521 modules_[i]->applyRC(rc);
3525 void GuiPreferences::updateRC(LyXRC const & rc)
3527 size_t const end = modules_.size();
3528 for (size_t i = 0; i != end; ++i)
3529 modules_[i]->updateRC(rc);
3533 void GuiPreferences::applyView()
3539 bool GuiPreferences::initialiseParams(string const &)
3542 formats_ = theFormats();
3543 converters_ = theConverters();
3544 converters_.update(formats_);
3545 movers_ = theMovers();
3549 // Make sure that the bc is in the INITIAL state
3550 if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
3557 void GuiPreferences::dispatchParams()
3560 rc_.write(ss, true);
3561 dispatch(FuncRequest(LFUN_LYXRC_APPLY, ss.str()));
3562 // issue prefsApplied signal. This will update the
3563 // localized screen font sizes.
3565 // FIXME: these need lfuns
3567 Author const & author =
3568 Author(from_utf8(rc_.user_name), from_utf8(rc_.user_email));
3569 theBufferList().recordCurrentAuthor(author);
3571 theFormats() = formats_;
3573 theConverters() = converters_;
3574 theConverters().update(formats_);
3575 theConverters().buildGraph();
3576 theBufferList().invalidateConverterCache();
3578 theMovers() = movers_;
3580 for (string const & color : colors_)
3581 dispatch(FuncRequest(LFUN_SET_COLOR, color));
3585 if (!tempSaveCB->isChecked())
3586 dispatch(FuncRequest(LFUN_PREFERENCES_SAVE));
3590 void GuiPreferences::setColor(ColorCode col, QString const & hex)
3592 colors_.push_back(lcolor.getLyXName(col) + ' ' + fromqstr(hex));
3596 void GuiPreferences::slotFileSelected(QString const file)
3602 QString GuiPreferences::browseLibFile(QString const & dir,
3603 QString const & name, QString const & ext)
3607 guilyxfiles_->passParams(fromqstr(dir));
3608 guilyxfiles_->selectItem(name);
3609 guilyxfiles_->exec();
3611 QString const result = uifile_;
3613 // remove the extension if it is the default one
3614 QString noextresult;
3615 if (getExtension(result) == ext)
3616 noextresult = removeExtension(result);
3618 noextresult = result;
3620 // remove the directory, if it is the default one
3621 QString const file = onlyFileName(noextresult);
3622 if (toqstr(libFileSearch(dir, file, ext).absFileName()) == result)
3629 QString GuiPreferences::browsebind(QString const & file)
3631 return browseLibFile("bind", file, "bind");
3635 QString GuiPreferences::browseUI(QString const & file)
3637 return browseLibFile("ui", file, "ui");
3641 QString GuiPreferences::browsekbmap(QString const & file)
3643 return browseLibFile("kbd", file, "kmap");
3647 QString GuiPreferences::browse(QString const & file,
3648 QString const & title) const
3650 return browseFile(file, title, QStringList(), true);
3654 Dialog * createGuiPreferences(GuiView & lv) { return new GuiPreferences(lv); }
3657 } // namespace frontend
3660 #include "moc_GuiPrefs.cpp"